/* Mainstage World.
   Studied Resident Advisor's magazine grid: the chrome disappears and the artwork plus a
   condensed headline does all the work. No card borders, no rounded boxes, no drop shadows.
   Mobile first, self hosted fonts, nothing fetched from another company. */

@font-face {
  font-family: "Oswald";
  src: url("/assets/fonts/oswald-latin.woff2") format("woff2");
  font-weight: 200 700;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2192, U+2212;
}
@font-face {
  font-family: "Oswald";
  src: url("/assets/fonts/oswald-latinext.woff2") format("woff2");
  font-weight: 200 700;
  font-display: swap;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB;
}
@font-face {
  font-family: "Instrument";
  src: url("/assets/fonts/instrument-latin.woff2") format("woff2");
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F;
}
@font-face {
  font-family: "Instrument";
  src: url("/assets/fonts/instrument-latinext.woff2") format("woff2");
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB;
}

:root {
  --ink: #0d0d10;
  --ink-soft: #5c5a66;
  --paper: #ffffff;
  --band: #f2f1ee;
  --line: #dedbd4;
  --accent: #e5322d;
  --max: 76rem;
  --text: 42rem;
  --display: "Oswald", "Haettenschweiler", "Arial Narrow", sans-serif;
  --body: "Instrument", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #f4f2ee;
    --ink-soft: #a5a1ae;
    --paper: #0b0b0e;
    --band: #15151a;
    --line: #26262f;
    --accent: #ff5b4a;
  }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 1.0625rem/1.6 var(--body);
}

a { color: inherit; }
img { max-width: 100%; display: block; }

/* header

   Fixed on every page, so it never jumps from static to fixed halfway down. On the front
   page it floats inside the film; everywhere else it is a solid bar. Past the first screen
   it condenses: smaller wordmark, no tagline, a hairline underneath. */

.top {
  position: sticky;
  top: 0;
  z-index: 50;
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: 1.5rem;
  padding: 0.9rem 1.25rem;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  transition: padding 260ms ease, background 260ms ease, border-color 260ms ease;
}

/* Only the front page lifts the masthead out of the flow, so it can sit inside the film.
   Everywhere else it is sticky and in the flow, which is why no page needs to reserve a
   guessed amount of space at the top. Guessing it put the first paragraph under the bar. */
body.is-home .top { position: fixed; left: 0; right: 0; }

.wordmark {
  grid-column: 1;
  display: block;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.35rem, 5.4vw, 2.1rem);
  line-height: 0.92;
  letter-spacing: -0.015em;
  text-transform: uppercase;
  text-decoration: none;
  transition: font-size 260ms ease;
}

.tagline {
  grid-column: 1;
  grid-row: 2;
  margin: 0.2rem 0 0;
  color: var(--ink-soft);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  transition: opacity 200ms ease, max-height 260ms ease;
  overflow: hidden;
  max-height: 2rem;
}

.nav {
  grid-column: 2;
  grid-row: 1 / span 2;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: clamp(0.75rem, 2.4vw, 1.6rem);
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.nav::-webkit-scrollbar { display: none; }

.nav a {
  position: relative;
  flex: 0 0 auto;
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(0.78rem, 2.6vw, 0.92rem);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-decoration: none;
  color: var(--ink);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}

/* The rule draws in from the left rather than appearing. Cheap, and it is the difference
   between a nav that feels made and one that feels defaulted. */
.nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0.7rem;
  height: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 260ms cubic-bezier(0.22, 1, 0.36, 1);
}

.nav a:hover::after, .nav a:focus-visible::after { transform: scaleX(1); }
.nav a:hover { color: var(--accent); }

/* The language switch is a control, not a link, so it looks like one. */
.nav a.switch {
  color: var(--accent);
  border: 1px solid currentColor;
  padding: 0.32rem 0.7rem;
  min-height: 0;
  letter-spacing: 0.1em;
}
.nav a.switch::after { display: none; }
.nav a.switch:hover { background: var(--accent); color: var(--paper); }

.top.is-stuck { padding-top: 0.45rem; padding-bottom: 0.45rem; }
.top.is-stuck .wordmark { font-size: clamp(1.05rem, 4vw, 1.35rem); }
.top.is-stuck .tagline { opacity: 0; max-height: 0; margin-top: 0; }

/* shared shells */

main { display: block; }

.hero, .wrap, #latest, .rail { max-width: var(--max); margin: 0 auto; padding: 0 1.25rem; }

.post, .page, .fest { max-width: var(--text); margin: 0 auto; padding: 2.25rem 1.25rem 3rem; }

/* section headings, RA's slash mark reworked as a rule */

.section-title {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--accent);
  margin: 2.5rem 0 1.25rem;
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.section-title::after {
  content: "";
  flex: 1;
  height: 2px;
  background: var(--line);
}

/* the hero, a real camera move across one 360 sphere shot inside UNTOLD */

.hero-track { position: relative; height: 260vh; }

/* On the front page the masthead floats inside the picture instead of sitting on a shelf
   above it. A full bleed hero that starts below a bar is not a hero, it is a banner. */
/* On the front page the masthead floats inside the picture instead of sitting on a shelf
   above it. A full bleed hero that starts below a bar is not a hero, it is a banner. */
body.is-home .top:not(.is-stuck) {
  border-bottom-color: transparent;
  background: linear-gradient(180deg, rgba(4,4,8,0.72), rgba(4,4,8,0.28) 55%, rgba(4,4,8,0));
  padding-bottom: 2rem;
}
body.is-home .top:not(.is-stuck) .wordmark,
body.is-home .top:not(.is-stuck) .nav a { color: #fff; }
body.is-home .top:not(.is-stuck) .tagline { color: rgba(255,255,255,0.66); }
body.is-home .top:not(.is-stuck) .nav a:hover { color: var(--accent); }
body.is-home .top:not(.is-stuck) .nav a.switch { color: #fff; }
body.is-home .top:not(.is-stuck) .nav a.switch:hover { background: #fff; color: #06060a; }

.hero-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  background: #040f1b;
}

/* The film sits under everything. object-fit cover on a wide screen, contain on a tall
   one, because the subject is a circle in the middle of the frame and cropping a phone
   down to it would cut the planet in half. The stage colour is sampled from the film's
   own corner sky, #040f1b, so on a phone there is no visible letterbox, only more night. */
/* The still and the film live in one box, and that box is the only thing that decides the
   shape. A video POSTER attribute is not usable here: Safari ignores object-fit on a poster
   and stretches it to the element, which is exactly what a real iPhone showed the moment
   autoplay did not start. An img obeys object-fit everywhere, so the still is an img. */
.hero-pic { position: absolute; inset: 0; }

.hero-still,
.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  display: block;
}

/* The film is underneath and always fully visible. The still sits ON TOP and is what fades
   away, rather than the film fading in.
   Two reasons, both learned the hard way on a real iPhone. A video paints its background
   colour over anything behind it before it has frames, so it must not have one. And Safari
   will not reliably autoplay a video it considers not visible, so hiding the film until it
   plays is a deadlock: invisible, therefore never played, therefore never visible. */
.hero-video { background: transparent; }

.hero-still {
  z-index: 1;
  background: #040f1b;
  transition: opacity 700ms ease;
}

.hero-stage.is-ready .hero-still { opacity: 0; }

/* No fade in, and no waiting for the film. The poster IS the first frame of the loop, so
   the browser paints it the moment it arrives and the video replaces it on the same frame.
   Hiding the video until it was ready meant three seconds of black rectangle. */

/* A phone is about 0.47 wide to tall and the subject is a circle, so no crop both fills
   the frame and keeps a whole planet. Rather than squeeze the desktop layout, a tall screen
   gets a different one: the film runs full width at its own shape, the headline sits under
   it, and the pair is centred as one block. No floating band, no dead sky. */
@media (max-aspect-ratio: 1/1) {
  .hero-stage {
    display: flex;
    flex-direction: column;
    /* The picture starts directly under the masthead rather than floating in the middle of
       the screen. --top-h is the real measured bar height, so this holds whether the nav
       wraps to one row in English or two in Romanian. */
    justify-content: flex-start;
    padding-top: var(--top-h, 7rem);
    gap: 1.4rem;
  }
  .hero-pic {
    /* relative, NOT static. The still and the film are absolutely placed inside this box,
       and a static box is not a box they can be placed inside, so they escaped to the
       viewport and filled the whole screen with a crop of the crowd. */
    position: relative;
    inset: auto;
    width: 100%;
    /* Stated, not inferred. A video with no metadata yet reports a 2 to 1 default shape, so
       leaving the height to work itself out squashed the picture until the film loaded. */
    aspect-ratio: 860 / 580;
  }
  .hero-lines {
    position: static;
    bottom: auto;
    padding-inline: 1.1rem;
  }
  /* The scrim would darken the whole screen now that the picture is only part of it. */
  .hero-stage::after {
    background: linear-gradient(180deg, rgba(4,4,8,0.72) 0%, rgba(4,4,8,0) 22%);
    opacity: 1;
  }
}

/* The grade travels with the move: tight and cool at the start, open and warm at the end.
   --p is written by the scroll loop, so this animates with the picture rather than on a timer. */
.hero-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(4,4,8,0.55) 0%, rgba(4,4,8,0) 26%, rgba(4,4,8,0) 44%, rgba(4,4,8,0.92) 100%),
    radial-gradient(140% 120% at 50% 40%, rgba(0,0,0,0) 55%, rgba(4,4,8,0.55) 100%);
  opacity: calc(0.72 + var(--p, 0) * 0.18);
}

.hero-lines {
  position: absolute;
  left: 0; right: 0; bottom: clamp(3.5rem, 12vh, 8rem);
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.15rem;
  padding: 0 clamp(1.25rem, 5vw, 4rem);
  max-width: 82rem;
  margin: 0 auto;
  pointer-events: none;
  perspective: 900px;
}

/* Lines arrive OUT OF DEPTH rather than fading in. Her own idea, and the most distinctive
   motion on any of these pages: reality comes to you, you do not go to the text. */
.hero-line {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 0.95;
  color: #fff;
  font-size: clamp(2.1rem, 7.6vw, 6.2rem);
  margin: 0;
  transform-style: preserve-3d;
  will-change: transform, opacity, filter;
}

.hero-line.one {
  opacity: clamp(0, calc((0.22 - var(--p, 0)) * 8), 1);
  transform: translateZ(calc(var(--p, 0) * 700px));
  filter: blur(calc(var(--p, 0) * 6px));
}

.hero-line.two {
  color: var(--accent);
  opacity: clamp(0, calc((var(--p, 0) - 0.34) * 7), 1);
  transform: translateZ(calc((0.62 - var(--p, 0)) * -1200px));
  filter: blur(clamp(0px, calc((0.62 - var(--p, 0)) * 26px), 14px));
}

.hero-cue {
  position: absolute;
  left: 50%;
  bottom: 2.2rem;
  transform: translateX(-50%);
  z-index: 2;
  font-family: var(--display);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: rgba(255,255,255,0.62);
  opacity: clamp(0, calc((var(--p, 0) - 0.72) * 6), 1);
}

/* Reduced motion gets a designed still, not a broken version. */
.hero-stage.is-still .hero-line { opacity: 1; transform: none; filter: none; }
.hero-stage.is-still .hero-line.two { margin-top: 0.4rem; }
.hero-stage.is-still ~ * .hero-cue, .hero-stage.is-still .hero-cue { display: none; }

@media (prefers-reduced-motion: reduce) {
  .hero-track { height: 100vh; }
  .hero-line { opacity: 1 !important; transform: none !important; filter: none !important; }
  .hero-cue { display: none; }
}

/* home */

/* The front page belongs to the lead story, so the standfirst stays small and gets out
   of the way. A big mission headline here just repeats the masthead. */
.hero { padding-top: 1.5rem; padding-bottom: 1.25rem; }

.hero h1 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 0.95rem;
  line-height: 1.2;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin: 0 0 0.4rem;
  color: var(--accent);
}

.hero p { color: var(--ink-soft); margin: 0; max-width: 58ch; font-size: 0.95rem; }

/* the artwork, photo or designed cover */

.card-art {
  display: flex;
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--band);
}

.card-art img { width: 100%; height: 100%; object-fit: cover; }

.cover {
  flex-direction: column;
  justify-content: flex-end;
  padding: 1rem;
  color: #fff;
}

.cover-eyebrow {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  opacity: 0.8;
  margin-bottom: 0.25rem;
}

.cover-word {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.5rem, 4.5vw, 2.4rem);
  line-height: 0.95;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}

.cover[data-tone="1"] { background: linear-gradient(150deg, #16213e, #4a2b6b); }
.cover[data-tone="2"] { background: linear-gradient(150deg, #7a1f2b, #d1492f); }
.cover[data-tone="3"] { background: linear-gradient(150deg, #12403a, #3f7d5a); }
.cover[data-tone="4"] { background: linear-gradient(150deg, #23304d, #2f7d8f); }
.cover[data-tone="5"] { background: linear-gradient(150deg, #4a2340, #a63f6b); }
.cover[data-tone="6"] { background: linear-gradient(150deg, #3a2a12, #9c6b28); }

/* cards */

.cards { list-style: none; margin: 0 0 2.5rem; padding: 0; display: grid; gap: 2rem 1.5rem; }

.card a { display: block; text-decoration: none; }

.card a:hover .card-title { color: var(--accent); }

.card-kicker, .card-title, .card-dek, .card-date { display: block; }

.card-kicker {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--accent);
  margin: 0.85rem 0 0.35rem;
}

.card-title {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.35rem;
  line-height: 1.1;
  letter-spacing: -0.005em;
}

.card-dek { color: var(--ink-soft); font-size: 0.95rem; margin-top: 0.45rem; }

.card-date {
  color: var(--ink-soft);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-top: 0.6rem;
}

/* the lead story */

.lead { margin-bottom: 1rem; }

.lead a { display: block; text-decoration: none; }

.lead .card-art { aspect-ratio: 16 / 9; }

.lead .card-title {
  font-size: clamp(1.9rem, 5.5vw, 3.1rem);
  line-height: 0.98;
  margin-top: 0.5rem;
}

.lead .card-dek { font-size: 1.05rem; max-width: 52ch; }

/* the numbered rail, the cheapest density on any magazine front page */

.rail-list { list-style: none; margin: 0; padding: 0; }

.rail-list li {
  display: flex;
  gap: 0.9rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--line);
}

.rail-list .n {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--line);
  min-width: 1.4rem;
}

.rail-list a {
  font-family: var(--display);
  font-weight: 500;
  font-size: 1.02rem;
  line-height: 1.2;
  text-decoration: none;
}

.rail-list a:hover { color: var(--accent); }

/* article */

.kicker {
  font-family: var(--display);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--accent);
  margin: 0 0 0.6rem;
}

.post h1, .page h1 {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(2rem, 6.5vw, 3.2rem);
  line-height: 1.0;
  letter-spacing: -0.01em;
  margin: 0 0 0.8rem;
}

.dek { font-size: 1.2rem; line-height: 1.45; color: var(--ink-soft); margin: 0 0 1.1rem; }

.byline {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  border-top: 2px solid var(--ink);
  border-bottom: 1px solid var(--line);
  padding: 0.7rem 0;
  margin: 0 0 1.75rem;
}

.lead-art { max-width: var(--max); margin: 0 auto 0; padding: 0 1.25rem; }

.lead-art .card-art { aspect-ratio: 21 / 9; }

.body h2 {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.6rem;
  line-height: 1.15;
  margin: 2.5rem 0 0.7rem;
}

.body h3 { font-family: var(--display); font-weight: 600; font-size: 1.2rem; margin: 1.9rem 0 0.5rem; }

.body p, .body li { margin: 0 0 1.05rem; }
.body ul, .body ol { padding-left: 1.2rem; }
.body a { color: var(--accent); }

.body table { width: 100%; border-collapse: collapse; font-size: 0.95rem; margin: 1.5rem 0; }

.body th, .body td {
  text-align: left;
  padding: 0.6rem 0.5rem;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.body th {
  font-family: var(--display);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
}

.table-scroll { overflow-x: auto; }

.note {
  background: var(--band);
  border-left: 3px solid var(--accent);
  padding: 0.95rem 1.1rem;
  margin: 0 0 1.75rem;
}

.note p { margin: 0; font-size: 0.95rem; }

/* embeds, click to load, nothing fetched until somebody presses play */

.embed {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #0a0a0d;
  overflow: hidden;
  margin: 1.75rem 0 0.5rem;
}

.embed iframe { width: 100%; height: 100%; border: 0; display: block; }

.embed-play {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  min-height: 44px;
  border: 0;
  cursor: pointer;
  color: #fff;
  background: linear-gradient(150deg, #241c2e, #0a0a0d);
  font: inherit;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 1rem;
}

.embed-play strong {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.1rem, 3vw, 1.6rem);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.embed-play span { color: #b8b2c4; font-size: 0.8rem; }

.embed-note { color: var(--ink-soft); font-size: 0.8rem; margin: 0 0 1.75rem; }

/* the 360 tour, same click to load idea, taller frame */

.tour { position: relative; aspect-ratio: 16 / 10; background: #0a0a0d; overflow: hidden; margin: 1.75rem 0 0.5rem; }

.tour iframe { width: 100%; height: 100%; border: 0; display: block; }

/* festival page */

.fest-hero {
  position: relative;
  min-height: 78vh;
  background: #0a0a0d;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
}

/* The picture is its own layer so it can be pushed independently of the card sitting on it.
   --s is written by the scroll loop. A slow push is what a title sequence does; it is not
   pretending to be 3D, it is just refusing to be a static banner. */
.fest-hero__img {
  position: absolute;
  inset: -2% -2%;
  background: #0a0a0d center / cover no-repeat;
  transform: scale(calc(1 + var(--s, 0) * 0.09)) translateY(calc(var(--s, 0) * -2.5%));
  will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
  .fest-hero__img { transform: none; }
}

.fest-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(6,5,10,0.34) 0%, rgba(6,5,10,0) 34%, rgba(6,5,10,0.92) 100%);
  opacity: calc(0.86 + var(--s, 0) * 0.14);
}

.fest-card {
  position: relative;
  z-index: 1;
  margin: 1.25rem;
  color: #fff;
  max-width: 34rem;
}

.fest-card h1 {
  font-family: var(--display);
  font-weight: 700;
  margin: 0 0 0.4rem;
  font-size: clamp(2.2rem, 9vw, 4rem);
  line-height: 0.92;
  letter-spacing: -0.015em;
  text-transform: uppercase;
}

.fest-when { margin: 0; font-family: var(--display); font-weight: 500; font-size: 1.05rem; }
.fest-where { margin: 0.15rem 0 0; color: #cfc9d6; font-size: 0.9rem; }

.credit {
  position: absolute;
  right: 0.9rem;
  bottom: 0.7rem;
  z-index: 1;
  margin: 0;
  max-width: 60%;
  text-align: right;
  color: rgba(255, 255, 255, 0.7);
  font-size: 0.7rem;
}

/* On a narrow screen there is no corner to spare. The credit stops floating and takes its
   own line under the card, which is also where a reader looks for it. */
@media (max-width: 47rem) {
  .fest-hero { flex-direction: column; justify-content: flex-end; align-items: stretch; }
  .credit {
    position: static;
    max-width: none;
    text-align: left;
    padding: 0 1.25rem 0.9rem;
    z-index: 1;
    font-size: 0.66rem;
  }
}

.crumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  font-family: var(--display);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  margin-bottom: 1rem;
}

.crumbs a { color: var(--accent); text-decoration: none; }
.crumbs > *:not(:last-child)::after { content: " /"; color: var(--line); }

.status {
  background: var(--band);
  border-left: 3px solid var(--accent);
  padding: 0.9rem 1.1rem;
  margin: 0 0 1.25rem;
  font-size: 0.95rem;
}

.info, .faq, .links, .sources {
  margin-top: 2.5rem;
  border-top: 2px solid var(--ink);
  padding-top: 1.25rem;
}

.info h2, .faq h2, .links h2, .sources h2 {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.95rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent);
  margin: 0 0 1rem;
}

.info table { width: 100%; border-collapse: collapse; font-size: 0.95rem; }

.info th {
  text-align: left;
  width: 9rem;
  padding: 0.55rem 0.5rem 0.55rem 0;
  border-bottom: 1px solid var(--line);
  color: var(--ink-soft);
  font-family: var(--display);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  vertical-align: top;
}

.info td { padding: 0.55rem 0; border-bottom: 1px solid var(--line); }

.tags { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 1rem 0 0; }

.tag {
  font-family: var(--display);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  border: 1px solid var(--line);
  padding: 0.3rem 0.7rem;
  color: var(--ink-soft);
}

.faq-item { border-bottom: 1px solid var(--line); padding-bottom: 1.1rem; margin-bottom: 1.1rem; }
.faq-item h3 { font-family: var(--display); font-weight: 600; font-size: 1.1rem; margin: 0 0 0.4rem; }
.faq-item p { margin: 0; }
.faq-src { margin-top: 0.45rem !important; font-size: 0.78rem; }
.faq-src a { color: var(--accent); }

.tickets { margin-top: 2rem; }

.buy, .button, .body a.button, .body a.buy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0.6rem 1.6rem;
  background: var(--accent);
  color: #fff;
  text-decoration: none;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.buy:hover, .button:hover, .body a.button:hover { filter: brightness(1.08); }

.affiliate { margin: 0.75rem 0 0; font-size: 0.78rem; color: var(--ink-soft); }

.links ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }

.links a {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0.4rem 0.9rem;
  border: 1px solid var(--line);
  text-decoration: none;
  font-family: var(--display);
  font-size: 0.92rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.links a:hover { border-color: var(--accent); color: var(--accent); }

.sources ol { padding-left: 1.2rem; margin: 0; }
.sources li { font-size: 0.9rem; margin-bottom: 0.5rem; word-break: break-word; }
.sources a { color: var(--accent); }
.checked { color: var(--ink-soft); font-size: 0.78rem; }

/* footer */

.foot {
  border-top: 2px solid var(--ink);
  margin-top: 3.5rem;
  padding: 2rem 1.25rem 3rem;
  color: var(--ink-soft);
  font-size: 0.88rem;
}

.foot > * { max-width: var(--max); margin-left: auto; margin-right: auto; }

.foot-name {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.4rem;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 0.5rem;
}

.foot p { margin: 0 0 0.55rem; }
.legal { font-size: 0.78rem; opacity: 0.85; }
.foot-links { display: flex; flex-wrap: wrap; gap: 1.2rem; margin-top: 1rem; }
.foot-links a, .sig a { color: var(--accent); }
.foot-links a { min-height: 44px; display: inline-flex; align-items: center; font-family: var(--display); text-transform: uppercase; font-size: 0.85rem; letter-spacing: 0.06em; }
.sig { margin-top: 1rem; font-size: 0.82rem; }

/* wider screens */

@media (min-width: 46rem) {
  .top { padding-left: 2rem; padding-right: 2rem; }
  .cards { grid-template-columns: repeat(3, 1fr); }
  .links ul { grid-template-columns: 1fr 1fr; }
  .fest-card { margin: 2.5rem; }
  .front { display: grid; grid-template-columns: 2fr 1fr; gap: 2.5rem; align-items: start; }
}

@media (min-width: 64rem) {
  .cards { grid-template-columns: repeat(4, 1fr); }
}

.hero-credit {
  position: absolute;
  right: 1rem;
  bottom: 1rem;
  z-index: 2;
  margin: 0;
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.5);
}


/* the masthead on a phone */
@media (max-width: 47rem) {
  .top {
    grid-template-columns: 1fr;
    row-gap: 0.1rem;
    padding: 0.7rem 1.1rem 0.5rem;
  }
  .wordmark { grid-column: 1; grid-row: 1; }
  .tagline { grid-column: 1; grid-row: 2; }
  .nav {
    grid-column: 1;
    grid-row: 3;
    justify-content: flex-start;
    flex-wrap: wrap;
    overflow-x: visible;
    gap: 0.15rem 1.05rem;
    margin-top: 0.15rem;
  }
  .nav a { min-height: 40px; }
  .nav a::after { bottom: 0.45rem; }
  .top.is-stuck .tagline { max-height: 0; opacity: 0; }
}


/* thumbs */
@media (max-width: 47rem) {
  .faq-src { margin-top: 0.3rem; }
  .faq-src a,
  .sources a,
  .crumbs a,
  .foot-links a {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    padding-right: 0.6rem;
  }
  .sources ol { display: grid; gap: 0.15rem; }
  .foot-links { display: flex; flex-wrap: wrap; column-gap: 1.1rem; }
  .card-art + .card-kicker { margin-top: 0.6rem; }

  /* The numbered festival list on the front page is eight straight navigation targets in a
     column, 24px apart. That is the hardest thing on the site to hit with a thumb. */
  .rail-list a { display: flex; align-items: center; min-height: 44px; }
  .rail-list li { align-items: center; }

  .nav a.switch { min-height: 40px; padding-block: 0.5rem; }
}


/* the front page hero on a tall screen, restated last so it wins on source order */
@media (max-aspect-ratio: 1/1) {
  .hero-stage .hero-lines {
    position: static;
    inset: auto;
    padding: 0 1.1rem;
    max-width: none;
    margin: 0;
  }

  /* The planet is cut off at the bottom in the film itself, the crowd runs straight off the
     frame edge, and no crop or scale brings back pixels that were never shot. So the lower
     edge is dissolved into the page instead of stopping in a hard line. */
  /* A gradient laid on top, not a mask cut out of it. Safari can drop a video entirely
     when its container is masked, and a hero that renders nothing on an iPhone is a far
     worse trade than the one pixel of accuracy a real mask would buy. The colour is the
     film's own corner sky, so the picture ends in night rather than in an edge. */
  .hero-stage .hero-pic { -webkit-mask-image: none; mask-image: none; }
  .hero-stage .hero-pic::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 32%;
    z-index: 2;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(4,15,27,0) 0%, #040f1b 92%);
  }

  .hero-stage .hero-cue { display: none; }

  /* A phone was scrolling nearly three screens of nothing before the first story. The tall
     pinned track exists so a mouse wheel can drive the camera; a thumb does not need it.
     So on a phone the hero is an ordinary block that scrolls away and the stories follow
     it immediately. The lines still move, measured against the hero itself. */
  .hero-track { height: auto; }
  .hero-stage {
    position: static;
    height: 86vh;
    height: 86svh;
  }
}

/* interviews

   The question is display type and the answer is body type, so the eye can tell at a glance
   who is speaking without reading a word. That is the whole design. */

.is-interview .dek {
  font-size: 1.15rem;
  color: var(--ink-soft);
  max-width: var(--text);
  margin: 0 0 1.4rem;
}

.portrait { margin: 0 0 2rem; }
.portrait img { width: 100%; height: auto; }
.portrait .credit {
  position: static;
  max-width: none;
  text-align: left;
  color: var(--ink-soft);
  font-size: 0.75rem;
  margin: 0.4rem 0 0;
}

.interview { max-width: var(--text); margin: 2rem auto 0; }

.qa { padding: 1.6rem 0; border-top: 1px solid var(--line); }
.qa:first-child { border-top: 2px solid var(--ink); }

.q {
  position: relative;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.15rem, 3.6vw, 1.45rem);
  line-height: 1.25;
  margin: 0 0 0.9rem;
  padding-left: 2.4rem;
}

/* The number is the interviewer's voice made small, so it never competes with the answer. */
.qn {
  position: absolute;
  left: 0;
  top: 0.1em;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.a { padding-left: 2.4rem; }
.a p { margin: 0 0 0.9rem; }
.a p:last-child { margin-bottom: 0; }

.no-answer {
  color: var(--ink-soft);
  font-style: italic;
}

@media (max-width: 47rem) {
  .q, .a { padding-left: 1.7rem; }
}
