/* Tidy-Lab login page — standalone stylesheet (no Vaadin bootstrap, no Aura CSS).
   Speaks the app's Aura "Refined Studio" language through a local token block
   (AURA_THEME_REMEDIATION.md, decision D7). Values mirror tidy-lab-theme.css —
   keep the two in sync when the app theme changes.

   Strict CSP on /login (LoginController): style-src 'self' means every style on
   this page must live in this file — no inline style="" attributes and no
   JS-injected <style> blocks (the wave-background module's rules live at the
   bottom of this file for that reason). */

/* Instrument Sans — the Aura theme's typeface, served same-origin from the
   vaadin-aura-theme jar (classpath:/META-INF/resources/aura/fonts/...).
   Same variable-font file and descriptors as Aura's own @font-face, so login
   and app render with identical glyphs. */
@font-face {
    font-family: "Instrument Sans";
    src: url(/aura/fonts/InstrumentSans/InstrumentSans.woff2) format("woff2");
    font-weight: 400 700;
    font-style: normal;
    font-display: swap;
}

:root {
    /* The login page has no in-app theme toggle, so tracking the OS scheme via
       color-scheme + light-dark() is correct here (unlike in-app CSS, which is
       driven by the documentElement color-scheme set by TLAppLayout). */
    color-scheme: light dark;

    /* GRACEFUL DEGRADATION: this base block holds the complete LIGHT theme as
       plain values. In browsers without light-dark() (pre Chrome/Edge 123,
       Firefox 120, Safari 17.5 — e.g. frozen Android WebViews on older lab
       tablets) a custom property holding light-dark() makes every consuming
       declaration invalid at computed-value time — it does NOT fall back to an
       earlier declaration. The @supports block below upgrades these tokens to
       scheme-aware pairs only where light-dark() actually parses. */

    /* Accent — brand purple (--tl-brand-purple #7C3AED) with the violet-700/800
       family for hover/active. White on #7C3AED is 5.7:1 (AA), so the solid
       button keeps one accent in both schemes. */
    --login-accent: #7C3AED;
    --login-accent-hover: #6D28D9;
    --login-accent-active: #5B21B6;
    --login-accent-text: #7C3AED;

    /* Surfaces — mirror --aura-background-color-light (#FCFCFE family). */
    --login-page-bg-start: #f5f7fa;
    --login-page-bg-end: #e4e9f0;
    --login-surface: #ffffff;
    --login-surface-hover: #f5f7fa;
    --login-input-bg: #ffffff;

    /* Text — mirrors the --vaadin-text-color spirit (contrast ratios in the
       @supports block comment). */
    --login-text: #1f2937;
    --login-text-secondary: #4a5368;
    --login-text-muted: #6b7280;

    /* Deliberate muted-grey wordmark (documented brand treatment). */
    --login-wordmark: #c4cacf;

    /* Borders — input/button boundaries are the only visual identifier of
       those controls on the card, so they must meet WCAG 1.4.11 (3:1 against
       the adjacent surface): 3.1:1 light / 3.4:1 dark. Decorative borders
       (card edge, divider) are exempt and stay subtle. */
    --login-border: #8a92a2;
    --login-border-strong: #6b7382;
    --login-card-border: rgba(0, 0, 0, 0.05);
    --login-divider: #e0e5ec;

    /* Status — derived from the app's semantic pairs (tidy-lab-theme.css
       --tl-status-error/success), tinted onto the card surface. */
    --login-error-text: #c92a2a;
    --login-error-bg: #fbeaea;
    --login-error-border: rgba(201, 42, 42, 0.3);
    --login-notice-text: #217a35;
    --login-notice-bg: #edf4ef;
    --login-notice-border: rgba(33, 122, 53, 0.3);

    /* Shadow — the Aura shadow-m recipe with the app's overridden shadow color
       (tidy-lab-theme.css --aura-shadow-color). */
    --login-shadow-color: rgba(0, 0, 0, 0.08);

    /* One radius scale keyed to the app's --aura-base-radius: 6 —
       6px controls, 12px card container. */
    --login-radius: 6px;
    --login-radius-l: 12px;
}

/* Scheme-aware token upgrade — see the degradation note in the base block.
   Dark values: the card sits one elevation step above the page background
   (#26262c on #17171c-#1e1e24). Accent text/ring lightens to violet-400
   #A78BFA because #7C3AED is only 2.9:1 on the dark card (#A78BFA is 5.5:1).
   Contrast on the card surface: text 14.7:1 / 13.7:1, secondary 7.6:1 /
   7.3:1, muted 4.8:1 / 5.9:1 (light / dark). Status tints are
   the hue at 8% light / 12% dark onto the card surface, precomputed as
   literals: error text 4.7:1 / 5.2:1, notice text 4.8:1 / 6.6:1. */
@supports (color: light-dark(#000, #fff)) {
    :root {
        --login-accent-text: light-dark(#7C3AED, #A78BFA);
        --login-page-bg-start: light-dark(#f5f7fa, #17171c);
        --login-page-bg-end: light-dark(#e4e9f0, #1e1e24);
        --login-surface: light-dark(#ffffff, #26262c);
        --login-surface-hover: light-dark(#f5f7fa, #313139);
        --login-input-bg: light-dark(#ffffff, #1e1e24);
        --login-text: light-dark(#1f2937, #f4f4f6);
        --login-text-secondary: light-dark(#4a5368, #b4b4c0);
        --login-text-muted: light-dark(#6b7280, #9ca3af);
        --login-wordmark: light-dark(#c4cacf, #55555f);
        --login-border: light-dark(#8a92a2, #70707e);
        --login-border-strong: light-dark(#6b7382, #8a8a98);
        --login-card-border: light-dark(rgba(0, 0, 0, 0.05), rgba(255, 255, 255, 0.07));
        --login-divider: light-dark(#e0e5ec, #3a3a44);
        --login-error-text: light-dark(#c92a2a, #ff8787);
        --login-error-bg: light-dark(#fbeaea, #403237);
        --login-error-border: light-dark(rgba(201, 42, 42, 0.3), rgba(255, 135, 135, 0.35));
        --login-notice-text: light-dark(#217a35, #69db7c);
        --login-notice-bg: light-dark(#edf4ef, #2e3c36);
        --login-notice-border: light-dark(rgba(33, 122, 53, 0.3), rgba(105, 219, 124, 0.35));
        --login-shadow-color: light-dark(rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.5));
    }
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    min-height: 100vh;
    min-height: 100dvh;
    font-family: "Instrument Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    background: linear-gradient(135deg, var(--login-page-bg-start) 0%, var(--login-page-bg-end) 100%);
    color: var(--login-text);
}

body {
    display: flex;
    /* The card, centered. `safe` keeps its top reachable when it is taller
       than the viewport (older engines ignore the second declaration and keep
       plain center). */
    flex-direction: column;
    align-items: center;
    justify-content: center;
    justify-content: safe center;
    padding: 24px;
}

.login-card {
    width: min(560px, 92vw);
    background: var(--login-surface);
    border: 1px solid var(--login-card-border);
    border-radius: var(--login-radius-l);
    padding: 24px 20px 32px;
    box-shadow: 0 8px 16px -3px var(--login-shadow-color);
    position: relative;
    z-index: 1;
}
@media (min-width: 640px) {
    .login-card { padding: 32px 40px 40px; }
}

/* Header row — welcome greeting (left) + grey right-aligned wordmark (the pre-SSO look). */
.card-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    margin: 0 0 24px;
}
.card-header .welcome {
    font-size: 18px;
    font-weight: 500;
    color: var(--login-text);
}
.card-header .brand {
    font-size: 20px;
    color: var(--login-wordmark);
    letter-spacing: -0.05em;
}

/* The hidden attribute must win over a class's display value: the passkey controls are rendered
   hidden and revealed by /js/passkey-login.js only where the browser has WebAuthn. */
.login-card [hidden] {
    display: none !important;
}

.notice,
.error {
    margin-bottom: 16px;
    padding: 12px 14px;
    border-radius: var(--login-radius);
    font-size: 14px;
    line-height: 1.4;
}
.notice {
    background: var(--login-notice-bg);
    color: var(--login-notice-text);
    border: 1px solid var(--login-notice-border);
}
.error {
    background: var(--login-error-bg);
    color: var(--login-error-text);
    border: 1px solid var(--login-error-border);
}

.login-form {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.login-form label {
    font-size: 13px;
    font-weight: 500;
    color: var(--login-text-secondary);
    margin-bottom: -4px;
}

/* Old faithful: username / password / sign-in sit in a row on wide screens. */
.login-form--row .field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
@media (min-width: 768px) {
    .login-form--row {
        display: grid;
        grid-template-columns: 1fr 1fr auto;
        align-items: end;
        gap: 16px;
    }
}

.login-form input[type="email"],
.login-form input[type="text"],
.login-form input[type="password"] {
    width: 100%;
    padding: 12px 14px;
    border: 1px solid var(--login-border);
    border-radius: var(--login-radius);
    /* 16px minimum: iOS Safari auto-zooms the page when a focused input
       renders below 16px (threshold verified current through iOS 18) —
       critical on the lab tablets this page serves. Matches Aura's own
       pointer-coarse input floor (max(16px, --aura-font-size-m)). */
    font-size: 16px;
    font-family: inherit;
    background: var(--login-input-bg);
    color: var(--login-text);
    transition: border-color 120ms;
}

/* Chrome/WebKit force their own autofill background via internal !important
   styles (pale blue box on the dark card). The inset-shadow trick paints the
   field's own surface over it; -webkit-text-fill-color restores token text. */
.login-form input:-webkit-autofill {
    -webkit-box-shadow: 0 0 0 1000px var(--login-input-bg) inset;
    -webkit-text-fill-color: var(--login-text);
    caret-color: var(--login-text);
}

/* Show-password toggle — sits inside the password field; ≥24×24 CSS px hit
   area (WCAG 2.2 SC 2.5.8; actual 36×36 for gloved-tablet use). Icon state
   is driven by data-visible (no aria-pressed — ARIA APG: never pair a pressed
   state with a changing accessible name), wired in login-init.js (CSP: external module). */
.pw-wrap {
    position: relative;
}
.pw-wrap input[type="password"],
.pw-wrap input[type="text"] {
    padding-right: 46px;
}
.pw-toggle {
    position: absolute;
    right: 5px;
    top: 50%;
    transform: translateY(-50%);
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    border-radius: var(--login-radius);
    color: var(--login-text-muted);
    cursor: pointer;
}
.pw-toggle:hover { color: var(--login-text); }
.pw-toggle .pw-eye-off { display: none; }
.pw-toggle[data-visible="true"] .pw-eye { display: none; }
.pw-toggle[data-visible="true"] .pw-eye-off { display: block; }

/* One shared focus ring for every interactive element (survives forced-colors
   mode — no outline: none anywhere). Text inputs match :focus-visible on any
   focus in current browsers, so the ring is consistent for mouse + keyboard. */
.login-form input:focus-visible,
.btn-primary:focus-visible,
.sso-btn:focus-visible,
.pw-toggle:focus-visible,
.alt-link a:focus-visible {
    outline: 2px solid var(--login-accent-text);
    outline-offset: 2px;
}
.login-form input:focus-visible {
    border-color: var(--login-accent-text);
}

.btn-primary {
    margin-top: 4px;
    padding: 12px 14px;
    background: var(--login-accent);
    color: #fff;
    border: none;
    border-radius: var(--login-radius);
    font-size: 16px;
    font-family: inherit;
    font-weight: 600;
    cursor: pointer;
    transition: background 120ms;
}
.btn-primary:hover { background: var(--login-accent-hover); }
.btn-primary:active { background: var(--login-accent-active); }

.alt-link {
    margin: 16px 0 0;
    text-align: center;
    font-size: 13px;
}
.alt-link a {
    color: var(--login-accent-text);
    text-decoration: none;
}
.alt-link a:hover { text-decoration: underline; }

.divider {
    display: flex;
    align-items: center;
    margin: 24px 0;
    border: none;
}
.divider::before,
.divider::after {
    content: "";
    flex: 1;
    border-bottom: 1px solid var(--login-divider);
}
.divider span {
    padding: 0 10px;
    color: var(--login-text-muted);
    font-size: 12px;
}

.sso-buttons {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.sso-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 12px 14px;
    text-align: center;
    text-decoration: none;
    color: var(--login-text);
    background: var(--login-surface);
    border: 1px solid var(--login-border);
    border-radius: var(--login-radius);
    font-size: 14px;
    font-weight: 500;
    transition: background 120ms, border-color 120ms;
}
.sso-btn:hover {
    background: var(--login-surface-hover);
    border-color: var(--login-border-strong);
}
/* The passkey button is a <button>, the provider buttons are links: same look, no UA button chrome. */
button.sso-btn {
    width: 100%;
    font-family: inherit;
    cursor: pointer;
}
button.sso-btn:disabled {
    cursor: progress;
    opacity: 0.7;
}
/* Provider mark: glyphs without an admin-set button_color use
   fill="currentColor" / stroke="currentColor", so this color drives the
   scheme-aware accent fallback (SVG presentation attributes are CSP-safe). */
.sso-mark {
    flex: none;
    color: var(--login-accent-text);
}

/* ===========================================================================
   Animated wave background (canvas from /js/wave-background.js).
   These rules were moved out of the module's injected <style> block — the
   login CSP (style-src 'self') blocks JS-injected styles. The module only
   creates the elements; everything visual lives here.
   =========================================================================== */
#wave-bg {
    position: fixed;
    inset: 0;
    z-index: 0;
    overflow: hidden;
}

#wave-canvas {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: block;
}

/* Gradient overlay — fades the scene toward the top so the card stays legible.
   Stops derive from the page surfaces: near-white in light, the #17171C/#1E1E24
   family in dark. Base rule = plain light stops (same degradation contract as
   the token block: pre-light-dark() browsers get the complete light scene —
   the wave module also pins its canvas palette to light there); the
   scheme-aware pairs live in the @supports block below. */
.wave-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(
        to bottom,
        rgba(240, 245, 250, 0.92) 0%,
        rgba(235, 240, 248, 0.85) 35%,
        rgba(230, 238, 248, 0.70) 60%,
        rgba(220, 230, 245, 0.55) 80%,
        transparent 100%
    );
    pointer-events: none;
}
@supports (color: light-dark(#000, #fff)) {
    .wave-overlay {
        background: linear-gradient(
            to bottom,
            light-dark(rgba(240, 245, 250, 0.92), rgba(23, 23, 28, 0.92)) 0%,
            light-dark(rgba(235, 240, 248, 0.85), rgba(25, 25, 31, 0.85)) 35%,
            light-dark(rgba(230, 238, 248, 0.70), rgba(27, 27, 34, 0.70)) 60%,
            light-dark(rgba(220, 230, 245, 0.55), rgba(30, 30, 36, 0.55)) 80%,
            transparent 100%
        );
    }
}

/* Grain texture (inline SVG data URI — allowed by img-src 'self' data:). */
.wave-grain {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    opacity: 0.035;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
    background-repeat: repeat;
}
