/* ═══════════════════════════════════════════════════════════════════════════
   07 - PAGES
   Styles that belong to exactly one inner page, plus the page hero and the
   breadcrumb, which every inner page shares.
   ═══════════════════════════════════════════════════════════════════════════ */

@layer pages {

/* ───────────────────────────────────────────────────────────────────────────
   SHARED - page hero and breadcrumb (§9)
   ─────────────────────────────────────────────────────────────────────────── */

.page-hero {
  position: relative;
  min-height: max(46vh, 380px);
  display: flex;
  align-items: flex-end;
  padding-block: calc(var(--header-h) + var(--sp-7)) var(--sp-8);
  isolation: isolate;
  overflow: clip;
  background: var(--ink-950);
}

.page-hero__media {
  position: absolute;
  inset: 0;
  z-index: -1;
}

/* The picture is absolutely filled and the img fills the picture; without the
   first of these the wrapper has no height and the photograph never shows. */
.page-hero__media .picture {
  position: absolute;
  inset: 0;
}

.page-hero__media .picture,
.page-hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.page-hero__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(7, 6, 5, .78), rgba(7, 6, 5, .5) 35%, rgba(10, 9, 8, .96));
}

.page-hero__ghost {
  bottom: -.2em;
  right: calc(var(--gutter) * -.3);
  z-index: 0;
}

.page-hero__inner {
  position: relative;
  z-index: 1;
}

.page-hero__title {
  margin-block: var(--sp-3) 0;
  font-size: var(--fs-h1);
}

.page-hero__deva {
  margin-top: var(--sp-3);
  font-size: clamp(.9375rem, .9rem + .4vw, 1.125rem);
  letter-spacing: .12em;
}

.page-hero__intro { margin-top: var(--sp-4); }
.page-hero__status { margin-top: var(--sp-4); }

.breadcrumb { margin-bottom: var(--sp-5); }

.breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-micro);
  color: var(--ivory-500);
  list-style: none;
  padding: 0;
}

.breadcrumb__list li + li::before {
  content: '/';
  margin-right: var(--sp-2);
  color: var(--ivory-700);
}

.breadcrumb__list a {
  transition: color var(--dur) var(--ease-out);
}

.breadcrumb__list a:hover { color: var(--gold-400); }
.breadcrumb__list [aria-current] { color: var(--ivory-300); }

/* ───────────────────────────────────────────────────────────────────────────
   BIOGRAPHY (§9.1)
   ─────────────────────────────────────────────────────────────────────────── */

.bio-opening__portrait {
  border-radius: var(--r-md);
  overflow: hidden;
}

/* The portrait stands still while the biography scrolls past it - the same
   pin the intro uses, and it needs the same two things said here.

   The position, because .frame-ornate sets `position: relative` in @layer
   components and .sticky-col sets `position: sticky` in @layer layout. The
   later layer wins whatever the specificity, so the ornament was quietly
   unpinning the picture. Restating it in @layer pages settles it; the offset
   still comes from the utility.

   The height, because a sticky box taller than the window has nowhere left to
   stick to and scrolls away like anything else. At the full width of a 5fr
   column the 4/5 ratio stood this portrait about as tall as a laptop screen,
   which is why nothing appeared to happen. Both sides are stated: with only a
   height the ratio would take over the width and draw the frame around a
   picture narrower than its column. The img inside covers rather than
   stretches (02-base.css), so the crop is the picture's, not the layout's. */
@media (min-width: 900px) {
  .bio-opening__portrait { position: sticky; }

  .bio-opening__portrait .ar-portrait {
    width: 100%;
    height: min(76svh, 700px);
  }
}

.bio-opening__body { display: grid; gap: var(--sp-7); }

.bio-opening__pull {
  margin-top: var(--sp-6);
  padding-left: var(--sp-5);
  border-left: 1px solid var(--hairline-hot);
}

/* A pull-quote may break out of the measure on a wide screen. */
@media (min-width: 1200px) {
  .bio-opening__pull {
    margin-inline: calc(var(--sp-8) * -1) 0;
    padding-left: var(--sp-8);
  }
}

.bio-block { display: grid; gap: var(--sp-4); }

/* ── Timeline ── */

.timeline__grid { position: relative; }

.timeline__sticky-year {
  display: none;
  font-family: var(--ff-display);
  font-size: clamp(2rem, 4vw, 3.25rem);
  line-height: 1;
  color: var(--ivory-700);
}

@media (min-width: 1024px) {
  .timeline__grid {
    display: grid;
    grid-template-columns: 140px minmax(0, 1fr);
    gap: var(--sp-8);
    align-items: start;
  }
  .timeline__sticky-year {
    display: block;
    position: sticky;
    top: calc(var(--header-h-shrunk) + var(--sp-8));
  }
}

.timeline__list {
  display: grid;
  gap: var(--sp-7);
  list-style: none;
  padding-left: clamp(var(--sp-6), 5vw, var(--sp-7));
}

.timeline__item {
  position: relative;
  display: grid;
  gap: var(--sp-4);
}

@media (min-width: 700px) {
  .timeline__item {
    grid-template-columns: minmax(0, 1fr) 220px;
    align-items: start;
  }
  /* Thumbnails alternate sides down the rail. */
  .timeline__item--alt .timeline__body { order: 2; }
  .timeline__item--alt .timeline__thumb { order: 1; }
}

/* The gold node on the taar-line. It fills as the item enters the viewport -
   the transition is on the reveal class, so a paused scroll looks settled. */
.timeline__dot {
  position: absolute;
  left: calc(clamp(var(--sp-6), 5vw, var(--sp-7)) * -1 - 3px);
  top: .55em;
  width: 9px;
  height: 9px;
  border: 1px solid var(--gold-500);
  background: var(--ink-850);
  transform: rotate(45deg);
  transition: background-color var(--dur-slow) var(--ease-out);
}

.timeline__item.is-revealed .timeline__dot { background: var(--gold-500); }

.timeline__body { display: grid; gap: var(--sp-2); }

.timeline__year {
  font-family: var(--ff-display);
  font-size: var(--fs-h4);
  line-height: 1;
  color: var(--gold-500);
}

.timeline__title { margin: 0; }
.timeline__text { color: var(--ivory-300); max-width: 56ch; }

.timeline__thumb {
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--ink-800);
}

/* ── Parampara diagram ── */

.parampara {
  position: relative;
  margin-top: var(--sp-8);
}

.parampara__wires {
  position: absolute;
  inset: 0;
  z-index: 0;
  color: var(--hairline-hot);
  pointer-events: none;
  overflow: visible;
}

.parampara__gurus {
  position: relative;
  z-index: 1;
  display: grid;
  gap: var(--sp-6);
  list-style: none;
  padding: 0;
}

/* However many teachers there are, the wide layout puts them all in one row,
   so each card gets its own wire to the centre. Between 900 and 1200px that
   is too tight for five, so they wrap three to a row with the short row
   centred - and parampara.js leaves the wires out, since a line from the
   first row would run behind the second. */
@media (min-width: 900px) {
  .parampara__gurus { display: flex; flex-wrap: wrap; justify-content: center; }
  .parampara__card { flex: 0 1 calc((100% - 2 * var(--sp-6)) / 3); }
}

@media (min-width: 1200px) {
  .parampara__gurus {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: var(--sp-5);
  }
}

.parampara__card {
  display: grid;
  /* Cards in a row share the tallest one's height. Left to stretch, the grid
     hands that slack to its rows and the square tile grows past the padding,
     so a card with a one-line name gets a bigger picture than its neighbour. */
  align-content: start;
  gap: var(--sp-3);
  justify-items: center;
  text-align: center;
  padding: var(--sp-5);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--ink-800) 70%, transparent);
  transition: border-color var(--dur) var(--ease-out);
}

.parampara__card:hover { border-color: var(--hairline-hot); }

/* The portrait is a square across the card's full width: the admin asks for
   1200 x 1200 uploads, and the teacher's face is the point of the card. The
   cap stops it filling a tablet screen once the grid drops to one column. */
.parampara__portrait,
.parampara__monogram {
  width: 100%;
  max-width: 320px;
  aspect-ratio: 1 / 1;
  border-radius: var(--r-sm);
}

.parampara__portrait {
  display: block;
  overflow: hidden;
  border: 1px solid var(--hairline);
}

.parampara__portrait img { object-fit: cover; }

/* The stand-in where a teacher's photograph cannot be licensed: the initial
   set in the display face inside a gold frame, the same size as a portrait
   so the names still line up across the row. */
.parampara__monogram {
  display: grid;
  place-items: center;
  border: 1px solid var(--hairline-hot);
  background: radial-gradient(circle at 50% 30%, var(--ink-700), var(--ink-850));
  font-family: var(--ff-display);
  font-size: clamp(3.5rem, 6vw, 5rem);
  line-height: 1;
  color: var(--gold-500);
  transition: border-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out);
}

.parampara__card:hover .parampara__monogram {
  border-color: var(--gold-500);
  color: var(--gold-300);
}

.parampara__name {
  margin: 0;
  font-size: var(--fs-h4);
  max-width: none;
}

.parampara__deva { color: var(--ivory-500); font-size: .9375rem; }
.parampara__gharana { margin: 0; justify-content: center; }
.parampara__note { color: var(--ivory-500); max-width: 30ch; }

.parampara__self {
  position: relative;
  z-index: 1;
  display: grid;
  gap: var(--sp-2);
  justify-items: center;
  margin-top: clamp(var(--sp-7), 8vw, var(--sp-10));
  padding: var(--sp-5) var(--sp-7);
  border: 1px solid var(--hairline-hot);
  border-radius: var(--r-pill);
  background: var(--ink-800);
  width: fit-content;
  margin-inline: auto;
}

.parampara__self-name {
  font-family: var(--ff-display);
  font-size: var(--fs-h4);
  color: var(--ivory-100);
}

.parampara__self-deva { color: var(--gold-500); font-size: .875rem; }

/* ── Sitar anatomy ── */

.sitar__layout {
  display: grid;
  gap: var(--sp-7);
  margin-top: var(--sp-7);
}

@media (min-width: 900px) {
  .sitar__layout { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); align-items: center; }
}

.sitar__figure {
  position: relative;
  color: var(--ivory-500);
}

.sitar-svg { width: 100%; height: auto; display: block; }

/* Naming a part lights it on the drawing as well as in the card. Every mark is
   in one of the groups the svg sets up, so stepping the whole instrument back
   and restoring one group is the entire effect.

   `color`, not `stroke`, because every stroke in there is currentColor: one
   declaration on the group reaches the outline, the hairlines inside it and
   the leader pointing at it, whatever their own widths and opacities.

   The step-back is .32 rather than something darker on purpose. The point is
   to name a part, not to hide the instrument - at a quarter or less the neck
   breaks up and the drawing reads as half-loaded rather than as one thing with
   a piece of it lit. */
.sitar-svg > g > * {
  transition:
    opacity var(--dur) var(--ease-out),
    color var(--dur) var(--ease-out);
}

.sitar__figure.is-focused .sitar-svg > g > * { opacity: .32; }

.sitar__figure.is-focused .sitar-svg .is-lit {
  opacity: 1;
  color: var(--gold-400);
}

@media (prefers-reduced-motion: reduce) {
  .sitar-svg > g > * { transition: none; }
}

/* The viewBox is the drawing's own bounds, so a hotspot's stored percentages
   are percentages of this box and the overlay is simply the same box. */
.sitar__spots {
  position: absolute;
  inset: 0;
  list-style: none;
  padding: 0;
}

.sitar__spot {
  position: absolute;
  left: var(--x);
  top: var(--y);
  display: grid;
  place-items: center;
  width: var(--touch);
  height: var(--touch);
  transform: translate(-50%, -50%);
  border-radius: 50%;
}

.sitar__spot-num {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border: 1px solid var(--hairline-hot);
  border-radius: 50%;
  background: var(--ink-900);
  font-size: 11px;
  color: var(--gold-400);
  transition:
    background-color var(--dur) var(--ease-out),
    color var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out);
}

.sitar__spot:hover .sitar__spot-num,
.sitar__spot:focus-visible .sitar__spot-num,
.sitar__spot[aria-pressed='true'] .sitar__spot-num {
  background: var(--action);
  color: var(--on-action);
  transform: scale(1.14);
}

.sitar__card {
  display: grid;
  gap: var(--sp-3);
  align-content: start;
  min-height: 15rem;
  padding: var(--sp-6);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  background: var(--ink-800);
}

.sitar-card__deva {
  font-family: var(--ff-deva);
  font-size: 1.5rem;
  line-height: 1.3;
  color: var(--gold-500);
}

.sitar-card__title {
  margin: 0;
  font-family: var(--ff-display);
  font-size: var(--fs-h3);
  color: var(--ivory-100);
}

.sitar-card__body { color: var(--ivory-300); }

/* ── Podcasts and interviews (§9.7) ── */

.podcasts__group + .podcasts__group { margin-top: var(--sp-8); }

/* The show's name over its episodes, with the count sitting on the rule that
   runs out to the edge - the same device the track list uses. */
.podcasts__show {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  margin: var(--sp-7) 0 var(--sp-5);
  color: var(--ivory-100);
}

.podcasts__show::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--hairline);
}

.podcasts__count {
  order: 1;                      /* past the rule, at the far end */
  font-size: var(--fs-micro);
  color: var(--ivory-500);
  font-variant-numeric: tabular-nums;
}

.podcast-card {
  display: grid;
  grid-template-rows: auto 1fr;
  height: 100%;
  overflow: hidden;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: var(--ink-800);
  transition:
    border-color var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out);
}

.podcast-card:hover,
.podcast-card:focus-within {
  border-color: var(--hairline-hot);
  transform: translateY(-2px);
}

.podcast-card__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--ink-900);
}

/* YouTube's stills are 4:3 with the picture letterboxed inside, so `cover` is
   what crops the bands off rather than showing them as grey bars. */
.podcast-card__still {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}

.podcast-card:hover .podcast-card__still { transform: scale(1.04); }

.podcast-card__still--empty { display: block; background: var(--ink-800); }

.podcast-card__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(7, 6, 5, .1) 40%, rgba(7, 6, 5, .72));
  pointer-events: none;
}

.podcast-card__play {
  position: absolute;
  right: var(--sp-3);
  bottom: var(--sp-3);
  --play-size: 46px;
}

.podcast-card__body {
  display: grid;
  align-content: start;
  gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-4) var(--sp-5);
}

.podcast-card__meta { color: var(--ivory-500); }

/* Episode titles are not headlines: they arrive long, punctuated by the show
   ("The NOBAT Show | Ep: 5 | ft. …"), and at heading size a single one filled
   the card and pushed everything else out of sight. This holds them just above
   body size, which is enough to lead the card without becoming it.

   `max-width: none` is the important line. 03-typography caps every h1-h4 at
   --measure-head, 18ch, which is a good measure for a heading standing in
   prose and quite wrong for one inside a card: the card already sets the
   width, and the cap stacked a second, narrower column inside it, leaving half
   the card empty beside the words. .card__title does the same thing for the
   same reason.

   `pretty`, not the `balance` inherited from that rule. Balance evens the
   lines out, which suits a two-line headline and not a title this long - it
   holds lines short on purpose. Pretty only guards the last line against a
   single stranded word and lets every line before it fill the width. */
.podcast-card__title {
  margin: 0;
  max-width: none;
  font-size: 1.0625rem;
  line-height: 1.35;
  color: var(--ivory-100);
  text-wrap: pretty;
}

.podcast-card__text {
  font-size: var(--fs-meta);
  color: var(--ivory-300);
}

/* Said on the card, not discovered on the click: this one leaves the site. */
.podcast-card__away {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  color: var(--ivory-500);
}

.podcast-card__links { margin-top: var(--sp-1); }

.podcast-teaser__more { margin-top: var(--sp-7); }

@media (prefers-reduced-motion: reduce) {
  .podcast-card,
  .podcast-card__still { transition: none; }
  .podcast-card:hover { transform: none; }
  .podcast-card:hover .podcast-card__still { transform: none; }
}

/* ── Downloads ── */

.download-list {
  border-top: 1px solid var(--hairline);
  list-style: none;
  padding: 0;
}

.download-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-4);
  padding-block: var(--sp-4);
  border-bottom: 1px solid var(--hairline);
  transition: background-color var(--dur) var(--ease-out);
}

.download-row:hover { background: var(--ink-800); }

.download-row__icon {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--hairline);
  border-radius: 50%;
  color: var(--gold-500);
}

.download-row__body { display: grid; gap: 2px; min-width: 0; }
.download-row__title { color: var(--ivory-100); }
.download-row__desc { color: var(--ivory-500); }

/* ───────────────────────────────────────────────────────────────────────────
   DISCOGRAPHY (§9.2)
   ─────────────────────────────────────────────────────────────────────────── */

.filter-bar { display: grid; gap: var(--sp-5); }

.filter-bar__pills ul,
.filter-bar__pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  list-style: none;
  padding: 0;
}

.filter-bar__tools {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sp-5);
  padding-bottom: var(--sp-4);
  border-bottom: 1px solid var(--hairline);
}

.field--inline { flex: 1 1 14rem; min-width: 0; }
.field--select { flex: 0 1 12rem; }

/* A label that never floats - used where there is no placeholder to shrink.
   A select always shows something, and a date input is never
   :placeholder-shown, so on neither of them can the control's own state drive
   the floating label. */
.field__label--static {
  position: static;
  display: block;
  order: -1;
  margin-bottom: var(--sp-1);
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--gold-500);
  transform: none;
}

/* `order` means nothing outside a flex or grid container, so a field holding a
   static label has to be a flex column - otherwise the label keeps the place
   the markup gives it, which is AFTER the control. That was the event date:
   EVENT DATE sat under its own input while every select's label sat above it,
   because the rule that made this work was written for .field--select and the
   date field is a plain .field. Keying off the label instead fixes the date
   without the template having to name it. And with no floating label to leave
   room for, the band above the control goes. */
.field:has(.field__label--static) {
  display: flex;
  flex-direction: column;
  --field-pad-top: 0;
}

.discography__grid { margin-top: var(--sp-6); }
.discography__empty { margin-top: var(--sp-6); }

/* ── Featured release ── */

.featured-release__cover { border-radius: var(--r-md); overflow: hidden; }
.featured-release__meta { margin-top: calc(var(--sp-3) * -1); }

/* ── Track list ── */

.track-list {
  counter-reset: track;
  list-style: none;
  padding: 0;
  border-top: 1px solid var(--hairline);
}

.track-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-3) var(--sp-4);
  padding-block: var(--sp-3);
  border-bottom: 1px solid var(--hairline);
  border-left: 2px solid transparent;
  padding-left: var(--sp-3);
  transition: background-color var(--dur) var(--ease-out),
              border-left-color var(--dur) var(--ease-out);
}

@media (min-width: 640px) {
  .track-row { grid-template-columns: auto minmax(0, 1fr) auto auto; }
}

.track-row:hover { background: var(--ink-800); }

/* The currently playing row takes the gold left border (§9.2). */
.track-row.is-playing {
  border-left-color: var(--gold-500);
  background: var(--ink-800);
}

.track-row__no {
  width: 2.2em;
  font-size: var(--fs-meta);
  color: var(--ivory-500);
}

.track-row__play {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 1px solid var(--hairline-hot);
  border-radius: 50%;
  color: var(--gold-400);
  transition: background-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out);
}

.track-row__play:hover,
.track-row__play:focus-visible {
  background: var(--action);
  color: var(--on-action);
}

.track-row__title { color: var(--ivory-100); min-width: 0; }
.track-row__raga { color: var(--ivory-500); }
.track-row__time { color: var(--ivory-500); font-size: var(--fs-meta); }

.track-list--compact .track-row { padding-block: var(--sp-2); }

.release-credits { margin-top: var(--sp-8); display: grid; gap: var(--sp-4); }

.release-hero__title { margin: 0; font-size: var(--fs-h1); }

.release-hero__facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5) var(--sp-7);
  margin: 0;
  padding-block: var(--sp-4);
  border-block: 1px solid var(--hairline);
}

.release-hero__fact dt {
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--ivory-500);
}

.release-hero__fact dd {
  margin: var(--sp-1) 0 0;
  font-family: var(--ff-display);
  font-size: var(--fs-h4);
  color: var(--ivory-100);
}

/* ── Film credits ── */

.credit-list {
  border-top: 1px solid var(--hairline);
  list-style: none;
  padding: 0;
}

.credit-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--sp-2) var(--sp-5);
  padding-block: var(--sp-4);
  border-bottom: 1px solid var(--hairline);
  align-items: baseline;
  transition: background-color var(--dur) var(--ease-out);
}

@media (min-width: 900px) {
  .credit-row {
    grid-template-columns: 5rem minmax(0, 1fr) auto minmax(0, 1.2fr);
    align-items: center;
  }
}

.credit-row:hover { background: var(--ink-800); }

.credit-row__year { color: var(--gold-500); font-size: var(--fs-meta); }

.credit-row__title {
  font-family: var(--ff-display);
  font-size: var(--fs-h4);
  color: var(--ivory-100);
}

.credit-row__kind { justify-self: start; }
.credit-row__meta { color: var(--ivory-500); }

.credits__note { margin-top: var(--sp-5); color: var(--ivory-700); }

/* ───────────────────────────────────────────────────────────────────────────
   GALLERY (§9.3)
   ─────────────────────────────────────────────────────────────────────────── */

.gallery__filters { margin-bottom: var(--sp-7); }

/* CSS columns, not a JS masonry library. */
.masonry {
  column-count: 1;
  column-gap: var(--sp-4);
}

@media (min-width: 700px) { .masonry { column-count: 2; } }
@media (min-width: 1200px) { .masonry { column-count: 3; } }

.masonry__item {
  break-inside: avoid;
  margin: 0 0 var(--sp-4);
}

.masonry__btn {
  position: relative;
  display: block;
  width: 100%;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--ink-850);
}

.masonry__btn img { width: 100%; transition: transform var(--dur-slow) var(--ease-out); }
.masonry__btn:hover img,
.masonry__btn:focus-visible img { transform: scale(1.04); }

.masonry__btn::before {
  content: '';
  position: absolute;
  inset: 10px;
  z-index: 2;
  border: 1px solid var(--hairline-hot);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
  pointer-events: none;
}

.masonry__btn:hover::before,
.masonry__btn:focus-visible::before { opacity: 1; }

.masonry__video {
  position: absolute;
  inset: 0;
  margin: auto;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 1px solid var(--gold-500);
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink-950) 55%, transparent);
  color: var(--gold-300);
}

.masonry__caption {
  margin-top: var(--sp-2);
  color: var(--ivory-500);
  text-align: left;
}

.masonry__credit { display: block; color: var(--ivory-700); }

.gallery__more {
  display: grid;
  gap: var(--sp-3);
  justify-items: center;
  margin-top: var(--sp-8);
}

.gallery__sentinel { display: block; height: 1px; }
.gallery__count { color: var(--ivory-500); }

/* ───────────────────────────────────────────────────────────────────────────
   CONCERTS (§9.4)
   ─────────────────────────────────────────────────────────────────────────── */

.concerts-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-5);
  padding-block: var(--sp-6);
}

/* The form takes the free width of the toolbar. Left at its content size it
   was squeezed beside the view switch until Year, City and Filter stacked in
   a column; given the room, they sit on one line. */
.concerts-toolbar__filters {
  flex: 1 1 32rem;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sp-4);
}

/* .btn sets align-self: start for the site at large; here Filter sits on the
   same baseline as the selects beside it and the view switch across from it. */
.concerts-toolbar__filters .btn { align-self: flex-end; }

/* On a phone the two selects share the line and Filter drops below them. */
@media (max-width: 479px) {
  .concerts-toolbar__filters .field--select { flex: 1 1 8rem; }
}

.concerts-toolbar__views { display: flex; gap: var(--sp-2); }

/* A row scrolled to from the calendar flashes gold, then settles. */
.concert-row.is-highlighted {
  background: var(--ink-700);
  box-shadow: inset 3px 0 0 var(--gold-500);
}

/* ── Calendar ── */

.calendar {
  display: grid;
  gap: var(--sp-7);
  margin-top: var(--sp-5);
}

@media (min-width: 700px) {
  .calendar { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
}

.calendar__month {
  width: 100%;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  padding: var(--sp-4);
  background: color-mix(in srgb, var(--ink-800) 60%, transparent);
}

.calendar__caption {
  padding-bottom: var(--sp-4);
  font-family: var(--ff-display);
  font-size: var(--fs-h4);
  color: var(--ivory-100);
  text-align: left;
}

.calendar__month th {
  padding-bottom: var(--sp-2);
  font-size: var(--fs-micro);
  font-weight: 500;
  color: var(--ivory-500);
}

.calendar__month th abbr { text-decoration: none; }

.calendar__month td { text-align: center; padding: 2px; }

.calendar__day {
  display: grid;
  place-items: center;
  gap: 2px;
  width: 100%;
  min-height: 36px;
  border-radius: var(--r-sm);
  font-size: var(--fs-meta);
  color: var(--ivory-500);
}

.calendar__day--has-event {
  color: var(--ivory-100);
  border: 1px solid var(--hairline-hot);
  transition: background-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out);
}

.calendar__day--has-event:hover,
.calendar__day--has-event:focus-visible {
  background: var(--action);
  color: var(--on-action);
}

.calendar__dot {
  width: 4px;
  height: 4px;
  background: var(--gold-500);
  transform: rotate(45deg);
}

.calendar__day--has-event:hover .calendar__dot { background: var(--ink-950); }

/* ── Concert detail ── */

.page-hero--concert { min-height: max(52vh, 420px); }

/* ── Concert footage gallery ──
   One row at a common height, each frame at its own shape: the height is
   fixed and aspect-ratio (set per slide as --ratio) gives the width. */
.concert-gallery {
  padding-top: var(--sp-6);
}

.concert-gallery__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-bottom: var(--sp-4);
}

.concert-gallery__title { margin: 0; }
.concert-gallery__count { margin-left: var(--sp-2); color: var(--ivory-500); }

.concert-gallery__nav {
  display: flex;
  gap: var(--sp-2);
}

.concert-gallery__nav .carousel__btn:disabled {
  opacity: .35;
  cursor: default;
  transform: none;
}

.concert-gallery__track {
  --slide-h: clamp(220px, 30vw, 380px);
  gap: var(--sp-4);
  margin: 0;
  padding-inline: 0;
  list-style: none;
}

.concert-gallery__track:focus-visible {
  outline: 2px solid var(--gold-500);
  outline-offset: 4px;
  border-radius: var(--r-md);
}

.concert-gallery__slide {
  height: var(--slide-h);
  aspect-ratio: var(--ratio, 3 / 2);
}

.concert-gallery__item {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--ink-850);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease-out);
}

.concert-gallery__item:hover,
.concert-gallery__item:focus-visible { border-color: var(--gold-500); }

.concert-gallery__item .picture,
.concert-gallery__item img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.concert-gallery__item img { transition: transform var(--dur-slow) var(--ease-out); }
.concert-gallery__item:hover img { transform: scale(1.03); }

/* The play badge is shared with the concert-row frames; larger here. */
.concert-gallery__item--video .footage__play svg { padding: 12px; }

.concert-detail__body { min-width: 0; }

.concert-detail__address {
  font-style: normal;
  color: var(--ivory-300);
  line-height: 1.8;
}

.concert-book__card {
  display: grid;
  gap: var(--sp-4);
  padding: var(--sp-6);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  background: var(--ink-800);
  box-shadow: var(--shadow-card);
}

.concert-book__facts { display: grid; gap: var(--sp-4); margin: 0; }

.concert-book__facts dt {
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--ivory-500);
}

.concert-book__facts dd {
  margin: var(--sp-1) 0 0;
  color: var(--ivory-100);
}

.concert-book__note {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  font-size: var(--fs-meta);
  color: var(--ivory-300);
}

.concert-book__enquire { margin-top: var(--sp-2); }

/* ───────────────────────────────────────────────────────────────────────────
   ABOUT (§9.5)
   ─────────────────────────────────────────────────────────────────────────── */

.mission__statement {
  max-width: 44ch;
  font-size: clamp(1.375rem, 1.1rem + 1.6vw, 2.25rem);
  line-height: 1.34;
  text-align: center;
  margin-inline: auto;
}

.services__grid { margin-top: var(--sp-6); }

/* Two by two. grid--2 fits as many 320px columns as it can, which on a wide
   screen is three - and the fourth card sat alone on a second row. */
@media (min-width: 700px) {
  .services__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* A column, not mini-card's grid: in a card stretched to its neighbour's
   height the grid rows grew too, spreading the lines apart and out of step
   with the card beside it. Now the text starts at the top in both, and the
   Enquire links share the bottom edge. */
.service-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-4);
}
.service-card > .link-arrow { margin-top: auto; }
.service-card__deva { color: var(--gold-500); }
.service-card__body { color: var(--ivory-300); }

.ensemble-card {
  display: grid;
  gap: var(--sp-3);
  position: relative;
}

.ensemble-card__portrait {
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--ink-850);
}

.ensemble-card__name { margin: 0; }
.ensemble-card__role { margin: 0; }

.ensemble-card__social {
  position: absolute;
  top: var(--sp-3);
  right: var(--sp-3);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}

.ensemble-card:hover .ensemble-card__social,
.ensemble-card:focus-within .ensemble-card__social { opacity: 1; }

/* ── Numbers band ── */

/* The figures sit in the middle of the page, not spread across it.
   A row that stretches to both gutters reads as three separate columns; a row
   that is only as wide as its figures reads as one statement. So the cells are
   laid out as a centred row, each one only as wide as it needs to be, with a
   hairline between them. However many figures there are, they stay centred, and
   on a narrow screen they wrap and stay centred. */
.numbers__band {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  margin: 0;
  text-align: center;
}

.numbers__cell {
  display: grid;
  align-content: start;
  justify-items: center;
  gap: var(--sp-3);
  min-width: 0;
  padding-inline: clamp(var(--sp-5), 4vw, var(--sp-9));
  border-left: 1px solid var(--hairline);
}

.numbers__cell:first-child { border-left: 0; }

/* Wrapped rows start a new line, and the first cell on it must not carry a
   divider either. Two per line below 900px is what the space allows. */
@media (max-width: 899px) {
  .numbers__cell { padding-inline: var(--sp-5); }
  .numbers__cell:nth-child(odd) { border-left: 0; }
}

/* The figures are the point of this band, so they are set at display size and
   at 700 - the heaviest weight Google Sans is drawn in. Asking for 800 would
   get a weight the family does not have, and the browser would smear the 700
   outlines to fake it, which at this size is very visible. */
.numbers__value {
  font-family: var(--ff-display);
  font-size: clamp(3.5rem, 2rem + 6vw, 7rem);
  font-weight: 700;
  line-height: .9;
  letter-spacing: var(--ls-display);
  color: var(--gold-500);
}

.numbers__label {
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--ivory-500);
}

/* ── Stepper ── */

.stepper {
  position: relative;
  display: grid;
  gap: var(--sp-6);
  margin-top: var(--sp-7);
  list-style: none;
  padding: 0;
}

@media (min-width: 900px) {
  .stepper { grid-template-columns: repeat(4, 1fr); gap: var(--sp-5); }

  /* The connecting hairline runs behind the dots. */
  .stepper::before {
    content: '';
    position: absolute;
    top: 5px;
    left: 12%;
    right: 12%;
    height: 1px;
    background: var(--hairline);
  }
}

.stepper__step {
  position: relative;
  display: grid;
  gap: var(--sp-2);
  padding-top: var(--sp-6);
}

.stepper__dot {
  position: absolute;
  top: 0;
  left: 0;
  width: 11px;
  height: 11px;
  border: 1px solid var(--gold-500);
  background: var(--ink-900);
  transform: rotate(45deg);
  transition: background-color var(--dur-slow) var(--ease-out);
}

.stepper__step.is-revealed .stepper__dot { background: var(--gold-500); }

.stepper__index {
  font-size: var(--fs-micro);
  letter-spacing: .16em;
  color: var(--gold-500);
}

.stepper__title { margin: 0; }

/* ───────────────────────────────────────────────────────────────────────────
   CONTACT (§9.6)
   ─────────────────────────────────────────────────────────────────────────── */

.contact__form-col { min-width: 0; }

.contact-form { margin-top: var(--sp-6); }

.contact-form__grid { display: grid; gap: var(--sp-5); }

@media (min-width: 700px) {
  .contact-form__grid { grid-template-columns: 1fr 1fr; }
  .contact-form__message,
  .contact-form__consent,
  .contact-form__challenge { grid-column: 1 / -1; }
}

.contact-form__phone {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr);
  gap: var(--sp-4);
  align-items: end;
}

.contact-form__submit { margin-top: var(--sp-7); }
.contact-form__note { margin-top: var(--sp-4); color: var(--ivory-500); }

.contact__aside { min-width: 0; }

.contact__line {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--touch);
  color: var(--ivory-200);
  transition: color var(--dur) var(--ease-out);
}

.contact__line .icon { color: var(--gold-500); }
.contact__line:hover { color: var(--gold-300); }

.contact__card {
  display: grid;
  gap: var(--sp-3);
  padding: var(--sp-5);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--ink-800) 70%, transparent);
}

.contact__card hr {
  width: 100%;
  height: 1px;
  border: 0;
  margin: 0;
  background: var(--hairline);
}

/* ───────────────────────────────────────────────────────────────────────────
   JOURNAL, SEARCH, LEGAL, 404
   ─────────────────────────────────────────────────────────────────────────── */

.journal__filters { margin-bottom: var(--sp-7); }

.pager {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  justify-content: center;
  margin-top: var(--sp-8);
}

.pager__link {
  display: grid;
  place-items: center;
  min-width: var(--touch);
  min-height: var(--touch);
  padding-inline: var(--sp-3);
  border: 1px solid var(--hairline);
  border-radius: var(--r-pill);
  font-variant-numeric: tabular-nums;
  color: var(--ivory-300);
  transition: border-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out);
}

.pager__link:hover { border-color: var(--hairline-hot); color: var(--ivory-100); }

.pager__link.is-current {
  background: var(--action);
  border-color: var(--action);
  color: var(--on-action);
}

.post__head { display: grid; gap: var(--sp-3); }
.post__title { margin: 0; font-size: var(--fs-h1); }
.post__meta { margin: 0; }

.post__figure {
  margin-block: var(--sp-7);
  border-radius: var(--r-md);
  overflow: hidden;
}

.post__body { margin-top: var(--sp-6); }

.post__nav {
  display: grid;
  gap: var(--sp-4);
  margin-top: var(--sp-9);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--hairline);
}

@media (min-width: 700px) {
  .post__nav { grid-template-columns: 1fr 1fr; }
  .post__nav-link--next { text-align: right; }
}

.post__nav-link {
  display: grid;
  gap: var(--sp-2);
  padding: var(--sp-4);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  color: var(--ivory-500);
  transition: border-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out);
}

.post__nav-link:hover { border-color: var(--hairline-hot); color: var(--ivory-200); }

.post__nav-title {
  font-family: var(--ff-display);
  font-size: var(--fs-h4);
  color: var(--ivory-100);
}

/* ── Search ── */

.search-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sp-4);
  margin-bottom: var(--sp-7);
}

.search-form .field { flex: 1 1 18rem; }

.search-page__hint,
.search-page__count { color: var(--ivory-500); }

.search-group { margin-top: var(--sp-7); }

.search-list {
  margin-top: var(--sp-4);
  border-top: 1px solid var(--hairline);
  list-style: none;
  padding: 0;
}

.search-row { border-bottom: 1px solid var(--hairline); }

.search-row__link {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-2) var(--sp-4);
  padding-block: var(--sp-4);
  padding-inline: var(--sp-3);
  transition: background-color var(--dur) var(--ease-out);
}

.search-row__link:hover { background: var(--ink-800); }

.search-row__title {
  font-family: var(--ff-display);
  font-size: var(--fs-h4);
  color: var(--ivory-100);
}

.search-row__meta { grid-column: 1; color: var(--ivory-500); }
.search-row__link .icon { grid-row: 1 / -1; grid-column: 2; color: var(--gold-500); }

/* ── Legal ── */

.legal__updated { margin-bottom: var(--sp-6); }
.legal__body h2 { color: var(--ivory-100); }

/* ── 404 ── */

.error-page {
  display: grid;
  place-items: center;
  min-height: 72svh;
}

.error-page__inner { max-width: 52ch; }
.error-page__code { color: var(--ivory-100); }

.error-page__search {
  justify-content: center;
  margin-top: var(--sp-5);
  width: min(100%, 28rem);
}

/* ───────────────────────────────────────────────────────────────────────────
   PRINT
   ─────────────────────────────────────────────────────────────────────────── */

@media print {
  .page-hero { min-height: 0; padding-block: 0 12pt; }
  .page-hero__media, .page-hero__ghost { display: none; }
  .concert-book__card { box-shadow: none; }
  .parampara__wires, .sitar__spots { display: none; }

  /* With the spots gone there is nothing to explain a part standing out, so
     print the whole instrument at one strength. */
  .sitar__figure.is-focused .sitar-svg > g > * { opacity: 1; color: inherit; }
  .masonry { column-count: 2; }
}

}
