/* Adrian Bellaire — site styles
   Palette comes from the wordmark: a near-black ground and its exact cream.
   Colour on the page comes only from cover art and photography. */

@font-face {
  font-family: 'Unison Pro';
  src: url('../assets/fonts/UnisonPro-Bold.otf') format('opentype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Unison Pro';
  src: url('../assets/fonts/UnisonPro-Light.otf') format('opentype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  --black: #121212;       /* near-black, not pure black */
  --header-black: #0D0D0D; /* a step darker than --black, for the header bar */
  --cream: #FEF9EB;
  --dust: #8E897D;        /* secondary text, 5.3:1 on --black */
  --rule: #2A2925;        /* decorative hairlines */
  --field: #6B675E;       /* form field and control borders, 3.3:1 on --black */
  --hover: #1C1C1A;       /* a step lighter than --black, for panels and placeholders */
  --error: #FF8F7E;

  --font-display: 'Anton', Impact, 'Arial Narrow', sans-serif;
  --font-text: 'Bricolage Grotesque', system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif;

  --max: 1320px;
  --gutter: clamp(20px, 4vw, 48px);
  --header-h: 54.4px;
  --dock-h: 116px; /* clearance for the floating player card + its gap from the edge */
  --ease-out: cubic-bezier(0.2, 0.7, 0.2, 1);
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: var(--header-h);
  -webkit-text-size-adjust: 100%;
}
html:has(body.has-player) { scroll-padding-bottom: calc(var(--dock-h) + 8px); }

body {
  margin: 0;
  background: var(--black);
  color: var(--cream);
  font-family: var(--font-text);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
body.has-player { padding-bottom: var(--dock-h); }

img { display: block; max-width: 100%; }
a { color: inherit; }
h1, h2, h3, p, ul, figure { margin: 0; }
[hidden] { display: none !important; }

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

/* The router moves focus to the new .view section on every navigation
   (including the very first page load) so screen readers announce it —
   but browsers disagree on whether that scripted focus counts as
   "visible", so this outline shows up inconsistently around the whole
   page. The move itself is what matters for accessibility; the ring
   around a non-interactive section isn't meaningful, so it's suppressed
   here rather than left to chance. */
.view:focus {
  outline: none;
}

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

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

.skip {
  position: absolute;
  top: -100px;
  left: var(--gutter);
  z-index: 100;
  padding: 10px 14px;
  background: var(--cream);
  color: var(--black);
  font-weight: 600;
  text-decoration: none;
}
.skip:focus { top: 12px; }

.noscript-note {
  padding-block: 24px;
  color: var(--dust);
}

/* ---------- Header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--header-black); /* solid fallback for browsers without backdrop-filter */
  border-bottom: 1px solid var(--rule);
}

/* Frosted glass: content scrolling underneath shows through, blurred. */
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .site-header {
    background: rgba(13, 13, 13, 0.72); /* matches --header-black at 72% */
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
  }
}

.header-inner {
  height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

/* Same condensed, tracked family and weight as the nav links, just bigger. */
.brand { display: flex; }
.brand img {
  display: block;
  height: 40.7px;
  width: auto;
}

.site-nav {
  display: flex;
  gap: clamp(16px, 3vw, 32px);
}

.site-nav a {
  font-family: 'Unison Pro', var(--font-text);
  padding-block: 10px;
  font-size: 10.5px;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dust);
  text-decoration: none;
  transition: color 0.15s ease;
}
.site-nav a:hover { color: var(--cream); }
.site-nav a.active { color: var(--cream); }

/* ---------- Shared ---------- */

/* Each page sits right under the sticky header now, not stacked below
   another section, so this only needs to be a page-top breathing gap. */
/* Same minimum as .hero, so the footer lands at the same place on every
   page regardless of how much content that page actually has. */
.section {
  min-height: calc(100svh - var(--header-h));
  padding-top: clamp(40px, 6vw, 72px);
}

.section-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(3rem, 9vw, 7.5rem);
  line-height: 0.9;
  letter-spacing: 0.005em;
  text-transform: uppercase;
}

/* Work and Composition share this smaller size, since the tab switch
   beside them already carries visual weight. */
.section-title--compact {
  font-size: clamp(1.9125rem, 5.1vw, 3.825rem);
}

#work-title,
#composition-title {
  font-family: 'Unison Pro', var(--font-text);
  font-weight: 700;
  font-size: clamp(1.295rem, 3.43vw, 2.59rem);
  letter-spacing: -0.01em;
}

/* Outlined rather than filled: transparent fill with a cream stroke. */
#work-title,
#composition-title {
  color: transparent;
  -webkit-text-stroke: 1px var(--cream);
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 24px;
  border: 1px solid var(--cream);
  border-radius: 2px;
  background: transparent;
  color: var(--cream);
  font: 600 16px/1 var(--font-text);
  font-stretch: 87.5%;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.button:hover { background: var(--cream); color: var(--black); }
.button[disabled] { opacity: 0.5; cursor: progress; }

.text-link {
  text-decoration: underline;
  text-decoration-color: var(--field);
  text-underline-offset: 0.2em;
  transition: text-decoration-color 0.15s ease;
}
.text-link:hover { text-decoration-color: var(--cream); }

.nowrap { white-space: nowrap; }

/* ---------- Hero ---------- */

.hero {
  position: relative;
  min-height: calc(100svh - var(--header-h));
  display: flex;
  flex-direction: column;
  padding-block: clamp(32px, 6vh, 72px) clamp(28px, 5vh, 56px);
  overflow: hidden;
}

/* The header's wordmark, static and centered, with the subtitle repeated
   around nine concentric circular paths (SVG textPath) to form rings,
   each spinning around it as one rigid formation. The ring closest to
   the logo is small, sharp and at full brightness; each ring further
   out is a little more blurred and dimmer than the last, fading
   gradually rather than reaching full blur/faintness right away.
   Adjacent rings spin in opposite directions. Rings stay within a
   bounded area sized in vmin rather than stretching out to the
   window's edges. */
.hero-orbit {
  position: absolute;
  top: 50%;
  left: 50%;
  width: clamp(360px, 100vmin, 920px);
  height: clamp(360px, 100vmin, 920px);
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 0;
}

.hero-mark {
  position: absolute;
  top: 50%;
  left: 50%;
  width: clamp(150px, 18vmin, 340px);
  height: auto;
  transform: translate(-50%, -50%);
}

.hero-orbit-rings {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* transform-box: view-box makes each ring spin around the shared circle
   center (the viewBox's own midpoint) rather than its own text bbox,
   which is what a plain CSS transform-origin would use instead. */
.hero-ring {
  transform-box: view-box;
  transform-origin: 50% 50%;
}

.hero-orbit-ring-text {
  font-family: 'Unison Pro', var(--font-text);
  font-size: 12.75px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  fill: var(--dust);
}

.hero-ring-1 { animation: hero-orbit-spin-cw 30s linear infinite; }
.hero-ring-2 { animation: hero-orbit-spin-ccw 38s linear infinite; opacity: 0.89; filter: blur(0.63px); }
.hero-ring-3 { animation: hero-orbit-spin-cw 46s linear infinite; opacity: 0.79; filter: blur(1.25px); }
.hero-ring-4 { animation: hero-orbit-spin-ccw 54s linear infinite; opacity: 0.68; filter: blur(1.88px); }
.hero-ring-5 { animation: hero-orbit-spin-cw 62s linear infinite; opacity: 0.58; filter: blur(2.5px); }
.hero-ring-6 { animation: hero-orbit-spin-ccw 70s linear infinite; opacity: 0.47; filter: blur(3.13px); }
.hero-ring-7 { animation: hero-orbit-spin-cw 78s linear infinite; opacity: 0.36; filter: blur(3.75px); }
.hero-ring-8 { animation: hero-orbit-spin-ccw 86s linear infinite; opacity: 0.26; filter: blur(4.38px); }
.hero-ring-9 { animation: hero-orbit-spin-cw 94s linear infinite; opacity: 0.15; filter: blur(5px); }

@keyframes hero-orbit-spin-cw {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

@keyframes hero-orbit-spin-ccw {
  from { transform: rotate(0deg); }
  to { transform: rotate(-360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .hero-ring { animation: none; }
}

/* Logo and CTA are centered together as one column, so the button reads
   as part of the same unit rather than a corner element. */
.hero-center {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 32px;
}

/* The drifting wordmarks pass directly behind this button at full
   brightness, so it needs its own solid ground to stay legible rather
   than the transparent fill buttons use elsewhere. */
.hero-center .button {
  background: var(--black);
  font-family: 'Unison Pro', var(--font-text);
  font-weight: 400;
  font-stretch: normal;
  min-height: 40.8px;
  padding: 0 20.4px;
  font-size: 13.6px;
}

.hero-center .button:hover {
  background: var(--cream);
}

/* ---------- Work ---------- */

/* Matches .wall's width and centering below, so the title stays locked
   to the same edges as the cover grid at every window width. */
.work-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px 48px;
  max-width: 940px;
  margin-inline: auto;
}

/* Switches between the Music Production and Composition pages. */
.tab-switch {
  display: flex;
  gap: clamp(16px, 3vw, 28px);
}

.tab-switch a {
  font-family: 'Unison Pro', var(--font-text);
  font-size: 11.9px;
  line-height: 1;
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dust);
  text-decoration: none;
  transition: color 0.15s ease;
}
.tab-switch a:hover { color: var(--cream); }
.tab-switch a.active { color: var(--cream); }

.empty-state { margin-top: clamp(40px, 5vw, 64px); }

.empty-note {
  max-width: 46ch;
  color: var(--dust);
}

.work-foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 24px;
  max-width: 940px;
  margin: clamp(54.4px, 7.65vw, 88.4px) auto 0;
  margin-bottom: calc(64px + clamp(19.2px, 2.7vw, 31.2px));
}

.work-foot .text-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 38.4px;
  padding: 0 19.2px;
  border: 1px solid var(--cream);
  border-radius: 2px;
  font-family: 'Unison Pro', var(--font-text);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--cream);
  text-decoration: none;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.work-foot .text-link:hover {
  background: var(--cream);
  color: var(--black);
}

.brands {
  max-width: 940px;
  margin: clamp(48px, 7vw, 80px) auto 0;
}

.brands-title {
  font-family: 'Unison Pro', var(--font-text);
  font-weight: 700;
  font-size: clamp(1.1rem, 2vw, 1.5rem);
  margin-bottom: clamp(20px, 3vw, 28px);
  text-align: center;
  color: transparent;
  -webkit-text-stroke: 1px var(--cream);
}

.brand-logos {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 32px 40px;
  padding: 0;
  margin: 0;
  list-style: none;
}

.brand-logos img {
  display: block;
  height: 32px;
  width: auto;
}

/* Credits: a one-off show card (Late Bloomer's three seasons share one
   composer line instead of repeating it three times) followed by a
   two-column brand/title list — two different structures on purpose,
   so the section doesn't just read as another logo row. */
.film-credits {
  max-width: 940px;
  margin: clamp(80px, 11vw, 128px) auto clamp(64px, 8vw, 96px);
}

.film-credits .brands-title {
  margin-top: clamp(56px, 8vw, 88px);
}

.film-credits .brands-title:first-child {
  margin-top: 0;
}

.credit-show {
  max-width: 560px;
  margin: 0 auto;
  padding: clamp(24px, 3.5vw, 36px) clamp(24px, 4vw, 44px);
  border: 1px solid var(--rule);
  text-align: center;
}

.credit-show-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 10px 14px;
  margin-bottom: clamp(18px, 3vw, 26px);
}

.credit-show-name {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2rem);
  letter-spacing: 0.005em;
  text-transform: uppercase;
}

.credit-show-network {
  font-family: 'Unison Pro', var(--font-text);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dust);
}

.credit-seasons {
  display: flex;
  justify-content: center;
  gap: clamp(20px, 3.5vw, 36px);
  padding: 0;
  margin: 0 0 clamp(18px, 3vw, 26px);
  list-style: none;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding-block: clamp(16px, 2.5vw, 22px);
}

.credit-seasons li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.credit-season-num {
  font-family: 'Unison Pro', var(--font-text);
  font-weight: 700;
  font-size: 15px;
}

.credit-season-eps {
  font-size: 12px;
  color: var(--dust);
}

.credit-composers {
  font-size: 14px;
  color: var(--dust);
}

.credit-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 clamp(32px, 5vw, 56px);
  padding: 0;
  margin: 0;
  list-style: none;
}

.credit-list li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding-block: 14px;
  border-bottom: 1px solid var(--rule);
}

.credit-brand {
  font-family: 'Unison Pro', var(--font-text);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  flex-shrink: 0;
}

.credit-title {
  text-align: right;
  color: var(--dust);
}

.credit-note {
  display: block;
  font-size: 12px;
  font-style: italic;
}

@media (max-width: 640px) {
  .credit-list { grid-template-columns: minmax(0, 1fr); }
  .credit-seasons { gap: clamp(16px, 6vw, 28px); }
}

/* TV + Film: one video plays large at a time, browsed via the strip
   below it — the same locked width/centering as .wall and .work-head. */
.reel {
  max-width: 940px;
  margin: clamp(20px, 2.5vw, 32px) auto 0;
  padding: clamp(24px, 3.5vw, 36px) clamp(24px, 4vw, 44px);
  border: 1px solid var(--rule);
}

.reel-stage {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(28px, 5vw, 72px);
  align-items: center;
}

.reel-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--hover);
}
.reel-frame img,
.reel-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: cover;
}

.reel-play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 64px;
  height: 64px;
  border: 0;
  border-radius: 50%;
  background: rgba(11, 11, 10, 0.72);
  color: var(--cream);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color 0.15s ease, transform 0.15s ease;
}
.reel-play:hover { background: var(--cream); color: var(--black); transform: scale(1.06); }
.reel-play svg { width: 24px; height: 24px; margin-left: 3px; }

.reel-count {
  margin-bottom: 12px;
  font-size: 14px;
  color: var(--dust);
}

.reel-project {
  font-family: 'Unison Pro', var(--font-text);
  font-weight: 700;
  font-size: clamp(1.225rem, 2.38vw, 2.1rem);
  line-height: 0.95;
  letter-spacing: 0.005em;
  text-transform: uppercase;
}

.reel-title {
  margin-top: 10px;
  font-size: 16px;
  color: var(--dust);
}

.reel-info .text-link {
  display: inline-block;
  margin-top: 20px;
}

.reel-credits {
  display: grid;
  grid-template-columns: minmax(88px, auto) 1fr;
  column-gap: 20px;
  row-gap: 12px;
  margin: 28px 0 0;
  padding-top: 24px;
  border-top: 1px solid var(--rule);
}

.reel-credits dt {
  align-self: center;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dust);
}

.reel-credits dd {
  align-self: center;
  margin: 0;
  font-size: 17px;
  color: var(--cream);
}

.reel-nav {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: clamp(28px, 4vw, 44px);
}

.reel-step {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--field);
  border-radius: 2px;
  background: none;
  color: var(--cream);
  cursor: pointer;
  transition: border-color 0.15s ease;
}
.reel-step:hover { border-color: var(--cream); }
.reel-step svg { width: 16px; height: 16px; }

.reel-strip {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  gap: 10px;
  margin: 0;
  padding: 6px 4px;
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}
.reel-strip::-webkit-scrollbar { display: none; }

.reel-thumb {
  position: relative;
  flex: none;
  display: block;
  width: clamp(96px, 12vw, 140px);
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--hover);
  opacity: 0.55;
  transition: opacity 0.15s ease, box-shadow 0.15s ease;
  scroll-snap-align: center;
}
.reel-thumb img { width: 100%; height: 100%; object-fit: cover; }
.reel-thumb:hover { opacity: 0.85; }
.reel-thumb[aria-current="true"] {
  opacity: 1;
  box-shadow: 0 0 0 2px var(--black), 0 0 0 4px var(--cream);
}

@media (max-width: 760px) {
  .reel-stage {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
  }
}

/* Cover wall */

.wall {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(24px, 3vw, 40px) clamp(16px, 2vw, 28px);
  max-width: 940px; /* covers smaller on wide screens; no effect once the grid is already narrower than this */
  margin: clamp(20px, 2.5vw, 32px) auto 0; /* auto here is what actually centers it */
  padding: 0;
  list-style: none;
}

.tile-btn {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.tile-btn:focus-visible { outline-offset: 6px; }

/* Covers stay full colour. The tilt is 3D: each one tips toward the
   pointer like a print being picked up, and settles flat when it isn't
   hovered (js/main.js sets --rx/--ry/--tilt-scale). */
.tile-art {
  position: relative;
  display: block;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--hover);
  transform: perspective(900px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)) scale(var(--tilt-scale, 1));
  transition: transform 0.5s var(--ease-out), box-shadow 0.3s var(--ease-out);
  will-change: transform;
}

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

.tile-btn.is-active .tile-art {
  box-shadow: inset 0 0 0 2px var(--cream);
}

/* Lifted shadow while hovered or focused, as if the cover tipped up off the wall. */
.tile-btn:hover .tile-art,
.tile-btn:focus-visible .tile-art {
  box-shadow: 0 22px 44px -16px rgba(0, 0, 0, 0.65);
}
.tile-btn.is-active:hover .tile-art,
.tile-btn.is-active:focus-visible .tile-art {
  box-shadow: inset 0 0 0 2px var(--cream), 0 22px 44px -16px rgba(0, 0, 0, 0.65);
}

/* Progress line for the playing track, in place of a waveform. */
.tile-progress {
  position: absolute;
  right: 10px;
  bottom: 10px;
  left: 10px;
  height: 3px;
  border-radius: 2px;
  background: rgba(254, 249, 235, 0.28);
  opacity: 0;
  transition: opacity 0.2s ease;
}
.tile-btn.is-active .tile-progress { opacity: 1; }

.tile-progress::after {
  content: "";
  display: block;
  height: 100%;
  width: var(--progress, 0%);
  border-radius: inherit;
  background: var(--cream);
}

.tile-state {
  position: absolute;
  top: 10px;
  left: 10px;
  padding: 5px 9px;
  border-radius: 2px;
  background: var(--cream);
  color: var(--black);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.tile-btn:hover .tile-state,
.tile-btn:focus-visible .tile-state,
.tile-btn.is-active .tile-state { opacity: 1; }

/* Always visible, unlike .tile-state — this marks a tile as video, it
   doesn't report a play/pause state the way the audio chip does. */
.video-badge {
  position: absolute;
  bottom: 10px;
  left: 10px;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(11, 11, 10, 0.72);
  color: var(--cream);
}
.video-badge svg { width: 13px; height: 13px; }

.tile-artist {
  display: block;
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--rule);
  font-family: 'Unison Pro', var(--font-text);
  font-weight: 700;
  font-size: 0.75rem;
  line-height: 0.95;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tile-title {
  display: block;
  margin-top: 6px;
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--dust);
  transition: color 0.15s ease;
}
.tile-btn.is-active .tile-title { color: var(--cream); }

/* ---------- About ---------- */

/* Top-anchored like Work's title: the photo (with a hairline frame offset
   behind it) beside the copy, then the artists as a row of covers below. */
.about-split {
  --about-photo-w: clamp(260px, 32vw, 400px);
  display: grid;
  grid-template-columns: var(--about-photo-w) 36.4ch;
  gap: clamp(40px, 6vw, 80px);
  align-items: stretch;
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
}

.about-photo {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
}

.about-photo::before {
  content: '';
  position: absolute;
  inset: 0;
  transform: translate(clamp(10px, 1.4vw, 18px), clamp(10px, 1.4vw, 18px));
  border: 1px solid var(--cream);
  pointer-events: none;
}

.about-photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1);
}

.about-copy {
  display: flex;
  flex-direction: column;
  max-width: 36.4ch;
}

#about-title {
  font-family: 'Unison Pro', var(--font-text);
  font-weight: 700;
  font-size: clamp(1.295rem, 3.43vw, 2.59rem);
  margin-bottom: clamp(20px, 3vw, 32px);
  color: transparent;
  -webkit-text-stroke: 1px var(--cream);
}

.about-copy p {
  margin-bottom: 20px;
  font-size: 15px;
}

.about-copy p:last-child { margin-bottom: 0; }

/* The artists sit in the leftover space below the copy, pinned to the
   bottom of the column (margin-top: auto in the flex column above) so
   the block never runs past the photo's own bottom edge. Small, quiet
   type — a footnote to the paragraphs above it, not a second headline.
   Names wrap naturally, separated by a small interpunct. */
.about-roster {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  margin: auto 0 0;
  padding: clamp(16px, 2.5vw, 24px) 0 0;
  border-top: 1px solid var(--rule);
  list-style: none;
}

.about-roster li {
  position: relative;
  font-family: 'Unison Pro', var(--font-text);
  font-size: 12.5px;
  letter-spacing: 0.02em;
  color: var(--dust);
  transition: color 0.15s ease;
}

/* A small dot after each name except the last, standing in for a comma. */
.about-roster li:not(:last-child)::after {
  content: '\00b7';
  position: absolute;
  left: calc(100% + 6px);
  color: var(--field);
}

.about-roster li:hover { color: var(--cream); }

@media (max-width: 760px) {
  .about-split {
    --about-photo-w: min(64vw, 300px);
    grid-template-columns: minmax(0, 1fr);
    width: 100%;
    gap: 56px;
  }
  .about-photo { width: var(--about-photo-w); margin-inline: auto; }
  .about-copy { max-width: none; }
}

/* ---------- Contact ---------- */

.contact-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(40px, 6vw, 96px);
  align-items: start;
}

.contact-title {
  max-width: 16ch;
  margin-bottom: 24px;
  font-family: 'Unison Pro', var(--font-text);
  font-weight: 700;
  font-size: clamp(1.598rem, 3.6vw, 3.196rem);
  line-height: 1.05;
  letter-spacing: 0.005em;
  text-transform: uppercase;
  color: transparent;
  -webkit-text-stroke: 1px var(--cream);
}

.contact-sub {
  max-width: 40ch;
  margin-bottom: 32px;
  color: var(--dust);
}

.contact-links {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 0;
  list-style: none;
}

.contact-links span { color: var(--dust); }

.contact-links a {
  font-family: 'Unison Pro', var(--font-text);
  font-weight: 400;
  font-size: 14.45px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 24px;
}

.field label {
  font-family: 'Unison Pro', var(--font-text);
  font-size: 12.75px;
  font-weight: 400;
}

.field input,
.field textarea {
  min-height: 48px;
  padding: 12px 14px;
  border: 1px solid var(--field);
  border-radius: 2px;
  background: transparent;
  color: var(--cream);
  font: inherit;
  transition: border-color 0.15s ease;
}
.field textarea { resize: vertical; }
.field input:focus,
.field textarea:focus { border-color: var(--cream); }
.field [aria-invalid="true"] { border-color: var(--error); }

.field-error {
  font-size: 15px;
  color: var(--error);
}

.contact-form .button {
  font-family: 'Unison Pro', var(--font-text);
  font-weight: 400;
  font-stretch: normal;
  font-size: 13.6px;
}

.form-status { margin-top: 16px; }
.form-status.is-error { color: var(--error); }

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

/* ---------- Footer ---------- */

/* Small and fixed, not vh-scaling — the page's own min-height (see
   .hero/.section) is what pins the footer to the bottom of the screen;
   this is just breathing room for pages whose content runs past that. */
.site-footer {
  margin-top: 24px;
  border-top: 1px solid var(--rule);
}

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: var(--header-h);
  padding-block: 8px;
  font-size: 15px;
  color: var(--dust);
}

.footer-links {
  display: flex;
  gap: 24px;
}

.footer-links a { text-decoration: none; }
.footer-links a:hover { color: var(--cream); }

/* ---------- Docked player ---------- */
/* A floating card, not a footer bar: the wrapper is transparent and lets
   clicks through everywhere except the card itself. */

.dock {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 30;
  display: flex;
  justify-content: center;
  padding: 0 var(--gutter) calc(16px + env(safe-area-inset-bottom));
  pointer-events: none;
  transform: translateY(140%);
  transition: transform 0.3s var(--ease-out);
}
.dock.is-open { transform: none; }

.dock-inner {
  width: 100%;
  max-width: 440px;
  min-height: 80px;
  border-radius: 14px;
  overflow: hidden;
  background: var(--hover);
  box-shadow: 0 16px 40px -12px rgba(0, 0, 0, 0.7);
  pointer-events: auto;
}
.dock-inner iframe { display: block; width: 100%; border: 0; }

/* ---------- Smaller screens ---------- */

@media (max-width: 1000px) {
  .wall { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Three columns leave each cover noticeably wider than the four-up
     layout, so the name can run bigger here without overflowing. */
  .tile-artist { font-size: clamp(0.6rem, 1.51vw, 0.94rem); }
}

@media (max-width: 900px) {
  .contact-grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 760px) {
}

@media (max-width: 640px) {
  .wall { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Two columns again means more room per cover than the three-column
     layout just above this breakpoint. */
  .tile-artist { font-size: clamp(0.5rem, 2.3vw, 0.92rem); }
  .tile-title { font-size: 11px; }
}

@media (max-width: 480px) {
  .site-nav a { letter-spacing: 0.08em; }
  .brand img { height: 34.1px; }
  .site-nav { gap: 14px; }

  /* At this width .hero-orbit is close to its own 360px floor, and the
     wordmark's floor (150px wide) no longer clears the innermost ring
     (30% of the orbit's own size) — they were sized for the same
     viewport-relative scaling further up but stop matching once both
     hit their floors together. Shrinking the mark and dropping the
     ring closest to it (plus the two outermost, faintest rings, which
     mostly just added visual noise at this size) fixes the crowding
     without changing anything above this breakpoint. */
  .hero-mark { width: clamp(100px, 30vw, 150px); }
  .hero-ring-1,
  .hero-ring-8,
  .hero-ring-9 { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}
