/* ═══════════════════════════════════════════════════════════════════════════
   HUBIONIS THEME TOKENS
   Must load BEFORE every other stylesheet.

   Why this file exists
   ────────────────────
   Colour was written directly into rules across 52 stylesheets, so nothing
   could be re-themed. These tokens are the seam: each stylesheet now asks for
   a role ("the accent", "the surface behind a card") and this file decides
   what that role looks like in the current theme.

   Dark is the default and stays what it always was, with one deliberate
   change: the accent moves off pure chartreuse.

       #7FFF00  hue 90°, saturation 100%, luminance 0.760
       #9ECB3A  hue 79°, saturation  58%, luminance 0.502   ← the logo

   The logo has always used a half-saturated leaf green; the UI was running at
   twice that saturation, which is what read as harsh. #9ECB3A still measures
   9.4:1 on the dark ground, so nothing loses contrast.

   Light exists because the old accent cannot cross over: #7FFF00 on white is
   1.30:1 — invisible. Hence the rule the whole palette follows,

       the bright end of the ramp FILLS, the dark end WRITES.

   Nothing above --hub-g600 is ever set as text.

   Alpha variants
   ──────────────
   A token cannot carry a varying alpha, so each themed colour also has an
   -rgb triplet for `rgb(var(--token-rgb) / 0.15)`. --hub-overlay-rgb is the
   important one: dark themes lighten with white overlays, light themes darken
   with ink ones, and routing both through a single token makes every
   rgba(255,255,255,α) in the codebase flip correctly.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
    /* ── Brand ramp — hue 79-98°, saturation held near the mark.
       400 and 500 are sampled pixels from the logo; the rest extends it.
       Ratios in the comments are against white. ───────────────────────────── */
    --hub-g50:  #F5FAEF;   /*  1.06 */
    --hub-g100: #E6F4D7;   /*  1.15 */
    --hub-g200: #CAE7B1;   /*  1.35 */
    --hub-g300: #ABD883;   /*  1.63 */
    --hub-g400: #9ECB3A;   /*  1.90 — logo, light end */
    --hub-g500: #72B740;   /*  2.45 — logo, deep end  */
    --hub-g600: #58962C;   /*  3.61 — borders, large text */
    --hub-g700: #41761E;   /*  5.48 — accent text on light */
    --hub-g800: #2E5714;   /*  8.44 */
    --hub-g900: #1E390E;   /* 12.75 */

    /* The gradient motif: the logo's own 79° → 95° sweep, one angle everywhere.
       Theme-independent — it fills, it never sits behind running text. */
    --hub-fill: linear-gradient(115deg, var(--hub-g400) 0%, var(--hub-g500) 100%);
    /* The one filled weight that can hold white type (5.48:1). The bright
       sweep cannot — white on #9ECB3A is 1.90:1. */
    --hub-fill-deep: linear-gradient(115deg, var(--hub-g700) 0%, var(--hub-g800) 100%);

    --hub-radius: 14px;
    --hub-transition: 0.2s ease;

    /* ── DARK (default) ──────────────────────────────────────────────────── */
    --hub-bg-deep:       #050F0F;
    --hub-bg:            #0A1A1A;
    --hub-bg-rgb:        10 26 26;
    --hub-elev:          #0F2A2A;
    --hub-elev-rgb:      15 42 42;
    --hub-surface:       #123232;
    --hub-surface-rgb:   31 85 85;

    --hub-ink:           #FFFFFF;
    --hub-ink-rgb:       255 255 255;
    --hub-ink-muted:     #C0C0C0;
    --hub-ink-faint:     #9CA7B8;

    /* Overlays: white lightens on dark. */
    --hub-overlay-rgb:   255 255 255;
    --hub-on-accent:     #0A1A1A;   /* text on a solid --hub-accent (9.41:1) */

    --hub-accent:        var(--hub-g400);
    --hub-accent-rgb:    158 203 58;
    --hub-accent-strong: var(--hub-g500);
    --hub-accent-soft:   var(--hub-g300);

    --hub-hairline:      rgb(158 203 58 / 0.15);
    --hub-focus:         rgb(158 203 58 / 0.45);

    /* Text that sits on --hub-fill. Dark in both themes — the sweep is bright
       in both, so this never becomes white. */
    --hub-on-fill:       #0A1A1A;

    --hub-success:       #4CAF50;
    --hub-warning:       #FFA726;
    --hub-warning-rgb:   255 167 38;
    --hub-error:         #FF6B6B;
    --hub-error-rgb:     255 107 107;
    --hub-info:          #29B6F6;
    --hub-info-rgb:      41 182 246;

    --hub-shadow:        0 8px 28px rgb(0 0 0 / 0.45);

    /* Modal scrim. Near-opaque on dark, because the page behind it is already
       dark; a proper dim on light, where blacking the page out would be jarring. */
    --hub-scrim:         rgb(6 18 18 / 0.97);
}

/* ── LIGHT ───────────────────────────────────────────────────────────────────
   Applied only where the page opts in with data-theme="light", so pages whose
   stylesheets are not tokenised yet keep the dark look they were written for.
   ────────────────────────────────────────────────────────────────────────── */
:root[data-theme="light"] {
    color-scheme: light;

    /* Off-white biased green, so a white card reads as lifted off it. */
    --hub-bg-deep:       #EDF3E7;
    --hub-bg:            #F7FAF4;
    --hub-bg-rgb:        247 250 244;
    --hub-elev:          #FFFFFF;
    --hub-elev-rgb:      255 255 255;
    --hub-surface:       #FFFFFF;
    --hub-surface-rgb:   255 255 255;

    --hub-ink:           #1A2A1A;   /* 15.11:1 on white */
    --hub-ink-rgb:       26 42 26;
    --hub-ink-muted:     #5A6958;   /*  5.84:1 on white */
    --hub-ink-faint:     #63725B;

    /* Overlays: ink darkens on light — the same rgba(…, α) rules now tint
       instead of blowing out. */
    --hub-overlay-rgb:   26 42 26;
    --hub-on-accent:     #FFFFFF;   /* text on a solid --hub-accent (5.48:1) */

    --hub-accent:        var(--hub-g700);   /* 5.48:1 — links, icons, labels */
    --hub-accent-rgb:    65 118 30;
    --hub-accent-strong: var(--hub-g800);
    --hub-accent-soft:   var(--hub-g600);

    --hub-hairline:      #DDE6D3;
    --hub-focus:         rgb(88 150 44 / 0.35);

    --hub-on-fill:       #1A2A1A;   /* 6.16:1 on the deep end of the sweep */

    --hub-success:       #2E7D32;
    --hub-warning:       #B25E02;
    --hub-warning-rgb:   178 94 2;
    --hub-error:         #C0392B;
    --hub-error-rgb:     192 57 43;
    --hub-info:          #0B6FA4;
    --hub-info-rgb:      11 111 164;
    --hub-cyan:          #067A8E;   /* 4.9:1 on the light ground */

    --hub-shadow:        0 6px 20px rgb(26 42 26 / 0.09);
    --hub-scrim:         rgb(26 42 26 / 0.45);
}

/* Follow the OS only once a page has opted into theming at all. Without the
   data-theme="dark" guard this would flip untokenised pages half-light. */
@media (prefers-color-scheme: light) {
    :root[data-theme="auto"] {
        color-scheme: light;
        --hub-bg-deep: #EDF3E7;
        --hub-bg: #F7FAF4;            --hub-bg-rgb: 247 250 244;
        --hub-elev: #FFFFFF;          --hub-elev-rgb: 255 255 255;
        --hub-surface: #FFFFFF;       --hub-surface-rgb: 255 255 255;
        --hub-ink: #1A2A1A;           --hub-ink-rgb: 26 42 26;
        --hub-ink-muted: #5A6958;
        --hub-ink-faint: #63725B;
        --hub-overlay-rgb: 26 42 26;
        --hub-on-accent: #FFFFFF;
        --hub-accent: var(--hub-g700); --hub-accent-rgb: 65 118 30;
        --hub-accent-strong: var(--hub-g800);
        --hub-accent-soft: var(--hub-g600);
        --hub-hairline: #DDE6D3;
        --hub-focus: rgb(88 150 44 / 0.35);
        --hub-on-fill: #1A2A1A;
        --hub-success: #2E7D32;
        --hub-warning: #B25E02; --hub-warning-rgb: 178 94 2;
        --hub-error: #C0392B;
        --hub-error-rgb: 192 57 43;
        --hub-info: #0B6FA4;
        --hub-info-rgb:      11 111 164;
        --hub-cyan: #067A8E;
        --hub-shadow: 0 6px 20px rgb(26 42 26 / 0.09);
        --hub-scrim: rgb(26 42 26 / 0.45);
    }
}

/* Headings filled with a gradient via background-clip: text. Starting from the
   theme's ink keeps them readable in both — every one of these used to start at
   white, which vanished on the light ground. */
:root {
    --hub-heading-fill: linear-gradient(135deg, var(--hub-ink) 0%, var(--hub-accent) 100%);
}

/* ═══════════════════════════════════════════════════════════════════════════
   THEME TOGGLE
   ══════════════════════════════════════════════════════════════════════════ */

.theme-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.42rem 0.7rem;
    background: rgb(var(--hub-accent-rgb) / 0.1);
    border: 1px solid rgb(var(--hub-accent-rgb) / 0.28);
    border-radius: 999px;
    color: var(--hub-accent);
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    transition: background var(--hub-transition), border-color var(--hub-transition);
}

.theme-toggle:hover {
    background: rgb(var(--hub-accent-rgb) / 0.2);
    border-color: rgb(var(--hub-accent-rgb) / 0.5);
}

.theme-toggle:focus-visible {
    outline: 2px solid var(--hub-accent);
    outline-offset: 2px;
}

.theme-toggle svg {
    width: 15px;
    height: 15px;
    stroke: currentColor;
    fill: none;
    stroke-width: 2;
}

/* Only the icon for the theme you would switch TO is shown. */
.theme-toggle .icon-to-light { display: none; }
:root[data-theme="light"] .theme-toggle .icon-to-light { display: block; }
:root[data-theme="light"] .theme-toggle .icon-to-dark  { display: none; }

@media (max-width: 768px) {
    .theme-toggle .theme-toggle-label { display: none; }
    .theme-toggle { padding: 0.42rem; }
}

@media (prefers-reduced-motion: reduce) {
    .theme-toggle { transition: none; }
}

/* The wordmark is a bitmap drawn for one ground; ship both and let the theme
   pick, rather than filtering a PNG. */
.logo-on-light { display: none; }
:root[data-theme="light"] .logo-on-dark  { display: none; }
:root[data-theme="light"] .logo-on-light { display: block; }

.nav-theme-item { display: flex; align-items: center; }

/* ── Season rating scale ────────────────────────────────────────────────────
 * best / good / fair / poor for a month in a region. This is DATA — the four
 * must stay distinguishable from one another, so unlike everything above it
 * does not collapse onto the brand accent; the hues are kept and only the
 * lightness moves for the light ground (the dark values run 1.4-3.2:1 on white).
 *
 * It lives here rather than in travel-planner.css because three surfaces read
 * it now — the homepage planner, the destination page's month strip and the
 * map legend — and one definition is the point of this file.
 * ────────────────────────────────────────────────────────────────────────── */
/* Four hue FAMILIES — green, teal, orange, indigo — not four shades of one.
 *
 * The previous scale was two greens, an amber and a slate, and on the light
 * ground all four sat between 5.5:1 and 7.0:1 against white: nearly the same
 * lightness. The eye sorts by lightness first, so they read as four dark blobs
 * and the pair that mattered most, best against good, was only ΔE 34 apart.
 *
 * Measured on this set: every colour clears 4.5:1 on the card it sits on, and
 * the closest pair is ΔE 47 on light and 59 on dark. Nothing here is left to
 * taste — the numbers are in the commit that introduced them.
 *
 * Indigo for the rainy season and teal for "good" are deliberate: keeping two
 * greens is what made the scale muddy, and no amount of tuning fixes adjacent
 * hues at matched lightness. */
.tp-rating-best { --tp-rating: #5BD97A; }   /* green  */
.tp-rating-good { --tp-rating: #4FD2E8; }   /* teal   */
.tp-rating-fair { --tp-rating: #FF9330; }   /* orange */
.tp-rating-poor { --tp-rating: #A99BF5; }   /* indigo */

:root[data-theme="light"] .tp-rating-best { --tp-rating: #0E6B32; }
:root[data-theme="light"] .tp-rating-good { --tp-rating: #0C6E80; }
:root[data-theme="light"] .tp-rating-fair { --tp-rating: #B4530A; }
:root[data-theme="light"] .tp-rating-poor { --tp-rating: #4B3E93; }
