/*
 * Site themes and type. Every color used by the site CSS is defined here as a
 * variable; edit the light and dark values below to restyle the whole site.
 *
 * With no saved choice (Auto) the theme follows the visitor's OS setting. The
 * header's settings (js/ui.js, js/theme.js) set <html data-theme="light|dark">,
 * which overrides it.
 *
 * Type (DESIGN.md): bold Helvetica Neue for big text (page and panel
 * titles, the brand), Proxima Nova for everything else, numbers included,
 * with tabular figures so values line up. Proxima Nova is used where it's
 * installed; otherwise Figtree, a free near-match. Helvetica Neue is on Apple
 * devices; elsewhere Helvetica or Arial, and Arimo (drawn to Helvetica's
 * metrics) where neither is installed (Android, Linux). The web fonts come
 * from the Google Fonts link in each page's <head>, and are only downloaded
 * when needed. To switch fonts, change these two lines.
 */
:root {
    /* Layers (z-index), lowest first. Page CSS uses these, never raw numbers.
       Inside a component that's already its own layer (the header, a map)
       small local numbers are fine. */
    --z-raised: 1;     /* sticky table heads, frozen columns */
    --z-overlay: 2;    /* boxes on a visual: map legends, zoom reset */
    --z-header: 100;   /* the sticky site header, with its menus and loading bar */
    --z-popover: 200;  /* floating page menus (a column's filter menu): over the header */
    --z-modal: 1000;   /* dialogs, sheets and their dimmed backdrops */
}

:root {
    --font-sans: "Proxima Nova", "Figtree", system-ui, sans-serif;
    --font-display: "Helvetica Neue", Helvetica, Arial, "Arimo", sans-serif;
}

/* ── Light (default) ───────────────────────────────────────────────────── */
/* White and cool greys with a single navy accent. */
:root {
    color-scheme: light;

    /* Page */
    --color-bg: #ffffff;
    --color-text: #1c2530;
    --color-text-muted: #5f6b78;

    /* Headings, links, bullets and other accents */
    --color-heading: #0b3d5c;
    --color-accent: #0b3d5c;
    --color-accent-hover: #1d6fa5;

    /* Cards, tabs, code, quotes */
    --color-surface: #ffffff;
    --color-surface-hover: #f2f5f8;
    --color-surface-muted: #eceff3;
    --color-border: #d8dee5;
    --color-tag-bg: #e6edf3;
    /* Flight status chips (homepage): en route blue, on station teal, returning amber */
    --status-enroute-bg: #dbe8f7;
    --status-enroute-text: #1a4f8f;
    --status-station-bg: #0f7a7a;
    --status-station-text: #ffffff;
    --status-returning-bg: #fbe5c0;
    --status-returning-text: #7a4800;
    --color-tag-text: #0b3d5c;
    /* Highlighted table rows (ADECK Viewer): a band, and the rows within it that matter most */
    --color-highlight: #e5eef7;
    --color-highlight-strong: #c2d8ec;

    /* Header bar (a page can still override --header-bg with data-color) */
    --header-bg: #0b3d5c;
    --header-text: #ffffff;
    --header-link-hover: rgba(255, 255, 255, 0.15);
    --header-rule: rgba(255, 255, 255, 0.35);
    --header-warn: #ffc56b;

    /* App controls (TDR viewer): inputs, buttons, notices */
    --color-text-faint: #6b7581;
    --color-border-strong: #c3ccd6;
    --color-skeleton: #e4e9ee;      /* placeholder blocks while page elements load */
    --color-input-bg: #f7f9fb;
    --color-button-bg: #0b3d5c;
    --color-button-hover: #134e74;
    --color-button-text: #ffffff;
    --color-button-neutral-bg: #eceff3;
    --color-button-neutral-border: #d0d7df;
    --color-button-neutral-hover: #e1e6ec;
    --color-button-neutral-text: #1c2530;
    --color-info-bg: #e6eef5;
    --color-info-border: #b9cddd;
    --color-info-text: #0b3d5c;
    --color-error: #c62828;
    --color-error-bg: #fdecec;
    --color-error-border: #f5c2c2;
    --color-warn: #9a5b00;

    /* Skew-T (dropsondes): the conventional meteorological colors */
    --skewt-temp: #c62828;
    --skewt-dew: #2e7d32;
    --skewt-dry: #c0772a;
    --skewt-moist: #2f6fb0;
    --skewt-mixing: #8a4fb8;
    --skewt-parcel: #3b3f46;
    --skewt-cape: #e53935;
    --skewt-cin: #1e6fd9;

    /* Hodograph height bands (dropsondes): 0-1, 1-3, 3-6, 6-9, 9+ km */
    --hodo-0: #c2185b;
    --hodo-1: #e65100;
    --hodo-2: #2e7d32;
    --hodo-3: #1565c0;
    --hodo-4: #6a1b9a;

    /* TDR 2D plot overlays: drawn over any color table, so the same in both themes */
    --tdr-track: #ff59d6;
    --tdr-track-start: #5fff8f;
    --tdr-track-end: #ff5f5f;
    --tdr-slice: #ffdd55;
    --tdr-flow: rgba(255, 255, 255, 0.92);
    --tdr-flow-halo: rgba(15, 15, 15, 0.55);
    --tdr-center-line: rgba(0, 0, 0, 0.55);
    --tdr-center-label: rgba(0, 0, 0, 0.75);

    /* Wind barbs by Saffir-Simpson category (HDOB page): hard cutoffs */
    --wind-cat-0: #1c2530;   /* below hurricane force */
    --wind-cat-1: #1f6fd1;
    --wind-cat-2: #2a9d3a;
    --wind-cat-3: #ef8a00;
    --wind-cat-4: #d62828;
    --wind-cat-5: #e0529c;
    /* Vortex Alignment's time-height panel: center offset from the low-level center, pale (aligned) to dark (tilted), hard steps */
    --tilt-bin-0: #e3eef8;
    --tilt-bin-1: #b5d2ea;
    --tilt-bin-2: #7fb0da;
    --tilt-bin-3: #4a86c0;
    --tilt-bin-4: #245f99;
    --tilt-bin-5: #0b3d5c;
    /* Agreement, 1 (very low) to 5 (very high): Ocean Winds' validation scale */
    --agree-1: #c62828;
    --agree-2: #e8710a;
    --agree-3: #c9a400;
    --agree-4: #7cb342;
    --agree-5: #2e7d32;
}

/* ── Dark ──────────────────────────────────────────────────────────────── */
/* Soft slate grey, off-white text, one muted steel-blue accent.
   Defined twice with the same values: once for OS dark mode (unless the
   visitor picked light), once for an explicit dark choice. Keep them in sync. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;

        --color-bg: #1e242c;
        --color-text: #d4dae1;
        --color-text-muted: #9ba6b2;

        --color-heading: #b3cce2;
        --color-accent: #7fb0da;
        --color-accent-hover: #a3c8e8;

        --color-surface: #262d36;
        --color-surface-hover: #2c343e;
        --color-surface-muted: #303843;
        --color-border: #3b4450;
        --color-tag-bg: #2a3a4b;
        --status-enroute-bg: #1d3550;
        --status-enroute-text: #9cc6ff;
        --status-station-bg: #138a8a;
        --status-station-text: #ffffff;
        --status-returning-bg: #4a3612;
        --status-returning-text: #f3c46b;
        --color-tag-text: #b3cce2;
        --color-highlight: #2c3947;
        --color-highlight-strong: #3a5876;

        --header-bg: #0f2f47;
        --header-text: #e6ebf0;
        --header-link-hover: rgba(255, 255, 255, 0.08);
    --header-rule: rgba(255, 255, 255, 0.25);
    --header-warn: #f0b35a;

        /* App controls (TDR viewer): inputs, buttons, notices */
        --color-text-faint: #8e99a5;
        --color-border-strong: #4a5360;
        --color-skeleton: #343c47;
        --color-input-bg: #20262e;
        --color-button-bg: #3e6f99;
        --color-button-hover: #4a7fac;
        --color-button-text: #ffffff;
        --color-button-neutral-bg: #303843;
        --color-button-neutral-border: #454e5a;
        --color-button-neutral-hover: #3a434f;
        --color-button-neutral-text: #d4dae1;
        --color-info-bg: #22364a;
        --color-info-border: #36536e;
        --color-info-text: #a3c8e8;
        --color-error: #f28b82;
        --color-error-bg: #3a2226;
        --color-error-border: #5c3237;
        --color-warn: #f0b35a;

        --skewt-temp: #f2665e;
        --skewt-dew: #5cc26a;
        --skewt-dry: #d49a5c;
        --skewt-moist: #6fa6de;
        --skewt-mixing: #b88ad9;
        --skewt-parcel: #e6e8eb;
        --skewt-cape: #ff6b61;
        --skewt-cin: #5aa2ff;
        --hodo-0: #f06292;
        --hodo-1: #ffa040;
        --hodo-2: #66bb6a;
        --hodo-3: #64b5f6;
        --hodo-4: #ba68c8;

        --wind-cat-0: #e8eaed;
        --wind-cat-1: #5a9dff;
        --wind-cat-2: #4cc35a;
        --wind-cat-3: #ffa22e;
        --wind-cat-4: #ff5a52;
        --wind-cat-5: #ff7cc4;
        --tilt-bin-0: #24374a;
        --tilt-bin-1: #2e5274;
        --tilt-bin-2: #3d72a1;
        --tilt-bin-3: #5b98cd;
        --tilt-bin-4: #92bfe6;
        --tilt-bin-5: #d4e7f8;
        /* Agreement, 1 (very low) to 5 (very high): Ocean Winds' validation scale */
        --agree-1: #f2665e;
        --agree-2: #ff9a3d;
        --agree-3: #f0d04a;
        --agree-4: #9ccc65;
        --agree-5: #4cc35a;
    }
}

:root[data-theme="dark"] {
    color-scheme: dark;

    --color-bg: #1e242c;
    --color-text: #d4dae1;
    --color-text-muted: #9ba6b2;

    --color-heading: #b3cce2;
    --color-accent: #7fb0da;
    --color-accent-hover: #a3c8e8;

    --color-surface: #262d36;
    --color-surface-hover: #2c343e;
    --color-surface-muted: #303843;
    --color-border: #3b4450;
    --color-tag-bg: #2a3a4b;
    --status-enroute-bg: #1d3550;
    --status-enroute-text: #9cc6ff;
    --status-station-bg: #138a8a;
    --status-station-text: #ffffff;
    --status-returning-bg: #4a3612;
    --status-returning-text: #f3c46b;
    --color-tag-text: #b3cce2;
    --color-highlight: #2c3947;
    --color-highlight-strong: #3a5876;

    --header-bg: #0f2f47;
    --header-text: #e6ebf0;
    --header-link-hover: rgba(255, 255, 255, 0.08);
    --header-rule: rgba(255, 255, 255, 0.25);
    --header-warn: #f0b35a;

    /* App controls (TDR viewer): inputs, buttons, notices */
    --color-text-faint: #8e99a5;
    --color-border-strong: #4a5360;
    --color-skeleton: #343c47;
    --color-input-bg: #20262e;
    --color-button-bg: #3e6f99;
    --color-button-hover: #4a7fac;
    --color-button-text: #ffffff;
    --color-button-neutral-bg: #303843;
    --color-button-neutral-border: #454e5a;
    --color-button-neutral-hover: #3a434f;
    --color-button-neutral-text: #d4dae1;
    --color-info-bg: #22364a;
    --color-info-border: #36536e;
    --color-info-text: #a3c8e8;
    --color-error: #f28b82;
    --color-error-bg: #3a2226;
    --color-error-border: #5c3237;
    --color-warn: #f0b35a;

    --skewt-temp: #f2665e;
    --skewt-dew: #5cc26a;
    --skewt-dry: #d49a5c;
    --skewt-moist: #6fa6de;
    --skewt-mixing: #b88ad9;
    --skewt-parcel: #e6e8eb;
    --skewt-cape: #ff6b61;
    --skewt-cin: #5aa2ff;
    --hodo-0: #f06292;
    --hodo-1: #ffa040;
    --hodo-2: #66bb6a;
    --hodo-3: #64b5f6;
    --hodo-4: #ba68c8;

    --wind-cat-0: #e8eaed;
    --wind-cat-1: #5a9dff;
    --wind-cat-2: #4cc35a;
    --wind-cat-3: #ffa22e;
    --wind-cat-4: #ff5a52;
    --wind-cat-5: #ff7cc4;
    --tilt-bin-0: #24374a;
    --tilt-bin-1: #2e5274;
    --tilt-bin-2: #3d72a1;
    --tilt-bin-3: #5b98cd;
    --tilt-bin-4: #92bfe6;
    --tilt-bin-5: #d4e7f8;
    /* Agreement, 1 (very low) to 5 (very high): Ocean Winds' validation scale */
    --agree-1: #f2665e;
    --agree-2: #ff9a3d;
    --agree-3: #f0d04a;
    --agree-4: #9ccc65;
    --agree-5: #4cc35a;
}

/* ── Night ─────────────────────────────────────────────────────────────── */
/* For a dark cockpit (js/theme.js): the dark theme, blacker, then the whole
   page through the red filter (#tr-night, js/theme.js), so every pixel
   (canvases, maps, satellite images, charts) is a dim red by its brightness.
   On the root the filter doesn't disturb fixed or sticky positioning.
   Dialogs sit in the top layer, outside it, so they get it too. Light
   content (paper: PDF pages) is inverted first, so it's dark, not glaring. */
:root[data-night] {
    --color-bg: #000000;
    --color-surface: #050505;
    --color-surface-hover: #101010;
    --color-surface-muted: #0b0b0b;
    --color-input-bg: #050505;
    --color-border: #2a2a2a;
    --color-border-strong: #3a3a3a;
    --color-skeleton: #161616;
    --header-bg: #000000;
}

/* --night-brightness: the red mode's dimmer (js/theme.js, the settings' slider) */
:root[data-night],
:root[data-night] dialog,
:root[data-night] dialog::backdrop {
    filter: url(#tr-night) brightness(var(--night-brightness, 1));
}

/* A dropdown's open list is drawn by the browser outside the page, so the
   filter never reaches it: its colors are red already (Chrome and Firefox
   on Windows, Linux and Android use these; macOS and iOS draw their own
   native menus, dark with color-scheme) */
:root[data-night] select option,
:root[data-night] select optgroup {
    color: #b30000;
    background-color: #000000;
}

:root[data-night] select option:checked {
    color: #ff1a1a;
    background-color: #2a0000;
}

:root[data-night] select option:disabled {
    color: #5c0000;
}

:root[data-night] .night-invert {
    filter: invert(1) hue-rotate(180deg);
}

/* ── Apply ─────────────────────────────────────────────────────────────── */
/* Browsers with classic scrollbars (Windows, most Linux) take the scrollbar's
   width out of pages that scroll and not out of pages that don't, which moved
   the header's right-aligned nav from page to page. Keep the space on every
   page. (Overlay scrollbars, on Macs and phones, aren't affected.) */
html {
    scrollbar-gutter: stable;
}

/* Every page is full-bleed; set here too so it doesn't hang on footer.css's
   :has() (browsers without it kept the default 8px margin) */
body {
    margin: 0;
}

body {
    background-color: var(--color-bg);
    color: var(--color-text);
    font-family: var(--font-sans);
    font-variant-numeric: tabular-nums;
}

/* Form controls don't inherit fonts by default */
button,
input,
select,
textarea {
    font-family: inherit;
    font-variant-numeric: inherit;
}

/* Controls aren't text: clicking, dragging or double-clicking one never
   selects its label or leaves a text caret in it. Links in running text
   stay selectable; only button-like ones (nav, cards, calls to action) are
   covered. Text fields keep working as usual. */
button,
summary,
select,
label,
[role="button"],
[role="tab"],
[role="menuitem"],
[role="separator"],
.site-header__brand,
.site-header__link,
.site-header__nav a,
.site-footer__link,
.home-intro__link,
.data-card,
.missions__primary {
    -webkit-user-select: none;
    user-select: none;
}

label :is(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea) {
    -webkit-user-select: text;
    user-select: text;
}

/* ── Skeletons (page elements loading) ──────────────────────────────────── */
/* A flat grey block standing in for an element whose content is on its way:
   titles, lists, the header's stamp, and data views (charts, maps, plots,
   readouts) while new data loads into them, with the loading bar (js/ui.js).
   Not for dropdowns, where a grey
   block reads as the control loading rather than the data (a loading
   dropdown is just disabled, showing "Loading…"). The element keeps its
   size; its content is hidden. Toggle it with Skeleton.on/off (js/ui.js),
   which fades the content in when it arrives. */
.skeleton {
    color: transparent !important;
    background-color: var(--color-skeleton) !important;
    border-color: var(--color-skeleton) !important;
    animation: skeleton-pulse 1.4s ease-in-out infinite;
    pointer-events: none;
    user-select: none;
}

.skeleton * {
    visibility: hidden;
}

/* A line of text still to come: <span class="skeleton skeleton-line" style="width: 60%"> */
.skeleton-line {
    display: inline-block;
    height: 0.8em;
    vertical-align: middle;
}

@keyframes skeleton-pulse {
    50% { opacity: 0.55; }
}

/* On the navy header a light block glares: a translucent one blends in */
.site-header .skeleton {
    background-color: rgb(255 255 255 / 0.14) !important;
    border-color: transparent !important;
}

/* The content arriving: the block fades out under it instead of snapping
   (Skeleton.off adds .skeleton-out for the length of the animation) */
.skeleton-out {
    animation: skeleton-out 0.3s ease-out;
}

@keyframes skeleton-out {
    from {
        color: transparent;
        background-color: var(--color-skeleton);
    }
}

.site-header .skeleton-out {
    animation-name: skeleton-out-header;
}

@keyframes skeleton-out-header {
    from {
        color: transparent;
        background-color: rgb(255 255 255 / 0.14);
    }
}

@media (prefers-reduced-motion: reduce) {
    .skeleton,
    .skeleton-out { animation: none; }
}

/* ── Wind category swatch ──────────────────────────────────────────────── */
/* A small square in the Saffir-Simpson category color of a wind, before its
   value in readouts (e.g. WL150): <span class="wind-swatch cat-3">. Hard
   cutoffs; below hurricane force it's --wind-cat-0. */
.wind-swatch {
    display: inline-block;
    width: 0.65rem;
    height: 0.65rem;
    margin-right: 0.3rem;
    vertical-align: -1px;
    background-color: var(--wind-cat-0);
}

.wind-swatch.cat-1 { background-color: var(--wind-cat-1); }
.wind-swatch.cat-2 { background-color: var(--wind-cat-2); }
.wind-swatch.cat-3 { background-color: var(--wind-cat-3); }
.wind-swatch.cat-4 { background-color: var(--wind-cat-4); }
.wind-swatch.cat-5 { background-color: var(--wind-cat-5); }

/* Page tags: a small bold label beside a title ("Research", "Experimental").
   Solid navy; --warn is outlined in the warn color, for data still being
   proven. Whatever holds one centers it on its text. */
.page-tag {
    display: inline-flex;
    align-items: center;
    flex: none;
    padding: 0.15rem 0.4rem;
    font-family: var(--font-sans);
    font-size: 0.62rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--color-button-text);
    background-color: var(--color-button-bg);
    border: 1px solid var(--color-button-bg);
}

.page-tag--warn {
    color: var(--color-warn);
    background-color: transparent;
    border-color: currentColor;
}

:is(h1, h2, h3, p, div, span):has(> .page-tag) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 0.5rem;
}


/* Close and Cancel buttons, site-wide: they fade to a light red on hover, as
   a flight plan's delete does. Any dialog form's Close/Cancel (value="close"
   or "cancel"), and anything marked data-close. */
button[value="close"],
button[value="cancel"],
[data-close] {
    transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}

/* (!important: it has to win over every page's own button hover, whatever its specificity or order) */
button[value="close"]:hover:not(:disabled),
button[value="cancel"]:hover:not(:disabled),
[data-close]:hover:not(:disabled) {
    color: var(--color-error) !important;
    border-color: var(--color-error-border) !important;
    background-color: var(--color-error-bg) !important;
}

@media (prefers-reduced-motion: reduce) {
    button[value="close"], button[value="cancel"], [data-close] { transition: none; }
}
