﻿/* =============================================================================================
   Himalayan Bank — public National ID wizard.

   Design brief, and the two constraints that shaped every decision below:

   1. This page asks a customer for a bank account number, a one-time code, and a photograph of
      their National ID card. Before any of that it has to LOOK like Himalayan Bank's own page.
      So the brand is loud where identity lives (the header rule, the progress bar, the single
      primary action, the reference number) and silent everywhere else.

   2. The brand colour IS red (#AC302E). A red error message on a red-branded page reads as
      *branded*, not as *wrong* -- see the "message and alert system" block below for what is
      used instead, and why there are three treatments rather than one.

   No CDN, no webfont, no build step. Every font named here is one the device already has.
   ============================================================================================= */

:root {
  /* --- brand ------------------------------------------------------------------------------ */
  --hbl-red: #AC302E;          /* identity + the ONE primary action per step. 6.5:1 on white. */
  --hbl-red-deep: #A72C32;     /* the brand's own secondary; kept as declared. */
  --hbl-red-press: #8A2523;    /* hover/active for the primary button. 8.9:1 on white. */
  --hbl-red-wash: #FBF2F1;     /* the faintest brand tint, for identity surfaces only. */

  --hbl-stone: #DBD8D3;
  --hbl-cream: #ECEAE6;
  --hbl-ink: #212529;
  /* Was #777777, which is 4.48:1 on white -- under AA by a hair, and this token carries every
     hint, every field border and the progress label. #6B6B6B is 5.3:1 and 3.2:1 against the
     stone/cream surfaces, so it clears AA as text and 1.4.11 as a control boundary. */
  --hbl-ink-muted: #6B6B6B;
  --hbl-near-black: #1A1A1A;
  --hbl-white: #FFFFFF;

  /* --- the message and alert system -------------------------------------------------------
     Three kinds, three treatments, because they ask the customer for three different things.
     None of them is red, and none of them relies on colour alone: each carries its own icon
     shape and its own 4px left rule, so the treatment survives greyscale, colour-blindness and
     a cheap phone screen in daylight.

       warn   -- "fix this input".      Amber-brown, triangle.  Matches the staff portal's own
                                        destructive treatment (officer-workflow spec D20), so the
                                        two HBL apps agree on what "not-brand-red trouble" is.
       notice -- "we could not do that". Slate, circled bar.    Nothing on this screen to retype;
                                        the failure is ours or the session's, not the customer's.
       ok     -- "that worked".          Green, check.

     Contrast, message text on its own background: warn 5.5:1, notice 7.8:1, ok 5.8:1. */
  --hbl-warn: #8A5A00;
  --hbl-warn-bg: #FDF6E7;
  --hbl-warn-line: #E3D2A8;

  --hbl-notice: #3E4C59;
  --hbl-notice-bg: #EEF1F4;
  --hbl-notice-line: #CBD4DC;

  --hbl-ok: #1F6B3B;
  --hbl-ok-bg: #EAF4EE;
  --hbl-ok-line: #BCDCC8;

  /* --- type -------------------------------------------------------------------------------
     ONE list, both scripts, no webfont. A font-family list resolves PER CHARACTER, so Latin
     glyphs are found in the first face that has them (Segoe UI / Roboto / SF) and Devanagari
     glyphs -- which none of those Latin faces contain -- fall through to the Devanagari faces
     named after them. The generic `sans-serif` is LAST on purpose: a generic always matches, so
     anything after it is unreachable, which is exactly the bug that would silently hand Nepali
     back to the browser default.

     Verdana (the previous stack) has no Devanagari coverage at all and is unusually wide, which
     costs about six characters per line at 360px. Both reasons to drop it. */
  --hbl-font:
    system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial,
    "Noto Sans Devanagari", "Nirmala UI", "Kohinoor Devanagari", "Mukta", "Mangal", "Kalimati",
    sans-serif;

  --hbl-tap-target: 48px;      /* was 44px; 48px is the Android/Material floor and easier one-handed */
  --hbl-radius: 10px;
  --hbl-radius-sm: 6px;
  --hbl-shadow: 0 1px 2px rgba(26, 26, 26, 0.05), 0 8px 24px rgba(26, 26, 26, 0.06);

  /* The card's horizontal padding, as a variable because the sticky action bar has to cancel it
     exactly (negative margin out, padding back in) to span the card edge to edge. Hard-coding it
     in two places is how that seam gets a half-centimetre of white down each side the first time
     one of them changes. */
  --hbl-card-pad: 1.25rem;

  /* Bottom inset for the sticky action bar. Both layouts render on phones and the embedded one
     sets viewport-fit=cover, so on a notched iPhone the bar would otherwise sit under the home
     indicator, where the primary action of every step is unreachable. */
  --hbl-safe-bottom: env(safe-area-inset-bottom, 0px);
}

@media (min-width: 30rem) { :root { --hbl-card-pad: 1.75rem; } }

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--hbl-font);
  color: var(--hbl-ink);
  background: var(--hbl-cream);
  font-size: 1.0625rem;        /* 17px: 16px is the iOS zoom floor, and this is a form for adults */
  line-height: 1.55;
  -webkit-text-size-adjust: 100%;
  /* Review finding C1: the language control now renders inside #wizard-form (in <main>), not in
     <header>, so it can no longer be positioned with normal flow/flex layout relative to the
     header. `position: relative` here establishes body as the containing block its own
     `position: absolute` resolves against, so `top`/`right` below are relative to the top of the
     page -- exactly where the header already sits -- regardless of which panel actually rendered
     the control. */
  position: relative;
}

/* --- Devanagari metrics -------------------------------------------------------------------
   Devanagari is not Latin with different glyphs. Three things break if it is treated as such,
   and all three are fixed here rather than by guessing a single line-height that suits neither:

   1. LEADING. The shirorekha (headline) sits above the x-height, i-matras rise above it again,
      and u/uu-matras and stacked conjuncts (क्ष, त्र, द्ध) descend well below the baseline. A
      1.55 line box crowds consecutive lines until the descenders of one touch the headline of
      the next. 1.8 for body text, 1.45 for headings, is the smallest that stays clear.

   2. LETTER-SPACING. Tracking is not decorative in Devanagari -- it cuts the shirorekha, which
      is a continuous stroke ACROSS the letters of a word. Any `letter-spacing` on Devanagari
      visually shatters the word. Every tracked rule in this file is therefore reset below.

   3. TEXT-TRANSFORM. Devanagari is unicameral. `uppercase` does nothing to it but does still
      affect any Latin (an account mask, a reference number) inside the same run, so it is turned
      off rather than left to apply unevenly.

   Selected on `html[lang="ne"]`, which both layouts already emit from the resolved UI culture --
   so this costs no markup, no class and no script.

   Note the ONE case this deliberately does not cover: the language-switch button always renders
   the OTHER language's name, so "नेपाली" appears on the English page. `.btn` below carries enough
   line-height for a single Devanagari line at any width, and buttons never clip, so it needs no
   lang-specific rule of its own. */
html[lang="ne"] body { line-height: 1.8; }
html[lang="ne"] h1,
html[lang="ne"] h2 { line-height: 1.45; }
html[lang="ne"] .summary__label { letter-spacing: normal; text-transform: none; }

h1 {
  font-size: 1.5rem;
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin: 0 0 0.5rem;
}
/* wizard.js focuses the heading on every fragment swap (announce()), so it does show a ring --
   for keyboard and AT users only, per :focus-visible, never as a stray outline after a tap. A
   little more offset than the page default because a heading's own descenders sit close to it.
   The pseudo-class is required, not decorative: a bare `h1 { outline-offset }` loses to the
   page-wide `:focus-visible` rule on specificity and would silently do nothing. */
h1:focus-visible { outline-offset: 4px; }
html[lang="ne"] h1 { letter-spacing: normal; }

p { margin: 0 0 0.875rem; }
p:last-child { margin-bottom: 0; }

a { color: var(--hbl-red-press); text-underline-offset: 0.2em; }
a:hover { color: var(--hbl-red); }

/* One focus treatment for the whole page, so a restyle cannot quietly delete it from one
   control. 3px near-black at a 2px offset reads at 15:1 against every surface used here --
   including the brand-red button, where a red ring would be invisible. */
:focus-visible {
  outline: 3px solid var(--hbl-near-black);
  outline-offset: 2px;
  border-radius: 2px;
}

/* --- wizard ------------------------------------------------------------- */

.wizard {
  max-width: 34rem;            /* ~66 Latin characters at 17px: a comfortable measure, not a page */
  margin: 0 auto;
  padding: 1.25rem 1rem 7rem;
  /* Restated so a browser that does not understand env() keeps the plain 7rem above rather than
     dropping the whole shorthand and letting the sticky bar sit on top of the last field. */
  padding-bottom: calc(7rem + var(--hbl-safe-bottom));
}

.wizard__progress-track {
  height: 6px; background: var(--hbl-stone); border-radius: 3px; overflow: hidden;
}
.wizard__progress-fill {
  height: 100%; background: var(--hbl-red); border-radius: 3px; transition: width 300ms ease;
}
.wizard__progress-label {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 0.875rem; color: var(--hbl-ink-muted); margin-bottom: 0.5rem;
}
/* The step counter is the customer's answer to "how much longer is this?", so it is the one
   thing on the label line that is not muted. */
.wizard__progress-label > span:first-child { color: var(--hbl-ink); font-weight: 600; }

.card {
  background: var(--hbl-white); border: 1px solid var(--hbl-stone);
  border-radius: var(--hbl-radius); padding: 1.5rem var(--hbl-card-pad); margin-top: 1.25rem;
  box-shadow: var(--hbl-shadow);
}

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

.field { margin-bottom: 1.5rem; }
.field__label { display: block; font-weight: 600; margin-bottom: 0.4375rem; }
.field__input {
  width: 100%;
  min-width: 0;                /* lets an input shrink inside a flex row instead of overflowing */
  min-height: var(--hbl-tap-target);
  padding: 0.75rem 0.875rem; font: inherit; color: inherit;
  background: var(--hbl-white);
  border: 1px solid var(--hbl-ink-muted); border-radius: var(--hbl-radius-sm);
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.field__input:hover { border-color: var(--hbl-ink); }
.field__input:focus { border-color: var(--hbl-ink); }

/* State is never colour alone: an invalid field also thickens its border and gains a left rule
   in the same amber the alert above it uses, so the two read as one thing to fix. */
.field__input[aria-invalid="true"] {
  border-color: var(--hbl-warn);
  border-width: 2px;
  border-left-width: 5px;
  background: var(--hbl-warn-bg);
}

/* .field__error is the message paragraph INSIDE an alert block (see _Alert.cshtml). It keeps
   this historical name because Step1Tests.ExtractErrorRegion isolates the error by exactly this
   selector to compare two renders byte for byte -- renaming it would break a real assertion for
   a cosmetic reason. It inherits its colour from the alert wrapper, which is what actually
   decides which of the three treatments applies. */
.field__error { color: inherit; margin: 0; }

.field__hint { color: var(--hbl-ink-muted); font-size: 0.9375rem; margin-top: 0.5rem; }

/* ---- Uploaded document preview -------------------------------------------------------------
   Filled by wizard.js from the file that will actually be sent, so what the customer checks is
   what the bank receives. [hidden] is honoured explicitly: a display rule on .preview would beat
   the attribute's own UA style and the element would show up empty before a file is chosen. */
.preview[hidden] { display: none; }

.preview {
    margin: 0.75rem 0 0;
    padding: 0.5rem;
    border: 1px solid var(--hbl-rule);
    border-radius: 6px;
    background: var(--hbl-surface-muted, #f7f7f8);
}

.preview__image {
    display: block;
    /* Bounded in BOTH directions. A tall portrait photograph constrained only by width pushes the
       consent checkbox and the submit button off the screen on a phone, which is the control this
       preview is supposed to help the customer reach. */
    max-width: 100%;
    max-height: 15rem;
    margin: 0 auto;
    border-radius: 4px;
}

.preview__caption {
    margin-top: 0.5rem;
    color: var(--hbl-ink-muted);
    font-size: 0.875rem;
    text-align: center;
    /* The file name is the customer's own and can be arbitrarily long; wrapping it is preferable
       to a caption that widens the panel on a narrow screen. */
    overflow-wrap: anywhere;
}

/* One input styled to look segmented. Six separate inputs break OS autofill, so this must
   stay a single field however it looks. */
.otp-input {
  font-size: 1.75rem; letter-spacing: 0.75em; text-indent: 0.75em;
  text-align: center; font-variant-numeric: tabular-nums;
  padding-left: 0.5rem; padding-right: 0.5rem;
}

/* --- buttons -------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.375rem;
  min-height: var(--hbl-tap-target); padding: 0.6875rem 1.25rem;
  font: inherit; font-weight: 600; line-height: 1.4;
  border-radius: var(--hbl-radius-sm); border: 1px solid transparent;
  text-decoration: none; text-align: center; cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}

.btn--primary { background: var(--hbl-red); color: var(--hbl-white); }
.btn--primary:hover { background: var(--hbl-red-press); color: var(--hbl-white); }
.btn--primary:active { background: var(--hbl-red-press); }
.btn--primary:disabled { opacity: 0.6; cursor: default; }
/* wizard.js sets aria-busy on the in-flight submit button. Marked visually as well as in the
   accessibility tree, because on a slow connection this is the only feedback there is. */
.btn--primary[aria-busy="true"] { background: var(--hbl-red-press); opacity: 0.75; cursor: progress; }

.btn--secondary {
  background: var(--hbl-white); color: var(--hbl-ink); border-color: var(--hbl-ink-muted);
}
.btn--secondary:hover { background: var(--hbl-cream); color: var(--hbl-ink); }

/* The primary action of every step is docked to the bottom of the viewport on phones, where the
   card is often taller than the screen. Back stays its natural width; Continue takes the rest,
   so the action a customer wants 95% of the time is the biggest target on the screen. */
.wizard__actions {
  display: flex; align-items: stretch; gap: 0.75rem; margin-top: 1.75rem;
}
/* Several panels render an empty <span> as a spacer where a Back button would go. It has no job
   in a flex row that already distributes space, and it would add a phantom gap. */
.wizard__actions > span:empty { display: none; }
.wizard__actions .btn--secondary { flex: 0 0 auto; }
.wizard__actions .btn--primary { flex: 1 1 auto; }

@media (max-width: 39.999rem) {
  .wizard__actions {
    position: sticky; bottom: 0; z-index: 3;
    background: var(--hbl-white);
    margin-left: calc(var(--hbl-card-pad) * -1); margin-right: calc(var(--hbl-card-pad) * -1);
    padding: 0.875rem var(--hbl-card-pad);
    padding-bottom: calc(0.875rem + var(--hbl-safe-bottom));
    border-top: 1px solid var(--hbl-stone);
    box-shadow: 0 -6px 16px rgba(26, 26, 26, 0.06);
  }
}
@media (min-width: 40rem) {
  .wizard__actions .btn--primary { flex: 0 0 auto; margin-left: auto; }
}

/* --- captcha -------------------------------------------------------------- */

/* Stacked by default. Side by side, the 160px image plus an input at its intrinsic width
   overflows a 360px viewport inside the card's padding -- a horizontal scrollbar on the very
   first screen of the wizard. It only goes back to a row once there is room for one. */
.captcha { display: flex; flex-direction: column; align-items: flex-start; gap: 0.625rem; }
.captcha__image {
  border: 1px solid var(--hbl-stone); border-radius: var(--hbl-radius-sm);
  background: var(--hbl-white); max-width: 100%; height: auto;
  /* Never shrinks. A flex item's default is `flex: 0 1 auto`, so in the side-by-side row below
     the browser would happily take the overflow out of the CAPTCHA -- shrinking the one element
     on the page whose entire job is to be readable, in order to make room for a text box that
     shrinks harmlessly. The input carries min-width: 0 (see .field__input) so it absorbs it all. */
  flex: 0 0 auto;
  /* The CAPTCHA is a puzzle, not decoration: a surface of its own so it does not read as part of
     the field below it. content-box is the point of this rule, not an afterthought -- the <img>
     carries width="160" height="56" attributes, and under the page-wide border-box those would
     have the padding eaten OUT of the 160px, scaling an already-small puzzle down to 152px and
     making it harder to read. content-box adds the padding around it instead. */
  box-sizing: content-box;
  padding: 0.25rem;
}
@media (min-width: 26rem) {
  .captcha { flex-direction: row; align-items: center; gap: 0.75rem; }
  .captcha .field__input { flex: 1 1 auto; }
}

/* --- browser shell ------------------------------------------------------- */

.site-header {
  background: var(--hbl-white);
  /* The brand as a rule under the masthead: identity without turning a form into a poster. */
  border-bottom: 3px solid var(--hbl-red);
}
/* Review finding C1: this class is now shared between an EMPTY placeholder in _Layout.cshtml's
   <header> (reserving the bar's vertical space so .site-header__main doesn't ride up over it) and
   the language-switch control itself (_LanguageSwitch.cshtml), which carries this class too and
   is absolutely positioned on top of the placeholder -- see .language-switch below. min-height
   guarantees both render at the identical height regardless of which one actually has content. */
.site-header__utility {
  background: var(--hbl-near-black); color: var(--hbl-white);
  font-size: 0.8125rem; padding: 0.25rem 1rem;
  display: flex; align-items: center; justify-content: flex-end; gap: 1rem;
  min-height: var(--hbl-tap-target);
}
.site-header__main {
  display: flex; align-items: center; justify-content: space-between;
  padding: 1rem; max-width: 72rem; margin: 0 auto;
}
.breadcrumb {
  background: var(--hbl-white); padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--hbl-stone);
  font-size: 0.875rem; color: var(--hbl-ink-muted);
}
/* The band runs edge to edge; only its content is held to the masthead's measure, so the
   breadcrumb's first character lines up with the logo. */
.breadcrumb__inner { max-width: 72rem; margin: 0 auto; }
.site-footer {
  background: var(--hbl-stone); padding: 2rem 1rem; margin-top: 3rem;
  font-size: 0.875rem;
}
.site-footer > div { max-width: 72rem; margin: 0 auto; }
.site-footer__bar {
  background: var(--hbl-near-black); color: var(--hbl-white);
  padding: 0.875rem 1rem; font-size: 0.8125rem;
}

/* --- embedded shell ------------------------------------------------------ */

.embedded-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.75rem 1rem; background: var(--hbl-white);
  border-bottom: 3px solid var(--hbl-red);
  /* Review finding C1: this row used to hold both the logo and the language control side by
     side; the control is now absolutely positioned back into the same top-right corner (see
     .language-switch--embedded below) rather than being a flex child, so this reserves the same
     row height the button used to contribute, keeping the logo vertically centred where it was. */
  min-height: calc(var(--hbl-tap-target) + 1.5rem);
}

/* --- language switch (review finding C1) ---------------------------------

   This control now renders inside each panel's #wizard-form (in <main>), after that panel's own
   primary submit button, so it is never #wizard-form's default HTML button -- see
   _LanguageSwitch.cshtml's remarks. It is pulled back to its old visual position with
   `position: absolute` against `body` (see body's own `position: relative` above), so nothing
   looks different to a customer who never presses Enter. */

.language-switch { display: flex; align-items: center; }

/* Browser shell: this element also carries .site-header__utility (shared class, see its own
   rule), so it already has the black-bar background/padding/flex layout -- only positioning is
   added here, overlaid exactly on top of the empty placeholder _Layout.cshtml's <header> reserves
   at the same top:0 coordinate. */
.language-switch.site-header__utility {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 4;
}

/* Embedded shell: no background bar in the original design, just the button sitting in the
   header row's top-right corner -- reproduced directly with top/right matching
   .embedded-header's own padding. */
.language-switch--embedded {
  position: absolute;
  top: 0.75rem; right: 1rem;
  z-index: 4;
}

/* The switch is a real control, not a link: it must be reachable one-handed and legible in
   Devanagari, which is what it renders on the English page. On the black utility bar it is
   drawn as an outline button so it does not disappear into the bar. */
.language-switch .btn {
  min-height: 2.25rem; padding: 0.25rem 0.875rem;
  font-size: 0.9375rem; line-height: 1.6;
}
.language-switch.site-header__utility .btn--secondary {
  background: transparent; color: var(--hbl-white); border-color: rgba(255, 255, 255, 0.55);
}
.language-switch.site-header__utility .btn--secondary:hover {
  background: rgba(255, 255, 255, 0.12); color: var(--hbl-white);
}
.language-switch.site-header__utility :focus-visible { outline-color: var(--hbl-white); }

/* --- alerts: the three message treatments ---------------------------------

   Server-rendered, always. This block is the PRIMARY presentation of every message in the
   wizard and it exists in the HTML the server sends -- there is a full no-script suite
   (NoScriptFallbackTests) that walks the wizard end to end with scripting off, and error text is
   the only way that customer learns what went wrong. The toast at the bottom of this file is an
   echo of this block and never a replacement for it.

   Each kind carries an icon (shape), a 4px left rule (position), a tinted background (surface)
   and a colour. Any one of those four alone identifies it; colour is never doing the work by
   itself. */

.alert {
  display: flex; align-items: flex-start; gap: 0.75rem;
  margin: 0 0 1.25rem;
  padding: 0.875rem 1rem;
  border: 1px solid;
  border-left-width: 4px;
  border-radius: var(--hbl-radius-sm);
  font-size: 1rem;
}

.alert__icon {
  flex: 0 0 auto; width: 1.375rem; height: 1.375rem;
  /* 1.375rem tall icon on a 1.55 line box: nudged down so it sits on the first line's optical
     centre rather than its top edge. */
  margin-top: 0.125rem;
}
html[lang="ne"] .alert__icon { margin-top: 0.3125rem; }

.alert__body { min-width: 0; }

/* "Fix this input." */
.alert--warn {
  color: var(--hbl-warn);
  background: var(--hbl-warn-bg);
  border-color: var(--hbl-warn-line);
  border-left-color: var(--hbl-warn);
}

/* "We could not do that." Nothing on this screen to retype. */
.alert--notice {
  color: var(--hbl-notice);
  background: var(--hbl-notice-bg);
  border-color: var(--hbl-notice-line);
  border-left-color: var(--hbl-notice);
}

/* "That worked." */
.alert--ok {
  color: var(--hbl-ok);
  background: var(--hbl-ok-bg);
  border-color: var(--hbl-ok-line);
  border-left-color: var(--hbl-ok);
}

/* The session-expiry page has no field to fix, so the whole card wears the notice treatment
   rather than carrying a block inside it. */
.notice-head {
  display: flex; align-items: flex-start; gap: 0.75rem;
  color: var(--hbl-notice); margin-bottom: 0.75rem;
}
.notice-head__icon { flex: 0 0 auto; width: 1.75rem; height: 1.75rem; margin-top: 0.0625rem; }
.notice-head h1 { margin: 0; color: var(--hbl-ink); }

/* --- motion -------------------------------------------------------------- */

.wizard__panel { animation: fade-in 200ms ease; }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* --- step 3, panel A: the declaration fork ------------------------------- */

.choice { display: flex; flex-direction: column; gap: 0.625rem; margin-bottom: 1.5rem; }

/* The whole option is the label, so the tap target is the row rather than the radio itself --
   min-height matches every other control's --hbl-tap-target. */
.choice__option {
  display: flex; align-items: flex-start; gap: 0.75rem;
  border: 1px solid var(--hbl-ink-muted); border-radius: var(--hbl-radius-sm);
  padding: 1rem; background: var(--hbl-white); cursor: pointer;
  min-height: var(--hbl-tap-target);
  transition: border-color 120ms ease, background-color 120ms ease;
}
.choice__option:hover { background: var(--hbl-cream); }

/* :focus-within, not :focus -- the focusable element is the radio inside, but the ring has to
   read as belonging to the row a keyboard user is actually on. */
.choice__option:focus-within {
  outline: 3px solid var(--hbl-near-black); outline-offset: 2px;
}

/* :has() is progressive: where it is unsupported the radio dot alone still shows the choice,
   which is the browser's own affordance and never depended on this. Where it is supported the
   whole row changes weight and border as well, so the selection is legible at arm's length. */
.choice__option:has(input:checked) {
  border-color: var(--hbl-red); border-width: 2px; padding: calc(1rem - 1px);
  background: var(--hbl-red-wash); font-weight: 600;
}

.choice__option input {
  margin-top: 0.15rem; width: 1.25rem; height: 1.25rem; accent-color: var(--hbl-red);
  flex: 0 0 auto;
}

/* --- step 3, panel B: capture and consent -------------------------------- */

/* The upload is where customers fail, so the control is a framed zone with a picture of the
   job rather than a bare file input. The <input> itself is untouched in every way that matters
   -- type, name, accept and capture="environment" all still ask for the rear camera, and with
   scripting off the whole thing is still one plain file field inside one plain multipart form. */
.capture-zone {
  border: 2px dashed var(--hbl-ink-muted);
  border-radius: var(--hbl-radius);
  background: var(--hbl-cream);
  padding: 1rem;
  text-align: center;
}
.capture-zone:hover { border-color: var(--hbl-ink); background: var(--hbl-white); }
/* The ring belongs to the zone, because the focusable thing inside it fills the zone. */
.capture-zone:focus-within { outline: 3px solid var(--hbl-near-black); outline-offset: 2px; }

/* The framing diagram. It says, without words and therefore identically in both languages,
   exactly what the hint underneath says: hold the card flat, fill the frame, keep the text
   readable. aria-hidden in the markup -- the hint is its text equivalent. */
.capture-zone__guide {
  display: block; width: 100%; max-width: 15rem; height: auto; margin: 0 auto 0.875rem;
}

.capture {
  display: block; width: 100%; min-height: var(--hbl-tap-target);
  border: 0; background: transparent; padding: 0;
  font: inherit; color: var(--hbl-ink);
  cursor: pointer;
}
/* The one part of a file input a page is allowed to style. Made a full-width button, because on
   a phone this is the thing the customer taps to open the camera. */
.capture::file-selector-button {
  display: block; width: 100%; min-height: var(--hbl-tap-target);
  margin: 0 0 0.5rem; padding: 0.6875rem 1rem;
  font: inherit; font-weight: 600;
  color: var(--hbl-red); background: var(--hbl-white);
  border: 2px solid var(--hbl-red); border-radius: var(--hbl-radius-sm);
  cursor: pointer;
}
.capture::file-selector-button:hover { background: var(--hbl-red-wash); }

/* The same rule again for WebViews that predate ::file-selector-button (Safari/iOS before 14.1,
   and the Android System WebView on devices that stopped updating -- both of which are ordinary
   customer hardware in Nepal). It has to be a SEPARATE rule, not another selector in the list
   above: one unrecognised pseudo-element invalidates the whole selector list, which would drop
   the styling on modern browsers too in order to serve old ones. */
.capture::-webkit-file-upload-button {
  display: block; width: 100%; min-height: var(--hbl-tap-target);
  margin: 0 0 0.5rem; padding: 0.6875rem 1rem;
  font: inherit; font-weight: 600;
  color: var(--hbl-red); background: var(--hbl-white);
  border: 2px solid var(--hbl-red); border-radius: var(--hbl-radius-sm);
  cursor: pointer;
}

.consent {
  margin-bottom: 1.5rem; padding: 1rem;
  background: var(--hbl-cream); border-radius: var(--hbl-radius-sm);
}

.consent__label {
  display: flex; gap: 0.75rem; align-items: flex-start;
  font-size: 0.9375rem; line-height: 1.6; cursor: pointer;
}
html[lang="ne"] .consent__label { line-height: 1.85; }

.consent__label input {
  margin-top: 0.15rem; width: 1.25rem; height: 1.25rem; accent-color: var(--hbl-red);
  flex: 0 0 auto;
}

/* --- step 4 confirmation -------------------------------------------------- */

.summary__label {
  font-size: 0.8125rem; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--hbl-ink-muted); margin-bottom: 0.25rem;
}

/* user-select: all so ONE tap selects the whole reference on a phone, where a customer is
   most likely trying to copy it into a message to themselves. Do not soften this to `text`:
   a partial selection of a reference number is worse than none, because it looks complete. */
.summary__reference {
  font-size: 1.75rem; font-weight: bold; color: var(--hbl-red);
  user-select: all; margin-bottom: 1.25rem; overflow-wrap: anywhere;
  font-variant-numeric: tabular-nums; letter-spacing: 0.01em; line-height: 1.3;
}

/* The reference is the one thing the customer must keep, so it gets a surface of its own that
   reads as "this is the receipt" rather than as another paragraph. */
.summary {
  border: 1px solid var(--hbl-stone); border-left: 4px solid var(--hbl-red);
  border-radius: var(--hbl-radius-sm); background: var(--hbl-red-wash);
  padding: 1rem; margin: 0 0 1.25rem;
}
.summary .summary__reference { margin-bottom: 0; }

/* --- the National ID already on file -------------------------------------
   Deliberately NOT .summary__reference, though it is the same kind of object: a number the
   customer has to read carefully, character by character, off a screen. Two differences decide
   it.

   It is not brand red and has no red-washed surface. Red here would read as "your receipt" on a
   page whose message is "there is nothing to do, and if this is wrong, go to a branch" -- the
   customer has not achieved anything and should not be congratulated. Ink, on the card's own
   background, is the honest weight.

   user-select: all, for the same reason the reference has it: on a phone, one tap takes the whole
   number into a message to themselves or to the branch, and a partial selection of an ID number
   is worse than none because it still looks complete.

   tabular-nums matters more here than anywhere else in this stylesheet. This is the one number a
   customer is expected to COMPARE, digit by digit, against a card in their other hand, and
   proportional figures make 1 and 7 and a dash-separated group of three misalign just enough to
   make that comparison unreliable. */
.nid-recorded {
  font-size: 1.5rem; font-weight: bold; color: var(--hbl-ink);
  font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
  user-select: all; overflow-wrap: anywhere;
  margin: 0 0 1rem;
}

/* --- toast: progressive enhancement, never the only presentation -----------
   Built by wizard.js from an alert block that is ALREADY in the server-rendered page. With
   scripting off none of this exists and nothing is lost: the alert is still there, in the
   markup, above the field. Hand-written in about forty lines rather than pulling toastr or
   Bootstrap from a CDN -- this is a DMZ page holding an account number and it fetches nothing
   from anyone. */

.toasts {
  position: fixed;
  left: 0.75rem; right: 0.75rem;
  /* Above the sticky action bar, never over it: covering the primary button with a message
     about why the last press failed is the one place a toast can do real harm. */
  bottom: calc(var(--hbl-tap-target) + 2.25rem + var(--hbl-safe-bottom));
  z-index: 20;
  display: flex; flex-direction: column; gap: 0.5rem;
  pointer-events: none;        /* the region never intercepts a tap meant for the form */
}
@media (min-width: 40rem) {
  .toasts { left: auto; right: 1.25rem; width: 24rem; }
}

.toast {
  display: flex; align-items: flex-start; gap: 0.75rem;
  padding: 0.875rem 1rem;
  border: 1px solid; border-left-width: 4px; border-radius: var(--hbl-radius-sm);
  box-shadow: 0 6px 24px rgba(26, 26, 26, 0.18);
  font-size: 1rem;
  pointer-events: auto;        /* ...but a toast itself can be tapped to dismiss */
  cursor: pointer;
  opacity: 0;
  transform: translateY(0.75rem);
  transition: opacity 220ms ease, transform 220ms ease;
}
.toast--in { opacity: 1; transform: translateY(0); }

.toast--warn { color: var(--hbl-warn); background: var(--hbl-warn-bg); border-color: var(--hbl-warn-line); border-left-color: var(--hbl-warn); }
.toast--notice { color: var(--hbl-notice); background: var(--hbl-notice-bg); border-color: var(--hbl-notice-line); border-left-color: var(--hbl-notice); }
.toast--ok { color: var(--hbl-ok); background: var(--hbl-ok-bg); border-color: var(--hbl-ok-line); border-left-color: var(--hbl-ok); }

.toast .alert__icon { margin-top: 0.125rem; }
.toast__text { min-width: 0; }

/* --- reduced motion -------------------------------------------------------
   Every transition and animation this stylesheet introduces is listed here. A customer who has
   asked their device for less motion gets the same page with none of it -- not a degraded one. */
@media (prefers-reduced-motion: reduce) {
  .wizard__panel { animation: none; }
  .wizard__progress-fill { transition: none; }
  .field__input,
  .btn,
  .choice__option { transition: none; }
  .toast { transition: none; transform: none; opacity: 1; }
}

/* --- forced colours -------------------------------------------------------
   Windows High Contrast discards every background and border COLOUR declared above and substitutes
   system ones, so the three message treatments stop being three colours. They do not stop being
   three messages: the border is still drawn (forced to a system colour, but still 4px on the left
   and 1px elsewhere) and the icons are unaffected. That is the whole reason each kind carries its
   own icon shape rather than only its own colour.

   The one thing forcing does NOT rescue is the progress fill, whose only content is a background:
   forced to the same system colour as its track, the bar and the track become one flat rectangle
   and the customer loses the answer to "how much longer is this?". */
@media (forced-colors: active) {
  .wizard__progress-fill { background: Highlight; }
}

/* --- masthead ------------------------------------------------------------
   The logo carries width and height attributes in both layouts so the masthead reserves its space
   before the file arrives (see _Layout.cshtml). These keep it from overflowing a 360px viewport if
   anyone ever raises those numbers, and keep the ratio honest if only one of them is changed. */
.site-header__main img,
.embedded-header img { max-width: 100%; height: auto; }
