/* ─────────────────────────────────────────────────────────────
   Elsewhere — photography & writing.
   Three switchable layouts share the hero, lightbox and panel.
   Loaded after styles.css so it can lean on the same tokens.
   ───────────────────────────────────────────────────────────── */

@layer elsewhere {
  .els-page {
    --film: #0f0d0b;
    --sprocket: #221d18;
    --paper: #e8e2d4;
    --ink-warm: #1a1613;
    background: var(--bg);
    overflow-x: hidden;
  }

  /* styles.css hides every h1/h2 until it gains .visible (the home
     page's scroll system). This page drives its own reveals. */
  .els-page :is(h1, h2) {
    opacity: 1;
    translate: none;
  }

  /* ── Hero ────────────────────────────────────────────────── */

  /* Work's hero is a bottom-aligned wall of display type. This one is
     deliberately the opposite: a horizontal strip of empty frames with
     the title set small and lowercase beneath it, like an index card
     clipped to a contact sheet. */

  .els-hero {
    position: relative;
    min-height: 92svh;
    display: grid;
    grid-template-rows: auto 1fr;
    gap: clamp(32px, 6vh, 72px);
    padding: 104px clamp(24px, 6vw, 96px) clamp(40px, 6vh, 72px);
  }

  .els-hero-rail {
    display: flex;
    gap: 10px;
    align-items: stretch;
    height: clamp(120px, 22vh, 220px);
  }

  /* Real frames from the collection, wiping in on load and then
     cross-fading to new photographs on a stagger. */
  .els-hero-frame {
    flex: 1 1 0;
    position: relative;
    overflow: hidden;
    background: #000;
    clip-path: inset(0 100% 0 0);
    transition: clip-path 1s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .els-hero-frame img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    filter: saturate(0.8) contrast(1.05);
    transition: opacity 1.1s ease;
  }

  .els-hero-frame img.is-on { opacity: 1; }

  /* Sprocket rails, drawn over the photo so the strip still reads as film. */
  .els-hero-frame::before,
  .els-hero-frame::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    height: 9px;
    z-index: 1;
    background-image: radial-gradient(
      ellipse 3px 2.5px at 50% 50%,
      rgba(0, 0, 0, 0.85) 0 99%,
      transparent 100%
    );
    background-size: 13px 9px;
  }

  .els-hero-frame::before { top: 0; }
  .els-hero-frame::after { bottom: 0; }

  .els-hero.in .els-hero-frame { clip-path: inset(0 0 0 0); }

  .els-hero-frame:nth-child(1) { transition-delay: 0.05s; }
  .els-hero-frame:nth-child(2) { transition-delay: 0.15s; }
  .els-hero-frame:nth-child(3) { transition-delay: 0.25s; }
  .els-hero-frame:nth-child(4) { transition-delay: 0.35s; }
  .els-hero-frame:nth-child(5) { transition-delay: 0.45s; }

  .els-hero-index {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
    grid-template-areas:
      "tag   tag"
      "title lede"
      "meta  lede";
    grid-template-rows: auto auto auto;
    align-content: start;
    align-items: start;
    gap: 18px clamp(32px, 6vw, 88px);
    padding-block-start: 12px;
    border-top: var(--hairline) solid color-mix(in srgb, var(--fg) 18%, transparent);
  }

  .els-hero-tag {
    grid-area: tag;
    display: flex;
    align-items: baseline;
    gap: 14px;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: var(--muted);
    opacity: 0;
    transition: opacity 0.6s ease 0.5s;
  }

  .els-hero-tag span { color: var(--accent); }
  .els-hero.in .els-hero-tag { opacity: 1; }

  /* Work stacks one enormous word. This stacks two, the second indented
     and outlined, so the pair reads as an index entry rather than a
     billboard. Bebas Neue has no lowercase, so the contrast is carried
     by weight and indent instead of case. */
  .els-hero-title {
    grid-area: title;
    align-self: start;
    font-family: var(--font-display);
    font-weight: 400;
    font-size: clamp(46px, 9.5vw, 132px);
    line-height: 0.84;
    letter-spacing: 0.02em;
    color: var(--fg) !important;
    margin: 0;
  }

  /* font-size:0 collapses the wrapper's own line box; without it the
     element is twice as tall as the word, since it stacks its empty
     line on top of the pseudo-element's. */
  .els-word {
    display: block;
    position: relative;
    overflow: hidden;
    font-size: 0;
  }

  /* Each word wipes up from behind its own edge. */
  .els-word::before {
    content: attr(data-word);
    display: block;
    font-size: clamp(46px, 9.5vw, 132px);
    text-transform: uppercase;
    translate: 0 105%;
    transition: translate 1s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .els-word:first-child::before { color: var(--fg); }

  .els-word:last-child {
    margin-inline-start: 0.42em;
  }

  .els-word:last-child::before {
    color: transparent;
    -webkit-text-stroke: 1.5px var(--accent);
  }

  .els-hero.in .els-word::before { translate: 0 0; }
  .els-hero.in .els-word:last-child::before { transition-delay: 0.12s; }

  .els-hero-lede {
    grid-area: lede;
    font-family: var(--font-mono);
    font-size: 13px;
    line-height: 2;
    max-width: 44ch;
    color: color-mix(in srgb, var(--fg) 62%, transparent);
    opacity: 0;
    transition: opacity 0.6s ease 0.6s;
  }

  .els-hero.in .els-hero-lede { opacity: 1; }

  .els-hero-meta {
    grid-area: meta;
    display: flex;
    gap: clamp(24px, 4vw, 48px);
    flex-wrap: wrap;
    margin: 0;
    padding-block-start: 8px;
    opacity: 0;
    transition: opacity 0.6s ease 0.75s;
  }

  .els-hero.in .els-hero-meta { opacity: 1; }

  .els-hero-meta dt {
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 0.26em;
    text-transform: uppercase;
    color: var(--muted);
    margin-block-end: 6px;
  }

  .els-hero-meta dd {
    margin: 0;
    font-family: var(--font-display);
    font-size: 30px;
    line-height: 1;
    letter-spacing: 0.03em;
    color: var(--accent);
  }

  .els-hero-scroll {
    position: absolute;
    right: clamp(24px, 6vw, 96px);
    bottom: clamp(40px, 6vh, 72px);
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: var(--muted);
    writing-mode: vertical-rl;
  }

  .els-hero-scroll::after {
    content: "";
    display: block;
    width: var(--hairline);
    height: 48px;
    margin: 12px auto 0;
    background: linear-gradient(var(--accent), transparent);
  }

  @media (width <= 900px) {
    .els-hero-index {
      grid-template-columns: 1fr;
      grid-template-areas:
        "tag"
        "title"
        "lede"
        "meta";
      grid-template-rows: auto auto auto auto;
      gap: 20px;
    }

    .els-hero-lede { max-width: none; }

    .els-hero-rail { height: clamp(90px, 16vh, 150px); }
    .els-hero-rail .els-hero-frame:nth-child(n + 4) { display: none; }
  }

  /* ══════════════════════════════════════════════════════════
     Concept D — Spiral
     ══════════════════════════════════════════════════════════ */

  /* Full takeover: the spiral becomes the page. The document stops
     scrolling and the hero/footer stand down entirely. */
  :root[data-immersive] body { overflow: hidden; }
  :root[data-immersive] .els-hero,
  :root[data-immersive] .els-foot { display: none; }

  :root[data-immersive] .els-stage {
    position: fixed;
    inset: 0;
    z-index: 0;
  }

  .els-spiral {
    position: relative;
    height: 100svh;
    background: #000;
    overflow: hidden;
    touch-action: none;
    border-block: var(--hairline) solid color-mix(in srgb, var(--fg) 12%, transparent);
  }

  :root[data-immersive] .els-spiral {
    height: 100%;
    border: none;
  }

  /* ── Overlay chrome ────────────────────────────────────── */

  /* Cleared past the fixed menu trigger in the top-left corner. */
  .els-spiral-chrome {
    position: absolute;
    top: clamp(78px, 12vh, 116px);
    left: clamp(20px, 4vw, 52px);
    z-index: 2;
    max-width: min(38vw, 420px);
    pointer-events: none;
  }

  .els-spiral-tag {
    display: flex;
    align-items: baseline;
    gap: 12px;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.5);
    margin-block-end: 10px;
  }

  .els-spiral-tag span { color: var(--accent-dark); }

  .els-spiral-title {
    font-family: var(--font-display);
    font-weight: 400;
    font-size: clamp(38px, 6.5vw, 92px);
    line-height: 0.84;
    letter-spacing: 0.02em;
    color: #fff !important;
    margin: 0 0 14px;
  }

  .els-spiral-title .els-word:first-child::before { color: #fff; }

  .els-spiral-title .els-word:last-child {
    margin-inline-start: 0.42em;
  }

  .els-spiral-title .els-word:last-child::before {
    color: transparent;
    -webkit-text-stroke: 1.5px var(--accent-dark);
  }

  /* The chrome is injected after load, so it animates on its own. */
  .els-spiral-title .els-word::before {
    translate: 0 105%;
    animation: verse-rise 1s cubic-bezier(0.16, 1, 0.3, 1) forwards;
  }

  .els-spiral-title .els-word:last-child::before { animation-delay: 0.12s; }

  @keyframes verse-rise {
    to { translate: 0 0; }
  }

  .els-spiral-lede {
    font-family: var(--font-mono);
    font-size: 12px;
    line-height: 1.95;
    color: rgba(255, 255, 255, 0.55);
    max-width: 38ch;
  }

  /* ── Poems, in the margin beside the spiral ────────────── */

  .els-spiral-verse {
    position: absolute;
    top: 50%;
    right: clamp(20px, 4vw, 52px);
    translate: 0 -50%;
    z-index: 2;
    width: min(32vw, 340px);
    pointer-events: none;
  }

  .els-verse {
    position: absolute;
    inset-inline: 0;
    top: 50%;
    translate: 0 -50%;
    text-align: right;
    opacity: 0;
    transition: opacity 0.9s ease, translate 0.9s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .els-verse.is-on { opacity: 1; }

  .els-verse-title {
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: var(--accent-dark);
    margin-block-end: 14px;
  }

  .els-verse-line {
    font-family: var(--font-display);
    font-size: clamp(17px, 1.7vw, 25px);
    line-height: 1.5;
    letter-spacing: 0.03em;
    color: rgba(255, 255, 255, 0.9);
  }

  /* ── Footer strip ──────────────────────────────────────── */

  /* Left inset clears the fixed theme toggle in the bottom-left. */
  .els-spiral-foot {
    position: absolute;
    left: clamp(64px, 8vw, 96px);
    right: clamp(20px, 4vw, 52px);
    bottom: clamp(18px, 3vh, 32px);
    z-index: 2;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 20px;
    pointer-events: none;
  }

  .els-spiral-count {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.24em;
    color: rgba(255, 255, 255, 0.4);
  }

  .els-spiral-count b {
    font-weight: 400;
    color: var(--accent-dark);
  }

  .els-spiral:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

  .els-spiral canvas {
    display: block;
    width: 100%;
    height: 100%;
    outline: none;
  }

  .els-spiral-hint {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.45);
  }

  /* The long hint wraps to two lines on a phone, which is what pushes the
     footer up into the poem. Swap in a shorter one that fits on one line
     (and drop "scroll", which isn't the gesture on touch anyway). */
  .els-spiral-hint-short { display: none; }

  @media (width <= 700px) {
    .els-spiral-hint-full { display: none; }
    .els-spiral-hint-short { display: inline; }
  }

  .els-spiral-loading {
    position: absolute;
    left: 50%;
    top: 50%;
    z-index: 3;
    translate: -50% -50%;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.75);
    pointer-events: none;
  }

  @media (width <= 900px) {
    .els-spiral { height: 80svh; }
    :root[data-immersive] .els-spiral { height: 100%; }

    .els-spiral-chrome {
      max-width: none;
      right: clamp(20px, 4vw, 52px);
    }

    /* No room for a true margin — the poem sits along the bottom, stacked
       clear of the footer strip rather than overlapping it. --els-foot-h is
       measured from the real footer at runtime (see elsewhere.js) because it
       reflows: one or two lines depending on width and hint length. */
    .els-spiral-verse {
      top: auto;
      bottom: calc(var(--els-foot-h, 34px) + clamp(18px, 3vh, 32px) + 18px);
      right: clamp(20px, 4vw, 52px);
      left: clamp(20px, 4vw, 52px);
      width: auto;
      translate: none;
      /* Long poems must not creep back up over the spiral's focal point. */
      max-height: 34svh;
      overflow: hidden;
    }

    .els-verse {
      position: relative;
      top: auto;
      translate: none;
      display: none;
    }

    .els-verse.is-on { display: block; }
    .els-verse-line { font-size: 16px; line-height: 1.45; }

    .els-spiral-foot { flex-direction: column; gap: 6px; align-items: flex-start; }
  }

  @media (width <= 600px) {
    .els-spiral-lede { display: none; }
    .els-verse-line { font-size: 15px; }
  }

  /* ── Shared poem type ────────────────────────────────────── */

  .els-poem-title {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    color: var(--accent);
    margin-block-end: 16px;
  }

  .els-poem-line {
    font-family: var(--font-display);
    font-size: 22px;
    line-height: 1.45;
    letter-spacing: 0.03em;
    color: color-mix(in srgb, var(--fg) 88%, transparent);
  }

  /* Margin mode: a poem set sideways in the gutter of a photo. */
  .els-margin {
    position: absolute;
    top: 0;
    left: 100%;
    margin-inline-start: 14px;
    writing-mode: vertical-rl;
    max-height: 100%;
    font-family: var(--font-mono);
    font-size: 10px;
    line-height: 2;
    letter-spacing: 0.08em;
    color: color-mix(in srgb, var(--fg) 45%, transparent);
    pointer-events: none;
    white-space: nowrap;
  }

  .els-margin-title {
    color: var(--accent);
    letter-spacing: 0.24em;
    text-transform: uppercase;
  }

  /* ══════════════════════════════════════════════════════════
     Concept A — Contact Sheet
     ══════════════════════════════════════════════════════════ */

  .els-sheet {
    padding: clamp(32px, 8vh, 80px) clamp(24px, 6vw, 96px) 96px;
  }

  .els-sheet-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding-block-end: 20px;
    margin-block-end: 48px;
    border-bottom: var(--hairline) solid color-mix(in srgb, var(--fg) 14%, transparent);
  }

  .els-sheet-label {
    font-family: var(--font-display);
    font-size: 34px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--fg);
  }

  .els-sheet-sub,
  .els-strip-hint,
  .els-drift-hint {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    color: var(--muted);
  }

  .els-sheet-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: clamp(28px, 4vw, 56px);
    align-items: start;
  }

  .els-cell {
    position: relative;
    opacity: 0;
    translate: 0 28px;
    transition:
      opacity 0.7s ease,
      translate 0.8s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .els-cell.in { opacity: 1; translate: 0 0; }

  /* Negative: a film cell with sprocket rails top and bottom. */
  .els-neg {
    display: block;
    width: 100%;
    padding: 0;
    background: var(--film);
    border: none;
    cursor: pointer;
    rotate: var(--tilt, 0deg);
    translate: 0 var(--lift, 0px);
    box-shadow: 0 18px 40px -22px rgba(0, 0, 0, 0.9);
    transition: rotate 0.5s cubic-bezier(0.16, 1, 0.3, 1),
      translate 0.5s cubic-bezier(0.16, 1, 0.3, 1),
      box-shadow 0.4s ease;
  }

  .els-neg:hover,
  .els-neg:focus-visible {
    rotate: 0deg;
    translate: 0 calc(var(--lift, 0px) - 8px);
    box-shadow: 0 26px 60px -22px rgba(0, 0, 0, 1);
  }

  .els-neg-holes {
    display: block;
    height: 13px;
    background-image: radial-gradient(
      ellipse 4px 3.5px at 50% 50%,
      var(--sprocket) 0 99%,
      transparent 100%
    );
    background-size: 17px 13px;
  }

  .els-neg-img {
    display: block;
    position: relative;
    overflow: hidden;
    aspect-ratio: 3 / 2;
    background: #000;
  }

  .is-portrait .els-neg-img { aspect-ratio: 2 / 3; }

  /* <picture> is inline by default, which would break the height:100%
     chain between the aspect-ratio box and the image inside it. */
  .els-neg-img picture,
  .els-frame-shot picture {
    display: block;
    width: 100%;
    height: 100%;
  }

  .els-drift-frame picture { display: block; }

  .els-neg-img img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: saturate(0.82) contrast(1.05);
    transition: filter 0.5s ease, scale 0.7s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .els-neg:hover img,
  .els-neg:focus-visible img {
    filter: saturate(1) contrast(1);
    scale: 1.03;
  }

  .els-neg-strip {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 9px 12px 11px;
    font-family: var(--font-mono);
    text-align: left;
  }

  .els-neg-num {
    font-size: 10px;
    letter-spacing: 0.2em;
    color: var(--accent);
  }

  .els-neg-name {
    font-size: 10px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--paper) 55%, transparent);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Poem as a paper slip lying on the light table. */
  .els-cell-poem .els-slip {
    position: relative;
    padding: 34px 28px 38px;
    background: var(--paper);
    color: var(--ink-warm);
    rotate: var(--tilt, 0deg);
    translate: 0 var(--lift, 0px);
    box-shadow: 0 18px 40px -22px rgba(0, 0, 0, 0.9);
    transition: rotate 0.5s cubic-bezier(0.16, 1, 0.3, 1),
      translate 0.5s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .els-cell-poem .els-slip:hover { rotate: 0deg; }

  .els-slip-mark {
    position: absolute;
    top: 14px;
    right: 16px;
    font-size: 13px;
    color: color-mix(in srgb, var(--ink-warm) 35%, transparent);
  }

  .els-cell-poem .els-poem-title { color: color-mix(in srgb, var(--ink-warm) 60%, transparent); }
  .els-cell-poem .els-poem-line { color: var(--ink-warm); font-size: 20px; }

  /* ══════════════════════════════════════════════════════════
     Concept B — Drift
     ══════════════════════════════════════════════════════════ */

  .els-drift {
    position: relative;
    height: 88svh;
    overflow: hidden;
    cursor: grab;
    touch-action: none;
    background:
      radial-gradient(120% 90% at 50% 0%, color-mix(in srgb, var(--accent) 5%, transparent), transparent 70%),
      var(--bg);
    border-block: var(--hairline) solid color-mix(in srgb, var(--fg) 12%, transparent);
  }

  .els-drift.is-dragging { cursor: grabbing; }
  .els-drift:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

  .els-drift-canvas {
    position: relative;
    width: var(--fw);
    height: var(--fh);
    will-change: transform;
  }

  .els-drift-node {
    position: absolute;
    left: var(--x);
    top: var(--y);
    translate: var(--px, 0) var(--py, 0);
    rotate: var(--tilt, 0deg);
    opacity: 0;
    transition: opacity 0.8s ease;
  }

  .els-drift-node.in { opacity: 1; }

  .els-drift-photo { width: var(--w); }

  .els-drift-frame {
    display: block;
    width: 100%;
    padding: 10px 10px 0;
    background: var(--film);
    border: none;
    cursor: pointer;
    box-shadow: 0 24px 50px -26px rgba(0, 0, 0, 1);
    transition: scale 0.5s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .els-drift-frame:hover,
  .els-drift-frame:focus-visible { scale: 1.04; }

  .els-drift-frame img {
    display: block;
    width: 100%;
    height: auto;
    filter: saturate(0.85) contrast(1.04);
    transition: filter 0.5s ease;
  }

  .els-drift-frame:hover img { filter: saturate(1) contrast(1); }

  .els-drift-cap {
    display: block;
    padding: 9px 2px 11px;
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    text-align: left;
    color: color-mix(in srgb, var(--paper) 50%, transparent);
  }

  .els-drift-poem {
    width: 340px;
    padding: 30px 26px;
    background: color-mix(in srgb, var(--bg) 82%, transparent);
    border: var(--hairline) solid color-mix(in srgb, var(--accent) 30%, transparent);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
  }

  .els-drift-hint {
    position: absolute;
    left: 24px;
    bottom: 20px;
    pointer-events: none;
  }

  .els-minimap {
    position: absolute;
    right: 20px;
    bottom: 20px;
    width: 108px;
    aspect-ratio: 3600 / 2600;
    border: var(--hairline) solid color-mix(in srgb, var(--fg) 25%, transparent);
    background: color-mix(in srgb, var(--bg) 60%, transparent);
    pointer-events: none;
  }

  .els-minimap-view {
    position: absolute;
    background: color-mix(in srgb, var(--accent) 30%, transparent);
    border: var(--hairline) solid var(--accent);
  }

  /* ══════════════════════════════════════════════════════════
     Concept C — Film Strip
     ══════════════════════════════════════════════════════════ */

  .els-strip {
    position: relative;
    background: var(--film);
    padding-block: 22px;
    border-block: var(--hairline) solid color-mix(in srgb, var(--fg) 12%, transparent);
  }

  .els-perf {
    height: 20px;
    background-image: radial-gradient(
      ellipse 6px 5px at 50% 50%,
      var(--sprocket) 0 99%,
      transparent 100%
    );
    background-size: 26px 20px;
  }

  .els-strip-track {
    display: flex;
    align-items: center;
    gap: clamp(24px, 3vw, 52px);
    padding: 30px clamp(24px, 6vw, 96px);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
  }

  .els-strip-track::-webkit-scrollbar { display: none; }

  .els-frame {
    position: relative;
    flex: 0 0 auto;
    scroll-snap-align: center;
    opacity: 0;
    translate: 0 24px;
    transition:
      opacity 0.7s ease,
      translate 0.8s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .els-frame.in { opacity: 1; translate: 0 0; }

  .els-frame-num {
    position: absolute;
    top: -18px;
    left: 0;
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 0.24em;
    color: color-mix(in srgb, var(--paper) 34%, transparent);
  }

  .els-frame-shot {
    display: block;
    padding: 0;
    border: none;
    background: #000;
    cursor: pointer;
    overflow: hidden;
    height: min(56svh, 460px);
    aspect-ratio: 3 / 2;
  }

  .els-frame-photo.is-portrait .els-frame-shot { aspect-ratio: 2 / 3; }

  .els-frame-shot img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: saturate(0.85) contrast(1.05);
    transition: filter 0.5s ease, scale 0.7s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .els-frame-shot:hover img,
  .els-frame-shot:focus-visible img {
    filter: saturate(1) contrast(1);
    scale: 1.04;
  }

  .els-frame-cap {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    padding-block-start: 12px;
    font-family: var(--font-mono);
  }

  .els-frame-title {
    font-size: 11px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--paper) 75%, transparent);
  }

  .els-frame-meta {
    font-size: 9px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--paper) 40%, transparent);
  }

  /* Poem as a full frame in the reel, printed on the film itself. */
  .els-frame-poem {
    width: min(78vw, 400px);
    height: min(56svh, 460px);
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 34px 30px;
    border: var(--hairline) dashed color-mix(in srgb, var(--paper) 26%, transparent);
  }

  .els-frame-poem .els-poem-line { color: color-mix(in srgb, var(--paper) 90%, transparent); }

  .els-strip-hint {
    position: absolute;
    right: clamp(24px, 6vw, 96px);
    top: 30px;
  }

  .els-strip-progress {
    position: absolute;
    left: clamp(24px, 6vw, 96px);
    right: clamp(24px, 6vw, 96px);
    bottom: 34px;
    height: var(--hairline);
    background: color-mix(in srgb, var(--paper) 18%, transparent);
  }

  .els-strip-progress span {
    display: block;
    height: 100%;
    width: 0%;
    background: var(--accent);
    transition: width 0.1s linear;
  }

  /* Margin poems need room the strip/drift don't have to spare. */
  .els-frame .els-margin,
  .els-drift-node .els-margin {
    display: none;
  }

  /* ── Page navigation ─────────────────────────────────────── */

  /* Withheld on a first visit until the page has been explored — see
     the reveal logic in elsewhere.js. Returning visitors get it at once. */

  /* A centred pair of ringed arrows with the page name between them.
     No backing plate — the rings are a translucent stroke, so the group
     sits at the same weight as the rest of the page's chrome. */
  .els-pagenav {
    position: fixed;
    left: 50%;
    bottom: clamp(18px, 3vh, 32px);
    translate: -50% 0;
    z-index: 45;
    display: flex;
    align-items: center;
    gap: clamp(14px, 2vw, 22px);
    pointer-events: none;
    transition: opacity 0.8s ease, translate 0.8s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .els-pagenav[data-hidden] {
    opacity: 0;
    translate: -50% 12px;
  }

  .els-pagenav-link {
    pointer-events: auto;
    display: inline-flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
    color: rgba(255, 255, 255, 0.92);
    transition: color 0.3s ease;
  }

  .els-pagenav[data-hidden] .els-pagenav-link { pointer-events: none; }

  .els-pagenav-arrow {
    display: grid;
    place-items: center;
    flex: none;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.14);
    background: rgba(190, 195, 200, 0.16);
    backdrop-filter: blur(6px);
    transition: background 0.3s ease, border-color 0.3s ease,
      translate 0.4s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .els-pagenav-arrow svg { width: 18px; height: 18px; }

  .els-pagenav-text {
    display: inline-flex;
    align-items: baseline;
    gap: 8px;
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    white-space: nowrap;
  }

  .els-pagenav-kicker { opacity: 0.7; }

  .els-pagenav-link:hover,
  .els-pagenav-link:focus-visible { color: #fff; }

  .els-pagenav-link:hover .els-pagenav-arrow,
  .els-pagenav-link:focus-visible .els-pagenav-arrow {
    border-color: rgba(255, 255, 255, 0.3);
    background: rgba(210, 215, 220, 0.26);
  }

  .els-pagenav-link:hover .els-pagenav-arrow { translate: -3px 0; }
  .els-pagenav-link.is-next:hover .els-pagenav-arrow { translate: 3px 0; }

  /* The lightbox owns the screen while it is open. */
  [data-lightbox-open] .els-pagenav,
  [data-menu-open] .els-pagenav {
    opacity: 0;
    pointer-events: none;
  }

  /* The spiral's hint and counter run along this same bottom edge; the
     nav takes the middle, so they step up out of its way. */
  .els-spiral-foot {
    transition: bottom 0.6s cubic-bezier(0.16, 1, 0.3, 1);
  }

  body:has(.els-pagenav:not([data-hidden])) .els-spiral-foot {
    bottom: calc(clamp(18px, 3vh, 32px) + 62px);
  }

  /* The poem rides above the footer, so it has to step up by the same 62px
     when the nav appears — otherwise the footer slides underneath it. */
  @media (width <= 900px) {
    .els-spiral-verse {
      transition: bottom 0.6s cubic-bezier(0.16, 1, 0.3, 1);
    }

    body:has(.els-pagenav:not([data-hidden])) .els-spiral-verse {
      bottom: calc(var(--els-foot-h, 34px) + clamp(18px, 3vh, 32px) + 18px + 62px);
    }
  }

  @media (max-width: 560px) {
    .els-pagenav { gap: 10px; }
    .els-pagenav-link { gap: 8px; }
    .els-pagenav-arrow { width: 40px; height: 40px; }
    .els-pagenav-arrow svg { width: 16px; height: 16px; }
    .els-pagenav-text { font-size: 10px; letter-spacing: 0.14em; }
    .els-pagenav-kicker { display: none; }
  }

  /* ── Lightbox ────────────────────────────────────────────── */

  /* The scrim fades; the figure scales up subtly with it. Driven by
     .is-open rather than [hidden], since display:none can't transition. */
  .els-lightbox {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: clamp(24px, 6vw, 80px);
    background: rgba(6, 5, 4, 0.94);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    opacity: 0;
    transition: opacity 0.2s ease;
    will-change: opacity;
  }

  .els-lightbox[hidden] { display: none; }
  .els-lightbox.is-open { opacity: 1; }

  .els-lb-figure {
    display: flex;
    flex-direction: column;
    gap: 16px;
    max-width: 100%;
    max-height: 100%;
    opacity: 0;
    scale: 0.98;
    transition:
      opacity 0.2s ease,
      scale 0.28s cubic-bezier(0.22, 1, 0.36, 1);
    will-change: opacity, scale;
  }

  .els-lightbox.is-open .els-lb-figure {
    opacity: 1;
    scale: 1;
  }

  .els-lb-imgwrap {
    min-height: 0;
    min-width: 0;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  /* width:auto would cap each photo at its own intrinsic size, so the few
     frames that only exist at 1024px would sit visibly smaller than the
     rest. Filling the box and letting object-fit letterbox keeps every
     photograph the same presented size. */
  .els-lb-img {
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 76svh;
    object-fit: contain;
    box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 1);
    transition: opacity 0.15s ease;
  }

  /* Stepping between photos: dip the frame and caption, not the scrim. */
  .els-lightbox.is-swapping .els-lb-img,
  .els-lightbox.is-swapping .els-lb-cap {
    opacity: 0;
  }

  .els-lb-cap { transition: opacity 0.15s ease; }

  .els-lb-cap {
    display: flex;
    align-items: baseline;
    gap: 16px;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.22em;
    text-transform: uppercase;
  }

  .els-lb-num { color: var(--accent); }
  .els-lb-title { color: var(--dark-fg); }
  .els-lb-meta { color: var(--muted); margin-inline-start: auto; }

  .els-lb-close,
  .els-lb-prev,
  .els-lb-next {
    position: absolute;
    z-index: 1;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: var(--hairline) solid color-mix(in srgb, var(--dark-fg) 25%, transparent);
    background: transparent;
    color: var(--dark-fg);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    /* Opacity is part of the open/close fade; without it here the
       controls snap in over a still-transparent scrim. */
    opacity: 0;
    transition:
      opacity 0.2s ease,
      background 0.2s ease,
      border-color 0.2s ease;
  }

  .els-lightbox.is-open :is(.els-lb-close, .els-lb-prev, .els-lb-next) {
    opacity: 1;
  }

  .els-lb-close:hover,
  .els-lb-prev:hover,
  .els-lb-next:hover {
    background: color-mix(in srgb, var(--accent) 22%, transparent);
    border-color: var(--accent);
  }

  .els-lb-close { top: 24px; right: 24px; }
  .els-lb-prev { left: 24px; top: 50%; translate: 0 -50%; }
  .els-lb-next { right: 24px; top: 50%; translate: 0 -50%; }

  :root[data-lightbox-open] body { overflow: hidden; }

  /* ── Footer ──────────────────────────────────────────────── */

  .els-foot {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 40px clamp(24px, 6vw, 96px) 88px;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--muted);
  }

  .els-foot-note { color: color-mix(in srgb, var(--muted) 70%, transparent); }

  .els-foot-note a {
    color: var(--accent);
    text-decoration: none;
    border-bottom: var(--hairline) solid color-mix(in srgb, var(--accent) 40%, transparent);
    transition: border-color 0.25s ease;
  }

  .els-foot-note a:hover { border-color: var(--accent); }

  /* ── Concept / poetry panel ──────────────────────────────── */

  #els_panel {
    position: fixed;
    right: 16px;
    bottom: 16px;
    z-index: 50;
    width: 210px;
    background: #16161a;
    border: var(--hairline) solid rgba(255, 255, 255, 0.18);
    border-radius: 8px;
    box-shadow: 0 8px 24px -8px rgba(0, 0, 0, 0.5);
    font-family: var(--font-mono);
    overflow: hidden;
  }

  .els-panel-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 11px 14px;
    background: transparent;
    border: none;
    color: rgba(255, 255, 255, 0.65);
    font-family: inherit;
    font-size: 9px;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    cursor: pointer;
  }

  .els-panel-dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--accent-dark);
  }

  .els-panel-body {
    padding: 0 14px 14px;
    display: grid;
    gap: 6px;
  }

  #els_panel.is-collapsed .els-panel-body { display: none; }

  .els-panel-label {
    margin-block-start: 6px;
    font-size: 8px;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.4);
  }

  .els-panel-row {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
  }

  .els-panel-row button {
    flex: 1 1 auto;
    padding: 7px 9px;
    background: rgba(255, 255, 255, 0.05);
    border: var(--hairline) solid transparent;
    border-radius: 4px;
    color: #ede8df;
    font-family: inherit;
    font-size: 9px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    cursor: pointer;
    transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
  }

  .els-panel-row button:hover { background: rgba(255, 255, 255, 0.12); }

  .els-panel-row button.is-on {
    background: color-mix(in srgb, var(--accent-dark) 22%, transparent);
    border-color: var(--accent-dark);
    color: #fff;
  }

  /* The photography/writing filter only means anything in "Separate". */
  .els-panel-filter { display: none; }
  body[data-poetry="toggle"] .els-panel-filter { display: block; }

  @media print {
    #els_panel { display: none; }
  }

  /* ── Responsive ──────────────────────────────────────────── */

  @media (width <= 900px) {
    .els-sheet-grid {
      grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
      gap: 28px;
    }

    /* No gutter to spare — margin poems fall under the photo. */
    .els-margin {
      position: static;
      writing-mode: horizontal-tb;
      margin: 12px 0 0;
      white-space: normal;
      max-height: none;
    }

    .els-drift { height: 78svh; }
    .els-hero-scroll { display: none; }

    #els_panel {
      right: 12px;
      bottom: 12px;
      width: 170px;
    }

    .els-frame-shot { height: min(44svh, 340px); }
    .els-frame-poem { height: min(44svh, 340px); width: min(80vw, 320px); }
  }

  @media (width <= 600px) {
    .els-sheet-grid { grid-template-columns: 1fr; }
    .els-minimap { display: none; }
    .els-lb-close { top: 12px; right: 12px; }

    /* Side arrows sit on top of the photograph at this width, and a thumb
       reaching for one covers what it is meant to be looking at. Below the
       frame they are also simply easier to reach. */
    /* :not([hidden]) matters — a bare display:grid here would outrank the
       [hidden] rule above and leave the lightbox on screen when closed. */
    .els-lightbox:not([hidden]) {
      display: grid;
      grid-template-rows: auto auto;
      grid-template-columns: 1fr 1fr;
      align-content: center;
      justify-content: stretch;
      row-gap: 22px;
    }

    .els-lb-prev,
    .els-lb-next {
      position: static;
      translate: none;
      grid-row: 2;
      width: 52px;
      height: 52px;
    }

    .els-lb-prev { grid-column: 1; justify-self: start; }
    .els-lb-next { grid-column: 2; justify-self: end; }

    .els-lb-figure {
      grid-row: 1;
      grid-column: 1 / -1;
      justify-self: center;
      align-self: center;
    }

    .els-lb-img { max-height: 62svh; }
  }

  /* ── Reduced motion ──────────────────────────────────────── */

  @media (prefers-reduced-motion: reduce) {
    .els-hero-tag,
    .els-hero-lede,
    .els-hero-meta,
    .els-cell,
    .els-frame,
    .els-drift-node {
      opacity: 1 !important;
      translate: none !important;
      transition: none !important;
    }

    .els-word::before {
      translate: none !important;
      transition: none !important;
    }

    .els-hero-frame {
      clip-path: none !important;
      transition: none !important;
    }

    .els-hero-frame img { transition: none !important; }

    .els-lightbox,
    .els-lb-figure,
    .els-lb-img,
    .els-lb-cap {
      transition: none !important;
    }

    .els-lb-figure {
      scale: 1 !important;
      translate: none !important;
    }

    .els-neg,
    .els-cell-poem .els-slip {
      rotate: 0deg !important;
      translate: none !important;
      transition: none !important;
    }

    .els-neg img,
    .els-frame-shot img,
    .els-drift-frame { transition: none !important; }
  }
}
