/* =====================================================================
   theme.css — light/dark theming + responsive chrome for all pages
   Loaded after each page's own styles so light overrides win.
   Canvas artwork stays dark by design; only UI chrome is themed.

   Scope note: the 89 visualizations come in two flavours —
     • "standard" pages expose #panel / #presets  → fully themed in light
     • a handful of bespoke pages (orange black-hole, purple Maxwell, the
       Euler explainer, …) have their own colour identity and embedded
       canvases; light overrides would clash, so they keep their native
       dark chrome. They are excluded via :has(#panel,#presets).
   ===================================================================== */

/* ---------- Design tokens ---------- */
:root,
html[data-theme="dark"]{
  --bg:#03060f;
  --text:#e0eaff;
  --text-dim:#8099bb;
  --card-bg:rgba(8,16,36,0.72);
  --card-border:rgba(255,255,255,0.08);
  --card-desc:#7090aa;
  --footer:#46618c;
  --link:#7ef0ff;
  --shadow:rgba(0,0,0,.5);
  --particle:120,170,255;              /* rgb triplet for background.js */
  --grad-1:#7ef0ff; --grad-2:#a080ff; --grad-3:#ff80c0;
  --accent-ink:#0e1f3a;
  --ctrl-bg:rgba(10,16,30,0.72);
  --ctrl-border:rgba(120,160,230,0.20);
  --ctrl-icon:#9fc0ff;
  /* Unified control-panel chrome (one colour across every visualization). */
  --panel-bg:rgba(11,17,32,0.90);
  --panel-bd:rgba(120,160,230,0.22);
  --panel-fg:#c2d2ef;          /* readable text on the dark panel fill */
  --panel-accent:#6aa6ff;      /* one accent for active states / sliders */
  --panel-accent-bg:rgba(106,166,255,0.16);
}

html[data-theme="light"]{
  --bg:#eaeef6;
  --text:#16243f;
  --text-dim:#51648a;
  --card-bg:rgba(255,255,255,0.82);
  --card-border:rgba(20,45,90,0.14);
  --card-desc:#566d8c;
  --footer:#73869f;
  --link:#0c75c4;
  --shadow:rgba(30,55,100,.18);
  --particle:70,110,180;
  --grad-1:#0891b2; --grad-2:#7c3aed; --grad-3:#db2777;
  --accent-ink:#0e1f3a;
  --ctrl-bg:rgba(255,255,255,0.9);
  --ctrl-border:rgba(20,45,90,0.18);
  --ctrl-icon:#2a4575;
  /* injected banners (cookie + work-in-progress) — light values */
  --wip-bg:rgba(200,120,0,0.10);
  --wip-bd:rgba(200,120,0,0.32);
  --wip-fg:#8a5200;
  --cb-bg:rgba(248,250,253,0.97);
  --cb-bd:rgba(20,45,90,0.14);
  --cb-fg:#46618c;
  --cb-link:#0c75c4;
  --cb-btn-bg:rgba(20,45,90,0.05);
  --cb-btn-bd:rgba(20,45,90,0.18);
  --cb-btn-fg:#2a4575;
  --cb-ok-bg:rgba(12,117,196,0.12);
  --cb-ok-bd:rgba(12,117,196,0.35);
  --cb-ok-fg:#0c5fa8;
}

html{ background:var(--bg); }
body{ transition:background-color .25s ease, color .25s ease; }

/* =====================================================================
   Floating controls (theme toggle + mobile panel toggle) — global
   ===================================================================== */
#mv-controls{ position:fixed; top:7px; right:9px; z-index:1000; display:flex; gap:6px; }
.mv-btn{
  width:34px; height:34px; padding:0;
  display:flex; align-items:center; justify-content:center;
  border-radius:9px;
  background:var(--ctrl-bg);
  border:1px solid var(--ctrl-border);
  color:var(--ctrl-icon);
  cursor:pointer;
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
  transition:color .15s, border-color .15s, background-color .15s, transform .15s;
  -webkit-tap-highlight-color:transparent;
}
.mv-btn:hover{ transform:translateY(-1px); color:var(--link); border-color:var(--link); }
.mv-btn svg{ width:18px; height:18px; display:block; }
.mv-gear{ display:none; }

/* Reserve room in viz navs so the toggle never overlaps nav content, and
   keep the (often very long) trailing equation from running under it. */
html nav{ padding-right:52px; }
html nav .eq{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* =====================================================================
   LIGHT MODE — UI chrome for the STANDARD visualization pages only.
   ===================================================================== */
html[data-theme="light"] body:has(#panel,#presets) nav{
  background:rgba(245,248,252,0.9);
  border-bottom-color:rgba(20,45,90,0.12);
}
html[data-theme="light"] body:has(#panel,#presets) nav a{ color:#54678c; }
html[data-theme="light"] body:has(#panel,#presets) nav a:hover{ color:#0c75c4; }
html[data-theme="light"] body:has(#panel,#presets) nav .cur{ color:#0c5fb0 !important; }
html[data-theme="light"] body:has(#panel,#presets) nav .sep{ color:#c2cee0; }
html[data-theme="light"] body:has(#panel,#presets) nav .eq{ color:#6a7d9e; }

html[data-theme="light"] #presets,
html[data-theme="light"] #panel{
  background:rgba(248,250,253,0.95);
  border-color:rgba(20,45,90,0.16);
}
html[data-theme="light"] body:has(#panel,#presets) .panel-head{ color:#8a99b3; }
html[data-theme="light"] body:has(#panel,#presets) .preset-btn{ color:#3f5780; border-top-color:rgba(20,45,90,0.10); }
html[data-theme="light"] body:has(#panel,#presets) .preset-btn:hover{ background:rgba(40,95,180,0.10); color:#143e78; }
html[data-theme="light"] body:has(#panel,#presets) .preset-btn small{ color:#8a99b3; }

html[data-theme="light"] body:has(#panel,#presets) .slider-lbl{ color:#5a6f93; }
html[data-theme="light"] body:has(#panel,#presets) .slider-lbl em{ color:#214a86; }
html[data-theme="light"] body:has(#panel,#presets) input[type=range]{ background:#d3dce9; }
html[data-theme="light"] body:has(#panel,#presets) input[type=range]::-webkit-slider-thumb{
  background:#2f76dd; box-shadow:0 0 5px rgba(40,110,220,.5);
}
html[data-theme="light"] body:has(#panel,#presets) input[type=range]::-moz-range-thumb{ background:#2f76dd; border:none; }

html[data-theme="light"] body:has(#panel,#presets) .ctrl-btn,
html[data-theme="light"] body:has(#panel,#presets) .btn{ color:#3f5780; border-color:rgba(20,45,90,0.22); }
html[data-theme="light"] body:has(#panel,#presets) .ctrl-btn:hover,
html[data-theme="light"] body:has(#panel,#presets) .btn:hover{ background:rgba(40,95,180,0.10); color:#143e78; }

html[data-theme="light"] body:has(#panel,#presets) .tog{ background:#cfd8e6; border-color:#b3c0d4; }
html[data-theme="light"] body:has(#panel,#presets) .tog::after{ background:#8595b0; }
html[data-theme="light"] body:has(#panel,#presets) .tog.on{ background:#2f76dd; border-color:#2f76dd; }
html[data-theme="light"] body:has(#panel,#presets) .tog.on::after{ background:#fff; box-shadow:none; }

html[data-theme="light"] body:has(#panel,#presets) #infobar{
  background:rgba(245,248,252,0.9);
  border-top-color:rgba(20,45,90,0.12);
  color:#5a6f93;
}
html[data-theme="light"] body:has(#panel,#presets) #infobar span{ color:#1c4e92; }

html[data-theme="light"] body:has(#panel,#presets) #hint{
  background:rgba(248,250,253,0.93);
  border-color:rgba(20,45,90,0.14);
  color:#5a6f93;
}
html[data-theme="light"] body:has(#panel,#presets) #hint b{ color:#2a4575; }
html[data-theme="light"] body:has(#panel,#presets) .pal-btn.active{ border-color:#143e78; }

/* Smooth chrome transitions on theme switch (standard pages) */
body:has(#panel,#presets) nav,
#panel, #presets, #infobar, #hint, .ctrl-btn, .preset-btn, .tog{
  transition:background-color .25s ease, color .25s ease, border-color .25s ease;
}

/* =====================================================================
   LIGHT MODE — privacy / document page (body.doc)
   ===================================================================== */
html[data-theme="light"] .doc{ background:var(--bg); color:#33445f; }
html[data-theme="light"] .doc nav{ background:#e7ecf4; border-bottom-color:#d2dcea; }
html[data-theme="light"] .doc nav a{ color:#5a6f93; }
html[data-theme="light"] .doc nav a:hover,
html[data-theme="light"] .doc nav a.cur{ color:#0c75c4; }
html[data-theme="light"] .doc nav .sep{ color:#cdd8e6; }
html[data-theme="light"] .doc h1{ color:#10203a; }
html[data-theme="light"] .doc .meta{ color:#73869f; }
html[data-theme="light"] .doc h2{ color:#0c5fa8; }
html[data-theme="light"] .doc p,
html[data-theme="light"] .doc ul{ color:#3f5474; }
html[data-theme="light"] .doc a{ color:#0c75c4; }
html[data-theme="light"] .doc code{ color:#0a4a78; background:rgba(12,117,196,0.10); }
html[data-theme="light"] .doc footer{ color:#8a9ab5; border-top-color:#d2dcea; }

/* =====================================================================
   DARK MODE — targeted contrast fix for the worst offenders.
   (Standard pages' hint / info-bar label text was ~1.5:1 contrast.)
   ===================================================================== */
html[data-theme="dark"] body:has(#panel,#presets) #hint{ color:#647ba3; }
html[data-theme="dark"] body:has(#panel,#presets) #hint b{ color:#92acd4; }
html[data-theme="dark"] body:has(#panel,#presets) #infobar{ color:#647ba3; }

/* =====================================================================
   UNIFIED PANELS & INFO BARS — every visualization's control panel,
   info bar and hint box uses one colour. Loaded after each page's own
   styles, so this wins. Only the fill and border colour are forced;
   each page keeps its own size / border sides.
   ===================================================================== */
html #panel,
html #presets,
html #left,
html #right,
html #controls,
html #left-panel,
html #right-panel,
html #info-side,
html .side-panel,
html #infobar,
html #hint,
html #info,
html #formula-bar{
  background-color:var(--panel-bg) !important;
  border-color:var(--panel-bd) !important;
  color:var(--panel-fg) !important;
}

/* All text inside those containers shares one visible colour, replacing
   each page's per-equation accent (orange, green, purple, …). */
html #panel *,
html #presets *,
html #left *,
html #right *,
html #controls *,
html #left-panel *,
html #right-panel *,
html #info-side *,
html .side-panel *,
html #infobar *,
html #hint *,
html #info *,
html #formula-bar *{
  color:var(--panel-fg) !important;
}

/* Interactive controls — replace each page's accent (green / orange / red …)
   with one shared accent so borders, active states and sliders match
   site-wide. Colour-swatch palette buttons (.pal-btn) are left untouched
   so they keep showing their real palette colours. */
html .ctrl-btn,
html .preset-btn,
html .btn,
html .tog,
html #panel button:not(.pal-btn),
html #presets button:not(.pal-btn),
html #left button:not(.pal-btn),
html #right button:not(.pal-btn),
html .side-panel button:not(.pal-btn){
  border-color:var(--panel-bd) !important;
}

html .ctrl-btn:hover,   html .ctrl-btn.active,
html .preset-btn:hover, html .preset-btn.active,
html .btn:hover,        html .btn.active,
html [aria-pressed="true"]:not(.pal-btn){
  border-color:var(--panel-accent) !important;
  background-color:var(--panel-accent-bg) !important;
}
html .tog.on{
  border-color:var(--panel-accent) !important;
  background-color:var(--panel-accent) !important;
}

html input[type=range]{ accent-color:var(--panel-accent) !important; }
html input[type=range]::-webkit-slider-thumb{
  background:var(--panel-accent) !important;
  box-shadow:0 0 6px rgba(106,166,255,.5) !important;
}
html input[type=range]::-moz-range-thumb{
  background:var(--panel-accent) !important;
  border-color:var(--panel-accent) !important;
}

/* =====================================================================
   SINGLE-SIDE LAYOUT — theme.js moves a page's left + right panels (and
   the hint) into this one right-hand scrollable column. Width and bottom
   offset (to clear the info bar) are set inline by the script.
   ===================================================================== */
#mv-stack{
  position:fixed; top:0; right:0; z-index:12;
  display:flex; flex-direction:column; gap:0;
  overflow-y:auto; -webkit-overflow-scrolling:touch; scrollbar-width:thin;
  background:var(--panel-bg);
  border-left:1px solid var(--panel-bd);
}
#mv-stack::-webkit-scrollbar{ width:8px; }
#mv-stack::-webkit-scrollbar-thumb{ background:var(--panel-bd); border-radius:99px; }
/* Children become one continuous panel: the stack supplies the single
   background + left border; each panel is transparent and edge-borderless.
   `html` prefix keeps this ahead of the unified `html #panel{…}` rule. */
html #mv-stack > *{
  position:static !important; inset:auto !important;
  width:100% !important; max-width:100% !important;
  max-height:none !important; box-sizing:border-box !important;
  margin:0 !important; border-radius:0 !important;
  background:transparent !important;
  border-left:0 !important; border-right:0 !important; border-bottom:0 !important;
}

/* =====================================================================
   RESPONSIVE — the site previously had zero media queries.
   Covers standard (#panel/#presets) and bespoke (.side-panel,#left,…) chrome.
   ===================================================================== */
@media (max-width:760px){
  nav{ overflow-x:auto; -webkit-overflow-scrolling:touch; scrollbar-width:none; }
  nav::-webkit-scrollbar{ display:none; }
  nav .eq{ display:none; }

  #panel, #presets, .side-panel, #left, #right, #left-panel, #right-panel{
    max-width:44vw;
    max-height:calc(100vh - 96px);
    overflow-y:auto;
  }
  #mv-stack{ max-width:60vw; }
}

@media (max-width:560px){
  #hint{ display:none; }
  .mv-gear{ display:flex; }
  html.mv-panels-hidden #mv-stack,
  html.mv-panels-hidden #panel,
  html.mv-panels-hidden #presets,
  html.mv-panels-hidden .side-panel,
  html.mv-panels-hidden #left,
  html.mv-panels-hidden #right,
  html.mv-panels-hidden #left-panel,
  html.mv-panels-hidden #right-panel,
  html.mv-panels-hidden #controls{ display:none; }
  #panel, #presets, .side-panel, #left, #right, #left-panel, #right-panel{ font-size:0.92em; }
}
