/* public_html/portal/auth.css - the anonymous account forms (sign in,
   sign up, forgot, reset). ASCII only. Loaded after theme.css and
   portal.css on pages that call portal_header($title, true): the normal
   portal chrome stays (top bar, theme toggle, footer, main.card); this
   file only styles the form component inside the card. Every color comes
   from the theme tokens so light and dark stay in lockstep with the rest
   of the site. Structure: fields -> dock (the submit button lives in an
   inset track) -> status line -> secondary actions. */

/* Two values that need a per-theme choice rather than a token mix: the
   dock's inset shadow (a black shadow reads as a smudge on a white card)
   and the idle button's fill (surface-3 vanishes against the light track).
   Same three-state pattern as theme.css: light default, explicit dark,
   OS dark unless the user forced light. */
:root {
  --auth-dock-shadow: 0 8px 18px -14px rgba(19, 26, 43, .28) inset;
  --auth-off-bg: var(--surface);
  --auth-off-edge: var(--border-strong);
}
:root[data-theme="dark"] {
  --auth-dock-shadow: 0 10px 24px -14px rgba(0, 0, 0, .6) inset;
  --auth-off-bg: var(--surface-3);
  --auth-off-edge: var(--border);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --auth-dock-shadow: 0 10px 24px -14px rgba(0, 0, 0, .6) inset;
    --auth-off-bg: var(--surface-3);
    --auth-off-edge: var(--border);
  }
}

main.card.auth-page {
  --auth-glow: color-mix(in srgb, var(--accent) 26%, transparent);
  --auth-glow-soft: color-mix(in srgb, var(--accent) 12%, transparent);
  --auth-ease-out: cubic-bezier(.23, 1, .32, 1);
  --auth-ease-in-out: cubic-bezier(.77, 0, .175, 1);
  --auth-r-field: 12px;
  position: relative;
}

/* ---- Scene: one soft accent halo behind the card --------------------- */
.auth-scene {
  position: fixed; left: 50%; top: 46%; z-index: 0;
  width: min(120vw, 1000px); aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, var(--auth-glow-soft, transparent), transparent 70%);
  pointer-events: none;
  opacity: 0;
  animation: auth-glow-in 900ms cubic-bezier(.23, 1, .32, 1) 120ms forwards;
}
:root { --auth-glow-soft: color-mix(in srgb, var(--accent) 11%, transparent); }
@keyframes auth-glow-in { to { opacity: 1; } }
main.card.auth-page { z-index: 1; }

/* ---- Card entrance: one orchestrated moment, then nothing moves alone -- */
.js main.card.auth-page > * {
  opacity: 0;
  transform: translateY(6px);
  animation: auth-row-in 420ms var(--auth-ease-out) forwards;
}
.js main.card.auth-page > :nth-child(1) { animation-delay: 40ms; }
.js main.card.auth-page > :nth-child(2) { animation-delay: 80ms; }
.js main.card.auth-page > :nth-child(3) { animation-delay: 110ms; }
.js main.card.auth-page > :nth-child(4) { animation-delay: 140ms; }
.js main.card.auth-page > :nth-child(5) { animation-delay: 170ms; }
@keyframes auth-row-in { to { opacity: 1; transform: none; } }
main.card.auth-page.is-leaving {
  transition: opacity 320ms var(--auth-ease-out), transform 320ms var(--auth-ease-out);
  opacity: 0;
  transform: translateY(-6px) scale(.99);
}

/* ---- Heading + lede ------------------------------------------------- */
main.card.auth-page h1 { margin-bottom: 6px; text-wrap: balance; }
main.card.auth-page .auth-lede {
  margin: 0 0 22px; color: var(--muted); font-size: 14px; line-height: 1.55;
  max-width: 36ch; text-wrap: pretty;
}

/* ---- Banner ---------------------------------------------------------- */
main.card.auth-page .auth-banner {
  margin: 0 0 16px; padding: .7rem 1rem;
  border-radius: var(--radius-sm); font-size: 14px; font-weight: 500; line-height: 1.45;
  border: 1px solid transparent;
}
main.card.auth-page .auth-banner[hidden] { display: none; }
main.card.auth-page .auth-banner.is-info {
  color: var(--ok); background: var(--ok-soft);
  border-color: color-mix(in srgb, var(--ok) 30%, transparent);
}
main.card.auth-page .auth-banner.is-error {
  color: var(--danger); background: var(--danger-soft);
  border-color: color-mix(in srgb, var(--danger) 30%, transparent);
}

/* ---- Fields ---------------------------------------------------------- */
main.card.auth-page form.auth-form { display: grid; gap: 16px; margin: 0; }

main.card.auth-page .field { display: grid; gap: 6px; }
main.card.auth-page .field-head {
  display: flex; align-items: baseline; justify-content: space-between; min-height: 18px;
}
main.card.auth-page .field-head label {
  display: block; font-size: 13.5px; font-weight: 600; color: var(--muted);
  transition: color 200ms ease;
}
main.card.auth-page .field:focus-within .field-head label { color: var(--accent); }
main.card.auth-page .field[data-state="invalid"] .field-head label { color: var(--danger); }
main.card.auth-page .field-link {
  padding: 6px 0; margin: -6px 0;
  font-size: 13px; font-weight: 600; color: var(--accent);
  border-radius: 6px; -webkit-tap-highlight-color: transparent;
}

main.card.auth-page .field-box {
  position: relative; display: flex; align-items: center; height: 48px;
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--auth-r-field);
  box-shadow: 0 0 0 0 transparent;
  transition: border-color 200ms ease, background-color 200ms ease, box-shadow 260ms var(--auth-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  main.card.auth-page .field-box:hover { border-color: var(--faint); }
}
main.card.auth-page .field:focus-within .field-box {
  border-color: var(--accent);
  box-shadow: var(--ring), 0 0 28px -8px var(--auth-glow);
}
main.card.auth-page .field[data-state="invalid"] .field-box {
  border-color: color-mix(in srgb, var(--danger) 70%, transparent);
}
main.card.auth-page .field[data-state="invalid"]:focus-within .field-box {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 22%, transparent);
}
main.card.auth-page .field[data-state="valid"]:not(:focus-within) .field-box {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border-strong));
}

main.card.auth-page .field-icon {
  flex: none; width: 18px; height: 18px; margin: 0 2px 0 14px;
  color: var(--faint); transition: color 200ms ease;
}
main.card.auth-page .field:focus-within .field-icon { color: var(--accent); }
main.card.auth-page .field[data-state="invalid"] .field-icon { color: var(--danger); }

main.card.auth-page .field-box input {
  flex: 1 1 auto; min-width: 0; width: auto; height: 100%;
  margin: 0; padding: 0 12px 0 10px;
  background: transparent; border: 0; border-radius: var(--auth-r-field);
  outline: 0; box-shadow: none;
  color: var(--text); font: inherit; font-size: 15px; line-height: 1;
  caret-color: var(--accent);
}
main.card.auth-page .field-box input:focus,
main.card.auth-page .field-box input:focus-visible { box-shadow: none; outline: 0; border: 0; }
main.card.auth-page .field-box input::placeholder { color: var(--faint); opacity: 1; }
main.card.auth-page .field-box input[type="password"] { letter-spacing: .12em; }
main.card.auth-page .field-box input[type="password"]::placeholder { letter-spacing: 0; }

/* Autofill: keep our well and text colors; the 1ms animation lets auth.js
   revalidate when a password manager fills silently. */
@keyframes cns-autofill { from { opacity: 1; } to { opacity: 1; } }
main.card.auth-page .field-box input:-webkit-autofill,
main.card.auth-page .field-box input:-webkit-autofill:hover,
main.card.auth-page .field-box input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--text);
  -webkit-box-shadow: 0 0 0 1000px var(--bg) inset;
  box-shadow: 0 0 0 1000px var(--bg) inset;
  caret-color: var(--text);
  transition: background-color 999999s ease-out 0s;
  animation-name: cns-autofill; animation-duration: 1ms;
}

/* Trailing controls: eye toggle, valid check. */
main.card.auth-page .field-eye {
  flex: none; width: 34px; height: 34px; margin-right: 5px; padding: 0;
  display: inline-grid; place-items: center;
  background: transparent; border: 0; border-radius: 9px;
  color: var(--faint); cursor: pointer;
  touch-action: manipulation; -webkit-tap-highlight-color: transparent;
  transition: color 160ms ease, background-color 160ms ease;
}
main.card.auth-page .field-eye:hover { color: var(--muted); background: var(--surface-2); }
main.card.auth-page .field-eye svg {
  grid-area: 1 / 1; width: 18px; height: 18px;
  transition: opacity 160ms ease, transform 160ms var(--auth-ease-out);
}
main.card.auth-page .field-eye .eye-off { opacity: 0; transform: scale(.8); }
main.card.auth-page .field-eye[aria-pressed="true"] .eye-on { opacity: 0; transform: scale(.8); }
main.card.auth-page .field-eye[aria-pressed="true"] .eye-off { opacity: 1; transform: none; }

main.card.auth-page .field-check {
  flex: none; width: 20px; height: 20px; margin-right: 13px;
  display: grid; place-items: center;
  background: var(--accent); color: var(--accent-fg); border-radius: 50%;
  opacity: 0; transform: scale(.6);
  transition: opacity 180ms ease, transform 240ms var(--auth-ease-out);
}
main.card.auth-page .field-check svg { width: 12px; height: 12px; }
main.card.auth-page .field[data-state="valid"] .field-check {
  opacity: 1; transform: none; animation: auth-check-pop 320ms var(--auth-ease-out);
}
@keyframes auth-check-pop { 0% { transform: scale(.6); } 60% { transform: scale(1.08); } 100% { transform: scale(1); } }
main.card.auth-page .field-eye + .field-check { margin-left: -2px; }

main.card.auth-page .field-hint {
  margin: 0; font-size: 12.5px; line-height: 1.4; color: var(--danger);
  opacity: 0; transform: translateY(-3px);
  transition: opacity 180ms ease, transform 220ms var(--auth-ease-out);
}
main.card.auth-page .field-hint:not(:empty) { opacity: 1; transform: none; }
main.card.auth-page .field-hint:empty { display: none; }

/* ---- Dock: the submit button's home --------------------------------- */
main.card.auth-page .dock {
  position: relative; height: 108px; margin-top: 4px;
  border-radius: 999px;
  background: var(--bg);
  box-shadow: 0 0 0 1px var(--border) inset, var(--auth-dock-shadow);
  overflow: hidden; touch-action: manipulation;
}
main.card.auth-page .dock-socket {
  position: absolute; left: 50%; top: 50%;
  width: var(--cta-w, 132px); height: 44px;
  transform: translate(-50%, -50%);
  border: 1px dashed color-mix(in srgb, var(--accent) 60%, transparent);
  border-radius: 999px; opacity: 0; pointer-events: none;
  transition: opacity 200ms ease;
}
main.card.auth-page .dock-tether {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; pointer-events: none; transition: opacity 160ms ease;
}
main.card.auth-page .dock-tether line { stroke: var(--accent); stroke-width: 3; stroke-linecap: round; }
main.card.auth-page .dock-tether circle { fill: var(--accent); }
main.card.auth-page .dock.is-displaced .dock-socket,
main.card.auth-page .dock.is-displaced .dock-tether { opacity: 1; }

/* ---- The submit button ---------------------------------------------- */
main.card.auth-page .cta {
  position: absolute; left: 50%; top: 50%;
  height: 44px; min-width: 132px; padding: 0 28px; margin: 0;
  transform: translate(-50%, -50%);
  display: inline-grid; place-items: center;
  border: 0; border-radius: 999px;
  font: inherit; font-size: 15px; font-weight: 600;
  color: var(--accent-fg); background: var(--accent);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .22) inset,
    0 10px 30px -10px var(--auth-glow);
  cursor: pointer; user-select: none; white-space: nowrap;
  touch-action: manipulation; -webkit-tap-highlight-color: transparent;
  will-change: transform;
  transition:
    background-color 240ms ease, color 240ms ease,
    box-shadow 260ms var(--auth-ease-out), transform 160ms var(--auth-ease-out);
}
main.card.auth-page .cta > span {
  grid-area: 1 / 1; display: inline-grid; place-items: center;
  transition: opacity 200ms ease, transform 240ms var(--auth-ease-out), filter 200ms ease;
}
main.card.auth-page .cta-spinner,
main.card.auth-page .cta-check,
main.card.auth-page .cta-fail { opacity: 0; transform: scale(.6); }
main.card.auth-page .cta-check svg, main.card.auth-page .cta-fail svg { width: 20px; height: 20px; }
main.card.auth-page .cta-spinner {
  width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid color-mix(in srgb, currentColor 25%, transparent);
  border-top-color: currentColor;
}
main.card.auth-page .cta-spinner.is-spinning { animation: auth-spin 640ms linear infinite; }
@keyframes auth-spin { to { rotate: 360deg; } }

/* Not ready: quiet, and on a fine pointer not where you left it. auth.js
   writes the transform every frame here, so transform is NOT transitioned
   or the spring would lag a frame behind itself. */
.js main.card.auth-page .cta[aria-disabled="true"] {
  color: var(--muted); background: var(--auth-off-bg);
  box-shadow: 0 0 0 1px var(--auth-off-edge) inset, 0 6px 16px -12px rgba(0, 0, 0, .35);
  cursor: default;
  transition-property: background-color, color, box-shadow;
}
@media (hover: hover) and (pointer: fine) {
  .js main.card.auth-page .cta[aria-disabled="true"]:hover { background: var(--auth-off-bg); }
}

/* Ready. */
main.card.auth-page .cta[data-state="ready"]:hover {
  transform: translate(-50%, calc(-50% - 1px));
  background: var(--accent-hover);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .26) inset,
    0 12px 36px -10px var(--auth-glow),
    0 0 40px -16px var(--accent);
}
main.card.auth-page .cta[data-state="ready"]:active { transform: translate(-50%, -50%) scale(.965); }

/* Loading: the label blurs away, the ring takes its place. */
main.card.auth-page .cta[data-state="loading"] { transform: translate(-50%, -50%) scale(.98); cursor: progress; }
main.card.auth-page .cta[data-state="loading"] .cta-label { opacity: 0; filter: blur(4px); transform: scale(.92); }
main.card.auth-page .cta[data-state="loading"] .cta-spinner { opacity: 1; transform: none; }

/* Success: the ring resolves into a check and the button glows once. */
main.card.auth-page .cta[data-state="success"] {
  background: var(--ok); color: var(--accent-fg);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .26) inset, 0 14px 40px -8px color-mix(in srgb, var(--ok) 50%, transparent);
}
main.card.auth-page .cta[data-state="success"] .cta-label,
main.card.auth-page .cta[data-state="success"] .cta-spinner { opacity: 0; transform: scale(.7); }
main.card.auth-page .cta[data-state="success"] .cta-check { opacity: 1; transform: none; }
main.card.auth-page .cta::after {
  content: ""; position: absolute; inset: -1px; border-radius: inherit;
  opacity: 0; pointer-events: none;
}
main.card.auth-page .cta[data-state="success"]::after { animation: auth-pulse 620ms var(--auth-ease-out) forwards; }
@keyframes auth-pulse {
  0% { opacity: .9; box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 50%, transparent); }
  100% { opacity: 0; box-shadow: 0 0 0 26px transparent; }
}

/* Error: the site's danger tint, a cross, and a 3px nudge of the button only. */
main.card.auth-page .cta[data-state="error"] {
  color: var(--danger); background: var(--danger-soft);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--danger) 55%, transparent), 0 10px 30px -14px color-mix(in srgb, var(--danger) 50%, transparent);
  animation: auth-nudge 260ms var(--auth-ease-in-out);
}
main.card.auth-page .cta[data-state="error"] .cta-label,
main.card.auth-page .cta[data-state="error"] .cta-spinner { opacity: 0; transform: scale(.7); }
main.card.auth-page .cta[data-state="error"] .cta-fail { opacity: 1; transform: none; }
@keyframes auth-nudge { 0%, 100% { translate: 0 0; } 25% { translate: -3px 0; } 75% { translate: 3px 0; } }

/* ---- Status line + keyboard hint ------------------------------------ */
main.card.auth-page .status {
  display: none; margin: 0; align-items: baseline; justify-content: center; gap: 8px;
  font-size: 13px; color: var(--muted); text-align: center; min-height: 20px;
}
.js main.card.auth-page .status { display: flex; }
main.card.auth-page .status-dot {
  flex: none; width: 6px; height: 6px; border-radius: 50%;
  background: var(--faint); align-self: center;
  transition: background-color 240ms ease, box-shadow 240ms ease;
}
main.card.auth-page .status[data-tone="ready"] .status-dot { background: var(--accent); box-shadow: 0 0 10px var(--auth-glow); }
main.card.auth-page .status[data-tone="success"] .status-dot { background: var(--ok); box-shadow: 0 0 10px color-mix(in srgb, var(--ok) 50%, transparent); }
main.card.auth-page .status[data-tone="loading"] .status-dot { background: var(--accent); animation: auth-dot 900ms ease-in-out infinite; }
main.card.auth-page .status[data-tone="error"] .status-dot { background: var(--danger); }
main.card.auth-page .status[data-tone="ready"] .status-text { color: var(--accent); }
main.card.auth-page .status[data-tone="success"] .status-text { color: var(--ok); }
main.card.auth-page .status[data-tone="error"] .status-text { color: var(--danger); }
main.card.auth-page .status-text { transition: opacity 120ms ease, filter 120ms ease, color 200ms ease; }
main.card.auth-page .status-text.is-swapping { opacity: 0; filter: blur(2px); }
@keyframes auth-dot { 50% { opacity: .35; } }

main.card.auth-page .hint-keys { display: none; margin: -8px 0 0; text-align: center; font-size: 12px; color: var(--faint); }
.js main.card.auth-page .hint-keys { display: block; }
main.card.auth-page .hint-keys kbd {
  display: inline-block; padding: 1px 6px; margin: 0 1px;
  font: 500 12px/1.5 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  color: var(--muted); background: var(--surface-2);
  border: 1px solid var(--border-strong); border-bottom-width: 2px; border-radius: 6px;
}

/* ---- Magic link: a small ghost pill that wakes when the email is valid -- */
main.card.auth-page form .magic-btn {
  justify-self: center; align-self: center; margin: 2px 0 0; padding: 7px 14px 7px 12px;
  display: inline-flex; align-items: center; gap: 8px;
  background: transparent; color: var(--faint);
  border: 1px dashed var(--border-strong); border-radius: 999px;
  font: inherit; font-size: 13.5px; font-weight: 600;
  cursor: default; touch-action: manipulation; -webkit-tap-highlight-color: transparent;
  transition: color 200ms ease, border-color 200ms ease, background-color 200ms ease,
              transform 160ms var(--auth-ease-out), box-shadow 200ms ease;
}
main.card.auth-page form .magic-btn svg {
  width: 16px; height: 16px; flex: none;
  opacity: .55; transform: scale(.85);
  transition: opacity 200ms ease, transform 260ms var(--auth-ease-out);
}
main.card.auth-page form .magic-btn[aria-disabled="false"] {
  color: var(--accent); border-style: solid;
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border-strong));
  cursor: pointer;
}
main.card.auth-page form .magic-btn[aria-disabled="false"] svg { opacity: 1; transform: none; }
@media (hover: hover) and (pointer: fine) {
  main.card.auth-page form .magic-btn[aria-disabled="false"]:hover {
    background: var(--accent-soft); border-color: var(--accent);
    transform: translateY(-1px);
    box-shadow: 0 6px 18px -12px var(--auth-glow);
  }
  main.card.auth-page form .magic-btn[aria-disabled="true"]:hover { background: transparent; }
}
main.card.auth-page form .magic-btn[aria-disabled="false"]:active { transform: scale(.97); }
main.card.auth-page form .magic-btn[aria-busy="true"] { cursor: progress; color: var(--muted); }
main.card.auth-page form .magic-btn[data-done="true"] {
  color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, var(--border-strong)); cursor: default;
}
main.card.auth-page form .magic-hint {
  display: block; text-align: center; margin: -8px 0 0;
  font-size: 12px; color: var(--faint);
  opacity: 0; transform: translateY(-3px);
  transition: opacity 180ms ease, transform 220ms var(--auth-ease-out);
}
main.card.auth-page form .magic-hint.is-shown { opacity: 1; transform: none; }
main.card.auth-page form .magic-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; box-shadow: none; }

/* ---- Secondary actions --------------------------------------------- */
main.card.auth-page .auth-alt {
  margin: 18px 0 0; padding-top: 16px;
  border-top: 1px solid var(--border);
  text-align: center; font-size: 14px; color: var(--muted);
}
main.card.auth-page .auth-alt a { font-weight: 600; }

/* ---- Focus ----------------------------------------------------------- */
main.card.auth-page .cta:focus-visible,
main.card.auth-page .field-eye:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 3px; box-shadow: none;
}
main.card.auth-page .cta:focus-visible { outline-offset: 4px; }

/* ---- Responsive ------------------------------------------------------- */
@media (max-width: 640px) {
  main.card.auth-page .field-box { height: 46px; }
  main.card.auth-page .field-box input { font-size: 16px; } /* iOS: no focus zoom */
  main.card.auth-page .dock { height: 96px; }
  main.card.auth-page .hint-keys { display: none !important; }
}

/* ---- Reduced motion: keep fades, drop movement ------------------------ */
@media (prefers-reduced-motion: reduce) {
  .auth-scene { animation-duration: 1ms; animation-delay: 0s; }
  .js main.card.auth-page > * { transform: none; animation-duration: 1ms; animation-delay: 0s; }
  main.card.auth-page.is-leaving { transform: none; }
  main.card.auth-page .field-check, main.card.auth-page .field-hint, main.card.auth-page .field-eye svg { transition-property: opacity; transform: none; }
  main.card.auth-page .field[data-state="valid"] .field-check { animation: none; }
  main.card.auth-page .cta { transition-property: background-color, color, box-shadow; }
  main.card.auth-page .cta > span { transition-property: opacity, filter; transform: none !important; }
  main.card.auth-page .cta[data-state="ready"]:hover,
  main.card.auth-page .cta[data-state="ready"]:active { transform: translate(-50%, -50%); }
  main.card.auth-page .cta[data-state="error"] { animation: none; }
  main.card.auth-page .cta[data-state="success"]::after { animation: none; }
  main.card.auth-page .status[data-tone="loading"] .status-dot { animation: none; }
}

/* ---- Honeypot --------------------------------------------------------- */
/* The sign-up form's "website" field. Deliberately NOT display:none or
   hidden: the simplest form-filling bots skip fields the CSS removes,
   and this one exists to be filled. It is moved off screen instead, and
   the markup keeps it out of reach of real users (wrapper aria-hidden,
   input tabindex=-1, autocomplete=off) and out of auth.js's field set. */
main.card.auth-page .hp-wrap {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Touch devices of any width (tablets included) zoom into fields under
   16px; the phone rule above only covered 480px. */
@media (pointer: coarse) {
  main.card.auth-page .field-box input { font-size: 16px; }
}

/* ---- Password strength (sign up, reset) ----------------------------- */
/* Sits inside the field like the hint does: same 13px scale, same muted
   ink, no extra card. The bar and the checklist use the site's semantic
   tokens (danger / warn / accent / ok); the label text carries the same
   meaning so color is never the only signal. Every checklist item is a
   requirement (app/password_policy.php enforces all six), so there is no
   "required" pill singling one out; the six sit in the 2-column grid with
   the common/predictable item spanning both. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
main.card.auth-page .pw-meter { display: grid; gap: 8px; margin-top: 4px; }
main.card.auth-page .pw-meter[hidden] { display: none; }
main.card.auth-page .pw-head {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  font-size: 12.5px; line-height: 1.4;
}
main.card.auth-page .pw-title { color: var(--muted); font-weight: 600; }
main.card.auth-page .pw-label {
  font-weight: 600; color: var(--faint); text-align: right;
  transition: color 200ms ease;
}
main.card.auth-page .pw-meter[data-level="0"] .pw-label,
main.card.auth-page .pw-meter[data-level="1"] .pw-label { color: var(--danger); }
main.card.auth-page .pw-meter[data-level="2"] .pw-label { color: var(--warn); }
main.card.auth-page .pw-meter[data-level="3"] .pw-label { color: var(--accent); }
main.card.auth-page .pw-meter[data-level="4"] .pw-label { color: var(--ok); }

main.card.auth-page .pw-bar {
  height: 6px; border-radius: 999px; overflow: hidden;
  background: var(--surface-3);
  box-shadow: 0 0 0 1px var(--border) inset;
}
main.card.auth-page .pw-fill {
  display: block; height: 100%; width: 0; border-radius: inherit;
  background: var(--faint);
  transition: width 220ms ease, background-color 220ms ease;
}
main.card.auth-page .pw-meter[data-level="0"] .pw-fill { width: 8%; background: var(--danger); }
main.card.auth-page .pw-meter[data-level="1"] .pw-fill { width: 30%; background: var(--danger); }
main.card.auth-page .pw-meter[data-level="2"] .pw-fill { width: 55%; background: var(--warn); }
main.card.auth-page .pw-meter[data-level="3"] .pw-fill { width: 80%; background: var(--accent); }
main.card.auth-page .pw-meter[data-level="4"] .pw-fill { width: 100%; background: var(--ok); }

main.card.auth-page .pw-reqs {
  list-style: none; margin: 2px 0 0; padding: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: 5px 14px;
  font-size: 12.5px; line-height: 1.4;
}
main.card.auth-page .pw-reqs li {
  display: flex; align-items: center; gap: 7px; min-width: 0;
  color: var(--faint); transition: color 200ms ease;
}
main.card.auth-page .pw-reqs li[data-req="common"] { grid-column: 1 / -1; }
main.card.auth-page .pw-text { min-width: 0; }
main.card.auth-page .pw-mark {
  flex: none; width: 14px; height: 14px; border-radius: 50%;
  border: 1.5px solid var(--border-strong); background: transparent;
  display: grid; place-items: center;
  transition: border-color 200ms ease, background-color 200ms ease;
}
main.card.auth-page .pw-mark::after {
  content: ""; width: 7px; height: 4px;
  border-left: 2px solid var(--accent-fg); border-bottom: 2px solid var(--accent-fg);
  transform: rotate(-45deg) translate(1px, -1px) scale(.6); opacity: 0;
  transition: opacity 160ms ease, transform 220ms var(--auth-ease-out);
}
main.card.auth-page .pw-reqs li[data-met="true"] { color: var(--text); }
main.card.auth-page .pw-reqs li[data-met="true"] .pw-mark { background: var(--ok); border-color: var(--ok); }
main.card.auth-page .pw-reqs li[data-met="true"] .pw-mark::after { opacity: 1; transform: rotate(-45deg) translate(1px, -1px) scale(1); }

@media (max-width: 480px) {
  main.card.auth-page .pw-reqs { grid-template-columns: 1fr; gap: 6px; }
  main.card.auth-page .pw-head { flex-direction: column; align-items: flex-start; gap: 2px; }
  main.card.auth-page .pw-label { text-align: left; }
}
@media (prefers-reduced-motion: reduce) {
  main.card.auth-page .pw-fill { transition: background-color 220ms ease; }
  main.card.auth-page .pw-mark::after { transition: opacity 160ms ease; transform: rotate(-45deg) translate(1px, -1px); }
}

/* Verification code box (portal/signup.php after a sign-up). Six wide
   monospace digits so a typed code is easy to proof-read; the button row
   stands in for the dock, which this plain-POST form does not use. */
main.card.auth-page .code-box {
  font: 600 22px/1 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  letter-spacing: .28em; text-align: center;
}
main.card.auth-page .code-actions { display: flex; justify-content: flex-end; }
main.card.auth-page .code-actions .btn { padding: .6rem 1.1rem; font-weight: 600; }
