/*
 * What Board - kiosk shell styles: reset, boot veil, stage, logo slot, status
 * chip, runtime notice card, and the html[data-theme] defaults.
 *
 * Board DESIGNS (currency, flights, transit) live in css/boards.css, which is
 * linked AFTER this file. This file owns no board layout; it only publishes the
 * tokens the designs build on.
 *
 * COLOUR CONTRACT. A device design may override ONLY the six custom properties
 * below (--bg --ink --accent --accent-strong --accent-soft --border), applied
 * through js/branding.js - never by injecting CSS. They arrive as an M3 LIGHT
 * palette (--bg a light page, --ink dark text), and the theme maps them:
 *   dark  (default): surface = --ink, text = --bg
 *   light          : surface = --bg,  text = --ink
 * The shell's own tokens are --stage-bg / --stage-ink; board designs derive
 * theirs from the six vars and never hardcode a brand colour.
 *
 * The boot veil and the notice card are NOT themed: their colours are literals
 * on purpose. They must look identical on every screen in the fleet, so a design
 * can neither repaint them nor hint at a tenant before one is known.
 */

:root {
    /* ---- Whitelisted branding tokens (device-overridable). The defaults are
       NEUTRAL greys in the shape of the M3 light palette: an unbranded board must
       look generic, so a device's own scheme is the only colour that ever reaches
       the display. ---- */
    --bg: #f4f5f7;
    --ink: #15181c;
    --accent: #5b6470;
    --accent-strong: #3f4852;
    --accent-soft: #dfe3e8;
    --border: #c9ced6;

    /* ---- Fixed shell tokens (not overridable). ---- */
    --font-stack: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --chip-bg: rgba(16, 18, 21, 0.86);
    --chip-ink: #ffffff;

    /* ---- Layout contract with the board renderers. The logo overlays the
       header's start edge, at most --board-logo-w wide and --board-logo-h tall,
       centred in the --board-header-h band; a design leaves that room in its own
       header. css/boards.css loads after this file and refines these on :root. ---- */
    --board-pad-x: 3vw;
    --board-header-h: 12vh;
    --board-logo-h: calc(var(--board-header-h) * 0.6);
    --board-logo-w: min(calc(var(--board-header-h) * 2.4), 24vw);
}

/* Theme: dark is the default (no attribute) and the explicit "dark". */
html {
    --stage-bg: var(--ink);
    --stage-ink: var(--bg);
}

html[data-theme="light"] {
    --stage-bg: var(--bg);
    --stage-ink: var(--ink);
}

* {
    box-sizing: border-box;
}

/* An author display rule (inline-flex, flex, grid) outranks the UA's
   [hidden]{display:none}, which left "hidden" chips painted on a live screen
   before. One global rule, so no component can defeat `hidden` by accident. */
[hidden] {
    display: none !important;
}

html,
body {
    height: 100%;
    margin: 0;
}

body {
    background: var(--stage-bg);
    color: var(--stage-ink);
    font-family: var(--font-stack);
    overflow: hidden; /* fixed-purpose signage: never scroll */
    -webkit-user-select: none;
    user-select: none;
    cursor: none; /* passive screen: no pointer */
}

/* ---- Boot veil -----------------------------------------------------------
   Covers everything until the first payload has been rendered on top of the
   branding. Literal colours (see the header). Lifted by main.js: `.is-done`
   fades it, then it goes [hidden]. */
.boot {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #101215;
    opacity: 1;
    transition: opacity 300ms ease;
    z-index: 100; /* above the chip (30) and the logo (20) */
}

/* Fade-out step; main.js sets [hidden] afterwards. pointer-events:none so a
   transparent veil mid-fade never swallows anything. */
.boot.is-done {
    opacity: 0;
    pointer-events: none;
}

.boot-spinner {
    width: max(28px, 4vmin);
    height: max(28px, 4vmin);
    border: max(3px, 0.4vmin) solid #2a2f36;
    border-top-color: #8a9099;
    border-radius: 50%;
    animation: boot-spin 900ms linear infinite;
}

@keyframes boot-spin {
    to {
        transform: rotate(360deg);
    }
}

/* Reduced motion: a gentle pulse instead of a spin. */
@media (prefers-reduced-motion: reduce) {
    .boot-spinner {
        border-color: #8a9099;
        animation: boot-pulse 2s ease-in-out infinite;
    }

    @keyframes boot-pulse {
        0%,
        100% {
            opacity: 0.25;
        }

        50% {
            opacity: 0.75;
        }
    }
}

/* ---- Stage ---------------------------------------------------------------
   The renderer mounts into this and owns everything inside. Viewport units, so
   the same bundle fills 1920x1080, 3840x2160 and portrait panels without a
   scale transform. */
.stage {
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    background: var(--stage-bg);
    color: var(--stage-ink);
    font-family: var(--font-stack);
    font-variant-numeric: tabular-nums;
}

/* ---- Device logo ---------------------------------------------------------
   Revealed by branding.js (it removes [hidden]) and tinted from --stage-ink, the
   colour the header text is drawn in. The element shrink-wraps the logo: a
   masked SVG is parked on a transparent <img> carrying the logo's aspect ratio,
   so height + auto width + max-width gives an exactly-fitting box. A board design
   reads this element (its `hidden` state and its width) to reserve the room it
   needs in its own header; the shell only positions it. */
.brand-logo {
    position: fixed;
    z-index: 20;
    left: var(--board-pad-x);
    top: calc((var(--board-header-h) - var(--board-logo-h)) / 2);
    height: var(--board-logo-h);
    width: auto;
    max-width: var(--board-logo-w);
    object-fit: contain;
    object-position: left center;
    pointer-events: none;
}

/* ---- Status chip ---------------------------------------------------------
   Over the board, top right, only while stale or offline. Literal neutrals so it
   reads on any design. */
.status-chip {
    position: fixed;
    top: 1.6vh;
    right: var(--board-pad-x);
    z-index: 30;
    display: inline-flex;
    align-items: center;
    gap: 0.8vmin;
    padding: 0.8vmin 1.6vmin;
    border-radius: 999px;
    background: var(--chip-bg);
    color: var(--chip-ink);
    border: 1px solid rgba(255, 255, 255, 0.18);
    font-size: max(14px, 1.7vmin);
    line-height: 1.2;
    letter-spacing: 0.01em;
    pointer-events: none;
}

.status-chip::before {
    content: "";
    width: 1.1vmin;
    height: 1.1vmin;
    min-width: 8px;
    min-height: 8px;
    border-radius: 50%;
    background: #e0a100; /* stale: amber */
}

.status-chip[data-state="offline"]::before {
    background: #d64545; /* offline: red */
}

/* ---- Runtime notice ------------------------------------------------------
   Built by js/notice.js when the address carries no ids, or the server keeps
   answering "no board for this device". It sits ABOVE the veil on purpose: the
   veil only lifts after a first render, and these are exactly the states that
   will never produce one. Opaque and literal-coloured (see the header): it is
   operator text that must be READ across a room, with the ids printed
   verbatim in monospace so a GUID can be compared character by character. */
.notice {
    position: fixed;
    inset: 0;
    z-index: 110; /* above the veil (100) */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2.6vh;
    padding: 4vh 6vw;
    text-align: center;
    background: #101215;
    color: #e8eaec;
    font-family: var(--font-stack);
}

.notice-title {
    font-size: 4.6vh;
    font-weight: 600;
    line-height: 1.15;
}

.notice-body {
    max-width: 70vw;
    font-size: 2.7vh;
    line-height: 1.4;
    color: rgba(232, 234, 236, 0.82);
}

.notice-ids {
    display: grid;
    grid-template-columns: auto auto;
    gap: 0.6vh 2vw;
    max-width: 86vw;
    margin: 0;
    font-family: "Cascadia Mono", "Consolas", ui-monospace, monospace;
    font-size: 2.3vh;
    line-height: 1.4;
    text-align: left;
    word-break: break-all;
}

.notice-ids dt {
    color: rgba(232, 234, 236, 0.6);
}

.notice-ids dd {
    margin: 0;
}

.notice-ids dd.is-missing {
    color: #e0a100;
    font-style: italic;
}
