/* ==========================================================================
   EVOQ DESIGN SYSTEM  ·  the .NET system
   --------------------------------------------------------------------------
   The same tokens the storefront uses, so the shop and the product people
   actually receive read as one company. Dark-committed: the brand mark is
   charcoal-on-black with a single cyan accent, so the whole system is built
   as "near-black surfaces + one signal colour".

   Teal is reserved for things you can ACT on — buttons, links, focus. Never
   decorative. When everything is highlighted, nothing is.

   Mobile is the whole audience here: these pages are opened by tapping a card
   with a phone, often on Egyptian mobile data on a mid-range Android. So:
   no scroll listeners, no fixed backgrounds, no filters that force repaints,
   transform/opacity animation only, and 16px minimum on inputs so iOS never
   zooms the page out from under someone mid-sign-in.
   ========================================================================== */

/* ==========================================================================
   THEME
   --------------------------------------------------------------------------
   The app chrome follows the phone. Someone who has set their device to light
   because they are outdoors, or to dark because it is late, has already told
   us what they want; a page that overrules that is being decorative at the
   customer's expense.

   The bare :root block is the LIGHT palette, and the media query redefines
   only tokens. That order matters: a colour whose sole definition sits inside
   the media query never applies for anyone whose device reports light, which
   is the classic way a themed page ends up rendering one theme's text on the
   other theme's background.

   THE PUBLIC PROFILE CARD IS DELIBERATELY EXEMPT. It is the product, not the
   interface — the customer chose its colours, and a business card that turns
   white because the person holding the phone prefers light mode is no longer
   their card. profile.css sets its own values and never reads these tokens.
   ========================================================================== */

:root {
    /* Tells the browser to draw form controls, scrollbars and autofill in the
       matching theme, instead of a dark page with white native widgets. */
    color-scheme: light dark;

    /* --- Surfaces ------------------------------------------------------
       Not pure white. A flat #fff under a near-black wordmark is harsh in
       daylight and clinical indoors; these carry a slight cool bias toward
       the brand teal so the neutral reads as chosen rather than inherited. */
    --void: #ffffff;
    --base: #f2f6f8;
    --surface: #ffffff;
    --raised: #e9eff3;
    --line: #dbe4ea;
    --line-strong: #c3d0d9;

    /* --- Ink ------------------------------------------------------------
       The darkest surface from the dark theme, reused as text. Reusing the
       opposite theme's surface keeps the two feeling like one family. */
    --ink: #0c1218;
    --ink-soft: #465865;
    --ink-mute: #6d818f;

    /* --- Signal -------------------------------------------------------
       Brand teal, measured off the chain link in the wordmark rather than
       eyeballed. 5.3:1 on the page and 5.3:1 behind void-coloured button
       text, so it works as both accent and fill. The tints exist for small
       text, where the brand colour itself sits too close to the ground. */
    --tap-50: #e8fafc;
    --tap-200: #86dde7;
    --tap-400: #17b4c6;
    --tap: #0291a2;
    --tap-600: #02737f;
    --tap-800: #014851;

    /* The deep blue the live profile has always used for its primary
       button. Kept as its own token so the digital-profile surfaces can
       stay recognisable to customers who already carry the card. */
    --action: #00628c;

    /* --- State (sparingly) --------------------------------------------- */
    --good: #34d399;
    --warn: #fbbf24;
    --bad: #fb7185;

    /* --- Type ----------------------------------------------------------
       Clamped so a 360px Android never gets a headline that wraps into six
       lines, and a desktop never gets a headline that looks like a mistake. */
    --font: "Geist", "Poppins", ui-sans-serif, system-ui, -apple-system,
            "Segoe UI", Roboto, sans-serif;

    --t-display: clamp(2rem, 8vw, 3.25rem);
    --t-h1: clamp(1.6rem, 6vw, 2.25rem);
    --t-h2: clamp(1.25rem, 4.5vw, 1.6rem);
    --t-body: 1rem;
    --t-small: 0.8125rem;
    --t-micro: 0.75rem;

    /* --- Shape --------------------------------------------------------- */
    --r-card: 1.25rem;
    --r-field: 0.75rem;
    --r-pill: 999px;

    /* --- Motion --------------------------------------------------------
       One easing curve for entrances, one for reversible things. More than
       two and the interface stops feeling like it was made by one person. */
    --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
    --ease-both: cubic-bezier(0.65, 0, 0.35, 1);

    /* --- Depth ---------------------------------------------------------
       On a light page a shadow is a soft grey cast; on near-black it has to
       be almost pure black or it reads as a muddy halo. */
    --shadow-1: 0 1px 2px rgba(15, 30, 45, .06);
    --shadow-2: 0 8px 24px rgba(15, 30, 45, .09);
    --shadow-3: 0 20px 48px rgba(15, 30, 45, .13);

    /* --- Page backdrop --------------------------------------------------
       The dark theme uses the card photograph behind a scrim. In light there
       is no dark photograph that works, so it becomes a soft wash instead —
       one token, so no page has to know which theme it is in. */
    --page-backdrop:
        radial-gradient(70ch 50ch at 12% -8%, rgba(2, 145, 162, .10), transparent 62%),
        radial-gradient(60ch 44ch at 96% 4%, rgba(0, 98, 140, .08), transparent 62%);

    /* Which wordmark to hang on the page. White letters vanish on a light
       ground, so the two themes need two files. */
    --wordmark: url('/assets/evoq-wordmark-ink.webp');

    /* Ink that sits ON the accent fill. Near-black in both themes: on
       #0291a2 it scores 5.6:1 where white manages 3.8:1. */
    --on-accent: #04070a;

    /* Row and tile hover. A white wash is invisible on a light ground and a
       black one is invisible on a dark one, so it flips with the theme. */
    --hover-tint: rgba(12, 18, 24, .045);

    /* Teal at full strength is 3.8:1 on white — fine as a button FILL with
       dark text on it, too weak for a link. Links get the darker step. */
    --link: var(--tap-600);
}

/* ==========================================================================
   DARK
   Only tokens are redefined here. Nothing below this point declares a colour
   that does not also exist above.
   ========================================================================== */

@media (prefers-color-scheme: dark) {
    :root {
        --void: #04070a;
        --base: #070b10;
        --surface: #0c1218;
        --raised: #131b23;
        --line: #1e2830;
        --line-strong: #2b3841;

        --ink: #eef4f7;
        --ink-soft: #a9bac6;
        --ink-mute: #6d818f;

        --shadow-1: 0 1px 2px rgba(0, 0, 0, .4);
        --shadow-2: 0 8px 24px rgba(0, 0, 0, .45);
        --shadow-3: 0 24px 64px rgba(0, 0, 0, .55);

        --page-backdrop:
            linear-gradient(180deg, rgba(7, 11, 16, .84), rgba(4, 7, 10, .95)),
            url('/assets/9.png');

        --wordmark: url('/assets/evoq-wordmark.webp');

        /* On near-black the full-strength teal clears 5:1; the darker step
           would disappear. */
        --link: var(--tap-200);

        --hover-tint: rgba(255, 255, 255, .035);
    }
}

/* ==========================================================================
   RESET
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; padding: 0; }

html {
    -webkit-text-size-adjust: 100%;
    /* Opt into the dark form controls, scrollbars and autofill styling the
       browser already knows how to draw, instead of fighting them. */
    color-scheme: dark;
}

body {
    font-family: var(--font);
    font-size: var(--t-body);
    line-height: 1.6;
    color: var(--ink);
    background: var(--base);
    /* clip, not hidden: `hidden` on body silently makes position:sticky
       stop working in every descendant. */
    overflow-x: clip;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

img, svg, video { display: block; max-width: 100%; }

button, input, textarea, select { font: inherit; color: inherit; }

a { color: inherit; }

/* ==========================================================================
   ACCESSIBILITY
   ========================================================================== */

/* A visible focus ring on every interactive thing, in the accent colour so
   it reads as "this is the live element". Removing focus rings is the single
   most common way a good-looking interface becomes unusable by keyboard. */
:where(a, button, input, textarea, select, [tabindex]):focus-visible {
    outline: 2px solid var(--tap-400);
    outline-offset: 2px;
    border-radius: 4px;
}

/* Honour the OS setting. Someone who gets motion sickness from parallax has
   already told their phone; the page does not get to overrule that. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ==========================================================================
   LAYOUT
   ========================================================================== */

/* dvh, not vh. On iOS Safari `100vh` is taller than the visible area while
   the address bar is showing, so a centred card sits too low and the page
   scrolls for no reason. */
.evoq-shell {
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 24px 20px;
    padding-top: max(24px, env(safe-area-inset-top));
    padding-bottom: max(24px, env(safe-area-inset-bottom));
}

.evoq-panel {
    width: 100%;
    max-width: 26rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    box-shadow: var(--shadow-3);
    padding: 28px 24px;
}

.evoq-panel--wide { max-width: 34rem; }

/* ==========================================================================
   TYPE
   ========================================================================== */

.evoq-title {
    font-size: var(--t-h1);
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: -0.02em;
}

.evoq-subtitle {
    font-size: var(--t-h2);
    font-weight: 600;
    letter-spacing: -0.015em;
}

.evoq-lead {
    color: var(--ink-soft);
    font-size: 0.9375rem;
    line-height: 1.65;
}

.evoq-muted { color: var(--ink-mute); font-size: var(--t-small); }

/* ==========================================================================
   FIELDS
   ========================================================================== */

.evoq-field { display: block; margin-bottom: 14px; }

.evoq-label {
    display: block;
    margin-bottom: 6px;
    font-size: var(--t-small);
    font-weight: 500;
    color: var(--ink-soft);
}

.evoq-input {
    width: 100%;
    /* 16px exactly. Anything smaller and iOS zooms the viewport on focus,
       which on a sign-in form looks like the page broke. */
    font-size: 16px;
    padding: 13px 15px;
    color: var(--ink);
    background: var(--void);
    border: 1px solid var(--line-strong);
    border-radius: var(--r-field);
    transition: border-color .18s var(--ease-both),
                box-shadow .18s var(--ease-both);
}

.evoq-input::placeholder { color: var(--ink-mute); }

.evoq-input:focus {
    outline: none;
    border-color: var(--tap);
    box-shadow: 0 0 0 3px rgba(2, 145, 162, .22);
}

.evoq-input[aria-invalid="true"] { border-color: var(--bad); }

/* A one-time code is read digit by digit, so it gets tracking, tabular
   figures and a monospaced face — the same reason bank cards are grouped. */
.evoq-input--code {
    text-align: center;
    letter-spacing: .42em;
    text-indent: .42em;
    font-variant-numeric: tabular-nums;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* ==========================================================================
   BUTTONS
   ========================================================================== */

.evoq-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    /* 48px is the smallest target most people can hit reliably with a thumb
       while walking, which is how a lot of these pages get used. */
    min-height: 48px;
    padding: 13px 20px;
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    border: 1px solid transparent;
    border-radius: var(--r-field);
    cursor: pointer;
    text-decoration: none;
    transition: transform .16s var(--ease-out),
                background-color .16s var(--ease-both),
                border-color .16s var(--ease-both);
}

/* Transform only — never width/height/top — so the press stays on the
   compositor and never triggers layout on a mid-range phone. */
.evoq-btn:active { transform: scale(.985); }

.evoq-btn[disabled], .evoq-btn.is-busy {
    opacity: .55;
    pointer-events: none;
}

.evoq-btn--primary {
    background: var(--tap);
    /* Near-black on teal in both themes — see --on-accent. */
    color: var(--on-accent);
}

.evoq-btn--primary:hover { background: var(--tap-400); }

.evoq-btn--ghost {
    background: transparent;
    border-color: var(--line-strong);
    color: var(--ink);
}

.evoq-btn--ghost:hover {
    background: var(--raised);
    border-color: var(--tap-600);
}

.evoq-btn--quiet {
    background: transparent;
    border-color: transparent;
    color: var(--ink-soft);
    min-height: 40px;
}

.evoq-btn--quiet:hover { color: var(--ink); }

/* ==========================================================================
   MESSAGES
   ========================================================================== */

/* Reserves its own height whether or not it holds text, so the button below
   never jumps down the instant an error appears — which is exactly when
   somebody's thumb is already moving toward it. */
.evoq-msg {
    min-height: 1.25rem;
    margin-top: 12px;
    font-size: var(--t-small);
    line-height: 1.5;
    color: var(--bad);
}

.evoq-msg--ok { color: var(--good); }
.evoq-msg--info { color: var(--ink-soft); }

/* ==========================================================================
   BRAND
   ========================================================================== */

.evoq-brand {
    display: flex;
    justify-content: center;
    margin-bottom: 22px;
}

.evoq-brand img {
    height: 34px;
    width: auto;
    /* The supplied wordmark is dark artwork on a light plate; on a near-black
       page it needs lifting rather than a second asset. */
    filter: brightness(0) invert(1);
    opacity: .92;
}

/* ==========================================================================
   ENTRANCE
   Compositor-only, runs once, and skipped entirely under reduced-motion by
   the rule above. No scroll listener anywhere in this file.
   ========================================================================== */

@keyframes evoq-rise {
    from { opacity: 0; transform: translate3d(0, 10px, 0); }
    to   { opacity: 1; transform: none; }
}

.evoq-rise {
    animation: evoq-rise .5s var(--ease-out) both;
}

.evoq-rise-2 { animation-delay: .06s; }
.evoq-rise-3 { animation-delay: .12s; }

/* ==========================================================================
   WORDMARK
   --------------------------------------------------------------------------
   An <img src> cannot change with the theme from CSS, and the white mark
   disappears on a light page. So the mark is a box with a background-image
   token: one element, two files, no JavaScript and no flash of the wrong one.

   Aspect is fixed at the artwork's own 3.2444:1, so a page sets height alone
   and the width follows — the same contract the <img> had.
   ========================================================================== */

.evoq-wordmark {
    display: block;
    aspect-ratio: 3.2444;
    background-image: var(--wordmark);
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
}
