/* ============================================================
   XC EXCHANGE — AUTH SURFACE
   Scoped to Views/Account/* via _LayoutAuth.cshtml.

   Additive to XC_Home_v4.css, which is loaded first and owns every
   token and the .btn system. Nothing here redefines a token; nothing
   here is loaded by any other surface.

   THE FORM — a full-viewport split, 60 / 40. The left plate is the
   photograph under a navy scrim: the mark and the way back at the top,
   the promise across the middle, and on the signup path the stamped
   ladder of steps already banked. The right panel is the ask: one
   column, one heading, the fields, one full-width action.

   No masthead and no footer. An account screen has exactly one job and
   every other destination on the site is a way to leave it unfinished;
   the mark on the plate is the way home, and it is the only one.

   Why the ladder survives the redesign: the signup path contains an
   AML-mandated identity check, and the only honest way to make that
   feel survivable is to show the visitor what they have already banked.
   ============================================================ */

/* ============================================================
   THE SPLIT
   100dvh, not 100vh: on iOS Safari the URL bar makes 100vh taller
   than the screen, which would push the submit button under the
   chrome on exactly the screens that can least afford it.
   ============================================================ */
html:has(body.authsurface) { height: 100%; }

body.authsurface {
  height: 100%;
  margin: 0;
  overflow: hidden;
  background: var(--surface);
}

.authsplit {
  display: grid;
  /* 60 / 40. fr rather than percentages so the gap-free split cannot
     round into a seam at fractional device pixel ratios. */
  grid-template-columns: 60fr 40fr;
  width: 100%;
  height: 100dvh;
  overflow: hidden;
}

/* ============================================================
   THE PLATE — left 60%
   ============================================================ */
.authvisual {
  position: relative;
  /* the scrim and the grain sit at z-index -1; isolation keeps them
     from escaping under the panel */
  isolation: isolate;
  display: flex;
  flex-direction: column;
  gap: clamp(1.25rem, .6rem + 1.6vw, 2.25rem);
  padding: clamp(1.6rem, .9rem + 2.2vw, 3.25rem);
  overflow: hidden;
  color: var(--on-navy);

  background-color: var(--navy-deep);
  background-image: url("images/auth-bg.png?v=20260827_mark");
  background-size: cover;
  /* The source is portrait -- 1123x1401, 0.80 -- and the column is
     landscape, so cover spends the difference on height: 16.5% of the
     frame at 16:10, 24.9% at 16:9. Centred, that loss is split evenly
     and the frame reads as a natural crop. Biasing it to protect one
     end only moves the whole loss onto the other, and contain removes
     it at the cost of bare margin down both sides -- both were tried
     and both read worse than an even crop. X is centred too: there is
     only horizontal overflow on windows taller than 3:4. */
  background-position: 50% 50%;
  background-repeat: no-repeat;
}

/* The scrim. Three layers, painted front to back: an amber bloom from
   the top-left corner -- the light the stamp is issued under -- then a
   vertical ramp that buries the foot of the frame so the legal line and
   the banner have a ground, then a horizontal ramp that darkens the
   near edge where the panel's white begins. Everything on the plate is
   read against the second layer, which is what carries the contrast. */
.authvisual::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(115% 80% at 6% -8%, rgba(255, 191, 0, .13), transparent 56%),
    linear-gradient(180deg,
      rgba(0, 6, 46, .70) 0%,
      rgba(0, 6, 46, .20) 28%,
      rgba(0, 6, 46, .52) 66%,
      rgba(0, 6, 46, .90) 100%),
    linear-gradient(94deg,
      rgba(0, 10, 77, .40) 0%,
      rgba(0, 6, 46, .08) 55%,
      rgba(0, 6, 46, .48) 100%);
}

/* the grain a large dark field needs to not read as flat fill */
.authvisual::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    radial-gradient(circle at 1px 1px, rgba(221, 225, 247, .055) 1px, transparent 0);
  background-size: 4px 4px;
}

/* ---- the mark and the way out ----------------------------- */
.authvisual-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex: 0 0 auto;
}

.authmark {
  display: block;
  text-decoration: none;
  flex: 0 0 auto;
  border-radius: var(--r);
}
/* The mark is sized by height, and the artwork changes what a given
   height buys: the old lockup was 240x60 (4.0:1), newlogo-white is
   1000x222 (4.5:1) with the baked tagline cut off, so the wordmark
   itself fills the box instead of sharing it with a second line. This
   is also the only masthead the surface has -- there is no bar above
   it -- so it is allowed to read as one. */
.authmark img {
  display: block;
  height: clamp(62px, 4.2vw, 92px);
  width: auto;
}
.authmark:focus-visible {
  outline: 2px solid var(--accent-fill);
  outline-offset: 6px;
}

/* The only navigation on the surface. A hairline pill rather than a
   plain link: on a photograph a bare underline has nothing to sit on. */
.authback {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  flex: 0 0 auto;
  padding: .5rem .85rem;
  border: 1px solid rgba(0, 6, 46, .12);
  border-radius: var(--r);
  /* solid white, so the ink flips to the accent navy -- on a
     photograph a white chip is its own ground and needs no blur
     behind it, which is why backdrop-filter comes off */
  background: #FFFFFF;
  box-shadow: 0 1px 2px rgba(0, 6, 46, .2);
  font-family: var(--f-ui);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  color: var(--accent-ink);
  text-decoration: none;
  transition: box-shadow .2s ease, border-color .18s ease,
    transform .16s cubic-bezier(.22, .75, .2, 1);
}
.authback svg { width: 15px; height: 15px; flex: 0 0 auto; }
/* the face is already white, so the hover has to come from the lift
   rather than from a colour change */
.authback:hover {
  border-color: rgba(0, 6, 46, .3);
  box-shadow: 0 4px 12px -4px rgba(0, 6, 46, .55);
  transform: translateY(-1px);
}
/* inward, and navy: an amber ring on a white face is the one place on
   this surface where the brand ring would not be visible */
.authback:focus-visible {
  outline: 2px solid var(--accent-ink);
  outline-offset: -3px;
}
@media (prefers-reduced-motion: reduce) {
  .authback:hover { transform: none; }
}

/* ---- the banner ------------------------------------------- */
.authbanner {
  /* pushed to the foot of the plate, where the scrim is deepest and the
     photograph has the least in it. This is the only auto margin in the
     column -- the legal line below takes a fixed offset instead -- so the
     whole of the free space lands above the type and it sits on the floor
     rather than halfway up it. */
  margin-top: auto;
  /* No frame: the words sit directly on the photograph. The hairline card
     that used to hold them was the thing the type was read against; with
     it gone that work falls entirely to the cast on each line below,
     which every line already carries. The measure is a reading bound now
     rather than a box to hug, so the block no longer shrinks to fit its
     longest line. */
  max-width: min(37rem, 100%);
  animation: plate-rise .7s cubic-bezier(.16, .84, .32, 1) both;
}
/* inside the card the first line sets its own top edge from the padding;
   the collapsed-margin spacing these carry was measured against open air */
.authbanner > :first-child { margin-top: 0; padding-top: 0; }
.authbanner > .authbanner-eyebrow:first-child::before { display: none; }

@keyframes plate-rise {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

.authbanner-eyebrow {
  position: relative;
  padding-top: .95rem;
  margin: 0;
  font-family: var(--f-mono);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .01em;
  color: var(--accent-fill);
  /* the frame that used to sit behind this is gone, so the label carries
     its own ground the way the two lines under it always have */
  text-shadow: 0 1px 12px rgba(0, 6, 46, .8), 0 0 3px rgba(0, 6, 46, .55);
}
.authbanner-eyebrow::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 28px;
  height: 2px;
  background: var(--accent-fill);
}

.authbanner-h {
  margin: .85rem 0 0;
  font-family: var(--f-display);
  /* stepped down: inside the card the type is read against a settled
     ground rather than competing with the photograph, so it no longer
     has to be large to hold its own */
  font-size: clamp(1.6rem, .9rem + 1.7vw, 2.4rem);
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -.022em;
  color: #FFFFFF;
  text-wrap: nowrap;
  /* the frame behind the type is a photograph, not a fill; a soft cast
     keeps the serif off it rather than in it */
  text-shadow: 0 1px 24px rgba(0, 6, 46, .55);
}

.authbanner-p {
  margin: .9rem 0 0;
  max-width: 40ch;
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--on-navy);
  text-wrap: pretty;
  /* the card behind this line is open now, so the line carries its own
     ground the way the headline above it always has */
  text-shadow: 0 1px 12px rgba(0, 6, 46, .8), 0 0 3px rgba(0, 6, 46, .55);
}

/* value props: the .stub-holds drawing, on the plate */
.authbanner .stub-holds { margin-top: 1.5rem; }
.authbanner .stub-holds li { text-shadow: 0 1px 12px rgba(0, 6, 46, .8), 0 0 3px rgba(0, 6, 46, .55); }

/* ============================================================
   THE PANEL — right 40%
   The panel is the scroll container, not the page: the plate stays
   put while a long step (details, identity) scrolls its own column.
   Centring is done with auto margins rather than justify-content,
   which clips the top of an overflowing flex child in every browser.
   ============================================================ */
.authpanel {
  position: relative;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--surface);
  padding: clamp(1.75rem, 1rem + 2vw, 3.25rem) clamp(1.25rem, .4rem + 2.6vw, 3.5rem);
}

.authpanel-inner {
  width: 100%;
  max-width: 27rem;
  margin: auto;
  flex: 0 0 auto;
}
/* the identity and details steps carry more fields than a login does */
.authpanel.is-wide .authpanel-inner { max-width: 34rem; }

/* ---- the plate's own furniture ----------------------------
   .stub-serial, .stub-holds, .stub-ladder and .stub-foot were drawn
   for a flat navy column and are reused here over a photograph.
   Two things change: everything gets a cast so it reads off the frame
   rather than in it, and the ladder gets a floor of its own so the
   numerals never land on whatever the picture puts behind them.
   ----------------------------------------------------------- */
.authvisual .stub-serial,
.authvisual .stub-holds,
.authvisual .stub-ladder,
.authvisual .stub-foot { flex: 0 0 auto; }

.authvisual .stub-serial,
.authvisual .stub-holds,
.authvisual .stub-foot { text-shadow: 0 1px 10px rgba(0, 6, 46, .65); }

.authvisual .stub-ladder {
  padding: .2rem .95rem;
  border: 1px solid var(--navy-line);
  border-radius: var(--r);
  background: rgba(0, 6, 46, .44);
  backdrop-filter: blur(3px);
}

/* the legal footing holds the floor of the plate. A fixed offset, not
   auto: two auto margins in this column would split the free space and
   leave the banner floating mid-plate. */
.authvisual .stub-foot {
  margin-top: clamp(1.1rem, 1.6vh, 2rem);
  padding-top: 1.1rem;
  /* --on-navy-dim was mixed for a flat navy field; over a photograph it
     drops below the contrast the licence line has to hold */
  color: rgba(221, 225, 247, .78);
}


/* ---- what the account holds -------------------------------
   The no-ladder screens (log in, invite, coming soon) would leave a
   column of air here otherwise. These are real destinations behind
   MyOrders, MyAccount and Esim, not reassurance copy.
   ----------------------------------------------------------- */
.stub-holds {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: .7rem;
}
.stub-holds li {
  display: flex;
  align-items: flex-start;
  gap: .6rem;
  font-size: 13px;
  line-height: 1.45;
  color: var(--on-navy);
}
.stub-holds svg {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  margin-top: .18em;
  color: var(--accent-fill);
}

/* ---- serial ----------------------------------------------- */
.stub-serial {
  margin: 0;
  padding: .8rem 0;
  border-block: 1px solid var(--navy-line);
}
.stub-serial dt {
  font-family: var(--f-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .01em;
  color: var(--on-navy-dim);
}
.stub-serial dd {
  margin: .3rem 0 0;
  font-family: var(--f-mono);
  font-size: 13.5px;
  font-weight: 500;
  color: #FFFFFF;
  overflow-wrap: anywhere;
}

/* ---- the ladder -------------------------------------------
   Numbers are information here: the visitor needs to know which of
   five questions they are on and how many remain.
   ----------------------------------------------------------- */
.stub-ladder {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
}
.stub-ladder li {
  position: relative;
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .6rem 0;
  border-top: 1px solid var(--navy-line);
  color: var(--on-navy-dim);
  font-size: 13.5px;
}
.stub-ladder li:last-child { border-bottom: 1px solid var(--navy-line); }

.rung-n {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 21px;
  height: 21px;
  border: 1px solid var(--navy-line);
  border-radius: 2px;
  font-family: var(--f-mono);
  font-size: 11px;
  font-weight: 500;
  color: var(--on-navy-dim);
}
.rung-l { min-width: 0; }

/* done: the label comes up to full strength and the row is stamped */
.stub-ladder li.is-done { color: var(--on-navy); }
.stub-ladder li.is-done .rung-n {
  border-color: rgba(255, 191, 0, .38);
  color: var(--accent-fill);
}

/* current: the numeral becomes the amber plate. No coloured border
   trick -- the fill is the state. */
.stub-ladder li.is-current {
  color: #FFFFFF;
  font-weight: 600;
  /* The row the visitor is standing on is washed in the stamp's own
     light, fading out before the stamp column. The wash is flush with
     the hairline rules above and below it -- overhanging them by even a
     few pixels reads as a misprint rather than as ink. */
  background: linear-gradient(90deg,
    rgba(255, 191, 0, .14), rgba(255, 191, 0, 0) 76%);
}
.stub-ladder li.is-current .rung-n {
  background: var(--accent-fill);
  border-color: var(--accent-fill);
  color: var(--accent-ink);
  font-weight: 600;
  /* the plate is the only lit object on the column */
  box-shadow: 0 0 0 3px rgba(255, 191, 0, .16), 0 2px 8px -2px rgba(255, 191, 0, .5);
}

/* ---- the stamp -------------------------------------------
   The one authored motion moment on this surface: an issued stamp
   landing slightly off-square, ring first, then the tick drawn.
   ---------------------------------------------------------- */
.rung-stamp {
  flex: 0 0 auto;
  margin-left: auto;
  width: 21px;
  height: 21px;
  color: var(--accent-fill);
}
.rung-stamp svg { width: 100%; height: 100%; display: block; }

.stub-ladder li.is-done .rung-stamp {
  animation: stamp-land .52s cubic-bezier(.16, .9, .28, 1) both;
}
.rung-stamp .stamp-ring,
.rung-stamp .stamp-tick {
  /* 66 covers the ring's circumference, 16 the tick's path */
  stroke-dasharray: 72;
  stroke-dashoffset: 0;
}
.stub-ladder li.is-done .rung-stamp .stamp-tick {
  animation: stamp-ink .4s cubic-bezier(.3, .9, .3, 1) .16s both;
}

@keyframes stamp-land {
  from { opacity: 0; transform: rotate(-16deg) scale(1.5); }
  to   { opacity: 1; transform: rotate(-7deg) scale(1); }
}
@keyframes stamp-ink {
  from { stroke-dashoffset: 26; }
  to   { stroke-dashoffset: 0; }
}
/* the resting angle is kept even when the animation is skipped */
.stub-ladder li.is-done .rung-stamp { transform: rotate(-7deg); }

/* ---- stub footing ---------------------------------------- */
.stub-foot {
  margin-top: auto;
  padding-top: 1.1rem;
  border-top: 1px solid var(--navy-line);
  display: grid;
  gap: .3rem;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--on-navy-dim);
}
.stub-foot .num { font-family: var(--f-mono); letter-spacing: .04em; }

/* ============================================================
   THE BODY
   ============================================================ */
.authbody { min-width: 0; }

/* The ask is the largest thing in the body and should read that way at
   a glance. Tighter tracking as it grows keeps the serif from looking
   loose at display size; text-wrap:balance stops a two-word orphan on
   the longer headings ("Confirm your email address"). */
.auth-h {
  font-size: clamp(1.75rem, 1.2rem + 2vw, 2.6rem);
  line-height: 1.06;
  letter-spacing: -.021em;
  text-wrap: balance;
}
/* more space above a heading than below it, everywhere */
.auth-lede {
  margin-top: .8rem;
  max-width: 54ch;
  font-size: 15px;
  line-height: 1.65;
  color: var(--body);
  text-wrap: pretty;
}
.auth-lede strong {
  font-family: var(--f-mono);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.auth-lede a, .auth-fine a { color: var(--brand); font-weight: 600; }

/* the form stack */
.auth-form { margin-top: 1.75rem; display: grid; gap: 1.15rem; }

/* The fields come up under the document, in order, once it has landed.
   Six steps is enough for every screen here except the details step,
   where the remainder simply arrives with the sixth -- a stagger the
   eye can still read as one movement rather than a queue. */
.auth-form > *,
.afork-route {
  animation: field-rise .44s cubic-bezier(.16, .84, .32, 1) both;
}
.auth-form > :nth-child(1), .afork-route:nth-of-type(1) { animation-delay: .20s; }
.auth-form > :nth-child(2), .afork-route:nth-of-type(2) { animation-delay: .26s; }
.auth-form > :nth-child(3), .afork-route:nth-of-type(3) { animation-delay: .32s; }
.auth-form > :nth-child(4) { animation-delay: .38s; }
.auth-form > :nth-child(5) { animation-delay: .44s; }
.auth-form > :nth-child(n + 6) { animation-delay: .50s; }

@keyframes field-rise {
  from { opacity: 0; transform: translateY(7px); }
  to   { opacity: 1; transform: none; }
}

/* a titled group inside a long form (the details step) */
.auth-group { display: grid; gap: 1.1rem; }
.auth-group > h2 {
  font-family: var(--f-mono);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .01em;
  color: var(--muted);
  padding-bottom: .6rem;
  border-bottom: 1px solid var(--line);
}
.auth-group + .auth-group { margin-top: 1rem; }

/* ============================================================
   FIELDS
   ============================================================ */
.afield { display: grid; align-content: start; gap: .45rem; min-width: 0; }

.afield > label,
.afield-lab {
  font-family: var(--f-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .01em;
  color: var(--muted);
  transition: color .16s ease;
}
.afield > label .opt {
  letter-spacing: .04em;
  text-transform: none;
  color: var(--line-strong);
}

/* the control itself */
.afield input[type="text"],
.afield input[type="email"],
.afield input[type="tel"],
.afield input[type="password"],
.afield input[type="date"],
.afield input[type="number"],
.afield select,
.actrl {
  width: 100%;
  min-width: 0;
  /* 48px tall at rest: comfortably over the 44px touch floor without
     becoming the chunky rounded field every SaaS signup ships */
  min-height: 48px;
  padding: .82rem .95rem;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  /* a hairline of inner shadow at the top edge -- the field reads as a
     recess in the sheet rather than a rectangle drawn on it */
  box-shadow: inset 0 1px 2px rgba(0, 10, 77, .045);
  font-family: var(--f-ui);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.35;
  caret-color: var(--brand);
  transition: border-color .16s ease, box-shadow .18s ease, background-color .16s ease;
  -webkit-appearance: none;
  appearance: none;
}

/* an email, a phone number, a postcode and a licence number are all
   read character by character -- they get the measured face */
.afield input[type="email"],
.afield input[type="tel"],
.afield input[type="date"],
.afield input.is-measured {
  font-family: var(--f-mono);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.afield input::placeholder {
  color: var(--muted);
  opacity: 1;
}

.afield input:hover:not(:focus),
.afield select:hover:not(:focus) {
  border-color: var(--muted);
  box-shadow: inset 0 1px 2px rgba(0, 10, 77, .06);
}

/* Focus is the one moment a field is the only thing that matters, so it
   gets three signals at once: the brand border, a soft ring, and the
   recess flipping to a lift. Ring first in the stack so the inset stays
   readable under it. */
.afield input:focus,
.afield select:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow:
    0 0 0 3.5px color-mix(in srgb, var(--brand) 15%, transparent),
    0 2px 8px -3px color-mix(in srgb, var(--brand) 32%, transparent),
    inset 0 1px 0 rgba(255, 255, 255, .6);
}

/* the label lights up with the field it belongs to, so the eye can find
   its place again after a glance away */
.afield:focus-within > label,
.afield:focus-within > .afield-lab { color: var(--brand); }

/* select needs its own caret: the native one belongs to no design system */
.afield select {
  padding-right: 2.4rem;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10' fill='none' stroke='%2371769F' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 4l3 3 3-3'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .85rem center;
  background-size: 11px 11px;
}

/* date inputs: the picker glyph is a browser surface too */
.afield input[type="date"]::-webkit-calendar-picker-indicator {
  opacity: .55;
  cursor: pointer;
  transition: opacity .16s ease;
}
.afield input[type="date"]:hover::-webkit-calendar-picker-indicator { opacity: 1; }

/* hint under a field */
.ahint {
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
}

/* field rows */
.arow { display: grid; gap: 1.1rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.arow-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* suburb / state / postcode: the last two only ever hold 3-4 characters */
.arow-addr { grid-template-columns: minmax(0, 2.2fr) minmax(0, 1fr) minmax(0, 1fr); }
.arow > .aspan { grid-column: 1 / -1; }

/* ---- validation ------------------------------------------
   jquery.validate.unobtrusive writes these class names; they are the
   contract, so they are styled rather than replaced.
   --------------------------------------------------------- */
.afield input.input-validation-error,
.afield select.input-validation-error {
  border-color: var(--down);
  background: var(--down-wash);
}
.afield input.input-validation-error:focus,
.afield select.input-validation-error:focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--down) 18%, transparent);
}

.field-validation-error,
.afield .text-danger {
  display: flex;
  align-items: flex-start;
  gap: .4rem;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.45;
  color: var(--down);
}
.field-validation-error:empty,
.afield .text-danger:empty { display: none; }
.field-validation-error::before,
.afield .text-danger:not(:empty)::before {
  content: "";
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
  margin-top: .16em;
  background: currentColor;
  /* an exclamation in a ring, drawn as a mask so it inherits the colour */
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.1' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9.5'/%3E%3Cpath d='M12 7.4v6'/%3E%3Cpath d='M12 16.6h.01'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.1' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9.5'/%3E%3Cpath d='M12 7.4v6'/%3E%3Cpath d='M12 16.6h.01'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* the summary block, when the server rejects the whole post */
.validation-summary-errors {
  padding: .9rem 1rem;
  border: 1px solid color-mix(in srgb, var(--down) 42%, var(--line));
  border-radius: var(--r);
  background: var(--down-wash);
  box-shadow: 0 1px 2px rgba(0, 10, 77, .05);
  font-size: 13.5px;
  color: var(--down);
}
.validation-summary-errors ul { margin: 0; padding-left: 1.1rem; display: grid; gap: .3rem; }
.validation-summary-errors ul:empty { display: none; }
.validation-summary-errors:has(ul:empty) { display: none; }
.validation-summary-valid { display: none; }

/* ============================================================
   NOTICES
   One plate, four semantic tints, each drawn from the token its
   meaning already owns. 1px borders only.
   ============================================================ */
.anote {
  display: flex;
  align-items: flex-start;
  gap: .7rem;
  padding: .9rem 1rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  background: var(--surface-2);
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--body);
  /* a notice is an object laid on the sheet, not a tinted band */
  box-shadow: 0 1px 2px rgba(0, 10, 77, .05);
  animation: field-rise .4s cubic-bezier(.16, .84, .32, 1) .12s both;
}
.anote strong { color: var(--ink); }
.anote svg { flex: 0 0 auto; width: 17px; height: 17px; margin-top: .1em; }

/* Each tint is carried by the rim, the wash and the icon together -- all
   1px, per the rule at the top of this section. A thickened left edge was
   tried here and removed: it is the single most recognisable tell of a
   generated interface, and this plate never needed it. Colour is already
   never alone, because every note ships an icon and its own words. */
.anote-bad {
  border-color: color-mix(in srgb, var(--down) 42%, var(--line));
  background: var(--down-wash);
  color: color-mix(in srgb, var(--down) 88%, var(--ink));
}
.anote-bad svg { color: var(--down); }

.anote-good {
  border-color: color-mix(in srgb, var(--up) 42%, var(--line));
  background: var(--up-wash);
  color: color-mix(in srgb, var(--up) 82%, var(--ink));
}
.anote-good svg { color: var(--up); }

.anote-warn {
  border-color: color-mix(in srgb, var(--accent-fill) 55%, var(--line));
  background: var(--accent-wash);
  color: color-mix(in srgb, var(--accent) 80%, var(--ink));
}
.anote-warn svg { color: var(--accent); }

.anote-info {
  border-color: color-mix(in srgb, var(--brand) 32%, var(--line));
  background: color-mix(in srgb, var(--brand) 7%, var(--surface));
  color: var(--body);
}
.anote-info svg { color: var(--brand); }

/* the development OTP hint -- deliberately unmistakable, so it can
   never be mistaken for production furniture */
.anote-dev {
  border-style: dashed;
  border-color: var(--line-strong);
  background: var(--surface-2);
  font-family: var(--f-mono);
  font-size: 12.5px;
  color: var(--body);
}
.anote-dev svg { color: var(--muted); }

/* ============================================================
   ACTIONS
   ============================================================ */
.btn-wide {
  width: 100%;
  min-height: 52px;
  padding-block: .95rem;
  font-size: 15px;
  letter-spacing: .008em;
}
.auth-form .btn-wide { margin-top: .55rem; }

/* Every control on this surface is keyboard-reachable and must show it.
   The amber ring is the same one .segmented already uses, so focus looks
   like one thing across the whole product. */
.authsurface .btn:focus-visible,
.authsurface .pw-eye:focus-visible,
.authsurface .btn-link:focus-visible {
  outline: 2px solid var(--accent-fill);
  outline-offset: 2px;
}

/* The brand button on the auth surface is the end of every screen, so it
   is drawn as a solid object: a top-lit face, a contact shadow, and a
   coloured cast that ties it to the brand rather than to the page.

   The face is the logo amber #FFBF00 (--accent-fill), not the logo blue.
   Amber is the stamp this whole surface is issued under -- it already
   rings every focused control and edges every route card -- so putting
   it on the one action per screen makes the primary path the same colour
   as the attention the surface pays. Amber is a light value, so the label
   flips to --accent-ink; that pair is the same one .btn-accent already
   uses on the home surface, so nothing new enters the system. */
.authbody .btn-brand {
  position: relative;
  overflow: hidden;
  background-color: var(--accent-fill);
  background-image: linear-gradient(180deg,
    color-mix(in srgb, #FFFFFF 26%, var(--accent-fill)), var(--accent-fill));
  color: var(--accent-ink);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .5),
    0 1px 2px rgba(94, 62, 0, .22),
    0 10px 20px -12px color-mix(in srgb, var(--accent-fill) 78%, transparent);
  transition:
    background-color .18s ease, background-image .18s ease, color .18s ease,
    transform .16s cubic-bezier(.22, .75, .2, 1), box-shadow .2s ease;
}

/* HOVER: the object lifts a pixel, the face warms to --accent-hot, and a
   single band of light crosses it left to right. The sweep is an
   animation rather than a transition on purpose -- a transition would
   run backwards when the pointer leaves, which reads as the light
   sliding back into the button. This plays once, forward, per hover. */
.authbody .btn-brand::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(100deg,
    transparent 38%,
    rgba(255, 255, 255, .34) 50%,
    transparent 62%);
  transform: translateX(-115%);
}
.authbody .btn-brand:hover::after,
.authbody .btn-brand:focus-visible::after {
  animation: auth-btn-sheen .62s cubic-bezier(.3, .1, .3, 1) forwards;
}
@keyframes auth-btn-sheen {
  from { transform: translateX(-115%); }
  to   { transform: translateX(115%); }
}
.authbody .btn-brand:hover {
  background-image: none;
  background-color: var(--accent-hot);
  transform: translateY(-1px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .55),
    0 2px 4px rgba(94, 62, 0, .24),
    0 16px 28px -14px color-mix(in srgb, var(--accent-fill) 85%, transparent);
}
/* press: the object goes down to the sheet and the cast collapses */
.authbody .btn-brand:active {
  transform: translateY(1px);
  box-shadow:
    inset 0 1px 3px rgba(120, 80, 0, .32),
    0 1px 1px rgba(94, 62, 0, .2);
}

/* The surface-wide focus ring is amber, which would vanish on an amber
   button. The primary action rings in --accent-ink and turns the ring
   inward, so it is drawn against the amber face itself rather than
   against the panel -- the one placement that holds in both the light
   and the dark panel. .afork-route already rings inward, so the inset
   ring is not a new idea on this surface. */
.authsurface .authbody .btn-brand:focus-visible {
  outline-color: var(--accent-ink);
  outline-offset: -3px;
}

/* The busy spinner draws in currentColor, which is now ink on amber --
   still the highest-contrast mark on the button. The sheen must not run
   while the form is submitting. */
.authbody .btn-brand.is-busy::after { animation: none; opacity: 0; }

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: .5;
  cursor: not-allowed;
  pointer-events: none;
}

/* a submit that is running: the label is swapped by xc-auth_v1.js, the
   spinner is drawn here so no markup changes */
.btn.is-busy { position: relative; pointer-events: none; opacity: .82; }
.btn.is-busy::before {
  content: "";
  width: 13px;
  height: 13px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: auth-spin .62s linear infinite;
}
@keyframes auth-spin { to { transform: rotate(360deg); } }

/* the quiet secondary rail under the primary action */
.auth-fine {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .4rem 1.35rem;
  font-size: 13px;
  color: var(--muted);
}
.auth-fine a {
  color: var(--brand);
  font-weight: 600;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .22em;
  text-decoration-color: color-mix(in srgb, var(--brand) 32%, transparent);
  transition: text-decoration-color .18s ease;
}
.auth-fine a:hover { text-decoration-color: var(--brand); }
/* .sep pushes the second item to the far end of the rail. Alone in the
   rail there is nothing to push away from, and the auto margin would strand
   one link against the right edge, so it reverts to sitting at the start. */
.auth-fine .sep { margin-left: auto; }
.auth-fine .sep:only-child { margin-left: 0; }

/* The one sentence in the product's own voice, at the foot of the panel:
   the account is not the product. Principle 1 in PRODUCT.md, rendered.
   No rule of its own -- .auth-fine above it already drew one, and two
   hairlines in four lines of 13px type is a stack, not a hierarchy. */
.authpage-out {
  margin: 1.35rem 0 0;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--muted);
}
.authpage-out a {
  color: var(--brand);
  font-weight: 600;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .22em;
  text-decoration-color: color-mix(in srgb, var(--brand) 35%, transparent);
  transition: text-decoration-color .18s ease;
}
.authpage-out a:hover { text-decoration-color: var(--brand); }

/* a link that is really a POST -- "resend code" */
.auth-linkform { display: contents; }
.btn-link {
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--f-ui);
  font-size: 13px;
  font-weight: 600;
  color: var(--brand);
  cursor: pointer;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .22em;
  text-decoration-color: color-mix(in srgb, var(--brand) 32%, transparent);
  transition: text-decoration-color .18s ease;
}
.btn-link:hover { text-decoration-color: var(--brand); }
.btn-link[disabled] { color: var(--muted); cursor: not-allowed; text-decoration: none; }

/* ============================================================
   CHECKBOX
   ============================================================ */
.acheck {
  display: flex;
  align-items: center;
  gap: .65rem;
  /* the whole label is the target; the padding is what takes the row to
     44px without inflating the box itself */
  min-height: 44px;
  font-size: 13.5px;
  color: var(--body);
  cursor: pointer;
  user-select: none;
  transition: color .16s ease;
}
.acheck input {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  margin: 0;
  accent-color: var(--brand);
  cursor: pointer;
}
.acheck:hover { color: var(--ink); }

/* ============================================================
   ONE-TIME CODE
   Six plates instead of one text field. The real input stays in the
   DOM so the post body and jquery.validate contract are untouched;
   xc-auth_v1.js hides it and keeps the two in sync. Without
   JavaScript the ordinary field is what renders.
   ============================================================ */
.otp {
  display: flex;
  gap: .55rem;
  /* six plates should read as plates, not as six wide fields */
  max-width: 22rem;
}
.otp input {
  flex: 1 1 0;
  min-width: 0;
  padding: .8rem .2rem;
  text-align: center;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  font-family: var(--f-mono);
  font-size: clamp(19px, 4.2vw, 24px);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  caret-color: var(--brand);
  box-shadow: inset 0 1px 2px rgba(0, 10, 77, .045);
  transition: border-color .16s ease, box-shadow .18s ease, transform .16s cubic-bezier(.22, .75, .2, 1);
  -webkit-appearance: none;
  appearance: none;
}
/* the plate being typed into lifts off the row */
.otp input:focus {
  outline: none;
  border-color: var(--brand);
  transform: translateY(-2px);
  box-shadow:
    0 0 0 3.5px color-mix(in srgb, var(--brand) 15%, transparent),
    0 6px 14px -6px color-mix(in srgb, var(--brand) 45%, transparent);
}
/* a filled plate reads as banked, like a stamped ladder row */
.otp input.is-filled {
  border-color: color-mix(in srgb, var(--brand) 55%, var(--line-strong));
  background: color-mix(in srgb, var(--brand) 5%, var(--surface));
}
.otp.is-wrong { animation: otp-reject .3s ease both; }
@keyframes otp-reject {
  10%, 90% { transform: translateX(-2px); }
  30%, 70% { transform: translateX(3px); }
  50%      { transform: translateX(-3px); }
}
/* the real field, once the grid has taken over for it */
.otp-real.is-shadowed {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ============================================================
   PASSWORD
   ============================================================ */
.pw { position: relative; display: flex; }
.pw input { padding-right: 3.4rem !important; }
.pw-eye {
  position: absolute;
  top: 50%;
  right: .25rem;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  /* 44px square, which the 48px field now has room for. The glyph stays
     17px; it is the target that grew, not the icon. */
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: 3px;
  background: none;
  color: var(--muted);
  cursor: pointer;
  transition: color .16s ease, background-color .16s ease;
}
.pw-eye:hover { color: var(--ink); background: var(--surface-2); }
.pw-eye svg { width: 17px; height: 17px; }

/* the server's rule, itemised, ticking off as it is met. A strength
   bar would be a guess; this is the actual acceptance criteria. */
.pwrules {
  list-style: none;
  margin: .2rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
  gap: .3rem .9rem;
}
.pwrules li {
  display: flex;
  align-items: center;
  gap: .42rem;
  font-size: 12px;
  color: var(--muted);
  transition: color .18s ease;
}
.pwrules li::before {
  content: "";
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  transition: background-color .18s ease, border-color .18s ease;
}
.pwrules li.is-met { color: var(--up); }
.pwrules li.is-met::before {
  border-color: var(--up);
  background: var(--up)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.5 12.8l4.4 4.4 8.6-9.6'/%3E%3C/svg%3E")
    center / 9px 9px no-repeat;
}

/* ============================================================
   THE FORK — Views/Account/Signup.cshtml
   Two routes, not two cards. Ruled rows inside the document, the way
   a form forks on paper.
   ============================================================ */
.afork { display: grid; margin-top: 1.75rem; border-top: 1px solid var(--line); }
.afork-route {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: .5rem 1.25rem;
  width: 100%;
  padding: 1.45rem 1rem 1.45rem 1.1rem;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: none;
  text-align: left;
  cursor: pointer;
  /* the tint, the amber edge and the arrow's own slide carry the hover;
     nudging the row with padding would animate layout for the same read */
  transition: background-color .18s ease;
}
/* The chosen route grows an amber edge out of the tear line's own colour
   -- the row is being selected off the document, so it is marked the way
   the document marks anything: with the stamp ink. */
.afork-route::before {
  content: "";
  position: absolute;
  inset-block: 0;
  left: 0;
  width: 3px;
  background: var(--accent-fill);
  transform: scaleY(0);
  transform-origin: 50% 50%;
  transition: transform .24s cubic-bezier(.22, .75, .2, 1);
}
.afork-route:hover,
.afork-route:focus-visible { background: var(--surface-2); }
.afork-route:hover::before,
.afork-route:focus-visible::before { transform: scaleY(1); }
.afork-route:focus-visible { outline: 2px solid var(--accent-fill); outline-offset: -2px; }

.afork-h {
  grid-column: 1;
  font-family: var(--f-display);
  font-size: 19.5px;
  font-weight: 600;
  letter-spacing: -.012em;
  color: var(--ink);
  transition: color .18s ease;
}
.afork-route:hover .afork-h { color: var(--brand); }
.afork-p {
  grid-column: 1;
  margin-top: .3rem;
  font-size: 13.5px;
  line-height: 1.55;
  max-width: 56ch;
  color: var(--body);
}
/* a two-line row would otherwise stand taller than the single-line ones;
   the supporting line takes the difference out of the row's own padding */
.afork-route:has(.afork-p) { padding-block: 1.15rem; }
.afork-go {
  grid-column: 2;
  grid-row: 1 / span 2;
  display: grid;
  place-items: center;
  width: 2.35rem;
  height: 2.35rem;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  color: var(--brand);
  transition: background-color .18s ease, border-color .18s ease, color .18s ease, transform .22s cubic-bezier(.22, .75, .2, 1);
}
.afork-go svg { width: 15px; height: 15px; }
.afork-route:hover .afork-go {
  background: var(--brand);
  border-color: var(--brand);
  color: #FFFFFF;
  transform: translateX(3px);
}

/* ============================================================
   SEGMENTED CHOICE — the claim lookup method
   Extends .segmented from XC_Home_v4.css with nothing but a top gap.
   ============================================================ */
.afield > .segmented { margin-top: .1rem; }

/* ============================================================
   IDENTITY STEP
   The Entrust / Onfido SDK mounts inside .sdkmount. Everything the
   third party draws is its own; what surrounds it is ours.
   ============================================================ */
.sdkmount {
  margin-top: 1.25rem;
  min-height: 520px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  background: #FFFFFF;
  padding: .5rem;
}
.sdkwait {
  display: grid;
  place-items: center;
  gap: .6rem;
  min-height: 300px;
  margin-top: 1.25rem;
  padding: 2rem 1.25rem;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface-2);
  text-align: center;
}
.sdkwait-ring {
  width: 34px;
  height: 34px;
  border: 2px solid var(--line-strong);
  border-top-color: var(--brand);
  border-radius: 50%;
  animation: auth-spin .8s linear infinite;
}
.sdkwait-h { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.sdkwait-p { font-size: 12.5px; color: var(--muted); }

.sdkstatus { margin-top: .9rem; font-size: 13px; }
/* signup_entrust.js injects these Bootstrap utility names */
.sdkstatus .text-danger  { color: var(--down); font-weight: 500; }
.sdkstatus .text-warning { color: var(--accent); font-weight: 500; }
.sdkstatus .text-muted   { color: var(--muted); }
.sdkstatus .spinner-border {
  display: inline-block;
  width: 13px;
  height: 13px;
  vertical-align: -1px;
  margin-right: .4rem;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: auth-spin .62s linear infinite;
}
.sdkstatus .spinner-border-sm { width: 12px; height: 12px; }
.sdkstatus .mr-2 { margin-right: .4rem; }
.sr-only-bs, .sdkstatus .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

/* the two actions on the identity step sit side by side */
.auth-actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: .4rem; }
.auth-actions .btn-wide { width: auto; flex: 1 1 14rem; }

/* ============================================================
   BROWSER SURFACES
   The parts we did not draw still belong to the design.
   ============================================================ */
.authsurface ::selection {
  background: var(--accent-fill);
  color: var(--accent-ink);
}
.authvisual ::selection {
  background: var(--accent-fill);
  color: var(--accent-ink);
}
.authsurface {
  scrollbar-color: var(--line-strong) var(--ground);
  scrollbar-width: thin;
}
.authsurface ::-webkit-scrollbar { width: 11px; height: 11px; }
.authsurface ::-webkit-scrollbar-track { background: var(--ground); }
.authsurface ::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border: 3px solid var(--ground);
  border-radius: 6px;
}
.authsurface ::-webkit-scrollbar-thumb:hover { background: var(--muted); }

/* an unstyled autofill flood undoes every field decision above */
.authbody input:-webkit-autofill,
.authbody input:-webkit-autofill:hover,
.authbody input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--ink);
  -webkit-box-shadow: 0 0 0 40px var(--surface) inset;
  caret-color: var(--brand);
}

/* ============================================================
   RESPONSIVE
   Three states. Wide: 60 / 40, both columns fixed to the viewport.
   Laptop: the panel takes a larger share, because 40% of 1024px is
   a column the fields cannot live in. Below 960: the split unstacks,
   the plate becomes a short head, and the page scrolls normally --
   a locked viewport on a phone fights the keyboard.
   ============================================================ */
@media (max-width: 1180px) {
  .authsplit { grid-template-columns: 54fr 46fr; }
  .authbanner .stub-holds { display: none; }
}

@media (max-width: 960px) {
  html:has(body.authsurface) { height: auto; }
  body.authsurface { height: auto; overflow: visible; }

  .authsplit {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto 1fr;
    height: auto;
    min-height: 100dvh;
    overflow: visible;
  }

  .authvisual {
    gap: 1.25rem;
    padding: 1.4rem 1.4rem 1.75rem;
    background-position: 42% 32%;
  }
  /* the column has become a wide, short head: the raking light has to
     turn with it or it reads as a band across the top */
  .authvisual::before {
    background:
      radial-gradient(90% 150% at 4% 0%, rgba(255, 191, 0, .12), transparent 60%),
      linear-gradient(180deg,
        rgba(0, 6, 46, .82) 0%,
        rgba(0, 6, 46, .58) 38%,
        rgba(0, 6, 46, .93) 100%);
  }

  .authbanner { margin-top: 1.5rem; max-width: none; }
  .authbanner-h { font-size: clamp(1.5rem, 1rem + 2.2vw, 2.05rem); }
  .authbanner-p { font-size: 14.5px; max-width: 54ch; }
  /* the value props already stood down at 1180 and stay down: on a phone
     they push the form below two full screens of scroll */
  .authbanner .stub-holds { display: none; }

  /* the plate keeps its legal footing, but it is no longer the tallest
     thing on the screen and does not need to be pushed to a floor */
  .stub-foot { margin-top: .4rem; }

  .authpanel {
    overflow: visible;
    padding: clamp(1.5rem, 1rem + 2vw, 2.5rem) 1.4rem 2.5rem;
  }
  .authpanel-inner,
  .authpanel.is-wide .authpanel-inner { max-width: 34rem; }

  /* the ladder becomes a rail: numbered plates in a row, labels under */
  .stub-ladder {
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: .5rem;
  }
  .stub-ladder li,
  .stub-ladder li:last-child {
    flex-direction: column;
    align-items: flex-start;
    gap: .4rem;
    padding: .7rem 0 0;
    border-bottom: 0;
    font-size: 12px;
    line-height: 1.3;
  }
  .rung-l { overflow-wrap: anywhere; }
  .rung-stamp {
    position: absolute;
    top: .45rem;
    left: 15px;
    width: 15px;
    height: 15px;
    margin-left: 0;
  }
  /* Between 460 and 960 the ladder is a horizontal rail of grid columns.
     A left-to-right wash across a narrow column reads as a stray tint,
     so it comes off and the lit numeral plate carries the state alone. */
  .stub-ladder li.is-current { background: none; }

  .arow, .arow-3, .arow-addr { grid-template-columns: minmax(0, 1fr); }
  /* postcode and state stay together: neither needs a full row */
  .arow-addr { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .arow-addr > :first-child { grid-column: 1 / -1; }
}

/* a laptop in landscape is short, not narrow: the banner is what gives
   way, never the fields */
@media (min-width: 961px) and (max-height: 760px) {
  .authbanner-h { font-size: clamp(1.5rem, .9rem + 1.3vw, 1.95rem); }
  .authbanner .stub-holds { display: none; }
  .authvisual { gap: 1rem; }
}

@media (max-width: 560px) {
  .authvisual { padding: 1.15rem 1.25rem 1.5rem; }
  .authvisual-top { gap: .6rem; }
  /* the clamp bottoms out at 62px, which is wider than a 360px plate
     has left once the back control is placed */
  .authmark img { height: 52px; }
  .authback span { display: none; }
  .authback { padding: .5rem; }
  .authpanel { padding-inline: 1.25rem; }
  .otp { gap: .35rem; }
  .otp input { padding: .7rem .1rem; }
  .auth-fine { gap: .5rem; }
  .auth-fine .sep { margin-left: 0; }
  .sdkmount { min-height: 460px; padding: .25rem; }
  .afork-route { padding-block: 1.15rem; }
  .afork-go { width: 2.1rem; height: 2.1rem; }
}

/* the ladder rail runs out of room for five labels well before the
   plate does */
@media (max-width: 460px) {
  .stub-ladder { grid-auto-flow: row; gap: 0; }
  .stub-ladder li,
  .stub-ladder li:last-child {
    flex-direction: row;
    align-items: center;
    gap: .65rem;
    padding: .5rem 0;
    border-top: 1px solid var(--navy-line);
  }
  .stub-ladder li:last-child { border-bottom: 1px solid var(--navy-line); }
  .rung-stamp { position: static; margin-left: auto; width: 17px; height: 17px; }
  /* below 460 the ladder is rows again, so the wash comes back */
  .stub-ladder li.is-current {
    background: linear-gradient(90deg,
      rgba(255, 191, 0, .14), rgba(255, 191, 0, 0) 76%);
  }
}

/* ============================================================
   REDUCED MOTION
   The stamp keeps its resting angle; nothing travels.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  /* Nothing travels. Each of these uses animation-fill-mode:both from a
     transparent, offset start, so removing the animation outright -- not
     shortening it -- is what leaves the element at its resting style. */
  .stub-ladder li.is-done .rung-stamp,
  .stub-ladder li.is-done .rung-stamp .stamp-tick,
  .otp.is-wrong,
  .authbanner,
  .auth-form > *,
  .afork-route,
  .anote {
    animation: none !important;
  }
  /* the amber route edge still appears on hover, it just stops sweeping */
  .afork-route::before { transition-duration: .01ms !important; }
  /* the lift on a focused plate and the press on the primary action are
     displacement, not state -- drop them and keep the colour signals */
  .otp input:focus { transform: none; }
  .authbody .btn-brand:hover,
  .authbody .btn-brand:active { transform: none; }
  .authbody .btn-brand:hover::after,
  .authbody .btn-brand:focus-visible::after { animation: none; opacity: 0; }

  .afork-go,
  .otp input,
  .btn { transition-duration: .01ms !important; }

  .btn.is-busy::before,
  .sdkwait-ring,
  .sdkstatus .spinner-border { animation-duration: 1.6s; }
}

/* ============================================================
   HIDDEN
   .afield is display:grid, which beats the browser's default
   [hidden] rule. The conditional fields in xc-auth_v1.js toggle the
   attribute, so this has to win.
   ============================================================ */
.authbody [hidden] { display: none !important; }

/* Unobtrusive validation renders this span on every field, empty, until
   something is wrong with it -- an empty grid row plus its gap otherwise.

   MUST stay scoped to the span. jquery.validate's validClass is the bare
   string "valid" (jquery.validate.js:287) and unhighlight() puts it on the
   CONTROL, not on the message (jquery.validate.js:357). An unqualified
   `.afield .valid` therefore hides the input the moment its value becomes
   valid -- type a good email and the field disappears from under you. */
.afield .field-validation-valid,
.afield span.valid { display: none; }

/* the second act on a two-post screen (send a code, then verify it) */
.auth-next { margin-top: 1.75rem; }

/* signup_entrust.js injects a Bootstrap spinner into the start button and
   resets the label itself; both are its contract, so both are supported */
.btn .spinner-border {
  display: inline-block;
  width: 13px;
  height: 13px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: auth-spin .62s linear infinite;
}
.btn .spinner-border-sm { width: 12px; height: 12px; }
.btn .mr-2 { margin-right: .1rem; }

@media (max-width: 560px) {
  /* the closing line breaks mid-phrase at this width; the action gets its
     own line rather than a split underline */
  .authpage-out a { display: block; margin-top: .3rem; }
}

/* ============================================================
   SEPARATOR
   Splits the two acts of a two-post screen without a heading that
   would only repeat the field label under it.
   ============================================================ */
.auth-rule {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 1.75rem 0 0;
}

/* a secondary action row: auto-width, left-aligned, not competing with
   the primary button below it */
.auth-actions.is-quiet { margin-top: .1rem; }
.auth-actions.is-quiet .btn { flex: 0 0 auto; }

/* A ghost button on the white body is white-on-hairline -- the same
   drawing as an empty text field. Tinting it keeps the two apart. */
.authbody .btn-ghost { background: var(--surface-2); }
.authbody .btn-ghost:hover { background: var(--surface-3); border-color: var(--muted); }

/* A note rendered straight after the lede is a sibling of the body, not
   a row of the form grid, so it has no gap of its own and lands tight
   under the sentence above it. */
.authbody > .anote { margin-top: 1.35rem; }
