/* Sign-in surface. Shared by /login, /login/dev and the out-of-band account
   pages (/forgot, /reset, /verify).

   HOUSE RULES THIS FILE FOLLOWS:
   1. Shades, not colours. Wayfinding and state are greyscale steps. Colour is
      reserved for meaning that is genuinely semantic (error, success, caution)
      and for third-party brand marks, which must stay recognisable. The old
      purple focus ring and purple "create account" link were decoration
      carrying no meaning, and are gone.
   2. Every control reads as a control at rest — a border, a distinct fill, or
      an underline before you ever hover it. Nothing is discoverable only by
      hovering: a first-time user has no reason to hover, and a touch screen
      never fires hover at all. */

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

:root {
  color-scheme: dark light;

  --ground: #101012;
  --card: #17171a;
  --raise: #1d1d21;
  --edge: #2a2a2e;
  --edge-strong: #3a3a40;
  --text: #e8e6e3;
  --dim: #9b9892;
  --faint: #6d6a66;
  --ok: #7ab98a;
  --fail: #e07a7a;
  --warn: #d6a860;
  --focus: #8f8d88;
  --radius: 10px;
  /* v77: reinstated for the sign-in surface only, to match the reference. */
  --accent: #8b7cf6;
  --accent-edge: rgba(139, 124, 246, 0.7);
}

@media (prefers-color-scheme: light) {
  :root {
    --ground: #f4f4f2;
    --card: #ffffff;
    --raise: #f7f7f5;
    --edge: #dedcd8;
    --edge-strong: #c4c1bb;
    --text: #1d1d1f;
    --dim: #5f5d59;
    --faint: #86837e;
    --ok: #2f7d4a;
    --fail: #b4453f;
    --warn: #8a6420;
    --focus: #6f6d68;
    --accent: #6d4fe0;
    --accent-edge: rgba(109, 79, 224, 0.7);
  }
}

/* v85: the grid-centring and the 24px padding here existed to place .card in
   the middle of the viewport. .card is gone — every page using this sheet is
   now the two-column .auth layout — so what is left is the typography and
   colour every rule below inherits from. */
body {
  min-height: 100vh;
  background: var(--ground);
  color: var(--text);
  font: 14px/1.55 -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* ---- masthead ---- */

.logo { display: flex; align-items: center; margin-bottom: 14px; }
/* HEIGHT ONLY. Written when the mark was 256x141 and the pair it replaced was
   square, so the old `width: 46px; height: 46px` squashed it into its own box.
   v120's hummingbird is square again (256x256) and the rule happens to be
   harmless for it, but it stays height-only: it is the shape-independent form,
   and the shape has now changed twice.

   One image, not a light/dark pair, and that is a constraint on the ARTWORK
   rather than a happy accident of it. The mark has to land on the dark auth
   card and on a light page alike, so its five facets are placed inside the
   lightness window where each clears 3:1 against both grounds — which is why
   the bird is a mid emerald rather than the deep #004C25 of the source file.
   Pick a mark that only works on one ground and the two rules that used to
   swap between them come back, along with the bug where both showed at once. */
.logo img { height: 30px; width: auto; display: block; }

.brand {
  font-family: Georgia, 'Times New Roman', serif;
  font-weight: 500;
  font-size: 25px;
  letter-spacing: -0.01em;
  text-align: center;
}

#tagline, .sub {
  color: var(--dim);
  text-align: center;
  margin-top: 5px;
  font-size: 13.5px;
}

/* The developer card should be tellable from the marketing one at a glance,
   without reaching for a colour: a small lettered chip does it. */
.chip {
  display: block;
  width: fit-content;
  margin: 12px auto 0;
  padding: 3px 9px;
  border: 1px solid var(--edge);
  border-radius: 999px;
  background: var(--raise);
  color: var(--dim);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.09em;
}
.chip[hidden] { display: none; }

/* ---- form ---- */

form { margin-top: 22px; }

label, .label {
  display: block;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--dim);
  margin-bottom: 6px;
}

.field { margin-bottom: 14px; }
.field[hidden] { display: none; }

/* Label left, inline action (Forgot? / Show) right, both on one baseline so
   the action never reads as a stray fragment. */
.field-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }

input[type="text"], input[type="email"], input[type="password"] {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--edge-strong);
  border-radius: var(--radius);
  background: var(--ground);
  color: var(--text);
  font: inherit;
}
input::placeholder { color: var(--faint); }
input:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -1px;
  border-color: var(--focus);
}
input[aria-invalid="true"] { border-color: var(--fail); }

/* Password field with the reveal button docked inside it. */
.pw-wrap { position: relative; display: flex; }
.pw-wrap input { padding-right: 72px; }
.reveal {
  position: absolute;
  right: 5px;
  top: 50%;
  transform: translateY(-50%);
  padding: 5px 9px;
  border: 1px solid var(--edge);
  border-radius: 7px;
  background: var(--raise);
  color: var(--dim);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}
.reveal:hover { border-color: var(--edge-strong); color: var(--text); }
.reveal:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }

/* ---- password strength ---- */
/* Greyscale bars: the NUMBER of filled segments carries the meaning, so this
   still reads for a colour-blind user and obeys shades-not-colours. The word
   beside it is the real signal; the bars only reinforce it. */
.strength { margin-top: 9px; }
.strength[hidden] { display: none; }
.bars { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; }
.bar { height: 3px; border-radius: 2px; background: var(--edge); }
.bar.on { background: var(--dim); }
.bar.on.full { background: var(--text); }
.strength-note { margin-top: 6px; font-size: 11.5px; color: var(--dim); }

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

.primary {
  width: 100%;
  margin-top: 6px;
  padding: 11px;
  border: 1px solid var(--text);
  border-radius: var(--radius);
  background: var(--text);
  color: var(--card);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.primary:hover:not(:disabled) { background: var(--dim); border-color: var(--dim); }
.primary:disabled { opacity: 0.45; cursor: default; }
.primary:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

.provider {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  margin-bottom: 8px;
  padding: 11px;
  border: 1px solid var(--edge-strong);
  border-radius: var(--radius);
  background: var(--raise);
  color: var(--text);
  font: inherit;
  font-weight: 500;
  cursor: pointer;
}
.provider:hover:not(:disabled) { background: var(--ground); border-color: var(--focus); }
.provider:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.provider.soon { opacity: 0.5; cursor: default; }
.provider .soon-tag {
  margin-left: 4px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--dim);
}
.picon { display: inline-flex; flex: none; }
.picon svg { width: 17px; height: 17px; display: block; }

/* Quiet text button — "Forgot?", "Create account", "Resend". Underlined at
   rest so it reads as an action without needing a colour to say so. */
.link-btn {
  padding: 0;
  border: none;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 12px;
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-color: var(--edge-strong);
  cursor: pointer;
}
.link-btn:hover { text-decoration-color: var(--text); }
.link-btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 3px; }
.link-btn.quiet { color: var(--dim); }
.link-btn:disabled { opacity: 0.5; cursor: default; }

/* ---- divider ---- */

.divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 18px 0;
  color: var(--faint);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.09em;
}
.divider[hidden] { display: none; }
.divider::before, .divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--edge);
}

/* ---- messages ---- */

/* One block for every outcome. A leading rule in the semantic colour plus the
   text; the panel itself stays neutral so an error never repaints the card. */
.msg {
  margin-top: 14px;
  padding: 10px 12px;
  border: 1px solid var(--edge);
  border-left: 3px solid var(--dim);
  border-radius: 8px;
  background: var(--raise);
  font-size: 13px;
  line-height: 1.5;
}
.msg[hidden] { display: none; }
.msg.err { border-left-color: var(--fail); }
.msg.ok { border-left-color: var(--ok); }
.msg.info { border-left-color: var(--dim); }
.msg .msg-action { display: block; margin-top: 8px; }

.foot {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--edge);
  text-align: center;
  color: var(--dim);
  font-size: 13px;
}
.foot[hidden] { display: none; }
.foot .link-btn { font-size: 13px; margin-left: 4px; }

.hint { margin-top: 10px; font-size: 11.5px; color: var(--faint); line-height: 1.5; }

/* Caps-lock warning under the password field. It is advice, not an error, so
   it never takes the error colour. */
.caps { margin-top: 7px; font-size: 11.5px; color: var(--warn); }
.caps[hidden] { display: none; }

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

@keyframes shake-x {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); }
  40%, 60% { transform: translateX(4px); }
}
.shake { animation: shake-x 0.4s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; }

/* Busy state swaps the label text as well as dimming, so a screen reader
   announces the change rather than watching an opacity that means nothing. */
.primary[aria-busy="true"] { opacity: 0.6; }

@media (prefers-reduced-motion: reduce) {
  .shake { animation: none; }
}

/* Code entry. Wide tracking and a monospace face so six digits are read as
   six discrete characters — the thing being copied out of an email — rather
   than as a number. */
.code-input {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 24px;
  letter-spacing: 0.32em;
  text-align: center;
  padding: 12px 12px 12px 22px; /* offset the trailing letter-space so it optically centres */
}

/* ---- account pages (/forgot /reset /verify) ---- */

.step[hidden] { display: none; }

/* v47: the reset is one card now — ask for the address, then take the code and
   the new password without leaving the page. These two carry the second stage. */

/* Who the code went to, with a way back if it was the wrong address. */
.sent-to {
  margin: 0 0 14px;
  font-size: 12.5px;
  color: var(--faint);
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}
.sent-to b { color: var(--text); font-weight: 500; overflow-wrap: anywhere; }

/* Sits directly under its field rather than at the foot of the card, so the
   note about where to find the code is next to the box it refers to. */
.hint.inline { margin-top: 6px; }

/* The password half of the second stage, revealed once the code is complete. */
#cp-pw-block[hidden] { display: none; }
#code-form[hidden] { display: none; }
#forgot-form[hidden] { display: none; }
.back { margin-top: 18px; text-align: center; }
.big-note { text-align: center; padding: 4px 0 2px; }
.big-note .glyph { display: block; margin-bottom: 10px; font-size: 26px; line-height: 1; color: var(--dim); }

/* v33: unavailable providers stay on the card, marked. They are visibly
   secondary — dimmer and tighter than a live one — so the eye still lands on
   the way in that actually works, while the others answer "is Facebook
   supported?" without anyone having to ask. */
.provider.soon {
  padding: 8px 11px;
  opacity: 0.62;
  cursor: not-allowed;
  border-style: dashed;
}
.provider.soon:hover { background: var(--raise); border-color: var(--edge-strong); }
.provider .soon-tag {
  margin-left: 6px;
  padding: 1px 6px;
  border: 1px solid var(--edge-strong);
  border-radius: 999px;
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--dim);
}
/* Brand marks read as an endorsement when a provider is not actually offered
   yet; draining them keeps the row honest without losing recognisability. */
.provider.soon .picon svg { filter: grayscale(1); }



/* ==== v78: the reference sign-in, matched to its literal values ============
   The source is a React + Tailwind component. There is no Tailwind here, so
   each utility is resolved to the value it compiles to and written out:

     rounded-2xl      16px          max-w-md     448px
     rounded-3xl      24px          w-64         256px
     gap-6 / space-y-5  24px / 20px p-4 / p-5 / p-8  16 / 20 / 32px
     text-4xl / 5xl   36px / 48px   text-sm      14px
     violet-400       #a78bfa       violet-500   #8b5cf6
                      (v120: both re-hued to the brand green — see --brand-400)

   v85: scoped to body.auth-body, which login.html AND account.html now both
   set. /forgot, /reset and /verify used to fall through to a centred card,
   so the page you reached from a recovery email looked like a different
   product from the one you had just been trying to sign in to. There is one
   signed-out design now; the card it fell back to has been deleted. */

.auth-body {
  /* shadcn dark tokens, as the reference renders them. */
  --background: #09090b;
  --foreground: #fafafa;
  --muted-foreground: #a1a1aa;
  --a-border: #27272a;
  --secondary: #27272a;
  --primary: #fafafa;
  --primary-foreground: #18181b;
  /* v120 THE BRAND ACCENT, AND IT IS NO LONGER VIOLET.
     The reference component this page reproduces used Tailwind's violet-400
     and violet-500, and the tokens carried those names. InfiniteFly's mark is
     green, so the names were about to describe the opposite of their values —
     renamed rather than quietly repurposed, because a token called --violet
     holding a green is how the next person paints something violet by
     accident.
     Same treatment as go.css's ramp: OKLCH lightness and chroma held, hue
     moved 289 to 153, so the reference's tonal choices survive intact.
     8.24:1 and 5.50:1 on this page's #09090b, against 7.31 and 4.70 before. */
  --brand-400: #3BBD70;
  --brand-500: #009B52;

  min-height: 100dvh;
  background: var(--background);
  color: var(--foreground);

  /* PIN THE LEGACY TOKENS DARK.
     This surface is dark unconditionally — it declares --background: #09090b
     and ignores prefers-color-scheme entirely. But most rules in this file
     predate it and are written against --raise / --edge / --text / --dim,
     which the :root light block above flips to near-white.
     On a machine set to light that produced an error box with a near-white
     background and, inherited from --foreground here, near-white text: the
     message telling you what went wrong was the one thing you could not read.
     The strength bars and every hairline had the same problem, in reverse.
     A surface that opts out of the colour scheme has to opt out of ALL of it. */
  --ground: #101012;
  --card: #17171a;
  --raise: #1d1d21;
  --edge: #2a2a2e;
  --edge-strong: #3a3a40;
  --text: #e8e6e3;
  --dim: #9b9892;
  --faint: #6d6a66;
  --ok: #7ab98a;
  --fail: #e07a7a;
  --warn: #d6a860;
  --focus: #8f8d88;
  --accent: #8b7cf6;
  --accent-edge: rgba(139, 124, 246, 0.7);
  /* UA widgets (autofill, native controls) must match the surface, not the OS. */
  color-scheme: dark;
}

/* v119.10 The toggle's other half. The surface stays an OS-ignoring opt-out —
   see the PIN comment above — but the choice is now the VISITOR'S, made with
   the .theme-toggle button and remembered in localStorage ('auth-theme').
   Every token the dark block pins is re-pinned here; a token overridden in
   one theme and inherited in the other is how the unreadable-error-box bug
   above happened the first time. */
.auth-body.light {
  --background: #f7f6f3;
  --foreground: #18181b;
  --muted-foreground: #55555c;
  --a-border: #dcdad5;
  --secondary: #ececea;
  --primary: #18181b;
  --primary-foreground: #fafafa;
  /* Darker greens, for the same reason the violets were darkened: the dark
     theme's --brand-400 is 1.9:1 as link text on this near-white ground.
     5.45:1 and 4.38:1 here — the second is a checkbox FILL, not text, so it is
     read against the 3:1 bar for a UI component. */
  --brand-400: #00743C;
  --brand-500: #008545;

  --ground: #f4f4f2;
  --card: #ffffff;
  --raise: #f7f7f5;
  --edge: #dedcd8;
  --edge-strong: #c4c1bb;
  --text: #1d1d1f;
  --dim: #5f5d59;
  --faint: #86837e;
  --ok: #2f7d4a;
  --fail: #b4453f;
  --warn: #8a6420;
  --focus: #6f6d68;
  --accent: #6d4fe0;
  --accent-edge: rgba(109, 79, 224, 0.7);
  --glass-fill: rgba(24, 24, 27, 0.04);
  color-scheme: light;
}

/* v119.10 One control, both auth pages, fixed clear of both columns. The
   glyphs swap in CSS so the button needs no re-render — the moon shows on
   dark (press for light), the sun on light. */
.theme-toggle {
  position: fixed;
  top: 14px;
  right: 16px;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--a-border);
  background: var(--background);
  color: var(--muted-foreground);
  cursor: pointer;
}
.theme-toggle:hover { color: var(--foreground); border-color: var(--edge-strong); }
.theme-toggle:focus-visible { outline: 2px solid var(--brand-400); outline-offset: 2px; }
.theme-toggle .tt-sun { display: none; }
.auth-body.light .theme-toggle .tt-sun { display: block; }
.auth-body.light .theme-toggle .tt-moon { display: none; }

/* v119.7 The mark is centred over the form column and sized to be READ, not
   spotted: at 28px left-aligned it read as a favicon in the corner while the
   Welcome heading and tagline under it were both centred, so the one element
   naming the product was the one element off the page's axis. .auth-inner is
   a 24px-gap flex column, so margin stays 0 — the gap is the spacing. */
.auth-body .logo { justify-content: center; margin: 0; }
.auth-body .logo img { height: 64px; width: auto; }

/* The two rules that used to live here forced the on-dark mark on this page
   whatever the OS was set to, because .auth-body hardcodes a dark palette and
   the base rule swapped on prefers-color-scheme — so a machine set to light got
   the light-ground mark on a dark card, near-black on near-black. That bug is
   gone with the pair: there is one mark and it works on either ground.

   v119.10 gave this page its own theme toggle, so BOTH grounds are now live
   here rather than one being hypothetical — which is what made the green
   mark's dual-ground contrast a requirement instead of a nicety. See the note
   on .logo img above; the near-black-on-near-black failure described here is
   exactly what a #004C25 mark at 64px on this card would have reproduced. */

/* h-[100dvh] flex flex-col md:flex-row w-[100dvw] */
.auth-body .auth {
  display: flex;
  flex-direction: column;
  width: 100%;
  min-height: 100dvh;
}
@media (min-width: 768px) {
  .auth-body .auth { flex-direction: row; height: 100dvh; }
}

/* flex-1 flex items-center justify-center p-8 */
.auth-col {
  flex: 1 1 0%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  min-width: 0;
}
/* w-full max-w-md  +  flex flex-col gap-6 */
.auth-inner {
  width: 100%;
  max-width: 448px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

/* text-4xl md:text-5xl font-semibold leading-tight, with the title span
   font-light tracking-tighter — the weight contrast is the whole effect. */
.auth-body .brand {
  font-family: inherit;
  font-weight: 300;
  font-size: 36px;
  line-height: 1.25;
  letter-spacing: -0.05em;
  text-align: left;
  color: var(--foreground);
}
@media (min-width: 768px) { .auth-body .brand { font-size: 48px; } }

.auth-body #tagline {
  margin: 0;
  text-align: left;
  font-size: 14px;
  color: var(--muted-foreground);
}
.auth-wordmark {
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}
.auth-body .chip { margin: 0; text-align: left; }

/* space-y-5 */
.auth-body form { margin: 0; display: flex; flex-direction: column; gap: 20px; }
.auth-body .field { margin: 0; }

/* text-sm font-medium text-muted-foreground */
/* Field labels only — :not(.check) is load-bearing, not tidiness.
   "Keep me signed in" is also a <label>, and this rule outspecifies .check
   (0,1,1 beats 0,1,0), so `display: block` was winning and that row was never
   a flex container at all. Measured before the fix: the declared 12px gap
   rendered as 3.69px — the literal whitespace between the two tags — and the
   checkbox sat 4.5px above the middle of its own text, because with no flex
   context the two were laid out inline on a shared baseline instead. */
.auth-body label:not(.check),
.auth-body .label {
  display: block;
  font-size: 14px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: var(--muted-foreground);
  margin-bottom: 6px;
}

/* GlassInputWrapper: rounded-2xl border border-border bg-foreground/5
   backdrop-blur-sm, focus-within:border-violet-400/70 + bg-violet-500/10
   — the Tailwind names of the SOURCE, kept as provenance. The values they map
   to are --brand-400 / --brand-500, green since v120. */
.glass {
  border-radius: 16px;
  border: 1px solid var(--a-border);
  /* A tint of the FOREGROUND over the ground — 5% white lifts a dark card and
     is invisible on a light one, so the field it draws would vanish. */
  background: var(--glass-fill, rgba(250, 250, 250, 0.05));
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  transition: background-color 150ms ease, border-color 150ms ease;
}
.glass:focus-within {
  border-color: rgba(167, 139, 250, 0.7);
  background: rgba(139, 92, 246, 0.1);
}

/* w-full bg-transparent text-sm p-4 rounded-2xl focus:outline-none */
.auth-body .glass input {
  width: 100%;
  padding: 16px;
  border: none;
  border-radius: 16px;
  background: transparent;
  color: var(--foreground);
  font: inherit;
  font-size: 14px;
}
.auth-body .glass input:focus,
.auth-body .glass input:focus-visible { outline: none; }
.auth-body .glass input::placeholder { color: var(--muted-foreground); }

/* pr-12, with the toggle at inset-y-0 right-3 */
.auth-body .pw-wrap { position: relative; display: block; }
.auth-body .pw-wrap input { padding-right: 48px; }
.auth-body .reveal {
  position: absolute;
  top: 0; bottom: 0; right: 12px;
  transform: none;
  display: flex;
  align-items: center;
  padding: 0;
  border: none;
  border-radius: 0;
  background: none;
  color: var(--muted-foreground);
  cursor: pointer;
  transition: color 150ms ease;
}
.auth-body .reveal:hover { color: var(--foreground); background: none; }
.reveal svg[hidden] { display: none; }
.reveal svg { display: block; }

/* flex items-center justify-between text-sm */
.row-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 14px;
}
/* flex items-center gap-3 cursor-pointer */
.check { display: flex; align-items: center; gap: 12px; cursor: pointer; margin: 0; }
/* --foreground, not a literal near-white: the label has to follow the theme
   or "Keep me signed in" is white-on-white the moment the toggle is used. */
.check span { font-size: 14px; color: var(--foreground); text-transform: none; letter-spacing: 0; font-weight: 400; }
.check input {
  appearance: none;
  width: 20px; height: 20px;
  flex: none;
  border: 1px solid var(--edge-strong);
  border-radius: 999px;
  background: transparent;
  cursor: pointer;
  transition: background-color 150ms ease, border-color 150ms ease;
}
.check input:checked {
  border-color: var(--brand-500);
  background: var(--brand-500);
  background-image: radial-gradient(circle at 50% 50%, #fff 0 28%, transparent 30%);
}
.check input:focus-visible { outline: 2px solid var(--brand-400); outline-offset: 2px; }

/* text-violet-400 in the source, --brand-400 here, underline on hover */
.link-accent {
  padding: 0;
  border: none;
  background: none;
  color: var(--brand-400);
  font: inherit;
  font-size: inherit;
  cursor: pointer;
  text-decoration: none;
  transition: color 150ms ease;
}
.link-accent:hover { text-decoration: underline; text-underline-offset: 2px; }
.link-accent:focus-visible { outline: 2px solid var(--brand-400); outline-offset: 2px; border-radius: 3px; }

/* w-full rounded-2xl bg-primary py-4 font-medium text-primary-foreground */
.auth-body .primary {
  width: 100%;
  margin: 0;
  padding: 16px;
  border: none;
  border-radius: 16px;
  background: var(--primary);
  color: var(--primary-foreground);
  font: inherit;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 150ms ease;
}
/* The button is --primary (near-white on dark, near-black on light), so its
   hover has to move TOWARD the ground rather than always toward white. */
.auth-body .primary:hover:not(:disabled) { background: var(--primary); opacity: 0.88; }
.auth-body .primary:disabled { opacity: 0.45; cursor: default; }
.auth-body .primary:focus-visible { outline: 2px solid var(--brand-400); outline-offset: 2px; }

/* A full-width rule with the label centred over it on the page background. */
.auth-body .divider {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  border-top: 1px solid var(--a-border);
  text-transform: none;
  letter-spacing: 0;
}
.auth-body .divider::before,
.auth-body .divider::after { content: none; }
.auth-body .divider > span {
  position: absolute;
  padding: 0 16px;
  background: var(--background);
  color: var(--muted-foreground);
  font-size: 14px;
}

/* w-full flex items-center justify-center gap-3 border rounded-2xl py-4 */
.auth-body #providers { display: flex; flex-direction: column; gap: 12px; }
.auth-body .provider {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  width: 100%;
  margin: 0;
  padding: 16px;
  border: 1px solid var(--a-border);
  border-radius: 16px;
  background: transparent;
  color: var(--foreground);
  font: inherit;
  font-size: 14px;
  font-weight: 400;
  cursor: pointer;
  transition: background-color 150ms ease;
}
.auth-body .provider:hover:not(:disabled) { background: var(--secondary); border-color: var(--a-border); }
.auth-body .provider .picon svg { width: 20px; height: 20px; }

/* text-center text-sm text-muted-foreground */
.auth-body .foot {
  margin: 0;
  text-align: center;
  font-size: 14px;
  color: var(--muted-foreground);
}
.auth-body .hint, .auth-body .sub { text-align: left; }

/* ---- right column: hidden md:block flex-1 relative p-4 ---- */

.auth-hero { display: none; }
@media (min-width: 768px) {
  .auth-hero { display: block; position: relative; flex: 1 1 0%; padding: 16px; min-width: 0; }
}
/* absolute inset-4 rounded-3xl bg-cover bg-center */
.auth-art {
  position: absolute;
  inset: 16px;
  border-radius: 24px;
  background-image: url("auth-hero.jpg");
  background-size: cover;
  background-position: center;
}

/* The demo's art is dark where its cards sit; this one is at its brightest
   there, so a translucent card over it loses the sub-line entirely. A scrim
   across the bottom of the image restores the contrast the card design
   assumes, without touching the card itself. */
.auth-art::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 24px;
  background: linear-gradient(to top, rgba(9, 9, 11, 0.72) 0%, rgba(9, 9, 11, 0.34) 22%, transparent 44%);
  pointer-events: none;
}

/* absolute bottom-8 left-1/2 -translate-x-1/2 flex gap-4 px-8 w-full justify-center */
.auth-tstrip {
  position: absolute;
  bottom: 32px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 16px;
  padding: 0 32px;
  width: 100%;
  justify-content: center;
}
/* The reference reveals the 2nd and 3rd cards at xl and 2xl. */
.tcard.t2, .tcard.t3 { display: none; }
@media (min-width: 1280px) { .tcard.t2 { display: flex; } }
@media (min-width: 1536px) { .tcard.t3 { display: flex; } }

/* flex items-start gap-3 rounded-3xl bg-zinc-800/40 backdrop-blur-xl
   border border-white/10 p-5 w-64 */
.tcard {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  width: 256px;
  flex: none;
  margin: 0;
  padding: 20px;
  border-radius: 24px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(24, 24, 27, 0.55);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  color: var(--foreground);
}
/* The demo's h-10 w-10 rounded-2xl avatar slot, now holding a mark rather than
   a face. Same 40px square and 16px radius, so the card's proportions are
   untouched. */
.tcard .tmark {
  width: 40px; height: 40px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 16px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.08);
  color: #fafafa;
}
.tcard .tmark svg { display: block; }
/* text-sm leading-snug */
.tcard figcaption { font-size: 14px; line-height: 1.375; min-width: 0; }
.tname { font-weight: 500; }
.thandle { color: rgba(250, 250, 250, 0.72); }
.ttext { margin-top: 4px; color: rgba(250, 250, 250, 0.92); }

/* ---- the intro ----
   animate-element / animate-slide-right / animate-testimonial, at the
   reference's delays. Its elements start at opacity 0 and are revealed BY the
   animation, so a background tab or headless renderer ships a blank page;
   here the visible state is the default and the animation lives only inside
   no-preference. */
@media (prefers-reduced-motion: no-preference) {
  .auth-inner > * {
    opacity: 0;
    filter: blur(6px);
    transform: translateY(14px);
    animation: fadeSlideIn 700ms cubic-bezier(0.25, 0.4, 0.55, 1.4) forwards;
  }
  .auth-inner > :nth-child(1) { animation-delay: 100ms; }
  .auth-inner > :nth-child(2) { animation-delay: 200ms; }
  .auth-inner > :nth-child(3) { animation-delay: 300ms; }
  .auth-inner > :nth-child(4) { animation-delay: 400ms; }
  .auth-inner > :nth-child(5) { animation-delay: 500ms; }
  .auth-inner > :nth-child(6) { animation-delay: 600ms; }
  .auth-inner > :nth-child(7) { animation-delay: 700ms; }
  .auth-inner > :nth-child(8) { animation-delay: 800ms; }
  .auth-inner > :nth-child(n+9) { animation-delay: 900ms; }

  @keyframes fadeSlideIn {
    to { opacity: 1; filter: blur(0px); transform: translateY(0px); }
  }

  .auth-art {
    opacity: 0;
    filter: blur(6px);
    transform: translateX(28px);
    animation: slideRightIn 800ms cubic-bezier(0.25, 0.4, 0.55, 1.4) 300ms forwards;
  }
  @keyframes slideRightIn {
    to { opacity: 1; filter: blur(0px); transform: translateX(0px); }
  }

  .tcard {
    opacity: 0;
    filter: blur(8px);
    transform: translateY(20px) scale(0.96);
    animation: testimonialIn 800ms cubic-bezier(0.25, 0.4, 0.55, 1.4) forwards;
  }
  .tcard.t1 { animation-delay: 1000ms; }
  .tcard.t2 { animation-delay: 1200ms; }
  .tcard.t3 { animation-delay: 1400ms; }
  @keyframes testimonialIn {
    to { opacity: 1; filter: blur(0px); transform: translateY(0px) scale(1); }
  }
}
