/* ===================================================================
   /signup/ and /login/ — the auth shell and its forms.

   Builds on the marketing tokens in styles.css (--bg --black --deep --surface
   --grey --soft --white --ease) and the page shell in pages.css. Mobile first,
   laid out down to 375px.

   The forms are ours (build/signup.mjs): 48px pills and fields, .9rem radius,
   one dark focus ring, sentence-case buttons — the same choices the Clerk
   `appearance` used to encode, now plain CSS at the bottom of this file.
   =================================================================== */

.signup-body .page { gap: 2rem; max-width: 76rem; }
@media (min-width: 1024px) { .signup-body .page { gap: 2.75rem; } }

/* ------------------------------------------------------------------ grid */

.signup-grid { display: grid; grid-template-columns: 1fr; gap: 1.75rem; align-items: start; }
@media (min-width: 1024px) {
  .signup-grid { grid-template-columns: 1fr 1fr; gap: 3rem; }
}
.signup-col { display: flex; flex-direction: column; gap: 1.5rem; min-width: 0; }
/* On phones the form comes first: the picker is a nicety, signing up is not. */
.signup-col-left { order: 2; }
.signup-col-right { order: 1; }
@media (min-width: 1024px) {
  .signup-col-left { order: 1; }
  .signup-col-right { order: 2; position: sticky; top: 7.5rem; }
}

/* ------------------------------------------------------------ service chip */

.su-chip {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: .4rem;
  background: var(--soft); color: var(--black);
  border-radius: 999px; padding: .45rem 1rem;
  font-size: .85rem; line-height: 1.2;
}
.su-chip[hidden] { display: none; }
.su-chip-slug { font-weight: 600; }

/* ----------------------------------------------------------- plan picker */

.plan-picker { border: 0; margin: 0; padding: 0; min-width: 0; }
.plan-legend {
  display: flex; flex-direction: column; gap: .2rem;
  padding: 0; margin-bottom: .75rem;
  font-size: .95rem; font-weight: 600; letter-spacing: -0.01em; color: var(--black);
}
.plan-legend-note { font-size: .82rem; font-weight: 400; color: #6b7378; }

.plan-grid { display: grid; grid-template-columns: 1fr; gap: .75rem; }
@media (min-width: 480px) { .plan-grid { grid-template-columns: 1fr 1fr; } }

.plan-card {
  position: relative;
  display: flex; flex-direction: column; gap: .3rem;
  background: #fff; border: 1px solid rgba(30,35,44,.12); border-radius: 1.25rem;
  padding: 1.1rem 1.1rem 1.15rem; cursor: pointer;
  transition: border-color .25s var(--ease), box-shadow .25s var(--ease), transform .25s var(--ease);
}
.plan-card:hover { border-color: rgba(30,35,44,.3); }
.plan-card.is-selected {
  border-color: var(--deep);
  box-shadow: inset 0 0 0 1px var(--deep);
}
.plan-card:focus-within { outline: 2px solid var(--deep); outline-offset: 3px; }

/* The radio stays in the accessibility tree and keeps keyboard selection
   working; the label is the visible control. */
.plan-radio { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }

.plan-flag {
  position: absolute; top: -.6rem; right: 1rem;
  background: var(--deep); color: var(--white);
  border-radius: 999px; padding: .2rem .6rem;
  font-size: .65rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
}
.plan-name { font-size: .72rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: #6b7378; }
.plan-card.is-selected .plan-name { color: var(--deep); }
.plan-price { font-size: 1.6rem; font-weight: 600; letter-spacing: -0.04em; line-height: 1.05; color: var(--black); }
.plan-per { font-size: .82rem; font-weight: 400; letter-spacing: 0; color: #6b7378; margin-left: .15rem; }
.plan-lines { display: flex; flex-direction: column; gap: .2rem; margin-top: .35rem; }
.plan-line { font-size: .85rem; line-height: 1.4; color: #4b5257; }

/* -------------------------------------------------------- what happens next */

.su-next { display: flex; flex-direction: column; gap: .85rem; }
.su-next-title { font-size: .95rem; font-weight: 600; letter-spacing: -0.01em; color: var(--black); margin: 0; }
.su-next-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .85rem; counter-reset: none; }
.su-next-item { display: flex; gap: .75rem; align-items: flex-start; }
.su-next-list.is-unordered .su-next-num { width: .5rem; height: .5rem; margin: .5rem .55rem 0 .55rem; }
.su-next-num {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.6rem; height: 1.6rem; border-radius: 999px;
  background: var(--deep); color: var(--white);
  font-size: .75rem; font-weight: 600;
}
.su-next-text { display: flex; flex-direction: column; gap: .12rem; min-width: 0; }
.su-next-head { font-size: .95rem; font-weight: 600; letter-spacing: -0.01em; color: var(--black); }
.su-next-sub { font-size: .87rem; line-height: 1.45; color: #6b7378; }

/* ------------------------------------------------------------ signup card */

.signup-card {
  background: #fff;
  border: 1px solid rgba(30,35,44,.12);
  border-radius: 1.5rem;
  padding: 1.5rem;
  display: flex; flex-direction: column; gap: 1rem;
  box-shadow: 0 24px 48px -36px rgba(12,16,22,.4);
  min-width: 0;
}
.signup-card-head { display: flex; flex-direction: column; gap: .3rem; }
.signup-card-title { font-size: 1.35rem; font-weight: 600; letter-spacing: -0.03em; line-height: 1.1; color: var(--black); margin: 0; }
.signup-card-sub { font-size: .9rem; line-height: 1.45; color: #6b7378; }

/* The mount point (legacy signup grid). */
.signup-mount { min-width: 0; display: flex; flex-direction: column; }
.signup-mount:empty { min-height: 0; }

.signup-fallback {
  font-size: .9rem; line-height: 1.5; color: #4b5257;
  background: var(--soft); border-radius: .9rem; padding: .85rem 1rem;
}
.signup-fallback[hidden] { display: none; }
.signup-fallback a { font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }

.signup-note { font-size: .9rem; line-height: 1.5; color: #4b5257; background: var(--soft); border-radius: .75rem; padding: .65rem .85rem; }

.su-fine { font-size: .9rem; color: #6b7378; }
.su-fine a { color: var(--black); text-decoration: underline; text-underline-offset: 3px; }

/* ------------------------------------------------------------------ aside */

.su-aside { min-width: 0; }
.su-aside .aside-card { max-width: 100%; }
@media (min-width: 1024px) {
  .su-aside .aside-card { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .25rem 2rem; align-items: start; padding: 1.75rem 2rem; }
  .su-aside .aside-card h3 { grid-column: 1 / -1; margin-bottom: .5rem; }
  .su-aside .aside-card .su-aside-note { grid-column: 1 / -1; }
}
.su-aside-note { font-size: .85rem; line-height: 1.5; color: var(--grey); margin: .75rem 0 0; }

/* --------------------------------------------------------------- 375px trim */

@media (max-width: 400px) {
  .signup-card { padding: 1.15rem; border-radius: 1.25rem; }
  .plan-card { padding: .95rem; }
  .plan-price { font-size: 1.4rem; }
  .su-aside .aside-card { padding: 1.25rem; }
}


/* ===================================================================
   /login/ — the auth shell.

   A full-viewport split: the form pane on the left, a dark brand panel on the
   right from 1024px up. The page is generated with renderPage({ bare: true }),
   so there is no site header, no page hero and no marketing footer here.
   =================================================================== */

.auth-body { background: var(--white); }
.auth-body .cookie-bar, .auth-body .cookie-banner { z-index: 60; }

.auth-shell {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-columns: 1fr;
}
@media (min-width: 1024px) {
  .auth-shell { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

.auth-pane {
  display: flex; flex-direction: column;
  min-width: 0; min-height: 100vh; min-height: 100dvh;
  padding: 1.25rem;
}
@media (min-width: 640px) { .auth-pane { padding: 1.75rem 2rem; } }
@media (min-width: 1024px) { .auth-pane { padding: 2rem 2.5rem; } }

/* ------------------------------------------------------------------- top bar */

.auth-bar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex: 0 0 auto; }
.auth-logo { display: inline-flex; align-items: center; gap: .55rem; }
.auth-logo img { width: 1.75rem; height: 1.75rem; }
.auth-wordmark { font-size: 1.15rem; font-weight: 600; letter-spacing: -0.045em; color: var(--black); }
.auth-bar-link {
  font-size: .875rem; font-weight: 500; color: var(--black);
  border: 1px solid rgba(30,35,44,.16); border-radius: 999px;
  padding: .5rem 1.1rem; white-space: nowrap;
  transition: border-color .25s var(--ease), background-color .25s var(--ease);
}
.auth-bar-link:hover { border-color: rgba(30,35,44,.4); background: rgba(30,35,44,.04); }
/* The way back to squiid.io: these pages are served from the console host, so "/" is not it. */
.auth-bar-actions { display: inline-flex; align-items: center; gap: .85rem; }
.auth-bar-back { font-size: .875rem; font-weight: 500; color: rgba(30,35,44,.6); white-space: nowrap; transition: color .25s var(--ease); }
.auth-bar-back:hover { color: var(--black); }
@media (max-width: 420px) { .auth-bar-back { display: none; } }

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

.auth-main { flex: 1 1 auto; display: flex; align-items: center; justify-content: center; padding: 1.25rem 0; min-width: 0; }

.auth-card {
  /* 36rem, not 25.5: at 1440 the pane is 720px wide and a 408px column left
     ~116px of nothing either side with everything stacked down the middle.
     Both cards are the same width so switching log in <-> create account never
     changes it mid-crossfade — the log-in form is simply a short card. */
  width: 100%; max-width: 36rem; min-width: 0;
  display: flex; flex-direction: column; gap: 1.1rem;
  background: #fff;
  border: 1px solid rgba(30,35,44,.10);
  border-radius: 1.5rem;
  padding: 1.75rem;
  box-shadow: 0 1px 2px rgba(12,16,22,.04), 0 24px 56px -40px rgba(12,16,22,.45);
}
@media (max-width: 400px) { .auth-card { padding: 1.25rem; border-radius: 1.25rem; } }

.auth-head { display: flex; flex-direction: column; gap: .35rem; }
.auth-title { font-size: 1.65rem; font-weight: 600; letter-spacing: -0.04em; line-height: 1.05; color: var(--black); margin: 0; }
.auth-sub { font-size: .9rem; line-height: 1.45; color: #6b7378; }

.auth-mount { min-width: 0; display: flex; flex-direction: column; }

/* --------------------------------------------------------------- legal line */

.auth-legal {
  flex: 0 0 auto;
  display: flex; flex-wrap: wrap; align-items: center; gap: .25rem 1rem;
  font-size: .78rem; color: var(--grey);
  /* Positioned so the gift-code popover it carries paints over the card, which
     GSAP's entrance tween leaves in a stacking context of its own. */
  position: relative; z-index: 50;
}
.auth-legal a { color: #6b7378; }
.auth-legal a:hover { color: var(--black); text-decoration: underline; text-underline-offset: 3px; }

/* -------------------------------------------------------------- brand panel */

.auth-brand { display: none; }
@media (min-width: 1024px) {
  .auth-brand {
    display: block; position: relative; overflow: hidden;
    background: var(--deep);
  }
  .auth-brand-video {
    position: absolute; inset: 0;
    width: 100%; height: 100%; object-fit: cover;
    opacity: 0; filter: grayscale(1) contrast(1.04) brightness(1.12);
  }
  /* two videos are stacked; signup.js crossfades .is-active when the page switches */
  .auth-brand-video.is-active { opacity: .68; }
  .auth-brand-veil {
    position: absolute; inset: 0;
    background:
      linear-gradient(180deg, rgba(12,16,22,.35) 0%, rgba(12,16,22,.05) 38%, rgba(12,16,22,.88) 100%),
      linear-gradient(90deg, rgba(12,16,22,.55) 0%, rgba(12,16,22,0) 42%);
  }
  .auth-brand-line {
    position: absolute; left: 3rem; right: 3rem; bottom: 3rem;
    font-size: clamp(1.9rem, 2.4vw, 2.6rem); font-weight: 600;
    letter-spacing: -0.045em; line-height: 1.08;
    color: var(--white);
  }
}
@media (prefers-reduced-motion: reduce) { .auth-brand-video { display: none; } }

/* ===================================================================
   The forms
   =================================================================== */

.auth-form { display: flex; flex-direction: column; gap: .75rem; min-width: 0; }
.auth-form[hidden] { display: none; }

.auth-social { display: grid; grid-template-columns: 1fr; gap: .5rem; }
/* Side by side from the width the wide card gives them (the card is 36rem from
   1024px up, its own padding taken off). */
@media (min-width: 560px) { .auth-social { grid-template-columns: 1fr 1fr; } }

.auth-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
  height: 48px; min-height: 48px; width: 100%;
  border-radius: 999px; border: 1px solid transparent;
  font: inherit; font-size: .95rem; font-weight: 600; letter-spacing: 0;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background-color .2s var(--ease), border-color .2s var(--ease), opacity .2s var(--ease);
}
.auth-btn-primary { background: #0C1016; color: #F0F6F8; }
.auth-btn-primary:hover, .auth-btn-primary:focus-visible { background: #1E242C; }
.auth-btn-social { height: 44px; min-height: 44px; background: #fff; color: var(--black); border-color: rgba(30,35,44,.15); font-weight: 500; font-size: .9rem; }
.auth-btn-social:hover, .auth-btn-social:focus-visible { background: #F0F6F8; border-color: rgba(30,35,44,.3); }
.auth-btn-social svg { flex: 0 0 auto; }
.auth-btn[disabled], .auth-btn[aria-busy="true"] { opacity: .55; cursor: progress; }
.auth-btn:focus-visible { outline: 2px solid var(--deep); outline-offset: 2px; }

.auth-rule { display: flex; align-items: center; gap: .85rem; margin: 0; color: #8b9296; font-size: .8rem; }
.auth-rule::before, .auth-rule::after { content: ""; flex: 1 1 auto; height: 1px; background: rgba(30,35,44,.12); }

.auth-field { display: flex; flex-direction: column; gap: .35rem; min-width: 0; }
.auth-label { font-size: .85rem; font-weight: 500; color: #4b5257; }
.auth-label-row { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.auth-input {
  height: 44px; min-height: 44px; width: 100%;
  border-radius: .9rem; border: 1px solid rgba(30,35,44,.15);
  background: #fff; color: var(--black);
  padding: 0 1rem; font: inherit; font-size: .95rem;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.auth-input::placeholder { color: #a3a9ad; }
.auth-input:focus, .auth-input:focus-visible { outline: none; border-color: var(--deep); box-shadow: 0 0 0 1px var(--deep); }
.auth-input[aria-invalid="true"] { border-color: #9a3b3b; }

.auth-link { background: none; border: 0; padding: 0; font: inherit; color: #0C1016; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.auth-link:hover { color: #1E242C; }
.auth-link-sm { font-size: .8rem; font-weight: 500; color: #6b7378; }
.auth-link-sm:hover { color: var(--black); }

.auth-msg { margin: 0; padding: .65rem .85rem; border-radius: .75rem; font-size: .875rem; line-height: 1.45; }
.auth-msg[hidden] { display: none; }
.auth-msg.is-error { background: rgba(154,59,59,.08); color: #9a3b3b; }
.auth-msg.is-notice { background: var(--soft); color: #1E232C; }

.auth-fine { margin: -.15rem 0 0; text-align: center; font-size: .78rem; line-height: 1.45; color: #8b9296; }
/* Two lines at the wide card's width, so it reads as a footnote rather than a
   paragraph; the three links stay. */
@media (min-width: 560px) { .auth-fine { font-size: .76rem; line-height: 1.4; } }
.auth-fine a { color: #6b7378; text-decoration: underline; text-underline-offset: 3px; }
.auth-fine a:hover { color: var(--black); }

/* "Check your email": the form folds down to the notice. The way to the other
   card is the pill in the top bar, which the fold never touches. */
.auth-form.is-sent > :not(.auth-msg) { display: none; }
/* …except on the two extra log-in panes, where the way back is that last line
   and the bar only offers the other card. */
.auth-form-pane.is-sent > .auth-fine { display: block; }

/* ===================================================================
   First / last name, the password rules, and the two extra log-in panes.

   The sign-up card grew four things at once — two name fields, a strength
   meter, a rule checklist and a confirm box — so every one of them is laid out
   to cost as little height as possible: the names share a row, the meter is a
   3px bar with a one-word verdict beside it, and the rules are a two-column
   grid of 12px lines. The card still fits 1440x800 and 1280x720 (see the
   max-height block above, which trims all of it one step further).
   =================================================================== */

/* Two fields on one row, stacked again only where a phone makes them too narrow. */
/* First/Last, and Password/Confirm: two fields abreast, using the card's
   width instead of another 80px of stack. Below the wide card they stack. */
.auth-row { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; min-width: 0; align-items: start; }
@media (max-width: 560px) { .auth-row { grid-template-columns: 1fr; } }

/* ------------------------------------------------------- password + the eye */

.auth-pw { position: relative; display: flex; align-items: center; min-width: 0; }
.auth-input-pw { padding-right: 2.85rem; }
.auth-eye {
  position: absolute; right: .4rem;
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; padding: 0;
  border: 0; border-radius: 999px; background: none;
  color: #8b9296; cursor: pointer;
  transition: color .2s var(--ease), background-color .2s var(--ease);
}
.auth-eye:hover { color: #1E232C; background: rgba(30,35,44,.06); }
/* The browser's own `[hidden] { display: none }` is namespaced to HTML, so an
   SVG with the attribute still paints. Say it again for the two eye icons. */
.auth-eye-icon[hidden] { display: none; }
.auth-eye:focus-visible { outline: 2px solid var(--deep); outline-offset: 1px; }

/* --------------------------------------------- strength meter and rule chips */

/* Eight pixels under the Password / Confirm row (the form's own gap is 12), ten
   between the track and the chips, and then the form's gap again to the button. */
.auth-pw-strength { display: flex; flex-direction: column; gap: 10px; margin-top: -4px; min-width: 0; }

/* One continuous 4px track, edge to edge, that fills a quarter at a time. Four
   separate segments read as four things stopping short of the right edge; this
   reads as one measurement of one password. */
.auth-pw-track {
  display: block; width: 100%; height: 4px;
  border-radius: 999px; background: rgba(30,35,44,.09);
  overflow: hidden;
}
.auth-pw-fill {
  display: block; width: 0; height: 100%;
  border-radius: 999px; background: #b9c0c4;
  transition: width .3s var(--ease), background-color .3s var(--ease);
}
/* grey -> amber -> mint, the same four steps the word beside the label names. */
.auth-pw-track.is-1 .auth-pw-fill { width: 25%; background: #b9c0c4; }
.auth-pw-track.is-2 .auth-pw-fill { width: 50%; background: #d9a441; }
.auth-pw-track.is-3 .auth-pw-fill { width: 75%; background: #7d8a5e; }
.auth-pw-track.is-4 .auth-pw-fill { width: 100%; background: #2f9e63; }

/* The verdict sits on the Password label's own row, right-aligned, and says
   nothing until there is something to judge. */
.auth-pw-word { font-size: .75rem; font-weight: 500; color: #8b9296; white-space: nowrap; }

/* Four equal chips on the same .6rem gutter the two field columns use, so the
   join between the second and third chip lands on the gutter between Password
   and Confirm. Equal columns, flush to both edges. */
.auth-pw-rules {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .6rem;
  list-style: none; margin: 0; padding: 0; min-width: 0;
}
@media (max-width: 560px) { .auth-pw-rules { grid-template-columns: 1fr 1fr; gap: .45rem; } }

.auth-chip {
  display: flex; align-items: center; justify-content: center; gap: .35rem;
  min-width: 0; padding: .35rem .4rem;
  border: 1px solid rgba(30,35,44,.12); border-radius: .6rem;
  font-size: .75rem; line-height: 1.2; white-space: nowrap;
  color: #8b9296;
  transition: color .2s var(--ease), border-color .2s var(--ease), background-color .2s var(--ease);
}
.auth-chip-icon { flex: 0 0 auto; color: rgba(30,35,44,.22); transition: color .2s var(--ease); }
.auth-chip-check { opacity: 0; transition: opacity .2s var(--ease); }
.auth-chip.is-met { color: #1E232C; border-color: rgba(47,158,99,.35); background: rgba(47,158,99,.06); }
.auth-chip.is-met .auth-chip-icon { color: #2f9e63; }
.auth-chip.is-met .auth-chip-check { opacity: 1; }

/* ------------------------------------------------------- inline field errors */

.auth-err { font-size: .76rem; line-height: 1.4; color: #9a3b3b; }
.auth-err[hidden] { display: none; }

/* The quiet row under the password on /login/ ("Forgot password?"). */
.auth-aside-row { margin: -.25rem 0 0; display: flex; justify-content: flex-end; }

/* -------------------------------------------------------------- the code boxes */

.auth-otp { display: flex; gap: .35rem; min-width: 0; }
.auth-otp input {
  flex: 1 1 0; min-width: 0; width: 100%;
  height: 46px; padding: 0;
  border-radius: .7rem; border: 1px solid rgba(30,35,44,.15);
  background: #fff; color: var(--black);
  font: 600 1.05rem/1 "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  text-align: center;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.auth-otp input:focus { outline: none; border-color: var(--deep); box-shadow: 0 0 0 1px var(--deep); }
@media (max-width: 400px) { .auth-otp { gap: .25rem; } .auth-otp input { height: 42px; font-size: .95rem; } }

/* the card's inner content is what animates on a sign-in ↔ sign-up switch */
.auth-swap-target { will-change: transform, opacity; }

/* Short laptop screens (a 1280x720 or 1366x768 panel, minus the browser chrome):
   the card is fixed to the viewport here, so it has to fit rather than scroll.
   One step down in every dimension, proportionally, so it still reads as the
   same card with room around it. */
@media (min-width: 1024px) and (max-height: 800px) {
  .auth-pane { padding: 1.25rem 2.5rem; }
  .auth-main { padding: .75rem 0; }
  .auth-card { gap: .9rem; padding: 1.5rem; }
  .auth-head { gap: .25rem; }
  .auth-title { font-size: 1.45rem; }
  .auth-form { gap: .65rem; }
  .auth-social { gap: .45rem; }
  .auth-btn-social, .auth-input { height: 42px; min-height: 42px; }
  .auth-btn-primary { height: 46px; min-height: 46px; }
  .auth-row { gap: .5rem; }
  .auth-pw-strength { gap: 8px; margin-top: -3px; }
  .auth-chip { padding: .28rem .35rem; font-size: .72rem; }
  .auth-otp input { height: 42px; }
  .auth-fine { font-size: .74rem; line-height: 1.4; }
}

/* Shorter than that again (a small window, a big zoom): the card stops
   pretending it fits and the pane scrolls, because a clipped card whose legal
   line lands on top of its own fine print is worse than a scrollbar. */
@media (min-width: 1024px) and (max-height: 640px) {
  .auth-pane { overflow-y: auto; }
  .auth-main { align-items: flex-start; }
}

/* The auth screens are fixed to the viewport from 1024px up: nothing to scroll to.
   Below that the card can be taller than a phone screen, so scrolling stays on. */
@media (min-width: 1024px) {
  html:has(.auth-body), .auth-body { height: 100%; overflow: hidden; overscroll-behavior: none; }
  .auth-shell { height: 100vh; height: 100dvh; min-height: 0; }
  .auth-pane { height: 100vh; height: 100dvh; min-height: 0; overflow: hidden; }
  .auth-main { min-height: 0; }
  /* both forms sit in a box the height of the taller one (sign-up), so the two cards match */
}

/* -------------------------------------------------------------------
   "Have a code?": the SQUIIDY easter egg. A quiet link at the right end of the
   footer that opens a small popover above itself, rather than a row inside the
   card — on a sign-up card an always-there code field reads like a checkout
   page, and it made the card taller than a laptop screen. Only on sign-up; a
   cookie carries the code to the console (/start reads it), so it is
   independent of auth.
   ------------------------------------------------------------------- */
.auth-code { position: relative; margin-left: auto; display: inline-flex; }
.auth-code[hidden] { display: none; }
[data-auth-kind="sign-in"] .auth-code { display: none; }
.auth-code-toggle { padding: 0; border: 0; background: none; font: 500 .78rem/1.4 Inter, ui-sans-serif, system-ui, sans-serif; color: #8b9296; cursor: pointer; text-decoration: none; white-space: nowrap; transition: color .2s; }
.auth-code-toggle:hover, .auth-code-toggle:focus-visible { color: #1E232C; text-decoration: underline; text-underline-offset: 3px; }
/* Once the code is in, the link says so and stops looking like an invitation. */
.auth-code.is-applied .auth-code-toggle { color: #2f9e63; font-weight: 600; }
.auth-code.is-applied .auth-code-toggle:hover { color: #2f9e63; }

/* The popover: anchored above the link, right-aligned so it can never run off
   the pane (which is `overflow: hidden` from 1024px up). */
.auth-code-pop {
  position: absolute; right: 0; bottom: calc(100% + .6rem); z-index: 40;
  width: 17.5rem; max-width: calc(100vw - 2.5rem);
  display: flex; flex-direction: column; gap: .5rem;
  background: #fff; border: 1px solid rgba(30,35,44,.10); border-radius: 1rem;
  padding: .9rem;
  box-shadow: 0 1px 2px rgba(12,16,22,.05), 0 18px 40px -22px rgba(12,16,22,.5);
}
.auth-code-pop[hidden] { display: none; }
.auth-code-title { font-size: .78rem; font-weight: 600; letter-spacing: .01em; color: #4b5257; }
.auth-code-row { display: flex; align-items: center; gap: .5rem; min-width: 0; }
.auth-code-row .auth-code-input { flex: 1 1 auto; min-width: 0; }
.auth-code-input { height: 40px; padding: 0 .9rem; border-radius: 999px; border: 1px solid rgba(30,35,44,.14); background: #fff; font: 500 .85rem/1 "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .08em; text-transform: uppercase; color: #1E232C; outline: none; transition: border-color .2s, box-shadow .2s; }
.auth-code-input:focus { border-color: #1E232C; box-shadow: 0 0 0 3px rgba(30,35,44,.08); }
.auth-code-input.is-valid { border-color: #3ddc84; box-shadow: 0 0 0 3px rgba(61,220,132,.18); }
.auth-code-apply { flex: 0 0 auto; height: 40px; padding: 0 1rem; border: 0; border-radius: 999px; background: #0C1016; color: #F0F6F8; font: 600 .8rem/1 Inter, ui-sans-serif, system-ui, sans-serif; cursor: pointer; transition: background-color .2s; }
.auth-code-apply:hover:not(:disabled) { background: #1E242C; }
.auth-code-apply:disabled { opacity: .45; cursor: default; }
.auth-code-error { margin: 0; font-size: .78rem; line-height: 1.4; color: #9a3b3b; }
.auth-code-error[hidden] { display: none; }
.auth-code-ok { margin: 0; font-size: .78rem; line-height: 1.4; color: #2f9e63; }
.auth-code-ok[hidden] { display: none; }

/* Narrow screens: the popover spans the pane rather than hanging off the link. */
@media (max-width: 480px) {
  .auth-code-pop { right: 0; width: calc(100vw - 2.5rem); }
}

/* 16-bit confetti, ported from main.js's deep-end burst (styles.css .deep-confetti).
   Fixed to the viewport, and on <body>, because the pane it bursts from clips
   its overflow from 1024px up. */
.auth-confetti { position: fixed; width: 0; height: 0; pointer-events: none; z-index: 80; }
.auth-confetti i { position: absolute; left: -3px; top: -3px; width: 6px; height: 6px; display: block; }

/* The card with no auth behind it: the forms are replaced by one honest line
   (signup.js, /api/public/auth-config). */
.auth-notice { margin: 0; padding: .9rem 1rem; border-radius: .75rem; background: var(--soft); font-size: .875rem; line-height: 1.5; color: #1E232C; }
.auth-notice[hidden] { display: none; }
.auth-notice a { color: #0C1016; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
