/* ============================================================
   FONTS
   ============================================================ */
@font-face {
  font-family: "Manege";
  src: url("../fonts/ManegeLight.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Garamond MT";
  src: url("../fonts/GaramondMT-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Garamond MT";
  src: url("../fonts/GaramondMT-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Garamond MT";
  src: url("../fonts/GaramondMT-Italic.woff2") format("woff2");
  font-weight: 500;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "PP Editorial New";
  src: url("../fonts/PPEditorialNew-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Suisse Intl Medium";
  src: url("../fonts/SuisseIntl-Medium-WebM.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Suisse Intl Medium";
  src: url("../fonts/SuisseIntl-MediumIt.woff2") format("woff2");
  font-weight: 500;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Suisse Intl Regular";
  src: url("../fonts/SuisseIntl-Regular-WebM.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Suisse Intl Regular";
  src: url("../fonts/SuisseIntl-RegularIt.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

/* ============================================================
   DESIGN TOKENS
   ============================================================ */
:root {
  --design-width: 1920;

  /* Font families */
  --font-medium: "Suisse Intl Medium", sans-serif;
  --font-regular: "Suisse Intl Regular", sans-serif;
  --font-serif: "Garamond MT", serif;
  --font-display: "Garamond MT", serif;
  --f-editorial: "PP Editorial New", serif;

  /* Desktop SuisseIntl font sizes — the 5 sizes used on desktop. */
  --f-desk-huge: 3.7rem;
  --f-desk-big: 2.4rem;
  --f-desk-normal: 2.2rem;
  --f-desk-small: 1.6rem;
  --f-desk-tiny: 1.3rem;

  /* Mobile SuisseIntl font sizes — the 5 sizes used on mobile. */
  --f-mobile-huge: 1.8rem;
  --f-mobile-big: 1.8rem;
  --f-mobile-normal: 1.6rem;
  --f-mobile-small: 1.3rem;
  --f-mobile-tiny: 1.1rem;

  /* Per-size letter-spacing + line-height — each size is a full type style.
     Unit-relative, so shared across desktop/mobile. Edited live by the debug
     panel. No SuisseIntl body element sets its own ls/lh; it comes from here. */
  --f-huge-ls: -0.04em;
  --f-huge-lh: 1.15;
  --f-big-ls: -0.01em;
  --f-big-lh: 1.1;
  --f-normal-ls: 0;
  --f-normal-lh: 1.2;
  --f-small-ls: 0;
  --f-small-lh: 1;
  --f-tiny-ls: 0;
  --f-tiny-lh: 1.1;

  /* Type scale — semantic sizes routed through the 4 desktop sizes above
     (mobile values are overridden in the @media (max-width:1024px) block) */
  --f-huge-size: var(--f-desk-huge); /* full-view header big text */
  --f-main-size: var(--f-desk-normal); /* body copy: .text-main, p, li, h2 */
  --f-main-lh: var(--f-normal-lh);
  --f-main-ls: var(--f-normal-ls);
  --f-h1-size: var(--f-desk-big);
  --f-h1-lh: var(--f-big-lh);
  --f-h1-ls: var(--f-big-ls);
  --f-card-title-size: var(--f-desk-big);
  --f-card-title-lh: var(--f-big-lh);
  --f-card-title-ls: var(--f-big-ls);
  --f-card-meta-size: var(--f-desk-small);
  --f-card-meta-lh: var(--f-small-lh);
  --f-card-meta-ls: var(--f-small-ls);
  --f-label-size: var(--f-desk-tiny);
  --f-label-large-size: var(--f-desk-small);
  --f-label-lh: var(--f-tiny-lh);
  --f-label-ls: var(--f-tiny-ls);
  /* Decorative / display fonts (Garamond MT, Manège, PP Editorial New) live in
     their OWN size scale, fully independent of the 4 SuisseIntl sizes above.
     Changing a SuisseIntl size/ls/lh must never affect these. Mobile values are
     overridden with independent literals in the @media block below. */
  --f-display-xl-size: 25rem;
  --f-display-l-size: 12.8rem;
  --f-display-m-size: 9.6rem;
  --f-display-s-size: 6.4rem;

  /* Letter spacing */
  --ls-tight: -0.08em; /* cards, tabs, meta, drawer header, side label */
  --ls-normal: -0.04em; /* display text, menu links */

  /* Layout */
  --page-padding-left: 11.2rem;
  --page-bg: #fff;
  --page-header-size: var(
    --f-desk-big
  ); /* h1 on info pages (visit, press, colophon…) */

  /* 3D card/box shadow */
  --shadow-depth: 1.2rem;
  --shadow-corner: 1.9rem;

  /* Spacing rhythms */
  --section-gap: 2.4rem; /* margin between page sections */
  --expanded-gap: 4rem; /* spacing inside expanded panels */

  /* Full-view close (X): matches the projects accordion plus/X icon size. */
  --close-x-size: 8rem;

  /* Tab bars (date squares, year links) */
  --tab-height: 3.2rem;
  --tab-width: 13.3rem;

  /* Custom scrollbar */
  --scrollbar-w: 1.65rem;
  --scrollbar-w-mobile: 0.8rem;
}

html {
  font-size: calc(100vw / var(--design-width) * 10);
}

@media (max-width: 1024px) {
  :root {
    --design-width: 375;
    --f-huge-size: var(--f-mobile-huge); /* full-view header big text */
    --f-huge-lh: 1.15;
    --f-huge-ls: 0;
    --f-main-size: var(
      --f-mobile-normal
    ); /* body copy (.text-main, p, li, h2) */
    --f-h1-size: var(--f-mobile-big);
    --f-card-title-size: var(--f-mobile-big);
    --f-card-meta-size: var(--f-mobile-big);
    --f-label-size: var(--f-mobile-small);

    /* Decorative display sizes — independent literals, NOT tied to the
       SuisseIntl mobile sizes. (The home/theme elements that use these also
       set their own explicit mobile sizes, so these are the safe fallbacks.) */
    --f-display-xl-size: 7.2rem;
    --f-display-l-size: 4.2rem;
    --f-display-m-size: 3.6rem;
    --f-display-s-size: 3.6rem;
  }
}

/* ============================================================
   BASE
   ============================================================ */
* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
  font-family: var(--font-regular);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  background-color: #fff;
  color: #000;
  min-height: 100vh;
  font-variant-emoji: text;
}

a {
  color: inherit;
  text-decoration: none;
}

/* No bold weight is loaded — map bold semantic tags to the medium font (500) */
strong,
b {
  font-family: var(--font-medium);
  font-weight: 500;
}

/* Links always take the surrounding text colour (no default blue/visited purple) */
a {
  color: inherit;
}

/* CMS rich-text links: the editor can emit an inline colour on the link OR on a
   span inside it, so force inherit on the link and its descendants. */
.cms-content a,
.cms-content a *,
.description-text a,
.description-text a *,
.expanded-description a,
.expanded-description a *,
.expanded-bio a,
.expanded-bio a *,
.expanded-full-content a,
.expanded-full-content a *,
.expanded-list-text a,
.expanded-list-text a *,
.curator a,
.curator a * {
  color: inherit !important;
}

/* CMS rich-text spans: the editor saves inline colour on every span; force
   inherit so dark-background expanded views (archive, events, news) show white.
   .expanded-section and .expanded-body are needed because <p class="expanded-list-text">
   wrapping a <p> is invalid HTML — browsers auto-close the outer <p> immediately,
   leaving the inner <p> as a sibling outside .expanded-list-text. */
.cms-content span,
.description-text span,
.expanded-description span,
.expanded-bio span,
.expanded-full-content span,
.expanded-list-text span,
.expanded-section span,
.expanded-body span,
.curator span {
  color: inherit !important;
}

/* CMS headings (h1/h2/h3 in rich text) → the "big" type style */
.cms-content :is(h1, h2, h3),
.description-text :is(h1, h2, h3),
.expanded-description :is(h1, h2, h3),
.expanded-bio :is(h1, h2, h3),
.expanded-full-content :is(h1, h2, h3),
.expanded-list-text :is(h1, h2, h3),
.curator :is(h1, h2, h3) {
  font-family: var(--font-medium);
  font-weight: 500;
  font-size: var(--f-h1-size);
  line-height: var(--f-big-lh);
  letter-spacing: var(--f-big-ls);
}

/* ============================================================
   TYPOGRAPHY CLASSES
   ============================================================ */
.text-main,
p,
li {
  font-family: var(--font-regular);
  font-size: var(--f-main-size);
  line-height: var(--f-main-lh);
  letter-spacing: var(--f-main-ls);
  margin: 0;
}
.text-main-medium,
h2 {
  font-family: var(--font-medium);
  font-weight: 500;
  font-size: var(--f-main-size);
  line-height: var(--f-main-lh);
  letter-spacing: var(--f-main-ls);
  margin: 0;
}
.text-h1,
h1 {
  font-family: var(--font-medium);
  font-weight: 500;
  font-size: var(--f-h1-size);
  line-height: var(--f-h1-lh);
  letter-spacing: var(--f-h1-ls);
  margin: 0;
}
.text-card-title {
  font-family: var(--font-regular);
  font-size: var(--f-card-title-size);
  line-height: var(--f-card-title-lh);
  letter-spacing: var(--f-card-title-ls);
  margin: 0;
}
.text-card-meta {
  font-family: var(--font-regular);
  font-size: var(--f-card-meta-size);
  line-height: var(--f-card-meta-lh);
  letter-spacing: var(--f-card-meta-ls);
  margin: 0;
}
.text-label {
  font-family: var(--font-regular);
  font-size: var(--f-label-size);
  line-height: var(--f-label-lh);
  letter-spacing: var(--f-label-ls);
  margin: 0;
}
.text-label-medium {
  font-family: var(--font-medium);
  font-weight: 500;
  font-size: var(--f-label-size);
  line-height: var(--f-label-lh);
  letter-spacing: var(--f-label-ls);
  margin: 0;
}
.text-display-xl {
  font-family: var(--font-serif);
  font-weight: 500;
  font-style: italic;
  font-size: var(--f-display-xl-size);
  line-height: 0.77;
  margin: 0;
}
.text-display-l {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--f-display-l-size);
  letter-spacing: var(--ls-normal);
  margin: 0;
}
.text-display-m {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--f-display-m-size);
  margin: 0;
}
.text-display-s {
  font-family: var(--f-editorial);
  font-weight: 400;
  font-size: var(--f-display-s-size);
  margin: 0;
}

/* ============================================================
   LAYOUT UTILITIES
   ============================================================ */
.box-3d {
  background-color: #fff;
  position: relative;
  isolation: isolate;
}
.box-3d::after {
  content: "";
  position: absolute;
  z-index: -1;
  bottom: calc(-1 * var(--shadow-depth));
  /* left flush with the card edge so the fold vertex never pokes left of it */
  left: 0;
  right: calc(-1 * var(--shadow-depth));
  /* +1px tucks the top edge under the card so sub-pixel rounding can't leave a gap */
  height: calc(var(--shadow-depth) + 1px);
  background-color: #000;
  clip-path: polygon(0 0, 100% 0, 100% 100%, var(--shadow-corner) 100%);
}
.box-3d::before {
  content: "";
  position: absolute;
  z-index: -1;
  /* top flush with the card edge so the fold vertex never pokes above it */
  top: 0;
  right: calc(-1 * var(--shadow-depth));
  bottom: -1px;
  /* +1px tucks the left edge under the card so sub-pixel rounding can't leave a gap */
  width: calc(var(--shadow-depth) + 1px);
  background-color: #000;
  clip-path: polygon(0 0, 100% var(--shadow-corner), 100% 100%, 0 100%);
}

/* ============================================================
   LAYOUT – MOBILE HEADER BAR
   ============================================================ */
main {
  width: 100%;
  min-height: 100vh;
}

.mobile-header-bar {
  display: none;
}
@media (max-width: 1024px) {
  .mobile-header-bar {
    display: block;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 5.6rem;
    background-color: var(--page-bg);
    z-index: 3500;
  }
}

/* ============================================================
   BODY CROSS PATTERN (home page only)
   ============================================================ */
.body-cross-pattern {
  display: none;
  position: fixed;
  top: 0;
  left: 14rem;
  width: calc(100% - 14rem);
  height: 100%;
  background-image: url("../assets/cross_pattern_white.png");
  background-repeat: repeat;
  z-index: -1;
  pointer-events: none;
}
@media (max-width: 1024px) {
  .body-cross-pattern {
    display: none !important;
  }
}

/* ============================================================
   PAGE SCROLL CONTAINERS – shared hide-scrollbar rule
   ============================================================ */
.programme-page,
.visit-page,
.awareness-page,
.press-page,
.colophon-page,
.news-page,
.events-page-container,
.projects-page,
.archive-page,
.contact-page,
.about-page {
  width: 100%;
  height: 100vh;
  height: var(--app-height, 100dvh); /* track the visible viewport, not the toolbar-collapsed 100vh — see setAppHeight() in app.js */
  overflow-y: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.programme-page::-webkit-scrollbar,
.visit-page::-webkit-scrollbar,
.awareness-page::-webkit-scrollbar,
.press-page::-webkit-scrollbar,
.colophon-page::-webkit-scrollbar,
.news-page::-webkit-scrollbar,
.events-page-container::-webkit-scrollbar,
.projects-page::-webkit-scrollbar,
.archive-page::-webkit-scrollbar,
.contact-page::-webkit-scrollbar,
.about-page::-webkit-scrollbar {
  display: none;
}

/* ============================================================
   LOGO COMPONENT
   ============================================================ */
.logo-link {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 4000;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
  width: 8.4rem;
  height: 8rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.logo-svg {
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}

/* @property declarations kept as no-JS fallback (Chrome only).
   Firefox does not reliably re-evaluate SVG stroke-dash* when custom
   properties change, so the real animation is driven by initLogoAnimation()
   in app.js which overrides these with style.animation = 'none'. */
@property --logo-head {
  syntax: "<number>";
  initial-value: 0;
  inherits: false;
}
@property --logo-tail {
  syntax: "<number>";
  initial-value: 50;
  inherits: false;
}

.logo-snake {
  stroke-dasharray: var(--logo-tail) calc(1000 - var(--logo-tail));
  stroke-dashoffset: calc(var(--logo-tail) - var(--logo-head));
  animation:
    logo-snake-head 5s linear infinite,
    logo-snake-tail 8s linear infinite;
}
@keyframes logo-snake-head {
  from {
    --logo-head: 0;
  }
  to {
    --logo-head: 1000;
  }
}
@keyframes logo-snake-tail {
  /* No-JS fallback (Chrome only — Firefox is handled by initLogoAnimation in app.js).
     0–7%   steep burst: tail falls immediately behind after minimum
     7–52%  linear drag
     52–65% easing out to max
     65–80% flat at max
     80–97% ease-in catch-up → minimum at 97%
     97–100% brief minimum (~0.24 s) */
  0% {
    --logo-tail: 50;
    animation-timing-function: linear;
  }
  55% {
    --logo-tail: 720;
    animation-timing-function: cubic-bezier(0.2, 0.4, 0.5, 1);
  }
  67% {
    --logo-tail: 780;
    animation-timing-function: linear;
  }
  82% {
    --logo-tail: 780;
    animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
  }
  97% {
    --logo-tail: 50;
    animation-timing-function: linear;
  }
  100% {
    --logo-tail: 50;
  }
}
@media (prefers-reduced-motion: reduce) {
  .logo-snake {
    animation: none;
    stroke-dasharray: 650 350;
    stroke-dashoffset: 0;
  }
}
@media (max-width: 1024px) {
  .logo-link {
    top: 0.5rem;
    width: 5.25rem;
    height: 5rem;
  }
}

/* ============================================================
   MENU COMPONENT
   ============================================================ */
.drawer {
  position: fixed;
  top: 0;
  left: -20%;
  width: 20%;
  height: 100vh;
  height: 100dvh;
  height: var(--app-height, 100dvh);
  background: #fff;
  z-index: 5000;
  transition: left 0.4s cubic-bezier(0.16, 1, 0.3, 1);
  padding: 3rem 0 2rem;
  display: flex;
  flex-direction: column;
}
.drawer.no-transition {
  transition: none !important;
}
.drawer.open {
  left: 0;
}

#menu-close {
  position: absolute;
  top: 2rem;
  right: 2rem;
  background: none;
  border: none;
  font-size: 4rem;
  cursor: pointer;
  line-height: 1;
  display: none;
}
@media (max-width: 1024px) {
  #menu-close {
    display: none;
  }
}

/* header is an <a> (link to home) — .drawer a must not override its type styles */
.drawer a.drawer-header {
  font-family: "PP Editorial New", serif;
  font-size: 12rem;
  font-weight: 400;
  line-height: 91%;
  letter-spacing: var(--ls-tight);
  text-align: left;
  padding-left: 0.6rem;
  margin-bottom: var(--expanded-gap);
  user-select: none;
}
.menu-groups {
  display: flex;
  flex-direction: column;
  gap: 3.5rem;
}
ul.group {
  list-style: none;
  margin: 0;
  padding: 0 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
ul.group li {
  margin: 0;
  padding: 0;
}
.drawer a {
  text-decoration: none;
  color: #000;
  font-family: "Suisse Intl Regular", sans-serif;
  font-size: 4rem;
  font-weight: 400;
  line-height: 1;
  letter-spacing: var(--ls-normal);
  display: block;
  transition: opacity 0.2s ease;
}
.drawer a.bold {
  font-family: "Suisse Intl Medium", sans-serif;
  font-weight: 500;
}
/* The drawer body holds the nav groups with the search panel layered over them.
   --search-bar-h is the resting height of the panel (just the input row); it is
   defined here so both the panel and the groups (which pad their bottom to clear
   it) can read it. */
.drawer-body {
  /* A bit taller than the input row itself so the focus underline (which sits at
     the row's bottom edge) clears the panel's overflow clip while resting. */
  --search-bar-h: 5rem;
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.drawer-body .menu-groups {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: none;
  padding-bottom: var(--search-bar-h); /* keep the last link clear of the resting bar */
}
.drawer-body .menu-groups::-webkit-scrollbar {
  display: none;
}

/* Rests as a bottom bar; grows to full height when a search is open. */
.search-panel {
  --search-font-size: 3.2rem;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--search-bar-h);
  background: #fff;
  display: flex;
  flex-direction: column;
  padding: 0 1.5rem;
  overflow: hidden;
  transition: height 0.45s cubic-bezier(0.16, 1, 0.3, 1);
}
.drawer.search-open .search-panel {
  height: 100%;
}
.search-bar {
  order: 3;
  flex: 0 0 auto;
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding-bottom: 0.6rem;
  margin-top: auto;
}
/* Underline draws in from the left when the field gains focus. */
.search-bar::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: #000;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.4s ease;
}
.search-bar:focus-within::after,
.drawer.search-open .search-bar::after {
  transform: scaleX(1);
}
.search-input {
  flex: 1 1 auto;
  min-width: 0;
  border: none;
  background: transparent;
  outline: none;
  color: #000;
  font-family: "Suisse Intl Regular", sans-serif;
  font-size: var(--search-font-size);
  font-weight: 400;
  line-height: 1;
  letter-spacing: var(--ls-normal);
  padding: 0;
}
/* "Search" reads as normal black menu text at rest, then fades to light gray
   once the field is focused (and disappears entirely as soon as you type). */
.search-input::placeholder {
  color: #000;
  opacity: 1;
  transition: opacity 0.3s ease;
}
.search-input:focus::placeholder {
  opacity: 0.35;
}
.search-input::-webkit-search-decoration,
.search-input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}
/* The language toggle and the close X share the same right-hand slot. The FI sits
   in flow (defining the slot's width); the X is overlaid on top, so they can
   cross-fade in place when the search is activated. */
.search-bar-end {
  flex: none;
  position: relative;
  display: flex;
  align-items: baseline;
}
.search-bar .lang-selector {
  font-family: "Suisse Intl Regular", sans-serif;
  font-size: 3.2rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: opacity 0.3s ease;
}
.search-clear {
  position: absolute;
  right: 0;
  bottom: 0;
  background: none;
  border: none;
  padding: 0;
  line-height: 0;
  cursor: pointer;
  color: #000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}
/* Same X as the full-view close button, sized to the search box text height. */
.search-clear svg {
  display: block;
  width: 2.8rem;
  height: 2.8rem;
}
/* Activation sequence (while the search bar holds focus): once the underline has
   finished drawing (0.4s), fade the language selector out, then bring the close X
   in — parked at the end of the bar. On blur it reverts immediately: X out, FI
   back in. */
.search-bar:focus-within .lang-selector,
.drawer.search-open .search-bar .lang-selector {
  opacity: 0;
  pointer-events: none;
  transition-delay: 0.4s;
}
.search-bar:focus-within .search-clear,
.drawer.search-open .search-clear {
  opacity: 1;
  pointer-events: auto;
  transition-delay: 0.7s;
}

.search-results {
  order: 1;
  flex: 0 1 auto;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
  scrollbar-width: none;
  opacity: 0;
  transition: opacity 0.3s ease 0.12s;
}
.search-results::-webkit-scrollbar {
  display: none;
}
.drawer.search-open .search-results {
  opacity: 1;
}
.drawer .search-result {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  font-family: "Suisse Intl Regular", sans-serif;
  font-size: var(--search-font-size);
  font-weight: 400;
  line-height: 1;
  letter-spacing: var(--ls-normal);
}
.drawer .search-result-label {
  flex: 1 1 auto;
  min-width: 0;
  word-break: break-word;
}
.drawer .search-result-section {
  flex: none;
  font-family: var(--font-medium);
  font-size: 1.6rem;
  font-weight: 500;
  letter-spacing: var(--ls-normal);
  color: #000;
  opacity: 1;
}
.search-empty {
  font-family: "Suisse Intl Regular", sans-serif;
  font-size: 2.4rem;
  letter-spacing: var(--ls-normal);
  opacity: 0.45;
  margin: 0;
  padding-top: 0.5rem;
}
.search-pagination {
  order: 2;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2rem;
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
  opacity: 0;
  transition: opacity 0.3s ease 0.12s;
}
.drawer.search-open .search-pagination {
  opacity: 1;
}
.search-pagination:empty {
  display: none;
}
.search-page-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: #000;
  font-family: "Suisse Intl Regular", sans-serif;
  font-size: 3.2rem;
  line-height: 1;
}
.search-page-btn[disabled] {
  opacity: 0.3;
  cursor: default;
}
.search-page-info {
  font-family: "Suisse Intl Regular", sans-serif;
  font-size: 2rem;
  letter-spacing: var(--ls-normal);
}

@media (max-width: 1024px) {
  .drawer {
    width: 100%;
    left: -100%;
    padding: 2vh 0 2vh;
  }
  .drawer-body {
    --search-bar-h: 6vh;
  }
  .search-panel {
    --search-font-size: 2.8vh;
    padding: 0 2rem;
  }
  .search-bar {
    margin-top: auto;
  }
  .search-results {
    gap: 1.4vh;
  }
  .search-bar .lang-selector {
    font-size: 2.8vh;
  }
  .search-clear svg {
    width: 3.2vh;
    height: 3.2vh;
  }
  .drawer .search-result-section {
    font-size: 1.8vh;
  }
  .search-empty {
    font-size: 2.8vh;
  }
  .search-page-btn {
    font-size: 3.5vh;
  }
  .search-page-info {
    font-size: 2.2vh;
  }
  .drawer.open {
    left: 0;
  }
  .drawer a.drawer-header {
    font-size: 11vh;
    margin-bottom: 3vh;
    padding-left: 2rem;
  }
  .menu-groups {
    gap: 1vh;
  }
  ul.group {
    padding: 0 2rem;
    gap: 0.1vh;
  }
  .drawer a {
    font-size: 4.5vh;
  }
}

/* ============================================================
   SIDE LABEL COMPONENT
   ============================================================ */
.side-label {
  position: fixed;
  bottom: 1.6rem;
  left: 0;
  font-family: "PP Editorial New", serif;
  font-size: 6.4rem;
  font-weight: 400;
  line-height: 91%;
  letter-spacing: var(--ls-tight);
  color: #000;
  z-index: 4500;
  writing-mode: vertical-rl;
  user-select: none;
  pointer-events: none;
}
@media (max-width: 1024px) {
  .side-label {
    top: 1.6rem;
    right: 1.6rem;
    bottom: auto;
    left: auto;
    font-size: 4rem;
    writing-mode: horizontal-tb;
  }
}

/* ============================================================
   HTMX TRANSITION
   ============================================================ */
#main-content {
  transition: opacity 0.15s ease;
}
#main-content.htmx-swapping {
  opacity: 0;
}
@media (hover: none), (pointer: coarse), (max-width: 1024px) {
  #cursor-trail {
    display: none !important;
  }
}

/* ============================================================
   HOME PAGE
   ============================================================ */
/* Home is a non-scrolling, fit-to-screen page. applyPageState() sets
   body overflow:hidden from data-body-overflow, but that only runs once app.js
   has loaded — long enough for the native scrollbar to flash on a full reload.
   Hiding it in CSS (matched at first paint via :has) prevents that flash. */
html:has([data-page="home"]),
body:has([data-page="home"]) {
  overflow: hidden;
}
.home-container {
  height: 100vh;
  height: 100dvh;
  height: var(--app-height, 100dvh); /* JS-measured viewport height; see setAppHeight() in app.js */
  width: 100%;
  display: grid;
  place-items: center;
  position: relative;
  text-align: center;
  margin: 0;
  padding: 0;
  isolation: isolate;
  -webkit-user-select: none;
  user-select: none;
}
/* While the water effect is live, suppress the browser's touch gestures over the
   home page so a finger-drag streams pointermove events (for the ripple) instead
   of being claimed as a pan. Scoped to .home-container so the menu drawer's own
   scrolling is unaffected. */
body.home-water-active .home-container {
  touch-action: none;
}
/* Layer 1: background photo */
.home-bg {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
}
.home-bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Layer 2: line-art overlay — sits over the photo but inset from the sides so
   it reads a touch smaller than the full-bleed photo beneath it */
.home-bg-line {
  position: absolute;
  inset: var(--home-line-pad-y, 10rem) var(--home-line-pad, 20rem);
  z-index: 2;
  width: auto;
  height: 100%;
  object-fit: contain;
  transform: translateY(-8rem);
  display: block;
  pointer-events: none;
}
/* Three.js water ripple layer (js/home-water.js): an opaque WebGL canvas that
   renders a refracted copy of the photo + line + bubbles + text. */
.home-water {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  overflow: hidden;
}
.home-water canvas {
  display: block;
  width: 100%;
  height: 100%;
}
/* Bubbles overlay: over the photo/line/cursor layers but below the text
   (z 4, text is z 10) so it never hides the title or the festival date.
   Inset from all edges (padding) so the bubble field reads a little smaller. */
.home-bubbles {
  position: absolute;
  inset: 0;
  z-index: 4;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  padding: var(--home-bubbles-pad, 5.5rem);
  object-fit: contain;
  display: block;
  pointer-events: none;
}
.top-text {
  position: absolute;
  top: 1rem;
  width: 100%;
  margin: 0;
  z-index: 10;
  padding: 0 1.2rem;
}
.top-text h1 {
  font-family: "Garamond MT", serif;
  font-weight: 400;
  font-style: normal;
  font-size: 19rem;
  letter-spacing: -0.09em;
  color: #fff;
  margin: 0;
  line-height: 0.8;
}
.middle-text {
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
  z-index: 10; /* above the smudge canvas (z 0), like the other text layers */
}
.middle-text h2 {
  font-family: "Garamond MT", serif;
  font-weight: 500;
  font-style: italic;
  font-size: 39rem;
  letter-spacing: var(--ls-normal);
  color: #fff;
  margin: 0;
  line-height: 0.9;
}
/* faint outer glow (blue) around the text — just enough to keep the white
   type legible on light parts of the artwork, no more */
.top-text h1,
.middle-text h2,
.bottom-text p {
  text-shadow: 0 0 0.35rem rgba(67, 112, 249, 0.55);
}
.bottom-text {
  position: absolute;
  /* span from the left sidebar to the right edge, 1rem above the bottom */
  left: var(--page-padding-left);
  right: 0;
  bottom: 1rem;
  margin: 0;
  z-index: 10; /* in the text layer, above the bubbles overlay */
  padding: 0;
}
.bottom-text p {
  font-family: "Manege", sans-serif;
  font-weight: 300;
  font-style: normal;
  /* big enough to run the full width of the band */
  font-size: 15rem;
  white-space: nowrap;
  letter-spacing: var(--ls-normal);
  color: #fff;
  margin: 0;
  line-height: 0.7;
  letter-spacing: -0.05em;
}
body.home-water-active .top-text h1,
body.home-water-active .middle-text h2,
body.home-water-active .bottom-text p {
  color: transparent;
  text-shadow: none;
}
@media (min-width: 1025px) {
  .top-text {
    left: 50%;
    right: auto;
    width: 100vw;
    transform: translateX(-50%);
  }
  .middle-text {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 100vw;
    transform: translate(-50%, -50%);
  }
  .bottom-text {
    left: 50%;
    right: auto;
    width: 100vw;
    transform: translateX(-50%);
  }
}
@media (max-width: 1024px) {
  html:has([data-page="home"]),
  body:has([data-page="home"]) {
    height: 100dvh;
    height: var(--app-height, 100dvh);
    overflow: hidden;
  }
  #main-content:has([data-page="home"]),
  [data-page="home"] {
    height: 100dvh;
    height: var(--app-height, 100dvh);
    overflow: hidden;
  }
  .home-container {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    width: 100vw;
    min-width: 100vw;
    height: 100vh;
    height: 100dvh;
    height: var(--app-height, 100dvh);
    /* keep the festival-date footer clear of the mobile browser chrome */
    padding: 6.5rem 0 4rem;
  }
  .home-bg,
  .home-bg img,
  .home-bg-line,
  .home-bubbles {
    width: 100vw;
    min-width: 100vw;
  }
  .home-bg img {
    object-position: left center;
  }
  .home-bg-line {
    inset: auto;
    left: 50%;
    top: 50%;
    width: auto;
    min-width: 0;
    height: 100dvh;
    height: var(--app-height, 100dvh);
    max-width: none;
    transform: translate(-50%, -50%);
  }
  .home-bubbles {
    inset: auto;
    left: auto;
    right: 0;
    top: 39%;
    width: auto;
    min-width: 0;
    height: 112dvh;
    min-height: 112dvh;
    max-width: none;
    padding: 0;
    object-fit: contain;
    transform: translateY(-50%) rotate(0deg);
  }
  .top-text,
  .middle-text,
  .bottom-text {
    position: relative;
    top: auto;
    bottom: auto;
    left: auto;
    right: auto;
    width: 100vw;
    margin-left: 0;
    margin-right: 0;
    padding-left: 0;
    padding-right: 0;
    text-align: center;
    align-items: center;
  }
  .top-text h1 {
    font-size: 8rem;
    line-height: 0.8;
    letter-spacing: -0.06em;
    white-space: normal;
    width: 100%;
  }
  .middle-text h2 {
    font-size: 16rem;
    line-height: 0.9;
    letter-spacing: -0.065em;
    width: 100%;
    text-align: center;
    transform: translateX(-1rem);
  }
  .bottom-text {
    width: 100%;
  }
  .bottom-text p {
    font-size: 6rem;
    letter-spacing: -0.07em;
    white-space: normal;
    width: 100%;
    display: block;
    line-height: 1;
    margin-bottom: -0.5em;
  }
}

/* ============================================================
   THEME PAGE
   ============================================================ */
/* ============================================================
   THEME PAGE — "Unknown Territories"
   Stacked layers (bottom → top):
     1. .theme-bg     background photo, object-fit: cover
     2. .theme-lines  vector lines, object-fit: cover
     3. .theme-globe  globe, centered, object-fit: contain
     4. .theme-corner four corner labels, edge-aligned to each other
     5. .theme-content title + body text in white, scrollable
   --corner-gap controls the inset of the corner labels (tweak freely).
   ============================================================ */
.theme-page {
  position: relative;
  width: 100%;
  height: 100vh;
  height: var(--app-height, 100dvh);
  overflow: hidden;
  background-color: #000;
  --corner-gap: 4rem;
  /* top corners sit higher than the bottom ones (≈half the inset) */
  --corner-gap-top: 2rem;
  /* left corners are pushed in further so they clear the left sidebar */
  --corner-gap-left: 7rem;
}

.custom-scrollbar {
  position: fixed;
  top: 0;
  right: 0;
  width: var(--scrollbar-w);
  height: 100vh;
  height: var(--app-height, 100dvh);
  background: transparent;
  z-index: 2000;
  /* display is set to block via inline style in the PHP helper as soon as the
     element is rendered, so there is no flash of missing scrollbar */
}
.custom-scrollbar-thumb {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  cursor: pointer;
}
/* On mobile, start the scrollbar below the fixed header bar (logo + DRIFTS, 5.6rem)
   so the thumb never overlaps it. The thumb JS uses the track's clientHeight. */
@media (max-width: 1024px) {
  .custom-scrollbar {
    width: var(--scrollbar-w-mobile);
    top: 5.6rem;
    height: calc(100vh - 5.6rem);
    height: calc(var(--app-height, 100dvh) - 5.6rem);
  }
}
/* Scrollbars on pages with expanded overlays must sit above them */
.archive-scrollbar {
  z-index: 8500;
} /* above gallery-view (4000) and expanded (7000) */
.programme-scrollbar {
  z-index: 8000;
}
.news-scrollbar,
.events-scrollbar {
  z-index: 8000;
  background: transparent;
}

/* Layer 1: background photo — covers the page, aspect ratio preserved (cover crops the overflow) */
.theme-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  pointer-events: none;
}
/* Layer 2: vector lines — also cover the page, aspect ratio preserved */
.theme-lines {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 1;
  filter: brightness(1.14) contrast(1.04);
  pointer-events: none;
}
/* Layer 3: second line graphic — also cover the page, aspect ratio preserved */
.theme-line {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 2;
  pointer-events: none;
}
/* Layer 4: globe — centered, aspect ratio preserved (contain fits it whole) */
.theme-globe {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 70vw;
  height: auto;
  max-height: 90vh;
  object-fit: contain;
  z-index: 3;
  pointer-events: none;
}
/* Layer 4: corner labels — pinned to each corner, --corner-gap from the edges,
   so opposite corners share the same top/bottom/left/right and read as aligned. */
.theme-corners {
  position: absolute;
  inset: 0;
  z-index: 6; /* above .theme-content (z5) so the labels receive hover; the
                 container itself stays pointer-events:none so only the labels
                 (pointer-events:auto) catch the pointer and the rest passes
                 through to the scrolling body. */
  pointer-events: none;
}
.theme-corner {
  position: absolute;
  display: inline-block;
  font-family: "PP Editorial New", serif;
  font-size: 5rem;
  line-height: 100%;
  letter-spacing: -0.05em;
  color: #fff;
  /* soft, subtle drop shadow so the white label stays readable on the artwork */
  text-shadow: 0 0.1rem 0.5rem rgba(0, 0, 0, 0.3);
  text-align: center; /* both label lines centered */
  /* the splash sits behind the text: padding is the gap between text and splash
     edge. The splash is drawn on ::before as a #FFF7E1 fill masked to the SVG
     shape (mask, not background-image, so it can be recoloured). */
  padding: 4rem 5.5rem;
  isolation: isolate; /* own stacking context so ::before (z-index:-1) sits behind the text */
  /* Only the text is interactive — the splash image just sits on the background.
     The corner itself ignores the pointer; the inner .theme-corner-label re-enables
     it, so hovering/clicking the splash does nothing and falls through. */
  pointer-events: none;
}
.theme-corner-label {
  pointer-events: auto;
  cursor: pointer; /* each corner is a clickable menu item (CMS article) */
}
.theme-corner-label:hover {
  font-style: italic;
}
.theme-corner::before {
  content: "";
  position: absolute;
  inset: -45%; /* expand the box well beyond the text so the splash reads bigger */
  z-index: -1; /* behind the text */
  background-color: #e7e4dc;
  transition: background-color 0.2s ease;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain; /* whole splash visible, never cropped */
  mask-size: contain;
}
.theme-corner:has(.theme-corner-label:hover)::before,
.theme-corner.active::before {
  background-color: #fff7e1; /* hovered (over the text), or the currently-selected article */
}
.theme-corner.top-left {
  top: var(--corner-gap-top);
  left: var(--corner-gap-left);
}
.theme-corner.top-left::before {
  -webkit-mask-image: url("../assets/26bg/theme_framework.svg");
  mask-image: url("../assets/26bg/theme_framework.svg");
  inset: -55%;
  transform: translateY(1.5rem);
}
.theme-corner.top-right {
  top: var(--corner-gap-top);
  right: var(--corner-gap);
}
.theme-corner.top-right::before {
  -webkit-mask-image: url("../assets/26bg/theme_ocean.svg");
  mask-image: url("../assets/26bg/theme_ocean.svg");
  inset: -22%; /* smaller than the others so this top-right splash doesn't run off-screen */
}
.theme-corner.bottom-left {
  bottom: var(--corner-gap);
  left: var(--corner-gap-left);
}
.theme-corner.bottom-left::before {
  -webkit-mask-image: url("../assets/26bg/theme_forest.svg");
  mask-image: url("../assets/26bg/theme_forest.svg");
  inset: -24%; /* a little smaller than the default splash */
  transform: translateY(-3rem); /* lift the splash off the screen bottom (text stays put) */
}
.theme-corner.bottom-right {
  bottom: var(--corner-gap);
  right: var(--corner-gap);
}
.theme-corner.bottom-right::before {
  -webkit-mask-image: url("../assets/26bg/theme_archipelago.svg");
  mask-image: url("../assets/26bg/theme_archipelago.svg");
}

/* Layer 5: title (fixed) + body text (scrolls), in white, over the artwork.
   .theme-content fills the viewport but does NOT scroll — the title stays put;
   only .theme-scroll scrolls. */
.theme-content {
  position: absolute;
  inset: 0;
  z-index: 5;
  height: 100vh;
  height: var(--app-height, 100dvh);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 2rem 1.5rem 0;
}
.theme-title {
  flex: none;
  font-family: "Garamond MT", serif;
  font-weight: 500;
  font-style: italic;
  font-size: 16rem;
  line-height: 90%;
  letter-spacing: -0.04em;
  text-align: center;
  color: #fff;
  /* keep the title on a single line (don't fold to two) */
  white-space: nowrap;
  max-width: none;
  margin: 0 0 3rem;
  /* soft drop shadow (50% black, slight spread) so the white text stays
     readable on light parts of the artwork — matches the home page */
  text-shadow: 0 0.2rem 0.8rem rgba(0, 0, 0, 0.5);
}
.theme-scroll {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-bottom: 8rem;
}
.theme-body {
  width: 88rem;
  max-width: 72vw;
  text-align: left;
  color: #fff;
}
.theme-body,
.theme-body p {
  color: #fff;
  text-shadow: 0 0.2rem 0.8rem rgba(0, 0, 0, 0.5);
}
.theme-body p {
  font-family: "Suisse Intl Regular", sans-serif;
  font-size: var(--f-desk-big);
  line-height: var(--f-big-lh);
  letter-spacing: var(--f-big-ls);
}
/* Hide the native scrollbar on both theme scroll containers (desktop scrolls
   #scroll-container, mobile scrolls .theme-content) so only the custom
   transparent-track + grey thumb scrollbar shows over the background image. */
#scroll-container,
.theme-content {
  scrollbar-width: none;
  -ms-overflow-style: none;
}
#scroll-container::-webkit-scrollbar,
.theme-content::-webkit-scrollbar {
  display: none;
}
@media (max-width: 1024px) {
  .theme-page {
    --corner-gap: 1.5rem;
    --corner-gap-left: 1.5rem;
    /* empty band at the very top of the page — leaves room for the fixed logo
       (~5.25rem) before the in-flow corner menu starts */
    --theme-top-empty: 6.5rem;
  }

  /* The background photo + line/globe layers already cover the whole .theme-page
     (100vh). The global black mobile header bar is collapsed on the theme page
     (data-mobile-header-height="0"), so the artwork now reaches the very top. */

  /* The 4 corner labels become an in-flow row that scrolls with the content.
     It sits below the empty top band (roughly where the title used to be) and
     scrolls up out of view with the title + body. */
  .theme-corners {
    position: static;
    inset: auto;
    width: 100%;
    height: auto;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0;
    margin-bottom: 2.5rem; /* gap before the title below */
    padding: 0;
  }
  .theme-corner {
    position: relative; /* not absolute (so it flows in the row) but still the
                           containing block for its own splash ::before */
    flex: 0 0 auto; /* labels define their own width; row spacing handles alignment */
    min-width: 0;
    font-size: 1.75rem;
    padding: 0;
  }
  /* cancel the per-corner top/bottom/left/right offsets (matching the .top-left…
     specificity) so the relative items all sit on one shared line */
  .theme-corner.top-left,
  .theme-corner.top-right,
  .theme-corner.bottom-left,
  .theme-corner.bottom-right {
    inset: auto;
  }
  .theme-corner.top-left {
    order: 1;
  }
  .theme-corner.bottom-left {
    order: 2;
  }
  .theme-corner.top-right {
    order: 3;
  }
  .theme-corner.bottom-right {
    order: 4;
  }
  .theme-corner::before {
    display: block;
    inset: -4.05rem -2.7rem;
    transform: none;
    background-color: rgba(231, 228, 220, 0.86);
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-position: center;
    mask-position: center;
    pointer-events: none;
  }
  .theme-corner.top-left::before {
    inset: -5.175rem -3.375rem;
    transform: translateY(0.25rem);
  }
  .theme-corner.top-right::before {
    inset: -4.8rem -3.75rem;
    transform: translate(0.65rem, -0.8rem);
  }
  .theme-corner.bottom-left::before {
    inset: -2.925rem -2.025rem;
    transform: translateY(-1.45rem);
  }
  .theme-corner.bottom-right::before {
    inset: -4rem -2.9rem;
    transform: translateX(-0.25rem);
  }

  /* The corner menu + title + body scroll together as one column, below an
     empty band at the top of the page. */
  .theme-content {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    height: auto;
    overflow-y: auto;
    box-sizing: border-box;
    padding: var(--theme-top-empty) 1.5rem 6rem;
  }
  .theme-title {
    font-size: clamp(5.55rem, 15.6vw, 8.8rem);
    letter-spacing: -0.065em;
    max-width: none;
    width: 100%;
    margin-left: 0;
    white-space: nowrap;
    text-align: center;
    transform: translateX(-0.75rem);
  }
  .theme-scroll {
    flex: none; /* natural height so it scrolls with the title, not on its own */
    overflow: visible;
    width: 100%;
    padding-bottom: 0;
  }
  .theme-globe {
    /* rotated 90deg, the element's width becomes the vertical axis. The artwork
       is ≈2:1, so its rotated visual width ≈ half the element width. Grow it as
       large as fits: height-bound at 95vh, width-bound at 190vw (≈95vw visual). */
    width: min(190vw, 95vh);
    max-width: none;
    max-height: none;
    /* push the centre down so the globe begins below the title (top bar 8rem +
       2rem padding + ~7rem title) rather than overlapping it */
    top: calc(50% + 16rem);
    /* rotate the two-globe artwork upright for the portrait mobile background */
    transform: translate(-50%, -50%) rotate(90deg);
  }
  .theme-body {
    width: 100%;
    max-width: none;
    padding: 0;
  }
  .theme-body p {
    font-size: var(--f-mobile-normal);
  }

  /* custom scrollbar tracks the full-height content (which now scrolls from the
     very top, with the corner menu inside it) */
  .theme-page .custom-scrollbar {
    top: 0;
    height: 100vh;
    height: var(--app-height, 100dvh);
  }
}

/* ============================================================
   PROGRAMME PAGE
   ============================================================ */
.programme-page {
  /* block (not flex) so this scroll container actually honors padding-bottom —
     flex scroll containers drop end padding/margin. The date-menu and grid still
     centre via their own margin:0 auto. */
  padding: 2rem 10rem 10rem var(--page-padding-left);
}
.programme-scrollbar {
  z-index: 8000;
  background: transparent;
}

/* Tab bar – shared base for date squares and year links */
.date-square,
.year-link {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  width: var(--tab-width);
  height: var(--tab-height);
  padding-left: 0.5rem;
  background-color: #fff;
  text-decoration: none;
  transition:
    background-color 0.2s ease,
    color 0.2s ease;
}

.date-menu {
  display: flex;
  gap: 0.1rem;
  margin-bottom: var(--expanded-gap);
  justify-content: flex-start;
  max-width: 170rem;
  width: 100%;
  margin-left: auto;
  margin-right: auto;
}
.date-square span {
  font-family: var(--font-medium);
  font-size: var(--f-desk-normal);
  line-height: var(--f-normal-lh);
  letter-spacing: var(--f-normal-ls);
  color: #000;
}
.date-square:hover,
.date-square.active {
  background-color: #000;
}
.date-square:hover span,
.date-square.active span {
  color: #fff;
  font-style: italic;
}

.events-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6rem;
  max-width: 144rem;
  width: 100%;
  margin: 0;
  align-items: start;
}

/* Card – shared 3D border pattern for event-card and archive-card */
.event-card,
.archive-card {
  display: flex;
  flex-direction: column;
  background-color: #000;
  position: relative;
  cursor: pointer;
  color: inherit;
  text-decoration: none;
  transition: transform 0.2s ease;
  isolation: isolate; /* own stacking context so the z-index:-1 borders sit behind content */
}
.event-card:hover,
.archive-card:hover {
  transform: translateY(-0.5rem);
}
.event-card:hover,
.archive-card:hover {
  background-color: #fff;
}
.event-card:hover .info-container,
.archive-card:hover .archive-info {
  color: #000;
}
.event-card:hover::before,
.event-card:hover::after,
.archive-card:hover::before,
.archive-card:hover::after {
  background-color: #fff;
}

.event-card::after,
.archive-card::after {
  content: "";
  position: absolute;
  z-index: -1;
  bottom: calc(-1 * var(--shadow-depth));
  /* left flush with the card edge so the fold vertex never pokes left of it */
  left: 0;
  right: calc(-1 * var(--shadow-depth));
  /* +1px tucks the top edge under the card so sub-pixel rounding can't leave a gap */
  height: calc(var(--shadow-depth) + 1px);
  background-color: #000;
  clip-path: polygon(0 0, 100% 0, 100% 100%, var(--shadow-corner) 100%);
}
.event-card::before,
.archive-card::before {
  content: "";
  position: absolute;
  z-index: -1;
  /* top flush with the card edge so the fold vertex never pokes above it */
  top: 0;
  right: calc(-1 * var(--shadow-depth));
  bottom: -1px;
  /* +1px tucks the left edge under the card so sub-pixel rounding can't leave a gap */
  width: calc(var(--shadow-depth) + 1px);
  background-color: #000;
  clip-path: polygon(0 0, 100% var(--shadow-corner), 100% 100%, 0 100%);
}

.image-container {
  width: 100%;
  aspect-ratio: 4 / 5;
  overflow: hidden;
}
.event-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.info-container {
  padding: 1.5rem 2rem 0 1rem;
  color: #fff;
  display: flex;
  flex-direction: column;
  flex-grow: 1;
}
/* Reserve room for two title lines (artist + title) so a card missing one of
   them keeps the same height as the others. --f-card-title-size tracks the
   actual title size on both breakpoints, so this holds on desktop and mobile.
   0.3rem = the gap between the two lines (.event-title margin-top). */
.top-info {
  min-height: calc(var(--f-card-title-size) * var(--f-big-lh) * 2 + 0.3rem);
}
.event-title {
  font-family: var(--font-regular);
  font-weight: normal;
  font-size: var(--f-desk-big);
  line-height: var(--f-big-lh);
  margin: 0.3rem 0 0;
  font-style: normal;
  letter-spacing: var(--f-big-ls);
}
.event-location {
  font-family: var(--font-medium);
  font-weight: 500;
  font-size: var(--f-desk-big);
  line-height: var(--f-big-lh);
  margin: 0;
  letter-spacing: var(--f-big-ls);
}
.bottom-info {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  margin: calc(var(--f-desk-big) * 1.5) -2rem 0 0;
}
.event-time,
.event-type {
  font-family: var(--font-medium);
  font-size: var(--f-desk-small);
  line-height: var(--f-small-lh);
  letter-spacing: var(--f-small-ls);
}
@media (min-width: 1025px) {
  /* half-line of breathing room between the bottom text row and the card's bottom
     edge — shared by programme/events (.info-container), news (.news-info) and
     archive (.archive-info) cards. The news/archive selectors are scoped to their
     card so they outrank the base `padding` shorthand defined later in the file. */
  .info-container,
  .news-card .news-info,
  .archive-card .archive-info {
    padding-bottom: calc(var(--f-desk-small) * 0.5);
  }
}

/* ── Expanded overlay (shared across programme / events / news / archive) ── */
.expanded-view {
  position: fixed;
  top: 0;
  left: var(--page-padding-left);
  right: 0;
  bottom: 0;
  background-color: #000;
  z-index: 2500;
  display: none;
  overflow-y: auto;
  color: #fff;
  scrollbar-width: none;
  -ms-overflow-style: none; /* hide native scrollbar — the custom scrollbar tracks this panel */
}
.expanded-view::-webkit-scrollbar {
  display: none;
}
.expanded-view.open {
  display: block;
}

/* Detail (full view) pages. */
.expanded-view.detail-view {
  display: block;
} /* always visible (no .open toggle) */
@media (min-width: 1025px) {
  /* Desktop: the panel is a fixed, iframe-like frame — it does NOT scroll. The black
     container, the image and the header all stay still; only .expanded-body scrolls,
     driven by the page's custom scrollbar (wired in app.js). Offset from the left so
     the logo + side-label column shows the page colour beside it. */
  .expanded-view.detail-view {
    position: static;
    overflow: hidden;
    height: 100vh;
    height: 100dvh;
    margin: 0 var(--page-padding-left);
    background: transparent;
  }
  /* Black container: fixed height (viewport minus the top/bottom insets), no scroll.
     X is absolute inside (position:relative) so it stays pinned to the frame. */
  .expanded-view.detail-view .expanded-content {
    position: relative;
    background: #000;
    margin: calc(var(--page-padding-left) / 2 * 0.75) 0
      calc(var(--page-padding-left) / 2);
    height: calc(
      100% - var(--page-padding-left) / 2 * 0.75 - var(--page-padding-left) / 2
    );
    min-height: 0;
    overflow: hidden;
  }
  /* Left (image) column stays still; equal top/bottom padding so the image fills the
     frame symmetrically. The image flexes to the column's available height (its top
     padding is +0.6rem to line up with the header text, so the bottom matches that). */
  .expanded-view.detail-view .expanded-left {
    height: 100%;
    min-height: 0;
    overflow: hidden;
    justify-content: center;
    padding-bottom: calc(var(--expanded-gap) + 0.6rem);
  }
  .expanded-view.detail-view .expanded-image-wrapper {
    width: fit-content;
    max-width: 100%;
  }
  .expanded-view.detail-view .expanded-image-wrapper img {
    width: auto;
    height: calc(100dvh - 22rem);
    max-width: 100%;
    object-fit: contain;
  }
  /* Archive gallery: thumbnails pinned to the bottom, then the image-title sits just
     above them, and the image fills/centres in the space above the title. The stage
     flexes to fill (pushing the title to the bottom of the image area) and the image
     stays centred and contained within it (dropping the fixed 10/9 ratio). */
  .expanded-view.detail-view .main-image-wrapper {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }
  .expanded-view.detail-view .gallery-stage {
    flex: 1 1 auto;
    min-height: 0;
    aspect-ratio: auto;
  }
  .expanded-view.detail-view .gallery-stage #main-expanded-image,
  .expanded-view.detail-view .gallery-stage .gallery-main-image {
    width: 100%;
    height: 100%;
    object-fit: contain;
  }
  .expanded-view.detail-view .thumbnails-container {
    flex: 0 0 auto;
  }
  /* Right column: header pinned at the top, body is the one scrolling region. */
  .expanded-view.detail-view .expanded-right {
    height: 100%;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* gap between the body area and the bottom edge of the black container,
       mirroring the top inset (--expanded-gap) above the header */
    padding-bottom: var(--expanded-gap);
  }
  .expanded-view.detail-view .expanded-header {
    flex: 0 0 auto;
  }
  .expanded-view.detail-view .expanded-body {
    flex: 1 1 auto;
    min-height: 0;
    margin-top: 0;
    overflow-y: auto;
    padding-bottom: 0;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .expanded-view.detail-view .expanded-body::-webkit-scrollbar {
    display: none;
  }
  /* Align the X's right edge with the body/header text right edge (the right
     column's right padding). The button's own 1rem padding insets the SVG, so the
     offset is paddingRight − 1rem. Archive uses a smaller right padding. */
  .expanded-view.detail-view .close-button {
    right: calc(var(--expanded-gap) * 1.5 - 1rem);
  }
  .archive-expanded-view.detail-view .close-button {
    right: calc(var(--expanded-gap) - 1rem);
  }
}
/* Mobile: the shared .expanded-view inset-panel rules apply (top bar stays visible,
   1.6rem spacing) so it reads like an opened projects accordion. */
@media (max-width: 1024px) {
  .detail-scrollbar {
    z-index: 4500;
  } /* above the panel (4000), below the drawer (5000) */
}
.close-button {
  position: absolute;
  top: calc(var(--expanded-gap) - 1rem);
  right: calc(var(--expanded-gap) - 1rem);
  background: none;
  border: none;
  cursor: pointer;
  z-index: 3100;
  padding: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.close-button svg {
  /* Match the visible size of the projects-page X. That X is an 8rem "+" rotated
     45°, so its arms only span 8rem / √2 ≈ 5.66rem corner-to-corner — whereas this
     SVG draws its arms across the full box, so it must be 5.66rem to look equal. */
  width: 5.66rem;
  height: 5.66rem;
}
.expanded-content {
  display: flex;
  min-height: 100vh;
  min-height: var(--app-height, 100dvh);
  width: 100%;
}
.expanded-left {
  width: 50%;
  padding: calc(var(--expanded-gap) + 0.6rem) 8rem 4rem
    calc(var(--expanded-gap) * 1.5);
  display: flex;
  flex-direction: column;
}
.expanded-image-wrapper {
  width: 100%;
  position: relative;
}
.expanded-image-wrapper img {
  width: 100%;
  height: auto;
  display: block;
}
.photo-credit {
  background: #fff;
  color: #000;
  padding: 0.6rem 1.6rem 0.6rem 0.6rem;
  width: 100%;
}
.expanded-right {
  width: 50%;
  padding: var(--expanded-gap) calc(var(--expanded-gap) * 1.5) 10rem 2rem;
}
.expanded-header {
  margin-bottom: 3rem;
}
/* Reserve room for the close button (its size + offset/padding) so a long title
   always wraps before reaching the X, at any desktop width */
.expanded-title {
  font-family: var(--font-medium);
  margin: 0;
  font-size: var(--f-huge-size);
  line-height: var(--f-huge-lh);
  letter-spacing: var(--f-huge-ls);
  padding-right: calc(var(--close-x-size) + 2rem);
}
.expanded-name {
  font-family: var(--font-regular);
  font-weight: 400;
  font-size: var(--f-huge-size);
  line-height: var(--f-huge-lh);
  margin: 0.3rem 0 0;
  font-style: normal;
  letter-spacing: var(--f-huge-ls);
  /* same close-button clearance as .expanded-title — in several views the long
     title is rendered in this line, so it must also wrap before reaching the X */
  padding-right: calc(var(--close-x-size) + 2rem);
}
.expanded-meta {
  display: flex;
  justify-content: space-between;
  margin-top: calc(var(--expanded-gap) * 1.5);
  font-family: var(--font-medium);
  font-weight: 500;
  font-size: var(--f-desk-normal);
  line-height: var(--f-normal-lh);
  letter-spacing: var(--f-normal-ls);
}
.expanded-meta--split {
  flex-wrap: wrap;
  column-gap: 1rem;
  row-gap: 0;
}
.expanded-meta--split > * {
  min-width: 0;
  max-width: 100%;
}
.expanded-meta--split > :first-child {
  flex: 0 0 auto;
}
.expanded-meta--split > :last-child {
  flex: 1 1 auto;
  margin-left: auto;
  text-align: right;
}
.expanded-meta--split > :nth-child(n + 3) {
  flex: 0 0 100%;
  margin-left: 0;
  text-align: left;
}
.expanded-meta :is(p, span, .expanded-link),
.expanded-date {
  margin-top: 0;
  margin-bottom: 0;
}
/* meta paragraphs (archive date/venue/location) — keep them in the small type style,
   overriding the global p rule that would otherwise make them "normal" */
.expanded-meta p {
  font-size: var(--f-desk-normal);
  line-height: var(--f-normal-lh);
  letter-spacing: var(--f-normal-ls);
}
.archive-expanded-view .expanded-meta p {
  font-family: var(--font-medium);
  font-weight: 500;
}
/* Single-line header (a programme/events or archive item missing either the title
   or the artist line): the top block is one big line shorter, so push the small
   bottom block (meta) down by an extra empty line. The 2-line header separates top
   from bottom with one --expanded-gap; the 1-line header uses two, keeping the
   bottom block at the same vertical position as the 2-line ones. */
.expanded-header--single-line .expanded-meta {
  margin-top: calc(var(--expanded-gap) * 2);
}
.section-separator {
  position: relative;
  width: 100%;
  height: 1px;
  margin: var(--expanded-gap) 0;
  background: transparent;
}
/* split-rule lines removed — the separator is kept only to preserve the section spacing */
.section-separator::before,
.section-separator::after {
  display: none;
}
.section-separator::before {
  left: 0;
}
.section-separator::after {
  right: 0;
}
.expanded-body {
  margin-top: var(--expanded-gap);
}
.expanded-description,
.expanded-bio,
.expanded-bio-title {
  font-family: var(--font-regular);
  font-size: var(--f-main-size);
  line-height: var(--f-main-lh);
  letter-spacing: var(--f-main-ls);
}
.expanded-description,
.expanded-bio {
  margin-bottom: var(--expanded-gap);
}
.expanded-bio-title {
  margin-bottom: 2rem;
}
.mobile-only {
  display: none;
}
.desktop-only {
}

@media (max-width: 1024px) {
  .programme-page {
    padding: 8.5rem 3.7rem 10rem 2.7rem;
  } /* +0.5rem right / -0.5rem left to centre card incl. its 1rem 3D border */
  .date-menu {
    position: fixed;
    top: 5.7rem;
    left: 0;
    flex-direction: row;
    flex-wrap: nowrap;
    justify-content: center;
    gap: 0.1rem;
    width: 100%;
    margin-bottom: 0;
    z-index: 4500;
    padding: 0 1.6rem;
    background-color: var(--page-bg);
  }
  .date-square {
    flex: 1;
    min-width: 0;
    height: 2.8rem;
    padding-left: 0.5rem;
    border: none;
  }
  .date-square span {
    font-size: var(--f-mobile-normal);
  }
  .events-grid {
    grid-template-columns: 1fr;
    margin-top: 1.6rem;
    gap: 2.1rem;
  }
  /* id selector (1,1,0) outranks the desktop `margin: 0 auto` centering rule;
     gap below the fixed dates menu matches the gap between two posts (2.1rem) */
  .programme-page #grid-container {
    margin-top: 1.1rem;
  }
  .event-title,
  .event-location {
    font-size: var(--f-mobile-big);
  }
  .event-time,
  .event-type {
    font-size: var(--f-mobile-small);
  }
  .bottom-info {
    margin-top: var(--f-mobile-big);
  }
  .event-card::after {
    bottom: -1rem;
    right: -1rem;
    height: calc(1rem + 1px);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 1.6rem 100%);
  }
  .event-card::before {
    right: -1rem;
    width: calc(1rem + 1px);
    clip-path: polygon(0 0, 100% 1.6rem, 100% 100%, 0 100%);
  }

  /* Mobile full view = inset panel (like an opened projects accordion):
     leaves the top bar (logo + DRIFTS) visible, 1.6rem spacing on the other edges */
  .expanded-view {
    top: 5.7rem;
    left: 1.6rem;
    right: 1.6rem;
    bottom: 1.6rem;
    z-index: 4000;
  } /* below the drawer (5000) so the menu opens over it */
  .expanded-content {
    flex-direction: column;
    min-height: 100%;
  }
  .mobile-only {
    display: block;
  }
  .expanded-mobile-header {
    padding: 1.2rem 1rem 1.6rem 1rem;
  } /* ~one blank line below the meta, before the image */
  .expanded-mobile-header .expanded-title {
    font-family: var(--font-medium);
    font-weight: 500;
    font-style: normal;
    font-size: var(--f-huge-size);
    line-height: var(--f-huge-lh);
    padding-right: calc(var(--f-mobile-big) + 3rem);
  }
  .expanded-mobile-header .expanded-name {
    font-family: var(--font-regular);
    font-weight: 400;
    font-style: normal;
    font-size: var(--f-huge-size);
    line-height: var(--f-huge-lh);
    margin-top: 0.3rem;
    /* Keep the second big line clear of the mobile X as well. */
    padding-right: calc(3.6rem + 1rem);
  }
  .expanded-mobile-header .expanded-meta {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    width: 100%;
    gap: 1rem;
    margin-top: 3.2rem;
    font-size: var(--f-mobile-small);
    line-height: var(--f-small-lh);
    letter-spacing: var(--f-small-ls);
  }
  .expanded-mobile-header .expanded-meta.expanded-meta--split {
    column-gap: 1rem;
    row-gap: 0.15rem;
  }
  .expanded-mobile-header .expanded-meta.expanded-meta--split > :last-child {
    text-align: right;
  }
  .expanded-mobile-header .expanded-meta.expanded-meta--split > :nth-child(n + 3) {
    flex-basis: 100%;
    margin-left: 0;
    text-align: left;
  }
  .expanded-left,
  .expanded-right {
    width: 100%;
  }
  .expanded-left {
    padding: 0 1rem 0 1rem;
  }
  .expanded-right {
    padding: 0 1rem 4rem 1rem;
  }
  .photo-credit {
    padding: 0.4rem 0.5rem;
    margin-bottom: var(--f-main-size);
  }
  .expanded-description,
  .expanded-bio,
  .expanded-bio-title {
    font-size: var(--f-mobile-normal);
    margin-bottom: 1.33rem;
  }
  /* Mobile close X: drawn to match the projects accordion plus/X icon
     (3.6rem box, 2px bars) instead of the SVG, which is hidden here. */
  .close-button {
    position: absolute;
    right: 1rem;
    top: 1.2rem;
    padding: 0;
    z-index: 7100;
    width: 3.6rem;
    height: 3.6rem;
  }
  .close-button svg {
    display: none;
  }
  .close-button::before,
  .close-button::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 0;
    width: 100%;
    height: 2px;
    background-color: #fff;
  }
  .close-button::before {
    transform: translateY(-50%) rotate(45deg);
  }
  .close-button::after {
    transform: translateY(-50%) rotate(-45deg);
  }
  .desktop-only {
    display: none !important;
  }
  .section-separator {
    margin: 1.33rem 0;
  }
  .expanded-body {
    margin-top: 0;
  }
}

/* ============================================================
   VISIT PAGE
   ============================================================ */
.visit-page {
  padding: 2rem var(--page-padding-left) 10rem var(--page-padding-left);
}
.visit-page .events-grid {
  max-width: 170rem;
}
.visit-card {
  display: flex;
  flex-direction: column;
  background-color: #000;
  position: relative;
  isolation: isolate;
}
.visit-card::after {
  content: "";
  position: absolute;
  z-index: -1;
  bottom: calc(-1 * var(--shadow-depth));
  left: 0;
  right: calc(-1 * var(--shadow-depth));
  height: calc(var(--shadow-depth) + 1px);
  background-color: #000;
  clip-path: polygon(0 0, 100% 0, 100% 100%, var(--shadow-corner) 100%);
}
.visit-card::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 0;
  right: calc(-1 * var(--shadow-depth));
  bottom: -1px;
  width: calc(var(--shadow-depth) + 1px);
  background-color: #000;
  clip-path: polygon(0 0, 100% var(--shadow-corner), 100% 100%, 0 100%);
}
.visit-image-wrap {
  width: 100%;
  overflow: hidden;
}
.visit-card .image-container {
  aspect-ratio: 1 / 1;
}
@media (min-width: 1025px) {
  .visit-page .events-grid {
    grid-template-columns: repeat(2, 1fr);
    max-width: 138rem;
  }
}
.visit-card-info {
  padding: 0;
  color: #000;
  display: flex;
  align-items: stretch;
  cursor: pointer;
  background-color: #fff;
}
.visit-card-text {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  margin: 1.5rem 0 1.5rem 1rem;
}
.visit-card-plus {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  padding: 0 1rem 0 2rem;
}
.visit-title {
  font-family: var(--font-medium);
  font-style: normal;
  font-size: var(--f-desk-big);
  line-height: var(--f-big-lh);
  letter-spacing: var(--f-big-ls);
  margin: 0;
}
.visit-card:hover .visit-title,
.visit-card:hover .visit-subtitle {
  font-style: italic;
}
.visit-subtitle {
  font-family: var(--font-regular);
  font-style: normal;
  font-size: var(--f-desk-big);
  line-height: var(--f-big-lh);
  letter-spacing: var(--f-big-ls);
  margin: 0;
}
.visit-card-meta {
  font-size: var(--f-desk-small);
  line-height: var(--f-small-lh);
}
.visit-card .plus-icon {
  width: 8rem;
  height: 8rem;
  position: relative;
  transition: transform 0.3s ease;
  flex-shrink: 0;
}
.visit-card .plus-icon::before {
  content: "";
  position: absolute;
  width: 100%;
  height: 2px;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
  background-color: #000;
}
.visit-card .plus-icon::after {
  content: "";
  position: absolute;
  width: 2px;
  height: 100%;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  background-color: #000;
}
.visit-card.open .plus-icon {
  transform: rotate(45deg);
}
.visit-accordion-content {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease-out;
}
.visit-card.open .visit-accordion-content {
  max-height: 400rem;
}
.visit-accordion-inner {
  background: #fff;
  color: #000;
  padding: 0 calc(var(--expanded-gap) / 2)
    calc(var(--f-main-size) * 3) 1rem;
}

/* CMS fetch failure */
.cms-error {
  font-family: var(--font-regular);
  font-size: var(--f-main-size);
  color: #c02820;
  margin: 0;
}

/* CMS-rendered rich text (Cockpit) – shared across all CMS-driven pages */
.cms-content h2 {
  margin-top: var(--section-gap);
  margin-bottom: 0.8rem;
}
.cms-content h2:first-child {
  margin-top: 0;
}
.cms-content a {
  color: inherit;
  text-decoration: none;
}

/* 1 empty line between consecutive paragraphs on text-heavy pages */
.cms-content p + p,
.description-text p + p,
.colophon-section p + p,
.text-body p + p,
.expanded-description p + p,
.expanded-bio p + p,
.expanded-full-content p + p {
  margin-top: var(--f-main-size);
}

/* ── Shared WYSIWYG typography for every container that renders Cockpit HTML.
   <strong> is mapped to the medium font globally (see `strong, b` rule). Here we
   pin italics to the regular italic cut and turn <hr> into the festival's split
   separator (two short rules with a gap in the middle), inheriting text colour
   so it works on both the dark expanded views and the light info pages. */
.cms-content em,
.cms-content i,
.description-text em,
.description-text i,
.expanded-description em,
.expanded-description i,
.expanded-bio em,
.expanded-bio i,
.expanded-full-content em,
.expanded-full-content i {
  font-family: var(--font-regular);
  font-style: italic;
}

.cms-content hr,
.description-text hr,
.expanded-description hr,
.expanded-bio hr,
.expanded-full-content hr {
  position: relative;
  width: 100%;
  height: 1px;
  border: 0;
  margin: var(--expanded-gap) 0;
  background: transparent;
}
.cms-content hr::before,
.cms-content hr::after,
.description-text hr::before,
.description-text hr::after,
.expanded-description hr::before,
.expanded-description hr::after,
.expanded-bio hr::before,
.expanded-bio hr::after,
.expanded-full-content hr::before,
.expanded-full-content hr::after {
  content: "";
  position: absolute;
  top: 0;
  width: 5.2rem;
  height: 1px;
  background-color: currentColor;
}
.cms-content hr::before,
.description-text hr::before,
.expanded-description hr::before,
.expanded-bio hr::before,
.expanded-full-content hr::before {
  left: 0;
}
.cms-content hr::after,
.description-text hr::after,
.expanded-description hr::after,
.expanded-bio hr::after,
.expanded-full-content hr::after {
  right: 0;
}
@media (max-width: 1024px) {
  .visit-page {
    padding: 5.6rem 2rem 10rem 1.6rem;
  }
  .visit-page .events-grid {
    grid-template-columns: 1fr;
    gap: 2.1rem;
  }
  .visit-card-text {
    margin: 0;
    padding: 1rem 2rem 0.8rem 0.8rem;
  }
  .visit-title {
    font-family: var(--font-medium);
    font-weight: 500;
    font-size: var(--f-mobile-big);
    line-height: 1.05;
    font-style: normal;
  }
  .visit-subtitle {
    font-family: var(--font-regular);
    font-weight: normal;
    font-size: var(--f-mobile-big);
    line-height: 1.05;
    font-style: normal;
    margin-top: 0.6rem;
  }
  .visit-card-meta {
    font-size: var(--f-mobile-small);
    line-height: var(--f-small-lh);
  }
  .visit-card .plus-icon {
    width: 3.6rem;
    height: 3.6rem;
  }
  .visit-card .plus-icon::before {
    height: 2px;
    transform: translateY(-50%);
  }
  .visit-card .plus-icon::after {
    width: 2px;
    transform: translateX(-50%);
  }
  .visit-card::after {
    bottom: -1rem;
    right: -1rem;
    height: calc(1rem + 1px);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 1.6rem 100%);
  }
  .visit-card::before {
    right: -1rem;
    width: calc(1rem + 1px);
    clip-path: polygon(0 0, 100% 1.6rem, 100% 100%, 0 100%);
  }
}

/* ============================================================
   AWARENESS PAGE
   ============================================================ */
.awareness-page {
  padding: 2rem 4rem 10rem var(--page-padding-left);
}
.awareness-page .box-3d {
  background-color: #f7f7f7;
}
.awareness-header h1 {
  font-family: var(--font-medium);
  font-size: var(--page-header-size);
  line-height: var(--f-big-lh);
}
.awareness-header {
  margin-bottom: var(--f-main-size);
}
@media (max-width: 1024px) {
  .awareness-page {
    padding: 5.6rem 2rem 10rem 1.6rem;
  }
  .awareness-header {
    margin-bottom: var(--f-main-size);
  }
  .awareness-header h1 {
    font-family: var(--font-regular);
    font-weight: 400;
    font-size: var(--f-main-size);
    line-height: var(--f-main-lh);
  }
  .awareness-page .box-3d::after {
    bottom: -0.55rem;
    right: -0.55rem;
    height: calc(0.55rem + 1px);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0.95rem 100%);
  }
  .awareness-page .box-3d::before {
    right: -0.55rem;
    width: calc(0.55rem + 1px);
    clip-path: polygon(0 0, 100% 0.95rem, 100% 100%, 0 100%);
  }
}

/* ============================================================
   PRESS PAGE
   ============================================================ */
.press-page {
  padding: 2rem var(--page-padding-left) 10rem var(--page-padding-left);
}
.press-page .box-3d {
  background-color: #f7f7f7;
}
.press-page .content-box {
  flex: 1;
}

.press-page .press-image-box {
  padding: 0;
  display: grid;
  grid-template-rows: 1fr auto;
}
.press-image-frame {
  overflow: hidden;
  min-height: 0;
}
/* full-bleed image: let the black 3D faces paint over the image's 1px
   bleeding edge (their tuck sits 1px inside the box) instead of leaving a
   light gap. z-index raises them above the image; isolation on .box-3d
   keeps this scoped so they still sit behind sibling boxes. */
.press-page .press-image-box::before,
.press-page .press-image-box::after {
  z-index: 1;
}
.press-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.press-page .press-image-box .photo-credit {
  background: transparent;
  /* cancel the global mobile .photo-credit margin-bottom (meant for the
     expanded-view overlays) so bottom spacing matches desktop */
  margin-bottom: 0;
}
.press-page .column-left,
.press-page .column-right,
.press-col-spacer {
  width: 33.33%;
}
@media (max-width: 1024px) {
  .press-page {
    padding: 5.6rem 2rem 10rem 1.6rem;
  }
  .press-page .column-left,
  .press-page .column-right {
    width: 100%;
  }
  .press-col-spacer {
    display: none;
  }
  .press-page .box-3d::after {
    bottom: -0.55rem;
    right: -0.55rem;
    height: calc(0.55rem + 1px);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0.95rem 100%);
  }
  .press-page .box-3d::before {
    right: -0.55rem;
    width: calc(0.55rem + 1px);
    clip-path: polygon(0 0, 100% 0.95rem, 100% 100%, 0 100%);
  }
}

/* ============================================================
   COLOPHON PAGE
   ============================================================ */
.colophon-page {
  padding: 2rem var(--page-padding-left) 10rem var(--page-padding-left);
}
.colophon-page .box-3d {
  background-color: #f7f7f7;
}

.colophon-content {
  display: flex;
  width: 100%;
  gap: var(--expanded-gap);
}
.colophon-col {
  width: 33.33%;
}
.colophon-section h2 {
  margin-bottom: 0.8rem;
}
@media (max-width: 1024px) {
  .colophon-page {
    padding: 5.6rem 2rem 10rem 1.6rem;
  }
  .colophon-content {
    flex-direction: column;
    gap: 1.2rem;
  }
  .colophon-col {
    width: 100%;
  }

  .colophon-page .box-3d::after {
    bottom: -0.55rem;
    right: -0.55rem;
    height: calc(0.55rem + 1px);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0.95rem 100%);
  }
  .colophon-page .box-3d::before {
    right: -0.55rem;
    width: calc(0.55rem + 1px);
    clip-path: polygon(0 0, 100% 0.95rem, 100% 100%, 0 100%);
  }
}

/* ============================================================
   NEWS PAGE
   ============================================================ */
.news-page {
  padding: 2rem 10rem 10rem var(--page-padding-left);
}
.news-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6rem;
  max-width: 170rem;
  margin: 0 auto;
}
.news-card {
  display: flex;
  flex-direction: column;
  cursor: pointer;
  transition: transform 0.2s ease;
  position: relative;
  background-color: #000;
  color: inherit;
  text-decoration: none;
  isolation: isolate; /* own stacking context so the z-index:-1 borders sit behind content */
}
.news-card:hover {
  transform: translateY(-0.5rem);
}
.news-card:hover {
  background-color: #fff;
}
.news-card:hover .news-info {
  background-color: #fff;
  color: #000;
}
.news-card:hover::before,
.news-card:hover::after {
  background-color: #fff;
}
.news-card::after {
  content: "";
  position: absolute;
  z-index: -1;
  bottom: calc(-1 * var(--shadow-depth));
  left: 0;
  right: calc(-1 * var(--shadow-depth));
  height: calc(var(--shadow-depth) + 1px);
  background-color: #000;
  clip-path: polygon(0 0, 100% 0, 100% 100%, var(--shadow-corner) 100%);
}
.news-card::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 0;
  right: calc(-1 * var(--shadow-depth));
  bottom: -1px;
  width: calc(var(--shadow-depth) + 1px);
  background-color: #000;
  clip-path: polygon(0 0, 100% var(--shadow-corner), 100% 100%, 0 100%);
}
.image-wrapper {
  width: 100%;
  aspect-ratio: 4 / 5;
  overflow: hidden;
}
.news-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
}
.news-info {
  padding: 1.5rem 2rem 0 1rem;
  color: #fff;
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  /* keep the date pinned to the bottom; when a row stretches this card to match a
     taller sibling, the extra height falls between the title and the date (the
     date's margin-top still sets the minimum gap) */
  justify-content: space-between;
  background-color: #000;
}
.news-title-block {
  min-height: calc(var(--f-card-title-size) * var(--f-big-lh) * 2);
}
.news-title {
  font-family: var(--font-medium);
  font-weight: 500;
  font-size: var(--f-desk-big);
  line-height: var(--f-big-lh);
  margin: 0;
  letter-spacing: var(--f-big-ls);
  font-style: normal;
}
.news-subtitle {
  font-family: var(--font-regular);
  font-weight: normal;
  font-style: normal;
  font-size: var(--f-desk-big);
  line-height: var(--f-big-lh);
  margin: 0.3rem 0 0;
  letter-spacing: var(--f-big-ls);
}
.news-date {
  font-family: var(--font-medium);
  font-size: var(--f-desk-small);
  line-height: var(--f-small-lh);
  margin: calc(var(--f-desk-small) * 1.5) 0 0;
  letter-spacing: var(--f-small-ls);
}

.news-expanded-view {
  background-color: #000;
}
.expanded-date {
  font-family: var(--font-medium);
  font-weight: 500;
  font-size: var(--f-desk-normal);
  line-height: var(--f-normal-lh);
  margin: 0;
  letter-spacing: var(--f-normal-ls);
}
.expanded-full-content {
  font-family: var(--font-regular);
  font-size: var(--f-main-size);
  line-height: var(--f-main-lh);
  letter-spacing: var(--f-main-ls);
}

@media (max-width: 1024px) {
  .news-page {
    padding: 6rem 3.7rem 10rem 2.7rem;
  } /* centre card incl. its 1rem 3D border */
  .news-grid {
    grid-template-columns: 1fr;
    gap: 2.1rem;
  }
  .news-card::after {
    bottom: -1rem;
    right: -1rem;
    height: calc(1rem + 1px);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 1.6rem 100%);
  }
  .news-card::before {
    right: -1rem;
    width: calc(1rem + 1px);
    clip-path: polygon(0 0, 100% 1.6rem, 100% 100%, 0 100%);
  }
  .news-title {
    font-size: var(--f-mobile-big);
  }
  .news-date {
    font-size: var(--f-mobile-small);
    margin-top: var(--f-mobile-small);
  }
  .expanded-date {
    font-size: var(--f-mobile-small);
    line-height: var(--f-small-lh);
    margin-top: 0;
    letter-spacing: var(--f-small-ls);
  }
  .expanded-full-content {
    font-size: var(--f-mobile-normal);
    margin-bottom: 1.33rem;
  }
  .expanded-mobile-header .expanded-date {
    padding-right: 6rem;
  }
  /* Reduce gap between photo credit and body text to one line */
  .news-expanded-view .photo-credit {
    margin-bottom: 0;
  }
  .news-expanded-view .expanded-right {
    padding-top: calc(var(--f-main-size) * var(--f-main-lh));
  }
}

/* ============================================================
   EVENTS PAGE
   ============================================================ */
.events-page-container {
  padding: 2rem 10rem 10rem var(--page-padding-left);
}
.events-page-container .events-grid,
.programme-page .events-grid {
  max-width: 170rem;
  width: 100%;
  margin: 0 auto;
}
.events-expanded-view {
  background-color: #000;
}
@media (max-width: 1024px) {
  .events-page-container {
    padding: 6rem 3.7rem 10rem 2.7rem;
  } /* centre card incl. its 1rem 3D border */
  .events-page-container .events-grid {
    grid-template-columns: 1fr;
    gap: 2.1rem;
  }
}

/* ============================================================
   PROJECTS PAGE
   ============================================================ */
.projects-page {
  padding: 2rem var(--page-padding-left) 10rem var(--page-padding-left);
}
.projects-header-box {
  background-color: #fff;
  padding: 1.5rem 2.4rem;
  margin-bottom: 0.8rem;
}
.projects-header-box p {
  font-size: var(--f-desk-big);
  line-height: var(--f-big-lh);
  margin: 0;
  letter-spacing: var(--f-big-ls);
}
.projects-list {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
}
/* Container is a plain block — it only needs to stack the trigger row and the
   collapsible content vertically. Keeping it block (not flex) avoids the
   flexbox min-height:auto vs max-height:0 conflict that broke the collapse. */
.project-accordion {
  width: 100%;
  background-color: #fff;
  transition: background-color 0.2s ease;
}
.project-accordion:hover {
  background-color: #c5c3be;
}
.project-accordion:hover .title,
.project-accordion:hover .name {
  font-style: italic;
}
.project-accordion.open {
  background-color: #fff !important;
}
.project-accordion.open .title,
.project-accordion.open .name {
  font-style: normal !important;
}

/* Trigger row is a 2-column grid: left half (title/name) | right half (meta).
   Grid tracks define the widths, so the children carry no widths of their own.
   minmax(0, 1fr) lets a track shrink below its content width, which is what
   prevents wide meta text from expanding a track and wrapping the row. */
.project-row {
  display: grid;
  grid-template-columns: 50% minmax(0, 1fr);
  align-items: center;
  width: 100%;
  margin: 0;
  padding: 0;
  border: none;
  background: none;
  -webkit-appearance: none;
  appearance: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

/* Left half: title + name stacked & vertically centred. Its top/bottom padding
   sets the closed row height — one text-line of breathing room above and below. */
.col-title-name {
  display: flex;
  flex-direction: column;
  justify-content: center;
  position: relative;
  padding: 2rem 2rem 2rem 2.4rem;
}
.col-title-name::after {
  content: "";
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 1px;
  height: 8rem;
  background-color: #000;
}

/* Right half: its own 4-track grid — form | format | year | plus. */
.row-right {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
  align-items: center;
  padding-right: 1.2rem;
}
.col-form,
.col-format,
.col-year {
  min-width: 0;
  padding: 0 2rem;
  white-space: pre-line;
}
.col-plus {
  display: flex;
  justify-content: flex-end;
  align-items: center;
}
.label {
  font-family: var(--font-regular);
  font-style: italic;
  font-size: var(--f-desk-small);
  line-height: var(--f-small-lh);
}
.col-title-name .title {
  font-family: var(--font-medium);
  font-weight: 500;
  font-size: var(--f-desk-big);
  line-height: var(--f-big-lh);
  letter-spacing: var(--f-big-ls);
}
.col-title-name .name {
  font-family: var(--font-regular);
  font-size: var(--f-desk-big);
  line-height: var(--f-big-lh);
  letter-spacing: var(--f-big-ls);
}
.col-form .col-text,
.col-format .col-text,
.col-year .col-text {
  font-family: var(--font-medium);
  font-weight: 500;
  font-size: var(--f-desk-small);
  line-height: var(--f-small-lh);
  letter-spacing: var(--f-small-ls);
}
.plus-icon {
  width: 8rem;
  height: 8rem;
  position: relative;
  transition: transform 0.3s ease;
}
.plus-icon::before {
  content: "";
  position: absolute;
  width: 100%;
  height: 2px;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
  background-color: #000;
}
.plus-icon::after {
  content: "";
  position: absolute;
  width: 2px;
  height: 100%;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  background-color: #000;
}
.project-accordion.open .plus-icon {
  transform: rotate(45deg);
}
.accordion-content {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease-out;
}
.project-accordion.open .accordion-content {
  max-height: 200rem;
}
.expanded-layout {
  display: flex;
  padding: 0 2.4rem 4rem;
}
.expanded-layout .expanded-left {
  width: 50%;
  padding: 0 2rem 0 0;
  display: block;
}
.project-image-wrapper {
  width: 100%;
}
.project-image-wrapper img {
  width: 100%;
  height: auto;
  display: block;
}
.project-image-wrapper .photo-credit {
  font-family: var(--font-regular);
  font-size: var(--f-desk-tiny);
  margin-top: 0.8rem;
  background: transparent;
  padding: 0;
  width: auto;
}
.expanded-layout .expanded-right {
  width: 50%;
  display: flex;
  flex-direction: column;
  padding: 0;
}
.expanded-meta-row {
  display: flex;
  width: 100%;
  margin-bottom: var(--expanded-gap);
}
.expanded-meta-row .col-form,
.expanded-meta-row .col-format,
.expanded-meta-row .col-year {
  width: 27.27%;
  padding: 0 2rem;
}
.expanded-layout .expanded-description {
  padding: 0 2rem;
}
.expanded-layout .expanded-description p {
  font-family: var(--font-regular);
  font-size: var(--f-main-size);
  line-height: var(--f-main-lh);
  letter-spacing: var(--f-main-ls);
}
.curator {
  margin-top: var(--f-main-size);
}

.mobile-bottom-info {
  display: none;
}
.mobile-center-line {
  display: none;
}

@media (max-width: 1024px) {
  .projects-page {
    padding: 5.7rem 1.6rem 10rem;
  }
  .projects-header-box {
    padding: 0.6rem 1.2rem 0.6rem 0.9rem;
  }
  .projects-header-box p {
    font-size: var(--f-mobile-big);
    line-height: var(--f-big-lh);
    letter-spacing: var(--f-big-ls);
  }
  .project-row {
    display: flex;
    padding: 0.6rem 0.6rem 0.6rem 0.9rem;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    gap: 1.4rem;
    position: relative;
  }
  .row-right {
    display: contents;
  }
  .col-title-name {
    width: 100%;
    padding: 0 4.6rem 0 0;
  }
  .col-title-name .title {
    font-size: var(--f-mobile-big);
    line-height: var(--f-big-lh);
  }
  .col-title-name .name {
    font-size: var(--f-mobile-big);
    line-height: var(--f-big-lh);
  }
  .col-title-name::after {
    display: none;
  }
  .mobile-center-line {
    display: none;
  }
  .mobile-bottom-info {
    display: block;
    width: 100%;
  }
  .meta-summary {
    font-family: var(--font-medium);
    font-size: var(--f-mobile-small);
    line-height: var(--f-small-lh);
  }
  .desktop-only {
    display: none;
  }
  .col-plus {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
    width: auto;
  }
  .plus-icon {
    width: 3.6rem;
    height: 3.6rem;
  }
  .plus-icon::before {
    height: 2px;
  }
  .plus-icon::after {
    width: 2px;
  }
  .expanded-layout {
    padding: 0 0.9rem 1.2rem;
    flex-direction: column;
  }
  .expanded-layout .expanded-left,
  .expanded-layout .expanded-right {
    width: 100%;
    padding: 0;
  }
  .expanded-meta-row {
    display: none;
  }
  .project-image-wrapper {
    width: 100%;
    margin: 0 0 1.2rem;
  }
  .project-image-wrapper .photo-credit {
    padding: 0.2rem 0;
    margin-top: 0.2rem;
    margin-bottom: 2.4rem;
    font-size: var(--f-mobile-tiny);
  }
  .expanded-layout .expanded-description {
    padding: 0;
  }
  .expanded-layout .expanded-description p,
  .curator {
    font-family: var(--font-regular);
    font-size: var(--f-mobile-normal);
    line-height: var(--f-normal-lh);
    margin-bottom: 1.4rem;
  }
  .curator {
    margin-top: 2.4rem;
  }
}

/* ============================================================
   ARCHIVE PAGE
   ============================================================ */
.archive-page {
  padding: 2rem 10rem 10rem var(--page-padding-left);
}
.years-menu {
  display: flex;
  gap: 0.1rem;
  margin-bottom: var(--expanded-gap);
  max-width: 170rem;
  width: 100%;
  margin-left: auto;
  margin-right: auto;
}
.year-link span {
  font-family: var(--font-medium);
  font-size: var(--f-desk-normal);
  line-height: var(--f-normal-lh);
  letter-spacing: var(--f-normal-ls);
  color: #000;
}
.year-link.active,
.year-link:hover {
  background-color: #c02820;
}
.year-link.active span,
.year-link:hover span {
  color: #fff;
  font-style: italic;
}
.archive-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6rem;
  max-width: 170rem;
  width: 100%;
  margin: 0 auto;
  align-items: start;
}
.archive-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
}
.archive-info {
  padding: 1.2rem 2rem 0 1rem;
  color: #fff;
  display: flex;
  flex-direction: column;
  flex-grow: 1;
}
.archive-date {
  font-family: var(--font-medium);
  font-size: var(--f-desk-small);
  line-height: var(--f-small-lh);
  letter-spacing: var(--f-small-ls);
}
.archive-title-block {
  min-height: calc(var(--f-card-title-size) * var(--f-big-lh) * 2);
}
.archive-title {
  font-family: var(--font-medium);
  font-weight: 500;
  font-size: var(--f-desk-big);
  line-height: var(--f-big-lh);
  margin: 0;
  letter-spacing: var(--f-big-ls);
  font-style: normal;
}
.archive-subtitle {
  font-family: var(--font-regular);
  font-weight: normal;
  font-style: normal;
  font-size: var(--f-desk-big);
  line-height: var(--f-big-lh);
  margin: 0.3rem 0 0;
  letter-spacing: var(--f-big-ls);
}

@media (min-width: 1025px) {
  .top-info {
    min-height: calc(var(--f-card-title-size) * 1.05 * 2 + 0.3rem);
  }
  .event-location {
    font-family: var(--font-medium);
    font-weight: 500;
    line-height: 1.05;
  }
  .event-title {
    line-height: 1.05;
    margin-top: 0.3rem;
    font-style: normal;
  }
  .news-title,
  .archive-title {
    line-height: 1.05;
  }
  .news-subtitle,
  .archive-subtitle {
    line-height: 1.05;
    margin-top: 0.3rem;
    font-style: normal;
  }
  .news-title::first-line,
  .archive-title::first-line {
    font-family: var(--font-medium);
    font-weight: 500;
  }
  .event-card:hover .event-location,
  .event-card:hover .event-title,
  .news-card:hover .news-title,
  .archive-card:hover .archive-title {
    font-style: italic;
  }
}

/* Mobile post cards (programme / events / news / archive): match the desktop
   card layout — the two big text lines sit tight together, the first line is
   bold and the second is normal (no italic), and the text area gets a tighter
   top/left padding with a little breathing room added at the bottom. */
@media (max-width: 1024px) {
  .event-location {
    font-family: var(--font-medium);
    font-weight: 500;
    line-height: 1.05;
  }
  .event-title {
    line-height: 1.05;
    margin-top: 0.3rem;
    font-style: normal;
  }
  .news-title,
  .archive-title {
    line-height: 1.05;
  }
  .news-subtitle,
  .archive-subtitle {
    line-height: 1.05;
    margin-top: 0.3rem;
    font-style: normal;
  }
  .news-title::first-line,
  .archive-title::first-line {
    font-family: var(--font-medium);
    font-weight: 500;
  }
  .info-container,
  .news-card .news-info,
  .archive-card .archive-info {
    padding: 1rem 2rem 0.8rem 0.8rem;
  }
}

.archive-meta-left {
  display: flex;
  flex-direction: column;
}
.archive-expanded-view {
  background-color: #000;
}
.archive-expanded-view .close-button svg path {
  stroke: #fff;
}
.archive-expanded-view .expanded-left {
  padding: calc(var(--expanded-gap) + 0.6rem) 6rem 0
    calc(var(--expanded-gap) * 1.5);
}
.archive-expanded-view .expanded-right {
  padding: var(--expanded-gap) var(--expanded-gap) 10rem var(--expanded-gap);
}
.main-image-wrapper {
  width: 100%;
  position: relative;
}
.gallery-stage {
  width: 100%;
  aspect-ratio: 10/9;
  position: relative;
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.gallery-stage #main-expanded-image,
.gallery-stage .gallery-main-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
.gallery-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  cursor: pointer;
  padding: 1.4rem 1.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}
.gallery-arrow img {
  display: block;
  height: 6rem;
  width: auto;
}
.gallery-arrow-prev {
  left: 0;
}
.gallery-arrow-next {
  right: 0;
}
.gallery-arrow-next img {
  transform: rotate(180deg);
}
.main-image-wrapper img {
  width: 100%;
  height: auto;
  display: block;
}
.main-image-wrapper .photo-credit {
  background: #fff;
  color: #000;
  padding: 0.4rem 0.6rem;
  font-size: var(--f-desk-tiny);
  line-height: var(--f-tiny-lh);
  width: 100%;
}
/* Expanded fullview image captions: white text, no background (they sit on the dark overlay bg).
   Scoped to .expanded-view so the light-bg visit/press pages and the projects accordion are unaffected. */
.expanded-view .photo-credit {
  background: transparent;
  color: #fff;
}
.thumbnails-container {
  padding: 1rem 0;
  display: grid;
  grid-template-columns: repeat(13, 1fr);
  grid-template-rows: repeat(2, auto);
  gap: 0.5rem;
}
@media (min-width: 1025px) {
  .gallery-stage {
    aspect-ratio: 25 / 28.35;
  } /* ~5% taller again */
  .thumbnails-container {
    padding-top: 2rem;
  } /* double the gap under the image title */
}
.thumb-item {
  width: 100%;
  aspect-ratio: 1;
  cursor: pointer;
  overflow: hidden;
  background-color: #000;
}
.thumb-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.6;
  transition: opacity 0.2s ease;
}
.thumb-item:hover img,
.thumb-item.active img {
  opacity: 1;
}
.expanded-subtitle {
  font-family: var(--font-regular);
  font-weight: 400;
  margin: 0.3rem 0 0;
  line-height: var(--f-huge-lh);
  font-style: normal;
  padding-right: calc(var(--close-x-size) + 2rem);
}
.event-location,
.event-title,
.news-title,
.news-subtitle,
.archive-title,
.archive-subtitle,
.expanded-title,
.expanded-name,
.expanded-subtitle {
  font-style: normal;
}
.event-card:hover .event-location,
.event-card:hover .event-title,
.news-card:hover .news-title,
.news-card:hover .news-subtitle,
.archive-card:hover .archive-title,
.archive-card:hover .archive-subtitle {
  font-style: italic;
}
.expanded-link {
  display: block;
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  font-size: var(--f-desk-normal);
  line-height: var(--f-normal-lh);
  letter-spacing: var(--f-normal-ls);
}
.expanded-link p,
.expanded-link a {
  margin: 0;
  font-size: inherit;
  line-height: inherit;
  letter-spacing: inherit;
}
.expanded-link:hover {
  border-bottom-color: #000;
}
.expanded-section-title {
  font-family: var(--font-regular);
  font-size: var(--f-main-size);
  margin-bottom: 0.8rem;
}
.expanded-list-text {
  font-family: var(--font-regular);
  font-size: var(--f-main-size);
  line-height: var(--f-main-lh);
  letter-spacing: var(--f-main-ls);
}
.expanded-section {
  margin-top: var(--expanded-gap);
}
.archive-venue {
  font-family: var(--font-medium);
  font-size: var(--f-desk-small);
  line-height: var(--f-small-lh);
  letter-spacing: var(--f-small-ls);
}

.gallery-view {
  position: fixed;
  inset: 0;
  background-color: #000;
  z-index: 4000;
  display: none;
  color: #fff;
}
.gallery-view.open {
  display: flex;
  align-items: center;
  justify-content: center;
}
.gallery-container {
  width: 80%;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.gallery-image-wrapper img {
  max-width: 100%;
  max-height: 70vh;
  display: block;
  object-fit: contain;
}
.gallery-close {
  position: fixed;
  top: 2rem;
  right: 2rem;
}

@media (max-width: 1024px) {
  .archive-page {
    padding: 8.5rem 3.7rem 10rem 2.7rem;
  } /* centre card incl. its 1rem 3D border */
  .years-menu {
    position: fixed;
    top: 5.7rem;
    left: 0;
    flex-direction: row;
    flex-wrap: nowrap;
    justify-content: center;
    gap: 0.1rem;
    width: 100%;
    margin-bottom: 0;
    z-index: 4500;
    padding: 0 1.6rem;
    background-color: var(--page-bg);
  }
  .year-link {
    flex: 1;
    min-width: 0;
    height: 2.8rem;
    padding-left: 0.5rem;
    border: none;
  }
  .year-link span {
    font-size: var(--f-mobile-big);
  }
  .archive-grid {
    grid-template-columns: 1fr;
    margin-top: 1.1rem;
    gap: 2.1rem;
  }
  .archive-title,
  .archive-subtitle {
    font-size: var(--f-mobile-big);
  }
  .archive-date,
  .archive-venue {
    font-size: var(--f-mobile-small);
  }
  .main-image-wrapper .photo-credit {
    font-size: var(--f-mobile-tiny);
  }
  .archive-card::after {
    bottom: -1rem;
    right: -1rem;
    height: calc(1rem + 1px);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 1.6rem 100%);
    left: 0;
  }
  .archive-card::before {
    right: -1rem;
    width: calc(1rem + 1px);
    clip-path: polygon(0 0, 100% 1.6rem, 100% 100%, 0 100%);
    top: 0;
    bottom: -2px;
  }
  .archive-expanded-view {
    z-index: 4000;
  } /* inset handled by the shared .expanded-view rule above */
  /* Match the body width to the visit accordion inset — overrides the desktop .expanded-gap
     padding which otherwise wins on specificity inside this media query */
  .archive-expanded-view .expanded-right {
    padding: 0 1rem 4rem 1rem;
  }
  /* Match the gallery's left inset to the title/body; keep the right inset for the X clearance */
  .archive-expanded-view .expanded-left {
    padding: 0 1rem 0 1rem;
  }
  /* Caption text flush with the image's left/right edge (drop its own horizontal inset) */
  .expanded-view .photo-credit {
    padding-left: 0;
    padding-right: 0;
  }
  .expanded-section,
  .expanded-body {
    margin-top: 0;
  }
  .expanded-section-title,
  .expanded-list-text,
  .expanded-description {
    font-size: var(--f-mobile-normal);
    margin-bottom: 1.33rem;
  }
  .section-separator::before,
  .section-separator::after {
    width: 10%;
  }
  .gallery-view {
    z-index: 8000;
  }
  .expanded-mobile-header .expanded-title {
    font-style: normal;
    font-size: var(--f-huge-size);
    line-height: var(--f-huge-lh);
  }
  .archive-expanded-view .expanded-mobile-header .expanded-subtitle {
    font-family: var(--font-regular);
    font-weight: 400;
    font-size: var(--f-huge-size);
    line-height: var(--f-huge-lh);
    font-style: normal;
  }
  .expanded-mobile-header .expanded-subtitle {
    font-size: var(--f-huge-size);
    line-height: var(--f-huge-lh);
    padding-right: calc(3.6rem + 1rem);
  }
  .expanded-mobile-header .expanded-meta p {
    font-size: var(--f-mobile-small);
    line-height: var(--f-small-lh);
    letter-spacing: var(--f-small-ls);
  }
  .expanded-mobile-header .expanded-link {
    font-size: var(--f-mobile-small);
  }
  .expanded-mobile-header .meta-row {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
  }
}

/* ============================================================
   CONTACT PAGE
   ============================================================ */
.contact-page {
  padding: 2rem 4rem 10rem var(--page-padding-left);
}
.content-columns {
  display: flex;
  width: 100%;
  gap: var(--expanded-gap);
}
.column-left,
.column-right {
  width: 50%;
  display: flex;
  flex-direction: column;
  gap: var(--expanded-gap);
}
.content-box {
  padding: var(--expanded-gap);
  min-height: 20rem;
}
.contact-section {
  margin-bottom: var(--section-gap);
}
.contact-section h2 {
  margin-bottom: var(--f-main-size);
}
.contact-section a {
  border-bottom: 1px solid transparent;
}
.contact-section a:hover {
  border-bottom-color: #000;
}
@media (max-width: 1024px) {
  .contact-page {
    padding: 5.7rem 2rem 10rem 1.6rem;
  }
  .content-columns {
    flex-direction: column;
    gap: 1.2rem;
  }
  .column-left,
  .column-right {
    width: 100%;
    gap: 1.2rem;
  }
  .content-box {
    padding: 1.3rem;
  }
  .contact-page .text-main,
  .contact-page h2,
  .contact-page p {
    font-size: var(--f-mobile-normal) !important;
  }
  .contact-section h2 {
    margin-bottom: var(--f-mobile-big);
  }
  .contact-page .box-3d::after {
    bottom: -0.55rem;
    right: -0.55rem;
    height: calc(0.55rem + 1px);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0.95rem 100%);
  }
  .contact-page .box-3d::before {
    right: -0.55rem;
    width: calc(0.55rem + 1px);
    clip-path: polygon(0 0, 100% 0.95rem, 100% 100%, 0 100%);
  }
}

/* ============================================================
   ABOUT PAGE
   ============================================================ */
.about-page {
  padding: 2rem var(--page-padding-left) 10rem var(--page-padding-left);
}
.about-menu {
  display: flex;
  gap: 0.1rem;
  margin-bottom: var(--expanded-gap);
  position: relative;
  z-index: 1000;
  width: 99%;
}
.menu-link {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: 0.4rem 7rem 0.4rem 0.8rem;
  background-color: #fff;
  border: none;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.2s ease;
}
.menu-link span {
  font-family: var(--font-medium);
  font-size: var(--f-main-size);
  line-height: var(--f-normal-lh);
  letter-spacing: var(--f-normal-ls);
  color: #000;
}
.menu-link.active,
.menu-link:hover {
  background-color: #000;
}
.menu-link.active span,
.menu-link:hover span {
  color: #fff;
}

.about-content .content-columns {
  display: flex;
  width: 100%;
  gap: var(--expanded-gap);
}
.about-content .column-left,
.about-content .column-right {
  width: 50%;
  display: flex;
  flex-direction: column;
  gap: var(--expanded-gap);
}
.practices-layout .column-left,
.practices-layout .column-right {
  gap: calc(var(--shadow-depth) * 2);
}
.about-content .content-box {
  padding: var(--expanded-gap);
  min-height: 20rem;
}
.about-content .content-box h2 {
  margin-bottom: var(--f-main-size);
}
.content-box.accordion {
  padding: 0;
  min-height: auto;
  cursor: pointer;
}
.accordion-header {
  padding: var(--expanded-gap);
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  border: none;
  background: none;
  text-align: left;
  cursor: pointer;
  color: inherit;
  -webkit-text-fill-color: currentColor;
}
.about-page .plus-icon {
  width: 8rem;
  height: 8rem;
  position: relative;
  transition: transform 0.3s ease;
}
.about-page .plus-icon::before {
  content: "";
  position: absolute;
  width: 100%;
  height: 2px;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
  background-color: #000;
}
.about-page .plus-icon::after {
  content: "";
  position: absolute;
  width: 2px;
  height: 100%;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  background-color: #000;
}
.about-page .content-box.accordion.open .plus-icon {
  transform: rotate(45deg);
}
.content-box.accordion .accordion-content {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease-in-out;
}
.content-box.accordion.open .accordion-content {
  max-height: 100rem;
}
.accordion-content-inner {
  padding: 0 var(--expanded-gap) var(--expanded-gap);
}
.partners-grid-box {
  padding: 0 !important;
}
.partners-layout .column-right .content-box {
  padding-top: var(--expanded-gap);
}
.partners-grid-box h2 {
  padding: var(--expanded-gap) var(--expanded-gap);
  border-bottom: 1px solid #000;
}
.about-content .content-box.partners-grid-box h2 {
  margin-bottom: 0;
}
.partners-logo-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  width: 100%;
}
.logo-item {
  position: relative;
  width: 100%;
  border-right: 1px solid #000;
  border-bottom: 1px solid #000;
}
.logo-item::before {
  content: "";
  display: block;
  padding-bottom: 100%;
}
.logo-item .logo-inner {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}
.logo-item:nth-child(5n) {
  border-right: none;
}
.partner-logo {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  filter: grayscale(1);
}
.partners-history {
  display: flex;
  flex-direction: column;
  gap: var(--section-gap);
}
.history-item .year {
  margin-bottom: 0.8rem;
}
.staff-list {
  display: flex;
  flex-direction: column;
  gap: 3.2rem;
}
.person-item {
  display: flex;
  flex-direction: column;
}
.person-item .contact {
  text-decoration: none;
  color: #000;
}
.person-item .contact:hover {
  text-decoration: underline;
}

.practices-layout .accordion-header {
  padding: 1.3rem 1.3rem 1.3rem var(--expanded-gap);
}
.practices-layout .accordion-header h2 {
  margin-bottom: 0;
} /* let align-items:center truly centre the title */
.practices-layout .accordion-content-inner {
  padding: 0 var(--expanded-gap) 1.3rem;
}
.staff-layout .column-left,
.staff-layout .column-right {
  width: 33.33%;
}

@media (max-width: 1024px) {
  .about-page {
    padding: 13.2rem 2rem 10rem 1.6rem;
  }
  .about-menu {
    position: fixed;
    top: 6.4rem;
    left: 0;
    flex-wrap: wrap;
    gap: 0.1rem;
    justify-content: flex-start;
    width: calc(100% - 2rem);
    margin-bottom: 0;
    z-index: 4500;
    padding: 0 0 0 1.6rem;
    background-color: var(--page-bg);
  }
  .menu-link {
    padding: 0.4rem 0 0.4rem 0.8rem;
    flex: 1 1 auto;
    min-width: 25%;
    border: none;
  }
  .menu-link span {
    font-size: var(--f-mobile-big);
  }
  .about-content .content-columns {
    flex-direction: column;
    gap: 1.2rem;
  }
  .about-content .column-left,
  .about-content .column-right {
    width: 100%;
    gap: 1.2rem;
  }
  .about-content .content-box:not(.partners-grid-box) {
    padding: 1.3rem;
  }
  .accordion-header {
    padding: 1.3rem;
  }
  .accordion-content-inner {
    padding: 0 1.3rem 1.3rem;
  }
  .partners-grid-box h2 {
    padding: 1.3rem;
  }
  .partners-logo-grid {
    grid-template-columns: repeat(3, 1fr);
  }
  .logo-item {
    border-right: 1px solid #000;
  }
  .logo-item:nth-child(3n) {
    border-right: none;
  }
  .logo-item:nth-child(5n) {
    border-right: 1px solid #000;
  }
  .logo-item:nth-child(5n):nth-child(3n) {
    border-right: none;
  }
  .about-page .plus-icon {
    width: 3.6rem;
    height: 3.6rem;
  }
  .about-page .plus-icon::before {
    height: 2px;
    transform: translateY(-50%);
  }
  .about-page .plus-icon::after {
    width: 2px;
    transform: translateX(-50%);
  }
  .about-page .text-main,
  .about-page .text-main-medium,
  .about-page h2,
  .about-page p,
  .about-page .role,
  .about-page .name,
  .about-page .contact {
    font-size: var(--f-mobile-normal) !important;
  }
  .about-page .box-3d::after {
    bottom: -0.55rem;
    right: -0.55rem;
    height: calc(0.55rem + 1px);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0.95rem 100%);
  }
  .about-page .box-3d::before {
    right: -0.55rem;
    width: calc(0.55rem + 1px);
    clip-path: polygon(0 0, 100% 0.95rem, 100% 100%, 0 100%);
  }
  .practices-layout .content-box.accordion {
    padding: 0.65rem;
  }
  .practices-layout .accordion-header {
    padding: 0.2rem 0.35rem;
  }
  .practices-layout .accordion-header h2 {
    margin-bottom: 0;
  }
  .practices-layout .accordion-content-inner {
    padding: 0 0.35rem 0.2rem;
  }
}

/* ============================================================
   MOBILE — GUARANTEE BOTTOM SPACING
   Placed last so its padding-bottom wins over each page's own
   padding shorthand. Ensures content clears the mobile browser chrome.
   ============================================================ */
@media (max-width: 1024px) {
  .programme-page,
  .visit-page,
  .awareness-page,
  .press-page,
  .colophon-page,
  .news-page,
  .events-page-container,
  .projects-page,
  .archive-page,
  .contact-page,
  .about-page,
  .theme-content {
    padding-bottom: 14rem;
  }

  /* Expanded card fullview body needs extra room under the browser chrome */
  .expanded-right,
  .archive-expanded-view .expanded-right {
    padding-bottom: 14rem;
  }
}
