/* ==========================================================================
   Console channel menu — visual system
   Original homage. No third-party wordmarks or channel artwork.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  color-scheme: light;

  /* Accent derived from the brand mark (#02b3fb sampled from the logo).
     --blue-dk is the text-safe shade: 5.09:1 on white. */
  --brand: #02b3fb;
  --blue: #02b3fb;
  --blue-dk: #0476a4;
  --blue-lt: #7ed7fc;
  --blue-pale: #e7f7fd;

  --ink: #2b3d4a;
  --ink-soft: #61798a;
  --ink-faint: #93a8b6;

  --edge: #b5d6e3;
  --bar: #ffffff;

  --slot-a: #edf1f4;
  --slot-b: #d3dee6;
  --slot-line: #c3d0d9;

  --frame: #ffffff;
  --shadow-1: 0 2px 4px rgba(28, 60, 84, 0.1), 0 6px 14px rgba(28, 60, 84, 0.11);
  --shadow-2: 0 4px 8px rgba(28, 60, 84, 0.14), 0 14px 30px rgba(28, 60, 84, 0.18);
  --shadow-bar: 0 -2px 10px rgba(28, 60, 84, 0.07);

  --font: "M PLUS Rounded 1c", "Nunito", ui-rounded, "Hiragino Maru Gothic ProN",
    "Segoe UI Variable Rounded", "Segoe UI", system-ui, -apple-system, sans-serif;

  --bar-h: 82px;
  --clock-nudge: 8px;   /* the clock sits high in the dome without this */
  --orb-x: clamp(10px, 2.2vw, 30px);   /* orb inset from the bar edge */
  --orb-size: clamp(46px, 7.6vh, 62px);
  --radius-tile: 13px;
  --ease: cubic-bezier(0.22, 0.75, 0.2, 1);

  /* Set at runtime by wii.js — these are only sane pre-paint defaults. */
  --tile-w: 168px;
  --tile-h: 126px;
  --gap: 18px;
  --row-gap: 18px;
  --page-w: 720px;
}

/* --------------------------------------------------------------------------
   2. Tile themes
   Each theme only needs three custom properties. Add your own freely.
   -------------------------------------------------------------------------- */
.theme-blue   { --t1: #2f8fd8; --t2: #0d4f8d; --tt: #fff; }
.theme-sky    { --t1: #35c3fd; --t2: #0288c4; --tt: #fff; }
.theme-green  { --t1: #3aa758; --t2: #146430; --tt: #fff; }
.theme-teal   { --t1: #24b7a0; --t2: #0b6d61; --tt: #fff; }
.theme-orange { --t1: #f7a53a; --t2: #d0640b; --tt: #fff; }
.theme-red    { --t1: #e75c46; --t2: #ad2415; --tt: #fff; }
.theme-pink   { --t1: #f186b4; --t2: #c74d84; --tt: #fff; }
.theme-indigo { --t1: #7477dd; --t2: #383b9c; --tt: #fff; }
.theme-slate  { --t1: #8597a4; --t2: #4a5966; --tt: #fff; }
.theme-paper  { --t1: #ffffff; --t2: #dfe9f1; --tt: #2b3d4a; }
.theme-disc   { --t1: #58646f; --t2: #1d242b; --tt: #fff; }
.theme-sepia  { --t1: #c08f5e; --t2: #6f4622; --tt: #fff; }
.theme-violet { --t1: #ab6ce0; --t2: #6427a6; --tt: #fff; }
.theme-amber  { --t1: #f3c645; --t2: #b07d06; --tt: #fff; }

/* --------------------------------------------------------------------------
   3. Reset / shell
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html, body { height: 100%; margin: 0; padding: 0; }

html {
  overflow: hidden;               /* vertical scroll lock */
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font);
  color: var(--ink);
  background: #eef3f7;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

button { font: inherit; color: inherit; }
img { max-width: 100%; }

/* Focus ring, consistent everywhere */
:focus-visible {
  outline: 3px solid var(--blue);
  outline-offset: 3px;
  border-radius: 6px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------------------
   4. The console frame
   -------------------------------------------------------------------------- */
.wii {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  background:
    radial-gradient(140% 100% at 50% -12%, #ffffff 0%, #f4f8fb 42%, #e4edf4 100%);
}

/* Faint vignette at the very edges, like a CRT-ish softness */
.wii::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background: radial-gradient(120% 85% at 50% 45%, transparent 55%, rgba(40, 78, 105, 0.06) 100%);
}

.stage {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  padding: clamp(10px, 2.2vh, 26px) 0 clamp(6px, 1.4vh, 16px);
}

/* --------------------------------------------------------------------------
   5. Carousel of pages
   -------------------------------------------------------------------------- */
.carousel {
  position: relative;
  flex: 1 1 auto;
  height: 100%;
  overflow: hidden;
  /* Neighbouring pages bleed in at the edges, as on the console. */
}

.strip {
  display: flex;
  align-items: center;
  height: 100%;
  gap: calc(var(--gap) * 2.2);
  will-change: transform;
  transition: transform 460ms var(--ease);
}
.strip.is-instant { transition: none; }

.page {
  flex: 0 0 var(--page-w);
  width: var(--page-w);
  display: grid;
  grid-template-columns: repeat(var(--cols, 4), var(--tile-w));
  grid-auto-rows: var(--tile-h);
  gap: var(--row-gap, var(--gap)) var(--gap);
  justify-content: center;
  align-content: center;
}

/* Inactive pages fade back so the active page reads as focused */
.page[aria-hidden="true"] { opacity: 0.55; }
.page { transition: opacity 320ms var(--ease); }

/* --------------------------------------------------------------------------
   6. Tiles
   -------------------------------------------------------------------------- */
.tile {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  padding: 3px;                       /* the white frame */
  border: 0;
  border-radius: var(--radius-tile);
  background: var(--frame);
  box-shadow: var(--shadow-1);
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: transform 180ms var(--ease), box-shadow 180ms var(--ease);
  -webkit-tap-highlight-color: transparent;
}

.tile__face {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6%;
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: calc(var(--radius-tile) - 4px);
  background: linear-gradient(168deg, var(--t1) 0%, var(--t2) 100%);
  color: var(--tt);
}

/* Optional image behind the label. An <img> rather than a CSS background,
   because the CSP forbids inline style attributes. */
.tile__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;   /* opt out of the global img cap */
  object-fit: cover;
  object-position: center;
}
/* Glossy top sheen */
.tile__face::before {
  content: "";
  position: absolute;
  z-index: 1;
  inset: 0 0 auto;
  height: 52%;
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.34) 0%,
    rgba(255, 255, 255, 0.13) 62%,
    rgba(255, 255, 255, 0) 100%
  );
  pointer-events: none;
}
/* With artwork behind it, the label needs a scrim instead of a top sheen. */
/* Strong enough that white text stays legible over any photograph, including
   a light subject sitting directly behind the label. */
.tile__face--img::before {
  inset: 0;
  height: 100%;
  background:
    linear-gradient(
      180deg,
      rgba(0, 0, 0, 0.10) 0%,
      rgba(0, 0, 0, 0.26) 38%,
      rgba(0, 0, 0, 0.56) 72%,
      rgba(0, 0, 0, 0.72) 100%
    );
}
/* Artwork that already carries its own title: no scrim, no overlay text.
   Set `labelInImage: true` on the tile. The link still gets an aria-label.
   The overlay text stays in the DOM and comes back if the image 404s, so a
   missing file never leaves a blank tile. */
.tile__face--art:not(.is-broken) .tile__icon,
.tile__face--art:not(.is-broken) .tile__label,
.tile__face--art:not(.is-broken) .tile__sub { display: none; }
.tile__face--art.is-broken::before { height: 100%; }
.tile__face--art::before {
  inset: 0 0 auto;
  height: 46%;
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.16) 0%,
    rgba(255, 255, 255, 0.05) 60%,
    rgba(255, 255, 255, 0) 100%
  );
}
.tile__face--img .tile__icon { width: 21%; opacity: 0.92; }
.tile__face--img .tile__label,
.tile__face--img .tile__sub {
  color: #fff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.75), 0 0 14px rgba(0, 0, 0, 0.45);
}

/* Inner hairline so the face sits inside the frame crisply */
.tile__face::after {
  content: "";
  position: absolute;
  z-index: 3;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.13);
  pointer-events: none;
}

/* Above the artwork and the scrim. Without this the positioned <img>
   paints over the label. */
.tile__icon,
.tile__label,
.tile__sub,
.tile__mono { position: relative; z-index: 2; }

.tile__icon {
  display: grid;
  place-items: center;
  width: 30%;
  max-width: 54px;
  aspect-ratio: 1;
  opacity: 0.95;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.22));
}
.tile__icon .glyph { width: 100%; height: 100%; }

.tile__label {
  max-width: 88%;
  font-size: clamp(11px, calc(var(--tile-w) * 0.105), 17px);
  font-weight: 800;
  line-height: 1.15;
  text-align: center;
  letter-spacing: 0.005em;
  text-wrap: balance;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.24);
}
.theme-paper .tile__label { text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8); }

.tile__sub {
  font-size: clamp(9px, calc(var(--tile-w) * 0.072), 12px);
  font-weight: 500;
  opacity: 0.82;
  text-align: center;
}

/* Hover / active */
@media (hover: hover) {
  .tile:hover {
    transform: translateY(-3px) scale(1.045);
    box-shadow: var(--shadow-2);
    z-index: 2;
  }
}
.tile:active { transform: translateY(-1px) scale(1.015); }

/* Outbound-link tiles get a small corner marker */
.tile[data-external] .tile__face::after {
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.13);
}
.tile__ext {
  position: absolute;
  top: 6%;
  right: 6%;
  width: 13%;
  max-width: 16px;
  opacity: 0.72;
}

/* Empty slot */
.tile--empty {
  cursor: default;
  box-shadow: 0 1px 2px rgba(28, 60, 84, 0.07);
  background: #f7fafc;
}
.tile--empty .tile__face {
  background: linear-gradient(168deg, var(--slot-a) 0%, var(--slot-b) 100%);
  color: var(--slot-line);
}
.tile--empty .tile__face::before { opacity: 0.5; }
.tile--empty .tile__face::after { box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.06); }
.tile--empty .tile__mono {
  font-size: clamp(11px, calc(var(--tile-w) * 0.125), 22px);
  font-weight: 800;
  letter-spacing: 0.14em;
  color: #ffffff;
  opacity: 0.62;
  user-select: none;
}

/* --------------------------------------------------------------------------
   7. Pager arrows + dots
   -------------------------------------------------------------------------- */
.pager {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  z-index: 6;
  display: grid;
  place-items: center;
  width: clamp(30px, 3.4vw, 44px);
  height: clamp(52px, 9vh, 82px);
  padding: 0;
  border: 0;
  background: none;
  color: var(--blue);
  cursor: pointer;
  transition: opacity 200ms var(--ease), transform 160ms var(--ease), color 160ms;
  filter: drop-shadow(0 1px 2px rgba(20, 80, 115, 0.28));
}
.pager svg { width: 100%; height: 100%; }
.pager--prev { left: clamp(2px, 0.8vw, 12px); }
.pager--next { right: clamp(2px, 0.8vw, 12px); }
.pager:hover { color: #3fc6fd; transform: scale(1.08); }
.pager:active { transform: scale(0.96); }
.pager[disabled] { opacity: 0; pointer-events: none; }

.dots {
  position: absolute;
  left: 50%;
  bottom: 2px;
  translate: -50% 0;
  z-index: 6;
  display: flex;
  gap: 7px;
}
.dots:empty { display: none; }
.dot {
  width: 7px; height: 7px; padding: 0;
  border: 0; border-radius: 50%;
  background: #c2d3de;
  cursor: pointer;
  transition: background 180ms, transform 180ms var(--ease);
}
.dot[aria-current="true"] { background: var(--blue); transform: scale(1.3); }

/* --------------------------------------------------------------------------
   8. Bottom bar
   -------------------------------------------------------------------------- */
.bar {
  position: relative;
  flex: 0 0 var(--bar-h);
  height: var(--bar-h);
  z-index: 8;
}

.bar__edge {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  filter: drop-shadow(0 -2px 6px rgba(28, 60, 84, 0.08));
}
.bar__fill { fill: var(--bar); }
.bar__line { fill: none; stroke: var(--edge); stroke-width: 2; }

/* Everything inside sits above the SVG */
.bar__inner {
  position: relative;
  height: 100%;
  display: flex;
  align-items: center;
}

/* Two rows split exactly on the bar's flat edge (52% of bar height):
   the clock rides inside the dome, the date sits in the bar below it. */
.bar__center {
  position: absolute;
  left: 50%;
  top: 0;
  translate: -50% 0;
  height: 100%;
  display: grid;
  grid-template-rows: 52% 48%;
  place-items: center;
  pointer-events: none;
  text-align: center;
  line-height: 1;
  white-space: nowrap;
}

/* Seven-segment clock, drawn rather than set in a typeface: unlit segments
   stay faintly visible behind the lit ones, the way a real LCD looks. */
.clock {
  position: relative;
  top: var(--clock-nudge);
  --seg-h: clamp(21px, 3.3vh, 31px);
  --seg-on: #66808f;
  --seg-off: rgba(102, 128, 143, 0.11);
  display: flex;
  align-items: center;
  gap: 0.16em;
  height: var(--seg-h);
  font-size: var(--seg-h);
}
.clock svg { height: 100%; width: auto; display: block; }
.clock .seg-off { fill: var(--seg-off); }
.clock .seg-on { fill: var(--seg-on); }
.clock .colon circle { fill: var(--seg-on); }
.clock .colon { animation: blink 2s steps(1, end) infinite; }
svg.clock__digit[hidden] { display: none; }
@keyframes blink { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0.28; } }

.date {
  font-size: clamp(13px, 2vh, 18px);
  font-weight: 700;
  line-height: 1.1;
  color: var(--ink);
}

/* Round buttons that straddle the bar edge */
.orb {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  display: grid;
  place-items: center;
  width: var(--orb-size);
  aspect-ratio: 1;
  padding: 0;
  border: 2px solid var(--edge);
  border-radius: 50%;
  background: linear-gradient(180deg, #ffffff 0%, #f2f7fa 58%, #e6eff5 100%);
  color: var(--blue-dk);
  box-shadow: 0 2px 5px rgba(28, 60, 84, 0.14), inset 0 1px 0 #fff;
  cursor: pointer;
  transition: transform 150ms var(--ease), box-shadow 150ms, color 150ms, border-color 150ms;
}
/* Centring is done by the `translate` property above. `transform` COMPOSES
   with it, so hover/active must set scale only: repeating the offset here
   shifts the element by half its own size. */
.orb:hover {
  transform: scale(1.07);
  border-color: var(--blue-lt);
  color: var(--blue);
  box-shadow: 0 4px 10px rgba(28, 60, 84, 0.2), inset 0 1px 0 #fff;
}
.orb:active { transform: scale(0.97); }
.orb--left { left: var(--orb-x); }
.orb--right { right: var(--orb-x); }
.orb .glyph { width: 46%; height: 46%; }
.orb__mono {
  font-size: clamp(13px, 1.9vh, 17px);
  font-weight: 800;
  letter-spacing: 0.03em;
  color: var(--blue-dk);
}

/* Small flat buttons beside the left orb (card slot, audio) */
.chip {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  display: grid;
  place-items: center;
  width: clamp(28px, 4.4vh, 36px);
  aspect-ratio: 1;
  padding: 0;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: #8fb3c7;
  cursor: pointer;
  transition: color 150ms, transform 150ms var(--ease), background 150ms;
}
/* A class that sets `display` outranks the UA sheet's [hidden] rule, so any
   element hidden via the attribute needs this said explicitly. */
.chip[hidden] { display: none; }
.chip:hover { color: var(--blue); background: var(--blue-pale); transform: scale(1.08); }
.chip .glyph { width: 76%; height: 76%; }
/* Sit clear of the orbs rather than guessing at a fixed offset. */
.chip--card { left: calc(var(--orb-x) + var(--orb-size) + 10px); }
.chip--audio { right: calc(var(--orb-x) + var(--orb-size) + 10px); }
.chip[aria-pressed="true"] { color: var(--blue); }
.chip--audio .glyph { opacity: 0.45; }
.chip--audio[aria-pressed="true"] .glyph { opacity: 1; }

/* --------------------------------------------------------------------------
   9. Channel view (used by the overlay and by standalone pages)
   -------------------------------------------------------------------------- */
.overlay {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  background: radial-gradient(140% 100% at 50% -12%, #ffffff 0%, #f3f8fb 45%, #e2ebf3 100%);
}
.overlay[hidden] { display: none; }
.overlay__backdrop {
  position: absolute; inset: 0;
  background: inherit;
  opacity: 0;
  transition: opacity 300ms var(--ease);
}
.overlay.is-open .overlay__backdrop { opacity: 1; }

.overlay__stage {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  padding: clamp(8px, 2vh, 22px) clamp(8px, 2.4vw, 30px) 0;
}

.channel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(1040px, 100%);
  margin: 0 auto;
  min-height: 0;
  border-radius: 18px;
  background: #fff;
  box-shadow: var(--shadow-2);
  overflow: hidden;
  transform-origin: top left;
}

/* Flight wash: a solid theme-coloured sheet that fills the card while it
   zooms out of its tile, so no text distorts mid-animation. */
.channel__wash {
  position: absolute;
  inset: 0;
  z-index: 5;
  background: linear-gradient(168deg, var(--t1, #2f8fd8) 0%, var(--t2, #0d4f8d) 100%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 240ms var(--ease);
}
.channel.is-flying .channel__wash { opacity: 1; }
.channel.is-flying > :not(.channel__wash) { opacity: 0; }
.channel > :not(.channel__wash) { transition: opacity 260ms var(--ease) 60ms; }

.channel__ico { display: grid; place-items: center; flex: 0 0 auto; }

body.is-channel-open { overflow: hidden; }

/* Standalone page variant scrolls the whole card region */
.channel__head {
  position: relative;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: clamp(10px, 1.6vw, 18px);
  padding: clamp(14px, 2.4vh, 24px) clamp(16px, 3vw, 34px);
  background: linear-gradient(168deg, var(--t1) 0%, var(--t2) 100%);
  color: var(--tt);
  overflow: hidden;
}
.channel__head::before {
  content: "";
  position: absolute; inset: 0 0 auto; height: 60%;
  background: linear-gradient(180deg, rgba(255,255,255,.28), rgba(255,255,255,0));
  pointer-events: none;
}
.channel__head .glyph { width: clamp(26px, 3.6vh, 40px); height: clamp(26px, 3.6vh, 40px); }
.channel__titles { position: relative; }
.channel__head :is(h1, h2) {
  margin: 0;
  font-size: clamp(19px, 3.4vh, 30px);
  font-weight: 800;
  line-height: 1.1;
  text-shadow: 0 1px 2px rgba(0,0,0,.2);
}
.channel__head p {
  margin: 3px 0 0;
  font-size: clamp(12px, 1.8vh, 15px);
  font-weight: 500;
  opacity: 0.9;
}

.channel__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: clamp(18px, 3.2vh, 34px) clamp(18px, 3.4vw, 44px) clamp(26px, 4vh, 44px);
  scrollbar-width: thin;
  scrollbar-color: #c6d8e4 transparent;
}
.channel__body::-webkit-scrollbar { width: 10px; }
.channel__body::-webkit-scrollbar-thumb {
  background: #c6d8e4; border-radius: 99px; border: 3px solid #fff;
}

/* Fade hint that there is more to scroll */
.channel::after {
  content: "";
  position: absolute;
  left: 0; right: 10px; bottom: 0;
  height: 26px;
  background: linear-gradient(rgba(255,255,255,0), #fff);
  pointer-events: none;
  opacity: 1;
  transition: opacity 200ms;
}
.channel.is-bottom::after { opacity: 0; }

/* --------------------------------------------------------------------------
   10. Prose inside a channel
   -------------------------------------------------------------------------- */
.prose { font-size: clamp(14.5px, 1.05rem, 17px); line-height: 1.65; color: #35485a; }
/* Text stays a comfortable measure; grids and tables get the full width. */
.prose > :is(p, ul, ol, blockquote, .lede, .timeline, .form, h2, h3, h4) { max-width: 68ch; }
.prose > :is(.cards, .links, .gallery, table) { max-width: none; }
.prose > .dc__list { max-width: none; padding-left: 0; }
.prose > :first-child { margin-top: 0; }
.prose > :last-child { margin-bottom: 0; }
.prose h2 {
  margin: 1.7em 0 0.5em;
  font-size: 1.28em;
  font-weight: 800;
  color: var(--ink);
  letter-spacing: -0.005em;
}
.prose h3 { margin: 1.4em 0 0.4em; font-size: 1.08em; font-weight: 800; color: var(--ink); }
.prose p, .prose ul, .prose ol { margin: 0 0 1em; }
.prose ul, .prose ol { padding-left: 1.25em; }
.prose li { margin: 0.3em 0; }
.prose li::marker { color: var(--blue); }
.prose a { color: var(--blue-dk); text-decoration-thickness: 2px; text-underline-offset: 3px; }
.prose a:hover { color: var(--blue); }
.prose strong { font-weight: 800; color: var(--ink); }
.prose hr { margin: 1.8em 0; border: 0; border-top: 2px dashed #dbe6ee; }
.prose blockquote {
  margin: 1.2em 0;
  padding: 0.7em 1.1em;
  border-left: 4px solid var(--blue-lt);
  background: var(--blue-pale);
  border-radius: 0 10px 10px 0;
  color: #33566b;
}
.prose code {
  padding: 0.12em 0.4em;
  border-radius: 5px;
  background: #eef3f7;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.9em;
}
.prose table { width: 100%; border-collapse: collapse; margin: 0 0 1.2em; font-size: 0.95em; }
.prose th, .prose td { padding: 0.55em 0.7em; border-bottom: 1px solid #e3ecf2; text-align: left; }
.prose th { font-weight: 800; color: var(--ink); }

/* Wide content never breaks the layout */
.prose :is(table, pre) { display: block; max-width: 100%; overflow-x: auto; }

.lede {
  font-size: clamp(15.5px, 1.16rem, 19px);
  font-weight: 500;
  color: var(--ink);
  line-height: 1.55;
}

/* --------------------------------------------------------------------------
   11. Reusable blocks for channel content
   -------------------------------------------------------------------------- */
/* Card grid — projects, work history, homelab entries */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
  gap: 14px;
  margin: 0 0 1.4em;
  padding: 0;
  list-style: none;
}
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 15px 16px 16px;
  border: 2px solid #e4edf3;
  border-radius: 14px;
  background: #fbfdfe;
  text-decoration: none;
  color: inherit;
  transition: transform 160ms var(--ease), border-color 160ms, box-shadow 160ms;
}
a.card:hover { transform: translateY(-2px); border-color: var(--blue-lt); box-shadow: var(--shadow-1); }
.card__thumb {
  display: block;
  width: calc(100% + 32px);
  max-width: none;   /* opt out of the global img cap so it can bleed */
  /* height:auto is required: the width/height HTML attributes (kept so the
     browser reserves space and avoids layout shift) otherwise win over
     aspect-ratio and the image renders at its natural height. */
  height: auto;
  margin: -15px -16px 11px;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  object-position: center;
  border-radius: 11px 11px 0 0;
  background: linear-gradient(168deg, var(--slot-a), var(--slot-b));
}

.card__tag {
  align-self: flex-start;
  padding: 2px 9px;
  border-radius: 99px;
  background: var(--blue-pale);
  color: var(--blue-dk);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.card h3 { margin: 0; font-size: 1.02rem; font-weight: 800; color: var(--ink); }
.card p { margin: 0; font-size: 0.92rem; line-height: 1.5; color: var(--ink-soft); }
.card--empty {
  align-items: center;
  justify-content: center;
  min-height: 104px;
  border-style: dashed;
  border-color: #dae5ec;
  background: #f7fafc;
  color: var(--ink-faint);
  font-weight: 700;
  font-size: 0.9rem;
}

/* Link buttons — social channel */
.links { display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); gap: 12px; padding: 0; margin: 0 0 1.4em; list-style: none; }
.linkbtn {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 12px 15px;
  border-radius: 13px;
  background: linear-gradient(168deg, var(--t1) 0%, var(--t2) 100%);
  color: var(--tt);
  text-decoration: none;
  font-weight: 800;
  box-shadow: var(--shadow-1);
  transition: transform 160ms var(--ease), box-shadow 160ms;
}
.linkbtn:hover { transform: translateY(-2px) scale(1.02); box-shadow: var(--shadow-2); }
.linkbtn .glyph { width: 22px; height: 22px; flex: 0 0 auto; }
.linkbtn span { flex: 1 1 auto; }
.linkbtn small { font-size: 11px; font-weight: 600; opacity: 0.8; }

/* Timeline — resume / work */
.timeline { list-style: none; margin: 0 0 1.4em; padding: 0 0 0 22px; border-left: 3px solid #e0eaf1; }
.timeline li { position: relative; margin: 0 0 1.3em; }
.timeline li::before {
  content: "";
  position: absolute;
  left: -30px; top: 5px;
  width: 13px; height: 13px;
  border: 3px solid #fff;
  border-radius: 50%;
  background: var(--blue);
  box-shadow: 0 0 0 2px #e0eaf1;
}
.timeline h3 { margin: 0; font-size: 1.02rem; font-weight: 800; }
.timeline .when { font-size: 0.84rem; font-weight: 700; color: var(--blue-dk); letter-spacing: 0.01em; }
.timeline p { margin: 0.35em 0 0; font-size: 0.94rem; line-height: 1.55; color: var(--ink-soft); }

/* Gallery */
.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 12px; padding: 0; margin: 0 0 1.2em; list-style: none; }
.shot {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  padding: 0;
  border: 3px solid #fff;
  border-radius: 12px;
  background: #eaf0f5;
  box-shadow: var(--shadow-1);
  overflow: hidden;
  cursor: pointer;
  transition: transform 160ms var(--ease), box-shadow 160ms;
}
.shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.shot:hover { transform: translateY(-3px) scale(1.02); box-shadow: var(--shadow-2); }
.shot--empty {
  display: grid; place-items: center;
  cursor: default;
  background: linear-gradient(168deg, var(--slot-a), var(--slot-b));
  color: #fff;
  box-shadow: 0 1px 2px rgba(28,60,84,.07);
}
.shot--empty .glyph { width: 30%; height: 30%; opacity: 0.75; }
.shot--empty:hover { transform: none; box-shadow: 0 1px 2px rgba(28,60,84,.07); }

/* Lightbox */
.lightbox {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center;
  padding: 4vmin;
  background: rgba(22, 44, 60, 0.86);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity 200ms var(--ease);
}
.lightbox[hidden] { display: none; }
.lightbox.is-open { opacity: 1; }
.lightbox__fig { margin: 0; display: grid; place-items: center; }
.lightbox img { max-width: 100%; max-height: 82vh; border-radius: 10px; border: 4px solid #fff; box-shadow: 0 20px 50px rgba(0,0,0,.4); }
.lightbox figcaption { margin-top: 12px; color: #eaf4fa; font-weight: 600; text-align: center; }
.lightbox__close {
  position: absolute; top: 3vmin; right: 3vmin;
  width: 46px; aspect-ratio: 1;
  border: 2px solid rgba(255,255,255,.55);
  border-radius: 50%;
  background: rgba(255,255,255,.14);
  color: #fff;
  cursor: pointer;
  display: grid; place-items: center;
}
.lightbox__close:hover { background: rgba(255,255,255,.28); }


/* --------------------------------------------------------------------------
   11b. Forecast Channel
   Layout borrowed from the console weather readout: a label pill and the
   location on one bar, a large temperature, and wind plus a timestamp along
   the bottom. All artwork and colour is original.
   -------------------------------------------------------------------------- */
.glyph-sprite { display: none; }

/* Paragraph rules below are written as `.fc .fc__x` (0,2,0) so they beat
   `.prose p` (0,1,1), which would otherwise add a 1em margin under the
   temperature. Do not flatten them to a single class. */
.fc { max-width: 620px; margin: 0 0 1.4em; }

.fc__card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 196px;
  padding: 0;
  border-radius: 16px;
  overflow: hidden;
  color: #fff;
  background: linear-gradient(170deg, var(--sky-a) 0%, var(--sky-b) 100%);
  box-shadow: var(--shadow-1);
  transition: background 500ms var(--ease);
}

/* Sky palettes. Chosen so white text clears 4.5:1 on the lighter end. */
.fc__card { --sky-a: #2f86c4; --sky-b: #6fb4dd; }
.fc__card[data-sky="clear"]        { --sky-a: #1f7fc0; --sky-b: #63aedd; }
.fc__card[data-sky="clear-night"]  { --sky-a: #131f3d; --sky-b: #33477a; }
.fc__card[data-sky="partly"]       { --sky-a: #3183b8; --sky-b: #7aa9c6; }
.fc__card[data-sky="partly-night"] { --sky-a: #1a2440; --sky-b: #3c4c72; }
.fc__card[data-sky="cloud"]        { --sky-a: #566f83; --sky-b: #8ba3b4; }
.fc__card[data-sky="cloud-night"]  { --sky-a: #212c3c; --sky-b: #45566a; }
.fc__card[data-sky="rain"]         { --sky-a: #3d5a70; --sky-b: #6d8698; }
.fc__card[data-sky="rain-night"]   { --sky-a: #1b2836; --sky-b: #3b4d5e; }
.fc__card[data-sky="storm"]        { --sky-a: #2f3947; --sky-b: #5b6879; }
.fc__card[data-sky="storm-night"]  { --sky-a: #1a1f28; --sky-b: #39434f; }
.fc__card[data-sky="snow"]         { --sky-a: #5b7893; --sky-b: #93aec4; }
.fc__card[data-sky="snow-night"]   { --sky-a: #232f3f; --sky-b: #46586d; }
.fc__card[data-sky="fog"]          { --sky-a: #5d6d77; --sky-b: #93a3ac; }
.fc__card[data-sky="fog-night"]    { --sky-a: #232a30; --sky-b: #47535c; }

/* A soft light source in the top corner, so the panel is not a flat wash. */
.fc__card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(80% 70% at 78% -12%, rgba(255, 255, 255, 0.3), transparent 62%);
  pointer-events: none;
}

.fc__top {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 14px 0;
}

.fc__pill {
  padding: 5px 16px;
  border-radius: 99px;
  background: linear-gradient(180deg, #57c26a 0%, #2f8f45 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45), 0 1px 3px rgba(0, 0, 0, 0.22);
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.fc__place {
  font-size: clamp(0.95rem, 2.4vw, 1.15rem);
  font-weight: 800;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}

.fc__body {
  position: relative;
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 10px 18px 8px;
}

.fc__readout { min-width: 0; }

.fc .fc__temp {
  margin: 0;
  font-size: clamp(3.2rem, 11vw, 4.6rem);
  font-weight: 800;
  line-height: 1;
  color: #ffd83d;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  font-variant-numeric: tabular-nums;
}
.fc__deg { font-weight: 500; }

.fc .fc__cond {
  margin: 8px 0 0;
  max-width: 22ch;
  font-size: clamp(1rem, 3vw, 1.3rem);
  font-weight: 800;
  line-height: 1.25;
  text-wrap: balance;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}

.fc__art {
  flex: 0 0 auto;
  width: clamp(78px, 20vw, 118px);
  aspect-ratio: 1;
  opacity: 0.95;
  filter: drop-shadow(0 3px 8px rgba(0, 0, 0, 0.28));
}
.fc__art svg { width: 100%; height: 100%; stroke-width: 1.35; }

.fc__foot {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 16px 12px;
  font-size: 0.84rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.92);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
.fc__wind { display: inline-flex; align-items: center; gap: 7px; font-weight: 800; }
.fc__wind svg { width: 17px; height: 17px; }
.fc__wind[hidden] { display: none; }

/* Loading: dim the readout and breathe, rather than showing a spinner. */
.fc__card--loading .fc__temp,
.fc__card--loading .fc__cond,
.fc__card--loading .fc__art { opacity: 0.45; animation: fcpulse 1.5s ease-in-out infinite; }
@keyframes fcpulse { 50% { opacity: 0.72; } }

/* ---- five-day strip ------------------------------------------------------ */
.fc__days {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
}
.fc__days:empty { display: none; }

.fc__day {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 100%;
  padding: 10px 4px 9px;
  border: 2px solid #e4edf3;
  border-radius: 12px;
  background: #fbfdfe;
  color: var(--ink);
  cursor: pointer;
  transition: transform 150ms var(--ease), border-color 150ms, box-shadow 150ms, background 150ms;
}
.fc__day:hover { transform: translateY(-2px); border-color: var(--blue-lt); box-shadow: var(--shadow-1); }
.fc__day[aria-current="true"] {
  border-color: var(--blue);
  background: var(--blue-pale);
  box-shadow: var(--shadow-1);
}
.fc__dow { font-size: 0.78rem; font-weight: 800; letter-spacing: 0.03em; color: var(--ink-soft); }
.fc__day[aria-current="true"] .fc__dow { color: var(--blue-dk); }
.fc__dayart { width: 30px; height: 30px; color: var(--blue-dk); }
.fc__dayart svg { width: 100%; height: 100%; }
.fc__range { font-size: 0.8rem; font-weight: 600; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.fc__range b { font-weight: 800; color: var(--ink); }

/* ---- controls ------------------------------------------------------------ */
.fc__actions { display: flex; flex-wrap: wrap; gap: 9px; margin: 13px 0 0; }
.btn--sm { padding: 8px 16px; font-size: 0.88rem; }
.btn--sm svg { width: 16px; height: 16px; }
.fc__actions .btn[hidden] { display: none; }

.fc .fc__credit { margin: 11px 0 0; font-size: 0.78rem; color: var(--ink-faint); }
.fc__credit a { color: var(--ink-soft); }

/* A caption blurb under a gallery, as on the console channel screens.
   Not named .strip: that class is already the carousel track. */
.blurb {
  margin: 2px 0 1.4em;
  padding: 11px 15px;
  border-radius: 11px;
  background: #f2f6f9;
  border: 2px solid #e4edf3;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

@media (max-width: 560px) {
  .fc__days { grid-template-columns: repeat(5, 1fr); gap: 5px; }
  .fc__day { padding: 8px 2px; }
  .fc__dayart { width: 24px; height: 24px; }
  .fc__range { font-size: 0.72rem; }
  .fc__dow { font-size: 0.7rem; }
}


/* --------------------------------------------------------------------------
   11c. Disc Channel
   The site's music player. The audio element lives in wii.js so playback
   survives channel navigation; this is only the view onto it.
   -------------------------------------------------------------------------- */
.dc { max-width: 640px; margin: 0 0 1.4em; }
.dc .dc__eyebrow,
.dc .dc__title,
.dc .dc__artist { margin: 0; max-width: none; }

.dc__deck {
  display: flex;
  align-items: center;
  gap: clamp(16px, 4vw, 28px);
  padding: clamp(16px, 3vw, 22px);
  border-radius: 16px;
  background: linear-gradient(168deg, #46525d 0%, #1a2027 100%);
  box-shadow: var(--shadow-1);
  color: #fff;
}

/* ---- the disc ------------------------------------------------------------ */
.dc__disc {
  flex: 0 0 auto;
  width: clamp(92px, 26vw, 138px);
  aspect-ratio: 1;
  filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.45));
  animation: dcspin 3.4s linear infinite;
  animation-play-state: paused;
}
.dc__disc.is-spinning { animation-play-state: running; }
.dc__disc svg { width: 100%; height: 100%; display: block; }
@keyframes dcspin { to { transform: rotate(360deg); } }

/* ---- readout ------------------------------------------------------------- */
.dc__meta { flex: 1 1 auto; min-width: 0; }

.dc .dc__eyebrow {
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--blue-lt);
}
.dc .dc__title {
  margin-top: 3px;
  font-size: clamp(1.05rem, 3.4vw, 1.35rem);
  font-weight: 800;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dc .dc__artist {
  font-size: 0.9rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.66);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-height: 1.2em;
}

/* ---- seek + volume sliders ------------------------------------------------ */
.dc__seek { margin: 12px 0 4px; }
.dc__times {
  display: flex;
  justify-content: space-between;
  margin-top: 3px;
  font-size: 0.74rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.6);
  font-variant-numeric: tabular-nums;
}

.dc__range {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 6px;
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.22);
  cursor: pointer;
}
.dc__range:disabled { cursor: default; opacity: 0.45; }
.dc__range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 15px; height: 15px;
  border-radius: 50%;
  background: #fff;
  border: 0;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
  cursor: pointer;
}
.dc__range::-moz-range-thumb {
  width: 15px; height: 15px;
  border-radius: 50%;
  background: #fff;
  border: 0;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
  cursor: pointer;
}
.dc__range:focus-visible { outline: 3px solid var(--blue-lt); outline-offset: 3px; }

/* ---- transport ----------------------------------------------------------- */
.dc__transport {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
}

.dc__btn {
  display: grid;
  place-items: center;
  width: 40px;
  aspect-ratio: 1;
  padding: 0;
  border: 2px solid rgba(255, 255, 255, 0.24);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
  cursor: pointer;
  transition: transform 140ms var(--ease), background 140ms, border-color 140ms;
}
.dc__btn svg { width: 17px; height: 17px; }
.dc__btn:hover:not(:disabled) { background: rgba(255, 255, 255, 0.2); border-color: rgba(255, 255, 255, 0.5); transform: scale(1.07); }
.dc__btn:active:not(:disabled) { transform: scale(0.95); }
.dc__btn:disabled { opacity: 0.35; cursor: default; }
.dc__btn--play {
  width: 52px;
  background: linear-gradient(180deg, #3fc6fd 0%, var(--blue) 50%, #0289c4 100%);
  border-color: rgba(255, 255, 255, 0.5);
}
.dc__btn--play svg { width: 21px; height: 21px; }
.dc__btn--play:hover:not(:disabled) { background: linear-gradient(180deg, #5fd2fe 0%, #16bcfd 50%, #0396d6 100%); }
.dc__btn--sm { width: 32px; border-width: 0; background: none; }
.dc__btn--sm svg { width: 18px; height: 18px; }

.dc__vol { display: flex; align-items: center; gap: 4px; margin-left: auto; min-width: 0; }
.dc__range--vol { width: clamp(52px, 16vw, 92px); height: 5px; }

/* ---- track list ---------------------------------------------------------- */
.dc__list { margin: 12px 0 0; padding: 0; list-style: none; display: grid; gap: 5px; }
.dc__list:empty { display: none; }

.dc__track {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 9px 13px;
  border: 2px solid #e4edf3;
  border-radius: 11px;
  background: #fbfdfe;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  transition: border-color 150ms, background 150ms, transform 150ms var(--ease);
}
.dc__track:hover { border-color: var(--blue-lt); transform: translateX(2px); }
.dc__track[aria-current="true"] { border-color: var(--blue); background: var(--blue-pale); }

.dc__num {
  flex: 0 0 auto;
  width: 20px;
  font-size: 0.8rem;
  font-weight: 800;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.dc__track[aria-current="true"] .dc__num { color: var(--blue-dk); }

.dc__names { flex: 1 1 auto; min-width: 0; }
.dc__tname {
  display: block;
  font-weight: 800;
  font-size: 0.95rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dc__tartist {
  display: block;
  font-size: 0.82rem;
  color: var(--ink-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Three bars that bounce only on the track actually playing. */
.dc__bars { display: flex; align-items: flex-end; gap: 2px; height: 15px; opacity: 0; }
.dc__track.is-playing .dc__bars { opacity: 1; }
.dc__bars i {
  display: block;
  width: 3px;
  border-radius: 2px;
  background: var(--blue);
  height: 5px;
}
.dc__track.is-playing .dc__bars i { animation: dcbar 900ms ease-in-out infinite; }
.dc__track.is-playing .dc__bars i:nth-child(2) { animation-delay: 160ms; }
.dc__track.is-playing .dc__bars i:nth-child(3) { animation-delay: 320ms; }
@keyframes dcbar { 0%, 100% { height: 5px; } 50% { height: 14px; } }

/* The bottom-bar transport pulses gently while something is playing. */
.chip--audio.is-playing { color: var(--blue); }
.chip--audio.is-playing::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 11px;
  border: 2px solid var(--blue-lt);
  animation: dcpulse 2s ease-in-out infinite;
  pointer-events: none;
}
@keyframes dcpulse { 50% { opacity: 0.25; } }

@media (max-width: 560px) {
  .dc__deck { flex-direction: column; align-items: stretch; text-align: center; }
  .dc__disc { align-self: center; }
  .dc__transport { justify-content: center; }
  .dc__vol { margin-left: 0; justify-content: center; }
  .dc .dc__title, .dc .dc__artist { white-space: normal; }
}

/* --------------------------------------------------------------------------
   12. Forms
   -------------------------------------------------------------------------- */
.form { max-width: 620px; }
.field { margin: 0 0 15px; }
.field > label {
  display: block;
  margin: 0 0 5px;
  font-size: 0.88rem;
  font-weight: 800;
  color: var(--ink);
}
.field input,
.field textarea {
  width: 100%;
  padding: 11px 14px;
  border: 2px solid #d9e5ed;
  border-radius: 12px;
  background: #fbfdfe;
  font: inherit;
  font-size: 0.98rem;
  color: var(--ink);
  transition: border-color 150ms, box-shadow 150ms, background 150ms;
}
.field textarea { min-height: 128px; resize: vertical; line-height: 1.55; }
.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--blue);
  background: #fff;
  box-shadow: 0 0 0 4px rgba(2, 179, 251, 0.18);
}
.field input::placeholder,
.field textarea::placeholder { color: #a8bcc9; }
.field--hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 12px 26px;
  border: 2px solid var(--blue-dk);
  border-radius: 99px;
  background: linear-gradient(180deg, #3fc6fd 0%, var(--blue) 46%, #0289c4 100%);
  color: #fff;
  font-weight: 800;
  font-size: 1rem;
  text-decoration: none;
  cursor: pointer;
  box-shadow: 0 2px 5px rgba(4, 118, 164, 0.3), inset 0 1px 0 rgba(255,255,255,.5);
  transition: transform 150ms var(--ease), box-shadow 150ms, filter 150ms;
}
.btn:hover { transform: translateY(-2px); filter: saturate(1.1) brightness(1.04); box-shadow: 0 5px 14px rgba(4, 118, 164, 0.34), inset 0 1px 0 rgba(255,255,255,.5); }
.btn:active { transform: translateY(0) scale(0.985); }
.btn[disabled] { opacity: 0.6; cursor: progress; transform: none; }
.btn--ghost {
  background: #fff;
  color: var(--blue-dk);
  border-color: var(--edge);
  box-shadow: var(--shadow-1);
}
.btn--ghost:hover { border-color: var(--blue-lt); }
.btn .glyph { width: 19px; height: 19px; }

.notice {
  margin: 0 0 16px;
  padding: 13px 16px;
  border-radius: 12px;
  border: 2px solid var(--blue-lt);
  background: var(--blue-pale);
  color: #1c5871;
  font-weight: 700;
  font-size: 0.94rem;
}
.notice--bad { border-color: #f0b3a8; background: #fdeeeb; color: #8f2a19; }
.notice[hidden] { display: none; }

/* --------------------------------------------------------------------------
   13. Channel bottom bar (back button)
   -------------------------------------------------------------------------- */
.bar--channel .bar__center { pointer-events: auto; }
.backbtn {
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 10px 26px 10px 20px;
  border: 2px solid var(--edge);
  border-radius: 99px;
  background: linear-gradient(180deg, #fff 0%, #f1f7fa 60%, #e5eff5 100%);
  color: var(--blue-dk);
  font-weight: 800;
  font-size: clamp(14px, 2vh, 17px);
  text-decoration: none;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(28, 60, 84, 0.16), inset 0 1px 0 #fff;
  transition: transform 150ms var(--ease), box-shadow 150ms, border-color 150ms;
}
.backbtn:hover { transform: scale(1.035); border-color: var(--blue-lt); box-shadow: 0 5px 14px rgba(28,60,84,.2), inset 0 1px 0 #fff; }
.backbtn:active { transform: scale(0.98); }
.backbtn .glyph { width: 18px; height: 18px; }

/* --------------------------------------------------------------------------
   14. Settings popover (left orb)
   -------------------------------------------------------------------------- */
.pop {
  position: absolute;
  left: var(--orb-x);
  bottom: calc(100% - 6px);
  z-index: 20;
  width: min(280px, calc(100vw - 24px));
  padding: 14px;
  border: 2px solid var(--edge);
  border-radius: 16px;
  background: #fff;
  box-shadow: var(--shadow-2);
  transform-origin: bottom left;
  animation: pop 200ms var(--ease);
}
.pop[hidden] { display: none; }
@keyframes pop { from { opacity: 0; transform: translateY(8px) scale(0.94); } }
.pop h2 { margin: 0 0 4px; font-size: 0.95rem; font-weight: 800; }
.pop p { margin: 0 0 10px; font-size: 0.82rem; line-height: 1.5; color: var(--ink-soft); }
.pop__row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 7px 0; border-top: 1px solid #eaf1f5; font-size: 0.88rem; font-weight: 700; }
.pop a { color: var(--blue-dk); font-weight: 800; text-decoration: none; }
.pop a:hover { text-decoration: underline; }

/* --------------------------------------------------------------------------
   15. Standalone channel page (no-JS / direct link / crawler)
   -------------------------------------------------------------------------- */
.page-channel .overlay { position: fixed; }

/* Server-rendered tile list; JS lifts these into the paginated grid.
   The no-JS fallback that reveals it lives in nojs.css. */
.tile-source { display: none; }

/* --------------------------------------------------------------------------
   16. Mobile
   -------------------------------------------------------------------------- */
@media (max-width: 759px) {
  :root { --bar-h: 68px; --radius-tile: 12px; --clock-nudge: 5px; }
  .channel { border-radius: 14px; }
  .channel__body { padding: 16px 16px 26px; }
  .cards { grid-template-columns: 1fr; }
  .links { grid-template-columns: 1fr; }
  .gallery { grid-template-columns: repeat(2, 1fr); }
  /* Not enough room beside the orbs; the source link lives in the popover. */
  .chip--card { display: none; }
  .dots { bottom: 0; }
  .pager { width: 24px; }
}

@media (max-width: 400px) {
  :root { --orb-x: 12px; --orb-size: 44px; }
}

/* Short viewports: give the grid every pixel */
@media (max-height: 560px) {
  :root { --bar-h: 60px; --clock-nudge: 4px; }
  .stage { padding-top: 6px; padding-bottom: 4px; }
}

/* --------------------------------------------------------------------------
   17. Motion preferences
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* --------------------------------------------------------------------------
   18. Print
   -------------------------------------------------------------------------- */
@media print {
  html { overflow: visible; }
  .wii, .bar, .pager, .dots { display: none !important; }
  .overlay { position: static; }
  .channel { box-shadow: none; }
  .channel__body { overflow: visible; }
}
