/* apps/website/html/css/auth.css — sign-in and two-factor.

   Built on css/system.css, which both pages link first. Per §8.6 nothing here defines a
   colour, a typeface or a radius; per §13 the layout is this page family's own decision.

   These are the first thing anyone sees, so they are deliberately the same object as the hub:
   the wordmark at 54px on the left, the thing you came to do on the right, the whole block
   centred in the window. Arriving at a login that is visibly the same page family as the
   estate it guards is the entire point of the composition.

   §4 holds — nothing is filled; a field is a baseline rule, not a box.
   §5 holds — no glyphs; the only mark on either page is type.
*/

/* A class that sets display beats the browser's own [hidden] rule, so anything toggled with
   the attribute has to say so explicitly. Both MFA states set display, and without this the
   page shows enrolment and verification at the same time. */
[hidden] { display:none !important }

.a-page { min-height:100vh; display:flex; align-items:center; justify-content:center;
  padding:40px 24px }
.a-wrap { width:100%; max-width:900px; display:flex; gap:64px; align-items:center }

.a-corner { position:fixed; top:18px; right:22px; display:flex; align-items:center; gap:14px;
  font-size:11px; color:var(--ink-5) }

/* The mark holds its own column so the form starts on a predictable line. */
.a-brand { flex:0 0 300px }
.a-wm { font-size:54px; font-weight:700; color:var(--ink); letter-spacing:-.04em; line-height:1;
  white-space:nowrap }
/* The tagline says which page this is — that is why neither page carries a heading. */
.a-tag { font-size:11px; letter-spacing:.26em; text-transform:uppercase; color:var(--ink-5);
  margin-top:14px; line-height:1.9 }

.a-form { flex:1; min-width:0; max-width:340px }
.a-lg { display:block; font-size:11px; letter-spacing:.18em; text-transform:uppercase;
  color:var(--ink-4); font-weight:500; margin-bottom:16px }

.a-in { font:inherit; font-size:15px; color:var(--ink); background:none; width:100%;
  border:0; border-bottom:1px solid var(--line); padding:8px 0; margin-bottom:16px;
  outline:none; transition:border-color 120ms ease }
.a-in::placeholder { color:var(--ink-5) }
.a-in:focus { border-bottom-color:var(--edge) }

.a-go { font:inherit; font-size:15px; color:var(--ink-2); background:none; border:0;
  padding:6px 0; cursor:pointer; transition:color 120ms ease }
.a-go:hover { color:var(--ink) }
.a-go[disabled] { color:var(--ink-5); cursor:default }

.a-msg { display:block; font-size:12px; margin-top:12px; min-height:16px; color:var(--ink-5) }
.a-msg.err { color:var(--err) }
.a-msg.ok { color:var(--ok) }
.a-hint { font-size:12px; color:var(--ink-5); line-height:1.6; margin-top:14px }

/* Two-factor: one cell per digit. The input itself is transparent and stretched across the
   cells, so the caret and every autofill/paste path stay native while the digits render as
   type on hairline rules — a real six-box control, not six inputs to keep in sync. */
.a-code { position:relative; width:315px; max-width:100% }
.a-cells { display:flex; gap:9px; pointer-events:none }
.a-cell { width:44px; height:56px; border-bottom:1px solid var(--line);
  display:flex; align-items:center; justify-content:center;
  font-size:26px; font-weight:600; color:var(--ink); font-variant-numeric:tabular-nums }
.a-cell.on { border-bottom-color:var(--edge) }
.a-cell:empty::after { content:"—"; color:var(--ink-5); font-size:15px; font-weight:400 }
/* Opacity, not visibility: a hidden input cannot hold focus or receive a paste. */
.a-code input { position:absolute; inset:0; width:100%; height:100%; opacity:0;
  font:inherit; letter-spacing:2.4em; border:0; background:none; outline:none; cursor:text }

/* Enrolment sits beside the mark: QR, then what to do with it. */
.a-enrol { flex:1; display:flex; gap:36px; align-items:flex-start; min-width:0 }
.a-qr { flex:0 0 148px }
.a-qr img { display:block; width:148px; height:148px; background:#fff }
.a-key { font-size:12px; color:var(--ink-4); margin-top:10px; letter-spacing:.08em;
  word-break:break-all; line-height:1.5 }
.a-key b { display:block; font-weight:400; color:var(--ink-5); letter-spacing:.13em;
  text-transform:uppercase; font-size:11px; margin-bottom:3px }
.a-steps { flex:1; min-width:0 }
/* Numbered because this is a real sequence — scan, then confirm. Not decoration. */
.a-step { display:flex; gap:12px; padding:8px 0; border-top:1px solid var(--line-2);
  font-size:13px; color:var(--ink-2); line-height:1.5 }
.a-step:first-child { border-top:0; padding-top:0 }
.a-step i { font-style:normal; font-size:11px; color:var(--ink-5); flex:0 0 14px;
  font-variant-numeric:tabular-nums; padding-top:2px }

@media (max-width: 780px) {
  .a-wrap { flex-direction:column; align-items:flex-start; gap:34px }
  .a-wm { font-size:38px }
  .a-brand { flex:none }
  .a-form { max-width:none; width:100% }
  .a-enrol { flex-direction:column; gap:26px }
}

/* Phone. Same brief as the hub: nothing moves sideways, and everything a state needs fits one
   screen. Sign-in and code entry are short enough to stay centred; enrolment is not, so it
   anchors to the top and is tuned until the QR, the key, the steps and the cells all fit. */
@media (max-width: 620px) {
  .a-page { min-height:100dvh; padding:26px 18px }
  .a-wrap { gap:26px; max-width:none }
  .a-wm { font-size:34px }
  .a-tag { margin-top:7px; font-size:10px; letter-spacing:.22em }
  /* 16px is the floor iOS uses to decide whether to zoom the page on focus. */
  .a-in { font-size:16px }

  /* Six cells across a 390px screen: the fixed 44px cell no longer fits with its gaps, so the
     row becomes fluid and the cells share what is there. */
  .a-code { width:100% }
  .a-cells { gap:6px }
  .a-cell { width:auto; flex:1; height:52px; font-size:23px }
  .a-code input { letter-spacing:0; text-align:center }
  /* letter-spacing positioned the invisible caret over each cell on desktop; at fluid widths
     that no longer lines up, so the caret is centred instead of pretending to track. */

  .a-enrol { gap:20px }
  .a-qr { flex:none }
  .a-qr img { width:132px; height:132px }
  .a-key { margin-top:8px; font-size:11px }
  .a-step { padding:6px 0; font-size:12px; line-height:1.45 }
  .a-hint { margin-top:10px }
}

/* Short phones in landscape, and small screens generally: enrolment cannot be centred without
   pushing its own controls off-screen, so it starts at the top and scrolls only if it must. */
@media (max-width: 620px) and (max-height: 780px) {
  .a-page:has(#enrol:not([hidden])) { align-items:flex-start }
}

/* A phone in landscape is wide but short, so the width-keyed phone rules never match it.
   Enrolment is the tall state, so it goes side-by-side and loses its vertical padding. */
@media (max-height: 500px) {
  .a-page { align-items:flex-start; padding:18px 22px; min-height:100dvh }
  .a-wrap { flex-direction:row; align-items:flex-start; gap:34px }
  .a-wm { font-size:28px }
  .a-brand { flex:0 0 190px }
  .a-qr img { width:112px; height:112px }
  .a-step { padding:4px 0; font-size:11.5px; line-height:1.35 }
  .a-cell { height:44px; font-size:20px }
  .a-hint { display:none }
}

/* The last squeeze, for an SE-sized screen: enrolment is the only state that still does not
   fit, and it is the one state with a fixed-size element in it. */
@media (max-width: 620px) and (max-height: 640px), (max-width: 340px) {
  .a-page { padding:18px 14px }
  .a-wrap { gap:18px }
  .a-wm { font-size:27px }
  .a-qr img { width:108px; height:108px }
  .a-key { margin-top:6px; font-size:10px }
  .a-step { padding:5px 0; font-size:11.5px; line-height:1.4 }
  .a-cell { height:46px; font-size:21px }
  .a-hint { display:none }   /* the label above the cells already says what to type */
}
