/* Theme — dark mode, with the elevation model fixed
   ----------------------------------------------------------------------
   Rewritten 2026-10-05.

   The first version simply inverted the palette: --bg went dark, --bg-alt
   went *lighter* than it. That was backwards, and it broke the page's one
   consistent depth cue.

   In light mode the page reads as: white body, slightly grey bands
   (#contact, #horologium, #shannon, the banner, the footer) sitting a
   step BACK, and white cards sitting on those bands a step FORWARD. The
   Shannon board and its stat tiles are white-on-grey; the clock table is
   white rows on a grey band.

   With --bg-alt lighter than --bg in dark mode, every one of those
   relationships flipped: the bands became the bright thing and the cards
   on top of them became darker than their own background, so they read as
   holes punched in the page rather than objects resting on it.

   The rule this file now keeps, in both modes:

       bands are darker than the page; cards are lighter than bands.

   so --bg-alt is always a step DOWN from --bg, light or dark.

   Theme resolution order:
     1. an explicit choice stored by the toggle  -> [data-theme]
     2. otherwise the OS preference              -> prefers-color-scheme
     3. otherwise light                          -> the :root defaults */

:root{
  --shine-tint: rgba(255,255,255,.70);
  --theme-swap: 240ms;
}

/* The dark palette is written twice because CSS has no way to share a
   declaration block between a media query and an attribute selector.
   Keep the two in step. */

@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --bg:#141720;          /* the page, and anything raised onto a band */
    --bg-alt:#0c0e13;      /* bands: a step back, as in light mode */
    --text:#e9ecf2;
    --muted:#9aa3b4;
    --border:#2b3142;
    --accent:#6e8cff;
    --accent-2:#ff6ef0;
    --shine-tint: rgba(180,205,255,.30);
  }
}

:root[data-theme="dark"]{
  --bg:#141720;
  --bg-alt:#0c0e13;
  --text:#e9ecf2;
  --muted:#9aa3b4;
  --border:#2b3142;
  --accent:#6e8cff;
  --accent-2:#ff6ef0;
  --shine-tint: rgba(180,205,255,.30);
}

body{
  transition: background-color var(--theme-swap) ease, color var(--theme-swap) ease;
}

/* ---------- instrument panels ----------
   The shared .panel gradient was tuned against a white page. On a dark
   one its bottom stop (#11131a) lands within three points of the body
   colour, so the panel dissolves into the page. Lift both stops so a
   panel still reads as an object sitting on the page.

   This deliberately does NOT reach #slime or #spacewar: their panels are
   near-black on purpose — a petri dish and a CRT — and an ID selector in
   their own files outranks this anyway. They get a rim instead, below. */

@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .panel{
    --panel-top:#2a3040;
    --panel-bottom:#1c212c;
    --panel-rim:rgba(255,255,255,.10);
  }
}
:root[data-theme="dark"] .panel{
  --panel-top:#2a3040;
  --panel-bottom:#1c212c;
  --panel-rim:rgba(255,255,255,.10);
}

/* The two panels that are meant to be darker than everything get an inner
   hairline so their edges are findable against a dark page. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) #slime .sl-console,
  :root:not([data-theme="light"]) #spacewar .sw-console{
    box-shadow:
      inset 0 0 0 1px rgba(255,255,255,.09),
      0 18px 40px rgba(0,0,0,.5);
  }
}
:root[data-theme="dark"] #slime .sl-console,
:root[data-theme="dark"] #spacewar .sw-console{
  box-shadow:
    inset 0 0 0 1px rgba(255,255,255,.09),
    0 18px 40px rgba(0,0,0,.5);
}

/* ---------- specific repairs ---------- */

/* The hero's letter animation lands on the accent blue, too dark to read
   against a near-black hero. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) #hero .gb .char{ color:#6e8cff; }
}
:root[data-theme="dark"] #hero .gb .char{ color:#6e8cff; }

/* The resume button's hover darkened toward navy, which vanishes here. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .btn{ color:#0f1115; }
  :root:not([data-theme="light"]) .btn:hover,
  :root:not([data-theme="light"]) .btn:focus-visible{ background:#9db3ff; color:#0f1115; }
}
:root[data-theme="dark"] .btn{ color:#0f1115; }
:root[data-theme="dark"] .btn:hover,
:root[data-theme="dark"] .btn:focus-visible{ background:#9db3ff; color:#0f1115; }

/* A drop shadow does nothing on a dark page; the photo needs an edge. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .about-photo img{ box-shadow:0 8px 24px rgba(0,0,0,.55); }
}
:root[data-theme="dark"] .about-photo img{ box-shadow:0 8px 24px rgba(0,0,0,.55); }

/* ---------- the toggle, which lives in the footer ----------
   It was in the top banner, but its label cycles Auto/Light/Dark, so the
   banner reflowed every time it was pressed. The header is meant to be the
   one fixed thing on a page that rebuilds itself daily, so the toggle moved
   to the footer, where the width change costs nothing. */

.theme-toggle{
  vertical-align:middle;
  margin-inline-start:10px;
  font:inherit;
  font-size:var(--fs-sm);
  display:inline-flex;
  align-items:center;
  gap:6px;
  padding:4px 11px;
  border-radius:var(--radius-pill);
  border:1px solid var(--border);
  background:var(--bg);
  color:var(--muted);
  cursor:pointer;
  line-height:1.4;
}

.theme-toggle:hover{ color:var(--text); border-color:var(--muted); }

.theme-toggle svg{
  width:13px; height:13px;
  flex:none;
  stroke:currentColor;
  fill:none;
  stroke-width:1.8;
  stroke-linecap:round;
  stroke-linejoin:round;
}

/* Only one of the two glyphs shows: the one for the mode you'd switch TO. */
.theme-toggle .ico-moon{ display:none; }
.theme-toggle[data-resolved="dark"] .ico-moon{ display:block; }
.theme-toggle[data-resolved="dark"] .ico-sun{ display:none; }

/* Without the script the toggle can do nothing, so it isn't shown. */
.theme-toggle[hidden]{ display:none; }

@media (prefers-reduced-motion: reduce){
  body{ transition:none; }
}
