
  /* ============ TOKENS ============ */
  :root {
    --void: #0a0d12;
    --void-2: #10141c;
    --aubergine: #1c2340;
    --aubergine-2: #262c52;
    --parchment: #e7ece8;
    --parchment-dim: #aab5b0;
    --ember: #49c9c0;
    --ember-bright: #6fe0d6;
    --ember-dim: #2f8a83;
    --verdigris: #9b86d9;
    --ash: #7c8a91;
    --hairline: rgba(228, 236, 232, 0.14);

    --font-display: 'Big Shoulders', sans-serif;
    --font-body: 'Newsreader', serif;
    --font-mono: 'IBM Plex Mono', monospace;

    --container: min(1120px, 92vw);
    --section-pad: clamp(4.5rem, 10vw, 8rem);
  }

  @media (prefers-reduced-motion: no-preference) {
    html { scroll-behavior: smooth; }
  }

  /* Fixed header, so anchor targets need one header-height of clearance.
     Keep it on the scroll container only: scroll-padding plus scroll-margin
     doubles the gap. nav-offset.js measures the real header and publishes
     --nav-h. The fallback is deliberately a little short; landing inside the
     section is invisible, landing short of it leaves a bright strip showing. */
  html {
    scroll-padding-top: var(--nav-h, 4rem);
  }

  * { box-sizing: border-box; }
  html, body { margin: 0; padding: 0; }

  body {
    background: var(--void);
    color: var(--parchment);
    font-family: var(--font-body);
    font-size: 1.08rem;
    line-height: 1.7;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
  }

  img, svg { display: block; max-width: 100%; }

  /* Links in running text keep their underline. Colour alone fails WCAG 1.4.1.
     The old underline was 40% of a dark orange, 2.1:1 against the background:
     present in the markup, invisible in practice. This is about 5:1. */
  a {
    color: var(--ember-bright);
    text-decoration-color: rgba(111, 224, 214, 0.55);
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
    transition: text-decoration-color 0.2s ease, color 0.2s ease;
  }
  a:hover { text-decoration-color: var(--ember-bright); }

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

  .visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .skip-link {
    position: absolute;
    left: 1rem; top: -3rem;
    background: var(--ember);
    color: var(--void);
    padding: 0.6rem 1rem;
    font-family: var(--font-mono);
    font-size: 0.85rem;
    z-index: 1000;
    transition: top 0.2s ease;
  }
  .skip-link:focus { top: 1rem; }

  .container { width: var(--container); margin: 0 auto; }

  .eyebrow {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ember) !important;
    margin: 0 0 1rem;
  }

  .eyebrow-heading { font-weight: 400; }

  h1, h2, h3 {
    font-family: var(--font-display);
    font-weight: 700;
    color: var(--parchment);
    margin: 0;
  }

  section { padding: var(--section-pad) 0; position: relative; }

  .section-head { max-width: 640px; margin-bottom: 3rem; }
  .section-head.center { margin-left: auto; margin-right: auto; text-align: center; }

  /* ============ GRAIN + AMBIENT LAYERS ============ */
  .grain {
    position: fixed; inset: 0; pointer-events: none; z-index: 5;
    opacity: 0.05; mix-blend-mode: overlay;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  }

  /* ============ NAV ============ */
  .nav {
    position: fixed; top: 0; left: 0; right: 0; z-index: 100;
    padding: 1.5rem 0;
    transition: background 0.3s ease, padding 0.3s ease, border-color 0.3s ease;
    border-bottom: 1px solid transparent;
  }
  .nav.scrolled {
    background: rgba(10, 10, 13, 0.85);
    backdrop-filter: blur(10px);
    padding: 1rem 0;
    border-bottom: 1px solid var(--hairline);
  }
  .nav-inner {
    width: var(--container); margin: 0 auto;
    display: flex; align-items: center; justify-content: space-between;
  }
  .nav-logo {
    font-family: var(--font-body);
    font-style: italic;
    font-size: 1.25rem;
    color: var(--parchment);
    text-decoration: none;
  }

  /* Egg trigger. A real button for keyboard access, but visually identical to
     the display text. The arrow cursor is intentional: no hover clue, no URL. */
  .secret-terminal-trigger {
    -webkit-appearance: none;
    appearance: none;
    border: 0;
    padding: 0;
    background: transparent;
    color: inherit;
    cursor: default !important;
    -webkit-tap-highlight-color: transparent;
  }

  .secret-terminal-trigger:hover {
    cursor: default !important;
  }
  .nav-links {
    display: flex; gap: 2.25rem;
    list-style: none; margin: 0; padding: 0;
  }
  .nav-links a {
    font-family: var(--font-mono);
    font-size: 0.78rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--parchment-dim);
    text-decoration: none;
    border-bottom: 1px solid transparent;
    padding-bottom: 2px;
  }
  .nav-links a:hover { color: var(--ember-bright); border-color: var(--ember-bright); }

  .menu-toggle {
    display: none;
    background: none; border: 1px solid var(--hairline);
    color: var(--parchment);
    font-family: var(--font-mono);
    font-size: 0.78rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    padding: 0.5rem 0.9rem;
    cursor: pointer;
  }

  .mobile-menu {
    position: fixed; inset: 0; z-index: 200;
    background: var(--void);
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: 2rem;
  }
  .mobile-menu[hidden] { display: none; }
  .mobile-menu a {
    font-family: var(--font-display);
    font-size: 1.75rem;
    color: var(--parchment);
    text-decoration: none;
  }
  .mobile-menu .close-btn {
    position: absolute; top: 1.5rem; right: 1.5rem;
    background: none; border: none;
    color: var(--parchment); font-size: 1rem;
    font-family: var(--font-mono);
    cursor: pointer;
  }

  /* ============ PHOTO SECTIONS ============ */
  /* Reusable: real photograph, desaturated and darkened, teal/violet tint
     pooled on top so it matches the palette instead of reading as stock. */
  .photo-section { position: relative; overflow: hidden; }
  .photo-bg {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover; object-position: center;
    filter: grayscale(0.4) brightness(0.55) contrast(1.05);
    z-index: 0;
  }
  .photo-overlay {
    position: absolute; inset: 0;
    background:
      radial-gradient(circle at 28% 30%, rgba(73,201,192,0.28), transparent 60%),
      radial-gradient(circle at 74% 68%, rgba(155,134,217,0.24), transparent 60%),
      linear-gradient(180deg, rgba(10,13,18,0.55) 0%, rgba(10,13,18,0.8) 100%);
    z-index: 1;
  }
  .photo-content { position: relative; z-index: 2; }

  .photo-band { min-height: 40vh; display: flex; align-items: center; justify-content: center; }


  /* ============ COAST SHELTER: NIGHT-VISION EASTER EGG ============ */
  /* Two photographs in the same crop. The night version is preloaded and swaps
     in instantly on activation: no fade, no flash, no reflow. */
  .coast-watch {
    width: 100%;
    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    cursor: default;
    -webkit-tap-highlight-color: transparent;
    -webkit-appearance: none;
    appearance: none;
    isolation: isolate;
  }

  .coast-watch:focus-visible {
    outline: 3px solid var(--ember-bright);
    outline-offset: -6px;
  }

  .coast-watch .coast-photo {
    transition: none;
  }

  .coast-watch .coast-photo-day {
    opacity: 1;
  }

  .coast-watch .coast-photo-night {
    opacity: 0;
    /* Already graded as night vision. Do not run the site photo filter over it twice. */
    filter: none;
  }

  .coast-watch .photo-overlay {
    transition: none;
  }

  .coast-watch.night-vision .coast-photo-day {
    opacity: 0;
  }

  .coast-watch.night-vision .coast-photo-night {
    opacity: 1;
  }

  .coast-watch.night-vision .photo-overlay {
    opacity: 0;
  }

  @media (prefers-reduced-motion: reduce) {
    .coast-watch .coast-photo,
    .coast-watch .photo-overlay { transition: none; }
  }

  /* ============ HERO ============ */
  .hero {
    min-height: 100svh;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    text-align: center;
    position: relative;
    padding: 6rem 1.5rem 4rem;
    background: var(--void);
    overflow: hidden;
  }

  .hero-glow {
    position: absolute;
    z-index: 1;
    top: 40%; left: 50%;
    width: 70vw; height: 70vw; max-width: 1000px; max-height: 1000px;
    transform: translate(-50%, -50%);
    background:
      radial-gradient(circle at 38% 45%, rgba(73,201,192,0.18) 0%, transparent 55%),
      radial-gradient(circle at 62% 55%, rgba(155,134,217,0.16) 0%, transparent 55%);
    filter: blur(50px);
    animation: drift 14s ease-in-out infinite alternate;
    pointer-events: none;
  }
  @keyframes drift {
    0%   { opacity: 0.75; transform: translate(-50%, -50%) scale(1) rotate(0deg); }
    50%  { opacity: 1;    transform: translate(-48%, -52%) scale(1.08) rotate(4deg); }
    100% { opacity: 0.85; transform: translate(-52%, -48%) scale(0.97) rotate(-3deg); }
  }
  @media (prefers-reduced-motion: reduce) {
    .hero-glow { animation: none; opacity: 0.85; }
  }

  .hero-content { position: relative; z-index: 2; }

  .hero .eyebrow { justify-content: center; }

  .glitch-display {
    position: relative;
    display: inline-block;
    font-family: var(--font-display);
    font-weight: 800;
    font-size: clamp(3.2rem, 11vw, 8.5rem);
    line-height: 1.05;
    letter-spacing: 0.01em;
    text-transform: uppercase;
    margin: 0.25rem 0 1.25rem;
  }
  /* Each letter is its own element with two duplicate copies layered over it
     (teal right, violet left) covering the whole glyph. Four burst patterns
     (gl-1..gl-4) are spread across the letters, each with its own delay and
     duration set inline, so the flicker never lands on every letter at once. */
  .glitch-letter { position: relative; display: inline-block; }
  .glitch-letter::before,
  .glitch-letter::after {
    content: attr(data-text);
    position: absolute;
    inset: 0;
    pointer-events: none;
    animation-timing-function: steps(1, end);
    animation-iteration-count: infinite;
    animation-delay: var(--delay, 0s);
    animation-duration: var(--duration, 5s);
  }
  .glitch-letter::before { color: var(--ember-bright); --glitch-dir: 1; opacity: 0.75; }
  .glitch-letter::after  { color: var(--verdigris);    --glitch-dir: -1; opacity: 0.75; }
  .glitch-letter.gl-1::before, .glitch-letter.gl-1::after { animation-name: glitch-1; }
  .glitch-letter.gl-2::before, .glitch-letter.gl-2::after { animation-name: glitch-2; }
  .glitch-letter.gl-3::before, .glitch-letter.gl-3::after { animation-name: glitch-3; }
  .glitch-letter.gl-4::before, .glitch-letter.gl-4::after { animation-name: glitch-4; }

  @keyframes glitch-1 {
    0%, 41%, 100% { transform: translate(calc(var(--glitch-dir) * 4px), 0); }
    42% { transform: translate(calc(var(--glitch-dir) * 12px), -2px); }
    43.5% { transform: translate(calc(var(--glitch-dir) * 2px), 1px); }
    45% { transform: translate(calc(var(--glitch-dir) * 4px), 0); }
  }
  @keyframes glitch-2 {
    0%, 63%, 100% { transform: translate(calc(var(--glitch-dir) * 4px), 0); }
    64% { transform: translate(calc(var(--glitch-dir) * -8px), 2px); }
    66% { transform: translate(calc(var(--glitch-dir) * 10px), 0); }
    67.5% { transform: translate(calc(var(--glitch-dir) * 4px), 0); }
  }
  @keyframes glitch-3 {
    0%, 18%, 100% { transform: translate(calc(var(--glitch-dir) * 4px), 0); }
    19% { transform: translate(calc(var(--glitch-dir) * 9px), -1px); }
    21%, 85% { transform: translate(calc(var(--glitch-dir) * 4px), 0); }
    86% { transform: translate(calc(var(--glitch-dir) * -6px), 1px); }
    88% { transform: translate(calc(var(--glitch-dir) * 4px), 0); }
  }
  @keyframes glitch-4 {
    0%, 55%, 100% { transform: translate(calc(var(--glitch-dir) * 4px), 0); }
    56% { transform: translate(calc(var(--glitch-dir) * 13px), 2px); }
    58% { transform: translate(calc(var(--glitch-dir) * -3px), -1px); }
    60% { transform: translate(calc(var(--glitch-dir) * 4px), 0); }
  }
  @media (prefers-reduced-motion: reduce) {
    .glitch-letter::before, .glitch-letter::after { animation: none; }
  }

  .hero .tagline {
    font-family: var(--font-body);
    font-style: italic;
    font-size: clamp(1.15rem, 2.2vw, 1.5rem);
    color: var(--parchment);
    max-width: 32rem;
    margin: 0 auto;
  }

  .hero-actions {
    position: relative; z-index: 2;
    display: flex; flex-direction: column; align-items: center; gap: 1rem;
    margin-top: 0.5rem;
  }
  .hero-link {
    font-family: var(--font-mono); font-size: 0.8rem;
    letter-spacing: 0.05em;
    color: var(--parchment-dim);
  }
  .hero-link:hover { color: var(--ember-bright); }

  /* ============ DIVIDER ============ */
  .divider {
    display: flex; align-items: center; gap: 1rem;
    max-width: 220px; margin: 0 auto;
    opacity: 0.75;
  }
  .divider .line { flex: 1; height: 1px; background: var(--hairline); }
  .divider svg { width: 15px; height: 15px; color: var(--ember); flex-shrink: 0; }

  /* ============ BIO ============ */
  .about-hero {
    display: flex;
    align-items: center;
    min-height: 85vh;
  }
  .about-hero .photo-bg {
    filter: grayscale(0.1) brightness(0.85) contrast(1.02);
  }
  .about-overlay {
    position: absolute; inset: 0; z-index: 1;
    background:
      radial-gradient(circle at 88% 25%, rgba(73,201,192,0.18), transparent 55%),
      radial-gradient(circle at 92% 78%, rgba(155,134,217,0.16), transparent 55%),
      linear-gradient(to right, transparent 0%, transparent 36%, rgba(10,13,18,0.78) 62%, var(--void) 84%);
  }
  .bio-text { max-width: 520px; margin-left: auto; text-align: center; }
  .bio-text p { color: var(--parchment-dim); margin: 0 0 1.35rem; }
  .bio-text p:last-of-type { margin-bottom: 0; }
  @media (max-width: 860px) {
    .about-hero {
      display: block;
      min-height: auto;
      padding: 0 0 4.5rem;
    }
    .about-hero .photo-bg {
      position: static;
      display: block;
      width: 100%;
      height: auto;
      aspect-ratio: 1 / 1;
      filter: grayscale(0.1) brightness(0.85) contrast(1.02);
    }
    .about-overlay { display: none; }
    .about-hero .container { padding-top: 2.5rem; }
    .bio-text { max-width: 100%; margin-left: 0; text-align: left; }
  }

  .kofi-callout {
    grid-column: span 2;
    min-height: 280px;
    display: flex; align-items: center; justify-content: center;
    padding: clamp(2rem, 4vw, 2.5rem);
  }
  .kofi-callout .photo-content { text-align: center; }
  .kofi-text {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(1.2rem, 2.6vw, 1.5rem);
    color: var(--parchment);
    max-width: 380px;
    margin: 0 auto 1.5rem;
  }

  /* ============ FEATURED STORY ============ */
  .featured-story {
    min-height: 70vh;
    display: flex; align-items: center;
    text-align: left;
  }
  .featured-content { max-width: min(520px, 46%); margin-right: auto; }
  .featured-title { margin-bottom: 0.5rem; }
  .featured-title a {
    font-family: var(--font-body); font-style: italic;
    font-size: clamp(1.75rem, 4vw, 2.75rem);
    color: var(--parchment); text-decoration: none;
  }
  .featured-title a:hover { color: var(--ember-bright); }
  .featured-venue {
    font-family: var(--font-mono); font-size: 0.75rem;
    letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--verdigris); margin-bottom: 1.25rem;
  }
  .featured-story p:not(.featured-venue) { color: var(--parchment-dim); margin-bottom: 1.75rem; }
  @media (max-width: 860px) {
    .featured-story { text-align: center; }
    .featured-content { max-width: 100%; margin-right: auto; margin-left: auto; }
  }

  /* ============ STORIES ============ */
  .stories-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: clamp(2rem, 4vw, 2.75rem) clamp(2rem, 5vw, 3.5rem);
  }
  .story-card {
    padding-bottom: clamp(1.5rem, 3vw, 2rem);
    border-bottom: 1px solid var(--hairline);
  }
  .story-venue {
    font-family: var(--font-mono); font-size: 0.72rem;
    letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--verdigris); margin-bottom: 0.6rem;
  }
  .mature-tag { color: var(--ember); }
  .story-card h3 { font-size: 1.4rem; margin-bottom: 0.6rem; line-height: 1.25; }
  .story-card h3 a {
    color: var(--parchment); text-decoration: none;
    font-family: var(--font-body); font-style: italic;
  }
  .story-card h3 a:hover { color: var(--ember-bright); }
  .story-card p { color: var(--parchment-dim); font-size: 0.98rem; margin: 0 0 1rem; }
  .story-link { font-family: var(--font-mono); font-size: 0.78rem; text-decoration: none; }

  /* Story card hover.
     The cards have no surface of their own, so the panel is a pseudo-element
     that only exists on hover. It bleeds past the card box, which means nothing
     needs padding or repositioning at rest and the grid is untouched. Only one
     card can be hovered, so neighbours never overlap.
     Cursors only: touch would leave the effect stuck half-on after a tap. */
  @media (hover: hover) and (pointer: fine) {
    .story-card {
      position: relative;
      isolation: isolate;
      transition:
        transform 420ms cubic-bezier(0.2, 0.7, 0.2, 1),
        border-bottom-color 420ms ease;
    }

    /* Fading a pseudo-element is much cheaper than animating box-shadow. */
    .story-card::before {
      content: "";
      position: absolute;
      inset: -1.15rem -1.15rem 0;
      z-index: -1;
      border-radius: 3px;
      background: linear-gradient(
        180deg,
        rgba(28, 35, 64, 0.50) 0%,
        rgba(16, 20, 28, 0.72) 100%
      );
      box-shadow:
        0 18px 44px rgba(0, 0, 0, 0.48),
        inset 0 0 0 1px rgba(231, 236, 232, 0.07);
      opacity: 0;
      pointer-events: none;
      transition: opacity 380ms ease;
    }

    /* Holographic pass: a wide gradient on an oversized background moved by
       background-position, so the element box does the clipping and no wrapper
       is needed. All stops well under 15% opacity, or it reads as tinsel. */
    .story-card::after {
      content: "";
      position: absolute;
      inset: -1.15rem -1.15rem 0;
      z-index: -1;
      border-radius: 3px;
      pointer-events: none;
      opacity: 0;

      background-image: linear-gradient(
        105deg,
        transparent 30%,
        rgba(111, 224, 214, 0.09) 42%,
        rgba(231, 236, 232, 0.13) 50%,
        rgba(155, 134, 217, 0.10) 58%,
        transparent 70%
      );
      background-size: 250% 100%;
      background-repeat: no-repeat;
      background-position: 140% 0;

      /* On hover out, fade first and only then reset the sweep, so it is never
         seen running backwards. */
      transition:
        opacity 300ms ease,
        background-position 0s linear 300ms;
    }

    .story-card:hover {
      transform: translateY(-6px) scale(1.012);
      border-bottom-color: rgba(111, 224, 214, 0.42);
    }

    .story-card:hover::before { opacity: 1; }

    .story-card:hover::after {
      opacity: 1;
      background-position: -40% 0;
      transition:
        opacity 260ms ease,
        background-position 1150ms cubic-bezier(0.22, 0.61, 0.24, 1);
    }

    .story-card:hover h3 a { color: var(--ember-bright); }
  }

  @media (prefers-reduced-motion: reduce) {
    .story-card,
    .story-card:hover {
      transform: none;
      transition: border-bottom-color 200ms ease;
    }
    .story-card::after,
    .story-card:hover::after { display: none; }
    .story-card::before { transition: opacity 200ms ease; }
  }

  /* ============ AWARDS ============ */
  .awards-list {
    max-width: 900px; margin: 0 auto;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(3rem, 8vw, 6rem);
    text-align: center;
  }
  .award-row:last-child {
    padding-left: clamp(1.5rem, 4vw, 3rem);
  }
  .award-name {
    font-family: var(--font-mono); font-weight: 500;
    letter-spacing: 0.08em; text-transform: uppercase;
    font-size: 0.92rem; color: var(--parchment); margin-bottom: 0.3rem;
  }
  .award-detail { font-family: var(--font-body); font-style: italic; color: var(--parchment-dim); font-size: 1rem; }
  @media (max-width: 700px) {
    .awards-list { grid-template-columns: 1fr; max-width: 420px; }
    .award-row:last-child { border-left: none; padding-left: 0; }
  }

  /* ============ SIGNATURE PANEL ============ */
  .panel {
    background: linear-gradient(180deg, var(--aubergine) 0%, var(--void-2) 100%);
  }
  .panel .container { text-align: center; max-width: 780px; }
  .panel h2 {
    font-family: var(--font-body);
    font-style: italic; font-weight: 400;
    font-size: clamp(1.8rem, 4vw, 2.75rem);
    line-height: 1.25; margin-bottom: 1.5rem;
  }
  .panel p { color: var(--parchment-dim); font-size: 1.1rem; margin-bottom: 2rem; }
  .panel .btn-link {
    font-family: var(--font-mono); font-size: 0.8rem;
    letter-spacing: 0.1em; text-transform: uppercase;
    text-decoration: none;
  }

  /* ============ PRAISE ============ */
  .quote {
    font-family: var(--font-body); font-style: italic;
    font-size: clamp(1.1rem, 1.6vw, 1.3rem);
    line-height: 1.45; color: var(--parchment);
    margin: 0 0 1.1rem;
    overflow-wrap: break-word;
  }
  .quote::before { content: "“"; color: var(--ember); }
  .quote::after { content: "”"; color: var(--ember); }
  .attribution {
    font-family: var(--font-mono); font-size: 0.75rem;
    letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--ash);
    overflow-wrap: break-word;
  }

  .praise-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(2rem, 5vw, 3rem);
  }
  .praise-card { text-align: center; }
  @media (max-width: 860px) {
    .praise-grid { grid-template-columns: 1fr; gap: 3rem; max-width: 420px; margin: 0 auto; }
  }

  /* ============ CONTACT + NEWSLETTER ============ */
  .contact-newsletter {
    background: radial-gradient(ellipse 80% 100% at 50% 100%, rgba(73,201,192,0.1), transparent);
  }
  .contact-newsletter-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(2.5rem, 6vw, 5rem);
  }
  .contact-col, .newsletter-col { text-align: center; display: flex; flex-direction: column; }
  .contact-col .btn { margin-top: auto; align-self: center; }
  .newsletter-col .newsletter-form { margin-top: auto; }
  .contact-col p, .newsletter-col p { color: var(--parchment-dim); margin-bottom: 2rem; }
  .newsletter-form {
    display: flex; gap: 0.75rem;
    max-width: 420px; margin: 0 auto;
  }
  .newsletter-form input[type="email"] {
    flex: 1; min-width: 0;
    background: var(--void-2);
    border: 1px solid var(--ash);
    color: var(--parchment);
    font-family: var(--font-body); font-size: 1rem;
    padding: 0.85rem 1.1rem;
  }
  .newsletter-form input[type="email"]::placeholder { color: var(--ash); }
  .btn {
    display: inline-block;
    background: var(--ember);
    color: var(--void);
    border: none;
    font-family: var(--font-mono); font-size: 0.8rem;
    letter-spacing: 0.08em; text-transform: uppercase;
    text-decoration: none;
    padding: 0.85rem 1.5rem;
    cursor: pointer;
    transition: background 0.2s ease, box-shadow 0.2s ease;
    white-space: nowrap;
  }
  .btn:hover { background: var(--ember-bright); box-shadow: 0 0 24px rgba(73,201,192,0.35); }


  /* ============ KO-FI SIGNAL BUTTON ============ */
  /* Circulating-edge treatment, kept to this palette. Scoped to the Ko-fi CTA
     only; other .btn elements are unaffected. */
  .kofi-neon-btn {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    background: rgba(10, 13, 18, 0.90);
    color: var(--parchment);
    border: 1px solid rgba(111, 224, 214, 0.30);
    box-shadow:
      inset 0 0 0 1px rgba(155, 134, 217, 0.08),
      0 0 0 rgba(73, 201, 192, 0);
    transition:
      transform 260ms cubic-bezier(0.2, 0.7, 0.2, 1),
      color 260ms ease,
      background 340ms ease,
      border-color 260ms ease,
      box-shadow 340ms ease;
  }

  .kofi-neon-btn .kofi-btn-label {
    position: relative;
    z-index: 2;
  }

  .kofi-neon-btn .kofi-edge {
    position: absolute;
    z-index: 3;
    display: block;
    pointer-events: none;
  }

  .kofi-edge-top {
    top: 0;
    left: -100%;
    width: 100%;
    height: 2px;
    background: linear-gradient(90deg, transparent, var(--ember-bright));
    animation: kofi-signal-top 1.6s linear infinite;
  }

  .kofi-edge-right {
    top: -100%;
    right: 0;
    width: 2px;
    height: 100%;
    background: linear-gradient(180deg, transparent, var(--verdigris));
    animation: kofi-signal-right 1.6s linear infinite;
    animation-delay: 0.4s;
  }

  .kofi-edge-bottom {
    right: -100%;
    bottom: 0;
    width: 100%;
    height: 2px;
    background: linear-gradient(270deg, transparent, var(--ember-bright));
    animation: kofi-signal-bottom 1.6s linear infinite;
    animation-delay: 0.8s;
  }

  .kofi-edge-left {
    bottom: -100%;
    left: 0;
    width: 2px;
    height: 100%;
    background: linear-gradient(0deg, transparent, var(--verdigris));
    animation: kofi-signal-left 1.6s linear infinite;
    animation-delay: 1.2s;
  }

  @keyframes kofi-signal-top {
    0% { left: -100%; }
    50%, 100% { left: 100%; }
  }

  @keyframes kofi-signal-right {
    0% { top: -100%; }
    50%, 100% { top: 100%; }
  }

  @keyframes kofi-signal-bottom {
    0% { right: -100%; }
    50%, 100% { right: 100%; }
  }

  @keyframes kofi-signal-left {
    0% { bottom: -100%; }
    50%, 100% { bottom: 100%; }
  }

  @media (hover: hover) and (pointer: fine) {
    .kofi-neon-btn:hover {
      transform: translateY(-2px);
      color: var(--void);
      border-color: rgba(231, 236, 232, 0.75);
      background: linear-gradient(
        110deg,
        var(--ember-bright) 0%,
        #8bd8d5 42%,
        var(--verdigris) 100%
      );
      box-shadow:
        0 0 5px rgba(111, 224, 214, 0.78),
        0 0 22px rgba(73, 201, 192, 0.50),
        0 0 48px rgba(155, 134, 217, 0.35),
        0 0 82px rgba(155, 134, 217, 0.18);
    }
  }

  .kofi-neon-btn:focus-visible {
    color: var(--void);
    background: linear-gradient(
      110deg,
      var(--ember-bright) 0%,
      #8bd8d5 42%,
      var(--verdigris) 100%
    );
    border-color: var(--parchment);
    box-shadow:
      0 0 0 2px var(--void),
      0 0 0 4px var(--parchment),
      0 0 30px rgba(73, 201, 192, 0.42);
  }

  @media (prefers-reduced-motion: reduce) {
    .kofi-neon-btn .kofi-edge { display: none; }
    .kofi-neon-btn { transition: none; }
  }
  .form-note {
    font-family: var(--font-mono); font-size: 0.7rem;
    color: var(--ash); margin-top: 1.1rem;
    line-height: 1.4;
  }

  /* ============ FOOTER ============ */
  footer {
    padding: 3rem 0;
    border-top: 1px solid var(--hairline);
  }
  .footer-inner {
    display: flex; justify-content: space-between; align-items: center;
    flex-wrap: wrap; gap: 1.5rem;
  }
  .footer-brand { font-family: var(--font-body); font-style: italic; color: var(--parchment); }
  .footer-copy { font-family: var(--font-mono); font-size: 0.72rem; color: var(--ash); margin-top: 0.4rem; }
  .footer-social { display: flex; gap: 1.75rem; list-style: none; margin: 0; padding: 0; }
  .footer-social a {
    font-family: var(--font-mono); font-size: 0.75rem;
    letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--parchment-dim); text-decoration: none;
    border-bottom: 1px solid transparent; padding-bottom: 2px;
  }
  .footer-social a:hover { color: var(--ember-bright); border-color: var(--ember-bright); }

  /* The icon links carry no text, so their box collapses to the width of the
     glyph, around 7px, which is not a target anyone can hit on a phone. The
     target is enlarged with a pseudo-element rather than with padding, so the
     footer's layout does not move a pixel. */
  .footer-social a:has(svg) {
    position: relative;
    border-bottom: 0;
  }

  .footer-social a:has(svg)::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
  }

  /* ============ RESPONSIVE ============ */
  @media (max-width: 860px) {
    .nav-links { display: none; }
    .menu-toggle { display: inline-block; }
    .contact-newsletter-grid { grid-template-columns: 1fr; gap: 3rem; }
    .kofi-callout { grid-column: span 1; min-height: 220px; }
  }
  @media (max-width: 480px) {
    .glitch-display { font-size: clamp(2.3rem, 12vw, 8.5rem); letter-spacing: 0.03em; }
  }
  @media (max-width: 560px) {
    .newsletter-form { flex-direction: column; }
    .footer-inner { flex-direction: column; align-items: flex-start; }
  }


  /* ============ BLOG ============ */
  .page-header {
    min-height: 55vh;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    text-align: center;
    padding: 8rem 1.5rem 3rem;
  }
  .page-header h1 {
    font-size: clamp(2.75rem, 7vw, 5rem);
    line-height: 1;
    letter-spacing: 0.01em;
    text-transform: uppercase;
    max-width: 21ch;
    margin: 0.25rem 0 1.25rem;
  }
  .page-header .tagline {
    font-family: var(--font-body); font-style: italic;
    font-size: clamp(1.05rem, 2vw, 1.3rem);
    color: var(--parchment-dim);
    max-width: 32rem; margin: 0 auto;
  }

  .post-list { max-width: 760px; margin: 0 auto; }
  .post-card {
    padding: clamp(2rem, 5vw, 3rem) 0;
    border-bottom: 1px solid var(--hairline);
  }
  .post-card:first-child { border-top: 1px solid var(--hairline); }
  .post-date {
    font-family: var(--font-mono); font-size: 0.72rem;
    letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--verdigris); margin-bottom: 0.75rem;
  }
  .post-card h2 {
    font-size: clamp(1.5rem, 3vw, 2rem);
    margin-bottom: 0.85rem; line-height: 1.2;
  }
  .post-card h2 a { color: var(--parchment); text-decoration: none; font-family: var(--font-body); font-style: italic; }
  .post-card h2 a:hover { color: var(--ember-bright); }
  .post-card p { color: var(--parchment-dim); margin: 0 0 1.1rem; }
  .post-card .story-link { font-family: var(--font-mono); font-size: 0.8rem; text-decoration: none; }
  .post-toggle {
    background: none; border: none; padding: 0; cursor: pointer;
    color: var(--ember-bright);
    text-decoration-color: rgba(73,201,192,0.4); text-underline-offset: 3px;
  }
  .post-toggle:hover { text-decoration-color: var(--ember-bright); }
  /* max-height alone only hides a collapsed post visually: the text stays in
     the accessibility tree and links stay tabbable, so a keyboard user tabs
     into a panel they cannot see. visibility removes it properly, delayed on
     the way closed so the slide still animates. */
  .post-full {
    max-height: 0;
    overflow: hidden;
    visibility: hidden;
    transition: max-height 0.4s ease, visibility 0s linear 0.4s;
  }
  .post-full.is-open {
    visibility: visible;
    transition: max-height 0.4s ease, visibility 0s linear 0s;
  }
  .post-full p { padding-top: 0.25rem; }
  .post-full p:last-child { margin-bottom: 1.1rem; }


  /* ============ SECRET FLOOD ============ */
  .secret-flood {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: 0;
    z-index: 9999;
    pointer-events: none;
    overflow: hidden;

    background:
      radial-gradient(circle at 20% 30%, rgba(111, 224, 214, 0.08), transparent 24%),
      radial-gradient(circle at 75% 55%, rgba(155, 134, 217, 0.08), transparent 28%),
      linear-gradient(
        to bottom,
        rgba(22, 126, 137, 0.92) 0%,
        rgba(8, 73, 88, 0.97) 35%,
        rgba(4, 35, 51, 0.99) 70%,
        #02141f 100%
      );

    /* The irregular polygon is the actual top edge of the water. */
    clip-path: polygon(
      0 25px,
      5% 9px,
      10% 20px,
      15% 4px,
      20% 24px,
      25% 12px,
      30% 29px,
      35% 8px,
      40% 20px,
      45% 3px,
      50% 25px,
      55% 11px,
      60% 30px,
      65% 6px,
      70% 22px,
      75% 10px,
      80% 27px,
      85% 5px,
      90% 21px,
      95% 8px,
      100% 24px,
      100% 100%,
      0 100%
    );

    transition:
      height 9s cubic-bezier(0.45, 0, 0.2, 1),
      clip-path var(--chop-speed, 520ms) ease-in-out;
  }

  /* Two layers under the random waterline: pale broken foam over a deeper
     teal secondary crest. */
  .secret-flood::before,
  .secret-flood::after {
    content: "";
    position: absolute;
    left: -14%;
    width: 128%;
    pointer-events: none;
  }

  .secret-flood::before {
    top: -1px;
    height: 43px;
    opacity: 0.78;
    background:
      radial-gradient(ellipse at 8% 12%,  rgba(242, 255, 253, 0.78) 0 7px, transparent 8px),
      radial-gradient(ellipse at 24% 25%, rgba(225, 250, 247, 0.66) 0 9px, transparent 10px),
      radial-gradient(ellipse at 43% 9%,  rgba(248, 255, 254, 0.72) 0 6px, transparent 7px),
      radial-gradient(ellipse at 61% 24%, rgba(224, 249, 246, 0.62) 0 10px, transparent 11px),
      radial-gradient(ellipse at 79% 7%,  rgba(246, 255, 254, 0.74) 0 7px, transparent 8px),
      radial-gradient(ellipse at 95% 21%, rgba(226, 250, 247, 0.64) 0 9px, transparent 10px),
      linear-gradient(
        178deg,
        rgba(235, 254, 252, 0.46) 0 11px,
        rgba(179, 237, 231, 0.20) 12px 20px,
        transparent 21px
      );
    background-size:
      173px 37px,
      229px 43px,
      191px 35px,
      263px 46px,
      211px 38px,
      287px 44px,
      100% 100%;
    animation: flood-crest-a 3.35s cubic-bezier(0.37, 0.04, 0.54, 0.98) infinite alternate;
  }

  .secret-flood::after {
    top: 9px;
    height: 39px;
    opacity: 0.66;
    background:
      radial-gradient(ellipse at 15% 10%, rgba(111, 224, 214, 0.42) 0 11px, transparent 12px),
      radial-gradient(ellipse at 39% 21%, rgba(73, 201, 192, 0.36) 0 14px, transparent 15px),
      radial-gradient(ellipse at 67% 8%,  rgba(111, 224, 214, 0.38) 0 10px, transparent 11px),
      radial-gradient(ellipse at 88% 24%, rgba(73, 201, 192, 0.34) 0 13px, transparent 14px),
      linear-gradient(
        183deg,
        rgba(111, 224, 214, 0.34) 0 14px,
        rgba(35, 143, 148, 0.14) 15px 27px,
        transparent 28px
      );
    background-size:
      247px 42px,
      311px 48px,
      223px 40px,
      337px 51px,
      100% 100%;
    animation: flood-crest-b 5.15s cubic-bezier(0.28, 0.06, 0.67, 0.93) infinite alternate-reverse;
  }

  .secret-flood.rising {
    height: 115%;
  }

  @keyframes flood-crest-a {
    0%   { transform: translateX(-5.5%) translateY(1px) skewX(-2deg) scaleY(0.86); }
    17%  { transform: translateX(-1%) translateY(7px) skewX(2deg) scaleY(1.13); }
    46%  { transform: translateX(4%) translateY(2px) skewX(-1deg) scaleY(0.94); }
    73%  { transform: translateX(1.5%) translateY(10px) skewX(3deg) scaleY(1.08); }
    100% { transform: translateX(-3%) translateY(4px) skewX(-3deg) scaleY(0.91); }
  }

  @keyframes flood-crest-b {
    0%   { transform: translateX(4%) translateY(8px) skewX(2deg) scaleY(1.08); }
    29%  { transform: translateX(-3%) translateY(2px) skewX(-4deg) scaleY(0.84); }
    54%  { transform: translateX(-5%) translateY(11px) skewX(1deg) scaleY(1.17); }
    82%  { transform: translateX(2%) translateY(4px) skewX(4deg) scaleY(0.93); }
    100% { transform: translateX(5%) translateY(7px) skewX(-1deg) scaleY(1.03); }
  }

  /* Bubbles */
  .secret-bubble {
    position: absolute;
    bottom: -40px;
    border: 1px solid rgba(231, 236, 232, 0.35);
    border-radius: 50%;
    opacity: 0;
    animation: secret-bubble-rise var(--bubble-speed) linear infinite;
    animation-delay: var(--bubble-delay);
  }

  @keyframes secret-bubble-rise {
    0% {
      transform: translateY(0) translateX(0);
      opacity: 0;
    }
    10% { opacity: 0.5; }
    80% { opacity: 0.25; }
    100% {
      transform: translateY(-110vh) translateX(var(--bubble-drift));
      opacity: 0;
    }
  }

  /* Small silver fish, revealed only after the flood reaches the top. */
  .secret-fish {
    position: absolute;
    z-index: 2;
    left: 10%;
    top: 74%;
    width: 44px;
    height: 24px;
    padding: 0;
    border: 0;
    border-radius: 60% 48% 48% 60%;
    opacity: 0;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;

    background:
      radial-gradient(circle at 72% 32%, rgba(255, 255, 255, 0.9) 0 3%, transparent 4%),
      linear-gradient(
        to bottom,
        #f2f4f3 0%,
        #aebcc0 38%,
        #65767c 67%,
        #c6d0d1 100%
      );

    box-shadow:
      inset 0 1px rgba(255, 255, 255, 0.55),
      inset 0 -2px rgba(10, 30, 37, 0.35);

    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.35));
    transform: translate(-50%, -50%);
    transform-origin: center;
  }

  .secret-fish:focus-visible {
    outline: 3px solid #ffffff;
    outline-offset: 7px;
  }

  /* The way out is a marker buoy. Flashes a group of two, like a cardinal mark.
     No clue depends on it and the water can be raised again as often as wanted. */
  .secret-flood-close {
    /* Rides the waterline inside the sky assembly, so it bobs on the surface
       rather than hanging in mid-water. Do not pin this to the viewport: a buoy
       that cannot be submerged is the whole point of using one. */
    position: absolute;
    z-index: 6;
    bottom: 6px;
    right: 14%;
    display: flex;
    flex-direction: column;
    align-items: center;
    min-width: 62px;
    min-height: 44px;
    padding: 0.5rem 0.4rem 0;
    border: 0;
    border-radius: 6px;
    background: none;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
    animation: buoy-bob 4.4s ease-in-out infinite;
  }

  .secret-flood-close:focus-visible {
    outline: 2px solid var(--parchment);
    outline-offset: 6px;
  }

  .buoy-light {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #fff6e8;
    box-shadow: 0 0 18px 6px rgba(255, 176, 92, 0.85);
    animation: buoy-flash 5.6s linear infinite;
  }

  .buoy-mast {
    width: 2px;
    height: 14px;
    background: var(--parchment);
  }

  .buoy-body {
    position: relative;
    overflow: hidden;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--parchment);
    box-shadow: 0 2px 12px rgba(2, 20, 31, 0.6);
  }

  /* The band every navigation mark carries. */
  .buoy-body::after {
    content: "";
    position: absolute;
    left: 0;
    top: 11px;
    width: 100%;
    height: 8px;
    background: var(--void);
  }

  /* Faded up only on hover or focus. It is the button accessible name either way. */
  .buoy-label {
    margin-top: 0.55rem;
    color: var(--parchment);
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    white-space: nowrap;
    text-shadow: 0 1px 4px #02141f;
    opacity: 0;
    transition: opacity 0.35s ease;
  }

  .secret-flood-close:hover .buoy-label,
  .secret-flood-close:focus-visible .buoy-label {
    opacity: 0.9;
  }


  /* ============ THE SURFACE ============
     The water belongs to the document, not to the screen: the newsletter, the
     stories and the about section are all under it. The surface is at the TOP OF
     THE PAGE, so the way out is to swim up and find the buoy.

     This assembly is a child of the flood, not of the body, so the buoy stays
     inside the aria-modal dialog and inside its focus trap. index.js pins it to
     the document top by writing --ak-surface, which makes it behave as though it
     were anchored to the page top while its fixed parent stays put. Measuring
     from the flood bottom (always the viewport bottom) rather than its top keeps
     this independent of the 115% rise height. */
  .secret-sky {
    position: absolute;
    left: 0;
    right: 0;
    bottom: var(--ak-surface, 100vh);
    height: 190px;
    z-index: 5;
    pointer-events: auto;
    /* Darker than the water, close to black. */
    background: linear-gradient(180deg, #01050a 0%, #020a11 56%, #04121a 100%);
  }

  /* Stars in two passes: many small, a few larger, both at low opacity so they
     read as a cold sky rather than as decoration. Two layers with different
     durations means the twinkle never pulses in unison. */
  .secret-sky::before,
  .secret-sky::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 22px;
    pointer-events: none;
  }

  .secret-sky::before {
    background-image:
      radial-gradient(1px 1px at 4% 26%, rgba(226,236,255,0.5), transparent 100%),
      radial-gradient(1px 1px at 11% 62%, rgba(226,236,255,0.36), transparent 100%),
      radial-gradient(1px 1px at 18% 14%, rgba(226,236,255,0.46), transparent 100%),
      radial-gradient(1px 1px at 26% 48%, rgba(226,236,255,0.3), transparent 100%),
      radial-gradient(1px 1px at 33% 72%, rgba(226,236,255,0.42), transparent 100%),
      radial-gradient(1px 1px at 41% 20%, rgba(226,236,255,0.34), transparent 100%),
      radial-gradient(1px 1px at 49% 56%, rgba(226,236,255,0.48), transparent 100%),
      radial-gradient(1px 1px at 57% 32%, rgba(226,236,255,0.3), transparent 100%),
      radial-gradient(1px 1px at 64% 68%, rgba(226,236,255,0.4), transparent 100%),
      radial-gradient(1px 1px at 72% 18%, rgba(226,236,255,0.44), transparent 100%),
      radial-gradient(1px 1px at 79% 52%, rgba(226,236,255,0.32), transparent 100%),
      radial-gradient(1px 1px at 86% 30%, rgba(226,236,255,0.46), transparent 100%),
      radial-gradient(1px 1px at 93% 64%, rgba(226,236,255,0.34), transparent 100%),
      radial-gradient(1px 1px at 97% 22%, rgba(226,236,255,0.4), transparent 100%);
    animation: star-twinkle-small 9.4s ease-in-out infinite;
  }

  .secret-sky::after {
    background-image:
      radial-gradient(1.6px 1.6px at 8% 40%, rgba(240,246,255,0.62), transparent 100%),
      radial-gradient(1.6px 1.6px at 23% 28%, rgba(240,246,255,0.5), transparent 100%),
      radial-gradient(1.6px 1.6px at 38% 60%, rgba(240,246,255,0.56), transparent 100%),
      radial-gradient(1.6px 1.6px at 54% 24%, rgba(240,246,255,0.48), transparent 100%),
      radial-gradient(1.6px 1.6px at 69% 46%, rgba(240,246,255,0.58), transparent 100%),
      radial-gradient(1.6px 1.6px at 83% 22%, rgba(240,246,255,0.5), transparent 100%),
      radial-gradient(1.6px 1.6px at 91% 48%, rgba(240,246,255,0.54), transparent 100%);
    animation: star-twinkle-large 13.1s ease-in-out infinite;
  }

  /* The choppy white waterline the buoy rides. Overhangs both edges so the chop
     never reveals a straight end; the flood clips it. */
  .secret-surface-line {
    position: absolute;
    left: -3%;
    right: -3%;
    bottom: -12px;
    height: 46px;
    z-index: 2;
    pointer-events: none;
  }

  .secret-surface-crest,
  .secret-surface-foam {
    position: absolute;
    inset: 0;
  }

  .secret-surface-crest {
    background: linear-gradient(
      180deg,
      rgba(73, 201, 192, 0.9) 0%,
      rgba(30, 122, 128, 0.72) 58%,
      rgba(12, 62, 74, 0.3) 100%
    );
    clip-path: polygon(
      0% 42%, 8% 30%, 16% 44%, 24% 28%, 33% 40%, 42% 26%, 51% 38%,
      60% 25%, 69% 39%, 78% 27%, 87% 41%, 95% 29%, 100% 40%,
      100% 100%, 0% 100%
    );
    animation: surface-chop-crest 12.7s ease-in-out infinite;
  }

  .secret-surface-foam {
    background: linear-gradient(
      180deg,
      rgba(255, 255, 255, 0.92) 0%,
      rgba(226, 246, 244, 0.6) 42%,
      rgba(255, 255, 255, 0) 100%
    );
    clip-path: polygon(
      0% 34%, 7% 22%, 15% 36%, 23% 20%, 32% 33%, 41% 19%, 50% 31%,
      59% 18%, 68% 32%, 77% 20%, 86% 34%, 94% 22%, 100% 33%,
      100% 62%, 0% 58%
    );
    animation: surface-chop-foam 9.1s ease-in-out infinite;
  }

  /* Deliberately mismatched durations and point positions, so the two layers
     never return to the same shape together and the loop is hard to read. */
  @keyframes surface-chop-foam {
    0%, 100% {
      clip-path: polygon(
        0% 34%, 7% 22%, 15% 36%, 23% 20%, 32% 33%, 41% 19%, 50% 31%,
        59% 18%, 68% 32%, 77% 20%, 86% 34%, 94% 22%, 100% 33%,
        100% 62%, 0% 58%
      );
    }
    33% {
      clip-path: polygon(
        0% 24%, 7% 35%, 15% 21%, 23% 34%, 32% 20%, 41% 32%, 50% 19%,
        59% 33%, 68% 21%, 77% 35%, 86% 22%, 94% 34%, 100% 23%,
        100% 60%, 0% 63%
      );
    }
    66% {
      clip-path: polygon(
        0% 31%, 7% 19%, 15% 33%, 23% 24%, 32% 36%, 41% 22%, 50% 34%,
        59% 21%, 68% 35%, 77% 23%, 86% 30%, 94% 19%, 100% 32%,
        100% 64%, 0% 57%
      );
    }
  }

  @keyframes surface-chop-crest {
    0%, 100% {
      clip-path: polygon(
        0% 42%, 8% 30%, 16% 44%, 24% 28%, 33% 40%, 42% 26%, 51% 38%,
        60% 25%, 69% 39%, 78% 27%, 87% 41%, 95% 29%, 100% 40%,
        100% 100%, 0% 100%
      );
    }
    40% {
      clip-path: polygon(
        0% 29%, 8% 43%, 16% 27%, 24% 41%, 33% 26%, 42% 39%, 51% 25%,
        60% 40%, 69% 28%, 78% 42%, 87% 29%, 95% 43%, 100% 30%,
        100% 100%, 0% 100%
      );
    }
    72% {
      clip-path: polygon(
        0% 38%, 8% 26%, 16% 40%, 24% 31%, 33% 44%, 42% 29%, 51% 42%,
        60% 27%, 69% 43%, 78% 30%, 87% 37%, 95% 26%, 100% 39%,
        100% 100%, 0% 100%
      );
    }
  }

  @keyframes star-twinkle-small {
    0%, 100% { opacity: 0.82; }
    50%      { opacity: 1; }
  }

  @keyframes star-twinkle-large {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.76; }
  }

  /* The fish stays in the deep. Put away as the reader nears the surface and
     brought back when they swim down again, so the surface is only ever the way
     out. !important because the skittish, nervous and bolting states carry the
     same specificity and any of them can be active when the reader swims up. */
  .secret-flood.at-surface .secret-fish {
    opacity: 0 !important;
    pointer-events: none !important;
    transition: opacity 0.55s ease !important;
  }

  @media (prefers-reduced-motion: reduce) {
    .secret-sky::before,
    .secret-sky::after,
    .secret-surface-crest,
    .secret-surface-foam {
      animation: none;
    }
  }

  @keyframes buoy-bob {
    0%, 100% { transform: translateY(0) rotate(-3.5deg); }
    50%      { transform: translateY(5px) rotate(3.5deg); }
  }

  /* Fl(2): two quick flashes, then a long dark period. */
  @keyframes buoy-flash {
    0%   { opacity: 1; }
    4%   { opacity: 1; }
    5%   { opacity: 0.1; }
    11%  { opacity: 0.1; }
    12%  { opacity: 1; }
    16%  { opacity: 1; }
    17%  { opacity: 0.1; }
    100% { opacity: 0.1; }
  }

  @media (prefers-reduced-motion: reduce) {
    .secret-flood-close { animation: none; }
    .buoy-light { animation: none; opacity: 1; }
    .buoy-label { opacity: 0.9; transition: none; }
  }

  /* Tail */
  .secret-fish::before {
    content: "";
    position: absolute;
    left: -11px;
    top: 2px;
    width: 0;
    height: 0;
    border-top: 5px solid transparent;
    border-bottom: 5px solid transparent;
    border-right: 13px solid #9eabad;
  }

  /* Eye */
  .secret-fish::after {
    content: "";
    position: absolute;
    right: 6px;
    top: 4px;
    width: 2px;
    height: 2px;
    border-radius: 50%;
    background: #071319;
    box-shadow: 0 0 0 1px rgba(235, 242, 241, 0.5);
  }

  .secret-flood.submerged .secret-fish {
    opacity: 0.88;
    animation: silver-fish-dart 13s linear infinite;
    /* Swimming back down fades the fish in, rather than snapping it on. */
    transition: opacity 0.55s ease;
  }

  @keyframes silver-fish-dart {
    0% {
      left: 8%;
      top: 78%;
      transform: translate(-50%, -50%) scaleX(1) rotate(-5deg);
    }
    7% {
      left: 28%;
      top: 68%;
      transform: translate(-50%, -50%) scaleX(1) rotate(-8deg);
    }
    11% {
      left: 57%;
      top: 61%;
      transform: translate(-50%, -50%) scaleX(1) rotate(-2deg);
    }
    16% {
      left: 72%;
      top: 46%;
      transform: translate(-50%, -50%) scaleX(1) rotate(-14deg);
    }
    20% {
      left: 87%;
      top: 41%;
      transform: translate(-50%, -50%) scaleX(1) rotate(2deg);
    }
    24% {
      left: 86%;
      top: 41%;
      transform: translate(-50%, -50%) scaleX(-1) rotate(-2deg);
    }
    32% {
      left: 54%;
      top: 37%;
      transform: translate(-50%, -50%) scaleX(-1) rotate(8deg);
    }
    37% {
      left: 31%;
      top: 45%;
      transform: translate(-50%, -50%) scaleX(-1) rotate(-10deg);
    }
    42% {
      left: 13%;
      top: 48%;
      transform: translate(-50%, -50%) scaleX(-1) rotate(3deg);
    }
    47% {
      left: 13%;
      top: 48%;
      transform: translate(-50%, -50%) scaleX(1) rotate(-3deg);
    }
    55% {
      left: 42%;
      top: 56%;
      transform: translate(-50%, -50%) scaleX(1) rotate(7deg);
    }
    59% {
      left: 70%;
      top: 72%;
      transform: translate(-50%, -50%) scaleX(1) rotate(11deg);
    }
    65% {
      left: 91%;
      top: 67%;
      transform: translate(-50%, -50%) scaleX(1) rotate(-4deg);
    }
    69% {
      left: 91%;
      top: 67%;
      transform: translate(-50%, -50%) scaleX(-1) rotate(4deg);
    }
    77% {
      left: 63%;
      top: 82%;
      transform: translate(-50%, -50%) scaleX(-1) rotate(-7deg);
    }
    82% {
      left: 36%;
      top: 86%;
      transform: translate(-50%, -50%) scaleX(-1) rotate(1deg);
    }
    88% {
      left: 17%;
      top: 72%;
      transform: translate(-50%, -50%) scaleX(-1) rotate(12deg);
    }
    92% {
      left: 17%;
      top: 72%;
      transform: translate(-50%, -50%) scaleX(1) rotate(-12deg);
    }
    100% {
      left: 8%;
      top: 78%;
      transform: translate(-50%, -50%) scaleX(1) rotate(-5deg);
    }
  }


  /* The flooded screen becomes the interaction surface only once submerged. */
  .secret-flood.submerged {
    pointer-events: auto;
    /* Vertical panning only. The surface is at the top of the DOCUMENT, so the
       reader has to be able to scroll up to reach it: touch-action: none made
       the way out unreachable on a phone while leaving it fine on a desktop,
       where a wheel is not a touch gesture. pan-y still blocks double-tap zoom
       and horizontal drag, and still leaves pointerdown cancellable, so the
       fish stays tappable. */
    touch-action: pan-y;
  }

  .secret-flood.submerged .secret-fish {
    pointer-events: auto;
    cursor: pointer;
    touch-action: none;
  }

  /* After the first touch, JS owns the fish position so it can flee the pointer. */
  .secret-flood.submerged .secret-fish.skittish {
    animation: none !important;
    transition:
      left 330ms cubic-bezier(0.18, 0.75, 0.25, 1),
      top 330ms cubic-bezier(0.18, 0.75, 0.25, 1),
      transform 180ms ease-out,
      filter 180ms ease-out,
      opacity 0.55s ease;
    filter:
      drop-shadow(0 2px 3px rgba(0, 0, 0, 0.35))
      drop-shadow(0 0 5px rgba(226, 246, 244, 0.14));
  }


  .secret-flood.submerged .secret-fish.skittish.first-flee {
    transition:
      left 720ms cubic-bezier(0.08, 0.82, 0.12, 1),
      top 720ms cubic-bezier(0.08, 0.82, 0.12, 1),
      transform 150ms ease-out,
      filter 150ms ease-out,
      opacity 0.55s ease;
  }

  /* After the second touch JS gives it short nervous movements while the shadow passes. */
  .secret-flood.submerged .secret-fish.nervous {
    animation: none !important;
    cursor: default;
    transition:
      left 620ms cubic-bezier(0.22, 0.72, 0.22, 1),
      top 620ms cubic-bezier(0.22, 0.72, 0.22, 1),
      transform 220ms ease-out,
      filter 220ms ease-out,
      opacity 0.55s ease;
    filter:
      drop-shadow(0 2px 3px rgba(0, 0, 0, 0.35))
      drop-shadow(0 0 7px rgba(226, 246, 244, 0.16));
  }

  /* Deliberately too blurred and incomplete to resolve into a specific creature. */
  .secret-leviathan {
    position: absolute;
    z-index: 1;
    left: -112%;
    top: 40%;

    width: min(101vw, 1360px);
    /* Never wider than the screen. The old flat 690px floor made the filtered
       surface about three times the needed area on a 390px phone. */
    min-width: min(690px, 100vw);
    aspect-ratio: 4.05 / 1;

    opacity: 0;
    pointer-events: none;

    /* No clip-path: it was also clipping the tail. Irregular border radius plus
       heavy blur gives a softer body. */
    border-radius: 37% 63% 56% 44% / 45% 39% 61% 55%;

    background:
      radial-gradient(
        ellipse at 72% 44%,
        rgba(0, 3, 8, 0.80) 0%,
        rgba(0, 7, 13, 0.68) 38%,
        rgba(0, 12, 20, 0.42) 61%,
        rgba(1, 19, 28, 0.12) 78%,
        transparent 91%
      ),
      radial-gradient(
        ellipse at 40% 57%,
        rgba(0, 4, 9, 0.58) 0%,
        rgba(0, 10, 16, 0.31) 52%,
        transparent 80%
      );

    /* Strong blur is intentional: seen through deep water, not a cut-out. */
    filter:
      blur(25px)
      drop-shadow(0 0 68px rgba(0, 0, 0, 0.44))
      drop-shadow(0 0 34px rgba(4, 29, 37, 0.22));

    transform: translateY(-50%) rotate(-1deg) scale(1, 0.96);
    transform-origin: 34% 50%;
  }

  /* Soft double-lobed tail, outside the body and unclipped. Two blurred radial
     masses read as a tail without a sharp outline. */
  .secret-leviathan::before {
    content: "";
    position: absolute;

    /* Most of the tail sits outside the body so its translucent shadow does not
       stack over the torso and go unnaturally black. */
    left: -20%;
    top: 10%;
    width: 30%;
    height: 80%;

    background:
      radial-gradient(
        ellipse at 80% 24%,
        rgba(1, 13, 20, 0.48) 0%,
        rgba(1, 17, 24, 0.34) 38%,
        rgba(2, 24, 31, 0.12) 63%,
        transparent 80%
      ),
      radial-gradient(
        ellipse at 80% 76%,
        rgba(1, 13, 20, 0.50) 0%,
        rgba(1, 17, 24, 0.35) 38%,
        rgba(2, 24, 31, 0.12) 63%,
        transparent 80%
      );

    filter:
      blur(22px)
      drop-shadow(0 0 18px rgba(0, 0, 0, 0.16));

    transform-origin: 91% 50%;
    transform: rotate(-5deg) scaleY(0.92) translateY(-1%);
  }

  /* A vague lower sweep. Suggests anatomy without a clean readable fin. */
  .secret-leviathan::after {
    content: "";
    position: absolute;
    left: 42%;
    top: 58%;
    width: 29%;
    height: 42%;

    border-radius: 31% 69% 61% 39% / 48% 36% 64% 52%;

    background:
      radial-gradient(
        ellipse at 33% 22%,
        rgba(0, 5, 10, 0.45) 0%,
        rgba(0, 10, 17, 0.28) 43%,
        rgba(0, 18, 25, 0.08) 66%,
        transparent 82%
      );

    filter: blur(20px);
    transform-origin: 26% 18%;
    transform: rotate(-17deg) scaleY(0.82);
  }

  .secret-flood.monster-awake .secret-leviathan {
    animation: leviathan-pass 17.4s cubic-bezier(0.22, 0.08, 0.28, 0.98) forwards;
  }

  .secret-flood.monster-awake .secret-leviathan::before {
    animation: leviathan-tail-undulate 3.8s ease-in-out infinite;
  }

  .secret-flood.monster-awake .secret-leviathan::after {
    animation: leviathan-fin-undulate 5.8s ease-in-out infinite;
  }

  /* Slow, but the back rises and falls enough to read as swimming. */
  @keyframes leviathan-pass {
    0% {
      left: -112%;
      opacity: 0;
      transform:
        translateY(-47%)
        rotate(-2deg)
        scale(0.96, 0.88)
        skewY(-1.4deg);
    }

    11% {
      opacity: 0.18;
      transform:
        translateY(-58%)
        rotate(1.2deg)
        scale(0.99, 1.08)
        skewY(1.1deg);
    }

    25% {
      opacity: 0.40;
      transform:
        translateY(-44%)
        rotate(2deg)
        scale(1.025, 0.91)
        skewY(-0.9deg);
    }

    40% {
      opacity: 0.55;
      transform:
        translateY(-59%)
        rotate(-1.6deg)
        scale(1.045, 1.09)
        skewY(1.25deg);
    }

    55% {
      opacity: 0.52;
      transform:
        translateY(-45%)
        rotate(1.8deg)
        scale(1.02, 0.90)
        skewY(-1.1deg);
    }

    70% {
      opacity: 0.44;
      transform:
        translateY(-57%)
        rotate(-1.7deg)
        scale(1.005, 1.07)
        skewY(0.95deg);
    }

    85% {
      opacity: 0.23;
      transform:
        translateY(-46%)
        rotate(1deg)
        scale(0.985, 0.92)
        skewY(-0.8deg);
    }

    100% {
      left: 123%;
      opacity: 0;
      transform:
        translateY(-55%)
        rotate(1.8deg)
        scale(0.96, 1.04)
        skewY(0.7deg);
    }
  }

  /* Tail flex is stronger and faster than the body flex. Heavily blurred, so
     even 15 degrees reads as an underwater sweep. */
  @keyframes leviathan-tail-undulate {
    /* Broad slow sweeps rather than rapid flicking. */
    0% {
      transform: rotate(-6deg) scaleY(0.88) translateY(-3%);
    }
    28% {
      transform: rotate(-2deg) scaleY(1.00) translateY(-1%);
    }
    55% {
      transform: rotate(5deg) scaleY(0.91) translateY(4%);
    }
    79% {
      transform: rotate(1deg) scaleY(1.03) translateY(1%);
    }
    100% {
      transform: rotate(-6deg) scaleY(0.88) translateY(-3%);
    }
  }

  @keyframes leviathan-fin-undulate {
    0% {
      transform: rotate(-19deg) scaleY(0.78);
      opacity: 0.33;
    }
    42% {
      transform: rotate(-14deg) scaleY(0.97);
      opacity: 0.42;
    }
    73% {
      transform: rotate(-17deg) scaleY(0.86);
      opacity: 0.37;
    }
    100% {
      transform: rotate(-19deg) scaleY(0.78);
      opacity: 0.33;
    }
  }

  /* PHONES AND TABLETS
     The leviathan is the most expensive thing this page draws. Three chained
     filters (blur plus two drop-shadows) each need a full-size offscreen buffer
     and each expands well past the element box: tens of megabytes per stage at
     phone pixel ratios. The pass also animates left, which is not compositable,
     so every buffer is rebuilt each frame for over seventeen seconds.
     Desktop absorbs it. iOS does not: the web content process hits its memory
     ceiling and the tab is killed ("A problem repeatedly occurred").
     Coarse pointers get one modest blur and travel by transform, so the layer
     is rasterised once and then moved. */
  @media (pointer: coarse), (max-width: 860px) {
    .secret-leviathan {
      filter: blur(18px);
      left: 0;
      transform: translateX(-112vw) translateY(-50%) rotate(-1deg) scale(1, 0.96);
    }

    .secret-leviathan::before { filter: blur(14px); }
    .secret-leviathan::after  { filter: blur(13px); }

    .secret-flood.monster-awake .secret-leviathan {
      animation: leviathan-pass-lite 17.4s linear forwards;
    }

    /* Undulating a blurred pseudo-element invalidates the parent filter buffer
       every frame. Not legible at this size, so tail and fin hold their line. */
    .secret-flood.monster-awake .secret-leviathan::before,
    .secret-flood.monster-awake .secret-leviathan::after {
      animation: none;
    }
  }

  /* These horizontal positions are the original easing curve sampled at each
     keyframe, so the pacing survives the switch to linear timing. */
  @keyframes leviathan-pass-lite {
    0% {
      opacity: 0;
      transform: translateX(-112vw) translateY(-47%) rotate(-2deg) scale(0.96, 0.88);
    }
    11% {
      opacity: 0.18;
      transform: translateX(-84.7vw) translateY(-58%) rotate(1.2deg) scale(0.99, 1.08);
    }
    25% {
      opacity: 0.40;
      transform: translateX(-17.5vw) translateY(-44%) rotate(2deg) scale(1.025, 0.91);
    }
    40% {
      opacity: 0.55;
      transform: translateX(43.6vw) translateY(-59%) rotate(-1.6deg) scale(1.045, 1.09);
    }
    55% {
      opacity: 0.52;
      transform: translateX(82.9vw) translateY(-45%) rotate(1.8deg) scale(1.02, 0.90);
    }
    70% {
      opacity: 0.44;
      transform: translateX(106.3vw) translateY(-57%) rotate(-1.7deg) scale(1.005, 1.07);
    }
    85% {
      opacity: 0.23;
      transform: translateX(118.7vw) translateY(-46%) rotate(1deg) scale(0.985, 0.92);
    }
    100% {
      opacity: 0;
      transform: translateX(123vw) translateY(-55%) rotate(1.8deg) scale(0.96, 1.04);
    }
  }

  /* The final panic: JavaScript supplies the destination off-screen. */
  .secret-flood.submerged .secret-fish.bolting {
    animation: none !important;
    transition:
      left 620ms cubic-bezier(0.12, 0.72, 0.15, 1),
      top 620ms cubic-bezier(0.12, 0.72, 0.15, 1),
      transform 180ms ease-out,
      opacity 180ms ease 500ms !important;
    opacity: 0;
  }


  @media (hover: hover) and (pointer: fine) {
    .secret-flood.submerged .secret-fish.skittish {
      filter:
        drop-shadow(0 2px 3px rgba(0, 0, 0, 0.35))
        drop-shadow(0 0 8px rgba(226, 246, 244, 0.18));
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .secret-flood {
      transition-duration: 1.5s;
      animation: none;
      transition: height 1.5s ease;
      clip-path: polygon(
        0 18px,
        8% 8px,
        16% 23px,
        24% 7px,
        32% 25px,
        40% 10px,
        48% 22px,
        56% 6px,
        64% 26px,
        72% 9px,
        80% 24px,
        88% 7px,
        96% 21px,
        100% 14px,
        100% 100%,
        0 100%
      );
    }

    .secret-flood::before,
    .secret-flood::after,
    .secret-bubble,
    .secret-flood.submerged .secret-fish {
      animation: none;
    }

    .secret-flood.submerged .secret-fish {
      left: 65%;
      top: 58%;
      opacity: 0.88;
    }
    .secret-flood.submerged .secret-fish.skittish,
    .secret-flood.submerged .secret-fish.nervous,
    .secret-flood.submerged .secret-fish.bolting {
      transition: none !important;
    }

    .secret-flood.monster-awake .secret-leviathan {
      animation: none;
      left: 18%;
      opacity: 0.42;
      transform: translateY(-50%);
    }

    .secret-flood.monster-awake .secret-leviathan::before,
    .secret-flood.monster-awake .secret-leviathan::after {
      animation: none;
    }

  }


  /* ============ THE TIDE ============ */
  /* Deepens from the bottom over about seven minutes. One transition, no timers,
     nothing repainted. The ceiling is low on purpose: it should never be legible
     as an effect. */
  .tide {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 4;
    opacity: 0;
    background: linear-gradient(
      to top,
      rgba(2, 20, 31, 0.85) 0%,
      rgba(4, 35, 51, 0.40) 42%,
      transparent 100%
    );
    transition: opacity 420s linear;
  }

  .tide.coming-in { opacity: 0.12; }

  @media (prefers-reduced-motion: reduce) {
    .tide { display: none; }
  }

  /* iOS composites fixed translucent gradients against the visual viewport
     differently, which turns this into an obvious blue sheet. Keep it for
     pointer/desktop, drop the fixed overlay on coarse touch devices. */
  @media (hover: none) and (pointer: coarse) {
    .tide { display: none; }
  }

  /* The tagline settling back to its real wording, slowly enough not to flash. */
  .hero .tagline {
    transition: opacity 700ms ease;
  }
  .hero .tagline.settling { opacity: 0; }


  /* ============ READ AGAIN ============ */
  /* .btn is nowrap by default; the third-stage label is long enough to need two
     lines once the featured story button has drifted. */
  .btn.link-drifted {
    white-space: normal;
    line-height: 1.35;
  }


  /* ============ FOOTER TICKER ============ */
  /* A news alert washed up at the bottom of a fiction site. Deliberately uses
     none of the page typefaces or colours.
     No broadcaster logo or typeface is reproduced. The black bar, red block and
     chevron are the shared grammar of televised news, not one outlet property. */
  .ticker {
    position: fixed;
    left: 0;
    right: 0;
    z-index: 300;

    bottom: 0;

    background: #000000;
    box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.55);

    /* Do not use an off-screen transform as the hidden state. iOS WebKit can paint
       bottom-fixed layers against the wrong viewport while the bottom bar resizes.
       visibility:hidden makes it genuinely unpaintable until JS surfaces it; the
       transform then only handles entrance and exit. */
    visibility: hidden;
    transform: translate3d(0, calc(100% + 40px), 0);
    transition:
      transform 460ms cubic-bezier(0.2, 0.7, 0.2, 1),
      visibility 0s linear 460ms;
    pointer-events: none;
  }

  /* Lifted clear of whatever the browser is overlaying at the bottom. */
  .ticker.surfaced {
    visibility: visible;
    transform: translate3d(0, var(--ticker-lift-y, 0px), 0);
    transition:
      transform 460ms cubic-bezier(0.2, 0.7, 0.2, 1),
      visibility 0s;
    pointer-events: auto;
  }

  .ticker-inner {
    display: flex;
    align-items: stretch;
    height: 48px;
    overflow: hidden;
    text-decoration: none;
  }

  /* The point is cut out of the block rather than added as a separate triangle,
     so the red never separates from its arrow at any width. */
  .ticker-label {
    flex: none;
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    background: #e4003b;
    color: #ffffff;
    padding: 0 2.5rem 0 1.15rem;
    clip-path: polygon(
      0 0,
      calc(100% - 22px) 0,
      100% 50%,
      calc(100% - 22px) 100%,
      0 100%
    );

    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
    font-size: 0.9rem;
    font-weight: 700;
    letter-spacing: 0.005em;
    white-space: nowrap;
    text-decoration: none;
  }

  /* The track needs its own clipping box. With overflow only on .ticker-inner
     the headline scrolls straight over the chevron. */
  .ticker-window {
    flex: 1 1 auto;
    min-width: 0;
    margin-left: 0.9rem;
    overflow: hidden;
    display: flex;
    align-items: center;
  }

  .ticker-track {
    display: flex;
    align-items: center;
    white-space: nowrap;
    /* Shift distance and duration are set by the script after measuring one item.
       Paused off-screen, so nothing runs for a reader who never finds it. */
    animation: ticker-run 15s linear infinite paused;
  }

  .ticker.surfaced .ticker-track {
    animation-play-state: running;
  }

  /* Each item carries its own trailing separator, so both copies are exactly the
     same width and the join reads as ticker rhythm. */
  .ticker-item {
    flex: none;
    display: flex;
    align-items: center;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
    font-size: 0.92rem;
    letter-spacing: 0.045em;
    text-transform: uppercase;
    color: #ffffff;
  }

  .ticker-head { font-weight: 600; }

  .ticker-cta {
    font-weight: 600;
    color: #ffffff;
    text-decoration: underline;
    text-decoration-color: rgba(255, 255, 255, 0.55);
    text-underline-offset: 4px;
  }

  .ticker-inner:hover .ticker-cta {
    text-decoration-color: #ffffff;
  }

  .ticker-sep {
    padding: 0 1.15rem;
    color: #e4003b;
    font-weight: 700;
  }

  /* Shift by exactly one item width, not a percentage of the strip, so the loop
     stays seamless however many copies are in it. */
  @keyframes ticker-run {
    from { transform: translateX(0); }
    to   { transform: translateX(calc(-1 * var(--ticker-shift, 100%))); }
  }

  @media (max-width: 560px) {
    .ticker-inner { height: 42px; }
    .ticker-label {
      font-size: 0.76rem;
      padding: 0 1.9rem 0 0.8rem;
      clip-path: polygon(
        0 0,
        calc(100% - 16px) 0,
        100% 50%,
        calc(100% - 16px) 100%,
        0 100%
      );
    }
    .ticker-window { margin-left: 0.65rem; }
    .ticker-item { font-size: 0.8rem; letter-spacing: 0.035em; }
    .ticker-sep { padding: 0 0.8rem; }
  }

  @media (prefers-reduced-motion: reduce) {
    .ticker { transition: none; }
    .ticker-track,
    .ticker.surfaced .ticker-track { animation: none; }
  }


  /* ============ REDUCED MOTION: THE FLOOD ============
     The main reduce-motion rule quiets the flood, but its crests, bubbles, fish
     and leviathan each carry their own infinite animation and kept running.
     Scoped to the flood. !important only to outrank the more specific rules above. */
  @media (prefers-reduced-motion: reduce) {
    .secret-flood,
    .secret-flood::before,
    .secret-flood::after,
    .secret-flood *,
    .secret-flood *::before,
    .secret-flood *::after {
      animation: none !important;
    }
  }


  /* ============ THE FORGET BUTTON ============
     Used under the coins on Current Work and on the privacy note. Quiet by
     design: findable by anyone looking for it. */
  .forget-line { margin: 1.5rem 0 0; }

  .forget-btn {
    padding: 0;
    border: 0;
    background: transparent;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ash);
    text-decoration: underline;
    text-underline-offset: 4px;
    cursor: pointer;
    -webkit-appearance: none;
  }

  .forget-btn:hover,
  .forget-btn:focus-visible { color: var(--parchment); }

  .forget-btn.is-confirming { color: var(--ember-bright); }


  /* ============ BLOG POST BODIES ============
     Shared by every file in /blog/, so a new post is markup and nothing else. */
  .post-body p { color: var(--parchment-dim); margin: 0 0 1.35rem; }
  .post-body p:last-child { margin-bottom: 0; }

  .post-body h3 {
    margin: 2.75rem 0 1.1rem;
    font-size: clamp(1.15rem, 2.4vw, 1.5rem);
    text-transform: none;
    letter-spacing: normal;
    color: var(--parchment);
  }

  .post-body strong { color: var(--parchment); font-weight: 500; }

  .post-back { margin-top: 3.5rem; }


  /* ============ THE CAULDRON ============ */

  .cauldron-trigger {
    display: inline;
    margin: 0;
    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    font-style: inherit;
    line-height: inherit;
    /* No affordance of any kind. The phrase is a clue and should read as ordinary
       running text. It stays a real button so it is still reachable by keyboard
       and assistive technology; the focus ring below is the only time it shows. */
    text-align: inherit;
    text-decoration: inherit;
    /* Both are tells: a button gets an arrow cursor and refuses to be selected,
       while the prose either side of it does neither. */
    cursor: text;
    -webkit-user-select: text;
    user-select: text;
    -webkit-appearance: none;
    appearance: none;
  }

  .cauldron-trigger:focus-visible {
    outline: 2px solid var(--ember);
    outline-offset: 3px;
  }

  .cauldron-overlay {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: rgba(0, 0, 0, 0.96);
  }

  .cauldron-dialog {
    position: relative;
    width: min(94vw, 840px);
    padding: 3.75rem 1.25rem 1.25rem;
    border: 1px solid var(--phosphor-dim, #3d968b);
    background: #000;
    box-shadow: 0 0 48px rgba(73, 201, 192, 0.22);
  }

  .cauldron-close {
    position: absolute;
    z-index: 3;
    top: 0.75rem;
    right: 0.75rem;
    min-width: 44px;
    min-height: 44px;
    padding: 0.55rem 0.8rem;
    border: 2px solid var(--parchment);
    background: #000;
    color: var(--parchment);
    font-family: var(--font-mono);
    font-size: 0.8rem;
    cursor: pointer;
  }

  .cauldron-player {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    cursor: default;
    overflow: hidden;
    background: #000;
    /* No margin, padding, or border that could create a grey band. */
  }

  /* The iframe fills the player with no gap. */
  .cauldron-iframe {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    border: 0;
  }

  /* UNUSED. index.js no longer builds a static overlay for the cauldron video.
     Delete these rules, or restore the overlay, but do not leave both. */
  .cauldron-static-video {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    z-index: 1;
    opacity: 1;
    transition: opacity 2.5s ease-in;
    image-rendering: pixelated;
  }

  .cauldron-static-video.tuning-in {
    opacity: 0;
    pointer-events: none;
  }

  /* When dismissing, a brief flash of static-like noise covers the exit. */
  .cauldron-static-out {
    position: absolute;
    inset: 0;
    z-index: 2;
    background: #111;
    background-image:
      repeating-linear-gradient(
        0deg,
        rgba(255,255,255,0.06) 0px,
        rgba(255,255,255,0.06) 1px,
        transparent 1px,
        transparent 3px
      );
    animation: cauldron-out 0.6s ease-out forwards;
  }

  @keyframes cauldron-out {
    0%   { opacity: 0; }
    20%  { opacity: 1; }
    100% { opacity: 1; }
  }

  @media (prefers-reduced-motion: reduce) {
    .cauldron-static-video { transition: none; display: none; }
    .cauldron-static-out { animation: none; }
  }
