/* Companion Sites — public site styles.
 * Driven entirely by the --site-* custom properties siteRender.js sets on
 * .site-root, so the same sheet serves every theme preset.
 *
 * Typography: self-hosted Newsreader (display serif) + Geist (sans) with
 * system fallbacks. CSP default-src 'self' permits same-origin woff2 —
 * the font files live in ./fonts/. If they 404 the stacks fall back to
 * Georgia / -apple-system and nothing breaks.
 *
 * Craft rules this sheet follows (docs/companion/website-editor-plan.md):
 * tinted neutrals, one accent hue, hairlines not cards, 0–4px radii, no
 * decorative shadows/gradients (the hero scrim is photographic, not
 * decorative), left-aligned prose at a 62ch measure, media wider than text,
 * compositor-only motion behind prefers-reduced-motion. */

/* --- Faces ---------------------------------------------------------------- */

@font-face {
  font-family: 'Newsreader';
  src: url('fonts/newsreader-var.woff2') format('woff2');
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Newsreader';
  src: url('fonts/newsreader-italic-var.woff2') format('woff2');
  font-weight: 200 800;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Geist';
  src: url('fonts/geist-var.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* Per-theme display faces — fetched lazily on first use, so each page pays
   for exactly one. */
@font-face { font-family: 'Syne'; src: url('fonts/syne-var.woff2') format('woff2'); font-weight: 400 800; font-style: normal; font-display: swap; }
@font-face { font-family: 'Fraunces'; src: url('fonts/fraunces-var.woff2') format('woff2'); font-weight: 300 900; font-style: normal; font-display: swap; }
@font-face { font-family: 'Instrument Serif'; src: url('fonts/instrument-serif-400.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Instrument Serif'; src: url('fonts/instrument-serif-italic-400.woff2') format('woff2'); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: 'Archivo'; src: url('fonts/archivo-var.woff2') format('woff2'); font-weight: 100 900; font-stretch: 62% 125%; font-style: normal; font-display: swap; }
@font-face { font-family: 'Space Mono'; src: url('fonts/space-mono-400.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Bricolage Grotesque'; src: url('fonts/bricolage-var.woff2') format('woff2'); font-weight: 200 800; font-style: normal; font-display: swap; }
@font-face { font-family: 'Unbounded'; src: url('fonts/unbounded-var.woff2') format('woff2'); font-weight: 200 900; font-style: normal; font-display: swap; }

/* --- Root ------------------------------------------------------------------ */

.site-root {
  min-height: 100vh;
  background: var(--site-bg, #0F0E0C);
  color: var(--site-text, #F4F1EA);
  font-family: var(--site-font-body, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Contain sideways overflow WITHOUT becoming a scroll container.
     `overflow-x: hidden` computes overflow-y to `auto`, which makes this
     element the nearest scrollport — and a sticky header inside a scrollport
     that never scrolls simply never sticks. `clip` clips without that side
     effect. The `hidden` line stays first as the fallback for engines that
     don't know `clip`: they lose stickiness, not layout. */
  overflow-x: hidden;
  overflow-x: clip;
}

.site-root a:focus-visible,
.site-root button:focus-visible,
.site-root input:focus-visible {
  outline: 2px solid var(--site-accent, #E9B44C);
  outline-offset: 2px;
}

/* --- Layout / rhythm --------------------------------------------------------
 * No universal hairlines between sections — rhythm comes from spacing that
 * varies by section type, not from ruled boxes. */

.site-section {
  /* Vertical rhythm is ONE expression, composed from two variables:
     --site-pad   the section's own base measure (theme + type set it)
     --site-density  a document-level multiplier the author controls
     Nothing else in this file sets padding-block on a section — everything
     sets --site-pad instead, so density scales the whole page uniformly and
     a section can never fall out of the system. */
  padding-block: calc(var(--site-pad, clamp(3.25rem, 8vw, 6rem)) * var(--site-density, 1));
  padding-inline: 0;
  --site-pad: clamp(3.25rem, 8vw, 6rem);
}

/* --- Density -----------------------------------------------------------------
 * The difference between a website and a slide deck is mostly this number.
 * 'airy' is the original measure: one idea per screenful, which suits a single
 * poster-like page and reads as a deck once a page has ten sections. 'balanced'
 * is the default because most pages are not posters. */
.site-root { --site-density: 0.62; }
.site-root[data-density="airy"] { --site-density: 1; }
.site-root[data-density="balanced"] { --site-density: 0.62; }
.site-root[data-density="compact"] { --site-density: 0.42; }

/* --- Seams -------------------------------------------------------------------
 * Two adjacent sections on the SAME background are one continuous band, so
 * paying full padding on both sides of an invisible boundary is what produced
 * 288px of nothing between two paragraphs. Where the background DOES change,
 * the full measure stays — a colour band needs room to read as deliberate.
 * The renderer stamps these by comparing resolved backgrounds. */
.site-section.site-seam-above { padding-top: calc(var(--site-pad) * var(--site-density, 1) * 0.36); }
.site-section.site-seam-below { padding-bottom: calc(var(--site-pad) * var(--site-density, 1) * 0.36); }

.site-section-inner {
  max-width: 680px;
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 5vw, 2rem);
}

/* Media sections run wider than prose — the measure contrast is deliberate. */
.site-section-gallery .site-section-inner { max-width: 1000px; }
.site-section-video .site-section-inner { max-width: 960px; }

/* Per-section content width override (data-width). High specificity via the
   attribute so it wins over the type-specific widths above. */
.site-section[data-width="narrow"] > .site-section-inner { max-width: 620px; }
.site-section[data-width="wide"] > .site-section-inner { max-width: 1120px; }
.site-section[data-width="full"] > .site-section-inner { max-width: none; }

/* Quieter bands for the conversion/utility sections. */
.site-section-signup,
.site-section-contact {
  --site-pad: clamp(2.75rem, 6vw, 4.25rem);
}

.site-section-signup {
  background: var(--site-surface, #171613);
}

/* Section headings are eyebrow labels — small tracked caps, the ONLY
 * uppercase on the page (plus the show-date column). Display type belongs
 * to the hero. */
/* A section heading is a heading, not a filing label.
 *
 * These were 0.78rem tracked caps in the secondary colour on every theme —
 * the single loudest "template" tell on the page, because no section ever
 * announced itself and the hero was the only real type in the document.
 * Display face, display scale, primary colour. Each theme's distinguishing
 * device (paper's italic, garden's rule, ember's numbering, neon's arrow) is
 * preserved below at the new scale.
 *
 * The old treatment is one setting away: layout.headings = 'label'. */
.site-heading {
  font-family: var(--site-font-display, var(--site-font-head, inherit));
  --fs-base: clamp(1.65rem, 1.05rem + 2.1vw, 2.75rem);
  font-size: calc(var(--fs-base) * var(--site-display-scale, 1));
  font-weight: 600;
  letter-spacing: -0.02em;
  text-transform: none;
  line-height: 1.08;
  color: var(--site-text);
  margin: 0 0 clamp(1.5rem, 3vw, 2.25rem);
  text-wrap: balance;
}

/* Serif display faces carry their own weight — 600 on Fraunces or Newsreader
   is a different animal from 600 on a grotesque. */
[data-headfont="serif"] .site-heading {
  font-weight: 500;
  letter-spacing: -0.01em;
}

/* The original label treatment, kept whole for documents that want the
   austere version. */
.site-root[data-headings="label"] .site-heading {
  font-family: var(--site-font-body, inherit);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--site-text-2, #A9A498);
  margin: 0 0 clamp(1.25rem, 3vw, 1.75rem);
}

/* An item count beside a display heading wants to read as a quiet annotation,
   not as part of the title. */
.site-heading .site-heading-count { font-size: 0.5em; vertical-align: 0.35em; }
.site-root[data-headings="label"] .site-heading .site-heading-count {
  font-size: inherit;
  vertical-align: baseline;
}

.site-blurb {
  color: var(--site-text-2, #A9A498);
  font-size: 1.02rem;
  margin: 0 0 1.25rem;
  max-width: 56ch;
}

/* --- Hero -------------------------------------------------------------------
 * Typographic: oversized display type anchored low in a color field.
 * Cover (has image): full-bleed photo behind the type, scrimmed into the
 * page background so any upload sits in-palette. */

.site-section-hero {
  display: flex;
  align-items: flex-end;
  min-height: min(72svh, 640px);
  padding-inline: 0;
  padding-block:
    calc(clamp(5rem, 14vw, 9rem) * var(--site-density, 1))
    calc(clamp(2.75rem, 7vw, 4.5rem) * var(--site-density, 1));
}

.site-section-hero .site-section-inner {
  width: 100%;
}

.site-align-center .site-section-inner { text-align: center; }
.site-align-left .site-section-inner { text-align: left; }

.site-hero-cover {
  position: relative;
  min-height: min(86svh, 760px);
}

.site-hero-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Slight desaturation settles any upload into the palette. */
  filter: saturate(0.85) contrast(1.02);
}

.site-hero-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 30%, var(--site-bg, #0F0E0C) 97%);
}

.site-hero-cover .site-section-inner {
  position: relative;
  z-index: 1;
}

.site-hero-heading {
  font-family: var(--site-font-display, var(--site-font-head, inherit));
  --fs-base: clamp(2.6rem, 1.4rem + 6.5vw, 5.5rem);
  font-size: calc(var(--fs-base) * var(--site-display-scale, 1));
  line-height: 1.02;
  margin: 0;
  overflow-wrap: break-word;
}

/* Serif display: real mid weights + optical sizing — never synthesized 800,
 * never sans-grade negative tracking (Georgia fallback smears otherwise). */
[data-headfont="serif"] .site-hero-heading {
  font-weight: 500;
  letter-spacing: -0.015em;
  font-variation-settings: 'opsz' 72;
}

[data-headfont="sans"] .site-hero-heading {
  font-weight: 700;
  letter-spacing: -0.02em;
}

.site-hero-tagline {
  color: var(--site-text-2, #A9A498);
  font-size: clamp(1.05rem, 2.6vw, 1.25rem);
  line-height: 1.5;
  margin: clamp(0.9rem, 2.5vw, 1.25rem) auto 0;
  max-width: 44ch;
}

.site-hero-cover .site-hero-tagline { color: var(--site-text, #F4F1EA); opacity: 0.82; }

.site-align-left .site-hero-tagline { margin-left: 0; }

/* Eyebrow — the one tracked-caps line above the display name. */
.site-hero-eyebrow {
  font-family: var(--site-font-body, inherit);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--site-accent, #E9B44C);
  margin: 0 0 clamp(0.9rem, 2.5vw, 1.25rem);
}

/* One action, ink-filled — the signup button's language at hero scale. */
.site-hero-cta {
  display: inline-block;
  margin-top: clamp(1.4rem, 3.5vw, 2rem);
  padding: 12px 26px;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--site-bg, #0F0E0C);
  background: var(--site-text, #F4F1EA);
  border-radius: 2px;
  text-decoration: none;
  transition: background-color 0.15s ease;
}
.site-hero-cta:hover { background: var(--site-accent, #E9B44C); }

/* --- About --------------------------------------------------------------- */

.site-about-img {
  display: block;
  width: 100%;
  max-height: 480px;
  object-fit: cover;
  border-radius: 4px;
  margin: 0 0 1.5rem;
}

.site-body p {
  margin: 0 0 1.1em;
  max-width: 62ch;
  font-size: 1.05rem;
  line-height: 1.7;
}

.site-body p:last-child { margin-bottom: 0; }

/* First paragraph reads as a lede. */
.site-section-about .site-body p:first-child {
  font-size: 1.18rem;
  line-height: 1.6;
}

/* Side-by-side about — image column beside the prose. */
.site-about-split {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
}
.site-about-split .site-about-img { margin: 0; max-height: none; }
/* Prose in a split column is set flush left whatever the theme does with a
   full-width paragraph. Centred rag in a narrow column is unreadable. */
.site-root .site-about-split .site-body,
.site-root .site-about-split .site-body p {
  text-align: left;
  margin-left: 0;
  margin-right: 0;
  max-width: none;
}
.site-about-side-right .site-about-img { order: 2; }

/* --- Quote ------------------------------------------------------------------ */

.site-quote { margin: 0; }

.site-quote-text {
  font-family: var(--site-font-display, var(--site-font-head, inherit));
  --fs-base: clamp(1.35rem, 0.9rem + 2.2vw, 1.9rem);
  font-size: calc(var(--fs-base) * var(--site-display-scale, 1));
  line-height: 1.35;
  margin: 0;
  max-width: 34ch;
  text-wrap: balance;
}

[data-headfont="serif"] .site-quote-text {
  font-style: italic;
  font-weight: 450;
  font-variation-settings: 'opsz' 36;
}
[data-headfont="sans"] .site-quote-text { font-weight: 500; letter-spacing: -0.01em; }

.site-quote-attr {
  display: block;
  margin-top: 1rem;
  font-family: var(--site-font-body, inherit);
  font-size: 0.92rem;
  color: var(--site-text-2, #A9A498);
  text-decoration: none;
}
a.site-quote-attr-link { border-bottom: 1px solid var(--site-border, rgba(244, 241, 234, 0.1)); transition: color 0.15s ease; }
a.site-quote-attr-link:hover { color: var(--site-accent, #E9B44C); }

/* --- Testimonials ------------------------------------------------------------
 * quote's plural sibling — same voice per theme, at list scale. */

.site-testimonials { display: grid; gap: clamp(1.75rem, 4vw, 2.5rem); }
.site-testimonials-rows { grid-template-columns: 1fr; }
.site-testimonials-grid { grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); }

.site-testimonial { margin: 0; }

.site-testimonial-text {
  font-family: var(--site-font-display, var(--site-font-head, inherit));
  font-size: clamp(1.1rem, 0.95rem + 0.8vw, 1.35rem);
  line-height: 1.45;
  margin: 0;
  max-width: 44ch;
  text-wrap: balance;
}

[data-headfont="serif"] .site-testimonial-text {
  font-style: italic;
  font-weight: 450;
  font-variation-settings: 'opsz' 24;
}
[data-headfont="sans"] .site-testimonial-text { font-weight: 500; letter-spacing: -0.005em; }

.site-testimonial-attr {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-top: 0.7rem;
  font-family: var(--site-font-body, inherit);
  font-size: 0.88rem;
  color: var(--site-text-2, #A9A498);
  text-decoration: none;
}
.site-testimonial-name { font-weight: 600; }
a.site-testimonial-attr-link { transition: color 0.15s ease; }
a.site-testimonial-attr-link:hover { color: var(--site-accent, #E9B44C); }

/* --- Statement --------------------------------------------------------------
 * A display band: one oversized line on the surface tint. */

.site-section-statement {
  background: var(--site-surface, #171613);
  --site-pad: clamp(4rem, 10vw, 7rem);
}

.site-statement-text {
  font-family: var(--site-font-display, var(--site-font-head, inherit));
  --fs-base: clamp(1.7rem, 1rem + 3.4vw, 3rem);
  font-size: calc(var(--fs-base) * var(--site-display-scale, 1));
  line-height: 1.18;
  margin: 0;
  max-width: 26ch;
  text-wrap: balance;
  overflow-wrap: break-word;
}

[data-headfont="serif"] .site-statement-text {
  font-weight: 500;
  letter-spacing: -0.01em;
  font-variation-settings: 'opsz' 60;
}
[data-headfont="sans"] .site-statement-text { font-weight: 700; letter-spacing: -0.02em; }

/* --- FAQ ---------------------------------------------------------------------
 * Native <details>/<summary> — zero JS, keyboard-accessible for free. */

.site-faq { display: flex; flex-direction: column; }

.site-faq-item { border-top: 1px solid var(--site-border, rgba(244, 241, 234, 0.1)); }
.site-faq-item:last-child { border-bottom: 1px solid var(--site-border, rgba(244, 241, 234, 0.1)); }

.site-faq-q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 0;
  cursor: pointer;
  list-style: none;
  font-weight: 600;
  font-size: 1.02rem;
  line-height: 1.4;
  transition: color 0.15s ease;
}
.site-faq-q::-webkit-details-marker { display: none; }
.site-faq-q:hover { color: var(--site-accent, #E9B44C); }

/* Plus → rotated-plus marker, drawn from currentColor bars. */
.site-faq-marker { position: relative; flex: 0 0 auto; width: 12px; height: 12px; }
.site-faq-marker::before, .site-faq-marker::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  background: currentColor;
}
.site-faq-marker::before { width: 12px; height: 1.5px; }
.site-faq-marker::after { width: 1.5px; height: 12px; transition: transform 0.2s ease; }
.site-faq-item[open] .site-faq-marker::after { transform: scaleY(0); }

.site-faq-a { padding: 0 0 20px; max-width: 62ch; }
.site-faq-a p { margin: 0 0 1em; font-size: 1rem; line-height: 1.65; color: var(--site-text-2, #A9A498); }
.site-faq-a p:last-child { margin-bottom: 0; }

/* --- Countdown ---------------------------------------------------------------
 * Display-scale digits; the label reads like an eyebrow. */

.site-count-label {
  font-family: var(--site-font-body, inherit);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--site-accent, #E9B44C);
  margin: 0 0 1.1rem;
}

.site-countdown { display: flex; gap: clamp(1.5rem, 5vw, 3rem); }

.site-count-unit { display: flex; flex-direction: column; gap: 6px; }

.site-count-num {
  font-family: var(--site-font-display, var(--site-font-head, inherit));
  font-size: clamp(2.4rem, 1.2rem + 5.5vw, 5rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
[data-headfont="serif"] .site-count-num { font-weight: 500; font-variation-settings: 'opsz' 72; }
[data-headfont="sans"] .site-count-num { font-weight: 700; letter-spacing: -0.02em; }

.site-count-unit-label {
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--site-text-2, #A9A498);
}

.site-count-done {
  font-family: var(--site-font-display, var(--site-font-head, inherit));
  font-size: clamp(1.7rem, 1rem + 3vw, 2.8rem);
  line-height: 1.2;
  margin: 0;
}

/* --- Embeds (music / video) ------------------------------------------------ */

.site-embeds {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

/* 16:9 frames (YouTube/Vimeo) keep a quiet card; fixed-height players
 * (Spotify/SoundCloud/Bandcamp) draw their own chrome and render bare. */
.site-embed {
  border-radius: 4px;
  overflow: hidden;
}

.site-embed-ratio {
  position: relative;
  padding-top: 56.25%; /* 16:9 */
  background: var(--site-surface, #171613);
  border: 1px solid var(--site-border, rgba(244, 241, 234, 0.1));
}

.site-embed-bare {
  background: transparent;
  border: 0;
}

.site-embed-frame {
  display: block;
  width: 100%;
  border: 0;
}

.site-embed-ratio .site-embed-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* --- Gallery --------------------------------------------------------------- */

.site-gallery-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.site-gallery-strip {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  padding-bottom: 8px;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}

.site-gallery-item {
  margin: 0;
}

.site-gallery-strip .site-gallery-item {
  flex: 0 0 auto;
  scroll-snap-align: start;
}

/* Photography is never boxed in borders. Grid stays 1:1 (curated); the strip
 * keeps each image's natural aspect at a shared height — an editorial
 * filmstrip, not a row of crops. */
.site-gallery-img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 2px;
  background: var(--site-surface, #171613);
}

.site-gallery-strip .site-gallery-img {
  width: auto;
  height: min(46vw, 320px);
  aspect-ratio: auto;
}

/* Aspect control — grid layout only; the strip stays natural-height. */
.site-gallery-grid.site-gallery-a-portrait .site-gallery-img { aspect-ratio: 4 / 5; }
.site-gallery-grid.site-gallery-a-landscape .site-gallery-img { aspect-ratio: 3 / 2; }
.site-gallery-grid.site-gallery-a-natural .site-gallery-img { aspect-ratio: auto; }

.site-gallery-caption {
  margin-top: 6px;
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--site-text-2, #A9A498);
}
.site-gallery-strip .site-gallery-caption { max-width: 320px; }

/* --- Shows ---------------------------------------------------------------- */

.site-shows {
  display: flex;
  flex-direction: column;
}

.site-show-row {
  display: flex;
  align-items: baseline;
  gap: 18px;
  padding: 16px 0;
}

.site-show-row + .site-show-row {
  border-top: 1px solid var(--site-border, rgba(244, 241, 234, 0.1));
}

.site-show-date {
  flex: 0 0 auto;
  min-width: 5.5em;
  white-space: nowrap;
  font-weight: 600;
  font-size: 0.85rem;
  color: var(--site-accent, #E9B44C);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.site-show-place { flex: 1 1 auto; min-width: 0; }

.site-show-venue {
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1.35;
}

.site-show-city {
  color: var(--site-text-2, #A9A498);
  font-size: 0.92rem;
}

.site-show-tickets {
  flex: 0 0 auto;
  align-self: center;
  color: var(--site-accent, #E9B44C);
  border: 1px solid var(--site-accent, #E9B44C);
  border-radius: 2px;
  padding: 7px 16px;
  font-size: 0.88rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.site-show-tickets:hover {
  background: var(--site-accent, #E9B44C);
  color: var(--site-bg, #0F0E0C);
}

.site-show-note {
  color: var(--site-text-2, #A9A498);
  font-size: 0.85rem;
  margin-top: 2px;
}

/* Sold out / cancelled — quiet uppercase tag where Tickets would sit. */
.site-show-flag {
  flex: 0 0 auto;
  align-self: center;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--site-text-2, #A9A498);
  white-space: nowrap;
}

/* History dims; a cancelled show also strikes its venue. */
.site-show-past { opacity: 0.45; }
.site-show-cancelled .site-show-venue { text-decoration: line-through; }

/* --- Links ------------------------------------------------------------------
 * A typographic index: hairline rows, label left, destination right. */

.site-links {
  display: flex;
  flex-direction: column;
  border-bottom: 1px solid var(--site-border, rgba(244, 241, 234, 0.1));
}

.site-link-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 15px 2px;
  border-top: 1px solid var(--site-border, rgba(244, 241, 234, 0.1));
  color: var(--site-text, #F4F1EA);
  text-decoration: none;
  transition: background-color 0.15s ease;
}

.site-link-row:hover {
  background: var(--site-surface, #171613);
}

.site-link-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.site-link-label {
  font-weight: 500;
  font-size: 1.02rem;
  min-width: 0;
  overflow-wrap: anywhere;
}

.site-link-sub {
  font-size: 0.85rem;
  color: var(--site-text-2, #A9A498);
  overflow-wrap: anywhere;
}

.site-link-meta {
  flex: 0 0 auto;
  display: flex;
  align-items: baseline;
  gap: 8px;
  color: var(--site-text-2, #A9A498);
  font-size: 0.85rem;
}

.site-link-arrow {
  color: var(--site-accent, #E9B44C);
  transition: transform 0.15s ease;
}

.site-link-row:hover .site-link-arrow {
  transform: translate(2px, -1px);
}

/* --- Signup ------------------------------------------------------------------
 * One quiet line, not a card: hairline-underline input + ink button. */

.site-signup-form {
  display: flex;
  gap: 14px;
  max-width: 460px;
  align-items: flex-end;
}

.site-signup-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 10px 2px;
  font: inherit;
  font-size: 1rem;
  color: var(--site-text, #F4F1EA);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--site-border, rgba(244, 241, 234, 0.1));
  border-radius: 0;
  outline: none;
  transition: border-color 0.15s ease;
}

.site-signup-input:focus {
  border-bottom-color: var(--site-accent, #E9B44C);
}

.site-signup-input::placeholder {
  color: var(--site-text-2, #A9A498);
  opacity: 0.7;
}

.site-signup-btn {
  flex: 0 0 auto;
  padding: 11px 22px;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--site-bg, #0F0E0C);
  background: var(--site-text, #F4F1EA);
  border: 0;
  border-radius: 2px;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.site-signup-btn:hover:not(:disabled) { background: var(--site-accent, #E9B44C); }
.site-signup-btn:disabled, .site-signup-input:disabled { opacity: 0.55; cursor: default; }

/* Honeypot — visually hidden, still in the accessibility-invisible DOM. */
.site-hp {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; border: 0; margin: -1px;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

.site-form-msg {
  margin: 12px 0 0;
  font-size: 0.95rem;
  min-height: 1.4em;
}

.site-form-msg-ok { color: var(--site-accent, #E9B44C); font-weight: 600; }
.site-form-msg-error { color: var(--site-danger, #E08D7A); }

/* --- Contact ---------------------------------------------------------------- */

.site-contact-email {
  display: inline-block;
  font-family: var(--site-font-display, var(--site-font-head, inherit));
  font-size: clamp(1.3rem, 3.2vw, 1.7rem);
  font-weight: 500;
  color: var(--site-text, #F4F1EA);
  text-decoration: none;
  border-bottom: 1px solid var(--site-accent, #E9B44C);
  padding-bottom: 2px;
  overflow-wrap: anywhere;
  transition: color 0.15s ease;
}

.site-contact-email:hover { color: var(--site-accent, #E9B44C); }

/* The contact FORM variant (props.form). Fields reuse .site-signup-input /
   .site-signup-btn so all fifteen theme identities style them for free —
   the presskit precedent. Only the column layout and the textarea's shape
   are its own. */
.site-contact-form {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
  max-width: 560px;
  margin-top: 20px;
}
.site-al-center .site-contact-form { margin-left: auto; margin-right: auto; }
.site-contact-form .site-signup-btn { align-self: flex-start; }
.site-al-center .site-contact-form .site-signup-btn { align-self: center; }
.site-contact-textarea {
  resize: vertical;
  min-height: 120px;
  line-height: 1.5;
}

/* --- Footer ---------------------------------------------------------------- */

.site-footer {
  border-top: 1px solid var(--site-border, rgba(244, 241, 234, 0.1));
  margin-top: clamp(2rem, 6vw, 4rem);
  padding: 2rem 0 2.5rem;
}

.site-footer-inner {
  max-width: 680px;
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 5vw, 2rem);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}

.site-footer-copy {
  color: var(--site-text-2, #A9A498);
  font-size: 0.85rem;
}

.site-footer-link {
  color: var(--site-text-2, #A9A498);
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-decoration: none;
  transition: color 0.15s ease;
}

.site-footer-link:hover { color: var(--site-accent, #E9B44C); }

/* --- Motion: scroll-reveal entrances ----------------------------------------
 * Each effect is its OWN @keyframes track with distinct choreography (elastic
 * pop, multi-bounce drop, pendulum swing, 3D flip/unfold, skew-glitch, mask
 * wipe) — not one tween re-timed. The site level (.site-root[data-motion])
 * only scales intensity (distance/scale/blur/duration/stagger); [data-reveal]
 * picks the track via --rv-anim; per-section instruments tune dur/delay/ease.
 * The IO (public pages only) adds .site-pre then .site-in, once. Compositor-
 * only (transform/opacity/filter/clip-path). data-motion="none" → renderer
 * never adds .site-pre; reduced-motion neutralizes everything. */

.site-root[data-motion="subtle"]     { --rv-dist: 12px; --rv-scale: .94; --rv-blur: 6px;  --rv-dur: .55s;  --rv-ease: cubic-bezier(.22,1,.36,1); --rv-step: 60ms;  }
.site-root[data-motion="standard"]   { --rv-dist: 24px; --rv-scale: .88; --rv-blur: 10px; --rv-dur: .75s;  --rv-ease: cubic-bezier(.22,1,.36,1); --rv-step: 85ms;  }
.site-root[data-motion="expressive"] { --rv-dist: 44px; --rv-scale: .80; --rv-blur: 14px; --rv-dur: .95s;  --rv-ease: cubic-bezier(.16,1,.30,1); --rv-step: 105ms; }
.site-root[data-motion="cinematic"]  { --rv-dist: 68px; --rv-scale: .70; --rv-blur: 20px; --rv-dur: 1.25s; --rv-ease: cubic-bezier(.16,1,.30,1); --rv-step: 140ms; }

/* Hidden until revealed — no transition; the keyframe track does all the work
 * (fill-mode:both holds the 0% frame before start and the 100% frame after). */
.site-pre { opacity: 0; }
.site-pre.site-in {
  animation-name: var(--rv-anim, siteRise);
  animation-duration: var(--rv-dur, .75s);
  animation-timing-function: var(--rv-tf, var(--rv-ease, ease));
  animation-delay: var(--rv-delay, 0s);
  animation-fill-mode: both;
  will-change: transform, opacity, filter;
}

/* Effect → track. up/scale are legacy aliases of rise/zoom (old docs). The
 * physical tracks (pop/bounce/swing/glitch) set --rv-tf so their multi-stage
 * choreography plays evenly instead of being crushed by an expo-out curve. */
[data-reveal="fade"]   { --rv-anim: siteFade; }
[data-reveal="rise"]   { --rv-anim: siteRise; }
[data-reveal="up"]     { --rv-anim: siteRise; }
[data-reveal="down"]   { --rv-anim: siteDrop; }
[data-reveal="left"]   { --rv-anim: siteInLeft; }
[data-reveal="right"]  { --rv-anim: siteInRight; }
[data-reveal="zoom"]   { --rv-anim: siteZoom; }
[data-reveal="scale"]  { --rv-anim: siteZoom; }
[data-reveal="pop"]    { --rv-anim: sitePop;    --rv-tf: cubic-bezier(.28,.84,.42,1); }
[data-reveal="bounce"] { --rv-anim: siteBounce; --rv-tf: linear; }
[data-reveal="flip"]   { --rv-anim: siteFlip; }
[data-reveal="swing"]  { --rv-anim: siteSwing;  --rv-tf: cubic-bezier(.28,.84,.42,1); }
[data-reveal="unfold"] { --rv-anim: siteUnfold; }
[data-reveal="blur"]   { --rv-anim: siteBlur; }
[data-reveal="wipe"]   { --rv-anim: siteWipe; }
[data-reveal="glitch"] { --rv-anim: siteGlitch; --rv-tf: cubic-bezier(.28,.84,.42,1); }

/* Per-section instruments — override the inherited --rv-*. Placed after the
 * effect tracks so an explicit easing choice wins over an effect's default. */
[data-rv-speed="slow"]   { --rv-dur: 1.1s; }
[data-rv-speed="medium"] { --rv-dur: .7s; }
[data-rv-speed="fast"]   { --rv-dur: .4s; }
[data-rv-delay="short"]  { --rv-delay: .12s; }
[data-rv-delay="medium"] { --rv-delay: .28s; }
[data-rv-delay="long"]   { --rv-delay: .5s; }
[data-rv-ease="smooth"]  { --rv-ease: cubic-bezier(.22,1,.36,1); --rv-tf: cubic-bezier(.22,1,.36,1); }
[data-rv-ease="spring"]  { --rv-ease: cubic-bezier(.34,1.56,.64,1); --rv-tf: cubic-bezier(.34,1.56,.64,1); }
[data-rv-ease="bounce"]  { --rv-ease: cubic-bezier(.42,1.9,.35,1); --rv-tf: cubic-bezier(.42,1.9,.35,1); }

/* --- Effect keyframes — each a distinct signature ------------------------- */
@keyframes siteFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes siteRise {
  from { opacity: 0; transform: translateY(var(--rv-dist)) scale(calc(1 - (1 - var(--rv-scale)) * .25)); }
  to   { opacity: 1; transform: none; }
}
@keyframes siteDrop {
  from { opacity: 0; transform: translateY(calc(-1 * var(--rv-dist))); }
  to   { opacity: 1; transform: none; }
}
@keyframes siteInLeft {
  0%   { opacity: 0; transform: translateX(calc(-1.6 * var(--rv-dist))); }
  60%  { opacity: 1; }
  100% { opacity: 1; transform: none; }
}
@keyframes siteInRight {
  0%   { opacity: 0; transform: translateX(calc(1.6 * var(--rv-dist))); }
  60%  { opacity: 1; }
  100% { opacity: 1; transform: none; }
}
@keyframes siteZoom {
  from { opacity: 0; transform: scale(var(--rv-scale)); }
  to   { opacity: 1; transform: none; }
}
/* Pop — springs up from small, overshoots, settles. */
@keyframes sitePop {
  0%   { opacity: 0; transform: scale(calc(var(--rv-scale) * .55)); }
  55%  { opacity: 1; transform: scale(1.06); }
  75%  { transform: scale(.975); }
  100% { opacity: 1; transform: scale(1); }
}
/* Bounce — drops in from above and bounces to rest. */
@keyframes siteBounce {
  0%   { opacity: 0; transform: translateY(calc(-2.2 * var(--rv-dist))); }
  45%  { opacity: 1; transform: translateY(0); }
  62%  { transform: translateY(calc(-.45 * var(--rv-dist))); }
  78%  { transform: translateY(0); }
  90%  { transform: translateY(calc(-.16 * var(--rv-dist))); }
  100% { transform: translateY(0); }
}
/* Flip — 3D card flip about its top edge. */
@keyframes siteFlip {
  0%   { opacity: 0; transform: perspective(1000px) rotateX(65deg); transform-origin: center top; }
  55%  { opacity: 1; }
  100% { opacity: 1; transform: perspective(1000px) rotateX(0); }
}
/* Swing — enters on a pendulum and settles. */
@keyframes siteSwing {
  0%   { opacity: 0; transform: translateY(calc(-.5 * var(--rv-dist))) rotate(-6deg); transform-origin: top center; }
  50%  { opacity: 1; transform: translateY(0) rotate(4deg); }
  70%  { transform: rotate(-2.4deg); }
  85%  { transform: rotate(1.4deg); }
  100% { opacity: 1; transform: rotate(0); }
}
/* Unfold — opens up from a thin folded line. */
@keyframes siteUnfold {
  0%   { opacity: 0; transform: perspective(1200px) rotateX(-82deg); transform-origin: top center; }
  60%  { opacity: 1; }
  100% { opacity: 1; transform: perspective(1200px) rotateX(0); }
}
/* Blur — resolves into focus while easing off a slight zoom. */
@keyframes siteBlur {
  0%   { opacity: 0; filter: blur(var(--rv-blur)); transform: scale(calc(1 + (1 - var(--rv-scale)) * .4)); }
  100% { opacity: 1; filter: blur(0); transform: none; }
}
/* Wipe — clip-path mask reveal, bottom to top. */
@keyframes siteWipe {
  0%   { opacity: 1; clip-path: inset(0 0 100% 0); }
  100% { opacity: 1; clip-path: inset(0 0 0 0); }
}
/* Glitch — enters sheared and snaps square through a couple of corrections. */
@keyframes siteGlitch {
  0%   { opacity: 0; transform: skewX(16deg) translateX(var(--rv-dist)); }
  40%  { opacity: 1; transform: skewX(-8deg) translateX(0); }
  70%  { transform: skewX(3deg); }
  100% { opacity: 1; transform: skewX(0); }
}

/* Stagger: the container itself holds still; its children run the same track,
 * cascaded. Child delay folds in any section-level --rv-delay. The container
 * also carries [data-reveal] (the track its children run), so it MUST opt out
 * of the section-level animation or the whole block doubles the motion. */
[data-stagger].site-pre { opacity: 1; }
[data-stagger].site-pre.site-in { animation: none; }
[data-stagger].site-pre [data-rv-child] { opacity: 0; }
[data-stagger].site-pre.site-in [data-rv-child] {
  animation-name: var(--rv-anim, siteRise);
  animation-duration: var(--rv-dur, .75s);
  animation-timing-function: var(--rv-tf, var(--rv-ease, ease));
  animation-delay: calc(var(--rv-delay, 0s) + var(--rv-i, 0) * var(--rv-step, 85ms));
  animation-fill-mode: both;
  will-change: transform, opacity, filter;
}

@media (prefers-reduced-motion: reduce) {
  .site-pre, .site-pre.site-in, [data-rv-child],
  [data-stagger].site-pre.site-in [data-rv-child] {
    opacity: 1 !important; transform: none !important;
    filter: none !important; clip-path: none !important; animation: none !important;
  }
  .site-root * { transition-duration: 0.01ms !important; }
}

/* --- Responsive ---------------------------------------------------------------- */

@media (max-width: 640px) {
  .site-gallery-grid { grid-template-columns: repeat(2, 1fr); }
  .site-signup-form { flex-direction: column; align-items: stretch; }
  .site-signup-btn { width: 100%; }
  .site-show-row { flex-wrap: wrap; row-gap: 6px; }
  .site-show-date { flex-basis: 100%; }
  .site-about-split { grid-template-columns: 1fr; }
  .site-about-side-right .site-about-img { order: 0; }
  .site-countdown { gap: 1.25rem; flex-wrap: wrap; }
}

@media (max-width: 400px) {
  .site-gallery-grid { grid-template-columns: 1fr; }
}

/* --- Work index (the portfolio section) ------------------------------------ */

/* Aligned to the standard measure. It was 800px, which nobody could see when
   headings were 12px grey labels — with display headings the 60px offset in
   the left edge is the first thing you notice, because the eye tracks the
   start of big type. Gallery and video stay wider on purpose: that measure
   contrast is about media, not about lists. */
.site-section-work .site-section-inner { max-width: 680px; }

.site-heading-count { color: var(--site-text-2, #A9A498); font-weight: 400; letter-spacing: 0; }

.site-work { display: flex; flex-direction: column; border-bottom: 1px solid var(--site-border, rgba(244,241,234,.1)); }

.site-work-rows .site-work-item {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding: 18px 2px;
  border-top: 1px solid var(--site-border, rgba(244,241,234,.1));
  color: var(--site-text, #F4F1EA);
  text-decoration: none;
  transition: background-color 0.15s ease;
}
a.site-work-item:hover { background: var(--site-surface, #171613); }

.site-work-main { flex: 1 1 auto; min-width: 0; display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.site-work-title { font-weight: 500; font-size: 1.05rem; overflow-wrap: anywhere; }
.site-work-meta { color: var(--site-text-2, #A9A498); font-size: 0.9rem; }
.site-work-year {
  flex: none; color: var(--site-accent, #E9B44C); font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}

/* Desktop hover thumbnail on rows with an image. */
.site-work-hover {
  display: none;
  position: absolute;
  right: 8%; top: 50%;
  width: 240px; height: 160px;
  object-fit: cover;
  transform: translateY(-50%) rotate(2deg);
  opacity: 0;
  pointer-events: none;
  z-index: 2;
  transition: opacity 0.2s ease;
}
@media (hover: hover) and (min-width: 800px) {
  .site-work-hover { display: block; }
  .site-work-item:hover .site-work-hover { opacity: 1; }
}

.site-work-cards { border-bottom: 0; display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(1rem, 3vw, 2rem); }
.site-work-cards .site-work-item { display: block; border-top: 0; padding: 0; }
.site-work-thumb {
  display: block; width: 100%; aspect-ratio: 3 / 2; object-fit: cover;
  border-radius: 2px; margin-bottom: 12px; background: var(--site-surface, #171613);
}
.site-work-thumb-empty { background: var(--site-surface, #171613); }
.site-work-cards .site-work-main { display: block; }
.site-work-cards .site-work-year { display: block; margin-top: 4px; }
@media (max-width: 640px) { .site-work-cards { grid-template-columns: 1fr; } }

/* --- Facts (label/value) ---------------------------------------------------- */

.site-facts-rows { display: flex; flex-direction: column; border-bottom: 1px solid var(--site-border, rgba(244,241,234,.1)); }
.site-facts-rows .site-fact-row {
  display: flex; align-items: baseline; gap: 18px;
  padding: 12px 2px;
  border-top: 1px solid var(--site-border, rgba(244,241,234,.1));
}
.site-fact-label {
  flex: none; min-width: 9em;
  font-size: 0.78rem; font-weight: 500; letter-spacing: 0.11em; text-transform: uppercase;
  color: var(--site-text-2, #A9A498);
}
.site-fact-value { font-size: 1rem; color: var(--site-text, #F4F1EA); text-decoration: none; }
a.site-fact-value { border-bottom: 1px solid var(--site-border, rgba(244,241,234,.1)); }
a.site-fact-value:hover { color: var(--site-accent, #E9B44C); }

.site-facts-grid {
  display: grid;
  /* auto-fit, not a fixed 2 — three facts get three columns instead of a
     stranded orphan on row two. min() keeps it from overflowing a phone. */
  grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr));
  gap: clamp(1.25rem, 3vw, 2rem);
  /* Bottom-align the cells so the labels sit on one line across the row even
     when a value wraps to two. Ragged tops read as intentional; a label that
     has slipped 30px below its neighbours reads as broken. */
  align-items: end;
}
.site-facts-grid .site-fact-row { display: flex; flex-direction: column-reverse; gap: 4px; }
.site-facts-grid .site-fact-value { font-family: var(--site-font-display, inherit); font-size: 1.4rem; }
@media (max-width: 640px) { .site-facts-grid { grid-template-columns: 1fr; } }

/* --- CTA (big closing contact block) ---------------------------------------- */

.site-section-cta { background: var(--site-surface, #171613); --site-pad: clamp(4rem, 10vw, 7rem); }
.site-cta-heading {
  font-family: var(--site-font-display, var(--site-font-head, inherit));
  --fs-base: clamp(1.7rem, 1rem + 3.4vw, 3rem);
  font-size: calc(var(--fs-base) * var(--site-display-scale, 1));
  line-height: 1.18; margin: 0; max-width: 26ch; text-wrap: balance;
}
.site-cta-sub { color: var(--site-text-2, #A9A498); margin: 1rem 0 0; max-width: 50ch; }
.site-cta-action {
  display: inline-block; margin-top: clamp(1.4rem, 3.5vw, 2rem); text-decoration: none;
}
.site-cta-email {
  font-family: var(--site-font-display, inherit);
  font-size: clamp(1.3rem, 3.2vw, 1.7rem);
  color: var(--site-text, #F4F1EA);
  border-bottom: 1px solid var(--site-accent, #E9B44C);
  padding-bottom: 2px; overflow-wrap: anywhere;
  transition: color 0.15s ease;
}
.site-cta-email:hover { color: var(--site-accent, #E9B44C); }
.site-cta-btn {
  padding: 12px 26px; font-size: 0.95rem; font-weight: 600;
  color: var(--site-bg, #0F0E0C); background: var(--site-text, #F4F1EA);
  border-radius: 2px; transition: background-color 0.15s ease;
}
.site-cta-btn:hover { background: var(--site-accent, #E9B44C); }

/* --- Hero status (availability) --------------------------------------------- */

.site-hero-status {
  display: inline-flex; align-items: center; gap: 8px;
  margin: clamp(1rem, 2.5vw, 1.4rem) 0 0;
  font-size: 0.85rem; color: var(--site-text-2, #A9A498);
}
.site-hero-status::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--site-accent, #E9B44C); flex: none;
  animation: site-status-pulse 2s ease-in-out infinite;
}
.site-align-center .site-hero-status { justify-content: center; }
@keyframes site-status-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
@media (prefers-reduced-motion: reduce) { .site-hero-status::before { animation: none; } }

/* --- Per-section style knobs ------------------------------------------------ */

.site-gallery-grid.site-gallery-c2 { grid-template-columns: repeat(2, 1fr); }
.site-gallery-grid.site-gallery-c4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 640px) {
  .site-gallery-grid.site-gallery-c4 { grid-template-columns: repeat(2, 1fr); }
}

.site-hero-tall { min-height: 100svh; }
/* Density shortens the DEFAULT hero; an author who explicitly picked 'tall'
   asked for a full screen and keeps it. */
.site-root[data-density="balanced"] .site-section-hero:not(.site-hero-tall):not(.site-hero-compact) { min-height: min(56svh, 520px); }
.site-root[data-density="compact"] .site-section-hero:not(.site-hero-tall):not(.site-hero-compact) { min-height: min(44svh, 420px); }
.site-hero-compact { min-height: 0; padding-block: calc(clamp(2.5rem, 6vw, 4rem) * var(--site-density, 1)); }

.site-bg-surface { background: var(--site-surface); }
/* Inverted band: swap the vars INSIDE the section — every child rule keys
   off --site-*, so the inversion cascades. --site-ink/--site-well are fixed
   copies set once on the root. */
.site-bg-inverted {
  background: var(--site-ink);
  --site-bg: var(--site-ink);
  --site-text: var(--site-well);
  --site-text-2: color-mix(in srgb, var(--site-well) 70%, var(--site-ink));
  --site-border: color-mix(in srgb, var(--site-well) 18%, transparent);
  --site-surface: color-mix(in srgb, var(--site-well) 8%, var(--site-ink));
}

/* ==========================================================================
   THEME IDENTITIES — five designs, not five palettes. Keyed off data-theme
   (stamped by siteRender) + --site-font-display. Pure additive CSS on the
   existing DOM: every published doc picks its identity up automatically.
   ========================================================================== */

/* ============ STUDIO — clean professional portfolio ============
   The neutral default: near-white, Geist, hairlines, lots of air. Leans on
   the base editorial system; these lines only sharpen the professional feel. */
[data-theme="studio"] .site-hero-heading {
  font-weight: 600; letter-spacing: -0.03em; line-height: 1.0;
  --fs-base: clamp(2.8rem, 1.4rem + 6vw, 6rem);
}
[data-theme="studio"] .site-section-hero { min-height: min(74svh, 640px); }
[data-theme="studio"] .site-hero-eyebrow { color: var(--site-text-2); }
[data-theme="studio"] .site-hero-status::before { background: #2FA84F; }
[data-theme="studio"] .site-heading { color: var(--site-text); font-weight: 600; }
.site-root[data-headings="label"][data-theme="studio"] .site-heading { color: var(--site-text-2); font-weight: 500; }
[data-theme="studio"] .site-hero-cta, [data-theme="studio"] .site-signup-btn,
[data-theme="studio"] .site-cta-btn {
  background: var(--site-text); color: var(--site-bg); border-radius: 4px;
}
[data-theme="studio"] .site-work-title { font-weight: 500; }
[data-theme="studio"] .site-work-year { color: var(--site-text-2); }
[data-theme="studio"] .site-section-cta { background: var(--site-surface); }
[data-theme="studio"] .site-cta-heading { font-weight: 600; letter-spacing: -0.02em; }
[data-theme="studio"] .site-statement-text { font-weight: 500; letter-spacing: -0.02em; }
[data-theme="studio"] .site-gallery-img, [data-theme="studio"] .site-about-img,
[data-theme="studio"] .site-work-thumb { border-radius: 4px; }

/* ============ NEON — gig-poster brutalism ============ */
[data-theme="neon"] .site-section { --site-pad: clamp(2.5rem, 6vw, 4rem); }
[data-theme="neon"] .site-section + .site-section { border-top: 3px solid var(--site-text); }
[data-theme="neon"] .site-hero-heading {
  font-weight: 850; font-stretch: 125%;
  text-transform: uppercase; letter-spacing: 0; line-height: 0.92;
  --fs-base: clamp(3rem, 1rem + 9vw, 8rem);
}
[data-theme="neon"] .site-section-hero .site-section-inner { max-width: none; }
[data-theme="neon"] .site-hero-bg { filter: grayscale(1) contrast(1.15); }
[data-theme="neon"] .site-hero-scrim {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--site-accent) 38%, transparent) 0%, var(--site-bg) 96%);
  mix-blend-mode: multiply;
}
[data-theme="neon"] .site-heading, [data-theme="neon"] .site-hero-eyebrow,
[data-theme="neon"] .site-show-date, [data-theme="neon"] .site-link-meta,
[data-theme="neon"] .site-gallery-caption, [data-theme="neon"] .site-footer-copy,
[data-theme="neon"] .site-footer-link { font-family: 'Space Mono', ui-monospace, monospace; }
[data-theme="neon"] .site-heading { text-transform: uppercase; letter-spacing: -0.01em; line-height: 0.98; }
[data-theme="neon"] .site-heading::before { content: "→ "; color: var(--site-accent); }
[data-theme="neon"] .site-hero-cta, [data-theme="neon"] .site-signup-btn,
[data-theme="neon"] .site-show-tickets {
  font-family: 'Space Mono', ui-monospace, monospace; text-transform: uppercase; border-radius: 0;
  background: transparent; color: var(--site-text); border: 2px solid var(--site-text);
  box-shadow: 4px 4px 0 var(--site-accent);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
[data-theme="neon"] .site-hero-cta:hover, [data-theme="neon"] .site-signup-btn:hover:not(:disabled),
[data-theme="neon"] .site-show-tickets:hover {
  background: transparent; color: var(--site-text);
  transform: translate(-2px, -2px); box-shadow: 6px 6px 0 var(--site-accent);
}
[data-theme="neon"] .site-links { border-bottom: 0; }
[data-theme="neon"] .site-link-row {
  border: 2px solid var(--site-text); margin-top: -2px; padding: 14px 16px;
}
[data-theme="neon"] .site-link-label { text-transform: uppercase; font-weight: 700; }
[data-theme="neon"] .site-link-row:hover { background: var(--site-text); color: var(--site-bg); }
[data-theme="neon"] .site-link-row:hover .site-link-meta,
[data-theme="neon"] .site-link-row:hover .site-link-sub,
[data-theme="neon"] .site-link-row:hover .site-link-arrow { color: var(--site-bg); }
[data-theme="neon"] .site-gallery-img, [data-theme="neon"] .site-about-img {
  border-radius: 0; border: 2px solid var(--site-text); filter: grayscale(1) contrast(1.1);
}
[data-theme="neon"] .site-embed { border-radius: 0; }
[data-theme="neon"] .site-embed-ratio { border: 2px solid var(--site-text); }
[data-theme="neon"] .site-statement-text {
  font-weight: 850; font-stretch: 125%;
  text-transform: uppercase; --fs-base: clamp(2rem, 5vw, 3.6rem); line-height: 0.95; max-width: none;
}
[data-theme="neon"] .site-section-statement { background: transparent; }
[data-theme="neon"] .site-quote-text {
  font-family: 'Space Mono', ui-monospace, monospace; --fs-base: 1.05rem; line-height: 1.6;
  border-left: 3px solid var(--site-accent); padding-left: 18px; font-style: normal;
}
[data-theme="neon"] .site-section-signup { background: var(--site-accent); }
[data-theme="neon"] .site-section-signup .site-heading,
[data-theme="neon"] .site-section-signup .site-blurb,
[data-theme="neon"] .site-signup-input { color: var(--site-on-accent, #0B0B0D); }
[data-theme="neon"] .site-section-signup .site-heading::before { color: var(--site-on-accent, #0B0B0D); }
[data-theme="neon"] .site-signup-input { border-bottom: 2px solid var(--site-on-accent, #0B0B0D); }
[data-theme="neon"] .site-signup-input::placeholder { color: rgba(11,11,13,0.6); }
[data-theme="neon"] .site-section-signup .site-signup-btn {
  background: var(--site-on-accent, #0B0B0D); color: var(--site-accent);
  border-color: var(--site-on-accent, #0B0B0D); box-shadow: none;
}
[data-theme="neon"] .site-show-row + .site-show-row { border-top: 3px solid var(--site-text); }
[data-theme="neon"] .site-show-venue { text-transform: uppercase; font-weight: 700; }
[data-theme="neon"] .site-footer { border-top: 6px solid var(--site-text); }

/* ============ PAPER — literary small press ============ */
[data-theme="paper"] { font-size: 18px; }
[data-theme="paper"] .site-section { --site-pad: clamp(3.5rem, 9vw, 6.5rem); }
[data-theme="paper"] .site-hero-heading {
  font-weight: 560; letter-spacing: -0.01em;
  line-height: 1.05; --fs-base: clamp(2.8rem, 1.4rem + 5.5vw, 5.25rem);
  font-variation-settings: 'opsz' 144, 'WONK' 1;
}
[data-theme="paper"] .site-section-hero {
  align-items: flex-start; min-height: 64svh;
  border-bottom: 3px double var(--site-text);
  padding-top: clamp(6rem, 16vw, 10rem);
}
[data-theme="paper"] .site-hero-tagline { font-style: italic; }
/* paper keeps its italic accent serif — at a size you can read across a room. */
[data-theme="paper"] .site-heading {
  font-family: var(--site-font-display); text-transform: none; letter-spacing: -0.01em;
  font-style: italic; font-weight: 480; color: var(--site-accent);
}
.site-root[data-headings="label"][data-theme="paper"] .site-heading {
  font-size: 1.05rem; letter-spacing: 0;
}
[data-theme="paper"] .site-section-about .site-body p:first-child::first-letter {
  font-family: var(--site-font-display); font-variation-settings: 'opsz' 144;
  font-size: 3.4em; line-height: 0.82; float: left; padding: 0.04em 0.1em 0 0;
  color: var(--site-accent);
}
[data-theme="paper"] .site-link-row,
[data-theme="paper"] .site-show-row + .site-show-row { border-top: 1px dotted var(--site-border); }
[data-theme="paper"] .site-links { border-bottom: 1px dotted var(--site-border); }
[data-theme="paper"] .site-link-host { font-style: italic; }
[data-theme="paper"] .site-show-date {
  font-variant: all-small-caps; letter-spacing: 0.08em; text-transform: none;
}
[data-theme="paper"] .site-show-tickets {
  border: 0; padding: 0; border-radius: 0; border-bottom: 1px solid var(--site-accent);
}
[data-theme="paper"] .site-show-tickets:hover { background: transparent; color: var(--site-accent); }
[data-theme="paper"] .site-gallery-img, [data-theme="paper"] .site-about-img { border-radius: 0; }
[data-theme="paper"] .site-gallery-item,
[data-theme="paper"] .site-embed-ratio {
  background: var(--site-surface); border: 1px solid var(--site-border); padding: 8px;
}
[data-theme="paper"] .site-about-img {
  background: var(--site-surface); border: 1px solid var(--site-border); padding: 8px;
}
[data-theme="paper"] .site-gallery-caption { font-style: italic; text-align: center; }
[data-theme="paper"] .site-hero-cta, [data-theme="paper"] .site-signup-btn {
  border-radius: 0; background: var(--site-accent); color: var(--site-bg);
}
[data-theme="paper"] .site-section-signup {
  background: transparent;
  border-top: 3px double var(--site-text); border-bottom: 3px double var(--site-text);
}
[data-theme="paper"] .site-quote-text {
  font-style: italic; font-weight: 480;
  --fs-base: clamp(1.5rem, 2.6vw, 2.1rem); font-variation-settings: 'opsz' 36;
}
[data-theme="paper"] .site-quote-attr { font-variant: all-small-caps; letter-spacing: 0.06em; }
[data-theme="paper"] .site-section-statement { background: transparent; text-align: center; }
[data-theme="paper"] .site-statement-text {
  font-style: italic; font-weight: 500;
  --fs-base: clamp(1.6rem, 3vw, 2.5rem); margin: 0 auto;
}
[data-theme="paper"] .site-statement-text::before {
  content: "❦"; display: block; color: var(--site-accent);
  font-size: 1.1rem; margin-bottom: 1rem; font-style: normal;
}
[data-theme="paper"] .site-footer { border-top: 3px double var(--site-text); }
[data-theme="paper"] .site-footer-inner { justify-content: center; gap: 24px; }

/* ============ MIDNIGHT — white-cube gallery at night ============ */
[data-theme="midnight"] { line-height: 1.7; }
[data-theme="midnight"] .site-section { --site-pad: clamp(5rem, 13vw, 9rem); }
[data-theme="midnight"] .site-hero-heading {
  font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.18em; line-height: 1.25;
  --fs-base: clamp(1.7rem, 1rem + 3vw, 3rem);
}
[data-theme="midnight"] .site-section-hero {
  align-items: center; min-height: 92svh; text-align: center;
}
[data-theme="midnight"] .site-section-hero .site-section-inner { text-align: center; }
[data-theme="midnight"] .site-hero-heading::after {
  content: ""; display: block; width: 32px; height: 2px;
  background: var(--site-accent); margin: 1.5rem auto 0;
}
[data-theme="midnight"] .site-hero-scrim {
  /* Derived from the palette bg — hardcoded dark broke the light variants
   * (daylight: dark text over a dark-tinted photo was unreadable). */
  background: linear-gradient(
    color-mix(in srgb, var(--site-bg) 55%, transparent),
    var(--site-bg)
  );
}
[data-theme="midnight"] .site-hero-tagline { margin-left: auto; margin-right: auto; }
/* midnight stays centred and austere — but a gallery wall still labels the
   room in type you can see. */
[data-theme="midnight"] .site-heading { text-align: center; letter-spacing: -0.015em; }
.site-root[data-headings="label"][data-theme="midnight"] .site-heading {
  font-size: 0.7rem; letter-spacing: 0.28em;
}
[data-theme="midnight"] .site-hero-eyebrow { letter-spacing: 0.3em; font-size: 0.7rem; }
[data-theme="midnight"] .site-section-inner { text-align: center; }
[data-theme="midnight"] .site-body p { margin-left: auto; margin-right: auto; }
[data-theme="midnight"] .site-links,
[data-theme="midnight"] .site-link-row,
[data-theme="midnight"] .site-show-row + .site-show-row,
[data-theme="midnight"] .site-footer { border: 0; }
[data-theme="midnight"] .site-link-row { justify-content: center; gap: 8px; padding: 12px 0; }
[data-theme="midnight"] .site-link-text { align-items: center; }
[data-theme="midnight"] .site-link-label {
  text-transform: uppercase; letter-spacing: 0.14em; font-size: 0.85rem; font-weight: 600;
}
[data-theme="midnight"] .site-link-host { display: none; }
[data-theme="midnight"] .site-link-row:hover { background: transparent; color: var(--site-accent); }
[data-theme="midnight"] .site-section-gallery .site-section-inner { max-width: none; padding: 0; }
[data-theme="midnight"] .site-gallery-grid, [data-theme="midnight"] .site-gallery-strip { gap: 2px; }
[data-theme="midnight"] .site-gallery-img, [data-theme="midnight"] .site-about-img { border-radius: 0; }
[data-theme="midnight"] .site-embed { border-radius: 0; }
[data-theme="midnight"] .site-embed-ratio { border: 0; background: transparent; }
[data-theme="midnight"] .site-hero-cta, [data-theme="midnight"] .site-signup-btn {
  background: transparent; color: var(--site-text); border: 1px solid var(--site-text);
  border-radius: 0; text-transform: uppercase; letter-spacing: 0.14em;
  font-size: 0.8rem; padding: 12px 28px;
}
[data-theme="midnight"] .site-hero-cta:hover,
[data-theme="midnight"] .site-signup-btn:hover:not(:disabled) {
  background: var(--site-text); color: var(--site-bg);
}
[data-theme="midnight"] .site-section-signup { background: transparent; }
[data-theme="midnight"] .site-signup-form { margin: 0 auto; }
[data-theme="midnight"] .site-quote-text {
  font-weight: 500; --fs-base: 1.1rem;
  letter-spacing: 0.04em; margin: 0 auto;
}
[data-theme="midnight"] .site-section-statement { background: transparent; }
[data-theme="midnight"] .site-statement-text {
  font-family: var(--site-font-body); --fs-base: 0.95rem; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.35em; line-height: 2;
  color: var(--site-text-2); max-width: none; margin: 0 auto;
}
[data-theme="midnight"] .site-show-row { justify-content: center; }
[data-theme="midnight"] .site-show-date { letter-spacing: 0.2em; }
[data-theme="midnight"] .site-footer-inner { justify-content: center; }

/* ============ EMBER — late-night cinema magazine ============ */
[data-theme="ember"] { counter-reset: sec; }
[data-theme="ember"] .site-hero-heading {
  font-weight: 400; letter-spacing: 0;
  --fs-base: clamp(3.2rem, 1.6rem + 7.5vw, 7rem); line-height: 0.98;
  font-variation-settings: normal;
}
[data-theme="ember"] .site-section-hero { min-height: min(78svh, 700px); }
[data-theme="ember"] .site-hero-tagline { font-family: var(--site-font-display); font-style: italic; font-size: clamp(1.15rem, 2.8vw, 1.45rem); }
[data-theme="ember"] .site-heading { border-top: 1px solid var(--site-accent); padding-top: 1.1rem; }
[data-theme="ember"] .site-heading::before { font-size: 0.42em; vertical-align: 0.55em; letter-spacing: 0.08em; }
.site-root[data-headings="label"][data-theme="ember"] .site-heading::before { font-size: inherit; vertical-align: baseline; letter-spacing: inherit; }
[data-theme="ember"] .site-heading::before {
  counter-increment: sec; content: counter(sec, decimal-leading-zero) " — ";
  color: var(--site-accent);
}
[data-theme="ember"] .site-gallery-img, [data-theme="ember"] .site-about-img {
  border-radius: 4px; filter: saturate(0.9) sepia(0.12);
}
[data-theme="ember"] .site-section-signup { border-top: 1px solid var(--site-accent); }
[data-theme="ember"] .site-quote-text {
  font-style: italic; font-weight: 400; --fs-base: clamp(1.6rem, 3vw, 2.3rem);
  border-left: 2px solid var(--site-accent); padding-left: 1.2rem;
  font-variation-settings: normal;
}
[data-theme="ember"] .site-statement-text {
  font-weight: 400; --fs-base: clamp(2rem, 4vw, 3.4rem);
  font-variation-settings: normal;
}

/* ============ GARDEN — hand-tended zine ============ */
[data-theme="garden"] .site-section { --site-pad: clamp(3rem, 7vw, 5rem); }
[data-theme="garden"] .site-hero-heading {
  font-weight: 700; letter-spacing: -0.01em;
  --fs-base: clamp(2.4rem, 1.2rem + 4.5vw, 4.25rem); line-height: 1.05;
  font-variation-settings: 'opsz' 96;
}
[data-theme="garden"] .site-section-hero {
  align-items: flex-start; min-height: 0;
  padding-block:
    calc(clamp(3.5rem, 8vw, 5rem) * var(--site-density, 1))
    calc(clamp(2rem, 5vw, 3rem) * var(--site-density, 1));
}
[data-theme="garden"] .site-hero-cover { min-height: min(70svh, 560px); }
[data-theme="garden"] .site-hero-bg { inset: 16px; width: calc(100% - 32px); height: calc(100% - 32px); border-radius: 24px; }
[data-theme="garden"] .site-hero-scrim { inset: 16px; border-radius: 24px; }
[data-theme="garden"] .site-heading {
  font-family: var(--site-font-display); text-transform: none; letter-spacing: -0.015em;
  font-weight: 600; color: var(--site-text);
}
.site-root[data-headings="label"][data-theme="garden"] .site-heading {
  font-size: 1.15rem; letter-spacing: 0;
}
[data-theme="garden"] .site-heading::before {
  content: ""; display: block; width: 28px; height: 3px; border-radius: 2px;
  background: var(--site-accent); margin-bottom: 0.6rem;
}
[data-theme="garden"] .site-links { border-bottom: 0; display: flex; flex-direction: column; gap: 10px; }
[data-theme="garden"] .site-link-row {
  background: var(--site-surface); border: 0; border-radius: 14px; padding: 14px 18px;
  transition: transform 0.15s ease, background-color 0.15s ease;
}
[data-theme="garden"] .site-link-row:hover {
  background: color-mix(in srgb, var(--site-surface) 94%, var(--site-accent));
  transform: translateY(-1px);
}
[data-theme="garden"] .site-hero-cta, [data-theme="garden"] .site-signup-btn {
  border-radius: 999px; background: var(--site-accent); color: var(--site-on-accent, #FFFFFF);
}
[data-theme="garden"] .site-signup-input {
  border: 1px solid var(--site-border); border-radius: 999px;
  padding: 12px 18px; background: var(--site-bg);
}
[data-theme="garden"] .site-gallery-img { border-radius: 16px; }
[data-theme="garden"] .site-about-img { border-radius: 16px; }
[data-theme="garden"] .site-gallery-grid .site-gallery-item { transition: transform 0.2s ease; }
[data-theme="garden"] .site-gallery-grid .site-gallery-item:nth-child(odd) { transform: rotate(-1.2deg); }
[data-theme="garden"] .site-gallery-grid .site-gallery-item:nth-child(even) { transform: rotate(1deg); }
[data-theme="garden"] .site-gallery-grid .site-gallery-item:hover { transform: rotate(0); }
[data-theme="garden"] .site-gallery-caption { font-style: italic; }
[data-theme="garden"] .site-embed { border-radius: 16px; }
[data-theme="garden"] .site-embed-ratio { border: 0; }
[data-theme="garden"] .site-section-signup {
  background: transparent;
}
[data-theme="garden"] .site-section-signup .site-section-inner {
  background: var(--site-surface); border-radius: 20px; padding: 2rem;
}
[data-theme="garden"] .site-quote-text { font-weight: 500; --fs-base: 1.35rem; }
[data-theme="garden"] .site-section-quote .site-section-inner {
  background: var(--site-surface); border-radius: 20px; padding: 2rem;
}
[data-theme="garden"] .site-section-statement {
  border-radius: 24px; margin: 0 clamp(12px, 3vw, 24px);
}
[data-theme="garden"] .site-statement-text {
  font-weight: 700; --fs-base: clamp(1.8rem, 3.5vw, 2.8rem);
}
[data-theme="garden"] .site-show-row {
  background: var(--site-surface); border: 0; border-radius: 14px;
  padding: 14px 18px; margin-top: 10px;
}
[data-theme="garden"] .site-show-row + .site-show-row { border-top: 0; }
[data-theme="garden"] .site-show-tickets { border-radius: 999px; }
[data-theme="garden"] .site-contact-email {
  background: var(--site-surface); border-radius: 999px; border-bottom: 0;
  padding: 10px 22px; font-size: 1.15rem;
}
[data-theme="garden"] .site-footer {
  background: var(--site-surface); border-top: 0; border-radius: 24px 24px 0 0;
  margin-top: clamp(2rem, 6vw, 4rem); padding-top: 2rem;
}

@media (max-width: 400px) {
  [data-theme="garden"] .site-gallery-grid .site-gallery-item { transform: none; }
}


/* --- Style-knob overrides (declared last: they beat theme rhythm) ----------- */
.site-root .site-sp-compact { --site-pad: clamp(1.75rem, 4vw, 3rem); }
.site-root .site-sp-roomy { --site-pad: clamp(5rem, 13vw, 9rem); }
.site-root .site-al-left .site-section-inner { text-align: left; }
.site-root .site-al-center .site-section-inner { text-align: center; }
.site-root .site-al-center .site-statement-text,
.site-root .site-al-center .site-quote-text,
.site-root .site-al-center .site-cta-heading { margin-left: auto; margin-right: auto; }
.site-root .site-al-center .site-countdown { justify-content: center; }
.site-root .site-al-center .site-count-unit { align-items: center; }

/* --- Theme identity lines for the new sections ------------------------------ */
[data-theme="midnight"] .site-work-rows .site-work-item { border: 0; justify-content: center; }
[data-theme="midnight"] .site-work { border-bottom: 0; }
[data-theme="midnight"] .site-work-title { text-transform: uppercase; letter-spacing: 0.14em; font-size: 0.9rem; }
[data-theme="midnight"] .site-heading-count { display: none; }
[data-theme="midnight"] .site-facts-rows { border-bottom: 0; }
[data-theme="midnight"] .site-facts-rows .site-fact-row { border: 0; justify-content: center; }
[data-theme="midnight"] .site-section-cta { background: transparent; }
[data-theme="midnight"] .site-cta-heading { text-transform: uppercase; letter-spacing: 0.14em; --fs-base: clamp(1.3rem, 2.4vw, 2rem); margin-left: auto; margin-right: auto; }
[data-theme="midnight"] .site-hero-status { text-transform: uppercase; letter-spacing: 0.2em; font-size: 0.7rem; }

[data-theme="paper"] .site-work-rows .site-work-item { border-top: 1px dotted var(--site-border); }
[data-theme="paper"] .site-work { border-bottom: 1px dotted var(--site-border); }
[data-theme="paper"] .site-work-meta { font-style: italic; }
[data-theme="paper"] .site-work-year { font-variant-numeric: oldstyle-nums; }
[data-theme="paper"] .site-work-hover { border: 1px solid var(--site-border); background: var(--site-surface); padding: 8px; }
[data-theme="paper"] .site-fact-label { font-variant: all-small-caps; text-transform: none; letter-spacing: 0.06em; }
[data-theme="paper"] .site-facts-rows .site-fact-row { border-top: 1px dotted var(--site-border); }
[data-theme="paper"] .site-section-cta { background: transparent; border-top: 3px double var(--site-text); border-bottom: 3px double var(--site-text); }
[data-theme="paper"] .site-cta-heading { font-style: italic; font-weight: 500; }
[data-theme="paper"] .site-hero-status { font-style: italic; }
[data-theme="paper"] .site-hero-status::before { content: "—"; width: auto; height: auto; background: transparent; animation: none; color: var(--site-accent); }
[data-theme="paper"] .site-heading-count { font-variant: all-small-caps; }

[data-theme="ember"] { counter-reset: sec work faqn; }
[data-theme="ember"] .site-work-rows .site-work-title::before {
  counter-increment: work; content: counter(work, decimal-leading-zero) " — ";
  color: var(--site-accent);
}
[data-theme="ember"] .site-work-year { color: var(--site-accent); }
[data-theme="ember"] .site-fact-label { color: var(--site-accent); }
[data-theme="ember"] .site-section-cta { border-top: 1px solid var(--site-accent); }
[data-theme="ember"] .site-cta-heading { font-style: italic; font-weight: 400; --fs-base: clamp(2rem, 4.5vw, 3.6rem); }
[data-theme="ember"] .site-heading-count { color: var(--site-accent); }

[data-theme="neon"] .site-work { border-bottom: 0; }
[data-theme="neon"] .site-work-rows .site-work-item { border: 2px solid var(--site-text); margin-top: -2px; padding: 14px 16px; }
[data-theme="neon"] .site-work-title { text-transform: uppercase; font-weight: 700; }
[data-theme="neon"] .site-work-meta, [data-theme="neon"] .site-work-year { font-family: 'Space Mono', ui-monospace, monospace; }
[data-theme="neon"] a.site-work-item:hover { background: var(--site-text); color: var(--site-bg); }
[data-theme="neon"] a.site-work-item:hover .site-work-meta,
[data-theme="neon"] a.site-work-item:hover .site-work-year { color: var(--site-bg); }
[data-theme="neon"] .site-work-thumb { border: 2px solid var(--site-text); border-radius: 0; filter: grayscale(1) contrast(1.1); }
[data-theme="neon"] .site-fact-label, [data-theme="neon"] .site-fact-value { font-family: 'Space Mono', ui-monospace, monospace; }
[data-theme="neon"] .site-facts-rows .site-fact-row { border-top: 3px solid var(--site-text); }
[data-theme="neon"] .site-section-cta { background: var(--site-accent); }
[data-theme="neon"] .site-section-cta .site-cta-heading { color: var(--site-on-accent, #0B0B0D); text-transform: uppercase; font-weight: 850; font-stretch: 125%; }
[data-theme="neon"] .site-section-cta .site-cta-sub { color: var(--site-on-accent, #0B0B0D); opacity: 0.78; }
[data-theme="neon"] .site-section-cta .site-cta-email { color: var(--site-on-accent, #0B0B0D); border-bottom-color: var(--site-on-accent, #0B0B0D); }
[data-theme="neon"] .site-hero-status { font-family: 'Space Mono', ui-monospace, monospace; }
[data-theme="neon"] .site-hero-status::before { content: "["; width: auto; height: auto; background: transparent; border-radius: 0; animation: none; color: var(--site-accent); }
[data-theme="neon"] .site-hero-status::after { content: "]"; color: var(--site-accent); }
[data-theme="neon"] .site-heading-count { font-family: 'Space Mono', ui-monospace, monospace; }

/* -- testimonials / faq / countdown, per identity -- */

/* studio: the hairline default IS the studio language — just quieter weights. */
[data-theme="studio"] .site-faq-q { font-weight: 500; }
[data-theme="studio"] .site-testimonial-name { font-weight: 500; }
[data-theme="studio"] .site-count-num { font-weight: 600; }

/* midnight: ruleless and centered, like everything else in the white cube. */
[data-theme="midnight"] .site-faq-item { border: 0; }
[data-theme="midnight"] .site-faq-item:last-child { border: 0; }
[data-theme="midnight"] .site-faq-q { justify-content: center; gap: 10px; text-transform: uppercase; letter-spacing: 0.12em; font-size: 0.85rem; }
[data-theme="midnight"] .site-faq-a { margin: 0 auto; }
[data-theme="midnight"] .site-testimonial-text { margin-left: auto; margin-right: auto; font-weight: 500; font-size: 1.05rem; letter-spacing: 0.03em; }
[data-theme="midnight"] .site-testimonial-attr { justify-content: center; }
[data-theme="midnight"] .site-countdown { justify-content: center; }
[data-theme="midnight"] .site-count-unit-label { letter-spacing: 0.25em; }
[data-theme="midnight"] .site-count-label { letter-spacing: 0.3em; font-size: 0.7rem; }

/* paper: dotted rules, italics, small caps — the small-press etiquette. */
[data-theme="paper"] .site-faq-item { border-top: 1px dotted var(--site-border); }
[data-theme="paper"] .site-faq-item:last-child { border-bottom: 1px dotted var(--site-border); }
[data-theme="paper"] .site-testimonial-name { font-variant: all-small-caps; font-weight: 500; letter-spacing: 0.04em; }
[data-theme="paper"] .site-testimonial-sub { font-style: italic; }
[data-theme="paper"] .site-count-label { font-style: italic; text-transform: none; letter-spacing: 0; font-size: 0.95rem; }

/* ember: gold chapter numbers and italic display — cinema-titles countdown. */
[data-theme="ember"] .site-testimonial-text {
  font-style: italic; font-weight: 400; font-variation-settings: normal;
  border-left: 2px solid var(--site-accent); padding-left: 1.2rem;
}
[data-theme="ember"] .site-faq-q-text::before {
  counter-increment: faqn; content: counter(faqn, decimal-leading-zero) " — ";
  color: var(--site-accent);
}
[data-theme="ember"] .site-count-num { color: var(--site-accent); font-weight: 400; font-variation-settings: normal; }
[data-theme="ember"] .site-count-done { font-style: italic; font-weight: 400; }

/* neon: boxed, monospaced, loud. */
[data-theme="neon"] .site-testimonial { border: 2px solid var(--site-text); padding: 18px; }
[data-theme="neon"] .site-testimonial-attr { font-family: 'Space Mono', ui-monospace, monospace; }
[data-theme="neon"] .site-faq-item { border-top: 3px solid var(--site-text); }
[data-theme="neon"] .site-faq-item:last-child { border-bottom: 3px solid var(--site-text); }
[data-theme="neon"] .site-faq-q { text-transform: uppercase; font-weight: 700; }
[data-theme="neon"] .site-faq-marker::before { height: 2px; }
[data-theme="neon"] .site-faq-marker::after { width: 2px; }
[data-theme="neon"] .site-faq-a p { font-family: 'Space Mono', ui-monospace, monospace; font-size: 0.9rem; }
[data-theme="neon"] .site-count-num { font-weight: 850; font-stretch: 125%; }
[data-theme="neon"] .site-count-unit-label, [data-theme="neon"] .site-count-label { font-family: 'Space Mono', ui-monospace, monospace; }
[data-theme="neon"] .site-count-label::before { content: "["; color: var(--site-accent); }
[data-theme="neon"] .site-count-label::after { content: "]"; color: var(--site-accent); }

/* garden: everything sits in soft surface cards. */
[data-theme="garden"] .site-testimonials { gap: 12px; }
[data-theme="garden"] .site-testimonial { background: var(--site-surface); border-radius: 14px; padding: 18px 20px; }
[data-theme="garden"] .site-testimonials-grid .site-testimonial:nth-child(odd) { transform: rotate(-0.6deg); }
[data-theme="garden"] .site-testimonials-grid .site-testimonial:nth-child(even) { transform: rotate(0.5deg); }
[data-theme="garden"] .site-faq { gap: 10px; }
[data-theme="garden"] .site-faq-item { background: var(--site-surface); border: 0; border-radius: 14px; padding: 2px 18px; }
[data-theme="garden"] .site-faq-item:last-child { border: 0; }
[data-theme="garden"] .site-count-unit { background: var(--site-surface); border-radius: 16px; padding: 14px 18px; }

[data-theme="garden"] .site-work { border-bottom: 0; gap: 10px; }
[data-theme="garden"] .site-work-rows .site-work-item { background: var(--site-surface); border: 0; border-radius: 14px; padding: 14px 18px; transition: transform 0.15s ease, background-color 0.15s ease; }
[data-theme="garden"] a.site-work-item:hover { transform: translateY(-2px); background: color-mix(in srgb, var(--site-surface) 94%, var(--site-accent)); }
[data-theme="garden"] .site-work-thumb { border-radius: 16px; }
[data-theme="garden"] .site-facts-rows { border-bottom: 0; gap: 10px; }
[data-theme="garden"] .site-facts-rows .site-fact-row { background: var(--site-surface); border: 0; border-radius: 14px; padding: 12px 18px; }
[data-theme="garden"] .site-section-cta { background: transparent; }
[data-theme="garden"] .site-section-cta .site-section-inner { background: var(--site-surface); border-radius: 20px; padding: 2.5rem 2rem; }
[data-theme="garden"] .site-cta-btn, [data-theme="garden"] .site-cta-email { border-radius: 999px; }
[data-theme="garden"] .site-cta-btn { background: var(--site-accent); color: var(--site-on-accent, #FFFFFF); }
[data-theme="garden"] .site-hero-status { background: var(--site-surface); border-radius: 999px; padding: 6px 14px; }
[data-theme="garden"] .site-heading-count { color: var(--site-accent); }


/* ============ SWISS — International Typographic Style ============
   The one direction the set had no answer for: structure as the whole design.
   Where `studio` is air — hairlines, generous margins, nothing shouting — swiss
   is a grid you can see. Both are set in Geist, and they look nothing alike,
   which is the point: a theme engine is a LAYOUT argument, not a palette.

   The moves, all of them period-correct rather than decorative:
     - one hairline, used everywhere and never varied in weight
     - section headings demoted to small tracked-out uppercase labels sitting
       under a red rule, so the eye reads structure before content
     - the section number promoted to a real typographic element in the accent
     - headlines set as large and as tight as the face will take, flush left,
       never centred
     - squared corners without exception, and a signal red that appears only on
       rules, numerals and the active state — never as decoration
   ================================================================ */

/* Measured, not generous. Swiss space is a module, not a cushion. */
[data-theme="swiss"] .site-section { --site-pad: clamp(2.75rem, 6.5vw, 4.5rem); }

/* Flush left is the whole argument, so swiss makes it the THEME DEFAULT — and
   only the default. Every section whose Alignment control the author left on
   "Theme default" carries no alignment class at all, and those are the ones
   this claims; a section the author explicitly centred keeps its own class and
   a higher-specificity rule, and still wins. The hero is deliberately not in
   this list: its Alignment control has no "theme default" option, so its value
   is always an explicit choice and overriding it would be taking the control
   away rather than answering it. */
[data-theme="swiss"] .site-section:not(.site-al-center):not(.site-al-left):not(.site-align-center):not(.site-align-left) .site-section-inner {
  text-align: left;
}
[data-theme="swiss"] .site-section + .site-section { border-top: 1px solid var(--site-text); }

/* Headlines: as large and as tight as Geist will go, always flush left. */
[data-theme="swiss"] .site-hero-heading {
  font-weight: 700;
  --fs-base: clamp(2.75rem, 10.5vw, 8rem);
  line-height: 0.9;
  letter-spacing: -0.045em;
  text-wrap: balance;
}
[data-theme="swiss"] .site-section-hero { min-height: min(66svh, 600px); }
[data-theme="swiss"] .site-hero-tagline { max-width: 46ch; }
[data-theme="swiss"] .site-hero-eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--site-accent);
}
[data-theme="swiss"] .site-hero-status::before { background: var(--site-accent); border-radius: 0; }
[data-theme="swiss"] .site-hero-bg { filter: grayscale(1) contrast(1.08); }

/* Section headings are LABELS under a rule — the structural signature. */
[data-theme="swiss"] .site-heading {
  text-transform: uppercase;
  --fs-base: clamp(0.72rem, 1.1vw, 0.82rem);
  letter-spacing: 0.16em;
  font-weight: 600;
  line-height: 1.3;
  border-top: 2px solid var(--site-accent);
  padding-block-start: 0.85rem;
  color: var(--site-text);
}
/* The number is set as a numeral in the signal colour, not as a footnote. */
[data-theme="swiss"] .site-heading-count {
  color: var(--site-accent);
  font-weight: 700;
  font-size: 1em;
  vertical-align: baseline;
  letter-spacing: 0.08em;
}

/* Nothing is rounded. Ever. */
[data-theme="swiss"] .site-gallery-img,
[data-theme="swiss"] .site-about-img,
[data-theme="swiss"] .site-work-thumb,
[data-theme="swiss"] .site-embed,
[data-theme="swiss"] .site-hero-cover,
[data-theme="swiss"] .site-hero-figure { border-radius: 0; }
[data-theme="swiss"] .site-embed-ratio { border: 1px solid var(--site-text); }

/* Actions: a solid black block that goes red on contact. */
[data-theme="swiss"] .site-hero-cta,
[data-theme="swiss"] .site-signup-btn,
[data-theme="swiss"] .site-cta-btn,
[data-theme="swiss"] .site-header-cta,
[data-theme="swiss"] .site-header-menu-cta,
[data-theme="swiss"] .site-show-tickets {
  border-radius: 0;
  background: var(--site-text);
  color: var(--site-bg);
  border: 1px solid var(--site-text);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 600;
  font-size: 0.78rem;
}
[data-theme="swiss"] .site-hero-cta:hover,
[data-theme="swiss"] .site-signup-btn:hover:not(:disabled),
[data-theme="swiss"] .site-cta-btn:hover,
[data-theme="swiss"] .site-header-cta:hover,
[data-theme="swiss"] .site-header-menu-cta:hover,
[data-theme="swiss"] .site-show-tickets:hover {
  background: var(--site-accent);
  border-color: var(--site-accent);
  color: #FFFFFF;
}

/* Ruled rows — links, shows, facts and work all read as one ledger. */
[data-theme="swiss"] .site-links { border-bottom: 0; }
[data-theme="swiss"] .site-link-row,
[data-theme="swiss"] .site-show-row + .site-show-row,
[data-theme="swiss"] .site-fact-row,
[data-theme="swiss"] .site-work-rows .site-work-item { border-top: 1px solid var(--site-border); }
[data-theme="swiss"] .site-link-label,
[data-theme="swiss"] .site-show-venue,
[data-theme="swiss"] .site-fact-label {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
}
[data-theme="swiss"] .site-link-row:hover { background: var(--site-accent); color: #FFFFFF; }
[data-theme="swiss"] .site-link-row:hover .site-link-meta,
[data-theme="swiss"] .site-link-row:hover .site-link-sub,
[data-theme="swiss"] .site-link-row:hover .site-link-host,
[data-theme="swiss"] .site-link-row:hover .site-link-arrow { color: #FFFFFF; }

/* Long-form type: tight, flush left, never italic. */
[data-theme="swiss"] .site-statement-text,
[data-theme="swiss"] .site-cta-heading {
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.02;
}
[data-theme="swiss"] .site-section-statement { background: transparent; }
[data-theme="swiss"] .site-quote-text {
  font-style: normal;
  font-weight: 500;
  letter-spacing: -0.02em;
  border-left: 2px solid var(--site-accent);
  padding-inline-start: 1.1rem;
}
[data-theme="swiss"] .site-quote-attr,
[data-theme="swiss"] .site-testimonial-name {
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.72rem;
  font-weight: 600;
}
[data-theme="swiss"] .site-work-title { font-weight: 600; letter-spacing: -0.01em; }
[data-theme="swiss"] .site-work-year,
[data-theme="swiss"] .site-show-date {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}
[data-theme="swiss"] .site-section-cta { background: var(--site-surface); }

/* Inputs sit on the rule, not in a box. */
[data-theme="swiss"] .site-signup-input {
  border-radius: 0;
  border: 0;
  border-bottom: 1px solid var(--site-text);
  background: transparent;
}

/* The footer closes the grid with the heaviest rule on the page. */
[data-theme="swiss"] .site-footer { border-top: 2px solid var(--site-text); }
[data-theme="swiss"] .site-footer-link,
[data-theme="swiss"] .site-footer-text,
[data-theme="swiss"] .site-footer-copy {
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.7rem;
}

/* ============ EDITORIAL — the feature well of a monthly ============
   `paper` is a literary small press: warm stock, one slow column, a drop cap,
   dotted rules. This is a MAGAZINE, and the difference is structural rather
   than tonal.

   Its signature is the one layout nothing else in the set does: a lede that
   spans the full measure in small caps, and then body copy that genuinely sets
   in two columns. Around that — hairline rules above and below every section
   label, a contents-page treatment for work rows, and a red that behaves like
   a section mark rather than a highlight.
   =================================================================== */

[data-theme="editorial"] { font-size: 17px; }
[data-theme="editorial"] .site-section { --site-pad: clamp(3rem, 7vw, 5rem); }

/* Masthead: the brand is set like a magazine's, and the header closes with the
   heavy rule a masthead always sits on. */
[data-theme="editorial"] .site-header { border-bottom: 3px double var(--site-text); }
[data-theme="editorial"] .site-header-brand {
  font-family: var(--site-font-display);
  font-size: 1.35rem;
  letter-spacing: -0.01em;
}
[data-theme="editorial"] .site-header-link,
[data-theme="editorial"] .site-footer-link,
[data-theme="editorial"] .site-footer-copy {
  font-variant-caps: all-small-caps;
  letter-spacing: 0.1em;
}

/* Section labels sit between two rules — the magazine's department mark. */
[data-theme="editorial"] .site-heading {
  font-variant-caps: all-small-caps;
  letter-spacing: 0.16em;
  font-weight: 500;
  --fs-base: clamp(0.95rem, 1.4vw, 1.1rem);
  border-top: 1px solid var(--site-text);
  border-bottom: 1px solid var(--site-border);
  padding-block: 0.5rem;
}
[data-theme="editorial"] .site-heading-count {
  color: var(--site-accent);
  font-variant-caps: normal;
}

/* Headlines: high-contrast serif, tight, with a real optical size. */
[data-theme="editorial"] .site-hero-heading {
  font-weight: 500;
  line-height: 1.02;
  letter-spacing: -0.025em;
  --fs-base: clamp(2.5rem, 7.5vw, 5.5rem);
}
[data-theme="editorial"] .site-hero-eyebrow {
  font-variant-caps: all-small-caps;
  letter-spacing: 0.2em;
  color: var(--site-accent);
}
[data-theme="editorial"] .site-hero-tagline {
  font-size: 1.2rem;
  line-height: 1.55;
  max-width: 52ch;
}

/* --- The signature: a spanning lede, then two columns ---------------------
   The first paragraph reads as the standfirst — full measure, small caps — and
   the rest of the piece sets in columns beneath it, which is what a feature
   well actually looks like. Columns only above 900px: two columns on a phone
   is a ransom note. And never inside the split-image about layout, where the
   prose is already in a narrow column of its own. */
[data-theme="editorial"] .site-section-about .site-body p:first-child {
  font-size: 1.25rem;
  line-height: 1.5;
  max-width: none;
}
[data-theme="editorial"] .site-section-about .site-body p:first-child::first-line {
  font-variant-caps: all-small-caps;
  letter-spacing: 0.05em;
}
@media (min-width: 900px) {
  [data-theme="editorial"] .site-section-about .site-body {
    columns: 2;
    column-gap: clamp(1.75rem, 3.5vw, 2.75rem);
    column-rule: 1px solid var(--site-border);
  }
  [data-theme="editorial"] .site-section-about .site-body p { max-width: none; }
  [data-theme="editorial"] .site-section-about .site-body p:first-child {
    column-span: all;
    margin-bottom: 1.4em;
  }
  /* The split layout supplies its own narrow column; do not column it twice. */
  [data-theme="editorial"] .site-about-split .site-body { columns: auto; column-rule: none; }
}

/* Pull quote: centred, italic, ruled off top and bottom. */
[data-theme="editorial"] .site-quote-text {
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.015em;
  line-height: 1.25;
}
[data-theme="editorial"] .site-quote {
  border-block: 1px solid var(--site-text);
  padding-block: clamp(1.25rem, 3vw, 2rem);
}
[data-theme="editorial"] .site-quote-attr,
[data-theme="editorial"] .site-testimonial-name,
[data-theme="editorial"] .site-work-year,
[data-theme="editorial"] .site-show-date {
  font-variant-caps: all-small-caps;
  letter-spacing: 0.1em;
}

/* Work reads as a contents page: title left, page-number-ish year right. */
[data-theme="editorial"] .site-work-rows .site-work-item {
  border-top: 1px solid var(--site-border);
}
[data-theme="editorial"] .site-work-title {
  font-family: var(--site-font-display);
  font-weight: 500;
  font-size: 1.25rem;
  letter-spacing: -0.01em;
}
[data-theme="editorial"] .site-work-year { color: var(--site-accent); }

[data-theme="editorial"] .site-statement-text {
  font-style: italic;
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -0.02em;
}
[data-theme="editorial"] .site-section-statement { background: var(--site-surface); }

/* Buttons are set as rules and small caps, not as pills. */
[data-theme="editorial"] .site-hero-cta,
[data-theme="editorial"] .site-signup-btn,
[data-theme="editorial"] .site-cta-btn,
[data-theme="editorial"] .site-header-cta,
[data-theme="editorial"] .site-header-menu-cta,
[data-theme="editorial"] .site-show-tickets {
  border-radius: 2px;
  background: var(--site-text);
  color: var(--site-bg);
  font-variant-caps: all-small-caps;
  letter-spacing: 0.12em;
}
[data-theme="editorial"] .site-hero-cta:hover,
[data-theme="editorial"] .site-signup-btn:hover:not(:disabled),
[data-theme="editorial"] .site-cta-btn:hover,
[data-theme="editorial"] .site-header-cta:hover,
[data-theme="editorial"] .site-header-menu-cta:hover,
[data-theme="editorial"] .site-show-tickets:hover { background: var(--site-accent); }

[data-theme="editorial"] .site-link-row,
[data-theme="editorial"] .site-fact-row,
[data-theme="editorial"] .site-show-row + .site-show-row { border-top: 1px solid var(--site-border); }
[data-theme="editorial"] .site-link-label,
[data-theme="editorial"] .site-fact-label { font-variant-caps: all-small-caps; letter-spacing: 0.08em; }
[data-theme="editorial"] .site-links { border-bottom: 1px solid var(--site-border); }
[data-theme="editorial"] .site-gallery-img,
[data-theme="editorial"] .site-about-img,
[data-theme="editorial"] .site-work-thumb { border-radius: 2px; }
[data-theme="editorial"] .site-footer { border-top: 3px double var(--site-text); }

/* ============ RISOGRAPH — two spot inks on newsprint ============
   `garden` is already the hand-tended zine: warm, botanical, rounded, gentle.
   This is the same subculture with a different machine behind it — a duplicator
   that lays down one flat spot colour per pass and never quite lines them up.

   The signature is MISREGISTRATION. Every headline carries a second impression
   a fraction of an em off in the accent ink, exactly the way a two-pass riso
   job does. It is drawn with text-shadow off var(--site-accent), so it re-inks
   itself for every palette variant instead of being three hardcoded pinks.

   The other period details: the ink is BLUE rather than black, because a riso
   almost never prints true black; images are pushed to a hard one-colour
   contrast; and blocks are stamped with a hard offset rather than a soft
   shadow, because a duplicator has no soft anything.
   ================================================================ */

[data-theme="risograph"] .site-section { --site-pad: clamp(2.75rem, 6.5vw, 4.5rem); }

/* The offset second impression — the whole theme in one declaration. */
[data-theme="risograph"] .site-hero-heading {
  font-weight: 700;
  line-height: 0.95;
  letter-spacing: -0.03em;
  text-shadow: 0.055em 0.055em 0 var(--site-accent);
}
[data-theme="risograph"] .site-statement-text {
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-shadow: 0.04em 0.04em 0 var(--site-accent);
}
[data-theme="risograph"] .site-heading {
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  text-shadow: 0.035em 0.035em 0 var(--site-accent);
}
[data-theme="risograph"] .site-heading-count {
  color: var(--site-accent);
  text-shadow: none;
}

/* A misregistered impression is a print artefact, not information. Anyone who
   has asked the OS for more contrast gets the single clean pass instead. */
@media (prefers-contrast: more) {
  [data-theme="risograph"] .site-hero-heading,
  [data-theme="risograph"] .site-statement-text,
  [data-theme="risograph"] .site-heading { text-shadow: none; }
}

[data-theme="risograph"] .site-hero-eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-weight: 700;
  color: var(--site-accent);
}
[data-theme="risograph"] .site-hero-status { background: var(--site-accent); color: var(--site-on-accent, #FFFFFF); border-radius: 0; padding: 5px 12px; }
[data-theme="risograph"] .site-hero-status::before { background: var(--site-on-accent, #FFFFFF); }

/* One flat pass of ink — photographs get pushed to a single hard colour. */
[data-theme="risograph"] .site-gallery-img,
[data-theme="risograph"] .site-about-img,
[data-theme="risograph"] .site-work-thumb,
[data-theme="risograph"] .site-hero-bg {
  filter: grayscale(1) contrast(1.45) brightness(1.06);
  border-radius: 0;
}

/* Stamped, not shadowed: a duplicator has no soft anything. */
[data-theme="risograph"] .site-hero-cta,
[data-theme="risograph"] .site-signup-btn,
[data-theme="risograph"] .site-cta-btn,
[data-theme="risograph"] .site-header-cta,
[data-theme="risograph"] .site-header-menu-cta,
[data-theme="risograph"] .site-show-tickets {
  border-radius: 0;
  background: var(--site-accent);
  color: var(--site-on-accent, #FFFFFF);
  border: 2px solid var(--site-text);
  box-shadow: 4px 4px 0 var(--site-text);
  text-transform: uppercase;
  font-weight: 700;
  letter-spacing: 0.06em;
  font-size: 0.8rem;
}
[data-theme="risograph"] .site-hero-cta:hover,
[data-theme="risograph"] .site-signup-btn:hover:not(:disabled),
[data-theme="risograph"] .site-cta-btn:hover,
[data-theme="risograph"] .site-header-cta:hover,
[data-theme="risograph"] .site-header-menu-cta:hover,
[data-theme="risograph"] .site-show-tickets:hover {
  box-shadow: 1px 1px 0 var(--site-text);
  transform: translate(3px, 3px);
}

/* Cut-and-paste rules: dashed, like a zine trimmed with a steel ruler. */
[data-theme="risograph"] .site-section + .site-section { border-top: 2px dashed var(--site-border); }
[data-theme="risograph"] .site-link-row,
[data-theme="risograph"] .site-fact-row,
[data-theme="risograph"] .site-work-rows .site-work-item,
[data-theme="risograph"] .site-show-row + .site-show-row { border-top: 2px dashed var(--site-border); }
[data-theme="risograph"] .site-links { border-bottom: 0; }
[data-theme="risograph"] .site-link-label,
[data-theme="risograph"] .site-show-venue,
[data-theme="risograph"] .site-fact-label,
[data-theme="risograph"] .site-work-title {
  text-transform: uppercase;
  font-weight: 700;
  letter-spacing: 0.02em;
}
[data-theme="risograph"] .site-link-row:hover { background: var(--site-accent); color: var(--site-on-accent, #FFFFFF); }
[data-theme="risograph"] .site-link-row:hover .site-link-meta,
[data-theme="risograph"] .site-link-row:hover .site-link-sub,
[data-theme="risograph"] .site-link-row:hover .site-link-host,
[data-theme="risograph"] .site-link-row:hover .site-link-arrow { color: var(--site-on-accent, #FFFFFF); }
[data-theme="risograph"] .site-work-year { color: var(--site-accent); font-weight: 700; }

[data-theme="risograph"] .site-quote-text {
  font-style: normal;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--site-accent);
}
[data-theme="risograph"] .site-section-statement { background: var(--site-surface); }
[data-theme="risograph"] .site-embed,
[data-theme="risograph"] .site-embed-ratio { border-radius: 0; border: 2px solid var(--site-text); }
[data-theme="risograph"] .site-signup-input { border-radius: 0; border: 2px solid var(--site-text); background: transparent; }
[data-theme="risograph"] .site-footer { border-top: 2px dashed var(--site-border); }

/* ============ DARKROOM — the type gets out of the way ============
   Every other theme in this set makes the headline the event. A photographer's
   site cannot afford that: the pictures are the work, and a 8rem name on top of
   them is the designer talking over the client.

   So darkroom inverts the one thing all nine others agree on. The hero heading
   is set SMALL — tracked-out monospace, closer to a caption than a title — and
   the space that would have gone to display type goes to the images instead.
   Sections are annotated rather than titled, the way a contact sheet is: frame
   numbers, edge codes, tight captions. Safelight red is the only colour, and it
   only appears on something you can act on.

   `ember` is the other dark serif theme and is a late-night cinema magazine:
   warm, gold, expressive. This one is a cold room with the lights off.
   ================================================================= */

/* Airy by construction — the pictures need the room. */
[data-theme="darkroom"] .site-section { --site-pad: clamp(3.5rem, 9vw, 7rem); }

/* The inversion: the name is an annotation, not a poster. */
[data-theme="darkroom"] .site-hero-heading {
  --fs-base: clamp(1.35rem, 2.6vw, 2.1rem);
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
[data-theme="darkroom"] .site-section-hero { min-height: min(58svh, 520px); }
[data-theme="darkroom"] .site-hero-tagline {
  font-size: 0.95rem;
  color: var(--site-text-2);
  max-width: 46ch;
}
[data-theme="darkroom"] .site-hero-eyebrow,
[data-theme="darkroom"] .site-heading {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 0.68rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  font-weight: 400;
  color: var(--site-text-2);
}
/* Frame number, as on a strip of film. */
[data-theme="darkroom"] .site-heading-count {
  font-family: 'Space Mono', ui-monospace, monospace;
  color: var(--site-accent);
  font-size: 1em;
  vertical-align: baseline;
  letter-spacing: 0.1em;
}

/* Prints, borderless and unrounded, in a contact-sheet grid. */
[data-theme="darkroom"] .site-gallery-img,
[data-theme="darkroom"] .site-about-img,
[data-theme="darkroom"] .site-work-thumb,
[data-theme="darkroom"] .site-hero-cover,
[data-theme="darkroom"] .site-hero-figure { border-radius: 0; }
[data-theme="darkroom"] .site-gallery-grid { gap: 6px; }
[data-theme="darkroom"] .site-gallery-caption {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 0.64rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--site-text-2);
}
[data-theme="darkroom"] .site-hero-scrim {
  background: linear-gradient(to top, rgba(12,12,13,.85), rgba(12,12,13,.35));
}

/* Body copy sits quiet and narrow. */
[data-theme="darkroom"] .site-body p { max-width: 58ch; color: var(--site-text-2); }
[data-theme="darkroom"] .site-section-about .site-body p:first-child { color: var(--site-text); }

/* Colour appears only on something actionable. */
[data-theme="darkroom"] .site-hero-cta,
[data-theme="darkroom"] .site-signup-btn,
[data-theme="darkroom"] .site-cta-btn,
[data-theme="darkroom"] .site-header-cta,
[data-theme="darkroom"] .site-header-menu-cta,
[data-theme="darkroom"] .site-show-tickets {
  border-radius: 0;
  background: transparent;
  color: var(--site-text);
  border: 1px solid var(--site-border);
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
[data-theme="darkroom"] .site-hero-cta:hover,
[data-theme="darkroom"] .site-signup-btn:hover:not(:disabled),
[data-theme="darkroom"] .site-cta-btn:hover,
[data-theme="darkroom"] .site-header-cta:hover,
[data-theme="darkroom"] .site-header-menu-cta:hover,
[data-theme="darkroom"] .site-show-tickets:hover {
  border-color: var(--site-accent);
  color: var(--site-accent);
}
[data-theme="darkroom"] .site-hero-status::before { background: var(--site-accent); }

/* Ledgers set as edge codes. */
[data-theme="darkroom"] .site-link-row,
[data-theme="darkroom"] .site-fact-row,
[data-theme="darkroom"] .site-work-rows .site-work-item,
[data-theme="darkroom"] .site-show-row + .site-show-row { border-top: 1px solid var(--site-border); }
[data-theme="darkroom"] .site-links { border-bottom: 1px solid var(--site-border); }
[data-theme="darkroom"] .site-link-label,
[data-theme="darkroom"] .site-work-title,
[data-theme="darkroom"] .site-show-venue {
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  font-weight: 400;
}
[data-theme="darkroom"] .site-fact-label,
[data-theme="darkroom"] .site-work-year,
[data-theme="darkroom"] .site-show-date,
[data-theme="darkroom"] .site-link-meta,
[data-theme="darkroom"] .site-footer-copy,
[data-theme="darkroom"] .site-footer-link,
[data-theme="darkroom"] .site-header-link {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
[data-theme="darkroom"] .site-link-row:hover .site-link-label { color: var(--site-accent); }

[data-theme="darkroom"] .site-statement-text,
[data-theme="darkroom"] .site-quote-text {
  font-family: var(--site-font-body, inherit);
  --fs-base: clamp(1.1rem, 2vw, 1.5rem);
  font-weight: 400;
  font-style: normal;
  line-height: 1.5;
  letter-spacing: 0.01em;
}
[data-theme="darkroom"] .site-section-statement { background: transparent; }
[data-theme="darkroom"] .site-embed,
[data-theme="darkroom"] .site-embed-ratio { border-radius: 0; }
[data-theme="darkroom"] .site-signup-input {
  border-radius: 0; border: 0;
  border-bottom: 1px solid var(--site-border);
  background: transparent;
}
[data-theme="darkroom"] .site-footer { border-top: 1px solid var(--site-border); }

/* ============ TECHNICAL — a working drawing ============
   The last register the set was missing: a document that has to be READ
   precisely rather than a page that has to be admired. Drafting-paper ground,
   one drafting blue, and the conventions of a drawing sheet used as real
   structure rather than as ornament.

   Three of those conventions do the work:
     - a LEADER LINE runs into every section label, the way a callout points at
       the thing it names
     - the section number sits in a CALLOUT BUBBLE — a circled reference, which
       is exactly what .site-heading-count already is, finally set as one
     - the footer is a TITLE BLOCK: ruled, boxed, monospaced, bottom of sheet

   It shares Geist with `studio` and `swiss`, which between them now demonstrate
   the whole argument: same face, three completely different documents.
   ======================================================= */

[data-theme="technical"] .site-section { --site-pad: clamp(2.5rem, 6vw, 4rem); }
[data-theme="technical"] .site-section + .site-section { border-top: 1px solid var(--site-border); }

/* Precision reads through the numbers, so every figure is tabular. */
[data-theme="technical"] .site-root,
[data-theme="technical"] .site-work-year,
[data-theme="technical"] .site-show-date,
[data-theme="technical"] .site-fact-value,
[data-theme="technical"] .site-count-num { font-variant-numeric: tabular-nums; }

/* A leader line into every label — the callout pointing at what it names. */
[data-theme="technical"] .site-heading {
  text-transform: uppercase;
  --fs-base: 0.74rem;
  letter-spacing: 0.18em;
  font-weight: 600;
  color: var(--site-text-2);
}
[data-theme="technical"] .site-heading::before {
  content: "";
  display: inline-block;
  width: clamp(16px, 3vw, 34px);
  border-top: 1px solid var(--site-accent);
  vertical-align: middle;
  margin-right: 0.7em;
  transform: translateY(-0.08em);
}
/* The section number, finally set as the circled reference it always was. */
[data-theme="technical"] .site-heading-count {
  color: var(--site-accent);
  border: 1px solid var(--site-accent);
  border-radius: 50%;
  padding: 0.1em 0.42em;
  font-size: 0.82em;
  vertical-align: baseline;
  letter-spacing: 0;
  font-weight: 500;
}

[data-theme="technical"] .site-hero-heading {
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -0.03em;
}
[data-theme="technical"] .site-hero-eyebrow {
  font-family: 'Space Mono', ui-monospace, monospace;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 0.68rem;
  color: var(--site-accent);
}
[data-theme="technical"] .site-hero-status::before { background: var(--site-accent); border-radius: 0; }

/* Squared, hairlined, cool. A drawing has no rounded corners and no shadows. */
[data-theme="technical"] .site-gallery-img,
[data-theme="technical"] .site-about-img,
[data-theme="technical"] .site-work-thumb,
[data-theme="technical"] .site-embed,
[data-theme="technical"] .site-hero-cover,
[data-theme="technical"] .site-hero-figure { border-radius: 0; }
[data-theme="technical"] .site-gallery-img,
[data-theme="technical"] .site-about-img,
[data-theme="technical"] .site-embed-ratio { border: 1px solid var(--site-border); }

[data-theme="technical"] .site-hero-cta,
[data-theme="technical"] .site-signup-btn,
[data-theme="technical"] .site-cta-btn,
[data-theme="technical"] .site-header-cta,
[data-theme="technical"] .site-header-menu-cta,
[data-theme="technical"] .site-show-tickets {
  border-radius: 0;
  background: var(--site-accent);
  color: var(--site-on-accent, #FFFFFF);
  border: 1px solid var(--site-accent);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 0.72rem;
  font-weight: 600;
}
[data-theme="technical"] .site-hero-cta:hover,
[data-theme="technical"] .site-signup-btn:hover:not(:disabled),
[data-theme="technical"] .site-cta-btn:hover,
[data-theme="technical"] .site-header-cta:hover,
[data-theme="technical"] .site-header-menu-cta:hover,
[data-theme="technical"] .site-show-tickets:hover {
  background: transparent;
  color: var(--site-accent);
}

/* Schedules, not lists. */
[data-theme="technical"] .site-link-row,
[data-theme="technical"] .site-fact-row,
[data-theme="technical"] .site-work-rows .site-work-item,
[data-theme="technical"] .site-show-row + .site-show-row { border-top: 1px solid var(--site-border); }
[data-theme="technical"] .site-links { border-bottom: 1px solid var(--site-border); }
[data-theme="technical"] .site-fact-label,
[data-theme="technical"] .site-link-meta,
[data-theme="technical"] .site-work-year,
[data-theme="technical"] .site-show-date,
[data-theme="technical"] .site-header-link {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
[data-theme="technical"] .site-link-label,
[data-theme="technical"] .site-work-title,
[data-theme="technical"] .site-show-venue { font-weight: 500; letter-spacing: -0.005em; }
[data-theme="technical"] .site-link-row:hover .site-link-label { color: var(--site-accent); }

[data-theme="technical"] .site-statement-text,
[data-theme="technical"] .site-cta-heading {
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.1;
}
[data-theme="technical"] .site-quote-text {
  font-style: normal;
  font-weight: 400;
  border-left: 1px solid var(--site-accent);
  padding-inline-start: 1rem;
}
[data-theme="technical"] .site-section-statement { background: var(--site-surface); }
[data-theme="technical"] .site-signup-input {
  border-radius: 0;
  border: 1px solid var(--site-border);
  background: transparent;
}

/* The title block: ruled, boxed, monospaced, bottom of sheet. */
[data-theme="technical"] .site-footer { border-top: 1px solid var(--site-text); }
[data-theme="technical"] .site-footer-inner {
  border: 1px solid var(--site-border);
  padding: 14px 18px;
}
[data-theme="technical"] .site-footer-copy,
[data-theme="technical"] .site-footer-link,
[data-theme="technical"] .site-footer-text {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Photographer attribution. Quiet enough to belong to the page, present enough
   to be a credit — Unsplash requires that a displayed photo names the
   photographer and links back, so this is a licence term wearing the clothes of
   a caption. It inherits the theme's secondary tone so it never fights the
   design it sits in. */
.site-credit {
  display: block;
  margin-top: 5px;
  font-size: 0.68rem;
  letter-spacing: 0.02em;
  color: var(--site-text-2);
  opacity: 0.75;
}
.site-credit a { color: inherit; text-underline-offset: 2px; }
.site-credit a:hover { opacity: 1; }

/* ==========================================================================
   LIGHTBOX — looking at the photograph
   ==========================================================================
 * A native <dialog>, so the focus trap, the inert backdrop, Escape-to-close
 * and focus restoration all come from the browser rather than from code that
 * would get one of them wrong.
 *
 * Deliberately neutral rather than themed: eleven themes disagree about
 * everything, and a picture being looked at full-size should sit on a quiet
 * ground in all of them. This is the one surface that is not an argument.
 * ========================================================================== */

.site-lightbox {
  border: 0;
  padding: 0;
  max-width: 100vw;
  max-height: 100vh;
  width: 100vw;
  height: 100dvh;
  background: rgba(8, 8, 9, 0.94);
  color: #f3f2ef;
  overflow: hidden;
}
.site-lightbox::backdrop { background: rgba(8, 8, 9, 0.9); }
.site-lightbox-figure {
  margin: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: clamp(1.5rem, 5vw, 4rem);
}
.site-lightbox-img {
  max-width: 100%;
  /* Leaves room for the caption without the image ever being cropped. */
  max-height: calc(100dvh - 8rem);
  width: auto;
  height: auto;
  object-fit: contain;
}
.site-lightbox-caption {
  font-size: 0.82rem;
  letter-spacing: 0.02em;
  color: rgba(243, 242, 239, 0.72);
  text-align: center;
  max-width: 60ch;
}
.site-lightbox-caption[hidden] { display: none; }
.site-lightbox-close {
  position: absolute;
  top: 12px; right: 16px;
  z-index: 1;
  width: 44px; height: 44px;   /* a real touch target, not a 16px glyph */
  border: 0;
  border-radius: 50%;
  background: rgba(243, 242, 239, 0.1);
  color: #f3f2ef;
  font: 400 26px/1 ui-sans-serif, system-ui, sans-serif;
  cursor: pointer;
}
.site-lightbox-close:hover { background: rgba(243, 242, 239, 0.2); }
.site-lightbox-close:focus-visible { outline: 2px solid #f3f2ef; outline-offset: 2px; }
/* Position in the set, for anyone arrowing through a long gallery. */
.site-lightbox[data-count]::after {
  content: attr(data-count);
  position: absolute;
  bottom: 14px; left: 50%;
  transform: translateX(-50%);
  font: 400 11px/1 ui-monospace, monospace;
  letter-spacing: 0.14em;
  color: rgba(243, 242, 239, 0.5);
}

/* The thumbnail advertises that it opens. */
.site-gallery-img[data-zoom] { cursor: zoom-in; }
.site-gallery-img[data-zoom]:focus-visible {
  outline: 2px solid var(--site-accent);
  outline-offset: 3px;
}

/* ==========================================================================
   SCALE + EDGE — the two dials that are not colour
   ==========================================================================
 * A theme decides how big display type runs against body copy, and how one
 * block is separated from the next. Those are the two things authors ask to
 * change most often and could previously only be had by switching theme.
 *
 * `scale` moves the DISPLAY face only — hero, section headings, statement,
 * quote, CTA. Body copy never moves, so this controls the contrast between the
 * two rather than zooming the page, and it cannot make anything unreadable.
 * ========================================================================== */

.site-root[data-scale="small"]  { --site-display-scale: 0.82; }
.site-root[data-scale="large"]  { --site-display-scale: 1.18; }
.site-root[data-scale="xlarge"] { --site-display-scale: 1.36; }

/* The multiplier is applied where each display size is DECLARED (--fs-base on
   .site-hero-heading, .site-heading, .site-statement-text, .site-cta-heading and
   .site-quote-text), not here. Setting font-size to a multiple of 1em at this
   level would resolve against the PARENT's size and throw the element's own
   clamp() away — which rendered a hero at body-copy size. */

/* Edge — rules and shadows, expressed as tokens the rest of the sheet already
   reads, so nothing here needs to know which theme it is in. */
.site-root[data-edge="bold"] { --site-border: color-mix(in srgb, var(--site-text) 42%, transparent); }
.site-root[data-edge="soft"] { --site-border: color-mix(in srgb, var(--site-text) 6%, transparent); }
.site-root[data-edge="lift"] { --site-border: color-mix(in srgb, var(--site-text) 20%, transparent); }
.site-root[data-edge="soft"] :is(.site-bg-surface, .site-gallery-img, .site-about-img, .site-work-thumb, .site-embed-ratio) {
  box-shadow: 0 18px 48px -24px color-mix(in srgb, var(--site-text) 40%, transparent);
}
.site-root[data-edge="lift"] :is(.site-bg-surface, .site-gallery-img, .site-about-img, .site-work-thumb, .site-embed-ratio) {
  box-shadow: 0 10px 22px -12px color-mix(in srgb, var(--site-text) 55%, transparent);
}
/* A shadow is depth cueing; high contrast wants an edge instead. */
@media (prefers-contrast: more) {
  .site-root[data-edge] :is(.site-bg-surface, .site-gallery-img, .site-about-img, .site-work-thumb, .site-embed-ratio) {
    box-shadow: none;
  }
  .site-root[data-edge="soft"] { --site-border: color-mix(in srgb, var(--site-text) 30%, transparent); }
}

/* ==========================================================================
   INTERACTION — how the page answers the cursor
   ==========================================================================
 * The motion system governs ENTRANCES: what happens when a section arrives.
 * This is the other half, and it was missing entirely — rows, media and
 * buttons had at most a background tint, identical on all eleven themes.
 *
 * `theme.overrides.hover` picks a house style. Stamped as data-hover on
 * .site-root by BOTH renderers.
 *
 * Rules this system obeys:
 *  - 'subtle' is a NO-OP. It is the default, and it resolves to exactly the
 *    base sheet's existing hover behaviour, so adding this enum changed nothing
 *    for any page already published. Only an author choosing something else
 *    moves anything.
 *  - Declared AFTER the theme blocks and at matching specificity, so an
 *    explicit choice beats a theme's own hover identity. Same principle as
 *    swiss and alignment: the theme owns the default, the author owns the
 *    decision.
 *  - Compositor-only. transform and opacity, plus colour. Nothing here can
 *    trigger layout, so none of it can jank a scroll.
 *  - Every treatment is mirrored onto :focus-visible. A keyboard visitor gets
 *    the same affordance a mouse does, which is the part that usually gets
 *    forgotten.
 *  - @media (hover: none) strips the hover states and re-hangs them on :active,
 *    because a touch device reports a "hover" that never ends.
 *  - prefers-reduced-motion drops every transform and keeps the colour.
 * ========================================================================== */

/* Families this applies to, named once. Rows are the ledger surfaces; media is
   anything with a picture in it; actions are the things you press. */

/* --- lift — the row steps aside behind a drawn accent bar ----------------- */
.site-root[data-hover="lift"] .site-link-row,
.site-root[data-hover="lift"] .site-work-rows .site-work-item,
.site-root[data-hover="lift"] .site-show-row { position: relative; }
.site-root[data-hover="lift"] .site-link-row::before,
.site-root[data-hover="lift"] .site-work-rows .site-work-item::before,
.site-root[data-hover="lift"] .site-show-row::before {
  content: "";
  position: absolute;
  left: -8px; top: 0; bottom: 0;
  width: 2px;
  background: var(--site-accent);
  transform: scaleY(0);
  transform-origin: 50% 0;
  transition: transform 0.24s cubic-bezier(.22,1,.36,1);
  pointer-events: none;
}
.site-root[data-hover="lift"] .site-link-row:hover,
.site-root[data-hover="lift"] .site-link-row:focus-visible,
.site-root[data-hover="lift"] .site-work-rows .site-work-item:hover,
.site-root[data-hover="lift"] .site-show-row:hover {
  transform: translateX(8px);
  background: transparent;
}
.site-root[data-hover="lift"] .site-link-row:hover::before,
.site-root[data-hover="lift"] .site-link-row:focus-visible::before,
.site-root[data-hover="lift"] .site-work-rows .site-work-item:hover::before,
.site-root[data-hover="lift"] .site-show-row:hover::before { transform: scaleY(1); }
.site-root[data-hover="lift"] .site-gallery-item:hover .site-gallery-img,
.site-root[data-hover="lift"] .site-work-item:hover .site-work-thumb {
  transform: translateY(-4px) scale(1.015);
}

/* --- underline — an accent rule wipes left to right ----------------------- */
.site-root[data-hover="underline"] .site-link-row,
.site-root[data-hover="underline"] .site-work-rows .site-work-item,
.site-root[data-hover="underline"] .site-show-row { position: relative; }
.site-root[data-hover="underline"] .site-link-row::after,
.site-root[data-hover="underline"] .site-work-rows .site-work-item::after,
.site-root[data-hover="underline"] .site-show-row::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: var(--site-accent);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 0.28s cubic-bezier(.22,1,.36,1);
  pointer-events: none;
}
.site-root[data-hover="underline"] .site-link-row:hover,
.site-root[data-hover="underline"] .site-link-row:focus-visible,
.site-root[data-hover="underline"] .site-work-rows .site-work-item:hover,
.site-root[data-hover="underline"] .site-show-row:hover { background: transparent; }
.site-root[data-hover="underline"] .site-link-row:hover::after,
.site-root[data-hover="underline"] .site-link-row:focus-visible::after,
.site-root[data-hover="underline"] .site-work-rows .site-work-item:hover::after,
.site-root[data-hover="underline"] .site-show-row:hover::after { transform: scaleX(1); }
.site-root[data-hover="underline"] .site-gallery-item:hover .site-gallery-caption,
.site-root[data-hover="underline"] .site-link-row:hover .site-link-label {
  color: var(--site-accent);
}

/* --- invert — the row fills with ink and the text flips ------------------- */
.site-root[data-hover="invert"] .site-link-row:hover,
.site-root[data-hover="invert"] .site-link-row:focus-visible,
.site-root[data-hover="invert"] .site-work-rows .site-work-item:hover,
.site-root[data-hover="invert"] .site-show-row:hover {
  background: var(--site-text);
  color: var(--site-bg);
}
.site-root[data-hover="invert"] .site-link-row:hover :is(.site-link-label, .site-link-sub, .site-link-meta, .site-link-host, .site-link-arrow),
.site-root[data-hover="invert"] .site-link-row:focus-visible :is(.site-link-label, .site-link-sub, .site-link-meta, .site-link-host, .site-link-arrow),
.site-root[data-hover="invert"] .site-work-rows .site-work-item:hover :is(.site-work-title, .site-work-meta, .site-work-year),
.site-root[data-hover="invert"] .site-show-row:hover :is(.site-show-venue, .site-show-city, .site-show-date, .site-show-note) {
  color: var(--site-bg);
}
.site-root[data-hover="invert"] .site-gallery-item:hover .site-gallery-img,
.site-root[data-hover="invert"] .site-work-item:hover .site-work-thumb { opacity: 0.72; }

/* --- none — a page that wants to be completely still ---------------------- */
.site-root[data-hover="none"] .site-link-row:hover,
.site-root[data-hover="none"] .site-work-rows .site-work-item:hover,
.site-root[data-hover="none"] .site-show-row:hover { background: transparent; }
.site-root[data-hover="none"] .site-link-row:hover .site-link-arrow { transform: none; }

/* --- actions: every style presses, none of them bounce -------------------- */
.site-root[data-hover="lift"] :is(.site-hero-cta, .site-signup-btn, .site-cta-btn, .site-header-cta, .site-show-tickets):hover,
.site-root[data-hover="underline"] :is(.site-hero-cta, .site-signup-btn, .site-cta-btn, .site-header-cta, .site-show-tickets):hover,
.site-root[data-hover="invert"] :is(.site-hero-cta, .site-signup-btn, .site-cta-btn, .site-header-cta, .site-show-tickets):hover {
  transform: translateY(-1px);
}
.site-root:not([data-hover="none"]) :is(.site-hero-cta, .site-signup-btn, .site-cta-btn, .site-header-cta, .site-show-tickets):active {
  transform: translateY(1px);
}

/* Shared transition for the moving parts, declared once. */
.site-root[data-hover="lift"] :is(.site-link-row, .site-work-item, .site-show-row, .site-gallery-img, .site-work-thumb),
.site-root[data-hover="underline"] :is(.site-link-row, .site-work-item, .site-show-row),
.site-root[data-hover="invert"] :is(.site-link-row, .site-work-item, .site-show-row, .site-gallery-img, .site-work-thumb),
.site-root :is(.site-hero-cta, .site-signup-btn, .site-cta-btn, .site-header-cta, .site-show-tickets) {
  transition: transform 0.22s cubic-bezier(.22,1,.36,1),
              background-color 0.18s ease, color 0.18s ease, opacity 0.22s ease;
}

/* --- Touch: a "hover" that never ends is not a hover ---------------------- */
@media (hover: none) {
  .site-root[data-hover] :is(.site-link-row, .site-work-item, .site-show-row):hover { transform: none; }
  .site-root[data-hover] :is(.site-link-row, .site-work-item, .site-show-row):hover::before,
  .site-root[data-hover] :is(.site-link-row, .site-work-item, .site-show-row):hover::after { transform: scaleY(0) scaleX(0); }
  /* …and the affordance moves to the press, which touch does have. */
  .site-root[data-hover="lift"] :is(.site-link-row, .site-work-item, .site-show-row):active::before { transform: scaleY(1); }
  .site-root[data-hover="underline"] :is(.site-link-row, .site-work-item, .site-show-row):active::after { transform: scaleX(1); }
  .site-root[data-hover="invert"] :is(.site-link-row, .site-work-item, .site-show-row):active {
    background: var(--site-text); color: var(--site-bg);
  }
}

/* --- Reduced motion: keep the colour, drop the movement ------------------- */
@media (prefers-reduced-motion: reduce) {
  .site-root[data-hover] :is(.site-link-row, .site-work-item, .site-show-row, .site-gallery-img, .site-work-thumb),
  .site-root :is(.site-hero-cta, .site-signup-btn, .site-cta-btn, .site-header-cta, .site-show-tickets) {
    transition: background-color 0.18s ease, color 0.18s ease;
    transform: none !important;
  }
  .site-root[data-hover] :is(.site-link-row, .site-work-item, .site-show-row)::before,
  .site-root[data-hover] :is(.site-link-row, .site-work-item, .site-show-row)::after {
    transition: none;
  }
  /* The bar and the rule still APPEAR — they just arrive rather than draw. */
  .site-root[data-hover="lift"] :is(.site-link-row, .site-work-item, .site-show-row):hover::before { transform: scaleY(1); }
  .site-root[data-hover="underline"] :is(.site-link-row, .site-work-item, .site-show-row):hover::after { transform: scaleX(1); }
}

/* --- In-page scrolling --------------------------------------------------- */
/* A nav that jump-cuts to a section throws away the visitor's sense of where
   they are. Applied to the scrolling element, which is <html>, not .site-root. */
html:has(.site-root[data-scroll="smooth"]) { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  /* A long smooth scroll is the exact vestibular trigger this setting exists
     for, so it wins outright. */
  html:has(.site-root[data-scroll="smooth"]) { scroll-behavior: auto; }
}

/* --- The companion cursor ------------------------------------------------ */
/* Additive, never a replacement: the system cursor stays exactly where it was.
   Built by siteRender.js only when the visitor has a fine pointer and has not
   asked for reduced motion — so this block styles something that simply does
   not exist in any other case. */
.site-cursor {
  position: fixed;
  left: 0; top: 0;
  z-index: 2147483000;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease, width 0.18s ease, height 0.18s ease,
              background-color 0.18s ease, border-color 0.18s ease;
  will-change: transform;
}
.site-cursor[data-visible="true"] { opacity: 1; }
.site-cursor[data-kind="dot"] {
  width: 9px; height: 9px;
  margin: -4.5px 0 0 -4.5px;
  border-radius: 50%;
  background: var(--site-accent, #E9B44C);
}
.site-cursor[data-kind="ring"] {
  width: 26px; height: 26px;
  margin: -13px 0 0 -13px;
  border-radius: 50%;
  border: 1.5px solid var(--site-accent, #E9B44C);
  background: transparent;
}
.site-cursor[data-kind="dot"][data-over="true"] {
  width: 26px; height: 26px;
  margin: -13px 0 0 -13px;
  background: color-mix(in srgb, var(--site-accent, #E9B44C) 35%, transparent);
}
.site-cursor[data-kind="ring"][data-over="true"] {
  width: 42px; height: 42px;
  margin: -21px 0 0 -21px;
  background: color-mix(in srgb, var(--site-accent, #E9B44C) 14%, transparent);
}
@media (prefers-reduced-motion: reduce) { .site-cursor { display: none; } }
@media (hover: none), (pointer: coarse) { .site-cursor { display: none; } }


/* ============ ATELIER — fashion, by subtraction ============
   Every other theme in this set fills the page. This one empties it. The
   argument is restraint: a hairline-light serif at display size, tracking wide
   enough to be a decision, and enough air that the type has to carry the whole
   composition. There is almost no colour, because a luxury page that reaches
   for an accent has stopped trusting its own typography.
   ============================================================ */
[data-theme="atelier"] .site-section { --site-pad: clamp(4.5rem, 12vw, 9rem); }
[data-theme="atelier"] .site-hero-heading {
  --fs-base: clamp(2.4rem, 1rem + 6vw, 5rem);
  font-weight: 300;
  letter-spacing: 0.06em;
  line-height: 1.14;
  text-transform: uppercase;
  font-variation-settings: 'opsz' 144, 'WONK' 0;
}
[data-theme="atelier"] .site-section-hero { min-height: min(84svh, 760px); }
[data-theme="atelier"] .site-hero-tagline {
  font-size: 0.95rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--site-text-2); max-width: 44ch;
}
[data-theme="atelier"] .site-heading {
  --fs-base: 0.72rem;
  font-family: var(--site-font-body);
  font-weight: 400; letter-spacing: 0.34em; text-transform: uppercase;
  color: var(--site-text-2);
}
[data-theme="atelier"] .site-heading-count { display: none; }
[data-theme="atelier"] .site-statement-text,
[data-theme="atelier"] .site-quote-text {
  font-weight: 300; font-style: normal; letter-spacing: 0.03em; line-height: 1.4;
}
[data-theme="atelier"] :is(.site-hero-cta, .site-signup-btn, .site-cta-btn, .site-header-cta, .site-show-tickets) {
  background: transparent; color: var(--site-text);
  border: 1px solid var(--site-text); border-radius: 0;
  letter-spacing: 0.22em; text-transform: uppercase; font-size: 0.68rem;
  padding-inline: 2em;
}
[data-theme="atelier"] :is(.site-hero-cta, .site-signup-btn, .site-cta-btn, .site-header-cta):hover {
  background: var(--site-text); color: var(--site-bg);
}
[data-theme="atelier"] :is(.site-link-row, .site-fact-row, .site-work-rows .site-work-item, .site-show-row + .site-show-row) {
  border-top: 1px solid var(--site-border);
}
[data-theme="atelier"] :is(.site-link-label, .site-work-title, .site-fact-label, .site-show-venue) {
  font-weight: 400; letter-spacing: 0.14em; text-transform: uppercase; font-size: 0.8rem;
}
[data-theme="atelier"] :is(.site-gallery-img, .site-about-img, .site-work-thumb, .site-embed) { border-radius: 0; }
[data-theme="atelier"] .site-gallery-grid { gap: clamp(1.5rem, 4vw, 3.5rem); }
[data-theme="atelier"] .site-footer { border-top: 1px solid var(--site-border); }
[data-theme="atelier"] :is(.site-footer-link, .site-footer-copy, .site-header-link) {
  letter-spacing: 0.2em; text-transform: uppercase; font-size: 0.66rem;
}

/* ============ ARCHIVE — a catalogue, not a poster ============
   The only theme where MORE on screen is the point. Tight rhythm, numbered
   sections, tabular figures, and rules on every row: the page reads as an
   index of a body of work rather than a pitch for it. Right for anyone whose
   answer to "what do you do" is a long list.
   ============================================================= */
[data-theme="archive"] { font-size: 15px; }
[data-theme="archive"] .site-section { --site-pad: clamp(1.75rem, 4vw, 3rem); }
[data-theme="archive"] .site-section + .site-section { border-top: 1px solid var(--site-text); }
[data-theme="archive"] .site-hero-heading {
  --fs-base: clamp(1.9rem, 1rem + 3.4vw, 3.2rem);
  font-weight: 700; letter-spacing: -0.02em; line-height: 1.02;
  font-stretch: 112%;
}
[data-theme="archive"] .site-section-hero { min-height: 0; }
[data-theme="archive"] .site-heading {
  --fs-base: 0.7rem;
  text-transform: uppercase; letter-spacing: 0.16em; font-weight: 700;
}
[data-theme="archive"] .site-heading-count {
  color: var(--site-accent); font-variant-numeric: tabular-nums; font-weight: 700;
}
[data-theme="archive"] .site-root,
[data-theme="archive"] :is(.site-work-year, .site-show-date, .site-fact-value) {
  font-variant-numeric: tabular-nums;
}
[data-theme="archive"] :is(.site-link-row, .site-fact-row, .site-work-rows .site-work-item, .site-show-row + .site-show-row) {
  border-top: 1px solid var(--site-border);
  padding-block: 7px;
}
[data-theme="archive"] :is(.site-link-label, .site-work-title, .site-show-venue) {
  font-weight: 600; font-size: 0.92rem; letter-spacing: -0.005em;
}
[data-theme="archive"] :is(.site-link-meta, .site-work-meta, .site-fact-label) {
  font-size: 0.74rem; letter-spacing: 0.06em; text-transform: uppercase;
}
[data-theme="archive"] .site-gallery-grid { gap: 4px; }
[data-theme="archive"] :is(.site-gallery-img, .site-work-thumb, .site-about-img, .site-embed) { border-radius: 0; }
[data-theme="archive"] :is(.site-hero-cta, .site-signup-btn, .site-cta-btn, .site-header-cta, .site-show-tickets) {
  border-radius: 0; background: var(--site-accent); color: #fff;
  text-transform: uppercase; letter-spacing: 0.1em; font-size: 0.72rem; font-weight: 700;
}
[data-theme="archive"] .site-body p { max-width: 68ch; }
[data-theme="archive"] .site-footer { border-top: 2px solid var(--site-text); }

/* ============ SALON — the room the work hangs in ============
   `paper` is a printed book; this is a gallery. Warm ground, ink-brown text,
   and frames with real margin around them — the mount board, not the poster.
   Headings sit centred and small above the work rather than shouting over it.
   ============================================================= */
[data-theme="salon"] { font-size: 17px; }
[data-theme="salon"] .site-section { --site-pad: clamp(3.5rem, 8vw, 6rem); }
[data-theme="salon"] .site-hero-heading {
  --fs-base: clamp(2.2rem, 1rem + 5vw, 4rem);
  font-weight: 400; letter-spacing: -0.01em; line-height: 1.16;
}
[data-theme="salon"] .site-hero-tagline { font-style: italic; color: var(--site-text-2); }
[data-theme="salon"] .site-heading {
  --fs-base: 0.82rem;
  font-family: var(--site-font-body);
  font-variant-caps: all-small-caps; letter-spacing: 0.2em; font-weight: 500;
  color: var(--site-text-2);
}
[data-theme="salon"] .site-heading-count { color: var(--site-accent); }
/* The mount: a wide pale border around every frame. */
[data-theme="salon"] :is(.site-gallery-img, .site-about-img, .site-work-thumb) {
  border-radius: 2px;
  border: 10px solid var(--site-surface);
  box-shadow: 0 1px 0 var(--site-border);
}
[data-theme="salon"] .site-gallery-grid { gap: clamp(1.25rem, 3vw, 2.5rem); }
[data-theme="salon"] .site-gallery-caption {
  font-style: italic; font-size: 0.8rem; color: var(--site-text-2);
}
[data-theme="salon"] .site-quote-text { font-style: italic; font-weight: 400; }
[data-theme="salon"] .site-statement-text { font-style: italic; font-weight: 400; line-height: 1.28; }
[data-theme="salon"] :is(.site-hero-cta, .site-signup-btn, .site-cta-btn, .site-header-cta, .site-show-tickets) {
  border-radius: 999px; background: var(--site-accent); color: #fff;
  letter-spacing: 0.06em; font-size: 0.82rem;
  padding-inline: 1.8em;
}
[data-theme="salon"] :is(.site-link-row, .site-fact-row, .site-show-row + .site-show-row) {
  border-top: 1px solid var(--site-border);
}
[data-theme="salon"] .site-footer { border-top: 1px solid var(--site-border); }

/* ============ TERMINAL — a well-configured shell ============
   Monospace throughout, a blinking cursor after the name, and section labels
   written as prompts. Not a novelty: for a developer portfolio this IS the
   professional register, the way a drawing sheet is for an architect.
   ============================================================ */
[data-theme="terminal"] .site-root,
[data-theme="terminal"] .site-body p,
[data-theme="terminal"] .site-blurb,
[data-theme="terminal"] .site-hero-tagline {
  font-family: 'Space Mono', ui-monospace, monospace;
}
[data-theme="terminal"] .site-section { --site-pad: clamp(2.25rem, 5vw, 3.5rem); }
[data-theme="terminal"] .site-hero-heading {
  --fs-base: clamp(1.7rem, 1rem + 3vw, 3rem);
  font-weight: 700; letter-spacing: -0.02em; line-height: 1.12;
}
/* The cursor. Steady for anyone who asked for less motion. */
[data-theme="terminal"] .site-hero-heading::after {
  content: "_";
  color: var(--site-accent);
  animation: terminal-caret 1.1s steps(1) infinite;
}
@keyframes terminal-caret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  [data-theme="terminal"] .site-hero-heading::after { animation: none; opacity: 1; }
}
[data-theme="terminal"] .site-heading {
  --fs-base: 0.8rem;
  font-weight: 400; letter-spacing: 0.02em; text-transform: lowercase;
  color: var(--site-text-2);
}
[data-theme="terminal"] .site-heading::before {
  content: "~/ ";
  color: var(--site-accent);
}
[data-theme="terminal"] .site-heading-count { display: none; }
[data-theme="terminal"] :is(.site-link-row, .site-fact-row, .site-work-rows .site-work-item, .site-show-row + .site-show-row) {
  border-top: 1px dashed var(--site-border);
}
[data-theme="terminal"] :is(.site-link-label, .site-work-title, .site-show-venue) { font-weight: 700; }
[data-theme="terminal"] .site-link-row::before {
  content: "› "; color: var(--site-accent);
}
[data-theme="terminal"] :is(.site-hero-cta, .site-signup-btn, .site-cta-btn, .site-header-cta, .site-show-tickets) {
  border-radius: 3px; background: transparent;
  border: 1px solid var(--site-accent); color: var(--site-accent);
  font-family: 'Space Mono', ui-monospace, monospace;
  letter-spacing: 0.04em; font-size: 0.78rem;
}
[data-theme="terminal"] :is(.site-hero-cta, .site-signup-btn, .site-cta-btn, .site-header-cta):hover {
  background: var(--site-accent); color: var(--site-bg);
}
[data-theme="terminal"] :is(.site-gallery-img, .site-about-img, .site-work-thumb, .site-embed) {
  border-radius: 3px; border: 1px solid var(--site-border);
}
[data-theme="terminal"] .site-quote-text {
  font-style: normal; border-left: 2px solid var(--site-accent); padding-inline-start: 1rem;
}
[data-theme="terminal"] .site-statement-text { font-weight: 700; letter-spacing: -0.01em; }
[data-theme="terminal"] .site-footer { border-top: 1px dashed var(--site-border); }

/* --- Face fitness — a swapped-in display face must not inherit another
   face's axes. Keyed off data-display; declared after theme blocks. -------- */
[data-display="instrument"] .site-hero-heading, [data-display="instrument"] .site-statement-text,
[data-display="instrument"] .site-cta-heading, [data-display="instrument"] .site-quote-text,
[data-display="newsreader"] .site-hero-heading, [data-display="newsreader"] .site-statement-text,
[data-display="newsreader"] .site-cta-heading, [data-display="newsreader"] .site-quote-text {
  font-weight: 500; font-stretch: 100%; font-variation-settings: normal;
}
[data-display="fraunces"] .site-hero-heading, [data-display="fraunces"] .site-statement-text,
[data-display="fraunces"] .site-cta-heading {
  font-weight: 560; font-stretch: 100%; font-variation-settings: 'opsz' 144, 'WONK' 1;
}
[data-display="spacemono"] .site-hero-heading, [data-display="spacemono"] .site-statement-text,
[data-display="spacemono"] .site-cta-heading, [data-display="spacemono"] .site-quote-text {
  font-weight: 400; font-stretch: 100%; letter-spacing: -0.01em; font-variation-settings: normal;
}
[data-display="syne"] .site-hero-heading { font-stretch: 100%; }
[data-display="unbounded"] .site-hero-heading, [data-display="unbounded"] .site-statement-text,
[data-display="unbounded"] .site-cta-heading {
  font-weight: 700; font-stretch: 100%; font-variation-settings: normal;
}
[data-display="geist"] .site-hero-heading { font-stretch: 100%; font-variation-settings: normal; }

/* --- Display case override ------------------------------------------------- */
[data-case="caps"] .site-hero-heading, [data-case="caps"] .site-statement-text,
[data-case="caps"] .site-cta-heading {
  text-transform: uppercase; letter-spacing: 0.04em; line-height: 1.05;
}
[data-case="normal"] .site-hero-heading, [data-case="normal"] .site-statement-text,
[data-case="normal"] .site-cta-heading {
  text-transform: none; letter-spacing: -0.005em;
}

/* --- Corner style override (sharp | soft | round) ---------------------------
   Wins over theme identity radii by declaration order + !important on the
   concrete consumers (themes set radii per-selector, not via tokens). */
[data-radius="sharp"] .site-hero-cta, [data-radius="sharp"] .site-signup-btn,
[data-radius="sharp"] .site-show-tickets, [data-radius="sharp"] .site-cta-btn,
[data-radius="sharp"] .site-contact-email, [data-radius="sharp"] .site-signup-input,
[data-radius="sharp"] .site-link-row, [data-radius="sharp"] .site-show-row,
[data-radius="sharp"] .site-embed, [data-radius="sharp"] .site-embed-ratio,
[data-radius="sharp"] .site-gallery-img, [data-radius="sharp"] .site-about-img,
[data-radius="sharp"] .site-work-thumb, [data-radius="sharp"] .site-hero-bg,
[data-radius="sharp"] .site-hero-scrim, [data-radius="sharp"] .site-section-statement,
[data-radius="sharp"] .site-section-signup .site-section-inner,
[data-radius="sharp"] .site-section-quote .site-section-inner,
[data-radius="sharp"] .site-section-cta .site-section-inner,
[data-radius="sharp"] .site-fact-row, [data-radius="sharp"] .site-work-rows .site-work-item,
[data-radius="sharp"] .site-testimonial, [data-radius="sharp"] .site-faq-item,
[data-radius="sharp"] .site-count-unit,
[data-radius="sharp"] .site-footer { border-radius: 0 !important; }

[data-radius="soft"] .site-hero-cta, [data-radius="soft"] .site-signup-btn,
[data-radius="soft"] .site-show-tickets, [data-radius="soft"] .site-cta-btn { border-radius: 6px !important; }
[data-radius="soft"] .site-embed, [data-radius="soft"] .site-embed-ratio,
[data-radius="soft"] .site-gallery-img, [data-radius="soft"] .site-about-img,
[data-radius="soft"] .site-work-thumb { border-radius: 10px !important; }
[data-radius="soft"] .site-link-row, [data-radius="soft"] .site-show-row,
[data-radius="soft"] .site-fact-row, [data-radius="soft"] .site-testimonial,
[data-radius="soft"] .site-faq-item, [data-radius="soft"] .site-count-unit { border-radius: 10px !important; }
[data-radius="soft"] .site-section-statement,
[data-radius="soft"] .site-section-signup .site-section-inner,
[data-radius="soft"] .site-section-cta .site-section-inner { border-radius: 14px !important; }

[data-radius="round"] .site-hero-cta, [data-radius="round"] .site-signup-btn,
[data-radius="round"] .site-show-tickets, [data-radius="round"] .site-cta-btn,
[data-radius="round"] .site-contact-email, [data-radius="round"] .site-signup-input { border-radius: 999px !important; }
[data-radius="round"] .site-embed, [data-radius="round"] .site-embed-ratio,
[data-radius="round"] .site-gallery-img, [data-radius="round"] .site-about-img,
[data-radius="round"] .site-work-thumb { border-radius: 16px !important; }
[data-radius="round"] .site-link-row, [data-radius="round"] .site-show-row,
[data-radius="round"] .site-fact-row, [data-radius="round"] .site-testimonial,
[data-radius="round"] .site-faq-item, [data-radius="round"] .site-count-unit { border-radius: 16px !important; }
[data-radius="round"] .site-section-statement,
[data-radius="round"] .site-section-signup .site-section-inner,
[data-radius="round"] .site-section-cta .site-section-inner { border-radius: 24px !important; }

/* --- Body face (mono nit: synthesized bold is acceptable) ------------------- */
[data-body="spacemono"] .site-root, [data-body="spacemono"] .site-body p { letter-spacing: -0.01em; }

/* --- Site header -------------------------------------------------------------
 * A ten-section page with no navigation is a scroll, not a site. This is the
 * chrome that makes it navigable: wordmark, section links, one optional CTA.
 * Three styles share one skeleton — the differences are alignment and weight,
 * not three separate layouts to keep in sync.
 *
 * Colours come from the same --site-* tokens every section uses, so the header
 * belongs to whatever theme and palette the author picked without a single
 * per-theme override. */

.site-header {
  position: relative;
  z-index: 20;
  background: var(--site-bg);
  border-bottom: 1px solid var(--site-border);
}

/* Sticky is opt-out, not opt-in: a long page is exactly where you want the nav
   to stay. The translucent fill needs a fallback for browsers without
   backdrop-filter, or the header goes transparent over scrolling content. */
.site-header[data-sticky] {
  position: sticky;
  top: 0;
}
@supports (backdrop-filter: blur(12px)) or (-webkit-backdrop-filter: blur(12px)) {
  .site-header[data-sticky] {
    background: color-mix(in srgb, var(--site-bg) 82%, transparent);
    -webkit-backdrop-filter: saturate(140%) blur(12px);
    backdrop-filter: saturate(140%) blur(12px);
  }
}

.site-header-inner {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 5vw, 2rem);
  min-height: 62px;
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2rem);
}

.site-header-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  text-decoration: none;
  color: var(--site-text);
  font-family: var(--site-font-display, var(--site-font-head, inherit));
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: -0.01em;
  /* The wordmark never wraps or shrinks — the nav yields first. */
  flex: none;
  white-space: nowrap;
}
.site-header-logo { height: 26px; width: auto; display: block; }

.site-header-nav {
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 2.2vw, 1.75rem);
  margin-left: auto;
  min-width: 0;
}

.site-header-link {
  color: var(--site-text-2);
  text-decoration: none;
  font-size: 0.875rem;
  white-space: nowrap;
  transition: color 160ms ease;
}
.site-header-link:hover { color: var(--site-text); }

.site-header-cta {
  flex: none;
  display: inline-flex;
  align-items: center;
  padding: 0.5rem 1rem;
  border: 1px solid var(--site-accent);
  border-radius: var(--site-radius, 4px);
  background: var(--site-accent);
  color: var(--site-bg);
  text-decoration: none;
  font-size: 0.83rem;
  font-weight: 600;
  white-space: nowrap;
  transition: opacity 160ms ease;
}
.site-header-cta:hover { opacity: 0.85; }
/* With no nav to push it, the CTA still sits right. */
.site-header-nav + .site-header-cta { margin-left: 0; }
.site-header-brand + .site-header-cta { margin-left: auto; }

/* Style variants ------------------------------------------------------------ */
/* bar — heavier rule, the nav reads as a toolbar. */
.site-header[data-style="bar"] { border-bottom-width: 2px; }
.site-header[data-style="bar"] .site-header-link {
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
/* centered — wordmark over nav, the editorial masthead. */
.site-header[data-style="centered"] .site-header-inner {
  flex-direction: column;
  gap: 0.5rem;
  padding-block: 0.9rem;
}
.site-header[data-style="centered"] .site-header-nav { margin-left: 0; }
.site-header[data-style="centered"] .site-header-brand { font-size: 1.15rem; }

/* Mobile menu ---------------------------------------------------------------
 * <details>/<summary> — opens, closes and is keyboard-operable with no
 * JavaScript at all, the same reasoning as the FAQ section. Hidden above the
 * breakpoint; it replaces the inline nav below it. */
.site-header-menu { display: none; position: relative; margin-left: auto; flex: none; }
.site-header-menu-btn {
  list-style: none;
  cursor: pointer;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: var(--site-radius, 4px);
}
.site-header-menu-btn::-webkit-details-marker { display: none; }
/* Three rules drawn from one element — no icon font, no inline SVG. */
.site-header-menu-bars,
.site-header-menu-bars::before,
.site-header-menu-bars::after {
  display: block;
  width: 20px;
  height: 2px;
  background: var(--site-text);
  content: '';
  position: relative;
}
.site-header-menu-bars::before { top: -6px; position: absolute; }
.site-header-menu-bars::after { top: 6px; position: absolute; }

.site-header-menu-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  min-width: 190px;
  display: flex;
  flex-direction: column;
  padding: 0.4rem;
  background: var(--site-surface);
  border: 1px solid var(--site-border);
  border-radius: var(--site-radius, 6px);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.28);
}
.site-header-menu-link {
  padding: 0.6rem 0.7rem;
  color: var(--site-text);
  text-decoration: none;
  font-size: 0.92rem;
  border-radius: 4px;
}
.site-header-menu-link:hover { background: var(--site-bg); }
.site-header-menu-cta { color: var(--site-accent); font-weight: 600; }

@media (max-width: 760px) {
  .site-header-nav { display: none; }
  /* The CTA earns its place in the panel on a phone rather than crowding the
     wordmark next to a menu button. */
  .site-header-inner > .site-header-cta { display: none; }
  .site-header-menu { display: block; }
  .site-header[data-style="centered"] .site-header-inner { flex-direction: row; }
}

/* An anchor jump must not land the section under a sticky header. */
.site-root:has(.site-header[data-sticky]) { scroll-padding-top: 74px; }
html:has(.site-header[data-sticky]) { scroll-padding-top: 74px; }

/* --- Footer links ------------------------------------------------------------ */
.site-footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.1rem;
  justify-content: center;
}
.site-footer-text {
  display: block;
  color: var(--site-text-2);
  font-size: 0.85rem;
  line-height: 1.5;
  max-width: 60ch;
}

/* --- Marquee -----------------------------------------------------------------
 * A looping ticker. The track holds the item list twice and travels exactly
 * -50%, so the moment it finishes the second copy is sitting where the first
 * started — the restart is invisible and nothing has to be measured.
 * Duration arrives as --mq-dur from a closed enum in the renderer. */
.site-section-marquee > .site-section-inner { max-width: none; padding: 0; }

.site-marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.site-marquee-track {
  display: flex;
  width: max-content;
  animation: site-mq var(--mq-dur, 30s) linear infinite;
  will-change: transform;
}
.site-marquee-track[data-dir="right"] { animation-direction: reverse; }
/* Reading the words is more important than watching them move. */
.site-marquee:hover .site-marquee-track { animation-play-state: paused; }
.site-marquee-run { display: flex; align-items: center; flex: none; }

.site-marquee-item,
.site-marquee-sep {
  font-family: var(--site-font-display, var(--site-font-head, inherit));
  font-size: clamp(1.5rem, 0.9rem + 2vw, 2.6rem);
  line-height: 1.1;
  white-space: nowrap;
  padding: 0 0.45em;
  color: var(--site-text);
}
.site-marquee-sep { color: var(--site-accent); }
.site-marquee[data-size="large"] .site-marquee-item,
.site-marquee[data-size="large"] .site-marquee-sep {
  font-size: clamp(2.4rem, 1.2rem + 4.5vw, 5.5rem);
  font-weight: 600;
  letter-spacing: -0.02em;
}

@keyframes site-mq {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(-50%, 0, 0); }
}

/* Motion off: the phrases are still the content, so show them standing still
   rather than hiding a section the author added. */
@media (prefers-reduced-motion: reduce) {
  .site-marquee-track { animation: none; }
  .site-marquee { mask-image: none; -webkit-mask-image: none; overflow-x: auto; }
}
.site-root[data-motion="none"] .site-marquee-track { animation: none; }

/* --- Split-text reveal --------------------------------------------------------
 * Each word rises on its own short delay. The words are ordinary inline spans
 * with real spaces between them, so selection, copy and screen readers are
 * unaffected — this is presentation only. */
[data-split] .site-word {
  display: inline-block;
  will-change: transform, opacity;
}
.site-pre [data-split] .site-word,
.site-section[data-reveal].site-pre [data-split] .site-word {
  opacity: 0;
  transform: translateY(0.55em);
}
.site-in [data-split] .site-word {
  opacity: 1;
  transform: none;
  transition:
    opacity 640ms cubic-bezier(0.22, 1, 0.36, 1) calc(var(--w-i, 0) * 48ms),
    transform 780ms cubic-bezier(0.22, 1, 0.36, 1) calc(var(--w-i, 0) * 48ms);
}
@media (prefers-reduced-motion: reduce) {
  [data-split] .site-word { opacity: 1 !important; transform: none !important; transition: none; }
}

/* --- Parallax ------------------------------------------------------------------
 * The renderer writes --px-y from scroll position; CSS owns the composite so
 * the work stays off the layout path. scale() gives the travel somewhere to go
 * without exposing an edge. */
[data-parallax] {
  transform: translate3d(0, var(--px-y, 0px), 0) scale(1.12);
  will-change: transform;
}
.site-about-img[data-parallax] { transform: translate3d(0, var(--px-y, 0px), 0) scale(1.06); }
@media (prefers-reduced-motion: reduce) {
  [data-parallax] { transform: none; }
}

/* --- Split hero ---------------------------------------------------------------
 * The image sits BESIDE the type instead of behind it. No scrim and no
 * centring: the copy keeps a real measure and a normal left edge, which is why
 * this reads as a considered layout rather than a caption over a photograph. */
.site-section-hero[data-hero-layout="split"] {
  align-items: center;
  min-height: min(64svh, 620px);
}
.site-section-hero[data-hero-layout="split"] > .site-section-inner { max-width: 1120px; }

.site-hero-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.75rem, 5vw, 4rem);
  align-items: center;
  width: 100%;
}
/* The figure can lead instead of follow. */
.site-hero-split[data-figure="left"] .site-hero-copy { order: 2; }

/* Whatever the theme does to centre a cover hero, split copy is set flush. */
.site-root .site-section-hero[data-hero-layout="split"] .site-hero-copy,
.site-root .site-section-hero[data-hero-layout="split"] .site-hero-copy * {
  text-align: left;
  margin-left: 0;
  margin-right: 0;
}
.site-hero-split .site-hero-heading { max-width: 16ch; }
.site-hero-split .site-hero-tagline { max-width: 42ch; }

.site-hero-figure {
  display: block;
  width: 100%;
  height: auto;
  max-height: 74svh;
  object-fit: cover;
}

@media (max-width: 760px) {
  .site-hero-split { grid-template-columns: 1fr; gap: clamp(1.25rem, 5vw, 2rem); }
  /* On one column the picture belongs under the words, whichever side it took
     on a wide screen — the headline is what the visitor came for. */
  .site-hero-split[data-figure="left"] .site-hero-copy { order: 0; }
  .site-hero-figure { max-height: 46svh; }
}

/* ==========================================================================
   TEXTURE — the material the theme is printed on
   ==========================================================================
 * Six presets built from type, colour and spacing alone all read as the same
 * minimal template because none of them has any SURFACE. `theme.overrides
 * .texture` gives a page a substrate: engineering grid, dot screen, halftone,
 * laid paper, atmospheric mesh, or film grain. Stamped as data-texture on
 * .site-root by BOTH renderers (siteRender.js and functions/s/_ssr.ts).
 *
 * Rules this system obeys:
 *  - Self-contained. CSS gradients, plus ONE inline SVG data-URI for grain
 *    (noise is the one thing gradients genuinely cannot make). No requests.
 *  - Derived, never hardcoded. Every treatment inks with
 *    color-mix(var(--site-text)) — so it re-tones itself for every palette
 *    variant and accent override, and INSIDE an inverted band, where
 *    .site-bg-inverted swaps --site-text, the texture flips with it.
 *  - Behind the content. The five substrate treatments are extra
 *    background-image LAYERS on surfaces that already paint a background —
 *    the root, and the surface/inverted bands. Nothing is added to the DOM,
 *    nothing is positioned, nothing can affect layout or take a pointer.
 *    Grain is the deliberate exception: it is a film stock, not a substrate,
 *    so it rides on top of everything as one fixed, inert, masked overlay.
 *  - Selectors are attribute-only ([data-texture="x"], not
 *    .site-root[data-texture="x"]) so the editor can paint a real specimen of
 *    each treatment in its picker instead of a hand-copied approximation.
 *
 * Selector shape per treatment:
 *    [data-texture="x"]                             the page (and specimens)
 *    .site-root[…] :is(.site-bg-surface, .site-bg-inverted)   colour bands
 *    .site-root[…][data-theme="studio"] .site-section-cta     studio's band
 * Each has higher specificity than the `background:` shorthand it layers on,
 * so the surface keeps its own background-COLOR and gains an image. */

/* Ink steps. Re-declared on every surface that paints, so each resolves
   against THAT surface's --site-text (a custom property's var()s resolve
   where the property is DECLARED, not where it is used). */
[data-texture],
.site-root[data-texture] :is(.site-bg-surface, .site-bg-inverted),
.site-root[data-texture][data-theme="studio"] .site-section-cta {
  --tex-1: color-mix(in srgb, var(--site-text) 3.5%, transparent);
  --tex-2: color-mix(in srgb, var(--site-text) 6%, transparent);
  --tex-3: color-mix(in srgb, var(--site-text) 9%, transparent);
  --tex-4: color-mix(in srgb, var(--site-text) 14%, transparent);
}

/* --- grid — engineering paper ------------------------------------------------
   A fine 24px rule with a heavier 120px module over it, so the page reads as
   ruled stock rather than as graph-paper wallpaper. */
[data-texture="grid"],
.site-root[data-texture="grid"] :is(.site-bg-surface, .site-bg-inverted),
.site-root[data-texture="grid"][data-theme="studio"] .site-section-cta {
  background-image:
    linear-gradient(to right, var(--tex-3) 1px, transparent 1px),
    linear-gradient(to bottom, var(--tex-3) 1px, transparent 1px),
    linear-gradient(to right, var(--tex-1) 1px, transparent 1px),
    linear-gradient(to bottom, var(--tex-1) 1px, transparent 1px);
  background-size: 120px 120px, 120px 120px, 24px 24px, 24px 24px;
  background-position: 0 0;
  background-repeat: repeat;
}

/* --- dots — Swiss dot grid ---------------------------------------------------
   One orthogonal lattice, generous pitch. Reads as measured, not decorated. */
[data-texture="dots"],
.site-root[data-texture="dots"] :is(.site-bg-surface, .site-bg-inverted),
.site-root[data-texture="dots"][data-theme="studio"] .site-section-cta {
  background-image:
    radial-gradient(circle at 50% 50%, var(--tex-4) 1.1px, transparent 1.7px);
  background-size: 20px 20px;
  background-position: 0 0;
  background-repeat: repeat;
}

/* --- halftone — print screen -------------------------------------------------
   Two lattices offset by half a tile: a 45° screen at a ~6.4px pitch, which is
   what a coarse print halftone at a flat tone actually is. Bigger dots and a
   much tighter pitch than `dots` — the two never read as the same thing. */
[data-texture="halftone"],
.site-root[data-texture="halftone"] :is(.site-bg-surface, .site-bg-inverted),
.site-root[data-texture="halftone"][data-theme="studio"] .site-section-cta {
  background-image:
    radial-gradient(circle at 50% 50%, var(--tex-4) 1.5px, transparent 2px),
    radial-gradient(circle at 50% 50%, var(--tex-4) 1.5px, transparent 2px);
  background-size: 9px 9px, 9px 9px;
  background-position: 0 0, 4.5px 4.5px;
  background-repeat: repeat;
}

/* --- paper — laid stock ------------------------------------------------------
   Close-set horizontal laid lines with widely-spaced vertical chain lines:
   the actual structure of laid paper, at sub-pixel weight so the browser
   anti-aliases it into a tooth rather than a screen door. */
[data-texture="paper"],
.site-root[data-texture="paper"] :is(.site-bg-surface, .site-bg-inverted),
.site-root[data-texture="paper"][data-theme="studio"] .site-section-cta {
  background-image:
    repeating-linear-gradient(0deg, var(--tex-2) 0 0.5px, transparent 0.5px 4px),
    repeating-linear-gradient(90deg, var(--tex-1) 0 1px, transparent 1px 30px);
  background-size: auto;
  background-position: 0 0;
  background-repeat: repeat;
}

/* --- mesh — atmosphere -------------------------------------------------------
   The one treatment that is light rather than tooth: three enormous, very soft
   blooms drawn from the accent and the ink. Deliberately NOT painted on colour
   bands — a 200px band showing a slice of a 1600px bloom reads as a stain, and
   a solid band interrupting an atmosphere is correct anyway. */
[data-texture="mesh"] {
  background-image:
    radial-gradient(58% 42% at 8% 6%, color-mix(in srgb, var(--site-accent) 15%, transparent) 0%, transparent 70%),
    radial-gradient(52% 38% at 92% 30%, color-mix(in srgb, var(--site-text) 8%, transparent) 0%, transparent 72%),
    radial-gradient(64% 46% at 46% 94%, color-mix(in srgb, var(--site-accent) 10%, transparent) 0%, transparent 74%);
  background-size: 100% 1600px;
  background-position: 0 0;
  background-repeat: repeat;
}

/* --- grain — film stock ------------------------------------------------------
   Noise is the one texture CSS gradients cannot make, so this is a single
   inline SVG feTurbulence tile — ~330 bytes, seamless (stitchTiles), no
   request. It is used as a MASK over a solid var(--site-text) plate, which is
   what keeps the grain token-derived: dark grain on a light page, light grain
   on a dark one, without the stylesheet ever knowing which it is.
   `background-blend-mode: overlay` was the alternative and is wrong — overlay
   collapses to nothing at both ends of the tonal range, i.e. on exactly the
   near-black and near-white backgrounds these themes use.
   Fixed and above the header (z-index 20) because film grain sits on the lens,
   not on the page; inert and unmeasured, so it cannot touch layout or input. */
[data-texture="grain"]::after {
  content: "";
  /* Contained by default so a specimen tile in the editor's picker gets grain
     inside ITS 56px box. Only the page root promotes it to the viewport —
     without that split, an editor swatch would throw a fixed grain plate over
     the whole editor chrome, which is where this rule is read outside /s/. */
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-color: var(--site-text, #F4F1EA);
  opacity: 0.07;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.7 0.7 0.7 0 -0.5'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.7 0.7 0.7 0 -0.5'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)'/%3E%3C/svg%3E");
  -webkit-mask-size: 160px 160px;
  mask-size: 160px 160px;
  -webkit-mask-repeat: repeat;
  mask-repeat: repeat;
}

/* On the page itself grain is film stock, not a substrate: it rides on the
   lens, above the header (z-index 20), and does not scroll with the content. */
.site-root[data-texture="grain"]::after {
  position: fixed;
  z-index: 21;
}

/* A texture is a finish, and a finish is the first thing to go when someone
   has asked the OS for higher contrast. */
@media (prefers-contrast: more) {
  [data-texture]:not([data-texture="none"]),
  .site-root[data-texture] :is(.site-bg-surface, .site-bg-inverted),
  .site-root[data-texture][data-theme="studio"] .site-section-cta { background-image: none; }
  [data-texture="grain"]::after { display: none; }
}

/* =========================================================================
   Pointer effects (data-hoverfx, per section)

   siteRender publishes NUMBERS only — --fx-rx/--fx-ry (tilt), --fx-x/--fx-y/
   --fx-on (spotlight), --fx-tx/--fx-ty (magnetic). Every transform lives here,
   so no page data ever reaches a style string.

   `float` is the one that needs no JS and is not gated on reduced motion: a
   shadow appearing is not movement. The other three never attach their
   listeners at all under reduced motion or on a coarse pointer, and the
   defaults below mean that if they somehow did, everything sits at rest.
   ========================================================================= */

[data-hoverfx] { --fx-rx: 0deg; --fx-ry: 0deg; --fx-tx: 0px; --fx-ty: 0px; --fx-on: 0; }

/* ---- float: lift + shadow, CSS only ---- */
[data-hoverfx="float"] .site-work-cards .site-work-item,
[data-hoverfx="float"] .site-gallery-item,
[data-hoverfx="float"] .site-testimonial,
[data-hoverfx="float"] .site-fact-row {
  transition: transform 0.25s ease,
              box-shadow 0.25s ease;
}
[data-hoverfx="float"] .site-work-cards .site-work-item:hover,
[data-hoverfx="float"] .site-gallery-item:hover,
[data-hoverfx="float"] .site-testimonial:hover,
[data-hoverfx="float"] .site-fact-row:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 32px -12px rgba(0, 0, 0, .32);
}

/* ---- tilt: 3D rotation toward the pointer ---- */
[data-hoverfx="tilt"] .site-work-cards,
[data-hoverfx="tilt"] .site-gallery-grid,
[data-hoverfx="tilt"] .site-testimonials,
[data-hoverfx="tilt"] .site-facts { perspective: 900px; }

[data-hoverfx="tilt"] .site-work-cards .site-work-item,
[data-hoverfx="tilt"] .site-gallery-item,
[data-hoverfx="tilt"] .site-testimonial,
[data-hoverfx="tilt"] .site-fact-row {
  transform: rotateX(var(--fx-rx)) rotateY(var(--fx-ry));
  transform-style: preserve-3d;
  /* Fast enough to feel attached to the pointer, slow enough not to jitter. */
  transition: transform 0.12s ease-out;
  will-change: transform;
}

/* ---- spotlight: a soft light under the pointer ---- */
[data-hoverfx="spotlight"] { position: relative; isolation: isolate; }
[data-hoverfx="spotlight"]::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: var(--fx-on);
  transition: opacity 0.25s ease;
  background: radial-gradient(
    circle 22rem at var(--fx-x, 50%) var(--fx-y, 50%),
    color-mix(in srgb, var(--site-accent) 14%, transparent),
    transparent 70%
  );
}
/* The content has to sit above the light, or the light washes the type. */
[data-hoverfx="spotlight"] > .site-section-inner { position: relative; z-index: 1; }

/* ---- magnetic: the action drifts toward the pointer ---- */
[data-hoverfx="magnetic"] .site-cta-action,
[data-hoverfx="magnetic"] .site-hero-cta,
[data-hoverfx="magnetic"] .site-signup-btn {
  transform: translate(var(--fx-tx), var(--fx-ty));
  transition: transform 0.22s ease-out;
  will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
  /* Belt and braces — the listeners are never attached, but if a value were
     ever left on an element the transform must not survive the preference. */
  [data-hoverfx="tilt"] .site-work-cards .site-work-item,
  [data-hoverfx="tilt"] .site-gallery-item,
  [data-hoverfx="tilt"] .site-testimonial,
  [data-hoverfx="tilt"] .site-fact-row,
  [data-hoverfx="magnetic"] .site-cta-action,
  [data-hoverfx="magnetic"] .site-hero-cta,
  [data-hoverfx="magnetic"] .site-signup-btn { transform: none; transition: none; }
  [data-hoverfx="spotlight"]::after { display: none; }
  [data-hoverfx="float"] .site-work-cards .site-work-item:hover,
  [data-hoverfx="float"] .site-gallery-item:hover,
  [data-hoverfx="float"] .site-testimonial:hover,
  [data-hoverfx="float"] .site-fact-row:hover { transform: none; }
}

/* =========================================================================
   Before / after (compare)

   The divider is an <input type="range"> stretched invisibly over the whole
   image: dragging anywhere works, and it is still the element a keyboard
   focuses and a screen reader announces. Everything visible — the seam, the
   handle — is drawn by this stylesheet on top of it.
   ========================================================================= */
.site-compare {
  --cmp: 50%;
  position: relative;
  width: 100%;
  overflow: hidden;
  background: var(--site-well, #000);
  /* touch-action so a vertical page scroll started on the image still scrolls
     the page — only a horizontal drag moves the divider. */
  touch-action: pan-y;
}
.site-compare[data-aspect="landscape"] { aspect-ratio: 3 / 2; }
.site-compare[data-aspect="square"] { aspect-ratio: 1 / 1; }
.site-compare[data-aspect="portrait"] { aspect-ratio: 4 / 5; }
.site-compare[data-aspect="natural"] { aspect-ratio: auto; }

.site-compare-img { display: block; width: 100%; height: 100%; object-fit: cover; }
.site-compare[data-aspect="natural"] .site-compare-img { height: auto; }

.site-compare-clip {
  position: absolute;
  inset: 0;
  /* Reveal the second image from the divider rightward. */
  clip-path: inset(0 0 0 var(--cmp));
}
.site-compare[data-aspect="natural"] .site-compare-clip { height: 100%; }

.site-compare-line {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--cmp);
  width: 2px;
  margin-left: -1px;
  background: var(--site-ink, #fff);
  pointer-events: none;
  z-index: 2;
}
.site-compare-line::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 2.25rem;
  height: 2.25rem;
  transform: translate(-50%, -50%);
  border: 2px solid var(--site-ink, #fff);
  border-radius: 50%;
  background: color-mix(in srgb, var(--site-bg) 45%, transparent);
  backdrop-filter: blur(2px);
}

.site-compare-range {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: ew-resize;
  z-index: 3;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
}
/* The thumb has to span the full height or a drag only registers on a sliver. */
.site-compare-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 3rem;
  height: 100vh;
  cursor: ew-resize;
}
.site-compare-range::-moz-range-thumb {
  width: 3rem;
  height: 100vh;
  border: 0;
  border-radius: 0;
  cursor: ew-resize;
}
/* Focus has to be visible on a control whose own paint is transparent. */
.site-compare-range:focus-visible { outline: none; }
.site-compare-range:focus-visible ~ .site-compare-line {
  box-shadow: 0 0 0 2px var(--site-accent), 0 0 0 5px color-mix(in srgb, var(--site-accent) 35%, transparent);
}

.site-compare-label {
  position: absolute;
  bottom: 0.75rem;
  z-index: 2;
  padding: .25rem .6rem;
  font-size: .7rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--site-ink, #fff);
  background: color-mix(in srgb, var(--site-bg) 55%, transparent);
  backdrop-filter: blur(3px);
  pointer-events: none;
}
.site-compare-label-a { left: 0.75rem; }
.site-compare-label-b { right: 0.75rem; }

/* =========================================================================
   Sticky scroll sequence

   A pinned visual beside steps that scroll past it. Below the breakpoint it
   stops being sticky and becomes an ordinary stack — pinning half a phone
   screen leaves nothing to read the steps in.
   ========================================================================= */
.site-sticky { display: block; }
.site-sticky-media { display: none; }
.site-sticky-step + .site-sticky-step { margin-top: clamp(2rem, 6vw, 4rem); }
.site-sticky-title { font-size: clamp(1.1rem, 2.2vw, 1.5rem); margin: 0 0 .4rem; }
.site-sticky-body { color: var(--site-text-2); margin: 0; }

@media (min-width: 900px) {
  .site-sticky {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(2rem, 5vw, 4rem);
    align-items: start;
  }
  .site-sticky[data-side="right"] .site-sticky-media { order: 2; }
  .site-sticky[data-side="right"] .site-sticky-steps { order: 1; }

  .site-sticky-media {
    display: block;
    position: sticky;
    /* Offset with `top` ALONE, never a transform.
       The first version centred the panel with top:50% + translateY(-50%).
       A transform is applied after layout, so the panel painted outside its
       own section and straight over the section above it — a music embed, in
       the case that caught this. Sticky positions the box; a transform moves
       the paint, and the two disagree.
       A fixed height instead of aspect-ratio keeps the panel inside the
       viewport at any column width, so it cannot grow tall enough to escape. */
    top: 12vh;
    height: min(76vh, 640px);
    width: 100%;
    overflow: hidden;
  }
  .site-sticky-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity 0.4s ease;
  }
  .site-sticky-img[data-on] { opacity: 1; }

  /* Room above and below so the first and last steps can reach the middle of
     the viewport — without this the last step never becomes active. */
  .site-sticky-steps { padding: 20vh 0; }
}

@media (prefers-reduced-motion: reduce) {
  /* Which image shows still changes — that is meaning, not motion. The
     crossfade is what goes. */
  .site-sticky-img { transition: none; }
}

/* =========================================================================
   Editor-only empty state

   data-section-id is stamped on section roots ONLY when the editor renders
   (opts.sectionAttr) — a published page never has it. So this is scoped to the
   editor by construction rather than by a class someone has to remember to add.

   Without it, inserting a section that carries no heading and no content yet —
   a full-bleed gallery, a before/after before its images — puts an invisible
   block on the canvas. The author clicks a tile in the insert panel and
   nothing appears to happen, which reads as a broken button rather than as an
   empty section waiting for content.
   ========================================================================= */
.site-section[data-section-id] > .site-section-inner:empty::after {
  content: "Empty — add content in the panel on the right";
  display: block;
  padding: 2.5rem 1rem;
  text-align: center;
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  color: var(--site-text-2);
  border: 1px dashed var(--site-border);
}

/* =========================================================================
   Shop (data-hydrated — SSR ships heading + blurb, the grid arrives at view
   time from shop-public so prices can never go stale on a published page)
   ========================================================================= */
.site-shop-blurb { color: var(--site-text-2); max-width: 46rem; }
.site-shop {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: clamp(1rem, 3vw, 2rem);
  margin-top: 1.2rem;
}
.site-shop-note { color: var(--site-text-2); font-size: .85rem; border: 1px dashed var(--site-border); padding: 1.4rem; text-align: center; grid-column: 1 / -1; }
.site-shop-card { display: flex; flex-direction: column; gap: .45rem; }
.site-shop-img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; display: block; background: var(--site-well, #000); }
.site-shop-title { font-size: 1.02rem; margin: .2rem 0 0; }
.site-shop-desc { color: var(--site-text-2); font-size: .88rem; margin: 0; }
.site-shop-row { display: flex; align-items: center; justify-content: space-between; gap: .8rem; margin-top: auto; padding-top: .3rem; }
.site-shop-price { font-variant-numeric: tabular-nums; }
.site-shop-soldout { color: var(--site-text-2); font-size: .8rem; letter-spacing: .06em; text-transform: uppercase; }
.site-shop-buy {
  font: inherit;
  padding: .5rem 1.1rem;
  background: var(--site-accent);
  color: var(--site-on-accent, var(--site-bg));
  border: 0;
  cursor: pointer;
  transition: transform 0.15s ease;
}
.site-shop-buy:hover { transform: translateY(-1px); }
.site-shop-buy:disabled { opacity: .6; cursor: default; transform: none; }
.site-shop-thanks {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: .9rem 1.1rem;
  border: 1px solid var(--site-border);
  background: var(--site-surface);
  margin-bottom: 1.4rem;
}
