/* ═══════════════════════════════════════════════════════════════════
   THE HUMAN SEXUAL REVOLUTION (ONGOING) — shared grammar
   revolution.css

   EMOTIONAL TARGET: walking into a 1978 record shop that is also
   a reliquary. Velvet dark, chrome light, nothing corporate.

   Membranes enforced here:
   · rejects extraction  → zero third-party CSS beyond fonts
   · protects contact    → [data-motion="stilled"] quiets EVERYTHING
   ═══════════════════════════════════════════════════════════════════ */

@import url('https://fonts.googleapis.com/css2?family=Bungee&family=DM+Serif+Display:ital@0;1&family=Josefin+Sans:ital,wght@0,300;0,400;0,600;1,400&family=Courier+Prime:ital,wght@0,400;0,700;1,400&family=Cinzel+Decorative:wght@400;700;900&family=Cormorant+Garamond:ital,wght@0,300;0,400;0,600;1,400;1,600&family=Ephesis&display=swap');

/* ── TOKENS ─────────────────────────────────────────────────────── */
:root {
  /* the void underneath everything — Nexus base, non-negotiable */
  --void:        #020005;
  --void-warm:   #0d0410;          /* velvet layer over the void */

  /* the glam layer — 1970s over the Nexus grammar */
  --hotpink:     #ff2e88;          /* stripe one. the first color cut. */
  --tangerine:   #ff7a1a;
  --gold:        #f5c518;          /* harvest gold */
  --lavender:    #c9a0ff;
  --cyan:        #26e0e0;
  --avocado:     #9db02c;          /* used sparingly. it earned the 70s. */
  --rose:        #ff9ecb;

  /* the maximalist layer — xerox punk + disco poster + activist zine */
  --neon-green:  #39ff14;          /* Girl Bar's acid duotone */
  --shout-orange:#ff3d00;          /* the diagonal banner color, flat */
  --paper:       #f5ead9;          /* cream flyer stock, not void */

  /* chrome is a gradient, never a flat color — now holographic foil,
     not silver: the same mechanism, an oil-slick rainbow instead of
     a mirror. built from the existing palette, no new hues needed. */
  --chrome: linear-gradient(
    135deg,
    var(--hotpink) 0%, var(--gold) 14%, var(--rose) 28%,
    var(--lavender) 42%, var(--cyan) 56%, var(--hotpink) 70%,
    var(--gold) 84%, var(--lavender) 100%
  );

  /* ── GROUND: the site now lives on white, colored per container.
     --page is the ground; --ink is "readable foreground on the CURRENT
     ground." Default = light. Dark contexts flip these below via
     [data-ground="dark"], so contrast is guaranteed by construction and
     no text is ever left invisible on its own background. ──────────── */
  --page:        #f7f4ef;          /* warm white — the universal ground */
  --ink:         #1a0a14;          /* dark ink, readable on white */
  --ink-dim:     #6b5d72;          /* muted, still readable on white */
  --line:        rgba(20,4,12,.16);
  --link:        #b0176b;          /* deep pink — readable link on white */

  /* text-safe accents: vivid hues wash out on white, so emphasis TEXT
     uses darkened variants. The vivid tokens above stay for grounds,
     borders, glows, the flag, and the mirrorball. */
  --gold-t:      #9a6a00;          /* amber, for gold emphasis on white */
  --cyan-t:      #0b7d7d;          /* teal, for cyan emphasis on white */
  --rose-t:      #b0176b;          /* deep rose, for rose emphasis on white */

  --font-display: 'Bungee', 'Impact', sans-serif;         /* fat glam, now a shout */
  --font-serif:   'DM Serif Display', 'Playfair Display', Georgia, serif; /* the grief/tabloid voice */
  --font-geo:     'Josefin Sans', 'Avant Garde', sans-serif;
  --font-mono:    'Courier Prime', 'Courier New', monospace;

  --ease-needle: cubic-bezier(.22,.9,.32,1);   /* tonearm damping */
  --beat: 517ms;                                /* one beat @ 116 BPM */
}

/* DARK CONTEXT — three ways in, one set of tokens:
   · the carve-out rooms (theriot, the Living register) set data-ground
     ="dark" themselves — always dark, never disco;
   · the global light/dark switch sets html[data-theme="disco"] — the
     whole site goes dark AND gets the glow layer further down.
   Flips the ground tokens back to velvet-dark so light text stays read. */
[data-ground="dark"], .on-dark, html[data-theme="disco"] {
  --page:    var(--void);
  --ink:     #f4ecff;
  --ink-dim: #9d8fb0;
  --line:    rgba(201,160,255,.18);
  --link:    var(--cyan);
  --gold-t:  var(--gold);
  --cyan-t:  var(--cyan);
  --rose-t:  var(--rose);
}

/* ── RESET / BODY ───────────────────────────────────────────────── */
* { margin:0; padding:0; box-sizing:border-box; }

html { scroll-behavior:smooth; overflow-x: clip; }   /* root clip: no stray element (e.g. a rotated shout-banner) can widen the page and force a mobile zoom */
html[data-motion="stilled"] { scroll-behavior:auto; }

body {
  background: var(--page);
  color: var(--ink);
  font-family: var(--font-geo);
  font-weight: 300;
  letter-spacing: .02em;
  line-height: 1.65;
  min-height: 100vh;
  overflow-x: hidden;
}

::selection { background: var(--hotpink); color: #fff; }

/* On touch devices, press-and-hold (the mirrorball's charge gesture) otherwise
   triggers the browser's text-selection / copy callout. Suppress it there —
   desktop selection stays intact, and form fields remain selectable. */
@media (hover: none), (pointer: coarse) {
  body { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
  input, textarea, [contenteditable] { -webkit-user-select: text; user-select: text; }
}

a { color: var(--link); text-decoration-color: rgba(176,23,107,.4); text-underline-offset: 3px; }
a:hover { color: var(--hotpink); }
[data-ground="dark"] a, .on-dark a, html[data-theme="disco"] a { text-decoration-color: rgba(38,224,224,.4); }
[data-ground="dark"] a:hover, .on-dark a:hover, html[data-theme="disco"] a:hover { color: var(--rose); }

:focus-visible {
  outline: 2px solid var(--hotpink);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ── ATMOSPHERE LAYERS (fixed, pointer-transparent) ─────────────── */

/* CRT scanlines — near-silent on the white ground; restored to full
   presence only inside the dark carve-out rooms. */
.scanlines {
  position: fixed; inset: 0;
  background: repeating-linear-gradient(
    0deg,
    rgba(0,0,0,.16) 0 1px,
    transparent 1px 3px
  );
  pointer-events: none;
  z-index: 40;
  /* base .12, gently breathing up with the room's amplitude (rests at .12
     when silent or in reduced-motion, since --rx-level defaults/pins to 0) */
  opacity: calc(.12 + var(--rx-level, 0) * .09);
  /* drift the pattern by moving the background, NOT the layer — a transform
     animation on a fixed overlay re-composites on every scroll frame and
     "catches" / tears on mobile. background-position leaves the layer pinned. */
  animation: scan-drift 9s linear infinite;
  transform: translateZ(0);        /* own compositor layer, promoted once */
  backface-visibility: hidden;
  will-change: background-position;
}
[data-ground="dark"] .scanlines, html[data-theme="disco"] .scanlines { opacity: calc(.5 + var(--rx-level, 0) * .16); }
@keyframes scan-drift { to { background-position: 0 3px; } }

/* film grain via feTurbulence — real texture, no image request */
.grain {
  position: fixed; inset: -50%;
  width: 200%; height: 200%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
  pointer-events: none;
  z-index: 41;
  animation: grain-shift .9s steps(4) infinite;
  backface-visibility: hidden;     /* pin to its own layer so scroll can't tear it */
  will-change: transform;
}
@keyframes grain-shift {
  0%   { transform: translate(0,0); }
  25%  { transform: translate(-1.2%, .8%); }
  50%  { transform: translate(.9%, -1.1%); }
  75%  { transform: translate(-.7%, -.6%); }
  100% { transform: translate(0,0); }
}

/* velvet vignette — on white it's the faintest warm edge-shade; inside
   the dark carve-out rooms it becomes the full center-pulling velvet. */
.velvet {
  position: fixed; inset: 0;
  background: radial-gradient(ellipse 96% 80% at 50% 42%,
              transparent 0%, rgba(120,60,20,.05) 82%, rgba(90,40,10,.10) 100%);
  pointer-events: none;
  z-index: 39;
}
[data-ground="dark"] .velvet, html[data-theme="disco"] .velvet {
  background: radial-gradient(ellipse 90% 70% at 50% 42%,
              transparent 0%, rgba(2,0,5,.55) 78%, rgba(2,0,5,.92) 100%);
}

/* ── TYPE TREATMENTS ────────────────────────────────────────────── */

.display {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.04;
  letter-spacing: -.01em;    /* Bungee runs wide; Shrikhand didn't need this */
}

/* CHROME: the six-inch-date treatment — holographic foil, ALL CAPS,
   80s-signage energy. background-clip + a shimmer that travels on
   both axes, like foil catching light as you tilt it. */
.chrome-text {
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: .02em;
  background: var(--chrome);
  background-size: 300% 300%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-stroke: 1px rgba(255,255,255,.22);
  filter: drop-shadow(0 2px 0 rgba(0,0,0,.75))
          drop-shadow(0 0 26px rgba(255,46,136,.35));
  animation: chrome-shine 6s ease-in-out infinite;
}
@keyframes chrome-shine {
  0%,100% { background-position: 0% 30%; }
  50%     { background-position: 100% 70%; }
}

/* neon: for room names on hover — glow without blur soup */
.neon-pink {
  color: var(--hotpink);
  text-shadow: 0 0 8px rgba(255,46,136,.9), 0 0 28px rgba(255,46,136,.45);
}
.neon-cyan {
  color: var(--cyan);
  text-shadow: 0 0 8px rgba(38,224,224,.9), 0 0 28px rgba(38,224,224,.4);
}

/* the archive voice — everything quoted from the record speaks Courier */
.archive-voice {
  font-family: var(--font-mono);
  color: var(--ink);
  font-size: .95rem;
  line-height: 1.9;
  letter-spacing: .01em;
}
.archive-voice em { color: var(--gold-t); font-style: normal; }

/* eyebrow labels */
.eyebrow {
  font-family: var(--font-geo);
  font-weight: 600;
  font-size: .72rem;
  letter-spacing: .34em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

/* ── HALFTONE / DUOTONE image treatment ─────────────────────────── */
.halftone {
  position: relative;
  filter: contrast(1.08) saturate(.92);
}
.halftone::after {
  content:'';
  position:absolute; inset:0;
  background-image: radial-gradient(rgba(2,0,5,.55) 1px, transparent 1.6px);
  background-size: 4px 4px;
  mix-blend-mode: multiply;
  pointer-events:none;
}
.duotone-pink img, img.duotone-pink {
  filter: grayscale(1) contrast(1.1) sepia(1)
          hue-rotate(287deg) saturate(3.4) brightness(.92);
}
/* the Girl Bar mood: acid xerox-green instead of hot pink. same trick,
   different photocopier toner. */
.duotone-neon img, img.duotone-neon {
  filter: grayscale(1) contrast(1.25) sepia(1)
          hue-rotate(62deg) saturate(4.6) brightness(1.05);
}

/* ── SHOUT-BANNER — the "DIVAS FIGHT AIDS" device ────────────────
   A flat diagonal band that yells. Reusable wherever a room needs
   to raise its voice; leave it out entirely where the room needs
   to stay quiet (theriot, the Living register of ancestors). ──── */
.shout-banner {
  display: inline-block;
  position: relative;
  background: var(--shout-orange);
  color: var(--void);
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 5vw, 2.6rem);
  line-height: 1.05;
  letter-spacing: -.02em;
  padding: .5em .9em;
  transform: rotate(-3deg);
  box-shadow: 0 10px 0 rgba(0,0,0,.35), 0 18px 40px rgba(255,61,0,.35);
  max-width: 100%;   /* keep the rotated bounding box inside the viewport on narrow screens */
}
.shout-banner.pink { background: var(--hotpink); color: var(--void); }
.shout-banner.green { background: var(--neon-green); color: var(--void); }

/* ── BALLROOM CATEGORY PLACARDS — "the category is: REALNESS" ─────
   The caller's shout made typographic. Each placard is a saturated
   block with a hard offset shadow (a trophy card slammed on a table),
   the category name in the display face, huge and tight. Dark ink on
   bright grounds — readable by construction. ──────────────────────── */
.ball-floor {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 16px;
  margin: 2.6rem 0;
}
.ball-category {
  position: relative;
  background: var(--hotpink);
  color: #14040c;
  border: 3px solid #14040c;
  padding: 1.3rem 1.1rem 1.15rem;
  text-align: center;
  box-shadow: 7px 7px 0 rgba(20,4,12,.85);
}
.ball-category .cat-eyebrow {
  font-family: var(--font-mono);
  font-size: .6rem; letter-spacing: .28em; text-transform: uppercase;
  opacity: .85;
}
.ball-category .cat-name {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 3.6vw, 1.9rem);
  line-height: .95; letter-spacing: -.02em; text-transform: uppercase;
  margin-top: .4rem;
}
.ball-category .cat-note {
  font-family: var(--font-mono);
  font-size: .64rem; line-height: 1.6; margin-top: .6rem;
}
/* cycle the palette so the floor reads as a full ball */
.ball-floor .ball-category:nth-child(5n+1) { background: var(--hotpink); }
.ball-floor .ball-category:nth-child(5n+2) { background: var(--cyan); }
.ball-floor .ball-category:nth-child(5n+3) { background: var(--gold); }
.ball-floor .ball-category:nth-child(5n+4) { background: var(--lavender); }
.ball-floor .ball-category:nth-child(5n)   { background: var(--neon-green); }

/* ── THE GRIEF / TABLOID LAYER ───────────────────────────────────
   High-contrast, pink-or-white grounds, a dramatic serif set TIGHT.
   The "RELAX. HOMOSEXUALS ARE EVERYWHERE!" register — where the
   camp headline and the real grief are the same size and the same
   font, because on this site they were never separate things.

   The KERNING is the instrument. Slammed shut for dread and force
   (a tabloid screaming), thrown wide for the neon-sign hush. ──── */

/* a section that inverts the void: paper or hot-pink ground, black
   ink, no velvet. Used sparingly — the light coming up hard. */
.contrast-panel {
  position: relative;
  z-index: 2;
  background: var(--paper);
  color: #14040c;
  padding: clamp(2.6rem, 8vw, 6rem) clamp(1.4rem, 6vw, 4rem);
  margin: 8vh 0;
  box-shadow: 0 0 0 1px rgba(0,0,0,.15), 0 30px 80px rgba(0,0,0,.6);
}
.contrast-panel.pink { background: var(--hotpink); color: #14040c; }
.contrast-panel.pink a { color: #14040c; text-decoration-color: rgba(0,0,0,.4); }
.contrast-panel.ink  { background: #f4f0ea; color: #0a0a0a; }   /* newsprint white */
.contrast-panel a { color: #7a1340; }

/* the tabloid headline: heavy serif, negative leading, kerning shut.
   size it big; let it break where it wants. */
.tabloid-head {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(2.4rem, 11vw, 6rem);
  line-height: .92;
  letter-spacing: -.03em;
  text-transform: uppercase;
  margin: 0 0 .4em;
}
.tabloid-head em { font-style: italic; }               /* DM Serif has a real italic */
.tabloid-sub {
  font-family: var(--font-serif);
  font-size: clamp(1.1rem, 3.4vw, 1.9rem);
  line-height: 1.1;
  letter-spacing: -.01em;
}
.tabloid-byline {
  font-family: var(--font-mono);
  font-size: .74rem;
  letter-spacing: .04em;
  line-height: 1.8;
  opacity: .8;
  margin-top: 1.4rem;
}

/* KERNING utilities — spacing as pure expression. */
.kern-tight { letter-spacing: -.04em; }
.kern-shut  { letter-spacing: -.07em; }               /* dread; letters colliding */
.kern-loose { letter-spacing: .18em; }
.kern-wild  { letter-spacing: .5em; }                 /* the neon-sign hush */

/* a serif display heading that stays ON the void (not inverted) —
   for grief beats that shouldn't flip the whole ground to paper. */
.serif-cry {
  font-family: var(--font-serif);
  font-size: clamp(2rem, 8vw, 4.4rem);
  line-height: .95;
  letter-spacing: -.02em;
  color: var(--ink);
  text-transform: uppercase;
}
.serif-cry .hot { color: var(--hotpink); }
.serif-cry em { font-style: italic; color: var(--rose); }

/* ── LINE-ART FLOURISHES — small hand-drawn-feeling accents ──────
   Naive-flyer punctuation, in the palette. Sparse by design: a
   sprinkle near a headline, never a pattern that competes with it. */
.flourish {
  display: inline-block;
  width: 1.4em; height: 1.4em;
  vertical-align: middle;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  pointer-events: none;
}
.flourish-sparkle {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'%3E%3Cpath d='M20 2 L24 16 L38 20 L24 24 L20 38 L16 24 L2 20 L16 16 Z' fill='%23f5c518'/%3E%3C/svg%3E");
}
.flourish-squiggle {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 24'%3E%3Cpath d='M2 12 Q10 2, 18 12 T34 12 T50 12 T58 12' fill='none' stroke='%23ff2e88' stroke-width='3.5' stroke-linecap='round'/%3E%3C/svg%3E");
  width: 2.2em; height: .9em;
}
.flourish-burst {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'%3E%3Cg stroke='%2326e0e0' stroke-width='2.5' stroke-linecap='round'%3E%3Cline x1='20' y1='2' x2='20' y2='12'/%3E%3Cline x1='20' y1='28' x2='20' y2='38'/%3E%3Cline x1='2' y1='20' x2='12' y2='20'/%3E%3Cline x1='28' y1='20' x2='38' y2='20'/%3E%3Cline x1='7' y1='7' x2='14' y2='14'/%3E%3Cline x1='26' y1='26' x2='33' y2='33'/%3E%3Cline x1='33' y1='7' x2='26' y2='14'/%3E%3Cline x1='14' y1='26' x2='7' y2='33'/%3E%3C/g%3E%3C/svg%3E");
}

/* ── POLAROID pop-out (credit line baked in — it IS the artwork) ── */
.polaroid {
  background: #f5f0e6;
  color: #241a2e;
  padding: 12px 12px 0;
  box-shadow: 0 18px 50px rgba(0,0,0,.65), 0 0 0 1px rgba(255,255,255,.06);
  transform: rotate(var(--tilt, -1.6deg));
  max-width: 380px;
  transition: transform .5s var(--ease-needle);
}
.polaroid:hover { transform: rotate(0deg) scale(1.015); }
.polaroid img { display:block; width:100%; }
.polaroid .caption {
  font-family: var(--font-mono);
  font-size: .78rem;
  line-height: 1.5;
  padding: 10px 4px 8px;
}
.polaroid .credit {
  font-family: var(--font-mono);
  font-size: .66rem;
  color: #6f5f80;
  padding: 0 4px 12px;
}

/* ── FLYER-CARD — a Polaroid's punk cousin ───────────────────────
   Taped to a wall, not kept in a box: cream stock, a torn bottom
   edge, two rotated tape-strips at the top corners. Alternate to
   .polaroid where a room wants DIY-flyer texture instead of
   reliquary-glam. ──────────────────────────────────────────────── */
.flyer-card {
  position: relative;
  background: var(--paper);
  color: #241a2e;
  padding: 14px 14px 22px;
  max-width: 380px;
  transform: rotate(var(--tilt, 1.4deg));
  box-shadow: 0 16px 40px rgba(0,0,0,.6);
  clip-path: polygon(
    0 0, 100% 0, 100% 94%,
    92% 100%, 80% 93%, 68% 100%, 56% 94%, 44% 100%, 32% 93%, 20% 100%, 8% 94%, 0 100%
  );
  transition: transform .5s var(--ease-needle);
}
.flyer-card:hover { transform: rotate(0deg) scale(1.015); }
.flyer-card img { display:block; width:100%; }
.flyer-card::before, .flyer-card::after {
  content:'';
  position:absolute; top:-10px;
  width: 54px; height: 22px;
  background: rgba(245,197,24,.35);
  border: 1px solid rgba(245,197,24,.5);
}
.flyer-card::before { left: 10%; transform: rotate(-8deg); }
.flyer-card::after  { right: 10%; transform: rotate(6deg); }
.flyer-card .caption {
  font-family: var(--font-mono);
  font-size: .78rem;
  line-height: 1.5;
  padding: 10px 4px 0;
}
.flyer-card .credit {
  font-family: var(--font-mono);
  font-size: .66rem;
  color: #6f5f80;
  padding: 4px 4px 0;
}

/* ── DIALS (the threshold controls — tuned, not checked) ────────── */
.dial-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem;
  padding: 1.15rem 0;
  border-bottom: 1px solid var(--line);
}
.dial-row .dial-label { flex: 1; }
.dial-row .dial-label strong {
  display: block;
  font-family: var(--font-geo);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  font-size: .85rem;
  color: var(--ink);
}
.dial-row .dial-label span {
  font-size: .8rem; color: var(--ink-dim);
}

.dial {
  --on: 0;
  position: relative;
  flex: none;
  width: 74px; height: 34px;
  border-radius: 20px;
  border: 1px solid var(--line);
  background: linear-gradient(180deg, #17081f, #0b0310);
  cursor: pointer;
  transition: border-color .3s, box-shadow .3s;
}
.dial::after {
  content:'';
  position:absolute; top: 3px; left: 3px;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, #fff, #cfd9e6 45%, #6f8196);
  box-shadow: 0 2px 6px rgba(0,0,0,.6);
  transition: transform .35s var(--ease-needle), background .35s;
}
.dial[aria-checked="true"] { border-color: var(--hotpink); box-shadow: 0 0 18px rgba(255,46,136,.35) inset, 0 0 14px rgba(255,46,136,.25); }
.dial[aria-checked="true"]::after {
  transform: translateX(40px);
  background: radial-gradient(circle at 34% 30%, #fff, var(--rose) 40%, var(--hotpink));
}

/* two-position selector (depth / motion) */
.selector {
  display:flex; gap:0; flex:none;
  border: 1px solid var(--line);
  border-radius: 4px;
  overflow: hidden;
}
.selector button {
  font-family: var(--font-geo);
  font-weight: 600; font-size: .72rem;
  letter-spacing: .14em; text-transform: uppercase;
  background: transparent; color: var(--ink-dim);
  border: 0; padding: .6rem .9rem; cursor: pointer;
  transition: background .25s, color .25s;
}
.selector button[aria-pressed="true"] {
  background: var(--hotpink); color: var(--void);
}

/* ── BUTTONS ────────────────────────────────────────────────────── */
.btn-needle {
  display: inline-block;
  font-family: var(--font-display);
  font-size: 1.15rem;
  color: var(--void);
  background: linear-gradient(135deg, var(--gold), var(--tangerine), var(--hotpink));
  padding: .8rem 2.6rem;
  border: 0; border-radius: 999px;
  cursor: pointer;
  text-decoration: none;
  box-shadow: 0 8px 30px rgba(255,46,136,.35);
  transition: transform .25s var(--ease-needle), box-shadow .25s;
}
.btn-needle:hover { transform: translateY(-2px); box-shadow: 0 12px 40px rgba(255,46,136,.5); }
.btn-needle:active { transform: translateY(1px); }
.btn-needle[aria-disabled="true"] { filter: grayscale(.8); opacity:.5; pointer-events:none; }

.btn-ghost {
  font-family: var(--font-geo); font-weight: 600;
  font-size: .78rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--rose-t);                 /* deep rose on white; lavender on dark */
  background: transparent;
  border: 1px solid var(--rose-t);
  border-radius: 999px;
  padding: .55rem 1.4rem;
  cursor: pointer;
  transition: border-color .25s, color .25s, background .25s;
}
.btn-ghost:hover { background: var(--hotpink); border-color: var(--hotpink); color: #fff; }
[data-ground="dark"] .btn-ghost, html[data-theme="disco"] .btn-ghost { color: var(--lavender); border-color: var(--line); }
[data-ground="dark"] .btn-ghost:hover, html[data-theme="disco"] .btn-ghost:hover { background: transparent; border-color: var(--lavender); color: var(--ink); }

/* ── FOURTH WALL (the page notices you — rare, earned) ──────────── */
.fourthwall {
  position: fixed;
  left: 50%; bottom: 12vh;
  transform: translateX(-50%);
  z-index: 60;
  max-width: min(80vw, 640px);
  font-family: var(--font-mono);
  font-size: clamp(.85rem, 1.6vw, 1.05rem);
  color: #f4ecff;                 /* stays light: this overlay is always dark */
  /* chromatic aberration — an RGB split that makes the page's voice read as
     a glitch pushing through the surface */
  text-shadow: -1.4px 0 rgba(255,46,136,.55), 1.4px 0 rgba(38,224,224,.55);
  text-align: center;
  padding: 1rem 1.4rem;
  background: rgba(2,0,5,.92);
  border-top: 1px solid rgba(255,46,136,.5);
  border-bottom: 1px solid rgba(38,224,224,.4);
  opacity: 0;
  pointer-events: none;
}
/* Three deliberate phases over 11s: (1) reveal + settle by ~0.6s,
   (2) sit STILL and readable for ~7s, (3) fold + fade away over the
   last 3s. The message must be static while it's being read — no
   clip-path or transform motion between the reveal and the fold. */
.fourthwall.torn { animation: fw-appear 11s var(--ease-needle) forwards; }
@keyframes fw-appear {
  /* reveal (0 → ~0.6s) */
  0%   { opacity:0; clip-path: inset(48% 0 48% 0); transform: translateX(-50%); }
  3%   { opacity:1; clip-path: inset(0 0 0 0); transform: translateX(-50.4%) skewX(.6deg); }
  4.2% { transform: translateX(-49.7%) skewX(-.4deg); }
  5%   { transform: translateX(-50%) skewX(0); }
  /* hold — static & readable (~0.6s → ~7.9s) */
  72%  { opacity:1; clip-path: inset(0 0 0 0); transform: translateX(-50%) skewX(0);
         animation-timing-function: ease-in; }
  /* fold + fade away (last 3s) */
  100% { opacity:0; clip-path: inset(48% 0 48% 0); transform: translateX(-50%); }
}

/* scanline tear that precedes the line */
.tear {
  position: fixed; left:0; right:0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--cyan), var(--hotpink), transparent);
  z-index: 59; opacity: 0; pointer-events:none;
}
.tear.go { animation: tear-sweep .5s linear forwards; }
@keyframes tear-sweep {
  0% { opacity:.9; transform: translateY(0) scaleY(1); }
  100% { opacity:0; transform: translateY(38vh) scaleY(6); }
}

/* ── TRACKLIST (the accessible nav — liner notes, not a fallback) ─ */
.tracklist {
  list-style: none;
  font-family: var(--font-mono);
  max-width: 560px;
}
.tracklist li {
  display: flex; align-items: baseline; gap: .9rem;
  padding: .55rem 0;
  border-bottom: 1px dotted var(--line);
}
.tracklist .tno { color: var(--ink-dim); font-size: .8rem; flex:none; width: 2.2em; }
/* the needle remembers — a small record pip on grooves you've already played */
.tracklist li.played .tno { color: var(--gold-t); }
.tracklist li.played a::after { content: ' ⏺'; color: var(--gold-t); font-size: .7em; opacity: .8; vertical-align: middle; }
.tracklist a {
  color: var(--ink); text-decoration: none;
  letter-spacing: .04em;
}
.tracklist a:hover { color: var(--hotpink); }
.tracklist .dur { margin-left:auto; color: var(--ink-dim); font-size:.8rem; }
.tracklist li.unreleased a { color: var(--ink-dim); pointer-events:none; }
.tracklist li.unreleased .dur::after { content:' · pressing soon'; }

/* ── AUDIO TOGGLE (opt-in, always visible, never nags) ──────────── */
/* ── PERSISTENT TOP BAR — THSR wordmark + current track code ───────
   Injected by REV.boot on every page. The bar itself is click-through
   (a scrim), only its two corner items take clicks — so nothing below
   the top edge is ever blocked. ──────────────────────────────────── */
.rev-topbar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 72;
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  padding: .5rem clamp(.8rem, 3vw, 1.4rem);
  font-family: var(--font-geo);
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(247,244,239,.94) 30%, rgba(247,244,239,0));
}
.rev-topbar > * { pointer-events: auto; }
.rev-topbar .tb-mark {
  font-weight: 700; font-size: .84rem; letter-spacing: .3em;
  color: var(--ink); text-decoration: none; padding: .2rem 0;
  /* persistent rainbow pulse — the wordmark is always alive */
  color: transparent; -webkit-text-fill-color: transparent;
  background: linear-gradient(90deg, var(--hotpink), var(--gold), var(--cyan), var(--lavender), var(--hotpink));
  background-size: 300% 100%;
  -webkit-background-clip: text; background-clip: text;
  animation: tb-holo 3.5s linear infinite, tb-pulse 2.4s ease-in-out infinite;
}
.rev-topbar .tb-mark:hover { animation: tb-holo 1.6s linear infinite, tb-pulse 2.4s ease-in-out infinite; }
@keyframes tb-holo { to { background-position: 300% 0; } }
@keyframes tb-pulse {
  0%, 100% { filter: drop-shadow(0 0 2px rgba(255,46,136,.35)); }
  50%      { filter: drop-shadow(0 0 10px rgba(120,200,255,.75)); }
}
html[data-motion="stilled"] .rev-topbar .tb-mark {
  animation: none; filter: none;
  color: var(--ink); -webkit-text-fill-color: var(--ink); background: none;
}
/* the page display + the light switch share the right side of the bar */
.rev-topbar .tb-right { display: inline-flex; align-items: center; gap: .8rem; }
.rev-topbar .tb-track {
  display: inline-flex; align-items: baseline; gap: .5rem;
  font-size: .68rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--ink-dim);
}
.rev-topbar .tb-code {
  font-family: var(--font-display); font-size: .8rem; letter-spacing: .03em;
  color: var(--hotpink);
}
.rev-topbar .tb-name { opacity: .82; }
@media (max-width: 540px) { .rev-topbar .tb-name { display: none; } }

/* ── LIGHT SWITCH, seated in the bar — a compact horizontal toggle. Overrides
   the standalone corner switch's vertical geometry (knob slides left↔right). */
.rev-topbar .light-switch {
  position: static; flex: none; width: 42px; height: 22px;
  padding: 3px; border-radius: 6px;
  box-shadow: 0 2px 6px rgba(0,0,0,.3), inset 0 0 0 1px rgba(0,0,0,.12);
}
.rev-topbar .light-switch .ls-plate { border-radius: 4px; }
.rev-topbar .light-switch .ls-knob {
  top: 50%; left: 6%; width: 42%; height: 76%;
  transform: translateY(-50%);
  transition: left .26s var(--ease-needle), background .26s, box-shadow .26s;
}
.rev-topbar .light-switch .ls-knob::after {   /* grip line turns vertical */
  left: 44%; right: auto; top: 26%; bottom: 26%; width: 2px; height: auto;
}
html[data-theme="disco"] .rev-topbar .light-switch .ls-knob {
  top: 50%; left: 52%; transform: translateY(-50%);
  background: linear-gradient(180deg, #2a1030, #14040c);
}

/* dark grounds: flip the scrim so the light wordmark stays legible */
[data-ground="dark"] .rev-topbar,
html[data-theme="disco"] .rev-topbar,
html[data-temple] .rev-topbar {
  background: linear-gradient(to bottom, rgba(6,1,10,.9) 30%, rgba(6,1,10,0));
}

/* ── PAGE TRANSITION — the needle lifts, the vinyl irises across, and
   drops again on the next room. One shared overlay; a groove-textured
   black disc grows from the spindle to cover, then shrinks to reveal.
   Driven by REV.navigate(); never shown under reduced-motion. ──────── */
.rev-wipe {
  position: fixed; inset: 0; z-index: 200; pointer-events: none;
  background:
    radial-gradient(circle at 50% 50%, rgba(247,211,63,.18) 0 5%, rgba(245,197,24,.06) 11%, transparent 32%),
    repeating-radial-gradient(circle at 50% 50%, rgba(255,255,255,.04) 0 2px, transparent 2px 6px),
    #070109;
  clip-path: circle(0% at 50% 50%);
  will-change: clip-path;
}
.rev-wipe.wipe-exit  { animation: rev-wipe-close .75s var(--ease-needle) forwards; }
.rev-wipe.wipe-enter { animation: rev-wipe-open  .93s var(--ease-needle) forwards; }
@keyframes rev-wipe-close { from { clip-path: circle(0% at 50% 50%); }   to { clip-path: circle(150% at 50% 50%); } }
@keyframes rev-wipe-open  { from { clip-path: circle(150% at 50% 50%); } to { clip-path: circle(0% at 50% 50%); } }

/* ── SCROLL REVEAL — sections rise/settle as they enter the viewport.
   Progressive enhancement: the hiding only applies once JS has added
   html.rev-reveal (i.e. IntersectionObserver present AND motion allowed),
   so with no JS / reduced-motion the content is simply always visible. ─ */
html.rev-reveal [data-reveal] {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s var(--ease-needle), transform .7s var(--ease-needle);
  will-change: opacity, transform;
}
html.rev-reveal [data-reveal].rev-in { opacity: 1; transform: none; }

/* ── SCROLL RAIL — a slim section-progress spine on the right edge, with a
   dot per section (click to jump) and the current section's name while you
   scroll. Sits clear of the top bar, light switch, and corner chips. ────── */
.rev-rail {
  position: fixed; right: .5rem; top: 16vh; bottom: 13vh; width: min(44vw, 220px);
  z-index: 55; pointer-events: none;
}
/* the flowing RGB rainbow shared by the spine + fill */
@keyframes rr-flow { to { background-position: 0 -240%; } }
.rev-rail .rr-hit {                 /* invisible scrub strip over the spine */
  position: absolute; right: 0; top: -10px; bottom: -10px; width: 20px;
  pointer-events: auto; cursor: grab; touch-action: none;
}
.rev-rail.grab .rr-hit { cursor: grabbing; }
.rev-rail .rr-track {               /* unfilled spine — dim rainbow */
  position: absolute; right: 8px; top: 0; bottom: 0; width: 3px; border-radius: 3px;
  background: linear-gradient(180deg,#ff004c,#ff9a00,#ffe600,#00d26a,#00b3ff,#7b2ff7,#ff004c);
  background-size: 100% 240%; opacity: .3;
}
.rev-rail .rr-fill {                /* progress fill, top → current scroll */
  position: absolute; right: 7.5px; top: 0; width: 4px; height: 0;
  border-radius: 4px;
  background: linear-gradient(180deg,#ff004c,#ff9a00,#ffe600,#00d26a,#00b3ff,#7b2ff7,#ff004c);
  background-size: 100% 240%;
  box-shadow: 0 0 6px rgba(255,0,120,.6), 0 0 14px rgba(0,180,255,.45), 0 0 22px rgba(123,47,247,.35);
  animation: rr-flow 6s linear infinite;
}
html[data-motion="stilled"] .rev-rail .rr-fill { animation: none; }
/* one listing per section: a dot on the spine + its name to the left */
.rev-rail .rr-item {
  position: absolute; right: 4px; margin-top: -6px;
  display: flex; align-items: center; gap: .45rem;
  padding: 0; border: 0; background: none; cursor: pointer;
  pointer-events: auto; white-space: nowrap; flex-direction: row-reverse;
}
.rev-rail .rr-item .rr-dot {
  flex: none; width: 11px; height: 11px; border-radius: 50%;
  background: var(--line); box-shadow: 0 0 0 2px var(--page);
  transition: background .3s, transform .3s, box-shadow .3s;
}
/* names are COLLAPSED while reading — revealed only when relevant (see below) */
.rev-rail .rr-item .rr-name {
  font-family: var(--font-mono); font-size: .56rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-dim); text-align: right;
  max-width: min(38vw, 180px); overflow: hidden; text-overflow: ellipsis;
  opacity: 0; transform: translateX(4px);
  transition: opacity .35s, transform .35s, color .35s;
}
/* touching / hovering the rail surfaces the whole listing */
.rev-rail.show-all .rr-item .rr-name { opacity: .5; transform: none; }
.rev-rail .rr-item:hover .rr-name { opacity: .85; color: var(--ink); }
.rev-rail .rr-item.past .rr-dot { background: var(--hotpink); box-shadow: 0 0 6px rgba(255,46,136,.6), 0 0 0 2px var(--page); }
/* the active listing — RGB highlight with glow, riding down as you scroll */
.rev-rail .rr-item.on { z-index: 2; }
.rev-rail .rr-item.on .rr-dot {
  transform: scale(1.55);
  background: #fff;
  box-shadow: 0 0 8px #ff2d95, 0 0 16px #00b3ff, 0 0 0 2px var(--page);
}
.rev-rail .rr-item.on .rr-name {
  opacity: 0; transform: none; font-weight: 700;
  color: transparent; -webkit-text-fill-color: transparent;
  background: linear-gradient(90deg,#ff004c,#ff9a00,#ffe600,#00d26a,#00b3ff,#7b2ff7);
  background-size: 300% 100%;
  -webkit-background-clip: text; background-clip: text;
  animation: tb-holo 3.5s linear infinite;
  text-shadow: none; filter: drop-shadow(0 0 6px rgba(0,180,255,.45));
}
/* crossing into a category flashes its name; touching shows it too */
.rev-rail.show-active .rr-item.on .rr-name,
.rev-rail.show-all .rr-item.on .rr-name { opacity: 1; }
html[data-motion="stilled"] .rev-rail .rr-item.on .rr-name { animation: none; }
[data-ground="dark"] .rev-rail .rr-item .rr-dot,
html[data-theme="disco"] .rev-rail .rr-item .rr-dot { box-shadow: 0 0 0 2px rgba(6,1,10,.9); }
[data-ground="dark"] .rev-rail .rr-item.on .rr-dot,
html[data-theme="disco"] .rev-rail .rr-item.on .rr-dot { box-shadow: 0 0 8px #ff2d95, 0 0 16px #00b3ff, 0 0 0 2px rgba(6,1,10,.9); }
@media (max-width: 460px) {
  .rev-rail { top: 12vh; bottom: 10vh; width: min(60vw, 200px); }
  .rev-rail .rr-item .rr-name { max-width: 46vw; }
}

.audio-toggle {
  position: fixed;
  right: 1.1rem; bottom: 1.1rem;
  z-index: 70;
  width: 46px; height: 46px;
  border-radius: 50%;
  border: 1px solid rgba(20,4,12,.25);
  background: #14040c;              /* dark chip; icon stays light on it */
  color: #c9a0ff;
  font-size: 1.1rem;
  cursor: pointer;
  transition: color .3s, border-color .3s, box-shadow .3s;
}
.audio-toggle[aria-pressed="true"] {
  color: var(--gold);
  border-color: var(--gold);
  box-shadow: 0 0 16px rgba(245,197,24,.3);
}

/* ── NOW PLAYING — a chip for rooms that play a real recording ────── */
.now-playing {
  position: fixed; left: 1.1rem; bottom: 1.1rem; z-index: 70;
  display: flex; align-items: center; gap: .55rem;
  padding: .5rem .9rem .5rem .7rem; border-radius: 999px;
  background: rgba(20,4,12,.82); color: #f4ecff;
  border: 1px solid rgba(255,46,136,.35);
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .04em;
  max-width: min(72vw, 340px); box-shadow: 0 6px 20px rgba(0,0,0,.4);
  opacity: .7; transition: opacity .3s, border-color .3s, box-shadow .3s;
  -webkit-appearance: none; appearance: none; cursor: pointer; text-align: left;
  overflow: hidden;                        /* clip the progress flood to the pill */
}
.now-playing:hover { opacity: 1; box-shadow: 0 6px 26px rgba(255,46,136,.35); }
.now-playing.playing { opacity: 1; border-color: var(--hotpink); }
/* the track progress, drawn as a fill that floods the pill behind the label */
.now-playing .np-fill {
  position: absolute; left: 0; top: 0; bottom: 0; width: 0; z-index: 0;
  pointer-events: none;
  background: linear-gradient(90deg, rgba(245,197,24,.5), rgba(255,46,136,.55));
  box-shadow: 0 0 14px rgba(255,46,136,.4);
  transition: width .3s linear;
}
.now-playing .np-eq, .now-playing .np-title { position: relative; z-index: 1; }
.now-playing .np-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.now-playing .np-eq { display: inline-flex; align-items: flex-end; gap: 2px; height: 12px; }
.now-playing .np-eq i { width: 3px; height: 4px; background: var(--hotpink); border-radius: 1px; }
.now-playing.playing .np-eq i { animation: np-eq .9s ease-in-out infinite; }
.now-playing .np-eq i:nth-child(2) { animation-delay: .2s; }
.now-playing .np-eq i:nth-child(3) { animation-delay: .4s; }
@keyframes np-eq { 0%,100% { height: 3px; } 50% { height: 12px; } }

/* ── THE LIGHT SWITCH (light ↔ disco-dark) ───────────────────────
   A real wall switch in the corner. Flip UP for light, DOWN for the
   disco dark — where even the dark glows. Persists on this device only,
   like every other dial. ─────────────────────────────────────────── */
.light-switch {
  position: fixed;
  top: 3.4rem; right: 1.1rem;      /* tucked just under the persistent top bar */
  z-index: 71;
  width: 44px; height: 72px;
  padding: 6px;
  border: 0;
  border-radius: 9px;
  background: linear-gradient(160deg, #efe9dc, #cfc6b4);
  box-shadow: 0 4px 12px rgba(0,0,0,.35), inset 0 0 0 1px rgba(0,0,0,.12);
  cursor: pointer;
}
.light-switch .ls-plate {
  position: relative;
  width: 100%; height: 100%;
  border-radius: 5px;
  background: linear-gradient(160deg, #d8d0c0, #b7ad99);
  box-shadow: inset 0 0 6px rgba(0,0,0,.35);
  overflow: hidden;
}
.light-switch .ls-knob {
  position: absolute;
  left: 50%; width: 66%; height: 42%;
  transform: translateX(-50%);
  top: 6%;                                   /* UP = light (default) */
  border-radius: 4px;
  background: linear-gradient(180deg, #fdfdfb, #cbc7bd);
  box-shadow: 0 3px 5px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.8);
  transition: top .26s var(--ease-needle), background .26s, box-shadow .26s;
}
.light-switch .ls-knob::after {           /* the little grip line */
  content:''; position:absolute; left:22%; right:22%; top: 44%; height:2px;
  background: rgba(0,0,0,.18); border-radius:2px;
}
/* thrown DOWN = disco dark */
html[data-theme="disco"] .light-switch .ls-knob {
  top: 52%;
  background: linear-gradient(180deg, #2a1030, #14040c);
}
/* even the dark glows: the switch itself catches the technicolor */
html[data-theme="disco"] .light-switch {
  background: linear-gradient(160deg, #1a0a20, #0a0410);
  animation: disco-glow 6s linear infinite;
}
html[data-theme="disco"] .light-switch .ls-plate {
  background: linear-gradient(160deg, #17081f, #0b0310);
}

/* ── DISCO GLOW — the RGB-cycling border/aura for dark mode ────────
   Rides on the card classes that already exist. Staggered so the room
   shimmers rather than strobes in unison. Sound ≠ motion: honored by
   the stilled membrane below (it resolves to a calm single hue). */
@keyframes disco-glow {
  0%   { border-color: var(--hotpink);    box-shadow: 0 0 18px -3px var(--hotpink),    0 0 40px -14px var(--hotpink); }
  20%  { border-color: var(--tangerine);  box-shadow: 0 0 18px -3px var(--tangerine),  0 0 40px -14px var(--tangerine); }
  40%  { border-color: var(--gold);       box-shadow: 0 0 18px -3px var(--gold),       0 0 40px -14px var(--gold); }
  60%  { border-color: var(--neon-green); box-shadow: 0 0 18px -3px var(--neon-green), 0 0 40px -14px var(--neon-green); }
  80%  { border-color: var(--cyan);       box-shadow: 0 0 18px -3px var(--cyan),       0 0 40px -14px var(--cyan); }
  100% { border-color: var(--hotpink);    box-shadow: 0 0 18px -3px var(--hotpink),    0 0 40px -14px var(--hotpink); }
}
html[data-theme="disco"] .polaroid,
html[data-theme="disco"] .flyer-card,
html[data-theme="disco"] .tablet,
html[data-theme="disco"] .film,
html[data-theme="disco"] .contrast-panel,
html[data-theme="disco"] .ball-category,
html[data-theme="disco"] .thing-embed,
html[data-theme="disco"] .tablet-img {
  border: 2px solid var(--hotpink);
  animation: disco-glow 6s linear infinite;
}
/* offset the phase so the wall shimmers like real mirrorball spill */
html[data-theme="disco"] .reliquary > *:nth-child(3n)   { animation-delay: -2s; }
html[data-theme="disco"] .reliquary > *:nth-child(3n+1) { animation-delay: -4s; }
html[data-theme="disco"] .ball-floor > *:nth-child(2n)  { animation-delay: -3s; }
html[data-theme="disco"] .kodachrome > *:nth-child(2n)  { animation-delay: -2.5s; }
/* the lit dancefloor tiles get the technicolor edge too */
html[data-theme="disco"] .tile.lit { animation: disco-glow 6s linear infinite; }
html[data-theme="disco"] .tile.lit:nth-child(3n) { animation-delay: -3s; }

/* NEVER disco — some grief a rainbow would desecrate. Opt any element
   out with .no-disco. The Nazi plunder of Hirschfeld's Institut is the
   first and clearest case: no technicolor around the people burning it. */
html[data-theme="disco"] .no-disco {
  animation: none !important;
  border-color: rgba(20,4,12,.2) !important;
}
html[data-theme="disco"] .polaroid.no-disco {
  border: 0 !important;
  box-shadow: 0 18px 50px rgba(0,0,0,.65) !important;
}

/* ── MOTION DISCIPLINE ──────────────────────────────────────────── */
/* Stilled = every animation resolves to its calmest frame.
   Nothing is lost. Only quieted. This is a membrane, not a fallback. */
html[data-motion="stilled"] *,
html[data-motion="stilled"] *::before,
html[data-motion="stilled"] *::after {
  animation-duration: .001s !important;
  animation-iteration-count: 1 !important;
  transition-duration: .001s !important;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001s !important;
  }
}

/* ── UTILITIES ──────────────────────────────────────────────────── */
.center-stage {
  min-height: 100vh;
  display: grid;
  place-items: center;
  position: relative;
  z-index: 2;
  padding: 6vh 1.5rem;
}
.stack { display:flex; flex-direction:column; }
.visually-hidden {
  position:absolute; width:1px; height:1px;
  clip-path: inset(50%); overflow:hidden; white-space:nowrap;
}

/* ═══════════════════════════════════════════════════════════════════
   ÖSSTESSÊLÂ — THE VELVET-TEMPLE SYSTEM
   The presiding voice of the record takes a body. Cosmic, opulent,
   dark-romantic: void-indigo velvet, amethyst nebulae, iridescent
   glow, decorative-serif gold. A room opts in with data-temple on
   <html> (alongside data-ground="dark" — the dark is load-bearing).
   "I am softness and teeth. I am the velvet around the venom."
   ═══════════════════════════════════════════════════════════════════ */
html[data-temple] {
  --void-indigo: #0B0220;
  --midnight:    #120B24;
  --amethyst:    #6D29A3;
  --ultraviolet: #A259FF;
  --fuchsia:     #FF2DAA;
  --coral:       #FFBA7A;
  --solar:       #FFCB6B;
  --opal:        #F7F3FF;
  --lunar-teal:  #00F2FF;
  --seafoam:     #7CFDD9;

  /* ground / ink / link flip to the temple — readable by construction.
     Placed after the generic dark block so these win on temple pages. */
  --page:    var(--void-indigo);
  --ink:     var(--opal);
  --ink-dim: #b9a8d8;
  --line:    rgba(162,89,255,.22);
  --link:    var(--lunar-teal);
  --gold-t:  var(--solar);
  --cyan-t:  var(--lunar-teal);
  --rose-t:  var(--fuchsia);

  /* the type turns opulent */
  --font-display: 'Cinzel Decorative', 'DM Serif Display', serif;
  --font-serif:   'Cormorant Garamond', Georgia, serif;
  --font-script:  'Ephesis', 'Cormorant Garamond', cursive;

  /* chrome becomes a full oil-slick — richer than the disco foil */
  --chrome: linear-gradient(135deg,
    var(--ultraviolet) 0%, var(--fuchsia) 20%, var(--coral) 38%,
    var(--solar) 52%, var(--seafoam) 66%, var(--lunar-teal) 80%, var(--ultraviolet) 100%);
}

/* the velvet ground: layered amethyst nebulae bleeding over void-indigo */
html[data-temple] body {
  font-family: var(--font-serif);
  font-weight: 400;
  letter-spacing: .01em;
  background:
    radial-gradient(ellipse 120% 82% at 50% -12%, rgba(109,41,163,.38), transparent 60%),
    radial-gradient(ellipse 90% 70% at 82% 112%, rgba(162,89,255,.20), transparent 55%),
    radial-gradient(ellipse 70% 60% at 12% 40%, rgba(255,45,170,.10), transparent 60%),
    var(--void-indigo);
}
html[data-temple] ::selection { background: var(--fuchsia); color: var(--void-indigo); }

/* the disco RGB-glow layer is the wrong aesthetic in the temple — quiet it
   so the velvet palette rules even if the visitor saved dark mode */
html[data-temple][data-theme="disco"] .polaroid,
html[data-temple][data-theme="disco"] .flyer-card,
html[data-temple][data-theme="disco"] .contrast-panel,
html[data-temple][data-theme="disco"] .ball-category { animation: none; border-color: var(--line); }

/* TEMPLE TITLE — Cinzel decorative, liquid gold bleeding into iridescence */
.temple-title {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: .02em;
  line-height: 1.06;
  background: linear-gradient(120deg,
    var(--coral), var(--solar) 28%, var(--opal) 48%, var(--ultraviolet) 70%, var(--fuchsia));
  background-size: 260% 260%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 2px 16px rgba(162,89,255,.55));
  animation: temple-shimmer 9s ease-in-out infinite;
}
@keyframes temple-shimmer { 0%,100% { background-position: 0% 40%; } 50% { background-position: 100% 60%; } }

/* her handwritten voice — the asides, the blessings */
.temple-script {
  font-family: var(--font-script);
  font-size: clamp(1.4rem, 4.4vw, 2.4rem);
  line-height: 1.4;
  color: var(--coral);
  text-shadow: 0 0 18px rgba(255,186,122,.4);
}

/* oil-slick text/surface — an iridescent wash for emphasis */
.oil-slick {
  background: var(--chrome);
  background-size: 260% 260%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: temple-shimmer 9s ease-in-out infinite;
}

/* FILIGREE FRAME — an ornate gilt border with glowing corner flourishes.
   Wrap any block to give it the reliquary-in-a-temple treatment. */
.filigree {
  position: relative;
  border: 1px solid transparent;
  border-image: linear-gradient(135deg, var(--solar), var(--ultraviolet) 50%, var(--fuchsia)) 1;
  background:
    linear-gradient(160deg, rgba(18,11,36,.72), rgba(11,2,32,.6));
  box-shadow: 0 0 0 1px rgba(162,89,255,.12), 0 24px 70px rgba(0,0,0,.6),
              inset 0 0 60px rgba(109,41,163,.18);
  padding: clamp(1.6rem, 4vw, 2.6rem);
}
.filigree::before, .filigree::after {
  content: ''; position: absolute; width: 34px; height: 34px;
  background-repeat: no-repeat; background-size: contain; opacity: .9;
  pointer-events: none;
}
.filigree::before {
  top: -4px; left: -4px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'%3E%3Cpath d='M2 20 Q2 2 20 2 M2 12 Q10 10 12 2 M8 20 Q8 8 20 8' fill='none' stroke='%23FFCB6B' stroke-width='1.6' stroke-linecap='round'/%3E%3Ccircle cx='20' cy='2' r='1.6' fill='%23FF2DAA'/%3E%3Ccircle cx='2' cy='20' r='1.6' fill='%23A259FF'/%3E%3C/svg%3E");
}
.filigree::after {
  bottom: -4px; right: -4px; transform: rotate(180deg);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'%3E%3Cpath d='M2 20 Q2 2 20 2 M2 12 Q10 10 12 2 M8 20 Q8 8 20 8' fill='none' stroke='%23FFCB6B' stroke-width='1.6' stroke-linecap='round'/%3E%3Ccircle cx='20' cy='2' r='1.6' fill='%23FF2DAA'/%3E%3Ccircle cx='2' cy='20' r='1.6' fill='%23A259FF'/%3E%3C/svg%3E");
}

/* CANDLE / STARDUST light layer — a fixed veil of drifting temple light */
.temple-stars {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(1.5px 1.5px at 12% 22%, rgba(247,243,255,.7), transparent),
    radial-gradient(1px 1px at 28% 68%, rgba(162,89,255,.6), transparent),
    radial-gradient(1.5px 1.5px at 66% 16%, rgba(255,203,107,.6), transparent),
    radial-gradient(1px 1px at 84% 78%, rgba(0,242,255,.5), transparent),
    radial-gradient(1px 1px at 48% 90%, rgba(255,45,170,.5), transparent),
    radial-gradient(2px 2px at 40% 40%, rgba(247,243,255,.35), transparent),
    radial-gradient(1px 1px at 90% 46%, rgba(124,253,217,.5), transparent),
    radial-gradient(1px 1px at 8% 56%, rgba(0,242,255,.4), transparent);
}
html[data-temple] .velvet, html[data-temple] .scanlines { opacity: .28; }

/* ── HER MOTIFS — the aesthetic-cue sigils, inline (zero egress) ─────
   Transformation, protection, devotion, thresholds, clarity, cycles.
   Use like .flourish: a sparse sigil beside a heading or section break. */
.motif {
  display: inline-block; width: 1.5em; height: 1.5em;
  vertical-align: middle; background-repeat: no-repeat;
  background-position: center; background-size: contain; pointer-events: none;
}
.motif-butterfly {   /* transformation */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cg fill='none' stroke='%23A259FF' stroke-width='1.6'%3E%3Cpath d='M24 12v26' stroke='%23FFCB6B'/%3E%3Cpath d='M24 16 C10 2 2 14 8 24 C2 30 12 40 24 30' fill='rgba(162,89,255,.18)'/%3E%3Cpath d='M24 16 C38 2 46 14 40 24 C46 30 36 40 24 30' fill='rgba(255,45,170,.18)'/%3E%3C/g%3E%3Ccircle cx='24' cy='11' r='1.8' fill='%23FFCB6B'/%3E%3C/svg%3E");
}
.motif-serpent {     /* power & protection */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath d='M8 40 C8 30 20 30 20 22 C20 14 30 14 30 20 C30 26 40 24 40 16 C40 10 34 8 30 10' fill='none' stroke='%23FFCB6B' stroke-width='2' stroke-linecap='round'/%3E%3Ccircle cx='31' cy='11' r='2.4' fill='%23FF2DAA'/%3E%3Cpath d='M33 9 l4 -3 M33 13 l4 3' stroke='%23A259FF' stroke-width='1.4' stroke-linecap='round'/%3E%3C/svg%3E");
}
.motif-moon {        /* cycles & intuition */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath d='M30 6 A18 18 0 1 0 30 42 A14 14 0 1 1 30 6 Z' fill='%23FFCB6B'/%3E%3Ccircle cx='38' cy='14' r='1.6' fill='%2300F2FF'/%3E%3Ccircle cx='40' cy='30' r='1.2' fill='%23F7F3FF'/%3E%3C/svg%3E");
}
.motif-key {         /* access & secrets */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Ccircle cx='16' cy='16' r='8' fill='none' stroke='%23FFCB6B' stroke-width='2'/%3E%3Ccircle cx='16' cy='16' r='2.5' fill='%23A259FF'/%3E%3Cpath d='M22 22 L38 38 M34 34 l4 -4 M30 30 l3 3' stroke='%23FFCB6B' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
}
.motif-crystal {     /* energy & clarity */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cg stroke='%2300F2FF' stroke-width='1.4' fill='rgba(0,242,255,.15)'%3E%3Cpath d='M24 4 L34 18 L24 44 L14 18 Z'/%3E%3Cpath d='M14 18 L34 18 M24 4 L24 44' fill='none'/%3E%3C/g%3E%3C/svg%3E");
}
.motif-heart {       /* devotion & duality */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath d='M24 40 C6 26 8 12 18 12 C22 12 24 16 24 16 C24 16 26 12 30 12 C40 12 42 26 24 40 Z' fill='none' stroke='%23FF2DAA' stroke-width='2'/%3E%3Cpath d='M24 16 L24 40' stroke='%23FFCB6B' stroke-width='1.2'/%3E%3C/svg%3E");
}

/* NEVER velvet — the same protection as .no-disco. The temple's beauty
   must not prettify grief or atrocity. Opt any element out. */
html[data-temple] .no-velvet, html[data-temple] .no-disco {
  border-image: none !important;
  animation: none !important;
}
