/* ═══════════════════════════════════════════════════════════════════════
   THEME — every color, font and shape knob for the whole site.

   This is the file to edit to change the site's vibe. Nothing else should
   contain a raw color; the rest of the CSS only ever refers to the tokens
   defined here, and each tool maps its own internal names onto them (see
   e.g. the `--tcprto-*` block in tools/tcp-rto-calculator.css).

   ── How to switch themes ──────────────────────────────────────────────
   The site ships exactly two themes: "default" (light, the :root values
   as-is) and "dusk" (dark). `theme` in src/_data/site.js sets the
   build-time default a visitor with no saved preference gets; the nav
   bar's light/dark toggle (partials/theme-toggle.njk) lets a visitor
   override that, persisted per-browser. Both write the same value to
   <html data-theme="…">, which the [data-theme="dusk"] block below reads.

   To add another theme: copy the [data-theme="dusk"] block, rename it,
   change the values — no component rule needs to change.

   ── Two kinds of token ────────────────────────────────────────────────
   1. THEME tokens (surfaces, text, accent, shape, type) — pure styling.
      Change these freely; they're what makes a theme a theme.
   2. DATA tokens (further down) — colors that carry *meaning* in a
      teaching tool: which bits are network vs host, which TCP variable is
      which, soft vs hard packet loss. Themes may retune these for
      contrast, but don't repurpose them arbitrarily or the diagrams stop
      teaching what they're supposed to teach.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
    /* ── Motion ── */
    --theme-fade-duration: 0.4s;   /* the toggle's light/dark crossfade below */

    /* ── Surfaces ── */
    --surface-page: #e2e8f0;      /* the page behind everything */
    --surface-card: #ffffff;      /* raised cards, panels, tool chrome */
    --surface-chrome: #f8fafc;    /* nav bar + anything that frames the page */
    --surface-sunken: #f4f4f4;    /* inset controls, readonly fields */
    --surface-hover: #c9d0d7;     /* hover wash on chrome elements */

    /* ── Text ── */
    --text-primary: #1a1a18;
    --text-body: #475569;         /* default body/nav text */
    --text-muted: #59677d;        /* secondary copy, captions (>=4.5:1 on light surfaces) */
    --text-subtle: #5f6975;       /* footer, de-emphasized meta (>=4.5:1 on --surface-page) */
    --text-on-accent: #ffffff;

    /* ── Accent ── */
    --accent: #3b82f6;
    --accent-strong: #1d4ed8;
    --accent-title: #2374ff;      /* the site/tool wordmark in the nav */
    --accent-soft: rgba(37, 99, 235, 0.1);   /* tinted active/selected bg */

    /* ── Lines & depth ── */
    --border: #e2e8f0;
    --border-strong: #ccc;
    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1);
    --shadow-md: 0 0 5px rgba(0, 0, 0, 0.3);
    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
    --overlay-scrim: rgba(0, 0, 0, 0.5);   /* dim behind the info modal */
    --shadow-card: rgba(0, 0, 0, 0.16) 0px 1px 4px;  /* inner cards */
    --shadow-card-color: rgba(0, 0, 0, 0.06);        /* used as a color, not a shadow */
    --shadow-pop: 0 2px 12px rgba(0, 0, 0, 0.08);    /* tooltips, popovers */
    --shadow-pressed: 0 0 3px rgba(0, 0, 0, 0.2);    /* :active button press */

    /* ── Shape ── */
    --radius-card: 0.75rem;       /* every card surface, site-wide */
    --radius-control: 0.375rem;   /* buttons, inputs, small chips */

    /* ── Type ── */
    --font-body: "IBM Plex Sans", "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif;
    --font-mono: "IBM Plex Mono", "Source Code Pro", "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace;

    /* ── Banner (site-wide announcement bar) ── */
    --banner-bg-from: #fff4e6;
    --banner-bg-to: #ffe4c4;
    --banner-accent: #f59e0b;
    --banner-border: #f0c88a;
    --banner-text: #78350f;
    --banner-text-hover: #321201;
    --banner-chip-bg: rgba(120, 53, 15, 0.1);  /* inline <code> + dismiss hover */

    /* ═══════════════════════════════════════════════════════════════════
       DATA TOKENS — these carry meaning. See note at the top of the file.
       ═══════════════════════════════════════════════════════════════════ */

    /* CIDR IP: network bits vs host bits, and success/error feedback */
    --data-one: #008080;          /* mask "1" bits — the network portion */
    --data-zero: #0a5aaa;         /* mask "0" bits — the host portion */
    --data-flash-ok: #4d94ff;
    --data-flash-err: #ff6b6b;

    /* SubnetIPv4: the three answer-action colors */
    --data-next: #1E40AF;
    --data-next-hover: #1E3A8A;
    --data-show: #0B7DBB;
    --data-show-hover: #09679A;
    --data-check: #157F61;
    --data-check-hover: #10634b;
    --data-answer-bg: #f5f5f5;
    --data-hint-bg: #e6f8ff;      /* the blue "how to use" box */
    --data-panel-bg: #f9fdff;     /* problem box / small buttons */
    --data-panel-border: #c5e6f3;
    --data-ok: #155724;
    --data-err: #721c24;
    --data-err-bg: #f8d7da;
    --data-err-border: #dc3545;
    /* "Warning" severity — solid bg + text pair, same idea as --data-err
       above but one notch lighter. Used by the TCP visualizer's "Soft loss"
       injection button, which sits between "no event" and the hard-loss
       (--data-err) button. */
    --data-warn: #633806;
    --data-warn-bg: #faeeda;

    /* TCP RTO Calculator: one hue per variable in the formulas */
    --data-rtt: #c8e6fa;          --data-rtt-ink: #1a5a8a;
    --data-srtt: #fef3c7;         --data-srtt-ink: #92660a;
    --data-var: #d1fae5;          --data-var-ink: #136e40;
    --data-rto: #ffe4e6;          --data-rto-ink: #9b1827;
    --data-gap: #ede9fe;          --data-gap-ink: #5b21b6;
    /* washed-out "carried in from the previous step" variants */
    --data-rtt-prev: #e8f5fe;     --data-rtt-prev-ink: #7ab3d4;
    --data-srtt-prev: #fefce8;    --data-srtt-prev-ink: #c9a84c;
    --data-var-prev: #edfaf4;     --data-var-prev-ink: #72c4a0;
    --data-gap-prev: #f5f3ff;     --data-gap-prev-ink: #a89cd6;

    /* TCP congestion visualizer: chart series, loss events, phase bands.
       Read by the chart JS via getComputedStyle, so the graph follows the
       theme rather than hardcoding its own palette. */
    --data-cwnd: #378ADD;
    --data-cwnd-line: #185fa5;
    --data-cwnd-fill: rgba(55, 138, 221, 0.08);
    --data-ssthresh: #7F77DD;
    --data-wmax: #1D9E75;
    --data-netlimit: rgba(120, 120, 110, 0.6);
    --data-loss-soft: #EF9F27;      --data-loss-soft-ink: #854F0B;
    --data-loss-soft-auto: #F5C878; --data-loss-soft-auto-ink: #888780;
    --data-loss-hard: #E24B4A;      --data-loss-hard-ink: #A32D2D;
    --data-phase-ss: rgba(250, 234, 195, 0.35);
    --data-phase-ss-line: rgba(239, 159, 39, 0.3);
    --data-phase-fr: rgba(226, 75, 74, 0.15);
    --data-phase-fr-line: rgba(226, 75, 74, 0.4);
    --data-phase-ca: rgba(195, 232, 214, 0.35);
    --data-phase-ca-line: rgba(29, 158, 117, 0.3);
    --data-phase-ca-ink: #0F6E56;
    --data-grid: rgba(128, 128, 128, 0.1);
    --data-axis: #888780;
    --data-tick: #73726c;
}

/* Crossfade for the light/dark toggle. Every color in the site is already a
   var() pointing at a token above, so re-theming is just the browser
   recomputing those tokens' values on <html data-theme="…"> — this is the
   one rule that makes that recomputation animate instead of snap, and it's
   the only place that has to know about it. No per-component transition
   lines needed: `*` reaches every element, so the instant a color-related
   property's *computed value* changes for any reason — including a theme
   switch — it fades instead of jumping.

   Scoped to color/paint properties only (not `all`): those don't trigger
   layout, so this can't fight with the max-height/height/opacity
   transitions the accordions and delete animation elsewhere in the site
   already use for their own purposes. Where a component declares its own
   `transition` (most interactive hover states do, at a snappier 0.15–0.3s),
   that more specific rule wins for whatever properties it names — this is
   only filling in the elements that don't otherwise animate, which is most
   of the page: backgrounds, card surfaces, borders, body text. */
*, *::before, *::after {
    transition:
        background-color var(--theme-fade-duration) ease,
        color var(--theme-fade-duration) ease,
        border-color var(--theme-fade-duration) ease,
        box-shadow var(--theme-fade-duration) ease,
        fill var(--theme-fade-duration) ease,
        stroke var(--theme-fade-duration) ease;
}

/* ═══════════════════════════════════════════════════════════════════════
   DUSK — dark theme
   ═══════════════════════════════════════════════════════════════════════ */
[data-theme="dusk"] {
    --surface-page: #0f172a;
    --surface-card: #1e293b;
    --surface-chrome: #1a2438;
    --surface-sunken: #273449;
    --surface-hover: #334155;

    --text-primary: #f1f5f9;
    --text-body: #cbd5e1;
    --text-muted: #94a3b8;
    --text-subtle: #77818d;
    --text-on-accent: #0f172a;

    --accent: #60a5fa;
    --accent-strong: #93c5fd;
    --accent-title: #7cb2ff;
    --accent-soft: rgba(96, 165, 250, 0.15);

    --border: #334155;
    --border-strong: #475569;
    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.5);
    --shadow-md: 0 0 5px rgba(0, 0, 0, 0.6);
    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.6);
    --overlay-scrim: rgba(0, 0, 0, 0.7);
    --shadow-card: rgba(0, 0, 0, 0.5) 0px 1px 4px;
    --shadow-card-color: rgba(0, 0, 0, 0.4);
    --shadow-pop: 0 2px 12px rgba(0, 0, 0, 0.5);
    --shadow-pressed: 0 0 3px rgba(0, 0, 0, 0.6);

    --banner-bg-from: #422006;
    --banner-bg-to: #533314;
    --banner-border: #78350f;
    --banner-text: #fde68a;
    --banner-text-hover: #fef3c7;
    --banner-chip-bg: rgba(253, 230, 138, 0.15);

    /* Data colors lightened for contrast against dark surfaces. */
    --data-one: #2dd4bf;
    --data-zero: #60a5fa;
    --data-answer-bg: #273449;
    --data-hint-bg: #172554;
    --data-panel-bg: #1e293b;
    --data-panel-border: #334155;
    --data-next: #60a5fa;   --data-next-hover: #93c5fd;
    --data-show: #38bdf8;   --data-show-hover: #7dd3fc;
    --data-check: #34d399;  --data-check-hover: #6ee7b7;
    --data-ok: #6ee7b7;
    --data-err: #fca5a5;
    --data-err-bg: #450a0a;
    --data-warn: #f2bd55;
    --data-warn-bg: #3d2a0a;

    --data-rtt: #1e3a5f;      --data-rtt-ink: #93c5fd;
    --data-srtt: #422006;     --data-srtt-ink: #fcd34d;
    --data-var: #064e3b;      --data-var-ink: #6ee7b7;
    --data-rto: #4c0519;      --data-rto-ink: #fda4af;
    --data-gap: #2e1065;      --data-gap-ink: #c4b5fd;
    --data-rtt-prev: #1a2a3f;   --data-rtt-prev-ink: #5b7fa6;
    --data-srtt-prev: #2a1a06;  --data-srtt-prev-ink: #a68b3d;
    --data-var-prev: #052e26;   --data-var-prev-ink: #3f8f76;
    --data-gap-prev: #1e0a45;   --data-gap-prev-ink: #7c6bb0;

    --data-grid: rgba(148, 163, 184, 0.12);
    --data-axis: #94a3b8;
    --data-tick: #94a3b8;
    --data-netlimit: rgba(148, 163, 184, 0.6);
    --data-phase-ss: rgba(239, 159, 39, 0.14);
    --data-phase-ca: rgba(29, 158, 117, 0.14);
}
