/* ============================================================
   Auth flow — one stylesheet for all six signed-out pages:
   logIn, signUp, forgotPassword, resetPassword,
   emailVerificationPending, emailVerificationFailed.

   Replaces logIn.css / signUp.css / forgotPassword.css /
   resetPassword.css / emailVerificationPending.css /
   emailVerificationFailed.css — six sheets that were 85-91% the same
   file and had already drifted apart: two focus rings for one
   component, two error palettes for one class, five copies of one
   input, seven greys, four border widths, three heading conventions.

   The visual language is error.css's, the page that was approved:
   28/600 title, hairline borders, `font: inherit` on controls, hover
   that changes colour and nothing else. Every colour comes from
   tokens.css.

   ONE OF EACH THING is the organising rule, because almost every
   defect here was a consistency defect. There is one control
   construction (.auth-control wrapping a bare .auth-input, always,
   even when there is no adornment), one height (44px), one radius,
   one error component per channel, one card width for the whole
   family. Drift becomes impossible by construction rather than by
   discipline.

   Focus is the one deliberate exception to "one of each": buttons and
   links take error.css's accent ring, which :focus-visible shows only
   to keyboard users, while text fields just darken their own border.
   They are split because :focus-visible DOES match a mouse click into
   a text input, so a shared ring would fire every time anyone clicked
   a field — see the focus rules below.
   ============================================================ */

.auth-page {
    /* cssReset puts Arial on body and no auth stylesheet ever overrode
       it, so the whole flow shipped in Arial while still paying to
       preload and download Outfit. Scoped to the shell class, the way
       .error-page does it — never on bare body. */
    font-family: 'Outfit', sans-serif;
    line-height: 1.5;
    color: var(--fd-text);
    background: var(--fd-bg);

    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 96px var(--fd-page-gutter) 64px;
    position: relative;
}

/* Centred with auto block margins, NOT justify-content: center. The old
   sheets used centring, so once the signup form grew taller than the
   viewport the top of it was clipped and the top padding was eaten.
   Auto margins centre when there is room and yield to the padding when
   there isn't. */
.auth-main {
    width: 100%;
    max-width: 440px;
    margin-block: auto;
    display: flex;
    flex-direction: column;
    gap: 24px;
}

/* Wordmark — the page's only chrome, and the only place the brand is
   printed. Each <h1> is a plain task label ("Log in"), never a brand
   greeting, so the mark is never shown twice. Same treatment as
   .error-wordmark; the left inset uses the gutter token rather than
   error.css's literal 32px so the mark and the card share one left
   edge once the gutter narrows. */
.auth-wordmark {
    position: absolute;
    top: 28px;
    left: var(--fd-page-gutter);
    font-size: 18px;
    font-weight: 600;
    letter-spacing: -0.3px;
    color: var(--fd-text);
    text-decoration: none;
    white-space: nowrap;
    transition: color 0.2s ease;
}

.auth-wordmark:hover {
    color: var(--fd-primary);
}

/* ------------------------------------------------------------
   Card

   ONE width for every page in the family. Login -> signup must not
   resize the card: a container that changes size between two pages of
   one flow reads as two designs. 440 - 80 padding = 360px inner, and
   the 2-up name row is (360 - 12) / 2 = 174px per field, which holds a
   16px first name comfortably.
   ------------------------------------------------------------ */
.auth-panel {
    background: var(--fd-surface);
    border: 1px solid var(--fd-border);
    border-radius: var(--fd-radius);
    box-shadow: var(--fd-shadow-xs);
    padding: 40px;
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.auth-head {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.auth-title {
    font-size: 28px;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.4px;
    color: var(--fd-text);
    margin: 0;
}

.auth-subtitle {
    font-size: 15px;
    line-height: 1.5;
    color: var(--fd-text-secondary);
    margin: 0;
    overflow-wrap: break-word;
}

.auth-subtitle strong {
    font-weight: 600;
    color: var(--fd-text);
}

/* ------------------------------------------------------------
   Form
   ------------------------------------------------------------ */

.auth-form {
    display: flex;
    flex-direction: column;
    gap: 18px;
}

/* Signup only: two labelled groups turn seven fields into two
   decisions. <fieldset> carries a UA min-width: min-content that stops
   a flex/grid child shrinking below its content — reset it or the name
   row cannot collapse on a narrow phone. */
.auth-group {
    border: 0;
    margin: 0;
    padding: 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 18px;
}

.auth-group + .auth-group {
    margin-top: 10px;
}

/* <legend> is pulled out of flow by the UA; float + full width is the
   standard way to make it lay out as a normal flex child. */
.auth-group-title {
    float: left;
    width: 100%;
    padding: 0;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    /* --fd-text-muted is the platform's habit for an eyebrow like this
       (.settings-section-label uses it) but it is 2.56:1 and fails as
       text. Uppercase + tracking is already doing the "this is a quiet
       section marker" work, so the colour does not have to be faint. */
    color: var(--fd-text-secondary);
}

/* A plain block, not a flex column with a gap: an empty error <p>
   generates no line box, so the margin construction below costs
   exactly 0px when there is no message, where a flex gap would reserve
   air under all seven signup fields forever. That in turn lets the
   error node stay permanently mounted for assistive tech instead of
   being display:none'd and remounted. */
.auth-field {
    display: block;
    min-width: 0;
}

.auth-label {
    display: block;
    margin-bottom: 6px;
    /* Deliberately quieter than the value the user types: at 13/500
       --fd-text-secondary the label names the field, and the 16px
       near-black value stays the loudest thing in the row. The old
       sheets had labels at the same size as the values, which is why
       the forms read as a wall of equal-weight text. */
    font-size: 13px;
    font-weight: 500;
    color: var(--fd-text-secondary);
}

.auth-hint {
    margin-top: 6px;
    font-size: 13px;
    line-height: 1.45;
    color: var(--fd-text-secondary);
}

.auth-error:not(:empty) {
    margin-top: 6px;
}

.auth-error {
    font-size: 13px;
    line-height: 1.45;
    color: var(--fd-danger-text);
}

/* First/last name share a row until the two fields would be too narrow
   to read. */
.auth-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

/* ------------------------------------------------------------
   Controls

   EVERY input is wrapped in .auth-control, with no exceptions — a
   plain field is just the case with no adornment. The wrapper owns the
   height, border, radius, background and all five states; the input
   owns nothing but its text. Adornments (a password toggle, the
   handle's "frontdesk.page/" affix, the availability icon) are flex
   siblings, never absolutely positioned over a padding reservation,
   so a longer affix can never sit on top of typed text.
   ------------------------------------------------------------ */

.auth-control {
    display: flex;
    align-items: stretch;
    width: 100%;
    min-height: 44px;
    background: var(--fd-surface);
    border: 1px solid var(--fd-control-border);
    border-radius: var(--fd-radius-sm);
    transition: border-color 0.15s ease;
}

.auth-control:hover {
    border-color: var(--fd-text-secondary);
}

.auth-input {
    /* Form controls are NOT in cssReset's `font: inherit` list, so
       without this they keep the UA font even once the page font is
       fixed. .auth-submit sets it for the same reason. */
    font: inherit;
    font-size: 16px;   /* below 16px, iOS zooms the page on focus */
    line-height: 1.4;
    color: var(--fd-text);
    flex: 1;
    min-width: 0;
    padding: 10px 14px;
    background: none;
    border: 0;
    border-radius: inherit;
    outline: none;
}

.auth-input::placeholder {
    color: var(--fd-text-muted);
}

/* Buttons, links and the wordmark keep error.css's ring, but note it is
   on :focus-visible — the browser only matches that for keyboard
   navigation, so clicking a button never draws it. Text fields are the
   exception and are handled separately below: :focus-visible DOES match
   a mouse click into a text input (the field accepts typing, so the UA
   considers the focus visible), which is why a ring here would fire on
   every click. */
.auth-submit:focus-visible,
.auth-btn:focus-visible,
.auth-link:focus-visible,
.auth-wordmark:focus-visible,
.auth-adorn:focus-visible {
    outline: 2px solid var(--fd-primary);
    outline-offset: 2px;
}

.auth-control:has(.auth-input[aria-invalid="true"]) {
    border-color: var(--fd-danger-text);
}

/* Clicking into a field is the most ordinary thing anyone does on these
   pages, so it gets the quietest possible acknowledgement: the border
   the field already has, darkened. No ring, no offset halo, no accent
   colour. --fd-text is 17.85:1 on the field and a clear step up from
   the resting --fd-control-border, so the indicator still satisfies the
   3:1 that WCAG asks of it while reading as nothing more than the box
   sharpening up.

   Last in the cascade on purpose: it outranks the hover and invalid
   borders above, so the focused field is never showing two states at
   once. The error message and its red text stay put underneath. */
.auth-control:has(.auth-input:focus) {
    border-color: var(--fd-text);
}

/* Adornments: a fixed-width flush square, so the tap target is the full
   height of the control and nothing overlaps the text. */
.auth-adorn {
    font: inherit;
    flex: 0 0 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: none;
    border: 0;
    border-radius: inherit;
    color: var(--fd-text-secondary);
    cursor: pointer;
    transition: color 0.15s ease;
}

.auth-adorn:hover {
    color: var(--fd-text);
}

/* Covers .auth-icon-show / .auth-icon-hide, which carry no styles of their
   own — they are toggled by the `hidden` attribute alone. */
.auth-adorn svg {
    width: 18px;
    height: 18px;
}

/* ------------------------------------------------------------
   Buttons
   ------------------------------------------------------------ */

.auth-submit,
.auth-btn {
    font: inherit;
    font-size: 15px;
    font-weight: 500;
    line-height: 1.2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 44px;
    padding: 11px 22px;
    border: 1px solid transparent;
    border-radius: var(--fd-radius-sm);
    text-decoration: none;
    text-align: center;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.auth-submit,
.auth-btn-primary {
    background: var(--fd-primary);
    border-color: var(--fd-primary);
    color: var(--fd-text-inverse);
}

.auth-submit:hover,
.auth-btn-primary:hover {
    background: var(--fd-primary-hover);
    border-color: var(--fd-primary-hover);
}

.auth-btn-secondary {
    background: var(--fd-surface);
    border-color: var(--fd-control-border);
    color: var(--fd-text);
}

.auth-btn-secondary:hover {
    background: var(--fd-bg-secondary);
}

/* The submitting state has to be visibly different, or a slow network
   reads as a dead button and the user posts again — which on /logIn and
   /registerUser spends a shared 10-per-15-minutes rate limit. The old
   signup swapped the label but left the button pixel-identical. */
.auth-submit[disabled] {
    /* Darker, not faded. `opacity` dims the label and the background by the
       same amount, so the "Logging in…" text the user is actually reading
       drops from 5.17:1 to 2.55:1. This keeps 6.70:1 and still reads as busy. */
    background: var(--fd-primary-hover);
    border-color: var(--fd-primary-hover);
    cursor: default;
}

.auth-actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* ------------------------------------------------------------
   Messages — one look per channel.
   ------------------------------------------------------------ */

/* Tint plus coloured text, no border. The old boxes bordered themselves with
   --fd-danger-light, which is an 8%-alpha FILL token and therefore invisible
   as a line — so they already read as borderless. Committing to that is one
   less edge to draw and keeps this file free of one-off rgba() literals. */
.auth-alert {
    font-size: 14px;
    line-height: 1.5;
    padding: 12px 14px;
    border-radius: var(--fd-radius-sm);
    overflow-wrap: break-word;
}

/* authForm.js focuses this on load so a screen reader announces it —
   role="alert" alone is silent for content that was already in the
   document. The focus is a means of announcement, not an interaction:
   the banner is not operable and is already the loudest thing on the
   page, so it takes no ring. (Left visible it reads as a selected
   control, and Chrome does treat a programmatic focus on a tabindex=-1
   element as :focus-visible on a fresh load.) */
.auth-alert:focus,
.auth-alert:focus-visible {
    outline: none;
}

.auth-alert-error {
    /* See --fd-danger-text in tokens.css: --fd-danger-hover is only 4.41:1
       once it sits on this tint, under the 4.5:1 bar for body text. */
    color: var(--fd-danger-text);
    background: var(--fd-danger-bg);
}

.auth-alert-success {
    color: var(--fd-success-text);
    background: var(--fd-success-bg);
}

/* ------------------------------------------------------------
   Links and prose
   ------------------------------------------------------------ */

.auth-link {
    color: var(--fd-primary);
    font-weight: 500;
    text-decoration: none;
    border-radius: 2px;
    transition: color 0.15s ease;
}

.auth-link:hover {
    color: var(--fd-primary-hover);
    text-decoration: underline;
}

/* "Forgot password?" — trails the password field, aligned to its right
   edge. Its own line, not crammed under the field's error slot the way
   it was. */
.auth-field-aside {
    /* width:fit-content + auto left margin, NOT display:block + text-align.
       A block-level <a> is as wide as the card, so its click target and focus
       ring covered the full row: clicking the empty space level with the words
       navigated away and threw out whatever had been typed. */
    display: block;
    width: fit-content;
    margin: 8px 0 0 auto;
    font-size: 13px;
}

.auth-footer {
    font-size: 14px;
    line-height: 1.5;
    color: var(--fd-text-secondary);
    text-align: center;
    overflow-wrap: break-word;
}

.auth-terms {
    font-size: 13px;
    line-height: 1.55;
    color: var(--fd-text-secondary);
}

/* Body copy on the two email-verification status pages. */
.auth-note {
    font-size: 15px;
    line-height: 1.6;
    color: var(--fd-text-secondary);
    overflow-wrap: break-word;
}

.auth-note strong {
    font-weight: 600;
    color: var(--fd-text);
}

.auth-prose {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* ------------------------------------------------------------
   Responsive

   Horizontal inset is owned entirely by --fd-page-gutter (40 / 20 / 16
   / 14), so this file carries two component breakpoints instead of the
   twelve ad-hoc ones the six old sheets carried between them, and none
   of them restate the gutter.
   ------------------------------------------------------------ */

@media (max-width: 480px) {
    .auth-page {
        padding-top: 84px;
        padding-bottom: 48px;
    }

    .auth-wordmark {
        top: 22px;
    }

    .auth-panel {
        padding: 28px 22px;
    }

    .auth-title {
        font-size: 25px;
    }
}

/* Two name fields cannot hold a label and a 16px value side by side
   much below this; one column each beats two cramped ones. */
@media (max-width: 400px) {
    .auth-row {
        grid-template-columns: 1fr;
        gap: 18px;
    }
}

/* No blanket prefers-reduced-motion rule here on purpose. auth.css contains no
   transforms and no keyframes — only colour transitions, which are not motion —
   so a blanket would buy nothing, and `animation-duration: .01ms !important` on
   `.auth-page *` reached into usernameField.css and froze the availability
   spinner, which already slows itself down for reduced motion. */
