/* ============================================================
   Analog Atelier — glitch prototype
   Single stylesheet. No external fonts, no libraries.
   ============================================================ */

:root {
  --bg:        #271f2c;   /* dusty eggplant (Format original) */
  --bg-soft:   #332739;   /* slightly lighter for dropdowns */
  --fg:        #efefef;
  --fg-dim:    #b0a8b5;
  --accent:    #ff2d2d;   /* CRT red */
  --cyan:      #00eaff;
  --magenta:   #ff1493;
  --line:      #3a2d42;
  --header-h:  93px;      /* site-header height (logo 64 + padding 14×2 + 1 border) */
  --maxw:      1600px;
  --pad:       clamp(16px, 3vw, 40px);
  --font-body: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
img, svg, iframe { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; background: none; border: 0; color: inherit; cursor: pointer; }

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.55;
  min-height: 100vh;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* ---------- CRT texture (phosphor triad + noise + vignette) ---------- */
body::before,
body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}
/* Phosphor RGB triads — coarser stripes to match reference. Oversized so
   the barrel filter never exposes bare edges. */
body::before {
  inset: -60px;      /* extend past viewport so barrel-inward doesn't reveal edges */
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.22 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"),
    repeating-linear-gradient(90deg,
      rgba(255, 70, 85, 0.26)  0   2px,
      rgba(60, 255, 120, 0.22) 2px 4px,
      rgba(90, 110, 255, 0.32) 4px 6px);
  mix-blend-mode: screen;
  opacity: 0.62;
  filter: url('crt-filter.svg#barrel');
  animation: crt-static 1.6s steps(6, end) infinite;   /* fizzy phosphor flicker */
}
/* Master CRT overlay: bright cool center bloom, gentle indigo side darkness.
   The physical-looking corner bezel comes from html::before below. */
body::after {
  background:
    /* 1. bright cool center bloom (blue-green phosphor glow) */
    radial-gradient(ellipse 50% 42% at 50% 46%,
      rgba(120, 230, 220, 0.24) 0%,
      rgba(120, 200, 235, 0.10) 40%,
      transparent 78%),
    /* 2. subtle indigo-black side shading (much less purple than before) */
    linear-gradient(to right,
      rgba(8, 10, 24, 0.28) 0%,
      rgba(8, 10, 24, 0.10) 10%,
      transparent 25%,
      transparent 75%,
      rgba(8, 10, 24, 0.10) 90%,
      rgba(8, 10, 24, 0.28) 100%),
    /* 3. top/bottom fade */
    linear-gradient(to bottom,
      rgba(0,0,0,0.35) 0%,
      transparent 14%,
      transparent 86%,
      rgba(0,0,0,0.35) 100%);
  animation: crt-breathe 7s ease-in-out infinite;      /* slow tube-glow pulse */
}
/* Static flicker: tiny opacity jitter + background-position wobble mimics
   the fizzy, restless quality of a live CRT tube. */
@keyframes crt-static {
  0%   { opacity: 0.56; background-position: 0 0, 0 0; }
  18%  { opacity: 0.68; background-position: 3px -1px, 0 0; }
  34%  { opacity: 0.58; background-position: -2px 2px, 0 0; }
  52%  { opacity: 0.70; background-position: 2px 3px, 0 0; }
  68%  { opacity: 0.60; background-position: -3px -2px, 0 0; }
  84%  { opacity: 0.66; background-position: 1px 2px, 0 0; }
  100% { opacity: 0.56; background-position: 0 0, 0 0; }
}
/* Slow breathing glow — very subtle brightness pulse across the master overlay.
   Using filter rather than opacity so the vignette/side-tint aren't undermined. */
@keyframes crt-breathe {
  0%, 100% { filter: brightness(1)    saturate(1); }
  50%      { filter: brightness(1.10) saturate(1.06); }
}

/* ---------- Degauss (home-return color-wobble effect) ---------- */
body.degauss {
  animation: degauss 1.7s ease-out;
}
@keyframes degauss {
  0%   { filter: hue-rotate(45deg)  saturate(2.4) brightness(1.55) contrast(1.35); }
  8%   { filter: hue-rotate(-70deg) saturate(2.5) brightness(1.45) contrast(1.40); }
  18%  { filter: hue-rotate(85deg)  saturate(2.0) brightness(1.32) contrast(1.20); }
  32%  { filter: hue-rotate(-40deg) saturate(1.6) brightness(1.22); }
  48%  { filter: hue-rotate(18deg)  saturate(1.28) brightness(1.12); }
  66%  { filter: hue-rotate(-8deg)  saturate(1.12) brightness(1.05); }
  84%  { filter: saturate(1.05) brightness(1.02); }
  100% { filter: none; }
}

/* ---------- TV FX layer (power-on + channel-change) ---------- */
/* Inactive by default — each effect is activated by a body class (.booting /
   .tuning) added by the site script. */
#tv-fx {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 200;           /* above everything, including the CRT bezel */
  overflow: hidden;
}
.tv-fx-bar,
.tv-fx-scan,
.tv-fx-static {
  position: absolute;
  left: 0;
  right: 0;
  opacity: 0;
  pointer-events: none;
}
/* Black "shutter" bars that cover the top and bottom halves during boot */
.tv-fx-bar { background: #000; }
.tv-fx-top { top: 0;    height: 50%; transform-origin: top;    transform: scaleY(0); }
.tv-fx-bot { bottom: 0; height: 50%; transform-origin: bottom; transform: scaleY(0); }
/* Bright scan line that appears in the middle as the tube warms up */
.tv-fx-scan {
  top: 50%;
  height: 3px;
  margin-top: -1.5px;
  background: linear-gradient(to bottom,
    transparent 0%,
    rgba(255,255,255,0.5) 15%,
    rgba(255,255,255,1)   50%,
    rgba(240,250,255,1)   60%,
    rgba(255,255,255,0.5) 85%,
    transparent 100%);
  box-shadow: 0 0 16px 6px rgba(180,220,255,0.55);
  transform: scaleY(0);
}
/* Static noise layer used for channel-change */
.tv-fx-static {
  top: 0; bottom: 0;
  height: 100%;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='2.2' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1.2 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  background-size: 220px 220px;
  mix-blend-mode: screen;
}

/* --- Booting (CRT power-on on first splash load) --- */
body.booting .tv-fx-top  { animation: crt-boot-top  1.85s ease-out forwards; }
body.booting .tv-fx-bot  { animation: crt-boot-bot  1.85s ease-out forwards; }
body.booting .tv-fx-scan { animation: crt-boot-scan 1.85s ease-out forwards; }

@keyframes crt-boot-top {
  0%   { opacity: 1; transform: scaleY(1); }
  10%  { opacity: 1; transform: scaleY(0.95); }
  22%  { opacity: 1; transform: scaleY(0.75); }
  45%  { opacity: 1; transform: scaleY(0.2);  }
  72%  { opacity: 0.8; transform: scaleY(0.02); }
  100% { opacity: 0; transform: scaleY(0); }
}
@keyframes crt-boot-bot {
  0%   { opacity: 1; transform: scaleY(1); }
  10%  { opacity: 1; transform: scaleY(0.95); }
  22%  { opacity: 1; transform: scaleY(0.75); }
  45%  { opacity: 1; transform: scaleY(0.2);  }
  72%  { opacity: 0.8; transform: scaleY(0.02); }
  100% { opacity: 0; transform: scaleY(0); }
}
@keyframes crt-boot-scan {
  0%   { opacity: 0; height: 2px;  margin-top: -1px;  transform: scaleY(0.1); }
  12%  { opacity: 0.4; transform: scaleY(1); }
  25%  { opacity: 1; height: 3px;  margin-top: -1.5px; }
  45%  { opacity: 1; height: 6px;  margin-top: -3px; }
  65%  { opacity: 0.55; height: 36px; margin-top: -18px; }
  82%  { opacity: 0.22; height: 140px; margin-top: -70px; }
  100% { opacity: 0; height: 0;   margin-top: 0; }
}

/* --- Tuning (channel-change, 80s TV flip style) ---
   Three layered effects below the header:
     · .tv-fx-static — base noise haze
     · #tv-fx::before — a bright static BAR that rolls vertically
     · #tv-fx::after  — a quick bluish flash at the moment of the snap
   The header bar stays untouched — all tuning layers start at var(--header-h). */
body.tuning .tv-fx-static {
  top: var(--header-h);
  height: calc(100% - var(--header-h));
  filter: contrast(1.3) brightness(1.2) saturate(1.3);
  animation: crt-tune 0.4s steps(8, end) forwards;
}
@keyframes crt-tune {
  0%   { opacity: 1; background-position: 0 0; }
  14%  { opacity: 1; background-position: 110px -40px; }
  28%  { opacity: 1; background-position: -80px 90px; }
  42%  { opacity: 0.95; background-position: 70px 150px; }
  56%  { opacity: 0.85; background-position: -140px -60px; }
  72%  { opacity: 0.55; background-position: 30px 30px; }
  86%  { opacity: 0.25; background-position: -50px 110px; }
  100% { opacity: 0; background-position: 0 0; }
}

/* Rolling static band and flash — pseudo-elements on #tv-fx */
#tv-fx::before,
#tv-fx::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  pointer-events: none;
  opacity: 0;
}
#tv-fx::before {
  /* horizontal static bar that rolls down the screen */
  top: var(--header-h);
  height: 60px;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='60'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='3' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1.4 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"),
    linear-gradient(to bottom,
      transparent 0%,
      rgba(240,240,240,0.35) 10%,
      rgba(250,250,250,0.92) 42%,
      rgba(230,230,240,0.98) 55%,
      rgba(200,200,220,0.70) 75%,
      transparent 100%);
  background-size: 200px 60px, 100% 100%;
  background-blend-mode: screen;
  mix-blend-mode: screen;
}
#tv-fx::after {
  /* bluish-white flash covering the content area (not the header) */
  top: var(--header-h);
  bottom: 0;
  background: rgba(240,250,255,0.55);
  mix-blend-mode: screen;
}
body.tuning #tv-fx::before { animation: crt-tune-roll  0.42s linear   forwards; }
body.tuning #tv-fx::after  { animation: crt-tune-flash 0.38s ease-out forwards; }
/* Clip the entire FX layer below the header during channel-change so neither
   the rolling bar's lead-in nor any flash can bleed up into the nav bar.
   Booting (power-on) keeps the full-viewport area uncropped. */
body.tuning #tv-fx { clip-path: inset(var(--header-h) 0 0 0); }

@keyframes crt-tune-roll {
  0%   { opacity: 0;    transform: translateY(-15vh); }
  10%  { opacity: 1;    transform: translateY(-5vh); }
  50%  { opacity: 0.95; transform: translateY(40vh); }
  90%  { opacity: 0.55; transform: translateY(95vh); }
  100% { opacity: 0;    transform: translateY(110vh); }
}
@keyframes crt-tune-flash {
  0%   { opacity: 0; }
  22%  { opacity: 0.9; }
  48%  { opacity: 0.35; }
  100% { opacity: 0; }
}

/* Physical CRT bezel — pillow-shape dark frame.
   Starts below the header so the nav area is unaffected.
   Four corner radial gradients pinch in hard at the corners and leave the
   middles of each edge relatively clear, producing the classic CRT screen
   silhouette (squircle with aggressive corners). */
html::before {
  content: "";
  position: fixed;
  top: var(--header-h);
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
  z-index: 10;
  /* Heavier perimeter darkening */
  box-shadow: inset 0 0 150px 30px rgba(0,0,0,0.78);
  /* Stack, top → bottom:
     1. Hard SVG bezel silhouette (solid black frame with a pillow-shaped cutout)
     2. Four corner radials for soft falloff inside the bezel
  */
  background-image:
    /* SVG bezel silhouette with a Gaussian-blurred inner edge — no longer a hard knife-cut */
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 60' preserveAspectRatio='none'><defs><filter id='s' x='-4%25' y='-4%25' width='108%25' height='108%25'><feGaussianBlur stdDeviation='0.35'/></filter></defs><path fill='%23000' fill-rule='evenodd' filter='url(%23s)' d='M -2 -2L 102 -2L 102 62L -2 62ZM 12.5 3.5C 5.5 3.5 3.5 7.5 3.5 12.5Q 0.5 30 3.5 47.5C 3.5 52.5 5.5 56.5 12.5 56.5Q 50 59 87.5 56.5C 94.5 56.5 96.5 52.5 96.5 47.5Q 99.5 30 96.5 12.5C 96.5 7.5 94.5 3.5 87.5 3.5Q 50 1 12.5 3.5Z'/></svg>"),
    /* Corner radials pulled back 7 percentage points (56% → 49%) and their
       falloff softened (final stop moved from 95% to 100%) */
    radial-gradient(ellipse 49% 49% at 0% 0%,
      rgba(0,0,0,1)    0%,
      rgba(0,0,0,0.90) 16%,
      rgba(0,0,0,0.55) 38%,
      rgba(0,0,0,0.18) 66%,
      rgba(0,0,0,0)    100%),
    radial-gradient(ellipse 49% 49% at 100% 0%,
      rgba(0,0,0,1)    0%,
      rgba(0,0,0,0.90) 16%,
      rgba(0,0,0,0.55) 38%,
      rgba(0,0,0,0.18) 66%,
      rgba(0,0,0,0)    100%),
    radial-gradient(ellipse 49% 49% at 0% 100%,
      rgba(0,0,0,1)    0%,
      rgba(0,0,0,0.90) 16%,
      rgba(0,0,0,0.55) 38%,
      rgba(0,0,0,0.18) 66%,
      rgba(0,0,0,0)    100%),
    radial-gradient(ellipse 49% 49% at 100% 100%,
      rgba(0,0,0,1)    0%,
      rgba(0,0,0,0.90) 16%,
      rgba(0,0,0,0.55) 38%,
      rgba(0,0,0,0.18) 66%,
      rgba(0,0,0,0)    100%);
  background-size: 100% 100%, auto, auto, auto, auto;
  background-repeat: no-repeat;
}

/* Push real content above the overlays */
.site, .site-footer { position: relative; z-index: 2; }

/* ---------- Layout ---------- */
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 var(--pad); }

/* ---------- Header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(39,31,44,0.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
.site-header .wrap {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 24px;
  padding-top: 14px;
  padding-bottom: 14px;
}
.header-logo img {
  height: 64px;
  width: auto;
  image-rendering: auto;
}
.header-logo {
  transition: filter .2s ease;
}
.header-logo:hover { filter: saturate(1.4) contrast(1.05); }

/* Primary nav */
.primary-nav { display: flex; justify-content: center; }
.primary-nav > ul {
  list-style: none; margin: 0; padding: 0;
  display: flex; gap: clamp(12px, 2vw, 32px);
  font-family: var(--font-mono);
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.primary-nav .cat > a,
.primary-nav .cat > span,
.primary-nav > ul > li > a {
  position: relative;
  display: inline-block;
  padding: 8px 4px;
  color: var(--fg);
  cursor: pointer;
  white-space: nowrap;
}
.primary-nav .cat { position: relative; }
.primary-nav .cat-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 4px;
  cursor: pointer;
}
.primary-nav .cat-label .arrow {
  color: var(--fg-dim);
  font-size: 10px;
  font-style: normal;
}
.primary-nav .sub {
  position: absolute;
  top: 100%;
  left: 50%;
  /* Push the sub out of the header's area entirely so its background doesn't
     fight with the header's translucent bg + backdrop-filter. */
  transform: translateX(-50%) translateY(34px);
  display: none;
  list-style: none;
  margin: 0;
  padding: 10px 0;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  min-width: 260px;
  z-index: 60;               /* sit above any header compositing */
}
/* Invisible hover bridge spans the gap between the cat-label and the sub */
.primary-nav .sub::before {
  content: "";
  position: absolute;
  top: -36px;
  left: 0;
  right: 0;
  height: 36px;
}
.primary-nav .cat:hover .sub,
.primary-nav .cat:focus-within .sub { display: block; }
/* Keep sub open while the cursor is inside it, even after leaving the cat */
.primary-nav .sub:hover { display: block; }
.primary-nav .sub a {
  display: block;
  padding: 10px 18px;
  color: var(--fg);
  position: relative;
}
.primary-nav .sub a:hover { color: var(--fg); }            /* glitch carries the hover */
.primary-nav .sub a.active { color: #C54B8C; }             /* no background pill */
.primary-nav a.active { color: #C54B8C; font-weight: 700; font-size: 17px; }

/* Socials */
.site-header .socials {
  display: flex; gap: 14px; align-items: center;
}
.site-header .socials a {
  width: 22px; height: 22px;
  color: var(--fg-dim);
  transition: color .15s ease, transform .15s ease;
}
.site-header .socials a:hover { color: var(--accent); transform: translateY(-1px); }
.site-header .socials svg { width: 100%; height: 100%; }

/* Mobile menu toggle */
.menu-toggle { display: none; }
@media (max-width: 900px) {
  .site-header .wrap {
    grid-template-columns: auto 1fr auto;
  }
  .menu-toggle {
    display: inline-flex;
    align-items: center; justify-content: center;
    width: 42px; height: 42px;
    border: 1px solid var(--line);
    font-family: var(--font-mono);
    letter-spacing: 0;
  }
  .primary-nav {
    position: fixed;
    inset: 64px 0 auto 0;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    padding: 18px var(--pad);
    display: none;
  }
  .primary-nav.is-open { display: block; }
  .primary-nav > ul {
    flex-direction: column;
    gap: 4px;
    align-items: stretch;
  }
  .primary-nav .sub {
    position: static;
    display: block;
    transform: none;
    background: transparent;
    border: 0;
    padding: 0 0 8px 16px;
  }
  .primary-nav .cat > span::after { display: none; }
}

/* ---------- Glitch text (hover) ----------
   Usage: <span class="glitch" data-text="HELLO">HELLO</span>
   ------------------------------------------- */
.glitch {
  position: relative;
  display: inline-block;
  color: inherit;
}
.glitch::before,
.glitch::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity .08s steps(2, end);
}
.glitch::before { color: var(--cyan);    transform: translate(-2px, 0); mix-blend-mode: screen; }
.glitch::after  { color: var(--magenta); transform: translate( 2px, 0); mix-blend-mode: screen; }
.glitch:hover::before,
.glitch:hover::after,
.glitch:focus-visible::before,
.glitch:focus-visible::after { opacity: 1; }
.glitch:hover::before { animation: glitch-a .45s steps(3, end) infinite; }
.glitch:hover::after  { animation: glitch-b .45s steps(3, end) infinite; }

/* Active page: 1.5s calm, then .5s burst at original speed, loop */
.active .glitch::before { animation: glitch-a .45s steps(3, end) infinite, glitch-toggle 2s linear infinite; }
.active .glitch::after  { animation: glitch-b .45s steps(3, end) infinite, glitch-toggle 2s linear infinite; }
@keyframes glitch-toggle {
  0%,    75%   { opacity: 0; }
  75.01%, 100% { opacity: 1; }
}
@keyframes glitch-a {
  0%   { clip-path: inset(0 0 82% 0); transform: translate(-3px, 0); }
  33%  { clip-path: inset(42% 0 40% 0); transform: translate(-2px, 1px); }
  66%  { clip-path: inset(78% 0 4% 0); transform: translate(-4px, -1px); }
  100% { clip-path: inset(15% 0 65% 0); transform: translate(-2px, 0); }
}
@keyframes glitch-b {
  0%   { clip-path: inset(70% 0 8% 0);  transform: translate(3px, 0); }
  33%  { clip-path: inset(12% 0 60% 0); transform: translate(2px, -1px); }
  66%  { clip-path: inset(38% 0 42% 0); transform: translate(4px, 1px); }
  100% { clip-path: inset(55% 0 25% 0); transform: translate(2px, 0); }
}
/* ---------- Firefox performance mode ----------
   Firefox renders SVG filters, backdrop-filter, and animated filter keyframes
   via slower code paths than Chromium/WebKit. When the site script detects
   Firefox it adds `.ff` to <html>; these rules strip the 3 most expensive
   effects while keeping the full CRT look intact (stripes stay straight,
   noise stays static, the bezel silhouette and corner darkening are
   unaffected). */
html.ff body::before {
  filter: none;                 /* disable the SVG barrel filter */
  animation: none;              /* disable the crt-static flicker */
  mix-blend-mode: normal;       /* avoid blend-mode quirks around iframes */
  opacity: 0.42;                /* compensate for losing screen-blend brightening */
}
html.ff body::after {
  animation: none;              /* disable the crt-breathe pulse */
}
html.ff .site-header {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  background: rgba(39,31,44,0.97);
}
/* Firefox iframe click-through: isolate each video so the hit-test resolves
   straight to the iframe without traversing the body overlays. */
html.ff .item.video {
  isolation: isolate;
  contain: layout paint;
}
html.ff .item.video iframe { pointer-events: auto; }

/* Defensive: make absolutely sure the TV FX overlay never captures clicks */
#tv-fx,
#tv-fx::before,
#tv-fx::after,
.tv-fx-bar,
.tv-fx-scan,
.tv-fx-static { pointer-events: none !important; }

/* Pause the continuous overlays while the tab is hidden — save CPU/battery */
html.paused body::before,
html.paused body::after { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .glitch:hover::before, .glitch:hover::after,
  .active .glitch::before, .active .glitch::after { animation: none; }
  body::before, body::after { animation: none; }          /* hold the CRT overlay steady */
  body.degauss { animation: none; }                        /* skip degauss flash */
  body.booting .tv-fx-top,
  body.booting .tv-fx-bot,
  body.booting .tv-fx-scan,
  body.tuning  .tv-fx-static,
  body.tuning  #tv-fx::before,
  body.tuning  #tv-fx::after { animation: none; opacity: 0; } /* skip turn-on / channel static */
}

/* ---------- Page title ---------- */
.page-title {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: clamp(28px, 4vw, 52px);
  letter-spacing: 0.02em;
  margin: 0;
  line-height: 1.05;
}
.page-kicker {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--fg-dim);
  margin: 0 0 8px;
}
.page-head {
  padding: 48px 0 24px;
  border-bottom: 1px solid var(--line);
}
.page-head + section { padding-top: 32px; }

/* ---------- Body text ---------- */
.prose { max-width: 72ch; }
.prose p { margin: 0 0 1.2em; color: var(--fg); }
.prose a {
  color: var(--cyan);
  border-bottom: 1px solid transparent;
  transition: border-color .15s ease;
}
.prose a:hover { border-bottom-color: var(--cyan); }

/* ---------- Single-column content stream ---------- */
/* Used by page-content blocks: prose sections, images with captions, videos */
.page { padding-top: 28px; }           /* breathing room between header and first block */
.page > .prose,
.page > .item {
  max-width: 1100px;
  margin: 0 auto 48px;
}
.page > .prose { max-width: 720px; margin-bottom: 32px; }
.prose h1,
.prose h2,
.prose h3 {
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
  text-align: center;
  margin: 48px 0 14px;
  color: var(--fg);
}
.prose h1 { font-size: clamp(28px, 3.6vw, 44px); }
.prose h2 { font-size: clamp(22px, 2.4vw, 30px); text-transform: lowercase; }
.prose h3 { font-size: clamp(18px, 2vw, 24px); }
.prose h1:first-child,
.prose h2:first-child,
.prose h3:first-child { margin-top: 16px; }
.prose p {
  font-size: 17px;
  line-height: 1.65;
  color: var(--fg);
  margin: 0 0 1em;
}
.prose p:last-child { margin-bottom: 0; }
.prose a {
  color: var(--cyan);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color .15s ease;
}
.prose a:hover { color: var(--magenta); }

/* Image & video items — single column, natural aspect ratio */
.item { margin: 0 auto 48px; }
.item img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 86vh;
  object-fit: contain;
  background: #0b0a0f;
  transition: filter .25s ease;
  filter: saturate(0.95) contrast(1.02);
}
.item:hover img { filter: saturate(1.12) contrast(1.06); }
.item figcaption {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--fg-dim);
  letter-spacing: 0.03em;
  padding: 10px 4px 0;
  text-align: center;
}

/* Video — figure can carry a figcaption, so the 16:9 aspect lives on an
   inner wrapper (.video-frame) rather than on the figure itself. */
.item.video .video-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #000;
  overflow: hidden;
}
.item.video .video-frame iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0;
}
.item.video.hero {
  max-width: 1400px;
  margin-bottom: 16px;
}
/* Figcaption alignment is inherited from .item figcaption (centered) */

/* ---------- Slideshow widget (mini gallery with thumbnails) ---------- */
.slideshow {
  display: grid;
  grid-template-columns: 1fr 240px;
  gap: 26px;
  max-width: 1100px;
  margin: 0 auto 48px;
}
.slideshow-main {
  position: relative;
  background: #0b0a0f;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border: 1px solid rgba(255,255,255,0.04);
}
.slideshow-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: rgba(0,0,0,0.55);
  color: #fff;
  font-size: 30px;
  line-height: 1;
  font-family: var(--font-mono);
  cursor: pointer;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 0 2px;
  opacity: 0.6;
  transition: opacity .15s ease, background .15s ease;
}
.slideshow-main:hover .slideshow-arrow { opacity: 0.9; }
.slideshow-arrow:hover { opacity: 1; background: rgba(0,0,0,0.85); }
.slideshow-arrow:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.slideshow-arrow.prev { left: 14px; }
.slideshow-arrow.next { right: 14px; }
.slideshow-main img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: opacity .2s ease;
}
.slideshow-thumbs {
  display: flex;
  flex-direction: column;
  gap: 18px;                              /* generous vertical spacing between thumbs */
  max-height: calc((1100px - 240px - 26px) * 2 / 3);
  overflow-y: auto;
  padding: 4px 4px 4px 0;
  scrollbar-width: thin;
  scrollbar-color: var(--fg-dim) transparent;
}
.slideshow-thumbs::-webkit-scrollbar { width: 6px; }
.slideshow-thumbs::-webkit-scrollbar-thumb { background: var(--fg-dim); border-radius: 3px; }
.slideshow-thumbs .thumb {
  display: block;
  padding: 0;
  margin: 0;
  border: 2px solid rgba(255,255,255,0.08);
  background: #0b0a0f;
  cursor: pointer;
  overflow: hidden;
  line-height: 0;                         /* prevent inline gap under img */
  flex-shrink: 0;                         /* don't compress when scroll container has max-height */
  transition: border-color .15s ease, background .15s ease;
}
.slideshow-thumbs .thumb img {
  width: 100%;
  height: auto;                           /* natural aspect — whole image, no letterbox */
  display: block;
  filter: saturate(0.9) contrast(0.98);
  transition: filter .15s ease, transform .2s ease;
}
.slideshow-thumbs .thumb:hover img { filter: saturate(1.15) contrast(1.05); transform: scale(1.03); }
.slideshow-thumbs .thumb:hover { border-color: var(--magenta); background: #120f17; }
.slideshow-thumbs .thumb.active { border-color: var(--cyan); background: #120f17; }
.slideshow-thumbs .thumb.active img { filter: saturate(1.1) contrast(1.05); }

@media (max-width: 800px) {
  .slideshow { grid-template-columns: 1fr; gap: 14px; }
  .slideshow-thumbs {
    max-height: 140px;
    flex-direction: row;
    gap: 12px;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 4px 0;
  }
  .slideshow-thumbs .thumb { flex: 0 0 auto; width: 140px; }
  .slideshow-thumbs .thumb img { width: 140px; }
}

/* ---------- Sections ---------- */
.section { padding: 48px 0; border-top: 1px solid var(--line); }
.section h2 {
  font-family: var(--font-mono);
  font-size: clamp(20px, 2.4vw, 28px);
  letter-spacing: 0.05em;
  margin: 0 0 18px;
}

/* ---------- Footer ---------- */
.site-footer {
  margin-top: 80px;
  padding: 32px 0 48px;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--fg-dim);
  text-align: center;
  letter-spacing: 0.1em;
}
.site-footer .socials {
  display: flex; gap: 18px; justify-content: center; margin-bottom: 14px;
}
.site-footer .socials a { width: 22px; height: 22px; color: var(--fg-dim); }
.site-footer .socials a:hover { color: var(--accent); }
.site-footer .socials svg { width: 100%; height: 100%; }

/* ---------- Contact form ---------- */
.contact-form-wrap {
  max-width: 600px;
  margin: 16px auto 48px;
  padding: 0 var(--pad);
}
.contact-form-wrap h2 {
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
  text-align: center;
  text-transform: lowercase;
  font-size: clamp(22px, 2.4vw, 30px);
  margin: 0 0 24px;
}
.contact-form {
  display: grid;
  gap: 16px;
  font-family: var(--font-mono);
}
.contact-form label {
  display: block;
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--fg-dim);
  text-transform: uppercase;
  position: relative;
}
.contact-form label span {
  display: block;
  margin-bottom: 6px;
}
.contact-form input[type="text"],
.contact-form input[type="email"],
.contact-form textarea {
  width: 100%;
  background: #1a1420;
  color: var(--fg);
  font: inherit;
  font-size: 15px;
  letter-spacing: 0;
  text-transform: none;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 2px;
  transition: border-color .15s ease, background .15s ease;
  box-sizing: border-box;
}
.contact-form input:focus,
.contact-form textarea:focus {
  outline: none;
  border-color: var(--cyan);
  background: #1f1824;
}
.contact-form textarea { resize: vertical; min-height: 120px; font-family: var(--font-mono); }
.contact-form .captcha-field code {
  background: #1a1420;
  padding: 2px 8px;
  border-radius: 2px;
  font-size: 14px;
  color: var(--cyan);
}
/* Honeypot — off-screen but still focusable so spam bots fill it */
.contact-form .hp-field {
  position: absolute !important;
  left: -9999px !important;
  top: auto !important;
  width: 1px !important;
  height: 1px !important;
  overflow: hidden !important;
}
.contact-submit {
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  background: transparent;
  color: var(--fg);
  border: 1px solid var(--cyan);
  padding: 12px 22px;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
  justify-self: start;
  position: relative;
}
.contact-submit:hover { background: rgba(0,234,255,0.1); }
.contact-submit:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }
.contact-status {
  min-height: 1.2em;
  font-size: 13px;
  color: var(--fg-dim);
  letter-spacing: 0.03em;
  margin: 4px 0 0;
}
.contact-status[data-kind="err"] { color: var(--accent); }
.contact-status[data-kind="ok"]  { color: var(--cyan); }

/* ---------- Tiny utilities ---------- */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
