/* ==========================================================================
   Fulcrium — THE AUTH SCREENS (login, TOTP enrol/verify, sign-out, one-time
   setup), rebuilt to the Dimensional Register by Task R10-3a v5.

   EVERY VALUE HERE IS READ OUT OF THE DESIGN OF RECORD —
   `docs/design/final/Fulcrium - All Screens.dc.html`, section "Getting in"
   (the <section> at lines 117-248, h2 at 120, four panels captioned at 157,
   195, 223 and 245) — and every recipe the register already carried is
   CONSUMED from css/preview/base.css rather than restated. The values the
   register did not carry are its TWELFTH `:root` block, added by this task and
   named there; nothing is re-derived here and this file holds no colour, no
   shadow and no radius literal of its own.

   THE MARKUP IS UNCHANGED except for one ruled relocation. These pages emit
   semantic HTML from api/login.php, api/enroll.php, api/totp-verify.php and
   api/setup.php through app/http.php's render_page() — h1, form, label, input,
   button, .err, .muted, .secret, .mono, details, img.qr — and this restyle is
   expressed entirely against that markup as it stands. The single exception is
   owner ruling R3: api/totp-verify.php's pre-existing
   inline margin attribute moved into the `details` rule below.

   SIX PAGES LOAD THIS FILE, NOT FOUR. The four designed screens, plus the
   sign-out page and the five one-time setup states, which have no design of
   their own and whose MARKUP is not touched (X5). Owner ruling R2 says they
   follow the restyle through this stylesheet; their rendered result is in the
   task report under V9, because setup.php seals itself with a 404 after use
   and cannot be walked.
   ========================================================================== */

/* ---- THE GROUND -----------------------------------------------------------
   FLAT, and that is owner ruling R5(c) plus the ground ruling, not a
   simplification. Before this task `getComputedStyle(document.body)
   .backgroundColor` was `rgba(0, 0, 0, 0)` on all four screens at all three
   viewports: css/base.css paints `body` with a radial-gradient shorthand, which
   leaves background-COLOR at its initial transparent. Safari tints the strips
   above and below the page from that colour, so these pages handed it nothing —
   the exact condition Tasks 107-109 eliminated everywhere else. `body.auth`
   (0,1,1) outranks css/base.css's `body` (0,0,1), so this one declaration
   settles it.                                                                */
body.auth{
  min-height:100svh;
  display:flex; align-items:center; justify-content:center;
  box-sizing:border-box;
  padding:calc(env(safe-area-inset-top) + 24px) calc(env(safe-area-inset-right) + 24px)
          calc(env(safe-area-inset-bottom) + 24px) calc(env(safe-area-inset-left) + 24px);
  background:var(--ground-auth);
  font-family:var(--font-body);
  color:var(--ink-body);
}

/* ---- THE CARD IS THE OBJECT (design line 127) ---------------------------- */
.card{
  width:100%; max-width:342px;      /* the design's 390px panel less its 24px padding */
  box-sizing:border-box;
  display:flex; flex-direction:column;
  padding:26px 22px 24px;
  border-radius:var(--radius-auth-card);
  background:var(--fill-auth-card);
  box-shadow:var(--shadow-auth-card);
}

/* ---- THE MARK, ON THE PASSWORD STEP ONLY ---------------------------------
   The design draws it on screens 1 and 2 and NOT on 3 or 4, and all four come
   out of the same renderer, so the scope is read off the markup itself:
   `name="username"` appears in api/login.php and in no other page that loads
   this file (measured — setup.php has password fields but no username field).

   IT IS A BACKGROUND IMAGE ON A PSEUDO-ELEMENT, so no markup changes and the
   mark stays decorative. The bytes are REFERENCED from assets/brand/, never
   copied: the file's gradient ids live in one place and a brand change needs no
   code change. Both routes were possible — assets/ answers 200 over HTTP from
   these pages and carries no deny rule — and the prompt's pre-ruling takes the
   reference.

   THE CROP is the same arithmetic the splash uses: the shipped file's viewBox is
   the whole 120-unit square while the artwork occupies only x 10.8-104.2,
   y 40.3-86.0 (docs/EMBLEM.md -> "Geometry"), so the box is sized by the CONTENT
   box and the image is scaled and offset to fill it. Every number comes from the
   register's four published --emblem-box-* tokens.

   ONE RENDERED WORDMARK PER SCREEN. The design pairs the emblem with the word
   "Fulcrium" set as 34px text; this app's own h1 already reads "Sign in to
   Fulcrium", so drawing the word again would render it twice on one screen. The
   emblem is drawn and the h1 carries the name — the same choice screen-splash.js
   records for the same reason. The deviation is in the task report.          */
.card:has(input[name="username"])::before{
  content:"";
  order:-1; align-self:center;
  --auth-emblem-w:132px;                                  /* design line 129 */
  width:var(--auth-emblem-w);
  height:calc(var(--auth-emblem-w) * var(--emblem-box-h) / var(--emblem-box-w));
  margin:0 0 20px;                                        /* design line 128 */
  background-image:url("/assets/brand/fulcrium-emblem.svg");
  background-repeat:no-repeat;
  background-size:calc(var(--auth-emblem-w) * var(--emblem-vb) / var(--emblem-box-w)) auto;
  background-position:
    calc(-1 * var(--auth-emblem-w) * var(--emblem-box-x) / var(--emblem-box-w))
    calc(-1 * var(--auth-emblem-w) * var(--emblem-box-y) / var(--emblem-box-w));
  filter:var(--shadow-emblem);                            /* design line 129 */
}

/* ---- THE HEADING (design line 142) --------------------------------------- */
.card h1{
  margin:0; align-self:flex-start;
  font-family:var(--font-display); font-weight:400;
  font-size:var(--type-title); line-height:1.15;
  color:var(--ink-strong);
  text-shadow:var(--emboss-title);
  -webkit-text-stroke:var(--emboss-stroke) currentColor;
}

/* ---- THE INSTRUCTION LINE (design lines 202, 230) ------------------------
   `.muted` is where owner ruling R5(a) lands. It consumed `--fs-cap`, whose
   clamp in css/base.css resolves to 10.88px at 640px of viewport height — under
   the 11px floor. It now takes --type-meta: 13px, flat, which is the size the
   design gives this text. Nothing on these pages consumes --fs-cap any more. */
.card p{ margin:0; line-height:1.45; font-size:var(--type-meta); }
.muted{
  font-family:var(--font-body); font-weight:600;
  font-size:var(--type-meta); line-height:1.45;
  color:var(--ink-sheet-soft);
}
.card h1 + .muted{ margin-top:10px; }                     /* design line 202 */

/* THE ONE PLACE THE DESIGN LOSES TO A FLOOR. The design sets this text #6B7680
   (--ink-soft) on the card. Measured against the card's DARKEST STOP #F4F7FA —
   which is how the darkest-stop doctrine measures a gradient — that is 4.31:1,
   under the 4.5 AA floor the standing rules require. --ink-sheet-soft (#5E6871)
   is the register's own soft-ink-on-a-sheet role, one step darker, and measures
   5.29:1 on the same fill. DOCTRINE OUTRANKS THE DESIGN, so the floor wins; both
   numbers are in the task report. Nothing else on these screens moved.        */

/* ---- THE ONE GENERIC MESSAGE (design lines 179-181) ----------------------
   PRESENTATION ONLY. The text is the server's and is byte-unchanged; so is the
   count of distinct messages. The single shared renderer is itself the
   non-enumeration control, and nothing here makes a failure more specific.   */
.err{
  box-sizing:border-box;
  margin:18px 0 0; padding:12px 14px;
  border-radius:var(--radius-field);
  background:var(--fill-auth-err);
  box-shadow:var(--shadow-auth-err);
  color:var(--ink-auth-err);
  font-family:var(--font-body); font-weight:700;
  font-size:var(--type-meta); line-height:1.45;
}

/* ---- THE FIELDS: LABEL + WELL (design lines 143-151) ---------------------
   The design groups each label with its well at 7px and the groups at 16px. The
   markup has no group wrapper, so the same rhythm is expressed as margins: 7px
   below a label, 16px above one, and the first label flush to the form's own
   18px offset from the heading.                                             */
form{ margin-top:18px; }
.err + form{ margin-top:16px; }
label{
  display:block; margin:16px 0 7px;
  font-family:var(--font-display); font-weight:500;
  font-size:var(--type-label); letter-spacing:var(--track-label);
  text-transform:uppercase;
  color:var(--ink-tagline);
  text-shadow:var(--emboss-label);
}
form > label:first-of-type{ margin-top:0; }

input[type=text],input[type=password]{
  width:100%; box-sizing:border-box;
  min-height:48px; padding:0 14px;
  border:0; border-radius:var(--radius-field);
  background:var(--fill-auth-well);
  box-shadow:var(--shadow-well);          /* the register's, byte-identical to the design's */
  font-family:var(--font-body); font-weight:600;
  font-size:16px;                         /* design line 146; 16px also stops iOS auto-zoom */
  color:var(--ink-body);
}
input::placeholder{ color:var(--ink-auth-placeholder); font-weight:600; }
/* No `outline:none` anywhere in this file: css/base.css's `:focus-visible` ring
   is an accessibility floor and this restyle leaves it standing. */

/* ---- THE SAGE KEY (design line 152). SAGE IS RESERVED for primary actions,
   and on these screens that is the submit button and nothing else. Every part
   of the recipe is the register's own advance key.                          */
button{
  width:100%; box-sizing:border-box;
  min-height:48px; margin-top:22px;       /* 16px group gap + the design's extra 6px */
  border:0; border-radius:var(--radius-input-pill);
  display:flex; align-items:center; justify-content:center;
  background:var(--fill-advance);
  box-shadow:var(--shadow-advance);
  color:var(--ink-advance);
  text-shadow:var(--emboss-advance);
  -webkit-text-stroke:var(--emboss-stroke) currentColor;
  font-family:var(--font-display); font-weight:400;
  font-size:var(--type-control); letter-spacing:.01em;
  cursor:pointer;
  transition:transform var(--dur-fast) var(--ease-standard),
             box-shadow var(--dur-fast) var(--ease-standard);
}
button:active{ transform:translateY(3px); box-shadow:var(--shadow-advance); }
@media (prefers-reduced-motion:reduce){
  button{ transition:none; }
  button:active{ transform:none; }
}

/* ---- THE ENROLMENT SCREEN: QR, THEN THE KEY AS TEXT (design lines 204-213)
   The QR is FLUID rather than the design's flat 196px. The design's panel is
   844px tall; the shortest supported viewport is 640px, and at 196px this
   screen overflowed it by 18px — owner ruling R5(b), which this task must
   clear. `min()` against vh is the app's established idiom for exactly this.
   THE SETUP KEY STAYS TEXT beside the QR, as the caption requires.          */
img.qr{
  display:block; align-self:center;
  width:min(196px,26vh); height:min(196px,26vh);
  box-sizing:border-box; margin:16px 0 0; padding:10px;
  border-radius:var(--radius-tile);
  background:#FFFFFF;
  box-shadow:var(--shadow-auth-qr);
  image-rendering:pixelated;
}
.muted:has(+ .secret){ font-size:var(--type-chip); margin-top:14px; }  /* design line 211 */
.secret{
  box-sizing:border-box;
  margin:6px 0 0; padding:11px 13px;
  border-radius:var(--radius-tile);
  background:var(--fill-auth-secret);
  box-shadow:var(--shadow-auth-secret);
  color:var(--ink-control);
  font-size:var(--type-meta); letter-spacing:.5px; word-break:break-all;
}
.mono{ font-family:ui-monospace,Menlo,Consolas,monospace; }

/* ---- THE BACKUP-CODE PATH (design lines 237-240) -------------------------
   Collapsed, and still reachable — the caption's own requirement. `details`
   carries the 16px offset that owner ruling R3 moved out of
   api/totp-verify.php's inline margin attribute; that is the one
   markup change this restyle makes outside its own stylesheet.              */
details{ margin-top:16px; }
details summary{
  display:flex; align-items:center; gap:8px;
  min-height:var(--tap); cursor:pointer;
  font-family:var(--font-body); font-weight:800;
  font-size:var(--type-meta); color:var(--ink-sheet-soft);   /* same floor finding as .muted */
  list-style:none;
}
details summary::-webkit-details-marker{ display:none; }
details summary::after{ content:"\203A"; font-size:var(--type-chip); font-weight:800; }
details[open] summary::after{ content:"\2039"; }

/* ---- THE UNDESIGNED PAGES (owner ruling R2) ------------------------------
   The sign-out page and the five setup states have no design of their own and
   their markup is untouched. They inherit everything above; these four rules
   are the remainder of their vocabulary, re-expressed in the same register so
   they sit beside the sign-in page rather than beneath it.                  */
a{ color:var(--ink-action-quiet); }
.codes{
  box-sizing:border-box; padding:16px; margin:16px 0 0;
  border-radius:var(--radius-tile);
  background:var(--fill-auth-secret);
  box-shadow:var(--shadow-auth-secret);
  color:var(--ink-control);
  font-family:ui-monospace,Menlo,Consolas,monospace;
  font-size:var(--type-meta); letter-spacing:.5px; white-space:pre-wrap;
}
.warn{ color:var(--ink-auth-err); font-weight:800; font-size:var(--type-meta); }
fieldset{
  margin:16px 0 0; padding:16px;
  border:0; border-radius:var(--radius-field);
  background:var(--fill-auth-secret);
  box-shadow:var(--shadow-auth-secret);
}
legend{
  padding:0 6px;
  font-family:var(--font-display); font-weight:500;
  font-size:var(--type-label); letter-spacing:var(--track-label);
  text-transform:uppercase; color:var(--ink-tagline);
}
