/* ==========================================================================
   DrAjokesings — Design System & Base
   Editorial gospel platform. White canvas, ink-black depth, one red accent
   used the way stage lighting is used: rare, and only when it means it.
   ========================================================================== */

@font-face {
  font-family: "Instrument Serif";
  src: local("Instrument Serif");
  font-display: swap;
}

:root {
  /* ---- Color: base palette ---- */
  --ink: #0a0908;             /* canvas — near-black, warm not cold */
  --ink-soft: #16130f;        /* raised dark surfaces */
  --ink-line: #2a2621;        /* hairlines on dark */
  --paper: #faf7f2;           /* canvas — warm white, not stark */
  --paper-dim: #efe8dd;       /* raised light surfaces */
  --paper-line: #ddd3c3;      /* hairlines on light */
  --red: #a91d2c;             /* the one accent — deep, blood/wine red */
  --red-bright: #d63a34;      /* rare flash: live indicators, active states */
  --gold: #a9895a;            /* smallest accent — marks, numerals, dividers */
  --gray-on-dark: #948c81;
  --gray-on-light: #6b6459;

  /* ---- Type ---- */
  --font-display: "Instrument Serif", "Times New Roman", serif;
  --font-ui: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  /* The logo is a drawing, not type: assets/images/logo.svg, and .sig below. */

  --step--1: clamp(0.8rem, 0.78rem + 0.1vw, 0.875rem);
  --step-0: clamp(1rem, 0.96rem + 0.2vw, 1.125rem);
  --step-1: clamp(1.25rem, 1.18rem + 0.35vw, 1.5rem);
  --step-2: clamp(1.7rem, 1.55rem + 0.75vw, 2.25rem);
  --step-3: clamp(2.4rem, 2.1rem + 1.5vw, 3.5rem);
  --step-4: clamp(3.2rem, 2.6rem + 3vw, 5.5rem);
  --step-5: clamp(4.2rem, 3.2rem + 5vw, 8rem);

  /* ---- Space ---- */
  --space-3xs: 0.25rem;
  --space-2xs: 0.5rem;
  --space-xs: 0.875rem;
  --space-s: 1.25rem;
  --space-m: 2rem;
  --space-l: 3.25rem;
  --space-xl: 5.5rem;
  --space-2xl: 9rem;
  --space-3xl: 14rem;

  /* ---- Layout ---- */
  --edge: clamp(1.25rem, 4vw, 4.5rem);
  --max-w: 1680px;
  --ease-cinema: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
  --dur-s: 0.4s;
  --dur-m: 0.9s;
  --dur-l: 1.6s;

  --nav-h: 84px;
  color-scheme: dark light;
}

/* ---- Reset ---- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: auto; }
html:focus-within { scroll-behavior: smooth; }
body {
  min-height: 100svh;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-ui);
  font-size: var(--step-0);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
body.no-scroll { overflow: hidden; height: 100svh; }
/* Live mode, first visit: the page waits (a second at most, see
   content.js) for the published words instead of showing the built-in
   ones and swapping them. */
.is-content-loading main,
.is-content-loading .site-footer { opacity: 0; }

/* The announcement bar (content.js; admin → Announcements). It sits above
   the fixed header, which moves down by its height, and the page moves down
   with it, so nothing is covered. */
.has-announcement { --announce-h: 2.5rem; }
.has-announcement body { padding-top: var(--announce-h); }
.has-announcement .site-header { top: var(--announce-h); }
.has-announcement .mobile-nav { padding-top: calc(var(--space-xl) + var(--announce-h)); }
.announce {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 305;
  height: var(--announce-h);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 3rem 0 1rem;
  background: var(--red);
  color: var(--paper);
  font-size: var(--step--1);
  text-align: center;
}
.announce__text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.announce__link { color: inherit; font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
.announce__close {
  position: absolute;
  right: 0.5rem;
  top: 50%;
  transform: translateY(-50%);
  width: 2rem;
  height: 2rem;
  color: inherit;
  font-size: 1.3rem;
  line-height: 1;
}
@media (max-width: 680px) {
  .has-announcement { --announce-h: 3.1rem; }
  .announce__text {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    white-space: normal;
    font-size: 0.78rem;
    line-height: 1.3;
  }
}
img, picture, video { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: none; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; padding: 0; }
/* The hidden attribute must win over any display a class sets (flex,
   grid…), or sections the scripts hide stay on screen. */
[hidden] { display: none !important; }
h1, h2, h3, h4 { font-weight: 400; line-height: 1.05; text-wrap: balance; }
p { text-wrap: pretty; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---- Skip link (a11y) ---- */
.skip-link {
  position: fixed;
  top: -100%;
  left: var(--space-s);
  z-index: 999;
  background: var(--paper);
  color: var(--ink);
  padding: var(--space-2xs) var(--space-s);
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: var(--step--1);
  transition: top var(--dur-s) var(--ease-soft);
}
.skip-link:focus {
  top: var(--space-s);
}

:focus-visible {
  outline: 2px solid var(--red-bright);
  outline-offset: 3px;
}

/* ---- Typography helpers ---- */
.display {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.01em;
}
.eyebrow {
  font-family: var(--font-ui);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--gray-on-dark);
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}
.eyebrow::before {
  content: "";
  width: 20px;
  height: 1px;
  background: var(--red);
  display: inline-block;
}
.section--light .eyebrow { color: var(--gray-on-light); }

.mono-index {
  font-variant-numeric: tabular-nums;
  color: var(--gold);
  font-size: var(--step--1);
}

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

/* ---- Layout shell ---- */
.wrap {
  max-width: var(--max-w);
  margin-inline: auto;
  padding-inline: var(--edge);
}

.section {
  position: relative;
  padding-block: var(--space-2xl);
  background: var(--ink);
}
.section--light { background: var(--paper); color: var(--ink); }
.section--raised { background: var(--ink-soft); }
.section--red { background: var(--red); color: var(--paper); }

/* ---- Buttons & links ---- */
.btn {
  --btn-fg: var(--paper);
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: var(--step--1);
  letter-spacing: 0.01em;
  color: var(--btn-fg);
  padding-block: var(--space-xs);
  cursor: pointer;
}
.btn-line {
  position: relative;
  padding-bottom: 3px;
}
.btn-line::after {
  content: "";
  position: absolute;
  left: 0; bottom: -1px;
  width: 100%; height: 1px;
  background: currentColor;
  transform-origin: left;
  transition: transform var(--dur-s) var(--ease-cinema);
}
.btn-line:hover::after,
.btn-line:focus-visible::after { transform: scaleX(0.35); }

.btn-solid {
  background: var(--red);
  color: var(--paper);
  padding: 1rem 1.75rem;
  border-radius: 2px;
  transition: background var(--dur-s) var(--ease-soft), transform var(--dur-s) var(--ease-soft);
}
.btn-solid:hover { background: var(--red-bright); transform: translateY(-2px); }

.btn-ghost {
  border: 1px solid color-mix(in srgb, currentColor 35%, transparent);
  padding: 1rem 1.75rem;
  border-radius: 2px;
  transition: border-color var(--dur-s) var(--ease-soft), background var(--dur-s) var(--ease-soft);
}
.btn-ghost:hover { border-color: currentColor; background: color-mix(in srgb, currentColor 8%, transparent); }

/* ---- The Talent Quest's call to apply ----
   Every button asking people to apply to the Talent Quest (.btn-quest)
   keeps calling: a light sweeps across it every few seconds, a warm glow
   breathes around it, and now and then it gives a little wiggle. The
   wiggle uses the `rotate` property, so it adds to a button's own
   movement (the magnetic pull, the hover lift, a slide's entrance)
   instead of fighting it. app.js stands the buttons down while
   applications are closed. Still for anyone who asks for reduced motion. */
.btn-quest { animation: questWiggle 7s var(--ease-soft) 2.4s infinite; }
.btn-solid.btn-quest {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  animation: questWiggle 7s var(--ease-soft) 2.4s infinite, questGlow 3.6s ease-in-out infinite;
}
.btn-solid.btn-quest::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: -30%;
  bottom: -30%;
  left: -75%;
  width: 45%;
  background: linear-gradient(100deg, transparent 0%, rgba(255, 232, 200, 0.45) 40%, rgba(255, 255, 255, 0.9) 50%, rgba(255, 232, 200, 0.45) 60%, transparent 100%);
  transform: skewX(-18deg);
  animation: questShine 3.6s ease-in-out infinite;
  pointer-events: none;
}
.btn-line.btn-quest { animation: questWiggle 7s var(--ease-soft) 2.4s infinite, questTextGlow 3.6s ease-in-out infinite; }

@keyframes questShine {
  0%, 48%   { left: -75%; }
  78%, 100% { left: 135%; }
}
@keyframes questGlow {
  0%, 100% { box-shadow: var(--quest-base, 0 0 0 0 transparent), 0 0 0 0 transparent, 0 0 0 0 transparent; }
  55%      { box-shadow: var(--quest-base, 0 0 0 0 transparent), 0 0 0 5px color-mix(in srgb, var(--red-bright) 26%, transparent), 0 0 30px 6px color-mix(in srgb, var(--gold) 55%, transparent); }
}
@keyframes questTextGlow {
  0%, 100% { text-shadow: 0 0 0 transparent; }
  55%      { text-shadow: 0 0 16px color-mix(in srgb, var(--gold) 90%, transparent); }
}
@keyframes questWiggle {
  0%, 82%, 100% { rotate: 0deg; }
  84% { rotate: -3deg; }
  86% { rotate: 3deg; }
  88% { rotate: -2.5deg; }
  90% { rotate: 2deg; }
  92% { rotate: -1deg; }
  94% { rotate: 0deg; }
}

/* The call at the bottom of every page while applications are open. */
.quest-call {
  position: fixed;
  right: max(16px, env(safe-area-inset-right));
  bottom: max(16px, env(safe-area-inset-bottom));
  z-index: 80;
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: calc(100vw - 32px);
  padding: 8px 8px 8px 18px;
  border: 1px solid color-mix(in srgb, var(--gold) 45%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 90%, transparent);
  color: var(--paper);
  box-shadow: 0 18px 40px -18px rgba(0, 0, 0, 0.75);
  -webkit-backdrop-filter: blur(10px);
          backdrop-filter: blur(10px);
  /* Hidden until app.js shows it, a moment after the page opens. */
  opacity: 0;
  translate: 0 24px;
  visibility: hidden;
  transition: opacity 0.5s var(--ease-soft), translate 0.7s var(--ease-cinema), visibility 0s linear 0.7s;
}
.quest-call.is-shown { opacity: 1; translate: 0 0; visibility: visible; transition-delay: 0s; }
/* Out of the way while it would cover the application form or the
   homepage slider's controls, and while a menu, form or video is open. */
.quest-call.is-away,
.no-scroll .quest-call { opacity: 0; translate: 0 18px; visibility: hidden; transition-delay: 0s, 0s, 0.7s; }
.quest-call__text { display: grid; gap: 2px; margin: 0; font-size: 0.78rem; line-height: 1.25; }
.quest-call__text strong { font-size: 0.86rem; font-weight: 700; }
.quest-call__text span { color: var(--gray-on-dark); }
.quest-call__btn { padding: 0.75rem 1.25rem; border-radius: 999px; font-size: 0.82rem; white-space: nowrap; }
.quest-call__close {
  display: grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  color: var(--gray-on-dark);
  font-size: 1.25rem;
  line-height: 1;
}
.quest-call__close:hover,
.quest-call__close:focus-visible { color: var(--paper); background: color-mix(in srgb, var(--paper) 10%, transparent); }
.has-persistent-player .quest-call { bottom: calc(max(16px, env(safe-area-inset-bottom)) + 96px); }
@media (max-width: 560px) {
  .quest-call { left: 12px; right: 12px; bottom: max(12px, env(safe-area-inset-bottom)); max-width: none; justify-content: space-between; gap: 10px; padding-left: 16px; }
  .quest-call__text span { display: none; }
  body.has-quest-call { padding-bottom: 76px; }
  body.has-quest-call.has-persistent-player { padding-bottom: 172px; }
}
/* Signed-in admins have their dock in the bottom-left corner. */
@media (max-width: 680px) {
  body:has(.edit-dock:not([hidden])) .quest-call { bottom: calc(max(12px, env(safe-area-inset-bottom)) + 48px); }
}

@media (prefers-reduced-motion: reduce) {
  .btn-quest,
  .btn-solid.btn-quest,
  .btn-line.btn-quest,
  .btn-solid.btn-quest::before { animation: none; }
}

/* ==========================================================================
   NAVIGATION
   ========================================================================== */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  height: var(--nav-h);
  z-index: 300;
  display: flex;
  align-items: center;
  mix-blend-mode: normal;
  transition: background var(--dur-s) var(--ease-soft), border-color var(--dur-s) var(--ease-soft);
  border-bottom: 1px solid transparent;
}
.site-header.is-scrolled {
  background: color-mix(in srgb, var(--ink) 82%, transparent);
  backdrop-filter: blur(14px) saturate(140%);
  border-bottom-color: var(--ink-line);
}
.site-header .wrap {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.brand {
  display: inline-flex;
  align-items: center;
  font-size: var(--step-1);
  line-height: 1;
  color: var(--paper);
}

.primary-nav { display: flex; align-items: center; gap: var(--space-l); }
.primary-nav__list { display: flex; gap: var(--space-m); }
.primary-nav__list a {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.01em;
  position: relative;
  padding-bottom: 4px;
}
.primary-nav__list a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 0; height: 1px;
  background: var(--red-bright);
  transition: width var(--dur-s) var(--ease-cinema);
}
.primary-nav__list a:hover::after,
.primary-nav__list a[aria-current="page"]::after { width: 100%; }

.nav-actions { display: flex; align-items: center; gap: var(--space-s); }

.menu-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  width: 28px;
  padding: var(--space-2xs);
}
.menu-toggle span {
  height: 1px;
  background: var(--paper);
  width: 100%;
  transition: transform var(--dur-s) var(--ease-cinema), opacity var(--dur-s) var(--ease-cinema);
}
.menu-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.menu-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 290;
  background: var(--ink);
  display: flex;
  flex-direction: column;
  padding: var(--space-xl) var(--edge);
  /* When the links don't fit (short phones, landscape) the panel scrolls
     itself instead of letting them spill out of its bottom edge. */
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Parked off the right-hand edge, where the menu button is, and slid in
     from there. */
  transform: translateX(100%);
  /* Closed, it is invisible as well as parked off screen: parked alone,
     links that overflowed its edge showed at the top of every page, over
     the logo. Visibility flips only after the slide-out has finished, so
     closing still animates. */
  visibility: hidden;
  transition: transform 0.6s var(--ease-cinema), visibility 0s linear 0.6s;
}
.mobile-nav.is-open {
  transform: translateX(0);
  visibility: visible;
  transition: transform 0.75s var(--ease-cinema);
}
/* Centred when everything fits, top-aligned and scrollable when it doesn't
   (justify-content: center would push the overflow out of reach). */
.mobile-nav > :first-child { margin-top: auto; }
.mobile-nav > :last-child { margin-bottom: auto; }
/* While the menu is open the header turns solid, so links scrolled up
   under it (short screens) pass behind the logo instead of through it. */
.site-header:has(~ .mobile-nav.is-open) { background: var(--ink); }

/* The links: block capitals in the UI face, numbered in gold and ruled
   apart with hairlines. Each slides in from the right behind the panel,
   one after another (--i is the item's place in the list, set by
   navigation.js); the page you are on is marked in red. */
.mobile-nav__list { counter-reset: mnav; border-top: 1px solid var(--ink-line); }
.mobile-nav__list li {
  counter-increment: mnav;
  border-bottom: 1px solid var(--ink-line);
  opacity: 0;
  transform: translateX(2.5rem);
  transition: opacity 0.25s var(--ease-soft), transform 0.25s var(--ease-soft);
}
.mobile-nav.is-open .mobile-nav__list li {
  opacity: 1;
  transform: none;
  transition: opacity 0.6s var(--ease-soft), transform 0.8s var(--ease-cinema);
  transition-delay: calc(0.22s + var(--i, 0) * 0.06s);
}
.mobile-nav__list a {
  display: flex;
  align-items: baseline;
  gap: var(--space-s);
  padding-block: 1rem;
  font-family: var(--font-ui);
  font-size: clamp(0.95rem, 0.9rem + 0.3vw, 1.1rem);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--paper);
  transition: color var(--dur-s) var(--ease-soft);
}
.mobile-nav__list a::before {
  content: counter(mnav, decimal-leading-zero);
  min-width: 1.6rem;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}
.mobile-nav__list a:hover { color: var(--gold); }
.mobile-nav__list a[aria-current="page"],
.mobile-nav__list a[aria-current="page"]::before { color: var(--red-bright); }
.mobile-nav__meta {
  margin-top: var(--space-l);
  color: var(--gray-on-dark);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  opacity: 0;
  transition: opacity 0.25s var(--ease-soft);
}
.mobile-nav.is-open .mobile-nav__meta { opacity: 1; transition: opacity 0.8s var(--ease-soft) 0.7s; }

/* ==========================================================================
   CINEMATIC INTRO
   ========================================================================== */
.intro {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--ink);
  display: grid;
  place-items: stretch;
}
.intro[hidden] { display: none; }
.intro__media { position: absolute; inset: 0; overflow: hidden; }
.intro__video, .intro__poster {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.intro__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(10,9,8,0.55) 0%, rgba(10,9,8,0.15) 35%, rgba(10,9,8,0.75) 100%);
}
.intro__content {
  position: relative;
  z-index: 2;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: var(--space-m) var(--edge) var(--space-l);
}
.intro__mark {
  font-size: var(--step-1);
  line-height: 1;
  color: var(--paper);
}
.intro__body { align-self: flex-end; max-width: 640px; }
.intro__eyebrow {
  font-size: var(--step--1);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gray-on-dark);
  margin-bottom: var(--space-xs);
}
.intro__title {
  font-family: var(--font-display);
  font-size: var(--step-4);
  color: var(--paper);
  line-height: 0.98;
}
.intro__title em { font-style: italic; color: var(--red-bright); }
.intro__controls {
  display: flex;
  align-items: center;
  gap: var(--space-l);
  margin-top: var(--space-m);
}
.intro__enter {
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: var(--step--1);
  letter-spacing: 0.02em;
  color: var(--paper);
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding-bottom: 6px;
  border-bottom: 1px solid var(--paper);
  transition: gap var(--dur-s) var(--ease-cinema), opacity var(--dur-s);
}
.intro__enter:hover { gap: var(--space-s); }
.intro__sound {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  color: var(--gray-on-dark);
  font-size: var(--step--1);
}
.intro__sound svg { width: 18px; height: 18px; }
.intro__progress {
  position: absolute;
  top: 0; left: 0;
  height: 2px;
  background: var(--red);
  width: 0%;
  z-index: 3;
  transition: width 0.2s linear;
}
.intro.is-leaving { pointer-events: none; }

/* ==========================================================================
   CUSTOM CURSOR
   ========================================================================== */
.cursor {
  position: fixed;
  top: 0; left: 0;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--paper);
  mix-blend-mode: difference;
  pointer-events: none;
  z-index: 998;
  transform: translate(-50%, -50%);
  will-change: transform;
}
.cursor__label {
  position: fixed;
  top: 0; left: 0;
  z-index: 997;
  pointer-events: none;
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--ink);
  background: var(--paper);
  border-radius: 50%;
  width: 84px; height: 84px;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translate(-50%, -50%) scale(0);
  transition: transform var(--dur-s) var(--ease-cinema);
  text-align: center;
}
.cursor__label.is-active { transform: translate(-50%, -50%) scale(1); }

@media (hover: none), (pointer: coarse) {
  .cursor, .cursor__label { display: none; }
}

/* ==========================================================================
   FOOTER
   ========================================================================== */
.site-footer {
  background: var(--ink);
  border-top: 1px solid var(--ink-line);
  padding-block: var(--space-xl) var(--space-m);
}
.footer-top {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: var(--space-l);
  padding-bottom: var(--space-xl);
}
.footer-brand { font-size: var(--step-3); line-height: 1; }
.footer-tagline { color: var(--gray-on-dark); margin-top: var(--space-s); max-width: 32ch; font-size: var(--step--1); }
.footer-col h3 {
  font-size: var(--step--1);
  color: var(--gray-on-dark);
  font-weight: 600;
  margin-bottom: var(--space-s);
  letter-spacing: 0.02em;
}
.footer-col ul { display: flex; flex-direction: column; gap: var(--space-2xs); }
.footer-col a { font-size: var(--step--1); transition: opacity var(--dur-s); }
.footer-col a:hover { opacity: 0.6; }
.footer-bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-top: 1px solid var(--ink-line);
  padding-top: var(--space-m);
  font-size: var(--step--1);
  color: var(--gray-on-dark);
}
.footer-social { display: flex; gap: var(--space-s); }

/* Loading / empty / error state primitives (shared across the site) */
.state-msg {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--step--1);
  color: var(--gray-on-dark);
  padding: var(--space-m) 0;
}
.state-msg[data-state="error"] { color: var(--red-bright); }
.spinner {
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  border-top-color: transparent;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Skeleton */
.skeleton {
  background: linear-gradient(90deg, var(--ink-soft) 25%, var(--ink-line) 37%, var(--ink-soft) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
}
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }

/* ==========================================================================
   FILM GRAIN + SCROLL PROGRESS
   Two site-wide atmospherics, both injected by navigation.js so no page
   markup carries them. The grain is a single SVG-noise tile drifting on a
   stepped animation — it gives flat colour the tooth of projected film,
   which is the whole conceit of the design. Both sit out of the way of
   pointer events, and both stand down under prefers-reduced-motion.
   ========================================================================== */
.grain {
  position: fixed;
  inset: -60%;
  z-index: 600;
  pointer-events: none;
  opacity: 0.048;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grainDrift 900ms steps(4) infinite;
  will-change: transform;
}
@keyframes grainDrift {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(-3%, 2%); }
  50%  { transform: translate(2%, -3%); }
  75%  { transform: translate(-2%, -2%); }
  100% { transform: translate(0, 0); }
}

.scroll-progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  z-index: 310;
  pointer-events: none;
  background: linear-gradient(90deg, var(--red), var(--red-bright) 60%, var(--gold));
  transform: scaleX(var(--progress, 0));
  transform-origin: left;
  transition: transform 0.12s linear;
}

@media (prefers-reduced-motion: reduce) {
  .grain { animation: none; }
  .scroll-progress { transition: none; }
}

/* ==========================================================================
   THE LOGO — her signature, "Dr. Ajokesings" (assets/images/logo.svg)
   It arrives the way a rope is laid: three strands, gold, red and light,
   trace the lettering from a little apart (two of them from opposite ends)
   and draw together into place; the solid signature fills in where they
   meet and the strands fall away. Hovering the header logo runs a gold
   strand along it again.

   Each page carries the drawing once, as <symbol id="dj-logo"> at the top
   of <body>; each logo is an <svg class="sig__logo"> holding five <use>
   copies of it (three strands, the ink, the hover strand). Colour follows
   the text colour around it, so it reads light on dark and dark on light.

   CSS runs all of it. navigation.js only holds it: in the homepage header
   until the intro film has cleared, and in the footer until it scrolls
   into view.
   ========================================================================== */
.sig-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.sig {
  --sig-delay: 0.3s;
  --sig-dur: 2.2s;
  --sig-ease: cubic-bezier(0.6, 0.02, 0.22, 1);
  --sig-h: 1.9em;   /* the logo's height; its width follows */
  --sig-rope: 20;   /* strand thickness, in the drawing's own units (2632 wide) */
  display: inline-block;
  vertical-align: middle;
  line-height: 0;
}
.sig__logo { display: block; width: auto; height: var(--sig-h); max-width: 100%; overflow: visible; }
.sig__ink { fill: currentColor; }
.sig__rope,
.sig__echo {
  fill: none;
  stroke-width: var(--sig-rope);
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  opacity: 0;
  transform-box: view-box;
  transform-origin: 50% 50%;
}
.sig__rope--gold { stroke: var(--gold); }
.sig__rope--red { stroke: var(--red-bright); }
.sig__rope--light { stroke: currentColor; }
.sig__echo { stroke: var(--gold); }

/* Where it sits: its height, and strands that suit the size. */
.brand .sig { --sig-h: 2.25em; --sig-rope: 24; }
.intro__mark .sig { --sig-h: 2.2em; --sig-rope: 24; }
.footer-brand .sig { --sig-h: 1.55em; --sig-rope: 15; }

/* ---- The entrance ---- */
.sig--autoplay .sig__rope--gold,
.sig.is-signing .sig__rope--gold { animation: sigStrandA var(--sig-dur) var(--sig-ease) var(--sig-delay) both; }
.sig--autoplay .sig__rope--red,
.sig.is-signing .sig__rope--red { animation: sigStrandB var(--sig-dur) var(--sig-ease) calc(var(--sig-delay) + 0.08s) both; }
.sig--autoplay .sig__rope--light,
.sig.is-signing .sig__rope--light { animation: sigStrandC var(--sig-dur) var(--sig-ease) calc(var(--sig-delay) + 0.16s) both; }
.sig--autoplay .sig__ink,
.sig.is-signing .sig__ink { animation: sigInk calc(var(--sig-dur) * 0.24) var(--ease-soft) calc(var(--sig-delay) + var(--sig-dur) * 0.52) both; }

/* Held by navigation.js: every part pauses together so they stay in step. */
.sig.is-waiting .sig__rope,
.sig.is-waiting .sig__ink { animation-play-state: paused; }

/* Over photography a soft ink halo lifts the signature off busy frames. */
.brand .sig,
.intro__mark .sig { filter: drop-shadow(0 0.03em 0.14em rgba(10, 9, 8, 0.65)); }

/* Hovering the header logo runs a gold strand along the lettering. */
.brand:hover .sig__echo,
.brand:focus-visible .sig__echo { animation: sigEcho 1.3s var(--ease-cinema) both; }

@keyframes sigStrandA {
  0%   { opacity: 0; stroke-dashoffset: 1;  transform: translate(-2.5%, -16%) rotate(-1.6deg); }
  10%  { opacity: 1; }
  62%  { opacity: 1; stroke-dashoffset: 0;  transform: none; }
  84%  { opacity: 0; }
  100% { opacity: 0; stroke-dashoffset: 0;  transform: none; }
}
@keyframes sigStrandB {
  0%   { opacity: 0; stroke-dashoffset: -1; transform: translate(2.5%, 16%) rotate(1.6deg); }
  10%  { opacity: 1; }
  62%  { opacity: 1; stroke-dashoffset: 0;  transform: none; }
  80%  { opacity: 0; }
  100% { opacity: 0; stroke-dashoffset: 0;  transform: none; }
}
@keyframes sigStrandC {
  0%   { opacity: 0;   stroke-dashoffset: 1; transform: scale(1.07); }
  14%  { opacity: 0.9; }
  62%  { opacity: 0.9; stroke-dashoffset: 0; transform: none; }
  86%  { opacity: 0; }
  100% { opacity: 0;   stroke-dashoffset: 0; transform: none; }
}
@keyframes sigInk {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes sigEcho {
  0%   { opacity: 1; stroke-dashoffset: 1; }
  65%  { opacity: 1; stroke-dashoffset: 0; }
  100% { opacity: 0; stroke-dashoffset: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .sig__rope,
  .sig__ink,
  .sig__echo { animation: none !important; }
}
