
/* The page ground is the platform's SUNKEN surface. The card is white, and a
   white card needs a ground a shade under it to read as a sheet rather than as
   a rectangle drawn on the page. It carries no text, so no pair is under a
   ratio. The :has() rules are progressive: a browser without :has() ignores
   them and the root below still covers the viewport with its own light ground. */
html:has(.sgn-page), body:has(.sgn-page) {
  color-scheme: light;
  background: #e8ecf4;
  color: #0f1a33;
}

.sgn-page {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  /* Stacked: masthead, form, notice. The middle row takes the slack, so on a
     tall phone the card is centred in what is left rather than the navy notice
     floating half way up a grey page. */
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--tn-color-surface-sunken);
  color: var(--tn-color-text);
  font-family: var(--tn-font-sans);
  font-size: var(--tn-text-base);
  line-height: var(--tn-leading-normal);
}

/* --------------------------------------------------------------- the navy */

.sgn-brand {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: var(--tn-space-xxxl);
  background: var(--tn-color-header-bg);
  color: var(--tn-color-header-ink);
}

/* On a wide screen the emblem sits above the words; on a phone the same two
   elements are one row, which is the whole of the mobile collapse. */
.sgn-brand__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--tn-space-md);
}

/*
 * THE EMBLEM SITS ON WHITE, ALWAYS.
 *
 * public/tn-seal.png is the Tamil Nadu state emblem as a colour raster with a
 * white ground baked in. Dropped straight onto the navy it reads as a white
 * sticker with a ragged edge; given a white tile it reads as what it is — an
 * emblem on paper. The same file, at the same size, is in the masthead of every
 * signed-in page, so the two doors agree.
 */
.sgn-brand__tile {
  --sgn-seal: 56px;
  flex: none;
  display: grid;
  place-items: center;
  width: calc(var(--sgn-seal) + (2 * var(--tn-space-xs)));
  height: calc(var(--sgn-seal) + (2 * var(--tn-space-xs)));
  background: var(--tn-color-surface-raised);
  border-radius: var(--tn-radius-lg);
  box-shadow: var(--tn-shadow-md);
}
/*
 * AN EXPLICIT LENGTH, NOT A PERCENTAGE. The tile is a grid whose single row is
 * auto-sized, so a percentage height on the image resolves against an
 * indefinite grid area — which means auto, which means the emblem renders at
 * its intrinsic 500px and covers the department's name. One custom property
 * drives both the tile and the emblem, so the two cannot disagree at any
 * breakpoint. Width follows the file's own aspect ratio.
 */
.sgn-brand__seal { display: block; width: auto; height: var(--sgn-seal); max-width: 100%; }

.sgn-brand__state {
  margin: 0 0 var(--tn-space-xxs);
  font-size: var(--tn-text-sm);
  font-weight: var(--tn-weight-semibold);
  letter-spacing: var(--tn-tracking-wider);
  text-transform: uppercase;
  color: var(--tn-color-header-ink-muted);
}

.sgn-brand__title {
  margin: 0;
  font-size: var(--tn-text-xxl);
  font-weight: var(--tn-weight-bold);
  line-height: var(--tn-leading-tight);
  letter-spacing: var(--tn-tracking-tight);
  color: var(--tn-color-header-ink);
  text-wrap: balance;
}

.sgn-brand__tagline {
  margin: var(--tn-space-sm) 0 0;
  max-width: 40ch;
  font-size: var(--tn-text-base);
  line-height: var(--tn-leading-snug);
  color: var(--tn-color-header-ink-muted);
}

/*
 * The tricolour. Three flat bands, drawn with a gradient rather than three
 * elements, decorative and aria-hidden. It is the whole decoration budget of
 * this column and it is the rule a printed government form already carries
 * under its letterhead.
 */
.sgn-brand__rule {
  align-self: stretch;
  max-width: 168px;
  height: 5px;
  margin: var(--tn-space-lg) 0 0;
  border-radius: var(--tn-radius-pill);
  background: linear-gradient(
    90deg,
    #ff9933 0 33.34%,
    #ffffff 33.34% 66.67%,
    #138808 66.67% 100%
  );
}

/* ------------------------------------------------------------- what it does */

.sgn-brand__features {
  margin: var(--tn-space-xxl) 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--tn-space-lg);
}

.sgn-brand__feature {
  display: flex;
  align-items: flex-start;
  gap: var(--tn-space-md);
  font-size: var(--tn-text-base);
  line-height: var(--tn-leading-snug);
  color: var(--tn-color-header-ink);
}

/* A tile, not a bare glyph: at 18px on navy a stroked icon disappears, and the
   tile gives every line the same left edge whatever the icon's own width. */
/*
 * @tn/ui's sign-in drawing (the dam, the hills and the row of quarters), at the
 * foot of the navy column. Re-inked for the navy through the illustration kit's
 * own custom properties, from the header tokens: light lines, a navy paper, the
 * header's edge colour for the washes. Decorative; it goes wherever the column
 * has no room for it (a phone, a short office panel) and in print.
 */
.sgn-brand__hero {
  --tn-illo-ink: var(--tn-color-header-ink-muted);
  --tn-illo-tint: var(--tn-color-header-border);
  --tn-illo-paper: var(--tn-color-header-bg);
  margin-top: auto;
  padding-top: var(--tn-space-md);
  width: min(100%, 280px);
  height: auto;
}

.sgn-brand__feature-tile {
  flex: none;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: var(--tn-radius-md);
  background: var(--tn-color-header-border);
  color: var(--tn-color-header-ink);
}

/* ------------------------------------------------------------- the notice */

/*
 * The standing legal line. It is the LAST thing in the navy on a wide screen
 * and the last thing on the page on a phone, in both cases directly under the
 * only act this page offers. It keeps the small size a footnote has and is set
 * against the department's own ground, so it reads as posted rather than as
 * left over.
 */
.sgn-legal {
  display: flex;
  align-items: flex-start;
  gap: var(--tn-space-sm);
  padding: var(--tn-space-lg) var(--tn-space-xxxl) var(--tn-space-xxxl);
  background: var(--tn-color-header-bg);
  font-size: var(--tn-text-sm);
  line-height: var(--tn-leading-snug);
  color: var(--tn-color-header-ink-muted);
}
.sgn-legal p { margin: 0; max-width: 48ch; }
.sgn-legal__icon { flex: none; margin-top: 1px; }

/* An accent focus ring is unreadable on navy. Anything focusable in either navy
   band gets the white one. */
.sgn-brand :focus-visible,
.sgn-legal :focus-visible {
  outline: 3px solid var(--tn-color-header-ink);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------- the card */

.sgn-main {
  display: flex;
  flex-direction: column;
  /* "safe center" so a card taller than the viewport — a phone in landscape
     with the keyboard up — overflows downwards and stays reachable instead of
     having its top scrolled out of existence. A browser too old for the keyword
     drops the second declaration and centres normally. */
  justify-content: center;
  justify-content: safe center;
  align-items: center;
  gap: var(--tn-space-lg);
  padding: var(--tn-space-xxl) var(--tn-space-md);
}

.sgn-card {
  width: 100%;
  max-width: 480px;
  padding: var(--tn-space-xxl);
  background: var(--tn-color-surface-raised);
  border: 1px solid var(--tn-color-border-strong);
  border-radius: var(--tn-radius-xl);
  /* Clips nothing that could be focused: every control is at least 16px inside
     this edge, so no focus ring (3px at 2px offset) is cut. */
  box-shadow: var(--tn-shadow-lg);
}

.sgn-card__title {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  font-size: var(--tn-text-xl);
  font-weight: var(--tn-weight-bold);
  line-height: var(--tn-leading-tight);
  letter-spacing: var(--tn-tracking-tight);
  color: var(--tn-color-text);
}

.sgn-card__mark { flex: none; width: 32px; height: 32px; }

.sgn-card__subtitle {
  margin: var(--tn-space-xxs) 0 0;
  max-width: 46ch;
  font-size: var(--tn-text-base);
  line-height: var(--tn-leading-snug);
  color: var(--tn-color-text-muted);
}

/* A hairline between who this is and what you do here. */
.sgn-form {
  margin-top: var(--tn-space-lg);
  padding-top: var(--tn-space-lg);
  border-top: 1px solid var(--tn-color-border);
}

/* The password is the last field; the caps-lock line sets its own spacing. */
.sgn-password.tn-field { margin-bottom: 0; }

/* ---------------------------------------------------------------- failure */

.sgn-error {
  display: flex;
  align-items: flex-start;
  gap: var(--tn-space-sm);
  margin-bottom: var(--tn-space-lg);
  padding: var(--tn-space-sm) var(--tn-space-md);
  background: var(--tn-color-danger-soft);
  border: 1px solid var(--tn-color-danger);
  border-left-width: 4px;
  border-radius: var(--tn-radius-md);
  color: var(--tn-color-danger-soft-ink);
}
.sgn-error:focus { outline: none; }
.sgn-error:focus-visible {
  outline: 3px solid var(--tn-color-focus-ring);
  outline-offset: 2px;
}
/* @tn/ui's alert icon, in the danger ink: the title beside it says it in words. */
.sgn-error__mark {
  flex: none;
  display: inline-flex;
  color: var(--tn-color-danger);
}
.sgn-error__title { margin: 0 0 2px; font-size: var(--tn-text-base); font-weight: var(--tn-weight-semibold); }
.sgn-error__detail { margin: 0; font-size: var(--tn-text-base); }

/* ----------------------------------------------------------------- fields */

/*
 * SUNLIGHT. Scoped to this form, so the capture form's own fields are untouched
 * and the package stylesheet does not change.
 *
 * The shared box is 1px of borderStrong #b4bed0, which theme.ts documents as a
 * structural edge with NO required ratio. At arm's length on a dam crest that
 * edge is not there. borderControl #6b7690 is the hex theme.ts measures because
 * WCAG 1.4.11 asks 3:1 of a control boundary; two pixels of it is the same box
 * every other screen shows, only findable.
 */
.sgn-form .tn-field__box {
  min-height: var(--tn-size-touch);
  border-width: 2px;
  border-color: var(--tn-color-border-control);
}
/* Equal specificity and later in the cascade, so an invalid field keeps its red
   edge on this page. :focus-within is NOT re-declared — the package sets the
   accent colour and glow, and border-WIDTH is a separate property, so the 2px
   survives focus. */
.sgn-form .tn-field--invalid .tn-field__box { border-color: var(--tn-color-danger); }

/* One step up from the platform's field label. theme.ts now sets the floor at
   14px everywhere; this is a two-word caption on the one page every member of
   staff reads cold, so it takes the 15px step. */
.sgn-form .tn-field__label { font-size: var(--tn-text-sm); }
/* The reveal is a full-height cell on the right of the password box. Trimming
   the label to its own width keeps the two from overlapping. */
.sgn-password .tn-field__label { width: fit-content; }

/* The answer is the loud object in the box. 17px is the next step up and stays
   above the 16px floor under which iOS Safari zooms the viewport. */
.sgn-form .tn-field__control > input {
  font-size: var(--tn-text-md);
  font-weight: var(--tn-weight-medium);
}

.sgn-form .tn-field__hint { font-size: var(--tn-text-sm); color: var(--tn-color-text-muted); }

/*
 * THE REVEAL IS A CELL OF THE FIELD, AND IT IS NOW ACTUALLY A CELL.
 *
 * It USED to be position:absolute over the right-hand end of the box while the
 * input kept width:100% underneath it, with 96px of padding-right to keep typed
 * text clear. That is a workaround, not a layout, and it left a real defect on
 * the first screen of the platform at ALL FIVE WIDTHS: 76x26px of the password
 * input sat underneath the button, so a tap near the end of the field hit
 * "Show" instead of placing the caret. Padding cannot fix that; only the input
 * ending where the button begins can.
 *
 * The input and the button are already siblings inside .tn-field__control (see
 * SignInScreen.tsx), so the control is simply a flex row. The input takes the
 * space that is left, the button takes its own, and the two boxes do not
 * intersect at any width.
 *
 * The gap is a real gap. This block used to say gap: 0 because the reveal
 * button was flush to the input and divided from it by a hairline; it is now a
 * rounded chip on a faint accent ground (see .sgn-reveal below, "A GROUND, NOT
 * A DIVIDING LINE"), and a chip pressed against the input's edge reads as a
 * rendering fault. Both declarations were left here, the second overriding the
 * first, which meant the file described a design it no longer had.
 */
.sgn-password .tn-field__control {
  display: flex;
  align-items: stretch;
  gap: var(--tn-space-xs);
}
.sgn-password .tn-field__control > input {
  flex: 1 1 auto;
  min-width: 0;
  width: auto;
  padding-right: var(--tn-space-sm);
}

.sgn-reveal.tn-btn {
  flex: none;
  align-self: stretch;
  min-width: 92px;
  min-height: var(--tn-size-touch);
  padding: 0 var(--tn-space-sm);
  /*
   * A GROUND, NOT A DIVIDING LINE.
   *
   * The absolutely-positioned version could run a hairline the full height of
   * the box because it was pinned to top:0 and bottom:0. A real cell sits
   * inside the box's padding and beside its own row, so a hairline stops short
   * of the box edges and reads as unfinished. A faint accent ground says
   * "second control on this line" without depending on where the box's edges
   * happen to be, and it survives the 44px control height unchanged.
   *
   * It is a button, so it reads the action (button) family, not the page's
   * link blue: the buttons kept their colours when the page went white and
   * dark blue.
   */
  background: var(--tn-color-action-soft);
  color: var(--tn-color-action-soft-ink);
  border-radius: var(--tn-radius-sm);
  font-size: var(--tn-text-base);
  font-weight: var(--tn-weight-semibold);
}
.sgn-reveal.tn-btn:hover {
  background: var(--tn-color-action);
  color: var(--tn-color-action-ink);
}
/* Inset, so the ring stays inside the field box instead of straddling it. */
.sgn-reveal.tn-btn:focus-visible { outline-offset: -3px; }

/* -------------------------------------------------------------- caps lock */

/* Height, not display:none, so the live region stays in the accessibility tree
   and the announcement is made when the text arrives. */
.sgn-caps {
  display: block;
  margin: var(--tn-space-xs) 0 0;
  padding: var(--tn-space-xs) var(--tn-space-sm);
  background: var(--tn-color-warning-soft);
  border-radius: var(--tn-radius-sm);
  font-size: var(--tn-text-sm);
  font-weight: var(--tn-weight-medium);
  color: var(--tn-color-warning-soft-ink);
}
.sgn-caps:empty { margin: 0; padding: 0; height: 0; overflow: hidden; }

/* ----------------------------------------------------------------- submit */

/* FULL WIDTH, ALWAYS. The card is 480px at its widest, which is the measure a
   primary button is allowed to fill without reading as a bar, and a thumb on a
   phone finds an edge-to-edge target without looking. */
.sgn-submit { display: flex; margin-top: var(--tn-space-xl); }

/* The session note closes the card the way the legal line closes the page. */
.sgn-card__note {
  margin: var(--tn-space-lg) 0 0;
  padding-top: var(--tn-space-md);
  border-top: 1px solid var(--tn-color-border);
  font-size: var(--tn-text-sm);
  line-height: var(--tn-leading-snug);
  color: var(--tn-color-text-muted);
}

/* ---------------------------------------------------- the no-access panel */

/* The refusal a signed-in account without report access sees, in the same card
   as the sign-in form: the portal's mark on top, then a hairline, then what is
   wrong and where to go instead (components/no-access.tsx, framed). */
.sgn-noaccess {
  margin-top: var(--tn-space-lg);
  padding-top: var(--tn-space-lg);
  border-top: 1px solid var(--tn-color-border);
  font-size: var(--tn-text-base);
  line-height: var(--tn-leading-snug);
  color: var(--tn-color-text);
}
.sgn-noaccess p, .sgn-noaccess ul { margin: 0; }
.sgn-noaccess .qtr-quiet { font-size: var(--tn-text-sm); color: var(--tn-color-text-muted); }
.sgn-noaccess__title {
  margin: 0;
  font-size: var(--tn-text-lg);
  font-weight: var(--tn-weight-bold);
  line-height: var(--tn-leading-tight);
  color: var(--tn-color-text);
  text-wrap: balance;
}

/* --------------------------------------------------------- under the card */

/* Anything the page wants said beside the form — the sign-out confirmation,
   where this site is. Off the card, so the card stays two fields and a button. */
.sgn-notes {
  width: 100%;
  max-width: 480px;
  font-size: var(--tn-text-sm);
  line-height: var(--tn-leading-snug);
  color: var(--tn-color-text-muted);
}
.sgn-notes p { margin: 0; }
/* The page passes a sign-out confirmation or nothing at all, and "nothing at
   all" is a rendered-but-empty element. Without this it is an invisible 20px of
   flex gap between the card and the notice. */
.sgn-notes:empty { display: none; }

/*
 * The sign-out confirmation is a message, not a footnote: full ink and a rule
 * down its left side, so it is not read as more of the standing small print.
 *
 * The rule is on the LEFT rather than underneath. Underneath it is a divider,
 * and a divider under the last thing on the page reads as the top of a section
 * that never arrives.
 */
.sgn-notes output {
  display: block;
  padding: var(--tn-space-xxs) 0 var(--tn-space-xxs) var(--tn-space-md);
  border-left: 3px solid var(--tn-color-border-control);
  color: var(--tn-color-text);
  font-weight: var(--tn-weight-medium);
}

/* ----------------------------------------------------------- wide layout */

/*
 * The split. The navy is one column of two rows — the department, then the
 * legal line pinned under it — and the card spans both, so the notice sits at
 * the foot of the department's own column rather than floating under the form.
 * The DOM order is brand, main, legal, which is the order a phone stacks them
 * in; the grid does the rearranging, so there is no second copy of any text and
 * nothing is display:none on the screen it was written for.
 */
@media (min-width: 900px) {
  .sgn-page {
    grid-template-columns: minmax(0, 44%) minmax(0, 1fr);
    grid-template-rows: 1fr auto;
  }
  .sgn-brand { grid-column: 1; grid-row: 1; }
  .sgn-legal { grid-column: 1; grid-row: 2; }
  .sgn-main  { grid-column: 2; grid-row: 1 / span 2; padding: var(--tn-space-xxxl); }

  /* The largest step in the scale, used once, on the line that names whose
     system this is. */
  .sgn-brand__title { font-size: var(--tn-text-xxxl); }
}

/*
 * A five-year-old 1366x768 office panel — at the 125% Windows scaling those
 * machines ship with, a ~1093x614 CSS viewport — must not scroll. An official
 * who has to scroll to find the button reads the page as broken. Buy the pixels
 * back from padding and from the gap between features, never from type.
 */
/* The drawing is the first thing to go when the window is short: the page
   must never scroll to reach the button. */
@media (min-width: 900px) and (max-height: 879.98px) {
  .sgn-brand__hero { display: none; }
}

@media (min-width: 900px) and (max-height: 820px) {
  .sgn-brand { padding: var(--tn-space-xxl); }
  .sgn-legal { padding: var(--tn-space-md) var(--tn-space-xxl) var(--tn-space-xxl); }
  .sgn-main  { padding: var(--tn-space-xl) var(--tn-space-xxl); }
  .sgn-brand__title { font-size: var(--tn-text-xxl); }
  .sgn-brand__tile { --sgn-seal: 44px; }
  .sgn-brand__features { margin-top: var(--tn-space-xl); gap: var(--tn-space-md); }
}

/* --------------------------------------------------------- narrow layout */

/*
 * THE PHONE. The navy becomes a masthead: emblem and department name on one
 * row, the tricolour under them, and nothing else. The feature list is what the
 * navy column is FOR on a desktop and is precisely what would push the username
 * field off a 390x844 screen, so it is not rendered here at all — display:none
 * takes it out of the accessibility tree too, which is right: it is decoration
 * for a person who has already decided to sign in.
 */
@media (max-width: 899.98px) {
  .sgn-brand { padding: var(--tn-space-lg) var(--tn-space-md); }
  .sgn-brand__head { flex-direction: row; align-items: center; gap: var(--tn-space-md); }
  .sgn-brand__tile { --sgn-seal: 42px; }
  .sgn-brand__title { font-size: var(--tn-text-lg); }
  .sgn-brand__tagline { margin-top: var(--tn-space-sm); font-size: var(--tn-text-sm); }
  .sgn-brand__rule { margin-top: var(--tn-space-md); max-width: 120px; height: 4px; }
  .sgn-brand__features,
  .sgn-brand__hero,
  .sgn-noaccess .qtr-noaccess__art { display: none; }

  .sgn-main { padding: var(--tn-space-lg) var(--tn-space-md) var(--tn-space-xl); }
  .sgn-card { padding: var(--tn-space-lg); }
  .sgn-legal { padding: var(--tn-space-md) var(--tn-space-md) var(--tn-space-lg); }
}

/* On a phone — or a modern one at 150% text scaling — the emblem tile is 56px
   of a 348px content width that the department name needs more than the emblem
   does. This was a hand-typed 379px, one of ten different breakpoint values in
   the codebase; it is on the scale now like everything else. */
@media (max-width: 639.98px) {
  .sgn-brand__tile { --sgn-seal: 34px; }
  .sgn-card { padding: var(--tn-space-md); }
}

/* --------------------------------------------------------- high contrast */

/* Windows High Contrast is switched on across a real share of government
   desktops. It throws the colours away; these put back the edges that were
   carrying the meaning — without them the navy, the card and the footnote run
   together as one field of Canvas. */
@media (forced-colors: active) {
  .sgn-card,
  .sgn-error,
  .sgn-caps:not(:empty),
  .sgn-brand__tile,
  .sgn-brand__feature-tile { border: 1px solid CanvasText; }
  .sgn-brand { border-bottom: 1px solid CanvasText; }
  .sgn-legal { border-top: 1px solid CanvasText; }
  .sgn-brand__rule { forced-color-adjust: none; }
  .sgn-error__mark { forced-color-adjust: none; }
  .sgn-reveal.tn-btn { border: 1px solid ButtonText; }
  .sgn-notes output { border-left-color: CanvasText; }
}

/* --------------------------------------------------------- more contrast */

@media print {
  .sgn-brand__hero { display: none; }
}

@media (prefers-contrast: more) {
  .sgn-form .tn-field__box { border-color: var(--tn-color-text); }
  .sgn-card__subtitle,
  .sgn-card__note,
  .sgn-notes,
  .sgn-form .tn-field__hint { color: var(--tn-color-text); }
  .sgn-brand__state,
  .sgn-brand__tagline,
  .sgn-legal { color: var(--tn-color-header-ink); }
}
