/* ═══════════════════════════════════════════════════════════════════════
   Design tokens — the CSS mirror of docs/VISUAL_STYLE.md and qml/Theme.qml.

   Two rules were followed literally when porting:
     · QML writes colours as #AARRGGBB (alpha FIRST). CSS #RRGGBBAA puts it
       last. Every translucent value below was converted by hand; the QML
       original is kept in a comment so the two can be diffed.
     · Theme.qml derives density from the live window width. The browser
       gives us that for free through media queries, so the `narrow`
       (< 400 px) and `compact` (< 600 px) tiers are expressed as overrides
       on :root rather than as JS-published properties.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
    /* ── Colour roles (VISUAL_STYLE.md § Color roles) ── */
    --canvas:            #0d1322;
    --canvas-raised:     #11182b;
    --surface:           #171c31;
    --surface-high:      #1e2740;
    --offset-base:       #080c18;
    --hairline:          #33415f;

    --text-primary:      #f5f7ff;
    --text-secondary:    #aeb9d6;
    --text-disabled:     #68758f;

    --accent-solo:       #ff6f91;
    --accent-multi:      #58dec8;
    --accent-utility:    #5dd6c0;
    --accent-settings:   #a78bfa;
    --accent-account:    #ffb36b;
    --accent-peer:       #7ea7ff;
    --accent-focus:      #a78bfa;
    --warning:           #ffb36b;
    --error:             #ff718c;

    /* Window chrome (Main.qml) */
    --window-bg:         #0b1020;
    --header-bg:         #0a0f1c;
    --tab-idle:          #8794af;
    --tab-selected:      #f8f9ff;
    /* The phone-first UI may breathe on desktop, but its navigation chrome
       must not turn into metre-long controls on a wide monitor (D181). */
    --app-max-width:     960px;

    /* Login palette (LoginLanding.qml) */
    --login-base:        #050916;
    --ink:               #f8fbff;
    --muted-ink:         #aab7d4;
    --aqua:              #61ead1;
    --violet:            #9277ff;
    --coral:             #ff7f91;

    /* ── Safe areas ──
       The viewport meta says `viewport-fit=cover`, and the install meta
       says `black-translucent`, so on a notched phone the page really does
       run under the status bar, the home indicator and — in landscape —
       the notch itself. Every one of those has to be paid back somewhere.

       Indirected through variables rather than used as env() at each site
       for one reason: env() cannot be overridden, and a variable can. A
       desktop browser reports zero for all four, so without this there is
       no way to see the notched layout, or to test it — which is how a
       landscape inset stays broken until somebody holds the phone. Set
       --safe-left and --safe-right on the root to 47px and the landscape
       case is on screen. */
    --safe-top:          env(safe-area-inset-top, 0px);
    --safe-right:        env(safe-area-inset-right, 0px);
    --safe-bottom:       env(safe-area-inset-bottom, 0px);
    --safe-left:         env(safe-area-inset-left, 0px);

    /* What a centred page column has to give up horizontally: its own
       padding on both sides, plus both insets. Subtracting the pair from
       the width and then centring clears whichever side the notch is on,
       and stays visually centred in the page rather than in the safe area.

       Padding on the page instead would do nothing: an absolutely
       positioned child resolves `inset: 0` against its ancestor's *padding
       box*, which includes the padding. And setting left/right on the
       column over-constrains it against its own `width`, so the browser
       drops `right` and the content hangs off that edge by exactly the
       inset it was supposed to clear. */
    --page-gutter:       calc(var(--page-padding) * 2
                              + var(--safe-left) + var(--safe-right));

    /* ── Density tokens (Theme.qml) — wide tier ── */
    --page-padding:      28px;
    --card-padding:      16px;
    --panel-padding:     18px;
    --row-spacing:       10px;
    --column-spacing:    12px;
    --role-label-width:  88px;
    --field-pad-left:    16px;
    --field-pad-right:   12px;
    --chevron-size:      14px;
    --chevron-spacing:   6px;
    --swap-button-height: 26px;

    /* ── Geometry (VISUAL_STYLE.md § Geometry) ── */
    --radius-compact:    14px;
    --radius-standard:   18px;
    --radius-card:       22px;
    --radius-modal:      26px;
    --touch-target:      48px;
    --touch-min:         44px;

    /* ── Depth: the "standard raised-surface recipe" ──
       A control is an offset base + a face that sinks 3 px on press.        */
    --press-offset:      3px;
    --face-reveal:       5px;   /* how much dark base the face leaves visible */

    --shadow-1: 0 2px 8px rgba(0, 0, 0, 0.38);
    --shadow-2: 0 4px 16px rgba(0, 0, 0, 0.46);
    --shadow-3: 0 6px 22px rgba(0, 0, 0, 0.52);

    /* ── Motion (VISUAL_STYLE.md § Animation) ── */
    --press-duration:    100ms;
    --hover-duration:    140ms;
    --state-duration:    200ms;
    --ease-out:          cubic-bezier(0.22, 0.61, 0.36, 1);   /* ≈ OutCubic */

    /* ── Type ──
       "LL Sans" is one family holding twenty scripts, each face gated by its
       own unicode-range (see css/fonts.css); the browser fetches exactly the
       one a codepoint needs. The system stack stays behind it as the honest
       fallback — a face that fails to load costs glyph shapes, not text.
       Han is the exception: SC, TC, JP and Korean Hanja draw the same
       codepoints differently, so they are separate families chosen by `lang`
       further down in app.css. */
    --font-stack: "LL Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
                  "Noto Sans", Roboto, "Helvetica Neue", Arial, sans-serif;
    --font-mono:  ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas,
                  "Liberation Mono", monospace;

    --type-tab:      13px;
    --type-body:     15px;
    --type-value:    16px;
    --type-card:     17px;
    --type-hero:     22px;
    --type-meta:     12px;
}

/* Theme.compact — "phone or small tablet" (Theme.qml: viewportWidth < 600) */
@media (max-width: 599px) {
    :root {
        --page-padding:   16px;
        --card-padding:   16px;
        --panel-padding:  18px;
        --row-spacing:    10px;
        --column-spacing: 12px;
    }
}

/* Theme.narrow — a single 600 px breakpoint is true for every phone in
   portrait, so it could not tell a 320 px device from a 430 px one. */
@media (max-width: 399px) {
    :root {
        --page-padding:    12px;
        --card-padding:    12px;
        --panel-padding:   12px;
        --row-spacing:     8px;
        --column-spacing:  8px;
        --field-pad-left:  12px;
        --field-pad-right: 10px;
        --chevron-spacing: 4px;
    }
}

/* VISUAL_STYLE.md § Animation: "Add a reduced-motion setting". The browser
   already ships one — honour it rather than waiting for a Settings toggle. */
@media (prefers-reduced-motion: reduce) {
    :root {
        --press-duration: 1ms;
        --hover-duration: 1ms;
        --state-duration: 1ms;
    }
    *, *::before, *::after {
        animation-duration: 1ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 1ms !important;
    }
}
