/* =============================================================================
 * screens/auth.css — unauthenticated auth surfaces
 * =============================================================================
 *
 * Layout shell + screen-scoped primitives for the auth entry surfaces
 * (login, password reset request + confirm, invite accept, 2FA verify,
 * registration verify error). Reference:
 *   docs/design-references/Learner/login.html  (sealed 2026-04-20)
 *
 * Composition is a two-column editorial frame on cream-200:
 *   ┌──────────────────────────────────────────────┐
 *   │ Brand / voice panel  │ Form panel            │
 *   │ (left, cream-200)    │ (right, white)        │
 *   └──────────────────────────────────────────────┘
 *
 * Left panel carries a stable masthead ("Security Awareness Training"),
 * a *contextual* eyebrow that narrates page state (Sign in / Check your
 * email / Let's try again / Almost there), and a daily SecurityQuote.
 * Right panel carries the form; no inner card (the frame is the
 * surface). Below 768px the layout stacks — left panel becomes a
 * compact brand header above the form.
 *
 * No sidebar, no topbar — auth deliberately skips the app shell. This
 * file is loaded only by templates/auth/base.html; dashboard / app
 * screens never see it and auth never sees dashboard.css.
 * ============================================================================= */


/* --- Shell ---------------------------------------------------------- */

/* Shell fills the viewport and vertical-centers the frame. On tall
 * viewports the frame floats in the middle instead of hanging from
 * the top with a sea of cream below it. When the frame is taller
 * than 100vh, min-height lets the shell grow and the page scrolls
 * naturally — no clipping. */
.auth-shell {
    max-width: 80rem;
    margin: 0 auto;
    padding: var(--space-10) var(--space-6);
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
}

.auth-frame {
    width: 100%;
    display: grid;
    grid-template-columns: 1fr;
    min-height: 640px;
    background: var(--color-surface);
    border-radius: var(--radius-3xl);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}

@media (min-width: 768px) {
    .auth-frame {
        grid-template-columns: 52fr 48fr;
        min-height: 680px;
    }
}

/* --- Left: brand + voice panel -------------------------------------- */

/* Cream-200 surface so it reads as one tonal step inset from the white
 * form panel. The panel itself is the containment; no inner card. */
.auth-voice {
    background: var(--cream-200);
    padding: var(--space-8) var(--space-8) var(--space-6);
    display: flex;
    flex-direction: column;
    gap: var(--space-10);
    position: relative;
    overflow: hidden;
}

@media (min-width: 768px) {
    .auth-voice {
        padding: var(--space-10);
    }
}

@media (min-width: 1024px) {
    .auth-voice {
        padding: var(--space-12) var(--space-12) var(--space-10);
    }
}

.auth-voice__brand {
    margin: 0;
    font-size: var(--text-xl);
    font-weight: var(--weight-extrabold);
    letter-spacing: -0.04em;
    text-transform: uppercase;
    color: var(--charcoal-900);
}

/* Top-aligned so the eyebrow starts close to where the right panel's
 * "Welcome back." title sits. Centering the hero inside its allocated
 * flex space pushed it visually low compared to the right panel (the
 * two panels use different centering mechanisms — right centers the
 * whole form cluster which is tall; left was centering only the hero
 * between the brand and footer, which bunched it toward the middle).
 * flex-start with padding-top trades that arrangement for one where
 * both panels' first text elements land at a similar Y. */
.auth-voice__hero {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    padding-top: var(--space-16);
    gap: var(--space-5);
}

.auth-voice__eyebrow {
    margin: 0;
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--color-accent-text);
}

/* Masthead — stable across all auth surfaces. Sized to fit "Security
 * Awareness Training" on one line at 1024px+ viewports where the two-
 * column layout is active; mobile stacks the panel above the form and
 * becomes unconstrained on width. Tighter tracking (-0.03em) helps the
 * long word-train pack in. */
.auth-voice__headline {
    margin: 0;
    font-size: clamp(var(--text-2xl), 2.8vw, var(--text-4xl));
    font-weight: var(--weight-extrabold);
    letter-spacing: -0.03em;
    line-height: var(--leading-tight);
    color: var(--charcoal-900);
}

.auth-voice__body {
    margin: 0;
    font-size: var(--text-lg);
    font-weight: var(--weight-regular);
    line-height: var(--leading-snug);
    color: var(--charcoal-500);
    max-width: 24rem;
}

/* Copy variant — used for multi-paragraph instructional voice body
 * (2FA setup / recovery codes) where the text is conversational
 * rather than a poetic quote. Smaller font + no max-width so the
 * lines flow across the voice panel width, visually aligning with
 * the "Security Awareness Training" headline above instead of
 * pegging to the narrower quote column. */
.auth-voice__body--copy {
    font-size: var(--text-sm);
    line-height: 1.6;
    max-width: none;
}

/* Inline label opening a paragraph — used for the "Authentication
 * Apps" cue immediately above the app list on the 2FA setup voice
 * panel. Extrabold + darker so it reads as a heading-weight label
 * within the same paragraph as the comma-separated app list that
 * follows it (separated by a single <br>, no extra gap). Sits as a
 * <span> inside .auth-voice__body--copy, so font-size inherits. */
.auth-voice__body-label {
    font-weight: var(--weight-extrabold);
    color: var(--charcoal-900);
}

/* Quote variant — italic pull-quote with attribution below. The daily
 * SecurityQuote rotates server-side (apps.tenants.SecurityQuote);
 * attribution is optional, so the template must handle both cases
 * (render `<cite>By {{ author }}</cite>` only when `quote.author`). */
.auth-voice__body--quote {
    font-style: italic;
    color: var(--charcoal-700);
}

.auth-voice__body-attr {
    display: block;
    margin-top: var(--space-3);
    font-style: normal;
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    letter-spacing: var(--tracking-normal);
    color: var(--color-text-muted);
}

.auth-voice__footer {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-4);
    font-size: var(--text-xs);
    color: var(--color-text-muted);
}

.auth-voice__footer a {
    color: var(--color-text-secondary);
    text-decoration: none;
    transition: color var(--transition-fast);
}

.auth-voice__footer a:hover {
    color: var(--charcoal-800);
}

.auth-voice__footer-sep {
    color: var(--cream-500);
}


/* --- Right: form panel ---------------------------------------------- */

/* White surface. Form sits centered inside with generous padding. No
 * inner card — the frame already contains.
 *
 * The ::before and ::after flex spacers mirror the voice panel's
 * brand-gap-hero-gap-footer stack so that the form-inner's flex: 1
 * midline lands at the same Y as the voice hero's content. Without
 * this, short-content pages (password_reset_done, _complete) would
 * center their content around the full form-panel midline, which
 * floats above voice headline because voice hero is offset by the
 * brand block above. */
.auth-form {
    padding: var(--space-10) var(--space-6);
    display: flex;
    flex-direction: column;
    background: var(--color-surface);
}

.auth-form::before {
    content: "";
    flex-shrink: 0;
    height: 4rem;
}

.auth-form::after {
    content: "";
    flex-shrink: 0;
    height: 3rem;
}

@media (min-width: 768px) {
    .auth-form {
        padding: var(--space-12) var(--space-10);
    }
}

@media (min-width: 1024px) {
    .auth-form {
        padding: var(--space-12) var(--space-16);
    }
}

.auth-form__inner {
    width: 100%;
    max-width: 26rem;
    margin: 0 auto;
    flex: 1 0 auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: var(--space-8);
}

/* Top-aligned variant — used by the 2FA setup form so its title
 * lands at the same Y as the voice panel's headline on the left
 * (which is also top-aligned via .auth-voice__hero's
 * justify-content: flex-start). Login keeps the default centered
 * variant because its taller form column reads better mid-panel.
 *
 * The padding-top compensates for the left panel's eyebrow + hero
 * gap stack that pushes the headline down from the top: without
 * this, the right title aligns with the LEFT eyebrow (which is too
 * high) instead of the LEFT headline. Token ≈ eyebrow-line-height
 * (~14px) + .auth-voice__hero gap (var(--space-5) = 20px) = ~34px,
 * matched here with var(--space-8) for a clean align. */
.auth-form__inner--top {
    justify-content: flex-start;
    padding-top: var(--space-8);
}

/* Centre the "Verification code" form-field label above the input
 * inside the top-aligned form panel — keeps the label on the same
 * vertical axis as the QR / button stack rather than dropping it to
 * a left-aligned default. Scoped so login's left-aligned labels
 * stay as the chassis intends. */
.auth-form__inner--top .form-field__label {
    text-align: center;
}

/* Slim the verification input down — the default form-field input
 * height (~50px from padding var(--space-3) + text-base line-height)
 * is overkill for a 6-digit numeric code. Tight padding + tight
 * line-height drop it to ~30px (≈40% shorter) so the code field
 * reads as a focused, compact target. Scoped so login's email +
 * password inputs keep their roomier touch-friendly height. */
.auth-form__inner--top .form-field__input {
    padding: var(--space-1) var(--space-3);
    line-height: var(--leading-tight);
}

/* Narrow the verification field + the submit button to a compact
 * centred column — the 6-digit code doesn't need full form-panel
 * width to read, and a narrower button matches the field's footprint
 * so the pair sit on one vertical spine below the QR. */
.auth-form__inner--top .auth-form__fields,
.auth-form__inner--top .auth-submit {
    width: 100%;
    max-width: 16rem;
    align-self: center;
}

/* Tighten the verification code characters — the default
 * .auth-code-input uses text-2xl + letter-spacing 0.5em for the
 * roomier login interstitial. In the 16rem-wide setup field, those
 * digits spread too wide and pump the input height back up. Scoped
 * smaller font + closer letter-spacing keeps the input compact and
 * the digits readable but not sprawling. */
.auth-form__inner--top .auth-code-input {
    font-size: var(--text-xl);
    letter-spacing: 0.2em;
}

.auth-form__header {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

/* Centered header variant — used when the form panel content (e.g.
 * a QR code) sits visually centred and the title above it should
 * read as the column's anchor. */
.auth-form__header--centered {
    text-align: center;
    align-items: center;
}

.auth-form__title {
    margin: 0;
    font-size: var(--text-4xl);
    font-weight: var(--weight-extrabold);
    letter-spacing: var(--tracking-tight);
    line-height: var(--leading-tight);
    color: var(--color-text);
}

.auth-form__subtitle {
    margin: 0;
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    color: var(--color-text-secondary);
}

.auth-form__fields {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

/* Secondary link row (Forgot password, Use a recovery code) — elevated
 * from caption-footnote to a proper affordance, but still subordinate
 * to the primary button above. Centered, medium weight. */
.auth-form__secondary {
    text-align: center;
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    color: var(--color-text-secondary);
}

.auth-form__secondary a {
    color: var(--color-accent-text);
    text-decoration: none;
    border-bottom: 1px solid transparent;
    transition: border-color var(--transition-fast);
}

.auth-form__secondary a:hover {
    border-bottom-color: var(--color-accent);
}

/* Quiet variant: demotes a secondary link to body-text colour at a
 * smaller size so it doesn't compete with the louder accent-coloured
 * sibling above it (e.g. "Find your workspace" sitting below "Forgot
 * your password?"). Two same-weight accent links read as parallel
 * primaries; the quiet variant restores the intended hierarchy. */
.auth-form__secondary--quiet {
    font-size: var(--text-xs);
}

.auth-form__secondary--quiet a {
    color: var(--color-text-secondary);
}

.auth-form__secondary--quiet a:hover {
    border-bottom-color: var(--color-text-secondary);
}

.auth-form__legal {
    font-size: var(--text-xs);
    line-height: var(--leading-snug);
    color: var(--color-text-muted);
    text-align: center;
    max-width: 20rem;
    margin: 0 auto;
}

.auth-form__legal a {
    color: var(--color-text-secondary);
    text-decoration: underline;
    text-underline-offset: 2px;
    text-decoration-color: var(--cream-500);
}

.auth-form__legal a:hover {
    color: var(--charcoal-800);
}


/* --- Non-field alert ------------------------------------------------- */

/* Wrong credentials, locked account, rate-limit lockout. Peach-toned
 * (see form-field.css for the same rule applied to per-field errors)
 * — never red. Positioned above the form fields when used. */
.auth-alert {
    display: flex;
    gap: var(--space-3);
    padding: var(--space-4);
    background: var(--peach-50);
    border: 1px solid var(--peach-200);
    border-radius: var(--radius-lg);
}

.auth-alert__icon {
    width: 1.25rem;
    height: 1.25rem;
    flex-shrink: 0;
    color: var(--peach-700);
    margin-top: 0.125rem;
}

.auth-alert__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    font-size: var(--text-sm);
    color: var(--charcoal-700);
    line-height: var(--leading-snug);
}

.auth-alert__title {
    margin: 0;
    font-weight: var(--weight-semibold);
    color: var(--charcoal-800);
}

.auth-alert__detail {
    margin: 0;
    color: var(--charcoal-600);
}


/* --- Primary submit -------------------------------------------------- */

/* The auth CTA is deliberately NOT the terracotta .btn--primary. Its
 * background matches --color-bg (the cream-200 page backdrop behind
 * .auth-shell) so the button reads as a cut-out from the same paper
 * the page is made of — editorial, understated. cream-200 on white
 * is only ~4% luminance apart, so the 1px charcoal-200 border does
 * the real affordance work. Bold charcoal-900 text carries the
 * authority the fill no longer does. The terracotta focus ring is
 * kept intact — it becomes the sole "active engagement" signal on
 * this surface, sharpening the accent's rarity elsewhere.
 * Contrast: charcoal-900 on cream-200 ≈ 15:1.
 *
 * Kept scoped to auth (not promoted to components/button.css) per the
 * "parallel vocabularies are fine" rule — .btn--primary is the
 * platform-wide CTA; auth gets its own. */
.auth-submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-3) var(--space-5);
    background: var(--color-bg);
    color: var(--charcoal-900);
    border: 1px solid var(--charcoal-200);
    border-radius: var(--radius-lg);
    font-family: inherit;
    font-size: var(--text-base);
    font-weight: var(--weight-bold);
    letter-spacing: -0.005em;
    cursor: pointer;
    transition:
        background var(--transition-base),
        border-color var(--transition-base),
        transform var(--transition-base),
        box-shadow var(--transition-base);
}

.auth-submit:hover {
    background: var(--cream-300);
    border-color: var(--charcoal-300);
    transform: translateY(-1px);
    box-shadow: var(--shadow-sm);
}

.auth-submit:active {
    transform: translateY(0);
    box-shadow: none;
}

.auth-submit:focus-visible {
    outline: 2px solid var(--color-focus);
    outline-offset: 3px;
}


/* --- 2FA one-time-code variant -------------------------------------- */

/* Wide text track + loose letter-spacing treats the code as a single
 * one-time value, visually distinct from a password. Still a plain
 * .form-field__input underneath — just this modifier for the code
 * context. Applied via an additional class on the input element. */
.auth-code-input {
    text-align: center;
    font-size: var(--text-2xl);
    font-weight: var(--weight-semibold);
    letter-spacing: 0.5em;
    padding: var(--space-4) var(--space-4);
    font-variant-numeric: tabular-nums;
}


/* --- Motion --------------------------------------------------------- */

/* Form panel fades up on load, left panel stays put (anchoring). The
 * stagger sequence mirrors the learner dashboard's content-entrance
 * keyframes; kept short because there's less to reveal. */
@keyframes auth-rise {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

.auth-form__inner > * {
    animation: auth-rise 360ms var(--ease-out-quart) both;
}

.auth-form__inner > *:nth-child(1) { animation-delay:   0ms; }
.auth-form__inner > *:nth-child(2) { animation-delay:  60ms; }
.auth-form__inner > *:nth-child(3) { animation-delay: 120ms; }
.auth-form__inner > *:nth-child(4) { animation-delay: 180ms; }
.auth-form__inner > *:nth-child(5) { animation-delay: 240ms; }
.auth-form__inner > *:nth-child(6) { animation-delay: 300ms; }

@media (prefers-reduced-motion: reduce) {
    .auth-form__inner > * {
        animation: none;
    }
    .auth-submit:hover {
        transform: none;
    }
}

/* =============================================================================
 * Front-door workspace field (landing.html)
 * =============================================================================
 * Input + fixed domain suffix on one line: the visitor types only the
 * workspace WORD, the suffix shows the rest of the address, so the field
 * explains what it wants. The suffix is display-only (aria-hidden in the
 * markup) — the form submits just the word. */
.workspace-field {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.workspace-field .form-field__input {
    flex: 1 1 auto;
    min-width: 0;
}

.workspace-field__suffix {
    flex-shrink: 0;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    white-space: nowrap;
}

/* Link-shaped auth-submit (the error pages' "Go home"): pin the ink on
 * hover too — without this, base.css's global a:hover repaints the text
 * accent-orange while the button ground goes cream (owner, 2026-08-04:
 * no orange hover text on these). */
a.auth-submit,
a.auth-submit:hover {
    color: var(--charcoal-900);
}
