/* ============================================================
   Fransisko Rumagit — personal site
   Palette sampled directly from the character design sheet.
   ============================================================ */

/* ---------- 1. Fonts (self-hosted, no third-party requests) ---------- */

@font-face {
  font-family: 'Fraunces';
  src: url('media/fonts/fraunces-latin.woff2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  src: url('media/fonts/fraunces-latin-ext.woff2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Instrument Sans';
  src: url('media/fonts/instrument-sans-latin.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Instrument Sans';
  src: url('media/fonts/instrument-sans-latin-ext.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}


/* ---------- 2. Tokens ---------- */

:root {
  /* the six swatches, read pixel-by-pixel off the character sheet */
  --ink:        #252726;
  --grey:       #5B5C5B;
  --rust:       #C16743;
  --amber:      #F49C5F;
  --cream:      #F5CF9E;
  --sage:       #5D857B;

  /* accessible derivatives (measured, not guessed) */
  --rust-deep:  #9A4626;   /* 5.9:1 on paper, 5.2:1 under both warm overlays */
  --sage-deep:  #4A6B62;   /* 5.5:1 on paper */
  --sage-light: #8FB3A8;   /* 7.9:1 on stage */

  /* grounds */
  --paper:      #FAF6EE;
  --paper-2:    #F2EBDF;
  --stage:      #161616;

  --rule:       rgba(37, 39, 38, 0.16);
  --rule-soft:  rgba(37, 39, 38, 0.09);
  --rule-light: rgba(245, 207, 158, 0.22);

  /* per-section accent, overridden by .movement--* */
  --accent:      var(--ink);
  --accent-deep: var(--ink);

  /* type */
  --serif: 'Fraunces', Georgia, 'Times New Roman', serif;
  --sans:  'Instrument Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --fs-label: 0.8125rem;
  --fs-sm:    0.9375rem;
  --fs-base:  1.0625rem;
  --fs-lede:  clamp(1.25rem, 1rem + 1.1vw, 1.6rem);
  --fs-h3:    clamp(1.05rem, 1rem + 0.3vw, 1.2rem);
  --fs-h2:    clamp(2rem, 1.3rem + 3.2vw, 3.5rem);
  --fs-name:  clamp(2.9rem, 1rem + 10.5vw, 8.5rem);

  /* 8px rhythm */
  --s1: 0.5rem;  --s2: 1rem;   --s3: 1.5rem; --s4: 2rem;
  --s5: 3rem;    --s6: 4rem;   --s7: 6rem;   --s8: 8rem;

  --wrap: 1180px;
  --gutter: clamp(1.25rem, 5vw, 3rem);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}


/* ---------- 3. Reset & base ---------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--fs-base);
  line-height: 1.62;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, video { max-width: 100%; height: auto; display: block; }

h1, h2, h3 { font-family: var(--serif); font-weight: 500; line-height: 1.1; margin: 0; }
p { margin: 0; }
ul, ol, dl, dd { margin: 0; padding: 0; }
li { list-style: none; }

a { color: inherit; }

.num { font-variant-numeric: tabular-nums lining-nums; }

::selection { background: var(--cream); color: var(--ink); }

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

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--ink);
  color: var(--paper);
  padding: 0.75rem 1.25rem;
  font-size: var(--fs-sm);
  text-decoration: none;
}
.skip:focus { left: 0.5rem; top: 0.5rem; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}


/* ---------- 4. Paper grain ---------- */

.grain {
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  opacity: 0.32;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.11'/%3E%3C/svg%3E");
}


/* ---------- 4b. Living backdrop ---------- */
/* Sits above the paper ground but below every piece of content. The stave
   ruling is the same motif that used to be pinned behind the hero — promoted
   to the whole page and set slowly in motion. */

/* Sits at z-index -1 so no content needs a z-index of its own. That also keeps
   `main` from becoming a stacking context, which would change how the page's
   blend-mode overlays (the grain, the interlude motes) resolve. */
.backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
}

.backdrop__staves {
  position: absolute;
  inset: -12rem 0;
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent 4.4rem,
    var(--rule-soft) 4.4rem,
    var(--rule-soft) calc(4.4rem + 1px)
  );
  -webkit-mask-image: linear-gradient(to right, transparent, #000 13%, #000 87%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 13%, #000 87%, transparent);
  animation: stave-drift 19s linear infinite,
             stave-breathe 11s ease-in-out infinite;
  will-change: transform;
}

/* second stave at a different period, drifting the other way */
.backdrop__staves--slow {
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent 7.2rem,
    var(--rule-soft) 7.2rem,
    var(--rule-soft) calc(7.2rem + 1px)
  );
  animation: stave-rise 31s linear infinite,
             stave-breathe-soft 17s ease-in-out infinite;
}

/* each travels exactly one period, so the loop has no seam */
@keyframes stave-drift { from { transform: translateY(0); }        to { transform: translateY(-4.4rem); } }
@keyframes stave-rise  { from { transform: translateY(-7.2rem); }  to { transform: translateY(0); } }
@keyframes stave-breathe      { 0%, 100% { opacity: 0.72; } 50% { opacity: 1; } }
@keyframes stave-breathe-soft { 0%, 100% { opacity: 0.50; } 50% { opacity: 0.24; } }

/* a pool of warm lamplight moving across the page */
.backdrop__glow {
  position: absolute;
  top: 0;
  left: 0;
  width: 78rem;
  height: 60rem;
  margin: -30rem 0 0 -39rem;
  background: radial-gradient(closest-side,
              rgba(244, 156, 95, 0.10), rgba(244, 156, 95, 0) 72%);
  animation: glow-sweep 34s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes glow-sweep {
  from { transform: translate3d(18vw, 14vh, 0) scale(1); }
  to   { transform: translate3d(84vw, 82vh, 0) scale(1.22); }
}

/* halo that follows the pointer — desktop only, see script.js */
.backdrop__cursor {
  position: absolute;
  top: 0;
  left: 0;
  width: 42rem;
  height: 42rem;
  margin: -21rem 0 0 -21rem;
  background: radial-gradient(closest-side,
              rgba(244, 156, 95, 0.11), rgba(244, 156, 95, 0) 70%);
  transform: translate3d(var(--mx, 50vw), var(--my, 40vh), 0);
  opacity: 0;
  transition: opacity 0.9s var(--ease);
  will-change: transform;
}
@media (hover: hover) and (pointer: fine) {
  html.has-pointer .backdrop__cursor { opacity: 1; }
}


/* ---------- 5. Layout primitives ---------- */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.eyebrow {
  font-size: var(--fs-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--grey);
  margin: 0 0 var(--s3);
}
.eyebrow--light { color: var(--sage-light); }

.dot { color: var(--accent); padding-inline: 0.35em; }

.rule {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: var(--s3) 0;
}

.prose p + p { margin-top: 1.1em; }
.prose { max-width: 42rem; }
.prose--wide { max-width: 50rem; }

.lede {
  font-family: var(--serif);
  font-size: var(--fs-lede);
  line-height: 1.34;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.prose .lede + p { margin-top: 1.4em; }
.prose p:not(.lede) { color: var(--grey); max-width: 64ch; }


/* ---------- 6. Masthead ---------- */

.masthead {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  transition: background-color 0.4s var(--ease), border-color 0.4s var(--ease);
  border-bottom: 1px solid transparent;
}
.masthead.is-stuck {
  background: rgba(250, 246, 238, 0.82);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom-color: var(--rule-soft);
}
.masthead.is-dark { color: var(--cream); }
.masthead.is-dark.is-stuck {
  background: rgba(22, 22, 22, 0.72);
  border-bottom-color: var(--rule-light);
}

.masthead__in {
  max-width: var(--wrap);
  margin-inline: auto;
  padding: 0 var(--gutter);
  min-height: 4.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
}

.monogram {
  font-family: var(--serif);
  font-size: 1.15rem;
  letter-spacing: 0.06em;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 2px;
}
.monogram__dot { color: var(--rust-deep); }
.masthead.is-dark .monogram__dot { color: var(--amber); }

.masthead__cta {
  font-size: var(--fs-sm);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 2px;
}
.masthead__cta > span {
  padding-bottom: 3px;
  border-bottom: 1px solid color-mix(in srgb, currentColor 38%, transparent);
  transition: border-bottom-color 0.3s var(--ease);
}
.masthead__cta:hover > span { border-bottom-color: currentColor; }


/* ---------- 7. Programme rail ---------- */

.rail { display: none; }

/* Only shown where the page margin is genuinely wide enough to hold it
   without crowding the text column — below 1500px it would collide. */
@media (min-width: 1500px) {
  .rail {
    display: block;
    position: fixed;
    top: 50%;
    left: clamp(1rem, 1.7vw, 1.5rem);
    transform: translateY(-50%);
    z-index: 95;
    opacity: 1;
    transition: opacity 0.5s var(--ease);
  }
  /* the index belongs to the programme, not the title page */
  .rail.is-hidden { opacity: 0; pointer-events: none; }
  .rail__list { display: grid; gap: 0.7rem; }
  .rail a {
    display: grid;
    grid-template-columns: 1.6rem auto;
    align-items: baseline;
    gap: 0.5rem;
    text-decoration: none;
    font-size: 0.75rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--grey);
    opacity: 0.5;
    transition: opacity 0.3s var(--ease), color 0.3s var(--ease);
    padding: 0.28rem 0;
  }
  .rail__num { font-family: var(--serif); font-variant-numeric: tabular-nums; }
  .rail a:hover { opacity: 0.9; }
  .rail a.is-current { opacity: 1; color: var(--rust-deep); }
  .rail a.is-current .rail__name { text-decoration: underline; text-underline-offset: 4px; }

  /* over the dark interlude */
  .rail.is-dark a { color: var(--cream); }
  .rail.is-dark a.is-current { color: var(--amber); }
}


/* ---------- 8. Overture (hero) ---------- */

.overture {
  position: relative;
  padding-top: clamp(7rem, 16vh, 11rem);
  padding-bottom: var(--s6);
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: hidden;
}

/* the hero's ledger ruling now comes from .backdrop, so the whole page shares it */

.overture__in {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s5);
  align-items: end;
}

.overture__name {
  font-size: var(--fs-name);
  line-height: 0.87;
  letter-spacing: -0.035em;
  font-weight: 500;
  margin: 0;
}
.overture__line { display: block; }
.overture__line--2 {
  color: var(--rust);
  font-style: italic;
  margin-left: 0.06em;
}

.overture__role {
  font-size: clamp(1rem, 0.9rem + 0.5vw, 1.2rem);
  letter-spacing: 0.04em;
  color: var(--ink);
}

.overture__blurb {
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--fs-lede);
  line-height: 1.4;
  color: var(--grey);
  max-width: 26ch;
  margin-top: var(--s4);
}

.overture__meta {
  font-size: var(--fs-label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--grey);
  margin-top: var(--s4);
}

.overture__figure { justify-self: start; }
/* figure.webp carries a real alpha channel, so it needs no blend-mode trick */
.overture__figure img {
  width: clamp(150px, 34vw, 250px);
  height: auto;
  animation: figure-float 7.5s ease-in-out infinite;
}
@keyframes figure-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-9px); }
}

.scroll-cue {
  position: relative;
  margin: var(--s6) auto 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: var(--grey);
  font-size: var(--fs-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 0.5rem 1rem;
  min-height: 44px;
}
.scroll-cue__line {
  width: 1px;
  height: 3rem;
  background: linear-gradient(to bottom, var(--rule), transparent);
}
.scroll-cue__line::after {
  content: '';
  display: block;
  width: 1px;
  height: 1rem;
  background: var(--rust);
  animation: cue 2.4s var(--ease) infinite;
}
@keyframes cue {
  0%   { transform: translateY(-1rem); opacity: 0; }
  40%  { opacity: 1; }
  100% { transform: translateY(3rem); opacity: 0; }
}

@media (min-width: 800px) {
  .overture__in {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--s6);
  }
  .overture__figure { justify-self: end; }
}

/* On a phone the hero is taller than the viewport. Centring it would push the
   first line of the name up behind the masthead, so anchor it to the top and
   let the page simply scroll. */
@media (max-width: 799px) {
  .overture {
    min-height: 0;
    justify-content: flex-start;
    padding-top: 6.5rem;
    padding-bottom: var(--s4);
  }
  .overture__in { gap: var(--s4); }
  .overture__blurb,
  .overture__meta { margin-top: var(--s3); }
  .overture__figure img { width: clamp(128px, 34vw, 170px); }
  .scroll-cue { display: none; }
}


/* ---------- 9. Movement (section) shell ---------- */

.movement {
  padding-block: clamp(4.5rem, 11vw, 8.5rem);
  position: relative;
}
.movement--rust { --accent: var(--rust); --accent-deep: var(--rust-deep); }
.movement--sage { --accent: var(--sage); --accent-deep: var(--sage-deep); }

/* section header: numeral · title · rule */
.mh {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: baseline;
  column-gap: clamp(0.9rem, 2vw, 1.6rem);
  margin-bottom: clamp(2.25rem, 5vw, 3.5rem);
}
.mh__num {
  font-family: var(--serif);
  font-size: clamp(0.95rem, 0.8rem + 0.5vw, 1.2rem);
  color: var(--accent-deep);
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
}
.mh__title {
  font-size: var(--fs-h2);
  letter-spacing: -0.025em;
  grid-column: 2;
}
.mh__rule {
  grid-column: 2;
  height: 1px;
  background: var(--rule);
  margin-top: 1.15rem;
  display: block;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.9s var(--ease) 0.15s;
}
.mh.in .mh__rule { transform: scaleX(1); }
html:not(.js) .mh__rule { transform: scaleX(1); }


/* ---------- 10. I. Portrait ---------- */

.portrait__body {
  display: grid;
  gap: var(--s5);
  align-items: start;
}
@media (min-width: 860px) {
  .portrait__body { grid-template-columns: minmax(0, 1.65fr) minmax(0, 1fr); gap: var(--s6); }
}

.stats { border-top: 1px solid var(--rule); }
.stats__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s2);
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--rule-soft);
}
.stats dt {
  font-size: var(--fs-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--grey);
}
.stats dd {
  font-family: var(--serif);
  font-size: 1.15rem;
}

.traits {
  display: flex;
  flex-wrap: wrap;
  gap: 0 clamp(1rem, 3vw, 2.25rem);
  margin-top: var(--s5);
  padding-top: var(--s3);
  border-top: 1px solid var(--rule);
  font-family: var(--serif);
  font-size: clamp(1rem, 0.9rem + 0.6vw, 1.35rem);
  color: var(--ink);
}
.traits li { position: relative; padding-right: clamp(1rem, 3vw, 2.25rem); }
.traits li:not(:last-child)::after {
  content: '·';
  position: absolute;
  right: 0;
  color: var(--rust);
}


/* ---------- 11. Plates (framed illustrations) ---------- */

.plate { margin: 0; }

/* the frame carries the border and does the clipping, so the image inside
   can scale on hover without spilling over the caption */
.plate__frame {
  display: block;
  overflow: hidden;
  border: 1px solid var(--rule-soft);
  background: var(--paper-2);
  transition: box-shadow 0.34s var(--ease), border-color 0.34s var(--ease);
}
.plate img {
  width: 100%;
  transition: transform 0.55s var(--ease);
}
.plate:hover img,
.plate:focus-within img { transform: scale(1.045); }

.plate figcaption {
  margin-top: 0.85rem;
  font-size: var(--fs-label);
  letter-spacing: 0.06em;
  color: var(--grey);
}


/* ---------- 11b. Pull-quote ---------- */

.pullquote {
  margin: clamp(3rem, 7vw, 4.75rem) 0 0;
  padding-left: clamp(1.25rem, 3vw, 2.25rem);
  border-left: 2px solid var(--rust);
  max-width: 46rem;
}
.pullquote__label {
  font-size: var(--fs-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--grey);
  margin-bottom: var(--s2);
}
.pullquote blockquote { margin: 0; }
.pullquote blockquote p {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(1.35rem, 1rem + 1.9vw, 2.3rem);
  line-height: 1.3;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-wrap: pretty;
}


/* ---------- 11c. Reading-row highlight ---------- */
/* A warm tint that bleeds slightly past the text column. These rows are not
   links, so they keep the default cursor on purpose — the tint is a scanning
   aid, not a promise that something is clickable. */

.stats__row,
.capabilities li,
.festival { position: relative; }

.stats__row > *,
.capabilities li > *,
.festival > * { position: relative; z-index: 1; }

.stats__row::before,
.capabilities li::before,
.festival::before {
  content: '';
  position: absolute;
  inset: 0 -0.9rem;
  z-index: 0;
  border-radius: 3px;
  background: color-mix(in srgb, var(--cream) 34%, transparent);
  opacity: 0;
  transition: opacity 0.28s var(--ease);
}
.stats__row::before { background: color-mix(in srgb, var(--cream) 22%, transparent); }

.stats__row:hover::before,
.capabilities li:hover::before,
.festival:hover::before { opacity: 1; }

.festival__year { transition: transform 0.28s var(--ease); }
.festival:hover .festival__year { transform: translateX(4px); }


/* ---------- 12. II. The Ledger ---------- */

.ledger__body {
  display: grid;
  gap: var(--s5);
  align-items: start;
}
@media (min-width: 900px) {
  .ledger__body { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: var(--s6); }
}

.capabilities {
  margin-top: var(--s5);
  border-top: 1px solid var(--rule);
}
.capabilities li {
  display: grid;
  grid-template-columns: 2.75rem 1fr;
  align-items: baseline;
  gap: var(--s1);
  padding: 0.95rem 0;
  border-bottom: 1px solid var(--rule-soft);
}
.capabilities__num {
  font-family: var(--serif);
  font-size: var(--fs-label);
  color: var(--rust-deep);
  letter-spacing: 0.06em;
}
.capabilities__text { font-size: var(--fs-sm); }


/* ---------- 13. Interlude — the podium (dark) ---------- */

.podium {
  position: relative;
  background: var(--stage);
  color: var(--cream);
  padding-block: clamp(5rem, 13vw, 9rem);
  overflow: hidden;
}
/* the house lights going down */
/* kept shorter than the section's top padding so the eyebrow below always
   lands on solid dark rather than halfway up the fade */
.podium__dim {
  position: absolute;
  inset: 0 0 auto 0;
  height: clamp(72px, 8vw, 120px);
  background: linear-gradient(to bottom, var(--paper), var(--stage));
  pointer-events: none;
  z-index: 1;
}
/* ...and coming back up on the way out */
.podium::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: clamp(72px, 8vw, 120px);
  background: linear-gradient(to bottom, var(--stage), var(--paper));
  pointer-events: none;
  z-index: 3;
}

/* dust hanging in the stage light */
.podium__motes {
  position: absolute;
  inset: -20%;
  pointer-events: none;
  z-index: 0;
  mix-blend-mode: screen;
}
.podium__motes::before,
.podium__motes::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cg fill='%23F5CF9E'%3E%3Ccircle cx='18' cy='34' r='1.2' opacity='.7'/%3E%3Ccircle cx='62' cy='12' r='.8' opacity='.5'/%3E%3Ccircle cx='105' cy='48' r='1.4' opacity='.6'/%3E%3Ccircle cx='150' cy='22' r='.9' opacity='.45'/%3E%3Ccircle cx='178' cy='72' r='1.1' opacity='.55'/%3E%3Ccircle cx='32' cy='88' r='1' opacity='.5'/%3E%3Ccircle cx='78' cy='110' r='1.3' opacity='.65'/%3E%3Ccircle cx='128' cy='96' r='.7' opacity='.4'/%3E%3Ccircle cx='166' cy='132' r='1.2' opacity='.5'/%3E%3Ccircle cx='24' cy='146' r='.9' opacity='.45'/%3E%3Ccircle cx='68' cy='172' r='1.1' opacity='.6'/%3E%3Ccircle cx='112' cy='158' r='.8' opacity='.4'/%3E%3Ccircle cx='152' cy='186' r='1.3' opacity='.55'/%3E%3Ccircle cx='190' cy='164' r='.9' opacity='.45'/%3E%3Ccircle cx='96' cy='68' r='.6' opacity='.35'/%3E%3Ccircle cx='44' cy='128' r='.7' opacity='.4'/%3E%3C/g%3E%3C/svg%3E");
  will-change: transform;
}
.podium__motes::before {
  background-size: 520px 520px;
  opacity: 0.55;
  animation: motes-far 58s linear infinite;
}
.podium__motes::after {
  background-size: 330px 330px;
  opacity: 0.34;
  animation: motes-near 37s linear infinite;
}
/* travels exactly one tile, so the drift never jumps */
@keyframes motes-far  { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-520px, -520px, 0); } }
@keyframes motes-near { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(330px, -330px, 0); } }

.podium__in { position: relative; z-index: 2; text-align: center; }

/* NB: `ch` here would resolve against the blockquote's inherited 17px, not the
   display size of the paragraph inside it — hence a root-relative width. */
.motto {
  margin: 0 auto clamp(2.5rem, 6vw, 4rem);
  max-width: min(100%, 46rem);
  text-wrap: pretty;
}
.motto p {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(1.5rem, 1rem + 3vw, 3rem);
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--cream);
}

.stagebox {
  position: relative;
  margin-inline: auto;
  max-width: 1000px;
  aspect-ratio: 16 / 9;
}
.stagebox__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* vignette melts the frame into the dark ground */
.stagebox::after {
  content: '';
  position: absolute;
  inset: -1px;
  pointer-events: none;
  box-shadow:
    inset 0 0 clamp(50px, 11vw, 140px) clamp(20px, 5vw, 60px) var(--stage),
    inset 0 0 clamp(20px, 4vw, 46px) clamp(4px, 1vw, 12px) var(--stage);
}

.podium__caption {
  margin: var(--s4) auto 0;
  max-width: 46ch;
  font-size: var(--fs-sm);
  color: var(--sage-light);
}

/* media controls */
.mediabtn {
  position: absolute;
  bottom: clamp(0.75rem, 2vw, 1.35rem);
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  padding: 0.5rem 0.9rem;
  border: 1px solid var(--rule-light);
  border-radius: 999px;
  background: rgba(22, 22, 22, 0.6);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: var(--cream);
  font: inherit;
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: background-color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.mediabtn:hover { background: rgba(22, 22, 22, 0.85); border-color: var(--cream); }
.mediabtn svg { width: 18px; height: 18px; flex: none; }
.sound { right: clamp(0.75rem, 2vw, 1.35rem); }
.play  { left: clamp(0.75rem, 2vw, 1.35rem); }

.sound__on { display: none; }
.sound[aria-pressed="true"] .sound__on  { display: inline; }
.sound[aria-pressed="true"] .sound__off { display: none; }

.play__pause { display: none; }
.play[data-playing="true"] .play__pause { display: inline; }
.play[data-playing="true"] .play__play  { display: none; }


/* ---------- 14. III. The Stage ---------- */

.festivals {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  border-top: 1px solid var(--rule);
}
.festival {
  display: grid;
  gap: var(--s2);
  padding: clamp(1.5rem, 3vw, 2.25rem) 0;
  border-bottom: 1px solid var(--rule-soft);
}
@media (min-width: 780px) {
  .festival {
    grid-template-columns: 6.5rem minmax(0, 1.5fr) minmax(0, 1.2fr);
    gap: var(--s4);
    align-items: start;
  }
}
.festival__year {
  font-family: var(--serif);
  font-size: 1.1rem;
  color: var(--sage-deep);
}
.festival__name {
  font-size: var(--fs-h3);
  letter-spacing: -0.01em;
}
.festival__where {
  margin-top: 0.35rem;
  font-size: var(--fs-sm);
  color: var(--grey);
}
.festival__meta { display: grid; gap: 0.45rem; }
.festival__meta > div {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: var(--s1);
  align-items: baseline;
}
.festival__meta dt {
  font-size: var(--fs-label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--grey);
}
.festival__meta dd { font-size: var(--fs-sm); }

/* unmistakable placeholders */
.tbd {
  color: var(--rust-deep);
  border-bottom: 1px dotted var(--rust);
  font-size: 0.9em;
  letter-spacing: 0.03em;
  overflow-wrap: anywhere;
}

.roles {
  display: grid;
  gap: var(--s4);
  margin-top: clamp(3rem, 7vw, 4.5rem);
}
@media (min-width: 720px) { .roles { grid-template-columns: repeat(3, 1fr); gap: var(--s5); } }
.roles li { border-top: 1px solid var(--rule); padding-top: var(--s2); }
.roles h3 { font-size: var(--fs-h3); color: var(--sage-deep); }
.roles p { margin-top: 0.4rem; font-size: var(--fs-sm); color: var(--grey); }


/* ---------- 15. IV. Instruments gallery ---------- */

.gallery {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2rem, 4vw, 3rem);
  margin-top: clamp(2.5rem, 6vw, 4rem);
}
@media (min-width: 720px) {
  .gallery { grid-template-columns: repeat(12, 1fr); }
  .gallery__item--third  { grid-column: span 4; }
  .gallery__item--wide   { grid-column: span 7; }
  .gallery__item--narrow { grid-column: span 5; }
}
/* The source illustrations all differ slightly in ratio. Pinning a height per
   row lands every bottom edge — and therefore every caption — on one line,
   while the columns stay deliberately unequal. */
.gallery__item--third img {
  height: clamp(160px, 17vw, 246px);
  width: 100%;
  object-fit: cover;
}
.gallery__item--wide img,
.gallery__item--narrow img {
  height: clamp(150px, 18vw, 262px);
  width: 100%;
  object-fit: cover;
}

.gallery__item figcaption { margin-top: 1rem; }

/* the plate lifts, the caption stays put */
.gallery__item .plate__frame {
  transition: transform 0.32s var(--ease),
              box-shadow 0.34s var(--ease),
              border-color 0.34s var(--ease);
}
.gallery__item:hover .plate__frame,
.gallery__item:focus-within .plate__frame {
  transform: translateY(-5px);
  box-shadow: 0 16px 32px -16px rgba(37, 39, 38, 0.30);
  border-color: color-mix(in srgb, var(--rust) 34%, var(--rule-soft));
}

.gallery__item h3 {
  display: inline;
  font-size: var(--fs-h3);
  letter-spacing: -0.01em;
  color: var(--ink);
  padding-bottom: 2px;
  /* underline that draws itself in from the left */
  background-image: linear-gradient(to right, var(--accent-deep), var(--accent-deep));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 1px;
  transition: background-size 0.42s var(--ease);
}
.gallery__item:hover h3,
.gallery__item:focus-within h3 { background-size: 100% 1px; }
.gallery__item figcaption p {
  margin-top: 0.3rem;
  font-size: var(--fs-sm);
  color: var(--grey);
  letter-spacing: 0;
}


/* ---------- 16. V. Coda ---------- */

.coda { padding-bottom: clamp(4rem, 9vw, 7rem); }
.coda__body {
  display: grid;
  gap: var(--s5);
  align-items: center;
}
@media (min-width: 820px) {
  .coda__body { grid-template-columns: minmax(0, 1.5fr) minmax(0, 0.8fr); gap: var(--s6); }
}
.coda__sub { margin-top: 1.1em; color: var(--grey); font-size: var(--fs-sm); }

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: var(--s4);
}
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 48px;
  padding: 0.75rem 1.35rem;
  border-radius: 999px;
  text-decoration: none;
  font-size: var(--fs-sm);
  letter-spacing: 0.01em;
  border: 1px solid transparent;
  transition: background-color 0.25s var(--ease), color 0.25s var(--ease),
              border-color 0.25s var(--ease), transform 0.25s var(--ease);
}
.btn__icon {
  width: 19px; height: 19px; flex: none;
  transition: transform 0.28s var(--ease);
}
.btn:hover .btn__icon { transform: translateX(2px); }
.btn--primary { background: var(--rust-deep); color: var(--paper); }
.btn--primary:hover { background: var(--ink); transform: translateY(-2px); }
.btn--ghost { border-color: var(--rule); color: var(--ink); }
.btn--ghost:hover { border-color: var(--sage-deep); color: var(--sage-deep); transform: translateY(-2px); }

.coda__portrait { margin: 0; justify-self: center; }
.coda__portrait img {
  width: clamp(170px, 30vw, 230px);
  border-radius: 50%;
  border: 1px solid var(--rule-soft);
}


/* ---------- 17. Colophon ---------- */

.colophon {
  background: var(--paper-2);
  border-top: 1px solid var(--rule);
  padding-block: clamp(3rem, 7vw, 5rem);
}
.colophon__in { display: grid; gap: var(--s5); }
@media (min-width: 860px) {
  .colophon__in { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: var(--s6); align-items: start; }
}

.colophon__quote { margin: 0; max-width: 34rem; }
.colophon__quote p[lang="id"] {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.1rem, 1rem + 0.7vw, 1.4rem);
  line-height: 1.4;
  color: var(--ink);
}
.colophon__gloss {
  margin-top: 0.7rem;
  font-size: var(--fs-sm);
  color: var(--grey);
}
.colophon__attr {
  margin-top: var(--s2);
  font-size: var(--fs-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--grey);
}

.colophon__label {
  font-size: var(--fs-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--grey);
  margin-bottom: 0.75rem;
}
.colophon__palette img { width: 100%; max-width: 345px; }
/* one column per swatch, so each code sits under the colour it names */
.swatches {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 0.4rem;
  margin-top: 0.6rem;
  max-width: 345px;
  font-size: 0.75rem;
  letter-spacing: 0.01em;
  color: var(--grey);
  text-align: center;
}
.swatches li::before { content: '#'; opacity: 0.5; }

.colophon__fine {
  grid-column: 1 / -1;
  border-top: 1px solid var(--rule);
  padding-top: var(--s3);
  font-size: var(--fs-label);
  color: var(--grey);
  max-width: 52ch;
}


/* ---------- 18. Motion ---------- */

html.js .reveal {
  opacity: 0;
  transform: translateY(14px);
}
html.js .reveal.in {
  opacity: 1;
  transform: none;
  transition: opacity 0.65s var(--ease), transform 0.65s var(--ease);
}
html.js .reveal[data-delay="1"].in { transition-delay: 0.08s; }
html.js .reveal[data-delay="2"].in { transition-delay: 0.16s; }
html.js .reveal[data-delay="3"].in { transition-delay: 0.24s; }
html.js .reveal[data-delay="4"].in { transition-delay: 0.32s; }
html.js .reveal[data-delay="5"].in { transition-delay: 0.40s; }


/* ---------- 19. Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  html.js .reveal { opacity: 1; transform: none; }
  .mh__rule { transform: scaleX(1); }
  .scroll-cue__line::after { animation: none; }

  /* the living backdrop holds still */
  .backdrop__staves,
  .backdrop__glow,
  .podium__motes::before,
  .podium__motes::after,
  .overture__figure img { animation: none !important; }

  /* no pointer halo at all — the listener is never attached either */
  .backdrop__cursor { display: none; }

  /* keep colour-only hovers, drop the movement */
  .plate:hover img,
  .plate:focus-within img,
  .gallery__item:hover .plate__frame,
  .gallery__item:focus-within .plate__frame,
  .festival:hover .festival__year,
  .btn:hover .btn__icon,
  .btn--primary:hover,
  .btn--ghost:hover { transform: none; }
}


/* ---------- 20. Print ---------- */

@media print {
  .rail, .masthead, .grain, .scroll-cue, .mediabtn, .stagebox,
  .backdrop, .podium__motes { display: none !important; }
  body { background: #fff; color: #000; }
  .podium { background: #fff; color: #000; }
  .motto p, .podium__caption { color: #000; }
  html.js .reveal { opacity: 1; transform: none; }
}
