/* ==========================================================================
   Luis Fabián — site stylesheet
   Theme: CSS custom properties switched via [data-theme] on <html>.
   ========================================================================== */

:root {
  --font: 'Montserrat', sans-serif;
  --container: 1240px;
}

:root[data-theme="dark"] {
  --bg: #0C0F0F;
  --bg-alt: #121414;
  --bg-raised: #1A1C1C;
  --text: #E2E2E2;
  --muted: #918EA3;
  --accent: #4924FB;
  --accent-text: #FFFFFF;
  --accent-light: #C4C0FF;
  --focus: #C4C0FF;
  --danger: #FF8A80;
  --border: rgba(255,255,255,0.10);
  --border-strong: rgba(255,255,255,0.18);
  --stripe: rgba(255,255,255,0.05);
  --watermark: rgba(255,255,255,0.06);
  --nav-bg: rgba(12,15,15,0.72);
  --logo-src: url('../assets/logo-horizontal-dark.webp');
}

:root[data-theme="light"] {
  --bg: #FFFFFF;
  --bg-alt: #F5F5F6;
  --bg-raised: #ECEBF0;
  --text: #16181A;
  --muted: #6B6879;
  --accent: #4924FB;
  --accent-text: #FFFFFF;
  --accent-light: #3A00E2;
  --focus: #4924FB;
  --danger: #B3261E;
  --border: rgba(0,0,0,0.12);
  --border-strong: rgba(0,0,0,0.22);
  --stripe: rgba(0,0,0,0.05);
  --watermark: rgba(0,0,0,0.07);
  --nav-bg: rgba(255,255,255,0.82);
  --logo-src: url('../assets/logo-horizontal-white.webp');
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
.skip-link {
  position: absolute; top: -48px; left: 12px; z-index: 999;
  background: var(--accent); color: var(--accent-text);
  padding: 12px 20px; border-radius: 8px; font-weight: 700; font-size: 14px;
  text-decoration: none; transition: top .15s ease;
}
.skip-link:focus { top: 12px; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  transition: background .25s ease, color .25s ease;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
p { text-wrap: pretty; }
.container { max-width: var(--container); margin: 0 auto; padding: 0 40px; }

/* ---------- utility ---------- */
.muted { color: var(--muted); }
.accent { color: var(--accent-light); }
.eyebrow {
  display: flex; align-items: center; gap: 12px;
  font-size: 11px; letter-spacing: .18em; color: var(--accent-light);
  text-transform: uppercase;
}
.eyebrow__rule { width: 26px; height: 1px; background: var(--accent-light); }
.section { padding-top: 96px; padding-bottom: 96px; }
.section--alt { background: var(--bg-alt); }
.section__head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; margin-bottom: 48px; flex-wrap: wrap;
}
.section__num { font-size: 13px; color: var(--accent-light); }
.section__title {
  margin: 0; font-weight: 700; font-size: clamp(34px, 4.4vw, 56px);
  line-height: 1.05; letter-spacing: -0.03em;
}
/* clamp()'s 4.4vw mid-value only overtakes the 34px floor above ~773px,
   so every phone was stuck at a flat 34px regardless of how narrow --
   fine for short titles, but "COLABORACIONES" (the longest one on the
   site) has no more room to give at that size below ~375px and the
   browser's own line-wrap splits it mid-word (one orphaned trailing
   letter on its own line). Scaling further down on narrow phones keeps
   every title on one line with room to spare. */
@media (max-width: 640px) {
  .section__title { font-size: clamp(26px, 8vw, 40px); }
}
.section__meta { font-size: 11px; letter-spacing: .16em; color: var(--muted); text-transform: uppercase; }

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px; padding: 15px 24px; font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; border: 1px solid transparent; cursor: pointer;
  font-family: var(--font); white-space: nowrap; border-radius: 10px;
  transition: box-shadow .25s ease, border-color .25s ease, transform .15s ease;
}
.btn--primary { background: var(--accent); color: var(--accent-text); }
.btn--outline { border-color: var(--border); color: var(--text); background: transparent; }
.btn:hover { box-shadow: 0 0 28px 6px color-mix(in srgb, var(--accent) 65%, transparent); }
.btn--outline:hover { border-color: var(--accent); }
/* Homepage section header CTAs (BIOGRAFÍA/DISCOGRAFÍA/CONCIERTOS/DETRÁS DE
   ESCENA/CONTACTO -> their full pages) -- always-on brand-colored border so
   they stand out from the neutral .btn--outline used elsewhere (tickets,
   Spotify link, etc.), instead of only lighting up on hover. */
.btn--section-cta { border-color: var(--accent); color: var(--accent-light); }
.btn--section-cta:hover { border-color: var(--accent-light); color: var(--text); }
@media (prefers-reduced-motion: reduce) { .btn { transition: none; } }
/* Ticket-stub notch on the right edge, like a torn ticket. A mask-image
   gradient rendered too fuzzy/inconsistent on the thin outline border at
   normal (non-retina) resolution, so instead a half-circle matching the
   page background sits flush against the edge, "punching" a crisp notch.
   The half-circle box itself is sized to the visible shape (not a full
   circle clipped in half) so it never extends past the button — a clipped
   full circle's un-painted half still occupies layout space and silently
   overflowed the page on narrow viewports. */
.btn--ticket { position: relative; border-radius: 0; }
.btn--ticket::after {
  content: "";
  /* right:-1px (not 0) because `right` for an absolutely-positioned child
     resolves against the button's padding edge, one pixel short of its
     actual 1px border — leaving a sliver of the button's own straight
     border uncovered on the outline variant otherwise. */
  position: absolute; top: 50%; right: -1px;
  width: 11px; height: 22px;
  transform: translateY(-50%);
  background: var(--bg);
  border-top-left-radius: 11px;
  border-bottom-left-radius: 11px;
  pointer-events: none;
}
.btn--ticket.btn--outline::after { border: 1px solid var(--border); border-right: none; box-sizing: border-box; }
.btn--block { width: 100%; }
.btn--sm { padding: 11px 18px; }

/* ---------- nav ---------- */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  border-bottom: 1px solid transparent;
  background: transparent;
  transition: background .25s ease, border-color .25s ease, backdrop-filter .25s ease;
}
.nav.is-scrolled {
  border-bottom-color: var(--border);
  background: var(--nav-bg); backdrop-filter: blur(28px); -webkit-backdrop-filter: blur(28px);
}
/* On pages where a photo sits directly behind the transparent (unscrolled)
   navbar, force light nav text regardless of the site theme — theme-aware
   colors go dark in light mode and disappear against the dark photo. Once
   scrolled, the nav has its own solid theme-matched background again. */
body[data-page-title="title.home"] .nav:not(.is-scrolled) .nav__links a,
body[data-page-title="title.tour"] .nav:not(.is-scrolled) .nav__links a {
  color: rgba(255,255,255,.88);
}
body[data-page-title="title.home"] .nav:not(.is-scrolled) .nav__links a.is-active,
body[data-page-title="title.tour"] .nav:not(.is-scrolled) .nav__links a.is-active {
  color: #fff;
}
body[data-page-title="title.home"] .nav:not(.is-scrolled) .nav__logo-img,
body[data-page-title="title.tour"] .nav:not(.is-scrolled) .nav__logo-img {
  filter: drop-shadow(0 1px 5px rgba(0,0,0,.75)) drop-shadow(0 0 14px rgba(0,0,0,.45));
}
.nav__inner { display: flex; align-items: center; justify-content: space-between; padding-top: 26px; padding-bottom: 26px; gap: 24px; }
.nav__inner > a:first-child {
  flex-shrink: 0;
  position: relative;
  display: inline-flex;
  /* The logo's tall bar-chart icon pulls the image's own bounding-box
     center upward relative to where the wordmark text actually sits,
     so centering the raw image leaves the wordmark looking lower than
     the nav links/icons next to it. Nudge it up just enough to land
     the wordmark's optical center alongside theirs. */
  transform: translateY(-5px);
}
.nav__inner > a:first-child::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 42%, rgba(240,238,255,.85) 50%, transparent 58%);
  background-size: 220% 100%;
  background-position: 160% 0;
  -webkit-mask-image: var(--logo-src);
  mask-image: var(--logo-src);
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  pointer-events: none;
  animation: nav-logo-shine 6s ease-in-out infinite;
}
@keyframes nav-logo-shine {
  0%, 45% { background-position: 160% 0; }
  70%, 100% { background-position: -60% 0; }
}
.nav__logo-img {
  height: 37px; width: auto; flex-shrink: 0;
}
@media (prefers-reduced-motion: reduce) {
  .nav__inner > a:first-child::after { animation: none; display: none; }
}
.nav__links { display: flex; gap: 30px; font-size: 12px; letter-spacing: .13em; color: var(--text); text-transform: uppercase; }
.nav__links a {
  border-bottom: 1px solid transparent; padding-top: 3px; padding-bottom: 3px;
  transition: border-color .2s ease;
}
.nav__links a.is-active, .nav__links a:hover { border-color: var(--accent); }
.nav__actions { display: flex; align-items: center; gap: 12px; }

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border: 1px solid var(--border); background: transparent;
  color: var(--text); cursor: pointer; padding: 0; border-radius: 10px;
  transition: box-shadow .25s ease, border-color .25s ease;
}
.icon-btn:hover { border-color: var(--accent); box-shadow: 0 0 18px 2px color-mix(in srgb, var(--accent) 50%, transparent); }
.icon-btn svg { width: 17px; height: 17px; }
.icon-btn .icon-moon { display: none; }
:root[data-theme="dark"] .icon-btn .icon-sun { display: none; }
:root[data-theme="dark"] .icon-btn .icon-moon { display: block; }

.lang-switch { position: relative; }
.lang-switch__chip {
  display: flex; align-items: center; gap: 8px; border: 1px solid var(--border);
  background: transparent; color: var(--text); padding: 8px 12px; cursor: pointer;
  font-family: var(--font); font-size: 11px; letter-spacing: .14em; border-radius: 10px;
  transition: box-shadow .25s ease, border-color .25s ease;
}
.lang-switch__chip:hover { border-color: var(--accent); box-shadow: 0 0 18px 2px color-mix(in srgb, var(--accent) 50%, transparent); }
.lang-switch__flag { font-size: 20px; line-height: 1; }
.lang-switch__menu {
  position: absolute; top: calc(100% + 8px); left: 50%; transform: translateX(-50%); min-width: 56px;
  background: var(--nav-bg); backdrop-filter: blur(28px); -webkit-backdrop-filter: blur(28px);
  border: 1px solid var(--border); box-shadow: 0 12px 32px rgba(0,0,0,.28);
  display: flex; flex-direction: column; z-index: 60; border-radius: 10px; overflow: hidden;
}
.lang-switch__menu[hidden] { display: none; }
.lang-switch__option {
  display: flex; align-items: center; justify-content: center; padding: 12px 14px;
  font-family: var(--font); font-size: 20px; color: var(--text);
  background: none; border: none; cursor: pointer; text-align: center;
}
.lang-switch__option:hover { background: var(--bg-alt); }
.lang-switch__option.is-active { color: var(--accent-light); }

.nav__burger {
  display: none; flex-direction: column; justify-content: center; gap: 5px;
  width: 34px; height: 34px; background: none; border: none; cursor: pointer; padding: 0;
}
.nav__burger span { width: 22px; height: 1.5px; background: var(--text); display: block; }

.nav__mobile-panel { display: none; }

/* ---------- hero (home) ---------- */
.hero {
  position: relative; min-height: 820px; overflow: hidden;
  display: flex; align-items: center; justify-content: center; text-align: center;
}
.hero__bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center 28%; z-index: 0; }
.hero__scrim {
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to bottom, rgba(6,7,7,.82) 0%, rgba(6,7,7,.7) 32%, rgba(6,7,7,.74) 66%, rgba(6,7,7,.9) 100%);
}
/* Light theme: without this, the hero looked identical to dark mode after
   switching — same stark black scrim — which read as broken/unfinished.
   Layer a soft white haze over the same dark gradient so it visibly
   responds to the theme switch while keeping enough contrast for the
   white hero text. */
:root[data-theme="light"] .hero__scrim {
  background:
    linear-gradient(to bottom, rgba(255,255,255,.22) 0%, rgba(255,255,255,.1) 30%, rgba(255,255,255,.12) 65%, rgba(255,255,255,.26) 100%),
    linear-gradient(to bottom, rgba(6,7,7,.7) 0%, rgba(6,7,7,.56) 32%, rgba(6,7,7,.6) 66%, rgba(6,7,7,.76) 100%);
}
.hero__stack { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; width: 100%; }
.hero__content {
  display: flex; flex-direction: column; align-items: center; gap: 24px;
  max-width: 720px; padding-top: 160px; padding-bottom: 40px;
}
.hero .eyebrow { color: #C4C0FF; }
.hero .eyebrow__rule { background: #C4C0FF; }
.hero__title { margin: 0; font-weight: 800; font-size: clamp(52px, 8vw, 128px); line-height: 1.05; letter-spacing: -0.045em; color: #fff; }
.hero__lede { margin: 0; font-size: 18px; line-height: 1.6; color: rgba(255,255,255,.8); max-width: 520px; }
.hero__ctas { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 4px; justify-content: center; }
.hero .btn--outline { border-color: rgba(255,255,255,.45); color: #fff; }
.hero__nowplaying {
  display: flex; align-items: center; gap: 16px; justify-content: center;
  padding-bottom: 56px;
  background: none; border: none; cursor: pointer; font: inherit; padding-left: 0; padding-right: 0;
}
.eq.is-paused span { animation-play-state: paused; }
.eq--mini { height: 16px; gap: 2px; }
.eq--mini span { width: 3px; }
.icon-btn.audio-mini { position: relative; }
.hero__nowplaying-label { font-size: 11px; letter-spacing: .16em; color: rgba(255,255,255,.7); text-transform: uppercase; }
.eq { display: flex; align-items: flex-end; gap: 3px; height: 26px; }
.eq span { width: 4px; background: var(--accent); animation: eq 1.1s ease-in-out infinite; }
.eq span:nth-child(1) { height: 10px; animation-delay: -0.9s; }
.eq span:nth-child(2) { height: 22px; animation-delay: -0.4s; }
.eq span:nth-child(3) { height: 16px; animation-delay: -0.6s; }
.eq span:nth-child(4) { height: 26px; background: var(--accent-light); animation-delay: -0.1s; }
.eq span:nth-child(5) { height: 8px; animation-delay: -1.1s; }
@keyframes eq { 0%, 100% { transform: scaleY(0.4); } 50% { transform: scaleY(1); } }
@media (prefers-reduced-motion: reduce) { .eq span { animation: none; transform: scaleY(0.7); } }

/* ---------- floating radio player (bottom-right, all pages) ---------- */
.fplayer {
  position: fixed; right: 53px; bottom: 56px; z-index: 45;
  display: flex; flex-direction: column-reverse; align-items: flex-end; gap: 6px;
  font-family: var(--font);
  /* The column-reverse flex box sizes itself to fit the panel row even
     while the panel is collapsed (opacity:0/pointer-events:none), so its
     own empty area would otherwise sit in front of page content below it
     (any element with pointer-events left at the auto default still
     catches clicks across its whole box, painted content or not) and
     silently swallow taps meant for whatever is underneath. Each
     interactive child re-enables pointer-events for itself. */
  pointer-events: none;
}
.fplayer[hidden] { display: none; }

.fplayer__fab {
  flex: none; width: 79px; height: 79px; padding: 4px; border-radius: 50%;
  border: 1px solid var(--border); background: transparent; cursor: pointer;
  box-shadow: 0 8px 24px rgba(0,0,0,.35);
  transition: box-shadow .25s ease, border-color .25s ease;
  pointer-events: auto;
}
.fplayer__fab:hover { border-color: var(--accent); box-shadow: 0 0 22px 4px color-mix(in srgb, var(--accent) 55%, transparent), 0 8px 24px rgba(0,0,0,.35); }
.fplayer__disc { display: block; width: 100%; height: 100%; }

/* "Now playing" bubble: appears once above the fab right after the page
   loads and picks a track, so a visitor knows what's about to play before
   ever opening the panel. Stays a permanent node (like .fplayer__panel)
   so it can fade in/out with a transition instead of snapping via [hidden].
   Positioned out of the fab/panel flex flow (rather than stacked as a
   third flex item) -- as a flex sibling it kept reserving its own height
   even while invisible, stacking an extra gap on top of the fab-panel
   one and leaving a large empty band between the fab and the opened
   panel. Anchored directly above the fab (79px tall + 6px gap) instead. */
.fplayer__bubble {
  position: absolute; right: 0; bottom: 85px; max-width: 220px; padding: 10px 14px 11px; border-radius: 12px;
  background: var(--nav-bg); backdrop-filter: blur(28px); -webkit-backdrop-filter: blur(28px);
  border: 1px solid var(--border); box-shadow: 0 12px 32px rgba(0,0,0,.35);
  font-size: 12px; line-height: 1.4; color: var(--muted);
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateY(6px) scale(.97);
  transition: opacity .3s ease, transform .3s ease, visibility 0s linear .3s;
}
.fplayer__bubble.is-visible {
  opacity: 1; visibility: visible; pointer-events: auto; cursor: pointer;
  transform: translateY(0) scale(1);
  transition: opacity .3s ease, transform .3s ease;
}
.fplayer__bubble strong { color: var(--text); font-weight: 700; }
.fplayer__bubble::after {
  content: ''; position: absolute; top: 100%; right: 28px; width: 12px; height: 12px; margin-top: -6px;
  background: var(--nav-bg); border-right: 1px solid var(--border); border-bottom: 1px solid var(--border);
  transform: rotate(45deg);
}
@media (prefers-reduced-motion: reduce) { .fplayer__bubble { transition: none; } }
@media (max-width: 640px) { .fplayer__bubble { max-width: 180px; font-size: 11px; } }
.fplayer.is-playing .fplayer__disc { animation: fplayer-spin 3s linear infinite; }
@keyframes fplayer-spin { to { transform: rotate(360deg); } }

.fplayer__panel {
  width: 288px; max-width: calc(100vw - 48px);
  display: flex; flex-direction: column; gap: 12px; padding: 16px; border-radius: 18px;
  background: var(--nav-bg); backdrop-filter: blur(28px); -webkit-backdrop-filter: blur(28px);
  border: 1px solid var(--border); box-shadow: 0 20px 48px rgba(0,0,0,.35);
  transform-origin: bottom right; opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateY(10px) scale(.96);
  transition: opacity .18s ease, transform .18s ease, visibility 0s linear .18s;
}
.fplayer.is-open .fplayer__panel {
  opacity: 1; visibility: visible; pointer-events: auto; transform: translateY(0) scale(1);
  transition: opacity .18s ease, transform .18s ease;
}

.fplayer__head { display: flex; align-items: center; gap: 10px; }
.fplayer__cover {
  flex: none; width: 44px; height: 44px; border-radius: 8px; object-fit: cover;
  background: var(--bg-alt); border: 1px solid var(--border);
}
.fplayer__meta { flex: 1; min-width: 0; }
.fplayer__title { margin: 0; font-size: 13px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fplayer__artist { margin: 2px 0 0; font-size: 10px; letter-spacing: .1em; color: var(--muted); text-transform: uppercase; }

.fplayer__iconbtn {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 8px; border: none; padding: 0;
  background: transparent; color: var(--text); cursor: pointer;
  transition: background .2s ease, color .2s ease;
}
.fplayer__iconbtn svg { width: 16px; height: 16px; }
/* Chromium's UA stylesheet doesn't apply [hidden]'s display:none to bare
   <svg> root elements (only to HTML elements), so the play/pause and
   repeat/shuffle icon swaps need it spelled out explicitly here. */
.fplayer__iconbtn svg[hidden] { display: none; }
.fplayer__iconbtn:hover { background: var(--bg-alt); color: var(--accent-light); }
.fplayer__iconbtn[aria-pressed="true"] { color: var(--accent-light); }
.fplayer__iconbtn--play { width: 42px; height: 42px; border-radius: 50%; background: var(--accent); color: var(--accent-text); }
.fplayer__iconbtn--play:hover { background: var(--accent); box-shadow: 0 0 18px 3px color-mix(in srgb, var(--accent) 55%, transparent); }
.fplayer__iconbtn--play svg { width: 17px; height: 17px; }

.fplayer__progress { display: flex; align-items: center; gap: 8px; }
.fplayer__time { flex: none; font-size: 10px; color: var(--muted); font-variant-numeric: tabular-nums; }
.fplayer__range {
  flex: 1; height: 4px; border-radius: 999px; background: var(--border-strong);
  appearance: none; -webkit-appearance: none; outline: none; cursor: pointer;
}
.fplayer__range::-webkit-slider-thumb {
  -webkit-appearance: none; width: 11px; height: 11px; border-radius: 50%;
  background: var(--accent-light); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-light) 35%, transparent);
  cursor: pointer;
}
.fplayer__range::-moz-range-thumb { width: 11px; height: 11px; border-radius: 50%; background: var(--accent-light); border: none; cursor: pointer; }

.fplayer__controls { display: flex; align-items: center; justify-content: center; gap: 4px; }

.fplayer__list {
  max-height: 220px; overflow-y: auto; display: flex; flex-direction: column; gap: 4px;
  margin-top: 2px; padding-top: 10px; border-top: 1px solid var(--border);
}
.fplayer__list[hidden] { display: none; }
.fplayer__list-group { margin: 6px 0 0; padding: 4px 8px 2px; font-size: 10px; letter-spacing: .12em; color: var(--muted); text-transform: uppercase; }
.fplayer__list-item {
  display: block; width: 100%; text-align: left; background: none; border: none;
  padding: 8px; border-radius: 8px; font-family: var(--font); font-size: 12px; line-height: 1.35;
  color: var(--text); cursor: pointer; white-space: normal; word-break: break-word;
}
.fplayer__list-item:hover { background: var(--bg-alt); }
.fplayer__list-item.is-current { color: var(--accent-light); font-weight: 700; }

@media (max-width: 640px) {
  .fplayer { right: 24px; bottom: 28px; }
  .fplayer__panel { width: calc(100vw - 32px); }
}
@media (prefers-reduced-motion: reduce) {
  .fplayer.is-playing .fplayer__disc { animation: none; }
  .fplayer__panel { transition: none; }
}

/* ---------- page hero (internal pages) ---------- */
.pagehero {
  position: relative; overflow: hidden; border-bottom: 1px solid var(--border);
}
.pagehero--text {
  padding: 150px 0 70px; background: var(--bg-alt);
}
.pagehero--text .pagehero__glow {
  position: absolute; left: 50%; top: -320px; width: 820px; height: 820px; transform: translateX(-50%);
  background: radial-gradient(circle, color-mix(in srgb, var(--accent) 22%, transparent) 0%, transparent 68%);
}
.pagehero--photo { height: 500px; border-radius: 0 0 32px 32px; }
.pagehero--photo img { width: 100%; height: 100%; object-fit: cover; }
.pagehero--photo::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to top, var(--bg), rgba(0,0,0,0.12) 55%, rgba(0,0,0,0.3));
}
:root[data-theme="light"] .pagehero--photo::after {
  background: linear-gradient(to top, var(--bg), rgba(255,255,255,0.1) 55%, rgba(255,255,255,0.25));
}
.pagehero--photo.pagehero--xl { height: 610px; }
.pagehero--photo.pagehero--music { height: 670px; }
.pagehero--photo.pagehero--tall { height: 640px; }
.pagehero--photo.pagehero--tall::after {
  background: linear-gradient(to top, var(--bg), rgba(0,0,0,0.4) 45%, rgba(0,0,0,0.65));
}
:root[data-theme="light"] .pagehero--photo.pagehero--tall::after {
  background: linear-gradient(to top, var(--bg), rgba(255,255,255,0.32) 45%, rgba(255,255,255,0.55));
}
@media (max-width: 640px) {
  .pagehero--photo.pagehero--tall { height: 520px; }
}
.pagehero__inner {
  position: relative; z-index: 2; display: flex; flex-direction: column; gap: 16px;
}
.pagehero--photo .pagehero__inner { position: absolute; left: 0; right: 0; bottom: 44px; padding: 0 40px; }
.breadcrumb { display: flex; gap: 10px; font-size: 11px; letter-spacing: .16em; color: var(--muted); text-transform: uppercase; }
.pagehero__title { margin: 0; font-weight: 800; font-size: clamp(48px, 7vw, 104px); line-height: 0.94; letter-spacing: -0.045em; }
.pagehero__lede { margin: 0; font-size: 18px; line-height: 1.6; color: var(--muted); max-width: 620px; }
.pagehero__tag { position: absolute; right: 40px; bottom: 44px; z-index: 2; font-size: 12px; letter-spacing: .16em; color: var(--muted); text-transform: uppercase; }

/* ---------- stats ---------- */
.stats { display: grid; grid-template-columns: repeat(4,1fr); border-bottom: 1px solid var(--border); background: var(--bg); }
.stats__item { padding: 40px; border-right: 1px solid var(--border); text-align: center; }
.stats__item:last-child { border-right: none; }
.stats__num { font-weight: 700; font-size: clamp(30px, 3.6vw, 52px); letter-spacing: -0.03em; font-variant-numeric: tabular-nums; line-height: 1; }
.stats__label { margin-top: 8px; font-size: 11px; letter-spacing: .16em; color: var(--muted); text-transform: uppercase; }

/* ---------- stats count-up: NumberFlow-style digit reels. Each digit is a
   masked vertical strip of 0-9 that slides to the current value via a CSS
   transition (not a replayed keyframe), so fast counting reads as smooth
   motion and it settles cleanly -- restarting a fade/flash on every tick
   made the whole number flutter instead. ---------- */
.stat-reel { position: relative; display: inline-block; width: 1ch; height: 1em; overflow: hidden; vertical-align: top; }
.stat-reel__strip { display: block; transition: transform .06s linear; will-change: transform; }
.stat-reel__strip span { display: block; height: 1em; line-height: 1; text-align: center; }
.stat-static { display: inline-block; }
@media (prefers-reduced-motion: reduce) {
  .stat-reel__strip { transition: none; }
}

/* ---------- title hover text-roll: each letter sits in a masked box holding
   two stacked copies. On hover the top copy slides up and out while the
   bottom copy slides up into place, staggered outward from the center of
   the word so the wave reads as coming from the middle. Touch devices can't
   hover, so main.js instead adds .is-active to the title once as it first
   scrolls into view, playing the same motion without a pointer. ---------- */
.section__title, .pagehero__title, .hero__title {
  /* Splitting the text into one inline-block per letter (below) already
     disables kerning between them. Disabling it here too, on the plain
     text main.js measures line-wrapping against before splitting, keeps
     that measurement's width matching what the split letters actually
     render at -- otherwise a line measured as fitting can come out a
     hair wider once split, and the excess gets clipped by .text-roll's
     overflow:hidden instead of wrapping. */
  font-kerning: none;
}
.text-roll {
  position: relative; display: inline-block; overflow: hidden; vertical-align: top; white-space: nowrap;
  /* A bold glyph's painted ink can extend a little past its own advance-
     width box (most visible on rounded letters like O/A). Mid-word that
     overhang just paints into the next letter's box unnoticed, but the
     last letter has nothing to its right to bleed into except this
     mask's own edge, which clipped it. This trailing buffer gives it
     room; it's transparent space, so left-aligned text still starts in
     the same place. */
  padding-right: 0.06em;
}
.text-roll--block { display: block; }
.tr-row { display: block; }
.tr-row--bottom { position: absolute; inset: 0; }
.tr-letter { display: inline-block; transition: transform .45s ease-in-out; will-change: transform; }
.tr-row--top .tr-letter { transform: translateY(0); }
/* The hidden copy sits a bit past 100% (not exactly 100%) so a tall
   diacritic (Á, Í...) that renders slightly past its own line-height box
   still clears the mask instead of leaving a sliver poking out at rest. */
.tr-row--bottom .tr-letter { transform: translateY(calc(100% + 0.15em)); }
.text-roll:hover .tr-row--top .tr-letter,
.is-active .tr-row--top .tr-letter { transform: translateY(calc(-100% - 0.15em)); }
.text-roll:hover .tr-row--bottom .tr-letter,
.is-active .tr-row--bottom .tr-letter { transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .tr-letter { transition: none; }
}
@media (hover: none) {
  .text-roll:hover .tr-row--top .tr-letter, .text-roll:hover .tr-row--bottom .tr-letter { transform: none; }
}

/* ---------- bio ---------- */
.bio { position: relative; display: grid; grid-template-columns: 1fr 1fr; gap: 56px; }
.bio__copy { display: flex; flex-direction: column; gap: 26px; max-width: 520px; }
.bio__copy p { margin: 0; font-size: 18px; line-height: 1.65; color: var(--muted); }
.factlist { display: flex; flex-direction: column; margin-top: 8px; }
.factlist__row {
  display: flex; justify-content: space-between; padding: 18px 0; border-top: 1px solid var(--border);
  font-size: 16px;
}
.factlist__row:last-child { border-bottom: 1px solid var(--border); }
.factlist__label { font-size: 12px; letter-spacing: .12em; color: var(--muted); text-transform: uppercase; }
.bio__gallery { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 220px 300px; gap: 16px; }
.bio__gallery figure { margin: 0; overflow: hidden; border-radius: 12px; }
.bio__gallery figure img { width: 100%; height: 100%; object-fit: cover; object-position: center; }
.bio__gallery figure.is-top img { object-position: center 0%; }
.bio__gallery figure.span2 { grid-column: span 2; }
img.pos-top { object-position: center 15%; }

.bio-hero { display: grid; grid-template-columns: 1fr 480px; gap: 64px; align-items: start; }
.bio-hero__photo { height: 520px; overflow: hidden; border-radius: 12px; }
.bio-hero__photo img { width: 100%; height: 100%; object-fit: cover; }

/* ---------- bio page: full-bleed banner + alternating split blocks ---------- */
.bio-banner { position: relative; margin: 0 calc(50% - 50vw); width: 100vw; height: 620px; overflow: hidden; }
.bio-banner img { width: 100%; height: 100%; object-fit: cover; }
.bio-banner::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to top, var(--bg), rgba(0,0,0,0.05) 40%, transparent 68%);
}
:root[data-theme="light"] .bio-banner::after {
  background: linear-gradient(to top, var(--bg), rgba(255,255,255,0.05) 40%, transparent 68%);
}
.bio-banner__tag {
  position: absolute; right: 40px; bottom: 28px; z-index: 2;
  font-size: 12px; letter-spacing: .16em; color: #fff; text-transform: uppercase;
  text-shadow: 0 2px 14px rgba(0,0,0,0.65);
}

.bio-split { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: start; }
.bio-split__photo { height: 420px; overflow: hidden; border-radius: 12px; }
.bio-split__photo img { width: 100%; height: 100%; object-fit: cover; object-position: center; }
.bio-split__photo.is-top img { object-position: center 0%; }
.bio-split__copy { display: flex; flex-direction: column; gap: 22px; }
.bio-split__copy p { margin: 0; font-size: 17px; line-height: 1.7; color: var(--muted); }
.bio-split__copy--lg p { font-size: 19px; }
.bio-split__copy--md p { font-size: 19px; }
.bio-split__media { display: flex; flex-direction: column; gap: 16px; }

.pull-quote {
  margin: 0; padding-left: 20px; border-left: 3px solid var(--accent);
  font-weight: 600; font-size: 21px; line-height: 1.55; letter-spacing: -0.01em; color: var(--text);
}
.badge {
  display: inline-flex; align-items: center; gap: 8px; font-size: 11px; letter-spacing: .12em;
  color: var(--accent-light); text-transform: uppercase;
}
.link-arrow { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; letter-spacing: .04em; color: var(--accent-light); font-weight: 600; transition: gap .2s ease; }
.link-arrow:hover { gap: 12px; }

.bio-mosaic { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: 56px; align-items: center; }
.bio-mosaic__quote { margin: 0; font-weight: 600; font-style: italic; font-size: clamp(24px, 2.6vw, 34px); line-height: 1.4; letter-spacing: -0.01em; text-align: left; }
.bio-mosaic__photo {
  aspect-ratio: 4 / 5; max-height: 480px; justify-self: end; width: 100%; max-width: 400px;
  border-radius: 22px; overflow: hidden; border: 2px solid var(--accent-light);
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent-light) 10%, transparent), 0 20px 50px -24px color-mix(in srgb, var(--accent) 70%, transparent);
}
.bio-mosaic__photo img { width: 100%; height: 100%; object-fit: cover; object-position: center 20%; display: block; }
.bio-mosaic__quote-accent { color: var(--accent); }
:root[data-theme="dark"] .bio-mosaic__quote-accent { color: var(--accent-light); }

/* ---------- bio content module: thin bordered card wrapping each section
   of the biography (roots, career, turning point, timeline, etc.), all
   sitting on the same background instead of alternating stripes. ---------- */
.bio-module { padding: 56px; border: 1px solid var(--accent); border-radius: 28px; margin-bottom: 40px; }
.bio-module:last-of-type { margin-bottom: 0; }
/* Body copy reads lighter than the sitewide --muted tone here specifically
   -- these are long paragraphs meant to be read carefully, not de-emphasized
   metadata, so they get a whiter, higher-contrast shade. Bolded phrases
   inside them pop in the brand accent instead of just a heavier weight. */
.bio-module p.muted, .bio-split__copy p { color: color-mix(in srgb, var(--text) 70%, var(--muted) 30%); }
.bio-module strong { color: var(--accent-light); font-weight: 700; }

/* ---------- image placeholder: stands in for a photo slot that hasn't
   been filled yet -- same footprint as the real photo would have, so
   swapping one in later is a one-line change. ---------- */
.img-placeholder {
  width: 100%; height: 100%; min-height: inherit; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 10px;
  background: var(--bg-alt); border: 1px dashed var(--border-strong);
  color: var(--muted); border-radius: inherit;
}
.img-placeholder svg { width: 30px; height: 30px; opacity: .55; }
.img-placeholder span { font-size: 11px; letter-spacing: .12em; text-transform: uppercase; text-align: center; padding: 0 12px; }
.img-placeholder--wide { height: 420px; border-radius: 16px; }

/* ---------- collaborations collage: grid of rounded photo tiles with the
   artist's name underneath -- photos are placeholders until supplied. ---------- */
.bio-collab__intro { margin: 20px 0 32px; font-size: 15px; }
.collab-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 32px 24px; }
.collab-grid__item { display: flex; flex-direction: column; align-items: center; gap: 14px; text-align: center; }
.collab-grid__photo {
  position: relative; width: 100%; aspect-ratio: 1 / 1; border-radius: 20px; overflow: hidden;
  transition: box-shadow .35s ease, transform .45s cubic-bezier(.2,.8,.2,1);
}
.collab-grid__photo img {
  width: 100%; height: 100%; object-fit: cover; object-position: center;
  transform: scale(var(--z, 1)); transition: transform .8s cubic-bezier(.2,.8,.2,1);
}
/* a light sheen sweeps across the photo on hover */
.collab-grid__photo::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 32%, rgba(255,255,255,.22) 50%, transparent 68%);
  transform: translateX(-130%); transition: transform .9s cubic-bezier(.2,.8,.2,1);
}
.collab-grid__item:hover .collab-grid__photo {
  transform: translateY(-6px);
  box-shadow: 0 0 0 1px var(--accent), 0 0 26px 6px color-mix(in srgb, var(--accent) 55%, transparent);
  animation: collab-glow 1.6s ease-in-out infinite alternate;
}
.collab-grid__item:hover .collab-grid__photo img { transform: scale(calc(var(--z, 1) * 1.14)); }
.collab-grid__item:hover .collab-grid__photo::after { transform: translateX(130%); }
.collab-grid__name { transition: color .3s ease; }
.collab-grid__item:hover .collab-grid__name { color: var(--accent-light); }
@keyframes collab-glow {
  from { box-shadow: 0 0 0 1px var(--accent), 0 0 18px 3px color-mix(in srgb, var(--accent) 45%, transparent); }
  to { box-shadow: 0 0 0 2px var(--accent-light), 0 0 36px 10px color-mix(in srgb, var(--accent) 65%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .collab-grid__item:hover .collab-grid__photo { animation: none; transform: none; }
  .collab-grid__photo img, .collab-grid__photo::after { transition: none; }
}
/* Per-photo crop tweaks: some uploads are portrait crops (centering
   vertically would leave too much empty background below the face) or
   show the artist small in frame -- object-position biases which part
   stays in the square crop, and scale() zooms in past what cover alone
   can do. Tuned by eye against each specific photo. */
.collab-grid__photo--zoom-md { --z: 1.25; }
.collab-grid__photo--horly { --z: 1.6; }
.collab-grid__photo--horly img { object-position: center 20%; }
.collab-grid__photo--lisandro { --z: 1.15; }
.collab-grid__photo--lisandro img { object-position: center 15%; }
.collab-grid__photo--silvestre img { object-position: center 8%; }
.collab-grid__photo .img-placeholder { border-radius: 20px; }
.collab-grid__photo .img-placeholder svg { width: 24px; height: 24px; }
.collab-grid__photo .img-placeholder span { font-size: 10px; }
.collab-grid__name { font-weight: 600; font-size: 14px; letter-spacing: -0.01em; color: var(--text); }

/* ---------- timeline: vertical spine with alternating left/right cards,
   each pairing a photo with a colored copy block. The spine's fill grows
   from 0 to full height as the section scrolls through view (JS drives
   .timeline__spine-fill's height from initTimelineScrollLine in main.js).
   Each year -- already the thing sitting on the spine, breaking the line
   at every stop -- lights up in brand purple once the fill reaches it,
   visually connecting the cards on-brand instead of the reference
   component's purple-to-blue demo gradient and separate dot markers
   (which would only sit on top of the year digits here). ---------- */
.timeline { position: relative; display: flex; flex-direction: column; gap: 48px; }
.timeline__spine {
  position: absolute; left: 50%; top: 0; bottom: 0; width: 3px; overflow: hidden;
  background: var(--border); transform: translateX(-1.5px); border-radius: 3px;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 10%, black 90%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, black 10%, black 90%, transparent 100%);
}
.timeline__spine-fill {
  position: absolute; inset-inline: 0; top: 0; height: 0; width: 100%; opacity: 0;
  background: linear-gradient(to bottom, var(--accent) 0%, var(--accent-light) 25%, var(--accent) 50%, var(--accent-light) 75%, var(--accent) 100%);
  background-size: 100% 320px; animation: spine-flow 2.8s linear infinite;
  border-radius: 3px;
}
@keyframes spine-flow { to { background-position: 0 320px; } }
/* glowing point riding the leading edge of the fill */
.timeline__head {
  position: absolute; left: 50%; top: 0; z-index: 3; width: 14px; height: 14px; margin-top: -7px;
  border-radius: 50%; background: #fff; pointer-events: none; opacity: 0;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent-light) 45%, transparent), 0 0 24px 8px color-mix(in srgb, var(--accent) 75%, transparent);
  transition: opacity .3s ease;
}
.timeline__head.is-on { opacity: 1; }
.timeline__head::after {
  content: ''; position: absolute; inset: -6px; border-radius: 50%;
  border: 2px solid var(--accent-light); animation: head-pulse 1.8s ease-out infinite;
}
@keyframes head-pulse { from { transform: scale(.6); opacity: .9; } to { transform: scale(2.4); opacity: 0; } }
.timeline__row {
  position: relative; display: grid; grid-template-columns: 1fr 96px 1fr; align-items: center; column-gap: 28px;
  opacity: 0; transform: translateY(28px); transition: opacity .6s ease, transform .6s ease;
}
.timeline__row.is-visible { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) { .timeline__row { transition: none; } }
.timeline__year {
  grid-column: 2; grid-row: 1; justify-self: center; text-align: center; font-weight: 800; font-size: 20px;
  letter-spacing: -0.02em; color: var(--muted); position: relative; z-index: 2;
  background: var(--bg); border: 1px solid var(--border-strong); border-radius: 999px; padding: 8px 16px;
  transition: color .4s ease, background .5s ease, border-color .4s ease, box-shadow .5s ease, transform .5s cubic-bezier(.34,1.56,.64,1);
}
.timeline__year.is-active {
  color: #fff; border-color: transparent; transform: scale(1.08);
  background: linear-gradient(135deg, var(--accent) 0%, color-mix(in srgb, var(--accent) 55%, #b9a8ff) 100%);
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 16%, transparent), 0 0 30px 6px color-mix(in srgb, var(--accent) 50%, transparent);
}
/* one ripple each time a year lights up */
.timeline__year::after {
  content: ''; position: absolute; inset: -2px; border-radius: inherit; pointer-events: none;
  border: 2px solid var(--accent-light); opacity: 0;
}
.timeline__year.is-active::after { animation: year-ripple 1s ease-out 1; }
@keyframes year-ripple { from { opacity: .9; transform: scale(1); } to { opacity: 0; transform: scale(1.7); } }
/* connector stroke drawn from the year to its card */
.timeline__row::before {
  content: ''; position: absolute; top: 50%; height: 2px; width: 34px; margin-top: -1px; z-index: 1;
  background: linear-gradient(90deg, var(--accent), var(--accent-light));
  transform: scaleX(0); transition: transform .6s cubic-bezier(.2,.8,.2,1) .15s;
}
.timeline__row--right::before { left: calc(50% + 42px); transform-origin: left center; }
.timeline__row--left::before { right: calc(50% + 42px); transform-origin: right center; }
.timeline__row.is-lit::before { transform: scaleX(1); }
.timeline__row.is-lit .timeline__card { border-color: var(--accent-light); box-shadow: 0 18px 44px -22px color-mix(in srgb, var(--accent) 80%, transparent); }
@media (prefers-reduced-motion: reduce) {
  .timeline__year, .timeline__row::before { transition: none; }
  .timeline__year.is-active::after, .timeline__head::after, .timeline__spine-fill { animation: none; }
}
/* grid-row:1 pins both to the same row explicitly -- without it, the
   left-row card (grid-column:1, placed *after* the year in source order,
   which already advanced the auto-placement cursor to column 2) can't
   backfill column 1 on that row under sparse packing and drops to a
   second row instead, throwing off the year/card alignment. */
.timeline__card { display: flex; align-items: stretch; grid-row: 1; height: 220px; border: 1px solid var(--accent); border-radius: 14px; overflow: hidden; transition: box-shadow .4s ease, border-color .4s ease; }
.timeline__card:hover { box-shadow: 0 0 28px 6px color-mix(in srgb, var(--accent) 65%, transparent); }
@media (prefers-reduced-motion: reduce) { .timeline__card { transition: none; } }
.timeline__row--left .timeline__card { grid-column: 1; }
.timeline__row--right .timeline__card { grid-column: 3; }
.timeline__photo { width: 44%; flex-shrink: 0; }
.timeline__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.timeline__copy {
  flex: 1; min-width: 0; background: var(--bg-alt); padding: 18px 20px;
  display: flex; flex-direction: column; justify-content: center; gap: 8px;
}
.timeline__event { font-weight: 700; font-size: 17px; letter-spacing: -0.01em; }
.timeline__detail { font-size: 13px; line-height: 1.55; color: var(--muted); }

/* ---------- quote ---------- */
.quote { display: grid; grid-template-columns: 1fr 380px; gap: 56px; align-items: center; }
.quote blockquote { margin: 0; font-weight: 600; font-size: clamp(26px, 3vw, 40px); line-height: 1.3; letter-spacing: -0.025em; }
.quote__photo { height: 380px; overflow: hidden; border-radius: 12px; }
.quote__photo img { width: 100%; height: 100%; object-fit: cover; }

/* ---------- pager ---------- */
.pager { display: grid; grid-template-columns: 1fr 1fr; border-top: 1px solid var(--border); }
.pager__link { padding: 44px 40px; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.pager__link--prev { border-right: 1px solid var(--border); }
.pager__link--next { align-items: flex-end; text-align: right; }
.pager__cue { font-size: 11px; letter-spacing: .16em; color: var(--muted); text-transform: uppercase; }
.pager__name { font-weight: 700; font-size: 28px; letter-spacing: -0.02em; }

/* ---------- footer ---------- */
.footer { padding: 48px 0; border-top: 1px solid var(--border); background: var(--bg-alt); }
.footer__inner { display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.footer__logo { height: 41px; width: auto; flex-shrink: 0; }
.footer__logo-link { display: inline-flex; flex-shrink: 0; }
.footer__logo-link:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; border-radius: 4px; }
.footer__copy { font-size: 11px; letter-spacing: .14em; color: var(--muted); text-transform: uppercase; }
.footer__credit { display: flex; justify-content: center; margin-top: 32px; }
.footer__legal { display: flex; align-items: center; justify-content: space-between; gap: 12px 24px; flex-wrap: wrap; margin-top: 40px; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); font-size: 12px; line-height: 1.6; color: var(--muted); }
.footer .footer__legal { padding-top: 30px; padding-bottom: 30px; }
.footer__business { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 0; margin: 0; padding: 0; list-style: none; }
.footer__business li { white-space: nowrap; }
.footer__business li + li::before { content: "·"; margin: 0 10px; opacity: .6; }
.footer__business a, .footer__legal-links a { color: inherit; text-decoration: none; }
.footer__legal-links { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.footer__legal-links button { background: none; border: none; padding: 0; font: inherit; color: inherit; cursor: pointer; }
.footer__business a:hover, .footer__legal-links a:hover, .footer__legal-links button:hover { color: var(--text); }
.footer__business a:focus-visible, .footer__legal-links a:focus-visible, .footer__legal-links button:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 2px; }
@media (max-width: 640px) {
  .footer__legal { flex-direction: column; align-items: center; text-align: center; gap: 18px; margin-top: 32px; }
  .footer .footer__legal { padding-top: 26px; padding-bottom: 26px; }
  .footer__business { flex-direction: column; gap: 2px; }
  .footer__business li + li::before { content: none; }
  .footer__legal-links { justify-content: center; }
}

/* ---------- legal pages ---------- */
.legal__title { font-size: clamp(36px, 6vw, 72px); }
.legal { max-width: 760px; font-size: 16px; line-height: 1.75; color: var(--text); }
.legal h2 { margin: 44px 0 14px; font-size: 20px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.3; }
.legal p { margin: 0 0 16px; }
.legal ul { margin: 0 0 16px; padding-left: 22px; }
.legal li { margin-bottom: 8px; }
.legal a { color: var(--accent-light); text-decoration: underline; text-underline-offset: 2px; }
.legal__intro { font-size: 18px; color: var(--muted); }
.legal__note:empty { display: none; }
.legal__note { padding: 12px 16px; border: 1px solid var(--border); border-radius: 10px; font-size: 14px; color: var(--muted); }
.legal__updated { font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
.legal ul.legal__facts { list-style: none; padding: 0; border-top: 1px solid var(--border); }
.legal__facts li { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin: 0; padding: 12px 0; border-bottom: 1px solid var(--border); }
.legal__facts li span:first-child { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.legal__facts li span:last-child { overflow-wrap: anywhere; }
.legal__table-wrap { overflow-x: auto; margin: 0 0 16px; border: 1px solid var(--border); border-radius: 10px; }
.legal__table-wrap:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.legal__table { width: 100%; min-width: 620px; border-collapse: collapse; font-size: 14px; line-height: 1.5; }
.legal__table th, .legal__table td { padding: 10px 12px; text-align: left; vertical-align: top; border-bottom: 1px solid var(--border); }
.legal__table th { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); font-weight: 600; background: var(--bg-alt); }
.legal__table tr:last-child td { border-bottom: none; }
.legal__table td:first-child { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; white-space: nowrap; }

/* ---------- cookie consent: compact card, bottom-left (the floating player owns bottom-right) ---------- */
.cookie-banner {
  position: fixed; left: 24px; bottom: 24px; z-index: 60; width: min(340px, calc(100vw - 32px));
  padding: 14px 16px; border-radius: 14px; border: 1px solid var(--border);
  background: var(--nav-bg); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
  box-shadow: 0 16px 40px rgba(0,0,0,.35); color: var(--text); font-size: 13px; line-height: 1.5;
  opacity: 0; transform: translateY(12px); transition: opacity .25s ease, transform .25s ease;
}
.cookie-banner.is-visible { opacity: 1; transform: translateY(0); }
.cookie-banner[hidden] { display: none; }
.cookie-banner__text { margin: 0 0 12px; color: var(--muted); }
.cookie-banner__text a { color: var(--text); text-decoration: underline; text-underline-offset: 2px; }
.cookie-banner__actions { display: flex; gap: 8px; }
.cookie-banner__btn {
  flex: 1; padding: 8px 12px; border-radius: 100px; border: 1px solid var(--border-strong); background: transparent;
  color: var(--text); font-family: var(--font); font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; cursor: pointer;
  transition: border-color .2s ease, background .2s ease;
}
.cookie-banner__btn:hover { border-color: var(--accent); }
.cookie-banner__btn--primary { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }
.cookie-banner__btn--primary:hover { filter: brightness(1.08); }
.cookie-banner__btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
@media (max-width: 640px) { .cookie-banner { left: 16px; bottom: 16px; } }
@media (prefers-reduced-motion: reduce) { .cookie-banner { transition: none; transform: none; } }

/* ---------- "Desarrollado por Villabo" agency credit badge -- colors
   swap with the site's own dark/light theme instead of the static
   vb-badge--oscuro class the vendor snippet ships with, since this
   site's theme is already driven by [data-theme] on :root. */
.vb-badge { display: inline-flex; align-items: center; gap: 10px; font-family: 'Manrope', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; font-size: 12px; line-height: 1; text-decoration: none; color: #666B74; border-radius: 4px; transition: color 150ms cubic-bezier(.2,0,0,1); }
.vb-badge__label { font-family: var(--font); font-weight: 500; transition: color 150ms cubic-bezier(.2,0,0,1); }
.vb-badge__mark { display: inline-flex; align-items: center; color: #1C1F3D; }
.vb-badge__logo { height: 31px; width: auto; aspect-ratio: 254/64; flex: none; display: block; }
.vb-badge__sub { fill: #4A4F5C; }
.vb-badge__arc { stroke: #00C2CC; }
.vb-badge:hover .vb-badge__label { color: #4A4F5C; }
.vb-badge:focus-visible { outline: 2px solid #2F6FED; outline-offset: 2px; }
:root[data-theme="dark"] .vb-badge { color: #B6BCC8; }
:root[data-theme="dark"] .vb-badge .vb-badge__mark { color: #F5F6F8; }
:root[data-theme="dark"] .vb-badge .vb-badge__sub { fill: #B6BCC8; }
:root[data-theme="dark"] .vb-badge:hover .vb-badge__label { color: #F5F6F8; }
@media (max-width: 480px) {
  .vb-badge__logo { height: 23px; }
}

/* ---------- footer dock: macOS-dock-style icon row -- each icon grows as
   the cursor nears it (JS drives width/height; CSS eases the change) and
   shows its platform name in a tooltip above. ---------- */
.dock { display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap; justify-content: center; }
.dock__item {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex-shrink: 0; border-radius: 50%;
  background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--muted);
  transition: width .2s cubic-bezier(.22,1,.36,1), height .2s cubic-bezier(.22,1,.36,1),
    color .25s ease, background .25s ease, box-shadow .25s ease;
}
.dock__item:hover {
  color: var(--accent-light); background: color-mix(in srgb, var(--accent) 22%, transparent);
  box-shadow: 0 0 18px 2px color-mix(in srgb, var(--accent) 50%, transparent);
}
/* The navbar's Instagram icon reuses the footer dock's look but stays lit
   at rest (in the brand's --accent blue-violet, not the paler
   --accent-light), instead of only lighting up on hover like the footer's
   own icons. */
.nav__social.dock__item { color: var(--accent); background: color-mix(in srgb, var(--accent) 16%, transparent); }
.nav__social.dock__item:hover { color: var(--accent); background: color-mix(in srgb, var(--accent) 30%, transparent); }
.dock__icon { width: 45%; height: 45%; display: flex; }
.dock__icon svg { width: 100%; height: 100%; }
.dock__tip {
  position: absolute; bottom: calc(100% + 10px); left: 50%; transform: translate(-50%, 4px);
  background: var(--bg); border: 1px solid var(--border); color: var(--text);
  font-size: 11px; letter-spacing: .04em; white-space: nowrap; padding: 4px 9px; border-radius: 6px;
  opacity: 0; pointer-events: none; transition: opacity .18s ease, transform .18s ease;
}
.dock__item:hover .dock__tip { opacity: 1; transform: translate(-50%, 0); }
@media (prefers-reduced-motion: reduce) {
  .dock__item { transition: color .25s ease, background .25s ease; }
}

/* ---------- discography ---------- */
.discog-grid { display: grid; grid-template-columns: repeat(4,1fr); gap: 20px; margin-bottom: 56px; }
.discog-grid--3 { grid-template-columns: repeat(3,1fr); }
.music-feature { display: grid; grid-template-columns: var(--cover-size, 400px) 1fr; gap: 56px; align-items: start; }
.discog-card {
  display: flex; flex-direction: column; gap: 14px; text-decoration: none; color: inherit;
  transition: filter .3s ease, transform .3s ease, opacity .3s ease;
}
.discog-card__art { aspect-ratio: 1; overflow: hidden; border-radius: 9px; transition: box-shadow .25s ease; }
.discog-card__art img { width: 100%; height: 100%; object-fit: cover; transition: transform .3s ease; }
.discog-card:hover .discog-card__art { box-shadow: 0 0 28px 6px color-mix(in srgb, var(--accent) 65%, transparent); }
.discog-card:hover .discog-card__art img { transform: scale(1.05); }
/* Focus-cards effect: hovering one album pulls it into focus by softening
   the rest of the grid, so attention lands on a single cover at a time. */
.discog-grid:has(.discog-card:hover) .discog-card:not(:hover) { filter: blur(4px); transform: scale(.97); opacity: .6; }
@media (prefers-reduced-motion: reduce) {
  .discog-card, .discog-card__art, .discog-card__art img { transition: none; }
  .discog-grid:has(.discog-card:hover) .discog-card:not(:hover) { filter: none; transform: none; opacity: 1; }
}
.discog-card__title { font-weight: 600; font-size: 19px; }
.discog-card__meta { margin-top: 6px; font-size: 11px; letter-spacing: .12em; color: var(--muted); text-transform: uppercase; }
.discog-card__meta.is-new { color: var(--accent-light); }

.feature-album { display: grid; grid-template-columns: 320px 1fr; gap: 56px; align-items: start; }
.feature-album__label { font-size: 11px; letter-spacing: .16em; color: var(--muted); text-transform: uppercase; }
.feature-album__title { font-weight: 700; font-size: clamp(28px,3vw,40px); line-height: 1.1; letter-spacing: -0.03em; margin: 8px 0 12px; }
.feature-album__desc { margin: 0 0 20px; font-size: 16px; line-height: 1.6; color: var(--muted); }

.discog-widget { background: var(--bg); border-radius: 18px; padding: 32px clamp(16px,3vw,40px) 40px; }
/* padding on every side (not just bottom) because overflow-x:auto forces
   overflow-y to clip too — without it the selected card's outline and the
   hover glow (both drawn outside the cover's own box) get cut off at the
   row's edges. */
.discog-widget__row { display: flex; gap: 22px; overflow-x: auto; padding: 36px 36px 14px; margin: -36px -36px 0; scrollbar-width: thin; }
.discog-widget__card { flex: 0 0 auto; width: 168px; background: none; border: none; padding: 0; text-align: left; cursor: pointer; font-family: var(--font); color: inherit; }
.discog-widget__cover {
  display: block; position: relative; width: 168px; height: 168px; border-radius: 10px; overflow: hidden;
  background: linear-gradient(135deg, var(--sw1, #333), var(--sw2, #111));
  outline: 2px solid transparent; outline-offset: 3px;
  transition: outline-color .2s ease, box-shadow .2s ease;
}
.discog-widget__card[aria-pressed="true"] .discog-widget__cover { outline-color: var(--accent); }
.discog-widget__card:hover .discog-widget__cover {
  outline-color: var(--accent);
  box-shadow: 0 0 28px 6px color-mix(in srgb, var(--accent) 65%, transparent);
}
.discog-widget__cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
@media (prefers-reduced-motion: reduce) { .discog-widget__cover { transition: none; } }
.discog-widget__card-title { margin-top: 10px; font-size: 14.5px; font-weight: 700; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.discog-widget__card-meta { margin-top: 2px; font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.discog-widget__panel { margin-top: 34px; display: grid; grid-template-columns: minmax(220px,34%) 1fr; gap: 44px; padding-top: 30px; border-top: 1px solid var(--border); }
.discog-widget__eyebrow { font-size: 11.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin-bottom: 14px; }
.discog-widget__big-title { font-size: clamp(28px,3.4vw,40px); font-weight: 800; line-height: 1.08; letter-spacing: -.01em; margin: 0 0 16px; }
.discog-widget__desc { font-size: 14.5px; line-height: 1.6; color: var(--muted); max-width: 38ch; margin: 0 0 22px; }
.discog-widget__play-btn {
  display: inline-flex; align-items: center; gap: 8px; background: var(--accent); color: var(--accent-text);
  font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; padding: 13px 26px;
  border-radius: 100px; text-decoration: none;
}
.discog-widget__play-btn:hover { filter: brightness(1.08); }
.discog-widget__tracklist { display: flex; flex-direction: column; }
.discog-widget__track { display: grid; grid-template-columns: 22px 1fr auto auto; align-items: center; gap: 16px; padding: 13px 4px; border-bottom: 1px solid var(--border); }
.discog-widget__track:first-child { border-top: 1px solid var(--border); }
.discog-widget__track-num { font-size: 12.5px; color: var(--muted); }
.discog-widget__track-title { font-size: 14.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.discog-widget__track-dur { font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.discog-widget__track-listen { font-size: 11px; font-weight: 700; letter-spacing: .06em; color: var(--muted); text-decoration: none; white-space: nowrap; }
.discog-widget__track-listen:hover { color: var(--text); }
.discog-widget__outline-btn {
  margin-top: 22px; display: inline-flex; align-items: center; gap: 8px; border: 1px solid var(--border-strong);
  color: var(--text); font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: 12px 22px; border-radius: 100px; text-decoration: none; background: none;
}
.discog-widget__outline-btn:hover { background: var(--stripe); }
@media (max-width: 640px) {
  .discog-widget__panel { grid-template-columns: 1fr; gap: 26px; }
}

/* Compact "follow on Spotify" card nested under the featured-album panel's
   play button. Fixed dark colors on purpose (not var(--bg)/var(--text)) so
   it still reads as a Spotify-branded card regardless of the site's own
   light/dark theme, same as the standalone embed this replaced. */
.discog-widget__follow {
  margin-top: 24px; padding: 20px; border-radius: 14px; background: #121414;
  display: flex; flex-direction: column; align-items: flex-start;
}
.discog-widget__follow-photo { width: 56px; height: 56px; border-radius: 50%; object-fit: cover; object-position: top center; margin-bottom: 12px; }
.discog-widget__follow-eyebrow { font-size: 10.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: #C4C0FF; }
.discog-widget__follow-name { font-family: var(--font); font-weight: 700; font-size: 18px; color: #F5F5F6; margin: 3px 0; }
.discog-widget__follow-meta { font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: #918EA3; margin-bottom: 14px; }
.discog-widget__follow-cta {
  display: inline-flex; align-items: center; gap: 8px; background: var(--accent); color: var(--accent-text);
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: 11px 20px; border-radius: 100px; text-decoration: none; transition: filter .15s ease;
}
.discog-widget__follow-cta:hover { filter: brightness(1.08); }

.tracklist { display: flex; flex-direction: column; }
.tracklist__row {
  display: grid; grid-template-columns: 40px 1fr auto auto; align-items: center; gap: 16px;
  padding: 16px 0; border-top: 1px solid var(--border); font-size: 12px; color: var(--muted);
}
.tracklist__row:last-child { border-bottom: 1px solid var(--border); }
.tracklist__name { font-size: 16px; color: var(--text); }
.tracklist__listen { color: var(--accent-light); letter-spacing: .12em; text-transform: uppercase; font-size: 11px; }
.tracklist__more { margin-top: 22px; align-self: flex-start; }

.platform-cta { display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap; padding-top: 56px; padding-bottom: 56px; border-top: 1px solid var(--border); }
.platform-cta__title { font-weight: 700; font-size: 32px; letter-spacing: -0.025em; margin: 0 0 8px; }
.platform-cta__desc { margin: 0; font-size: 16px; color: var(--muted); }
.platform-list { display: flex; gap: 12px; flex-wrap: wrap; }
.platform-btn { display: inline-flex; align-items: center; gap: 10px; }
.platform-btn svg { width: 16px; height: 16px; flex-shrink: 0; }

/* ---------- tour ---------- */
.filters { display: flex; gap: 10px; flex-wrap: wrap; }
.filter-chip {
  border: 1px solid var(--border); color: var(--muted); padding: 10px 18px;
  font-size: 11px; letter-spacing: .14em; text-transform: uppercase; cursor: default;
}
.filter-chip.is-active { background: var(--accent); color: var(--accent-text); border-color: transparent; }

.dates { display: flex; flex-direction: column; }
.date-row {
  display: grid; grid-template-columns: 110px 1fr 1fr auto; align-items: center; gap: 18px;
  padding: 24px 0; border-top: 1px solid var(--border);
}
.date-row:last-child { border-bottom: 1px solid var(--border); }
.date-row--tour { grid-template-columns: 110px 1fr 1fr 90px auto; }
.date-row.is-highlight { background: linear-gradient(to right, color-mix(in srgb, var(--accent) 14%, transparent), transparent 60%); }
.date-row__day { font-weight: 700; font-size: 30px; letter-spacing: -0.02em; }
.date-row__month { font-size: 12px; color: var(--accent-light); }
.date-row__city { font-size: 19px; min-width: 0; overflow-wrap: break-word; }
.date-row__region { font-size: 13px; color: var(--muted); margin-top: 2px; }
.date-row__venue { font-size: 15px; color: var(--muted); }
.date-row__time { font-size: 13px; color: var(--muted); }
.date-row__cta { text-align: right; }
@media (min-width: 981px) {
  .date-row__cta .btn { min-width: 168px; }
}
.date-row .flag { margin-right: 6px; }

.past-dates { display: flex; flex-direction: column; margin-top: 24px; }
.past-row { display: grid; grid-template-columns: 130px 1fr 1fr; gap: 18px; align-items: center; padding: 26px 0; border-top: 1px solid var(--border); color: var(--muted); font-size: 15px; }
.past-row:last-child { border-bottom: 1px solid var(--border); }

.cta-split { display: grid; grid-template-columns: 1fr 340px; gap: 48px; align-items: center; }
.cta-split__photo { height: 280px; overflow: hidden; border-radius: 12px; }
.cta-split__photo img { width: 100%; height: 100%; object-fit: cover; }
.cta-split__photo.is-top img { object-position: center 0%; }

/* Portrait (2:3) photo variant -- lets the photo column keep its own
   natural proportions instead of being force-cropped into the wide
   landscape box above, so the card grows taller rather than cropping. */
.cta-split--tall { grid-template-columns: 1fr 280px; }
.cta-split--tall .cta-split__photo { height: auto; aspect-ratio: 3 / 5; }

/* ---------- media ---------- */
.video-card__play {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  width: 68px; height: 68px; border-radius: 50%; background: var(--accent);
  display: flex; align-items: center; justify-content: center;
}
.video-card__play::after { content:''; width:0; height:0; border-top:10px solid transparent; border-bottom:10px solid transparent; border-left:16px solid #fff; margin-left:4px; }

.video-preview {
  display: block; position: relative; width: 100%; max-width: 100%; aspect-ratio: 16 / 9;
  border-radius: 12px; overflow: hidden; border: none; background: none; padding: 0; cursor: pointer;
}
.video-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---------- gallery carousel: 3D coverflow — centered card sits flat and
   large, neighbors recede in perspective with rotation/scale/opacity falloff ---------- */
.gallery-carousel { position: relative; }
.gallery-carousel__viewport {
  position: relative; height: 494px; overflow: hidden;
  perspective: 1400px; perspective-origin: 50% 50%;
}
/* Without this, a touch browser is free to treat a horizontal drag as
   an attempt to scroll the page and never hands the gesture to the
   touchstart/touchend listeners below -- the classic reason a swipe
   carousel feels dead on a real phone despite working in devtools.
   pan-y keeps vertical page scrolling native while leaving horizontal
   drags to our JS. */
.gallery-carousel__track { position: relative; width: 100%; height: 420px; transform-style: preserve-3d; touch-action: pan-y; }
.gallery-carousel__item {
  /* Width is intentionally auto: each card keeps its photo's own aspect
     ratio (a landscape shot renders as a wider card, a portrait shot as a
     narrower one) instead of forcing every photo into one fixed box and
     cropping to fit. Centering under left:50% happens via the
     translateX(-50%) baked into styleFor()'s transform in main.js, since
     a fixed margin-left can't center a width that now varies per card. */
  position: absolute; top: 0; left: 50%; width: auto; height: 420px;
  cursor: pointer;
  transition: transform .55s cubic-bezier(.16,.84,.44,1), opacity .55s ease, filter .55s ease;
}
.gallery-carousel__item.is-current { cursor: default; }
.gallery-carousel__clip { display: inline-block; width: auto; height: 100%; border-radius: 24px; overflow: hidden; vertical-align: top; }
.gallery-carousel__clip img { display: block; width: auto; height: 100%; max-width: none; }
.gallery-carousel__caption {
  /* Centered on the card's own midpoint with a capped width of its own,
     rather than stretched left:0/right:0 to match the card's box -- since
     a card's width now varies with its photo's aspect ratio (and can run
     wider than a narrow phone's viewport for a landscape photo), a
     caption that matched that width could render mostly off-screen,
     clipped by the viewport's overflow:hidden. */
  position: absolute; left: 50%; bottom: -50px; width: max-content; max-width: 320px;
  transform: translateX(-50%); text-align: center;
  font-size: 15px; color: var(--accent-light);
  opacity: 0; filter: blur(6px); transition: opacity .4s ease, filter .4s ease; pointer-events: none;
}
.gallery-carousel__item.is-current .gallery-carousel__caption { opacity: 1; filter: blur(0); }
/* Photo captions hang from the top of their slot (not the bottom) so a
   caption that wraps to two lines grows downward and every caption still
   starts at the same height. */
.gallery-carousel:not(.gallery-carousel--video) .gallery-carousel__caption { bottom: auto; top: calc(100% + 33px); max-width: min(600px, 90vw); }
.gallery-carousel__controls { display: flex; align-items: center; justify-content: center; gap: 20px; margin-top: 24px; }
.gallery-carousel__arrow {
  width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--border);
  background: none; color: var(--accent-light); display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: border-color .2s ease, color .2s ease; flex-shrink: 0;
}
.gallery-carousel__arrow:hover { border-color: var(--accent); color: var(--accent); }
.gallery-carousel__arrow svg { width: 18px; height: 18px; }
.gallery-carousel__dots { display: flex; align-items: center; gap: 8px; }
.gallery-carousel__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--border); border: none; padding: 0; cursor: pointer; transition: background .2s ease, transform .2s ease; }
.gallery-carousel__counter { font-size: 12px; letter-spacing: .1em; color: var(--muted); font-variant-numeric: tabular-nums; }
.gallery-carousel__dot.is-current { background: var(--accent); transform: scale(1.35); }
@media (prefers-reduced-motion: reduce) {
  .gallery-carousel__item, .gallery-carousel__caption { transition: none; }
}
@media (max-width: 640px) {
  .gallery-carousel__viewport { height: 474px; perspective: 1000px; }
  .gallery-carousel__track { height: 400px; }
  /* On desktop, height stays fixed and width follows each photo's aspect
     ratio -- there's enough screen width to spare. On a narrow phone,
     that same rule let a landscape photo's card grow wider than the
     viewport itself, filling the whole screen with zero neighbors
     peeking in on either side: no coverflow depth, no visual cue there
     was anything to swipe to, and a swipe felt like a jarring full-screen
     swap instead of a slide. Flipping which dimension is fixed for
     mobile -- width fixed, height auto -- keeps every card a predictable
     size so neighbors are always visible and the swipe reads as motion. */
  /* top:50% instead of 0 -- height now varies per card (a landscape photo
     is a shorter card than a portrait one at the same fixed width), so
     centering it vertically needs a translateY(-50%) to match, which
     styleFor() in main.js adds to the transform only at this width. */
  /* Cards sit on a shared baseline (bottom:0) rather than being centered:
     a portrait card is taller than a landscape one at this fixed width, and
     centering them put each caption -- which hangs off its own card's
     bottom -- at a different height, so it jumped up and down mid-swipe. */
  .gallery-carousel__item { width: 220px; height: auto; top: auto; bottom: 0; }
  .gallery-carousel__clip { width: 100%; height: auto; }
  .gallery-carousel__clip img { width: 100%; height: auto; }
  .gallery-carousel__caption { bottom: -44px; }
  .gallery-carousel:not(.gallery-carousel--video) .gallery-carousel__viewport { height: 500px; }
  .gallery-carousel:not(.gallery-carousel--video) .gallery-carousel__caption { top: calc(100% + 27px); max-width: 300px; }
}

/* ---------- landscape-only photo carousel without captions (home):
   no caption band to reserve, and on phones a wider card so horizontal
   photos read at a useful size instead of a thin strip. ---------- */
.gallery-carousel.gallery-carousel--landscape .gallery-carousel__viewport { height: 440px; }
@media (max-width: 640px) {
  .gallery-carousel.gallery-carousel--landscape .gallery-carousel__viewport { height: 230px; }
  .gallery-carousel.gallery-carousel--landscape .gallery-carousel__track { height: 210px; }
  .gallery-carousel.gallery-carousel--landscape .gallery-carousel__item { width: 290px; }
}

/* ---------- video carousel: same coverflow mechanic, sized for 16:9
   YouTube thumbnails instead of portrait photos. Unlike the photo
   carousel above, this one keeps a fixed uniform box (video thumbnails
   are already roughly uniform, and cropping them the same way regardless
   of source resolution matters more here than for the photo cards). */
.gallery-carousel--video .gallery-carousel__viewport { height: 465px; }
.gallery-carousel--video .gallery-carousel__track { height: 405px; }
.gallery-carousel--video .gallery-carousel__item { width: 720px; height: 405px; }
.gallery-carousel--video .gallery-carousel__clip {
  display: block; position: relative; width: 100%; height: 100%;
  border: none; background: none; padding: 0; font: inherit; text-decoration: none; color: inherit; cursor: pointer;
}
.gallery-carousel--video .gallery-carousel__clip img { width: 100%; height: 100%; object-fit: cover; }
/* Video cards keep a fixed uniform width, so their (often long) titles
   can stay stretched to that full width like before instead of the
   photo carousel's capped/centered caption. */
.gallery-carousel--video .gallery-carousel__caption { left: 0; right: 0; bottom: -36px; width: auto; max-width: none; transform: none; }
.gallery-carousel--video .gallery-carousel__clip .video-card__play { width: 52px; height: 52px; }
.gallery-carousel__video-frame { width: 100%; height: 100%; border: none; display: block; }
@media (max-width: 640px) {
  .gallery-carousel--video .gallery-carousel__viewport { height: 240px; }
  .gallery-carousel--video .gallery-carousel__track { height: 180px; }
  .gallery-carousel--video .gallery-carousel__item { width: 320px; height: 180px; }
  .gallery-carousel--video .gallery-carousel__caption { bottom: -34px; }
}

/* ---------- media.html's photo gallery: static bento collage ----------
   The whole grid gets the aspect-ratio (not any individual cell), so
   row/column sizes are always a fraction of a width that's already
   correct for the viewport -- no fixed px height to go stale at some
   in-between breakpoint the way .bio__gallery/.contact-photo did. */
.media-collage {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: 1fr 1fr;
  gap: 14px;
  aspect-ratio: 1104 / 756;
}
.media-collage__item {
  overflow: hidden;
  border-radius: 16px;
  border: 1px solid var(--accent);
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.6s ease, transform 0.6s ease, box-shadow .35s ease, border-color .35s ease;
}
.media-collage__item:hover { border-color: var(--accent-light); box-shadow: 0 0 26px 4px color-mix(in srgb, var(--accent) 50%, transparent); }
.media-collage__item.is-visible { opacity: 1; transform: translateY(0); }
.media-collage__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.8s cubic-bezier(.2,.8,.2,1);
}
.media-collage__item:hover img { transform: scale(1.1); }
.media-collage__item--tall { grid-row: span 2; }
@media (prefers-reduced-motion: reduce) {
  .media-collage__item { opacity: 1; transform: none; transition: none; }
  .media-collage__item img { transition: none; }
  .media-collage__item:hover img { transform: none; }
}
@media (max-width: 768px) {
  .media-collage {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: none;
    aspect-ratio: auto;
  }
  .media-collage__item { aspect-ratio: 1 / 1; }
  .media-collage__item--tall { grid-row: auto; grid-column: span 2; aspect-ratio: 16 / 10; }
}
.media-collage__item { cursor: zoom-in; }
.media-collage__item img:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }

/* ---------- media.html gallery lightbox ---------- */
.lightbox { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; padding: 20px; touch-action: pan-y; }
.lightbox[hidden] { display: none; }
.lightbox__backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.88); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
.lightbox__stage { position: relative; z-index: 1; max-width: 90vw; max-height: 85vh; display: flex; align-items: center; justify-content: center; }
.lightbox__img { max-width: 90vw; max-height: 85vh; width: auto; height: auto; object-fit: contain; border-radius: 8px; box-shadow: 0 30px 80px rgba(0,0,0,.5); animation: modal-in .25s ease; }
.lightbox__close {
  position: absolute; top: 20px; right: 20px; z-index: 2; width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,.4); border: 1px solid var(--border); color: #fff; cursor: pointer; padding: 0;
}
.lightbox__close svg { width: 18px; height: 18px; }
.lightbox__arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2; width: 48px; height: 48px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,.4); border: 1px solid var(--border); color: #fff; cursor: pointer; padding: 0;
  transition: border-color .2s ease, color .2s ease;
}
.lightbox__arrow:hover { border-color: var(--accent); color: var(--accent); }
.lightbox__arrow svg { width: 22px; height: 22px; }
.lightbox__arrow--prev { left: 20px; }
.lightbox__arrow--next { right: 20px; }
.lightbox__counter {
  position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); z-index: 2;
  font-size: 12px; letter-spacing: .1em; color: #fff; font-variant-numeric: tabular-nums;
}
@media (max-width: 640px) {
  .lightbox__arrow { width: 40px; height: 40px; }
  .lightbox__arrow--prev { left: 8px; }
  .lightbox__arrow--next { right: 8px; }
  .lightbox__close { top: 12px; right: 12px; }
}
@media (prefers-reduced-motion: reduce) {
  .lightbox__img { animation: none; }
}

.presskit { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 24px; border-top: 1px solid var(--border); padding-top: 56px; }
.presskit__title { font-weight: 700; font-size: 30px; line-height: 1.2; letter-spacing: -0.02em; margin: 8px 0; }
.presskit__desc { margin: 0; font-size: 15px; line-height: 1.6; color: var(--muted); }
.filelist { display: flex; flex-direction: column; }
.filelist__row { display: flex; justify-content: space-between; align-items: center; padding: 18px 0; border-top: 1px solid var(--border); }
.filelist__row:last-child { border-bottom: 1px solid var(--border); }
.presskit__actions { display: flex; flex-direction: column; gap: 12px; justify-content: center; }

/* ---------- contact ---------- */
.contact-layout { display: grid; grid-template-columns: 1fr 400px; gap: 64px; align-items: start; }
.form-field { display: flex; flex-direction: column; gap: 10px; }
.form-field label { font-size: 11px; letter-spacing: .14em; color: var(--muted); text-transform: uppercase; }
.form-field input, .form-field textarea, .form-field select {
  background: transparent; border: none; border-bottom: 2px solid var(--border);
  color: var(--text); font-family: var(--font); font-size: 16px; padding: 6px 0 10px; resize: none;
}
.form-field input:focus, .form-field textarea:focus, .form-field select:focus { outline: none; border-color: var(--focus); }
.form-field input[aria-invalid="true"], .form-field textarea[aria-invalid="true"] { border-color: var(--danger); }
.form-optional { color: var(--muted); letter-spacing: .08em; }
.form-error { margin: 0; font-size: 13px; line-height: 1.4; color: var(--danger); }
.form-honey { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.form-consent { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 10px; margin: 0 0 22px; max-width: 620px; font-size: 13px; line-height: 1.5; color: var(--muted); }
.form-consent input { flex: none; width: 18px; height: 18px; margin: 1px 0 0; accent-color: var(--accent); cursor: pointer; }
.form-consent input:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.form-consent label { flex: 1; min-width: 0; cursor: pointer; }
.form-consent a { color: var(--text); text-decoration: underline; text-underline-offset: 2px; }
.form-consent .form-error { flex-basis: 100%; padding-left: 28px; }
.form-error-status { margin: 16px 0 0; font-size: 14px; color: var(--danger); }
form [type="submit"]:disabled { opacity: .6; cursor: wait; }
.form-field select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  cursor: pointer;
}
.form-field select option { background: var(--bg); color: var(--text); }
.form-field--select { position: relative; }
.form-field--select::after {
  content: "";
  position: absolute; right: 4px; bottom: 16px;
  width: 0; height: 0;
  border-left: 5px solid transparent; border-right: 5px solid transparent;
  border-top: 6px solid var(--muted);
  pointer-events: none;
}
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; max-width: 620px; }
.form-grid .span2 { grid-column: span 2; }
.contact-photo { height: 480px; overflow: hidden; border-radius: 12px; }
.contact-photo img { width: 100%; height: 100%; object-fit: cover; }
.contact-links { display: flex; flex-direction: column; margin-top: 48px; }
.contact-links__row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; padding: 16px 0; border-top: 1px solid var(--border); }
.contact-links__row span:last-child { overflow-wrap: anywhere; text-align: right; }
.contact-links__row:last-child { border-bottom: 1px solid var(--border); }
.contact-social { display: flex; justify-content: space-between; align-items: flex-end; gap: 16px; flex-wrap: wrap; padding: 16px 0; border-bottom: 1px solid var(--border); }
/* The dock reserves 64px so icons can magnify upward without shifting the row;
   bottom-aligning plus a label line-height equal to the resting icon size keeps
   the label centered on the icons instead of on that reserved box. */
.contact-social > .factlist__label { line-height: 40px; }
.contact-social .dock { justify-content: flex-end; min-height: 64px; max-width: none; margin: 0; }
@media (max-width: 980px) {
  .contact-social > .factlist__label { line-height: 36px; }
}
@media (min-width: 981px) and (max-width: 1120px) {
  .contact-social { flex-direction: column; align-items: flex-start; gap: 0; }
  .contact-social > .factlist__label { line-height: normal; }
}
@media (max-width: 640px) {
  .contact-social { flex-direction: column; align-items: flex-start; }
  .contact-social > .factlist__label { line-height: normal; }
  .contact-social .dock { justify-content: flex-start; min-height: 0; gap: 8px; }
}
@media (max-width: 380px) {
  .contact-social .dock { gap: 6px; }
  .contact-social .dock__item { width: 34px; height: 34px; }
}
@media (max-width: 340px) {
  .contact-social .dock { display: grid; grid-template-columns: repeat(4, 34px); }
}
.form-note { font-size: 13px; color: var(--muted); margin-top: -8px; }
.form-success { display: none; margin-top: 16px; font-size: 14px; color: var(--accent-light); }
.form-success.is-visible { display: block; }

/* Tighten the right side of the navbar before the mobile menu takes over,
   so there's always room for the logo at full size without it getting
   squeezed/distorted by flex-shrink. */
@media (max-width: 1180px) {
  .nav__links { gap: 16px; font-size: 11px; }
  .nav__actions { gap: 6px; }
  .icon-btn { width: 34px; height: 34px; }
  .icon-btn svg { width: 15px; height: 15px; }
  .nav__social.dock__item { width: 34px; height: 34px; }
  .lang-switch__chip { padding: 6px 8px; }
  .nav__actions .btn--sm { padding: 9px 12px; font-size: 10px; }
}

/* =========================================================================
   Responsive
   ========================================================================= */
@media (max-width: 980px) {
  .container { padding: 0 20px; }
  .nav__inner { padding-top: 19px; padding-bottom: 19px; }
  /* .container's shorthand reset above (it only means to touch left/right)
     also zeroes padding-top/bottom on anything combining .container with
     a class that sets its own vertical padding but skips .section (which
     re-asserts its own padding-top/bottom later in this same block) --
     .platform-cta is exactly that case, so it needs the same treatment. */
  .platform-cta { padding-top: 32px; padding-bottom: 32px; }
  .nav__links { display: none; }
  .nav__burger { display: flex; }
  .nav__logo-img { height: 34px; }
  .nav__inner > a:first-child { transform: translateY(-4px); }
  .footer__logo { height: 23px; }
  .nav__actions .btn--sm { display: none; }
  /* Instagram already lives in the footer dock on every page -- dropping it
     from the mobile top bar thins out a 5-icon cluster crowding the right
     edge opposite the lone logo, which read as the whole nav being
     off-balance/shifted right. */
  .nav__social { display: none; }

  .nav__mobile-panel {
    position: fixed; top: 89px; right: 0; bottom: 0; left: 0; background: var(--bg); z-index: 49;
    padding: 24px 20px; overflow-y: auto;
  }
  .nav__mobile-panel.is-open { display: block; }
  .nav__mobile-links { display: flex; flex-direction: column; gap: 4px; margin-bottom: 24px; }
  .nav__mobile-links a { padding: 16px 4px; border-bottom: 1px solid var(--border); font-size: 15px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
  .nav__mobile-links a.is-active { color: var(--text); }

  .section { padding-top: 56px; padding-bottom: 56px; }
  .hero { min-height: 100svh; }
  .hero__content { padding: 120px 20px 24px; max-width: 100%; }
  .hero__nowplaying { padding: 0 20px 40px; max-width: 100%; }
  .hero__ctas { flex-direction: column; width: 100%; }
  .hero__ctas .btn { width: 100%; text-align: center; }

  .stats { grid-template-columns: 1fr 1fr; }
  .stats__item { padding: 22px 20px; }
  .stats__item:nth-child(2n) { border-right: none; }
  .stats__item:nth-child(n+3) { border-top: 1px solid var(--border); }

  .bio { grid-template-columns: 1fr; gap: 28px; }
  .bio__gallery { grid-template-columns: 1fr; grid-template-rows: auto; }
  /* A fixed px height here (sized for a half-width desktop column) turns
     into a much wider, shallower box once these figures go full-width
     in a single mobile column -- badly over-cropping portrait photos
     (a hand-and-torso shot with the head sheared clean off). aspect-ratio
     keeps the crop proportional to whatever width the figure actually
     ends up at. */
  .bio__gallery figure.span2 { grid-column: span 1; height: auto; aspect-ratio: 2 / 1; }
  .bio__gallery figure { height: auto; aspect-ratio: 2 / 1; }
  .bio-hero { grid-template-columns: 1fr; gap: 28px; }
  .bio-hero__photo { height: 280px; }
  .bio-banner { height: 320px; }
  .bio-split { grid-template-columns: 1fr; gap: 28px; }
  /* Same fixed-height-vs-full-width mismatch fixed above for
     .bio__gallery/.contact-photo: this is a half-width desktop column
     (safe crop there) that goes full-width on mobile at the same
     height, over-cropping several of these photos. aspect-ratio
     replicates the desktop column's own proportions (588x420) so the
     crop stays consistent regardless of viewport width. */
  .bio-split__photo { height: auto; aspect-ratio: 4 / 3; }
  .bio-split__copy--lg p { font-size: 17px; }
  .bio-split__copy--md p { font-size: 17px; }
  .bio-mosaic { grid-template-columns: 1fr; gap: 24px; }
  .bio-module { padding: 28px; border-radius: 20px; margin-bottom: 24px; }
  .img-placeholder--wide { height: 240px; }
  .collab-grid { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 24px 16px; }
  .collab-grid__name { font-size: 13px; }

  .discog-grid { grid-template-columns: 1fr 1fr; gap: 14px; }
  .feature-album { grid-template-columns: 1fr; gap: 24px; }
  .music-feature { grid-template-columns: 1fr; gap: 28px; }
  /* alignFeatureVideoWidth() (main.js) skips its text-width-matching JS
     below this breakpoint and leaves sizing to CSS -- a small bleed past
     the column, centered, so it reads as bigger and more prominent than
     just filling the column at 100%. */
  .music-feature .video-preview { width: calc(100% + 24px); max-width: none; margin-left: -12px; }
  .tracklist__row { grid-template-columns: 28px 1fr auto; }
  .tracklist__row span.tracklist__listen { display: none; }

  .timeline { gap: 32px; }
  .timeline__spine { left: 0; transform: none; }
  .timeline__head { left: 1.5px; }
  .timeline__row { grid-template-columns: 1fr; row-gap: 12px; padding-left: 24px; }
  .timeline__row::before { display: none; }
  .timeline__year { grid-column: 1; justify-self: start; font-size: 17px; padding: 6px 14px; transform-origin: left center; }
  .timeline__row--left .timeline__card, .timeline__row--right .timeline__card { grid-column: 1; grid-row: 2; }
  .timeline__card { height: auto; min-height: 145px; }
  .quote { grid-template-columns: 1fr; gap: 28px; }
  .quote__photo { height: 260px; }

  .platform-cta { flex-direction: column; align-items: flex-start; }
  .platform-list { width: 100%; }
  .platform-list .btn { flex: 1 1 calc(50% - 6px); }

  .date-row { grid-template-columns: 72px 1fr auto; gap: 8px; }
  .date-row__day { font-size: 22px; }
  .date-row__venue, .date-row__time { display: none; }
  .date-row__cta .btn { padding: 9px 10px; font-size: 9px; letter-spacing: .06em; }
  .past-row { grid-template-columns: 1fr; gap: 4px; padding: 20px 0; }

  .cta-split { grid-template-columns: 1fr; gap: 24px; }
  .cta-split__photo { height: 220px; }
  .cta-split--tall .cta-split__photo { height: auto; }

  .presskit { grid-template-columns: 1fr; gap: 32px; }

  .contact-layout { grid-template-columns: 1fr; gap: 32px; }
  .form-grid { grid-template-columns: 1fr; }
  .form-grid .span2 { grid-column: span 1; }
  /* Same fixed-height-vs-full-width mismatch as .bio__gallery: this box
     is a narrow 400px column at desktop, sized for a portrait crop, but
     going full-width on mobile with the same height turns it into a
     wide letterbox that shears the head clean off a portrait photo. */
  .contact-photo { height: auto; aspect-ratio: 1 / 1; }
  .contact-photo img { object-position: center 5%; }

  .pager__link { padding: 28px 20px; }
  .pager__name { font-size: 18px; overflow-wrap: break-word; }
  .footer__inner { flex-direction: column; text-align: center; }
  /* 8 icons at this size don't reliably fit one row across common phone
     widths, so they'd wrap wherever they happened to run out of space
     (e.g. 7+1) -- capping the row to fit exactly 4 makes the wrap land on
     a clean, evenly centered 4+4 grid instead. */
  .dock { gap: 10px; max-width: 188px; margin: 0 auto; }
  .dock__item { width: 36px; height: 36px; }

  .pagehero--text { padding: 105px 0 40px; }
  .pagehero--photo .pagehero__inner { padding: 0 20px; }
  .pagehero__tag { display: none; }
}

/* ---------- streaming platform modal ---------- */
body.modal-open { overflow: hidden; }
.modal { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; padding: 20px; }
.modal[hidden] { display: none; }
.modal__backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.6); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); }
.modal__panel {
  position: relative; z-index: 1; background: var(--bg); border: 1px solid var(--border);
  max-width: 420px; width: 100%; padding: 40px 32px; animation: modal-in .25s ease;
}
.modal__panel--form { max-width: 560px; max-height: 90vh; overflow-y: auto; }
.modal__panel--form .form-grid { max-width: none; }
.modal__panel--form .contact-links { margin-top: 28px; }
@keyframes modal-in { from { opacity: 0; transform: translateY(12px) scale(.98); } to { opacity: 1; transform: translateY(0) scale(1); } }
.modal__close {
  position: absolute; top: 16px; right: 16px; width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--border); color: var(--text); cursor: pointer; padding: 0;
}
.modal__close svg { width: 16px; height: 16px; }
.modal__title { margin: 0 0 8px; font-weight: 700; font-size: 26px; letter-spacing: -0.02em; }
.modal__subtitle { margin: 0 0 28px; font-size: 14px; line-height: 1.5; color: var(--muted); }
.modal__platforms { display: flex; flex-direction: column; gap: 10px; }
.modal__platform {
  display: flex; align-items: center; gap: 14px; padding: 14px 16px;
  border: 1px solid var(--border); border-radius: 10px; font-size: 13px; letter-spacing: .08em; text-transform: uppercase;
}
.modal__platform:hover { border-color: var(--accent); color: var(--accent-light); }
.modal__platform svg { width: 20px; height: 20px; flex-shrink: 0; }

/* ---------- biography modules: reveal on scroll, glow on hover, photos settle in ---------- */
.bio-module { transition: opacity .8s ease, transform .9s cubic-bezier(.2,.8,.2,1), box-shadow .45s ease, border-color .45s ease; }
.bio-module.reveal-ready:not(.is-visible) { opacity: 0; transform: translateY(36px) scale(.985); }
.bio-module:hover {
  border-color: var(--accent-light);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 50%, transparent), 0 0 46px -4px color-mix(in srgb, var(--accent) 45%, transparent), inset 0 0 70px -40px color-mix(in srgb, var(--accent) 60%, transparent);
}
.bio-module .bio-split__copy, .bio-module .bio-split__media, .bio-module .bio-mosaic__quote, .bio-module .bio-mosaic__photo {
  transition: opacity .8s ease .15s, transform .9s cubic-bezier(.2,.8,.2,1) .15s;
}
.bio-module .bio-split__media, .bio-module .bio-mosaic__photo { transition-delay: .3s; }
.bio-module.reveal-ready:not(.is-visible) .bio-split__copy,
.bio-module.reveal-ready:not(.is-visible) .bio-split__media,
.bio-module.reveal-ready:not(.is-visible) .bio-mosaic__quote,
.bio-module.reveal-ready:not(.is-visible) .bio-mosaic__photo { opacity: 0; transform: translateY(18px); }
.bio-module .bio-split__photo img, .bio-module .cta-split__photo img, .bio-module .bio-mosaic__photo img {
  transform: scale(1.12); transition: transform 1.8s cubic-bezier(.2,.8,.2,1);
}
.bio-module.is-visible .bio-split__photo img, .bio-module.is-visible .cta-split__photo img, .bio-module.is-visible .bio-mosaic__photo img { transform: scale(1); }
.bio-module.is-visible .bio-split__photo:hover img, .bio-module.is-visible .cta-split__photo:hover img, .bio-module.is-visible .bio-mosaic__photo:hover img {
  transform: scale(1.06); transition-duration: .8s;
}
@media (prefers-reduced-motion: reduce) {
  .bio-module, .bio-module * { transition: none !important; }
  .bio-module.reveal-ready:not(.is-visible), .bio-module.reveal-ready:not(.is-visible) * { opacity: 1 !important; transform: none !important; }
}

/* ---------- media: featured video + secondary + scrolling rail ---------- */
.video-feature { display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); gap: 28px; align-items: start; }
.video-feature__frame {
  position: relative; display: block; width: 100%; aspect-ratio: 16 / 9; padding: 0; margin: 0;
  border-radius: 20px; overflow: hidden; border: 1px solid var(--accent); background: #000; cursor: pointer;
  font: inherit; color: inherit; transition: box-shadow .35s ease, border-color .35s ease;
}
.video-feature__frame:hover { border-color: var(--accent-light); box-shadow: 0 0 28px 4px color-mix(in srgb, var(--accent) 50%, transparent); }
.video-feature__btn { position: relative; display: block; width: 100%; height: 100%; padding: 0; border: none; background: none; cursor: pointer; }
.video-feature__frame img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .7s cubic-bezier(.2,.8,.2,1); }
.video-feature__frame:hover img { transform: scale(1.05); }
.video-feature__frame--secondary { border-radius: 16px; }
.video-feature__frame--secondary.is-playing { border-color: var(--accent-light); box-shadow: 0 0 22px 2px color-mix(in srgb, var(--accent) 45%, transparent); }
.video-feature__frame:focus-visible, .video-feature__btn:focus-visible, .video-rail__btn:focus-visible, .video-rail__arrow:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.video-feature__title { margin: 16px 0 0; font-weight: 700; font-size: 20px; letter-spacing: -0.01em; }
.video-feature__subtitle { margin: 10px 0 0; font-weight: 600; font-size: 15px; }
.video-feature__side { display: flex; flex-direction: column; gap: 24px; min-width: 0; }
.video-card__play--sm { width: 48px; height: 48px; }
.video-card__play--sm::after { border-top-width: 8px; border-bottom-width: 8px; border-left-width: 13px; }
.video-rail__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.video-rail__label { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.video-rail__arrows { display: flex; gap: 8px; }
.video-rail__arrow {
  width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--border-strong); background: none;
  color: var(--accent-light); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: border-color .2s ease;
}
.video-rail__arrow:hover { border-color: var(--accent); }
.video-rail__arrow svg { width: 15px; height: 15px; }
.video-rail__track {
  list-style: none; margin: 0; padding: 4px 2px 10px; display: flex; gap: 14px;
  overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; overscroll-behavior-x: contain;
}
.video-rail__track::-webkit-scrollbar { display: none; }
.video-rail__item { flex: 0 0 calc(50% - 7px); min-width: 0; scroll-snap-align: start; }
.video-rail__btn {
  display: flex; flex-direction: column; gap: 8px; width: 100%; padding: 0; border: none; background: none;
  text-align: left; color: var(--text); font-family: var(--font); cursor: pointer;
}
.video-rail__thumb {
  display: block; aspect-ratio: 16 / 9; border-radius: 12px; overflow: hidden; border: 1px solid var(--border-strong);
  transition: border-color .3s ease, box-shadow .3s ease;
}
.video-rail__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .6s cubic-bezier(.2,.8,.2,1); }
.video-rail__btn:hover .video-rail__thumb, .video-rail__btn.is-playing .video-rail__thumb { border-color: var(--accent); box-shadow: 0 0 18px 2px color-mix(in srgb, var(--accent) 45%, transparent); }
.video-rail__btn:hover .video-rail__thumb img { transform: scale(1.07); }
.video-rail__btn.is-playing .video-rail__title { color: var(--accent-light); }
.video-rail__title { font-size: 13px; font-weight: 600; line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
@media (max-width: 980px) {
  .video-feature { grid-template-columns: 1fr; gap: 24px; }
  .video-feature__side { display: grid; grid-template-columns: minmax(0, 1fr); }
  .video-rail__item { flex-basis: 40%; }
  .bio-mosaic { grid-template-columns: 1fr; gap: 28px; }
  .bio-mosaic__photo { justify-self: center; max-width: 420px; }
}
@media (max-width: 640px) {
  .video-rail__item { flex-basis: 72%; }
  .video-feature__title { font-size: 17px; }
  .pagehero--photo { border-radius: 0 0 22px 22px; }
}
