/* =====================================================================
 * Jain Digambar Diwali Poojan — core stylesheet
 * Design language: warm paper · near-black ink · restrained gold
 * Light by default; only the surfaces painted over video stay dark.
 * ===================================================================== */

/* ---------- 1. TOKENS ------------------------------------------------- */
:root {
  /* surface — a warm paper scale. The names carry over from the dark build:
     900 is still the page itself, and the numbers still climb toward the
     raised / hovered / pressed tones. Only the direction of travel flips. */
  /* The page is a light grey and the panels sitting on it are white — the
     playlist, the side cards, the popovers. The scale keeps a little
     warmth so the gold still belongs to it, but the ground is grey and
     the surfaces raised off it are paper. */
  --ink-900: #f0efec;   /* the page itself */
  /* Raised surfaces. Not pure white — that is spent on one thing only, the
     playlist, so the sequence reads as the sheet you are working on and
     everything else as furniture around it. */
  --ink-850: #f8f8f6;
  --paper:   #ffffff;   /* the playlist, and nothing else */
  --ink-800: #f8f7f4;
  --ink-750: #eeede9;
  --ink-700: #e4e2db;
  --ink-600: #d6d3ca;

  /* text — likewise: --ivory still means "the strongest text colour". */
  --ivory:   #191510;
  --ivory-2: #3b352a;
  --muted:   #6d6553;
  --muted-2: #928a76;

  /* accent */
  --gold:      #c9a227;
  --gold-lite: #e8cf85;
  --gold-deep: #8f7016;
  --gold-glow: rgba(201, 162, 39, .34);
  /* #c9a227 is a fill, not a text colour: on paper it lands near 2.5:1 and
     small labels smear into the background. --gold-ink is the same hue
     carried down to a readable value; over video it resolves to --gold-lite. */
  --gold-ink:  #8a6a0d;
  --on-gold:   #241a06;

  /* hairlines and washes, as ink on paper rather than light on dark */
  --line:      rgba(40, 31, 10, .14);
  --line-2:    rgba(40, 31, 10, .09);
  --fill-1:    rgba(40, 31, 10, .04);
  --fill-2:    rgba(40, 31, 10, .07);
  --fill-3:    rgba(40, 31, 10, .10);
  --glass:     rgba(250, 250, 248, .74);
  --glass-bar: rgba(255, 255, 255, .9);
  --slider-track: rgba(40, 31, 10, .2);
  /* the paper the player's own chrome is printed on, over the footage */
  --vid-glass: rgba(251, 250, 247, .94);

  /* type
     Latin      — Marcellus for display (classical, warm), Manrope for UI
     Devanagari — Martel for display (warm editorial serif), Mukta for UI.
     Martel + Mukta are a matched pair from the same foundry, and both have
     solid conjunct shaping — which display faces like Rozha One handle
     poorly at UI sizes. */
  --f-serif:       'Marcellus', 'Cormorant Garamond', 'Iowan Old Style', Georgia, serif;
  --f-title:       'Marcellus', 'Cormorant Garamond', Georgia, serif;
  --f-display:     'Cormorant Garamond', 'Marcellus', Georgia, serif;
  --f-sans:        'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --f-deva:        'Mukta', 'Devanagari Sangam MN', 'Noto Sans Devanagari', 'Kohinoor Devanagari', sans-serif;
  --f-deva-display:'Martel', 'Noto Serif Devanagari', 'Devanagari Sangam MN', serif;

  /* geometry */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 18px;
  --shadow: 0 16px 40px rgba(58, 44, 12, .13);
  --ring: 0 0 0 2px var(--ink-850), 0 0 0 3.5px var(--gold);

  /* layout */
  --topbar-h: 62px;
  --gap: 22px;
  --stage-pad: clamp(14px, 2.4vw, 28px);
  --stage-max: 1680px;
  --list-w: clamp(320px, 27vw, 400px);


  /* One height for everything in the landing's top-right cluster, and for
     the panel handles opposite it, so the whole top edge lines up. */
  --tool-h: 40px;

  /* side panels — see section 8b */
  --panel-w: clamp(280px, 22vw, 360px);
  /* One margin for everything pinned to the edge of the landing — the two
     handles, the top-right cluster, and both panels. They read as a set of
     columns, and a set of columns has to share its guides. */
  --edge: clamp(16px, 3vw, 30px);
  /* Vertical room the top row needs before a panel may start under it. */
  --edge-top: clamp(72px, 9vh, 88px);
  /* Where the top row sits, and therefore where a panel folds away to. */
  --handle-top: clamp(16px, 3vh, 28px);


  /* Native widgets — the search field's clear glyph, form autofill,
     scrollbar gutters — follow this rather than the page colours. */
  color-scheme: light;

  /* motion */
  --e-out: cubic-bezier(.22, .8, .28, 1);
  --e-io:  cubic-bezier(.6, .02, .2, 1);
}

/* ---------- 1b. NO DARK REGION LEFT ----------------------------------
 * There used to be a second palette here, re-declared on the surfaces
 * painted over moving footage — first the player frame, then the landing
 * screen. Both are gone: the player controls sit on a scrim that was
 * turned to paper, and the landing chrome (mantra dock, language toggle,
 * panel handles) was asked for in paper too.
 *
 * What that costs is contrast against the footage, which each of those
 * pieces now buys back for itself with an opaque ground and its own
 * shadow rather than by borrowing a dark palette. One palette, one page.
 * -------------------------------------------------------------------- */

/* ---------- 2. RESET -------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow-x: hidden;          /* never allow horizontal page scroll */
}

body {
  background: var(--ink-900);
  color: var(--ivory);
  font-family: var(--f-sans);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overscroll-behavior: none;
}

body.is-landing { overflow: hidden; }

img, video { display: block; max-width: 100%; }
button, input { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
ol, ul { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, p { margin: 0; }

/* Component rules below set display on these elements, which would beat the
   UA's `[hidden]{display:none}` on specificity. Everything the JS toggles via
   .hidden depends on this staying authoritative. */
[hidden] { display: none !important; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.ico { width: 21px; height: 21px; fill: currentColor; flex: none; }
.ico--sm { width: 16px; height: 16px; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

:focus { outline: none; }
:focus-visible { box-shadow: var(--ring); border-radius: var(--r-sm); }

::selection { background: var(--gold-glow); color: var(--ivory); }

/* scrollbars */
* { scrollbar-width: thin; scrollbar-color: var(--ink-600) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--ink-600); border-radius: 99px; }
*::-webkit-scrollbar-thumb:hover { background: #c6bb9d; }


/* =====================================================================
 * 3. LANDING
 * ===================================================================== */
.landing {
  position: fixed;
  inset: 0;
  display: grid;
  grid-template-rows: 1fr auto;
  overflow: hidden;
  background: var(--ink-900);
}

.landing__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

.landing.no-video::before {
  content: '';
  position: absolute; inset: 0; z-index: 0;
  background: var(--fallback-img) center / cover no-repeat, var(--ink-850);
  filter: saturate(.85);
}

.landing__inner {
  position: relative; z-index: 2;
  align-self: center;
  text-align: center;
  padding: 6vh 24px 0;
  animation: riseIn 1.1s var(--e-out) both .25s;
}
/* The background footage already carries its own wordmark, so the entire
   overlay text block — eyebrow, title, divider rule and subtitle — is
   hidden and the footage is left to speak for itself.
   To bring it back, delete this one rule. */
.landing__inner { display: none; }

.landing__eyebrow {
  font-family: var(--f-deva);
  font-size: clamp(11px, 1.5vw, 13px);
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--gold-lite);
  opacity: .82;
  margin-bottom: 22px;
}

.landing__title {
  font-family: var(--f-title);
  font-weight: 500;
  font-size: clamp(30px, 6.4vw, 76px);
  line-height: 1.06;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #fffaf0;
  text-shadow: 0 2px 30px rgba(0, 0, 0, .6);
}
.landing__title-line { display: block; }
.landing__title-line:last-child {
  background: linear-gradient(100deg, var(--gold-lite) 8%, #fff4d8 38%, var(--gold) 78%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}

.landing__rule {
  display: flex; align-items: center; justify-content: center;
  gap: 12px; margin: 26px auto 20px; max-width: 300px;
}
.landing__rule span {
  height: 1px; flex: 1;
  background: linear-gradient(90deg, transparent, rgba(201, 162, 39, .55), transparent);
}
.landing__rule i {
  width: 5px; height: 5px; flex: none;
  background: var(--gold); transform: rotate(45deg);
  box-shadow: 0 0 10px var(--gold-glow);
}

.landing__subtitle {
  font-family: var(--f-serif);
  font-size: clamp(14px, 2.1vw, 21px);
  font-weight: 300;
  letter-spacing: .34em;
  text-transform: uppercase;
  color: var(--ivory-2);
  opacity: .9;
}

/* ---------- chakra CTA ------------------------------------------------ */
.landing__cta-wrap {
  position: relative; z-index: 2;
  /* Pinned to the bottom row explicitly: the text block above is hidden, so
     auto-placement would otherwise drop the CTA into the first row. */
  grid-row: 2;
  align-self: end;
  display: grid; justify-items: center;
  padding-bottom: clamp(28px, 5vh, 54px);

  /* Ranged right while the preparation panel is folded — that corner is
     free, and it is where the CTA belongs. When the panel comes out it
     takes the right of the screen, so the CTA slides to the middle to stay
     clear of it, and slides back when the panel folds.

     Done as a transform rather than by switching `justify-self`, which is
     not animatable: the item stays centred in the grid and the transform
     carries it to the right edge — 50% here is half its own width, so the
     sum lands its right edge exactly --edge from the page. */
  justify-self: center;
  transform: translateX(calc(50vw - var(--edge) - 50%));
  transition: transform .5s var(--e-out);
}
body.panel-r-on .landing__cta-wrap { transform: none; }

/* The medallion artwork behind this is gone; the CTA is the plate alone,
   so the button simply wraps it. */
.chakra {
  position: relative;
  display: inline-grid;
  place-items: center;
  padding: 0;               /* the UA gives buttons 1px 6px; the plate is the button */
  border-radius: 99px;
  transition: transform .5s var(--e-out);

  /* The entrance lives on the button, not on the wrapper, because the
     wrapper's transform is now doing the positioning and an animation
     would outrank it. `backwards` rather than `both`: it holds the opening
     frame before the delay, then lets go — a filled-forwards animation
     would go on outranking :hover for the life of the page. */
  animation: riseIn 1.1s var(--e-out) backwards .55s;
}
/* A lift, not just a swell. Scale alone reads as the button growing;
   moving it against its own shadow is what reads as it rising. */
.chakra:hover  { transform: translateY(-2px) scale(1.02); }
.chakra:active { transform: translateY(1px) scale(.99); transition-duration: .12s; }
.chakra:focus-visible { outline: none; }
.chakra:focus-visible .chakra__label {
  box-shadow:
    inset 0 1px 0 rgba(255, 253, 242, .92),
    inset 0 -1px 0 rgba(90, 62, 6, .45),
    0 0 0 2px #fffdf4,
    0 0 0 4.5px var(--gold-deep),
    0 10px 24px rgba(74, 51, 4, .2);
}

/* engraved gold disc holding the label */
.chakra__label {
  position: relative;
  z-index: 2;
  /* A lozenge, not a disc.
     A circle is a poor container for four words: the line has to break at
     the widest point and every other line loses the corners, so the text
     ends up small and cramped in the middle of a lot of gold. Since the
     medallion's own centre is below the fold, the label has nothing left
     to be the hub of — so it stops pretending, and becomes a plate that
     fits its text: one line at a readable size, with the rays of the
     rising sun behind it.

     It sits in normal flow now — there is no circle left to place it
     against, so the wrapper's own bottom padding is what lifts it off the
     edge of the screen. */
  max-width: min(84vw, 460px);
  border-radius: 99px;
  display: grid;
  place-items: center;
  padding: 16px 36px;
  text-align: center;
  text-wrap: balance;
  font-family: var(--f-deva-display);
  font-size: clamp(13px, 1.4vw, 18px);
  font-weight: 700;
  line-height: 1.3;
  color: #3a2600;
  /* Struck metal, not a glossy web button. Three layers: a narrow specular
     sweep, a top gloss that dies by 42%, and the metal itself. The hard
     tone break at 46/54% is the reflection horizon — it is the one thing
     that separates gold from a yellow gradient. */
  background:
    linear-gradient(100deg,
      transparent 34%,
      rgba(255, 255, 255, .50) 46%,
      rgba(255, 255, 255, .08) 54%,
      transparent 64%),
    linear-gradient(180deg, rgba(255, 255, 255, .55) 0%, rgba(255, 255, 255, 0) 42%),
    linear-gradient(180deg,
      #f7e6b4 0%,
      #eed58c 20%,
      #ddb84f 46%,
      #cda32f 54%,
      #b98a1a 78%,
      #9d7010 100%);
  /* The old single 26px black blob went grey and muddy the moment the scrim
     came off. Four warm-brown layers instead — each roughly double the last
     — read as one object catching one light, and a hairline ring keeps the
     edge crisp against a bright frame of the footage. */
  box-shadow:
    inset 0 1px 0 rgba(255, 253, 242, .92),
    inset 0 -1px 0 rgba(90, 62, 6, .45),
    inset 0 -7px 14px rgba(120, 84, 8, .26),
    0 0 0 1px rgba(146, 106, 14, .55),
    0 1px 1px rgba(74, 51, 4, .16),
    0 3px 5px rgba(74, 51, 4, .14),
    0 8px 16px rgba(74, 51, 4, .14),
    0 18px 36px rgba(74, 51, 4, .18),
    0 0 46px rgba(201, 162, 39, .26);
  text-shadow: 0 1px 0 rgba(255, 250, 225, .65);
  transition: box-shadow .45s var(--e-out), transform .45s var(--e-out);
}
/* The button itself already scales on hover; the plate only deepens. */
.chakra:hover .chakra__label {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 250, 1),
    inset 0 -1px 0 rgba(90, 62, 6, .4),
    inset 0 -7px 14px rgba(120, 84, 8, .2),
    0 0 0 1px rgba(163, 120, 20, .6),
    0 2px 2px rgba(74, 51, 4, .14),
    0 5px 9px rgba(74, 51, 4, .13),
    0 12px 22px rgba(74, 51, 4, .13),
    0 26px 48px rgba(74, 51, 4, .2),
    0 0 66px rgba(232, 207, 133, .5);
}

.chakra.is-firing { animation: fireCta .62s var(--e-io) forwards; }

/* The last line of bare text on the footage. A halo was not enough — the
   background video runs from a white temple to near-black — so it takes a
   plate of its own like every other piece of landing chrome. */

/* ---------- language toggle -------------------------------------------- */
.langbtn {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 6px 12px;
  border-radius: 99px;
  font-size: 11.5px;
  letter-spacing: .04em;
  color: var(--muted);
  background: var(--vid-glass);
  border: 1px solid var(--line);
  box-shadow: 0 4px 16px rgba(24, 18, 4, .18);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  transition: color .25s, border-color .25s, background .25s;
}
.langbtn:hover { color: var(--ivory); border-color: rgba(201, 162, 39, .55); }
.langbtn__sep { opacity: .35; }
/* din / raat toggle - jo chal raha hai wo sunehra */
.modebtn { font-size: 1.05em; }
.modebtn__day   { color: var(--gold-ink); }
.modebtn__night { opacity: .6; }
body.mode-night .modebtn__day   { color: var(--muted); opacity: .6; }
body.mode-night .modebtn__night { color: var(--gold-ink); opacity: 1; }
.langbtn__on  { color: var(--gold-ink); }          /* active language */
.langbtn__off { opacity: .6; }
body.lang-en .langbtn__on  { color: var(--muted); opacity: .6; }
body.lang-en .langbtn__off { color: var(--gold-ink); opacity: 1; }

/* The landing's two top clusters. Each panel's handle sits at its own end
   of the page, flush with that panel's edge, so a card folds into the
   button next to it rather than into thin air — the mantra control keeps
   the left company, the language toggle the right.

   Fixed, and outside .landing, so they are not inside the section that
   gets hidden on the way into the Poojan. */
.landing__tools {
  position: fixed; z-index: 6;
  top: var(--handle-top);
  display: flex; align-items: center; gap: 10px;
  animation: riseIn .9s var(--e-out) both .8s;
}
.landing__tools--l { left: var(--edge); }
.landing__tools--r { right: var(--edge); }
body.is-poojan .landing__tools { display: none; }

/* To the eye these are one control repeated, so they get one plate: the
   same height, ring, ground and shadow. Each still keeps its own insides.
   The handles are left out — they carry a gold ring of their own, and it
   says whether their panel is out. */
.landing__tools .audiodock,
.landing__tools .langbtn {
  height: var(--tool-h);
  border-radius: 99px;
  background: var(--vid-glass);
  border: 1px solid var(--line);
  box-shadow: 0 8px 26px rgba(24, 18, 4, .24);
  backdrop-filter: blur(16px) saturate(1.2);
  -webkit-backdrop-filter: blur(16px) saturate(1.2);
}
.landing__tools .langbtn            { padding: 0 15px; }
.landing__tools .audiodock          { padding: 0 6px 0 5px; height: var(--tool-h); }
.landing__tools .audiodock__btn     { padding: 0 10px 0 8px; }
.landing__tools .audiodock__vol-btn { width: 30px; height: 30px; }
.langbtn--bar { background: none; backdrop-filter: none; -webkit-backdrop-filter: none; }

/* ---------- audio dock ------------------------------------------------ */
/* Up in the cluster rather than floating in the bottom-left corner. That
   corner was the only thing keeping the left panel from running the full
   height of the page, and this is what gave it back. */
.audiodock {
  position: relative;
  display: flex; align-items: center; gap: 2px;
  padding: 5px 6px 5px 5px;
  border-radius: 99px;
  background: var(--vid-glass);
  border: 1px solid var(--line);
  backdrop-filter: blur(16px) saturate(1.2);
  -webkit-backdrop-filter: blur(16px) saturate(1.2);
  box-shadow: 0 8px 26px rgba(24, 18, 4, .24);
  animation: riseIn .9s var(--e-out) both .85s;
}
body.is-poojan .audiodock { display: none; }

.audiodock__btn {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 12px 7px 10px;
  border-radius: 99px;
  color: var(--ivory-2);
  transition: color .3s, background .3s;
}
.audiodock__btn:hover { color: var(--ivory); background: var(--fill-1); }

.audiodock__label {
  font-size: 12.5px;
  letter-spacing: .05em;
  white-space: nowrap;
}

/* mini visualiser */
.audiodock__viz {
  display: flex; align-items: flex-end; gap: 2.5px;
  height: 15px; width: 17px;
}
.audiodock__viz i {
  width: 2.5px; flex: none;
  background: var(--gold);
  border-radius: 2px;
  height: 4px;
  transform-origin: bottom;
  transition: height .3s var(--e-out);
  opacity: .55;
}
.audiodock.is-playing .audiodock__viz i {
  opacity: 1;
  animation: vizBar 1.1s var(--e-io) infinite;
}
.audiodock.is-playing .audiodock__viz i:nth-child(1) { animation-delay: 0s;    height: 12px; }
.audiodock.is-playing .audiodock__viz i:nth-child(2) { animation-delay: .18s;  height: 15px; }
.audiodock.is-playing .audiodock__viz i:nth-child(3) { animation-delay: .36s;  height: 8px;  }
.audiodock.is-playing .audiodock__viz i:nth-child(4) { animation-delay: .52s;  height: 13px; }

.audiodock.is-missing { opacity: .45; pointer-events: none; }

/* the browser is holding audible playback until one interaction —
   a soft gold breath on the dock invites it without nagging */
.audiodock.is-awaiting {
  border-color: rgba(201, 162, 39, .45);
  animation: dockWait 2.8s var(--e-io) infinite;
}
.audiodock.is-awaiting .audiodock__viz i { background: var(--gold); opacity: .9; }
@keyframes dockWait {
  0%, 100% { box-shadow: 0 8px 26px rgba(24, 18, 4, .24), 0 0 0 0 rgba(201, 162, 39, .45); }
  50%      { box-shadow: 0 8px 26px rgba(24, 18, 4, .24), 0 0 0 7px rgba(201, 162, 39, 0); }
}

.audiodock__vol-btn {
  position: relative;
  display: grid; place-items: center;
  width: 34px; height: 34px;
  border-radius: 50%;
  color: var(--muted);
  transition: color .3s, background .3s;
}
.audiodock__vol-btn:hover { color: var(--ivory); background: var(--fill-2); }
.audiodock.is-muted .audiodock__vol-btn { color: var(--gold-ink); }
.audiodock.is-muted .audiodock__viz i { animation-play-state: paused; opacity: .35; }

/* The slider reveals itself on hover/focus, so the speaker button is free to
   be a plain mute toggle (same pattern as the player's volume control). */
.audiodock__pop {
  display: flex; align-items: center; gap: 10px;
  width: 0; opacity: 0; overflow: hidden;
  transition: width .42s var(--e-out), opacity .3s, padding .42s var(--e-out);
}
.audiodock:hover .audiodock__pop,
.audiodock:focus-within .audiodock__pop,
.audiodock.pop-open .audiodock__pop {
  width: 146px; opacity: 1; padding: 0 10px 0 4px;
}
.audiodock__pct {
  font-size: 11px; color: var(--muted);
  font-variant-numeric: tabular-nums; width: 30px;
}


/* =====================================================================
 * 4. TRANSITION VEIL
 * ===================================================================== */
.veil {
  position: fixed; inset: 0; z-index: 90;
  /* The landing is dark footage and the app is paper, so the veil is paper:
     the crossing reads as a lamp being lit rather than as a blackout. */
  background: radial-gradient(circle at 50% 60%, #ffffff 0%, var(--ink-900) 100%);
  opacity: 0; pointer-events: none;
  transition: opacity .5s var(--e-io);
}
.veil.is-on { opacity: 1; pointer-events: all; }

body.is-leaving .landing__inner { opacity: 0; transform: translateY(-10px); transition: opacity .45s, transform .55s var(--e-out); }


/* =====================================================================
 * 5. APP SHELL
 * ===================================================================== */
.app {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .6s var(--e-out), transform .7s var(--e-out);
  background:
    radial-gradient(90% 60% at 50% -10%, rgba(201, 162, 39, .16), transparent 60%),
    var(--ink-900);
}
.app.is-in { opacity: 1; transform: none; }

/* ---------- topbar ---------------------------------------------------- */
.topbar {
  position: sticky; top: 0; z-index: 30;
  height: var(--topbar-h);
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  padding: 0 clamp(14px, 2.4vw, 28px);
  background: var(--glass-bar);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border-bottom: 1px solid var(--line-2);
}
.topbar__left, .topbar__right { display: flex; align-items: center; gap: 6px; min-width: 0; }
/* The header's right-hand controls are fixed affordances; the title beside
   them is the elastic part, and it already has an ellipsis for the purpose.
   Without this the flex box balances the row by taking the space out of the
   buttons instead — at 320 the language toggle was squeezed from 70px to 43
   and its own label spilled out over the edge of the screen. */
.topbar__right, .topbar__right > * { flex: none; }

/* The preparation handle again, but the header is not footage. The drop
   and the blur that keep it legible floating over video have nothing to
   lift off a flat bar and read as a smudge under it — so up here it sits
   flush, and sized to the other header buttons rather than to the landing
   cluster. Lit is signal enough on its own; the gold fill needs no halo. */
.topbar .paneldock {
  width: 36px; height: 36px;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.topbar .paneldock .ico { width: 19px; height: 19px; }
.topbar .paneldock.is-on { box-shadow: none; }

.brand { display: flex; align-items: center; gap: 11px; min-width: 0; }
.brand__mark {
  width: 26px; height: 26px; flex: none;
  border-radius: 50%;
  border: 1px solid rgba(201, 162, 39, .45);
  background:
    radial-gradient(circle at 50% 50%, var(--gold) 0 2.5px, transparent 3px),
    conic-gradient(from 0deg, transparent 0 8deg, rgba(201,162,39,.5) 8deg 10deg, transparent 10deg 30deg);
  box-shadow: 0 0 12px rgba(201, 162, 39, .18);
}
/* Devanagari needs headroom above the baseline for its matras; with
   overflow:hidden for the ellipsis, a tight line-height clips them. */
.brand__text { display: flex; flex-direction: column; min-width: 0; line-height: 1.5; }
.brand__text strong {
  color: var(--ivory);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brand__text em {
  font-style: normal; font-size: 10.5px;
  color: var(--muted-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ---------- stage grid ------------------------------------------------ */
.stage {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--list-w);
  gap: var(--gap);
  padding: var(--gap) var(--stage-pad) 34px;
  align-items: start;
  max-width: var(--stage-max);
  width: 100%;
  margin: 0 auto;
}

/* Nothing steps aside in here any more: the side panels belong to the
   landing screen, and the Poojan view is left to the video and the list. */
.col-player { min-width: 0; display: grid; gap: 18px; }
.col-list {
  min-width: 0;
  position: sticky;
  top: calc(var(--topbar-h) + var(--gap));
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  max-height: calc(100dvh - var(--topbar-h) - var(--gap) - 34px);
  background: var(--paper);
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  overflow: hidden;
}


/* =====================================================================
 * 6. PLAYER
 * ===================================================================== */
.player { position: relative; }

.player__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  /* Letterbox bars, on the rare clip that is not 16:9. Paper rather than
     black, so a mismatched aspect ratio reads as a margin on the page and
     not as a hole cut into it. */
  background: var(--ink-700);
  border-radius: var(--r-lg);
  overflow: hidden;
  /* Spelled out rather than reaching for --shadow: this element is itself
     one of the dark roots above, so the token would resolve to the dark
     value and drop a heavy black plate onto the paper. */
  box-shadow: 0 20px 46px rgba(52, 40, 10, .17), 0 0 0 1px rgba(40, 31, 10, .10);
  transition: opacity .28s var(--e-out);
}
/* A dip, not a blank-out. At .35 the frame read as a broken page whenever
   the swap ran long; .62 still says "changing" and keeps the poster legible
   the whole way through. player.js guarantees this lifts — see SWAP_MAX_MS. */
.player.is-swapping .player__frame { opacity: .62; }

.player__video { width: 100%; height: 100%; object-fit: contain; background: var(--ink-700); }

.player__tap { position: absolute; inset: 0; z-index: 2; }

.player__center {
  position: absolute; z-index: 3;
  top: 50%; left: 50%;
  translate: -50% -50%;
  width: 78px; height: 78px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--vid-glass);
  border: 1px solid rgba(201, 162, 39, .45);
  backdrop-filter: blur(8px);
  box-shadow: 0 6px 20px rgba(52, 40, 10, .22);
  color: var(--gold-ink);
  opacity: 0;
  pointer-events: none;
  transition: opacity .3s var(--e-out);
}
.player__center .ico { width: 30px; height: 30px; }
.player:not(.is-playing) .player__center { opacity: 1; }
.player.has-error .player__center { opacity: 0; }
.player__center.is-pulse { animation: centrePulse .5s var(--e-out); }

.player__spinner {
  position: absolute; z-index: 4;
  top: 50%; left: 50%; translate: -50% -50%;
  width: 42px; height: 42px;
}
.player__spinner i {
  display: block; width: 100%; height: 100%;
  border: 2px solid rgba(201, 162, 39, .22);
  border-top-color: var(--gold-ink);
  border-radius: 50%;
  animation: spin .85s linear infinite;
}

/* loop chip */
.loopchip {
  position: absolute; z-index: 5;
  top: 14px; left: 14px;
  display: flex; align-items: center; gap: 8px;
  padding: 7px 13px;
  border-radius: 99px;
  font-size: 11.5px;
  font-family: var(--f-deva);
  letter-spacing: .04em;
  color: var(--ivory-2);
  background: var(--vid-glass);
  border: 1px solid var(--line);
  box-shadow: 0 4px 14px rgba(52, 40, 10, .18);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  font-variant-numeric: tabular-nums;
}
.loopchip--ab { border-color: rgba(201, 162, 39, .5); color: var(--gold-ink); }
.loopchip__dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 9px var(--gold-glow);
  animation: breathe 2.6s var(--e-io) infinite;
}

/* error */
.player__error {
  position: absolute; inset: 0; z-index: 8;
  display: grid; place-content: center; justify-items: center;
  gap: 8px; padding: 30px; text-align: center;
  background: rgba(250, 247, 240, .95);
  backdrop-filter: blur(6px);
}
.player__error-title { font-family: var(--f-deva); font-size: 17px; color: var(--ivory); }
.player__error-sub { font-size: 12px; color: var(--muted-2); word-break: break-all; max-width: 460px; }
.player__error-actions { display: flex; gap: 10px; margin-top: 12px; flex-wrap: wrap; justify-content: center; }

/* ---------- lyrics / captions ------------------------------------------
   One whole line at a time, drawn by captions.js.

   NO PLATE. This is the one surface in the app that deliberately does not
   take --vid-glass, and the reason is that a caption is not chrome. The
   loop chip and the mantra dock are controls sitting *on* the picture, and
   a plate is what separates a control from what it floats over. A lyric is
   part of what is being watched — it belongs to the picture, not on top of
   it — and every player and lyric video worth copying treats it that way:
   the words themselves, and contrast bought with shadow rather than with
   a box. The first version here was a white rounded plate, and it read as
   a browser tooltip parked over the footage.

   Legibility without a box comes from two things stacked:
     • a soft dark HALO bound to the text — a wide radial wash with no edge
       anywhere, so it reads as atmosphere and not as a panel. It travels
       with the line and leaves with it.
     • a layered text-shadow: one tight shadow to cut the letterform away
       from whatever is behind it, two wide ones for depth.
   Together they hold up over a bright frame as well as this dark one.

   THE ANIMATION IS ON THE LINE, NEVER INSIDE IT. It arrives out of focus
   and slightly small, comes up, sharpens and settles as one object.
   Nothing staggers per word or per character: the material has no
   word-level timings, and moving parts of a Devanagari cluster
   independently breaks it exactly the way tracking does. Same rule as
   Typography, one step further.
   --------------------------------------------------------------------- */
.cues {
  position: absolute; z-index: 5;
  left: 0; right: 0; bottom: 52px;
  padding: 0 4%;
  /* One grid cell for every line, so the outgoing and the incoming one
     occupy the same place and genuinely cross instead of the second
     pushing the first out of the way. */
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: center; align-items: end;

  /* ONE KNOB FOR THE WHOLE THING.
     --cue-size is the type size at this breakpoint; --cue-scale is the
     multiplier you actually reach for, and it comes from `captions.scale`
     in config.js. Everything else about the line — its padding, and the
     halo that carries it — is stated in em or in %, so it is already
     measured in terms of the type. Halve the scale and the words, the
     breathing room and the wash all halve together: there is no second
     number to keep in step, and no way to end up with small text
     rattling around inside a box that stayed big. */
  --cue-size: clamp(23px, 2.15vw + 10px, 46px);
  --cue-scale: 1;

  /* The controls sit on top and stay pressable through this layer. */
  pointer-events: none;
  transition: transform .34s var(--e-out);
}
/* Lift clear of the control bar while it is out; take the room back the
   moment it hides. Transformed rather than re-positioned so it travels on
   the same curve, and at the same time, as the bar itself. */
.player:not(.is-idle) .cues { transform: translateY(-72px); }
.player.has-error .cues,
.cues.is-off { display: none; }

.cue {
  grid-area: 1 / 1;
  max-width: min(88%, 1000px);
  margin: 0;
  /* The padding is the halo's room. It is generous because the wash has to
     fade to nothing well before its own edge — a halo you can find the
     boundary of is just a box with soft corners. */
  padding: 0.7em 1.4em;
  text-align: center;
  text-wrap: balance;

  font-family: var(--f-deva-display);
  font-weight: 700;
  font-size: calc(var(--cue-size) * var(--cue-scale));
  line-height: 1.45;
  /* Not pure white. The whole app is lit by one gold, and a warm white
     belongs to it where a clinical one would sit outside it. */
  color: #fff9ee;

  background:
    radial-gradient(ellipse 70% 78% at 50% 52%,
      rgba(8, 5, 2, .62) 0%,
      rgba(8, 5, 2, .46) 42%,
      rgba(8, 5, 2, .18) 70%,
      rgba(8, 5, 2, 0)   100%);

  text-shadow:
    0 1px 2px  rgba(0, 0, 0, .62),   /* cuts the letterform out           */
    0 3px 14px rgba(0, 0, 0, .5),    /* depth                             */
    0 0 44px   rgba(0, 0, 0, .38);   /* holds up over a bright frame      */

  /* the rest state of a line that has not arrived yet */
  opacity: 0;
  transform: translateY(28px) scale(.92);
  filter: blur(11px);
  /* Expo-out. It leaves fast and lands slow, which is what makes a line
     feel like it settles rather than slides — the nearest thing a
     transition has to the spring Apple Music uses on the same gesture. */
  transition:
    opacity   .62s cubic-bezier(.16, 1, .3, 1),
    transform .62s cubic-bezier(.16, 1, .3, 1),
    filter    .52s cubic-bezier(.16, 1, .3, 1);
}

.cue.is-in {
  opacity: 1;
  transform: none;
  filter: blur(0);
  /* A gold bloom that arrives with the line and is gone a beat later, so
     the words look lit rather than printed. It is on its own delay because
     it should follow the landing, not race it. */
  animation: cueBloom 1.15s var(--e-out) both;
}

.cue.is-out {
  opacity: 0;
  transform: translateY(-16px) scale(.975);
  filter: blur(7px);
  /* Leaves faster than it arrives, so the incoming line is never read
     through the one it replaced. Keep in step with OUT_MS in captions.js. */
  transition-duration: .36s;
  animation: none;
}

@keyframes cueBloom {
  0%   { text-shadow: 0 1px 2px rgba(0,0,0,.62), 0 3px 14px rgba(0,0,0,.5),
                      0 0 44px rgba(0,0,0,.38), 0 0 0 rgba(232, 207, 133, 0); }
  38%  { text-shadow: 0 1px 2px rgba(0,0,0,.62), 0 3px 14px rgba(0,0,0,.5),
                      0 0 44px rgba(0,0,0,.38), 0 0 26px rgba(232, 207, 133, .34); }
  100% { text-shadow: 0 1px 2px rgba(0,0,0,.62), 0 3px 14px rgba(0,0,0,.5),
                      0 0 44px rgba(0,0,0,.38), 0 0 14px rgba(232, 207, 133, .1); }
}

/* Latin sets tighter than Devanagari and, unlike it, can take tracking. */
body.lang-en .cue {
  font-family: var(--f-serif);
  font-weight: 400;
  letter-spacing: .015em;
  line-height: 1.35;
}

/* The CC button reads lit while captions are on, the way loop does. */
.iconbtn--cc.is-on { color: var(--gold-ink); }

/* ---------- control bar ------------------------------------------------ */
.controls {
  position: absolute; z-index: 6;
  left: 0; right: 0; bottom: 0;
  padding: 46px 14px 12px;
  display: grid; gap: 6px;
  /* The single column is capped at the container rather than left to size
     itself. Without this a control row that is one button too wide for the
     screen widens the whole grid to its own max-content, and the scrub bar
     — the other row — is stretched along with it and runs off the frame. */
  grid-template-columns: minmax(0, 1fr);
  /* The controls need a ground of their own whatever the footage is doing
     underneath. It used to be a black wash with light icons; it is the
     same wash in paper, with ink icons, so the player belongs to the same
     page as everything around it. */
  background:
    linear-gradient(to top, rgba(250, 247, 240, .97) 8%, rgba(250, 247, 240, .74) 48%, transparent 100%);
  transition: opacity .34s var(--e-out), transform .34s var(--e-out);
}
.player.is-idle .controls { opacity: 0; transform: translateY(10px); pointer-events: none; }
.player.is-idle .player__tap { cursor: none; }
.player.has-error .controls { opacity: 0; pointer-events: none; }

.controls__row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: nowrap;
}
.controls__group { display: flex; align-items: center; gap: 2px; min-width: 0; }
.controls__group--end { gap: 1px; }

/* ---------- icon buttons + tooltips ------------------------------------- */
.iconbtn {
  position: relative;
  display: grid; place-items: center;
  width: 38px; height: 38px;
  border-radius: 50%;
  color: var(--ivory-2);
  transition: color .22s, background .22s, transform .22s var(--e-out);
}
.iconbtn:hover { color: var(--ivory); background: var(--fill-3); }
.iconbtn:active { transform: scale(.92); }

.iconbtn--primary { width: 46px; height: 46px; color: var(--ivory); }
.iconbtn--primary .ico { width: 25px; height: 25px; }
.iconbtn--primary:hover { background: rgba(201, 162, 39, .2); }

.iconbtn--ghost { width: 36px; height: 36px; color: var(--muted); }
.iconbtn--ghost:hover { color: var(--ivory); }
.iconbtn--ghost.is-on { color: var(--gold-ink); }

.iconbtn--tiny { width: 28px; height: 28px; color: var(--muted); }
.iconbtn--tiny .ico { width: 16px; height: 16px; }

/* toggle-on state */
.iconbtn.is-on { color: var(--gold-ink); }
.iconbtn.is-on::after {
  content: '';
  position: absolute; bottom: 4px; left: 50%; translate: -50% 0;
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 8px var(--gold-glow);
}
.iconbtn.has-preset { color: rgba(138, 106, 13, .6); }

.speedbtn__text {
  font-size: 12px; font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
}

/* tooltip */
[data-tip]::before {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 9px); left: 50%;
  translate: -50% 0;
  padding: 5px 10px;
  border-radius: 6px;
  background: rgba(250, 250, 248, .98);
  border: 1px solid var(--line);
  box-shadow: 0 6px 18px rgba(52, 40, 10, .2);
  color: var(--ivory-2);
  font-family: var(--f-deva);
  font-size: 11px; line-height: 1.3;
  white-space: nowrap;
  opacity: 0; pointer-events: none;
  transition: opacity .2s var(--e-out), translate .2s var(--e-out);
  translate: -50% 4px;
  z-index: 40;
}
[data-tip]:hover::before,
[data-tip]:focus-visible::before { opacity: 1; translate: -50% 0; }
/* Anything living along the top of the page has no room above it, which is
   where a tooltip goes by default — so theirs drop below instead. The
   panel header's does too, because .sidepanel__card clips its overflow and
   a tip above the minimise button would be cut off entirely. */
.topbar [data-tip]::before,
.landing__tools [data-tip]::before,
.sidepanel__head [data-tip]::before { bottom: auto; top: calc(100% + 8px); }

/* At the page edges a centred tip runs off the side, so it hangs from the
   corner it is nearest instead. */
.landing__tools--l [data-tip]::before { left: 0; translate: 0 4px; }
.landing__tools--r [data-tip]::before { left: auto; right: 0; translate: 0 4px; }
.sidepanel__head [data-tip]::before   { left: auto; right: 0; translate: 0 4px; }
.landing__tools--l [data-tip]:hover::before,
.landing__tools--l [data-tip]:focus-visible::before,
.landing__tools--r [data-tip]:hover::before,
.landing__tools--r [data-tip]:focus-visible::before,
.sidepanel__head [data-tip]:hover::before,
.sidepanel__head [data-tip]:focus-visible::before { translate: 0 0; }

/* ---------- scrub bar --------------------------------------------------- */
.controls__scrub { padding: 0 4px; }

.scrub {
  position: relative;
  height: 20px;
  display: flex; align-items: center;
  cursor: pointer;
  touch-action: none;
}
.scrub__rail {
  position: relative;
  width: 100%; height: 4px;
  border-radius: 99px;
  background: rgba(40, 31, 10, .2);
  overflow: visible;
  transition: height .2s var(--e-out);
}
.scrub:hover .scrub__rail,
.scrub.is-active .scrub__rail,
.scrub:focus-visible .scrub__rail { height: 6px; }

.scrub__buffer, .scrub__played {
  position: absolute; inset: 0;
  border-radius: 99px;
  transform-origin: left center;
  transform: scaleX(0);
}
.scrub__buffer { background: rgba(40, 31, 10, .18); }
.scrub__played { background: linear-gradient(90deg, var(--gold-deep), var(--gold)); }

/* custom-loop band on the timeline */
.scrub__loop {
  position: absolute; top: -3px; bottom: -3px;
  border-radius: 3px;
  background: rgba(201, 162, 39, .26);
  border-left: 2px solid var(--gold-lite);
  border-right: 2px solid var(--gold-lite);
  pointer-events: none;
}

.scrub__knob {
  position: absolute; top: 50%;
  width: 13px; height: 13px;
  translate: -50% -50%;
  border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 0 3px rgba(201, 162, 39, .3), 0 2px 6px rgba(52, 40, 10, .35);
  opacity: 0;
  transition: opacity .2s var(--e-out), scale .2s var(--e-out);
  pointer-events: none;
}
.scrub:hover .scrub__knob,
.scrub.is-active .scrub__knob,
.scrub:focus-visible .scrub__knob { opacity: 1; }
.scrub.is-active .scrub__knob { scale: 1.15; }

.scrub__hover {
  position: absolute; bottom: 22px;
  translate: -50% 0;
  padding: 3px 8px;
  border-radius: 5px;
  background: var(--vid-glass);
  border: 1px solid var(--line);
  box-shadow: 0 4px 12px rgba(52, 40, 10, .2);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--ivory-2);
  pointer-events: none;
}

/* ---------- volume + timecode -------------------------------------------- */
.volume { display: flex; align-items: center; }
.volume .slider--inline {
  width: 0; opacity: 0;
  transition: width .32s var(--e-out), opacity .25s, margin .32s var(--e-out);
}
.volume:hover .slider--inline,
.volume:focus-within .slider--inline { width: 78px; opacity: 1; margin: 0 8px 0 2px; }

.timecode {
  display: flex; align-items: center; gap: 5px;
  margin-left: 8px;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  color: var(--ivory-2);
  letter-spacing: .02em;
  white-space: nowrap;
}
.timecode__sep { color: var(--muted-2); }

/* ---------- range slider -------------------------------------------------- */
.slider {
  --fill: 100%;
  -webkit-appearance: none; appearance: none;
  height: 4px; border-radius: 99px;
  background: linear-gradient(90deg, var(--gold-ink) var(--fill), var(--slider-track) var(--fill));
  cursor: pointer;
}
.slider--vol { flex: 1; min-width: 0; }
.slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--gold-ink);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .45);
  cursor: pointer;
}
.slider::-moz-range-thumb {
  width: 12px; height: 12px; border: 0; border-radius: 50%;
  background: var(--gold-ink);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .45);
  cursor: pointer;
}

/* ---------- popovers ------------------------------------------------------- */
.abpanel, .menu {
  position: absolute; z-index: 20;
  right: 14px; bottom: 78px;
  background: rgba(250, 250, 248, .98);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: 0 18px 44px rgba(52, 40, 10, .22);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  opacity: 0;
  transform: translateY(8px) scale(.985);
  transform-origin: bottom right;
  transition: opacity .2s var(--e-out), transform .22s var(--e-out);
}
.abpanel.is-open, .menu.is-open { opacity: 1; transform: none; }

.abpanel { width: min(330px, calc(100% - 28px)); padding: 16px 16px 14px; }

.abpanel__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.abpanel__title {
  font-family: var(--f-deva);
  font-size: 14.5px; font-weight: 500;
  letter-spacing: .04em;
  color: var(--gold-ink);
}

.abpanel__grid {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: end; gap: 10px;
}
.abpanel__arrow { color: var(--muted-2); padding-bottom: 9px; font-size: 14px; }

.field { display: grid; gap: 6px; min-width: 0; }
.field__label {
  font-family: var(--f-deva);
  font-size: 11px; letter-spacing: .1em;
  color: var(--muted);
}
.field__input {
  width: 100%;
  padding: 9px 11px;
  border-radius: var(--r-sm);
  background: var(--ink-750);
  border: 1px solid var(--line);
  color: var(--ivory);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  letter-spacing: .05em;
  text-align: center;
  transition: border-color .22s, background .22s;
}
.field__input:focus { border-color: rgba(201, 162, 39, .6); background: var(--ink-700); }

.abpanel__quick { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.chip {
  padding: 5px 10px;
  border-radius: 99px;
  font-family: var(--f-deva);
  font-size: 11px;
  color: var(--muted);
  background: var(--ink-750);
  border: 1px solid var(--line);
  transition: color .22s, border-color .22s, background .22s;
}
.chip:hover { color: var(--gold-ink); border-color: rgba(201, 162, 39, .38); background: var(--ink-700); }

.abpanel__msg {
  min-height: 16px; margin-top: 10px;
  font-family: var(--f-deva);
  font-size: 11.5px; color: var(--muted-2);
}
.abpanel__msg.is-error { color: #b0472a; }

.abpanel__actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 6px; }

.btn {
  padding: 8px 16px;
  border-radius: var(--r-sm);
  font-family: var(--f-deva);
  font-size: 12.5px;
  color: var(--ivory-2);
  background: var(--ink-700);
  border: 1px solid var(--line);
  transition: background .22s, color .22s, border-color .22s, box-shadow .22s;
}
.btn:hover { background: var(--ink-600); color: var(--ivory); }
.btn--gold {
  background: linear-gradient(160deg, #e2c469, var(--gold) 65%, #a9821c);
  border-color: rgba(232, 207, 133, .5);
  color: var(--on-gold);
  font-weight: 500;
}
/* `.btn:hover` outranks `.btn--gold` (0,2,0 vs 0,1,0), so it would repaint a
   gold button with the plain dark background and leave the dark-brown label
   unreadable. The gradient has to be restated here, not just brightened. */
.btn--gold:hover {
  background: linear-gradient(160deg, #f0d98d, #dcb531 65%, #bd9220);
  border-color: rgba(232, 207, 133, .75);
  color: #241a06;
  box-shadow: 0 0 18px rgba(201, 162, 39, .28);
}
.btn--gold:active { filter: brightness(.96); }

/* speed menu */
.menu { padding: 6px; min-width: 132px; display: grid; gap: 1px; }
.menu__item {
  padding: 8px 12px;
  border-radius: var(--r-sm);
  text-align: left;
  font-size: 12.5px;
  color: var(--ivory-2);
  transition: background .18s, color .18s;
}
.menu__item:hover { background: var(--ink-700); color: var(--ivory); }
.menu__item[aria-checked="true"] { color: var(--gold-ink); }
.menu__item[aria-checked="true"]::after { content: '·'; float: right; }

/* The lyrics menu carries two things — a switch and a size — so unlike the
   speed menu it needs to say which is which. */
.menu--cc { min-width: 176px; }
.menu__label {
  margin: 8px 0 2px;
  padding: 0 12px;
  font-size: 10px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--muted-2);
}
.menu__sep { height: 1px; margin: 6px 4px 2px; background: var(--line-2); }
/* The switch reads as a switch: its state is a word, not a dot. */
.menu__item--switch { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.menu__state { font-size: 11.5px; color: var(--muted-2); }
.menu__item--switch[aria-checked="true"] .menu__state { color: var(--gold-ink); }
.menu__item--switch[aria-checked="true"]::after { content: none; }



/* =====================================================================
 * 7. VIDEO META
 * ===================================================================== */
.meta { display: grid; gap: 10px; padding: 0 2px; }

.meta__eyebrow {
  display: flex; align-items: center; gap: 10px;
  font-size: 11px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--muted-2);
  font-variant-numeric: tabular-nums;
}
.meta__cat {
  font-family: var(--f-deva);
  letter-spacing: .12em;
  color: var(--gold-ink);
  text-transform: none;
}
.meta__cat::before { content: '—'; margin-right: 10px; color: var(--muted-2); }

.meta__title {
  font-family: var(--f-deva-display);
  font-size: clamp(21px, 2.7vw, 30px);
  font-weight: 600;
  line-height: 1.28;
  color: var(--ivory);
}
.meta__title-en {
  font-family: var(--f-serif);
  font-size: 14px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: -4px;
}
.meta__desc {
  font-family: var(--f-deva);
  font-size: 14px;
  line-height: 1.75;
  color: var(--ivory-2);
  opacity: .8;
  max-width: 68ch;
}

.meta__tags { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 2px; }
.tag {
  padding: 4px 11px;
  border-radius: 99px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  letter-spacing: .04em;
  color: var(--muted);
  background: var(--ink-800);
  border: 1px solid var(--line-2);
}
.tag--loop {
  font-family: var(--f-deva);
  color: var(--gold-ink);
  border-color: rgba(201, 162, 39, .34);
  background: rgba(201, 162, 39, .10);
}

.upnext {
  display: flex; align-items: center; gap: 10px;
  margin-top: 4px; padding-top: 14px;
  border-top: 1px solid var(--line-2);
}
.upnext__label {
  font-family: var(--f-deva);
  font-size: 11px; letter-spacing: .18em;
  color: var(--muted-2);
}
.upnext__btn {
  font-family: var(--f-deva);
  font-size: 13.5px;
  color: var(--ivory-2);
  border-bottom: 1px solid transparent;
  transition: color .22s, border-color .22s;
}
.upnext__btn:hover { color: var(--gold-ink); border-color: rgba(201, 162, 39, .5); }


/* ---------- save for offline -------------------------------------------
 * One button, three states. The progress bar is the button's own fill
 * rather than a separate track: there is only one thing happening, and it
 * is happening to this button.
 * ---------------------------------------------------------------------- */
.dlbtn {
  position: relative;
  overflow: hidden;
  justify-self: start;
  display: inline-flex; align-items: center; gap: 8px;
  margin-top: 4px;
  padding: 8px 16px 8px 13px;
  border-radius: 99px;
  font-family: var(--f-deva);
  font-size: 12.5px;
  color: var(--gold-ink);
  background: rgba(201, 162, 39, .1);
  border: 1px solid rgba(201, 162, 39, .42);
  transition: color .2s, background .22s, border-color .22s, transform .18s var(--e-out);
}
.dlbtn:hover {
  background: rgba(201, 162, 39, .2);
  border-color: rgba(201, 162, 39, .7);
}
.dlbtn:active { transform: scale(.97); }

/* the fill is the progress */
.dlbtn::before {
  content: '';
  position: absolute; inset: 0 auto 0 0;
  width: 0;
  background: rgba(201, 162, 39, .3);
  transition: width .3s linear;
}
.dlbtn.is-busy::before { width: var(--p, 0%); }
.dlbtn > * { position: relative; z-index: 1; }

.dlbtn.is-saved {
  color: var(--on-gold);
  background: linear-gradient(160deg, #e8cf85, var(--gold));
  border-color: rgba(232, 207, 133, .75);
}

body.lang-en .dlbtn { font-family: var(--f-sans); }

/* A saved row says so, so the list can be read for what will play with no
   network without having to open each one. */
.row.is-saved .row__thumb::before {
  content: '';
  position: absolute; z-index: 2;
  top: 5px; left: 5px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 0 2px rgba(4, 4, 6, .5);
}

/* =====================================================================
 * 8. PLAYLIST
 * ===================================================================== */
.listhead {
  padding: 18px 16px 14px;
  border-bottom: 1px solid var(--line-2);
  display: grid; gap: 13px;
  background: linear-gradient(180deg, var(--ink-800), var(--paper));
}
/* Title, then count, then the pencil — a row, not three things pushed to
   the corners. `space-between` used to strand the count in the middle of
   the header with air on both sides; letting the title take the slack
   instead keeps the count and the button together at the right, where
   they belong to each other. */
.listhead__top { display: flex; align-items: center; gap: 9px; }
.listhead__title {
  flex: 1;
  min-width: 0;
  font-family: var(--f-deva-display);
  font-size: 19px; font-weight: 700;
  color: var(--ivory);
  position: relative;
  padding-left: 13px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.listhead__title::before {
  content: '';
  position: absolute; left: 0; top: 50%;
  translate: 0 -50%;
  width: 5px; height: 5px;
  background: var(--gold);
  rotate: 45deg;
  box-shadow: 0 0 9px var(--gold-glow);
}
/* A counted badge rather than loose grey text: it sits beside a heading
   and a button, and needed an edge of its own to hold its ground. */
.listhead__count {
  flex: none;
  padding: 3.5px 10px;
  border-radius: 99px;
  font-family: var(--f-sans);
  font-size: 10.5px; font-weight: 600;
  letter-spacing: .05em;
  color: var(--muted);
  background: var(--fill-1);
  border: 1px solid var(--line-2);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.listsearch {
  display: flex; align-items: center; gap: 9px;
  padding: 10px 13px;
  border-radius: 10px;
  background: var(--fill-1);
  border: 1px solid var(--line);
  color: var(--muted-2);
  transition: border-color .22s, background .22s;
}
.listsearch:focus-within {
  border-color: rgba(201, 162, 39, .5);
  background: rgba(201, 162, 39, .05);
}
.listsearch__input {
  flex: 1; min-width: 0;
  border: 0; background: none;
  font-family: var(--f-deva);
  font-size: 13.5px; color: var(--ivory);
}
.listsearch__input::placeholder { color: var(--muted-2); }
/* The native glyph is drawn for the platform scheme; on paper it needs no
   inversion, only enough dimming to sit below the text it clears. */
.listsearch__input::-webkit-search-cancel-button { opacity: .45; }

/* The bar treatment drops the plate: inside the header there is already
   one, and a second would read as a button that is somehow raised. */
.langbtn--bar { box-shadow: none; }

/* the chip strip scrolls sideways; fade the right edge so a cut-off chip
   reads as "more here" rather than as a broken layout */
.filters {
  display: flex; gap: 6px;
  overflow-x: auto;
  padding-bottom: 2px;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 28px), transparent 100%);
          mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 28px), transparent 100%);
}
.filters::-webkit-scrollbar { display: none; }
.filter {
  flex: none;
  padding: 6px 13px;
  border-radius: 99px;
  font-family: var(--f-deva);
  font-size: 12.5px; font-weight: 500;
  color: var(--muted);
  background: var(--fill-1);
  border: 1px solid transparent;
  white-space: nowrap;
  transition: color .22s, background .22s, border-color .22s;
}
.filter:hover { color: var(--ivory-2); background: var(--fill-2); }
.filter.is-on {
  color: #1d1503;
  background: linear-gradient(160deg, #e8cf85, var(--gold));
  border-color: rgba(232, 207, 133, .6);
  box-shadow: 0 2px 12px rgba(201, 162, 39, .28);
}

.list {
  overflow-y: auto;
  padding: 10px 10px 14px;
  display: grid; gap: 4px;
  align-content: start;
  scroll-padding: 12px;
}

.row__btn {
  position: relative;
  width: 100%;
  display: grid;
  grid-template-columns: 22px 116px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  padding: 9px 11px 9px 8px;
  border-radius: 13px;
  text-align: left;
  border: 1px solid transparent;
  transition: background .24s var(--e-out), border-color .24s, transform .24s var(--e-out);
}
.row__btn:hover {
  background: var(--fill-1);
  border-color: var(--line-2);
}
.row__btn:active { transform: scale(.995); }

.row.is-active .row__btn {
  background:
    linear-gradient(100deg, rgba(201, 162, 39, .22) 0%, rgba(201, 162, 39, .07) 55%, transparent 100%);
  border-color: rgba(201, 162, 39, .28);
}
.row.is-active .row__btn::before {
  content: '';
  position: absolute; left: -1px; top: 16%; bottom: 16%;
  width: 3px; border-radius: 99px;
  background: linear-gradient(180deg, var(--gold-lite), var(--gold));
  box-shadow: 0 0 12px var(--gold-glow);
}

.row__num {
  position: relative;
  display: grid; place-items: center;
  font-family: var(--f-sans);
  font-size: 12px; font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--muted-2);
  transition: color .22s;
}
.row__btn:hover .row__num { color: var(--muted); }
.row.is-active .row__num { color: var(--gold-ink); }
.row.is-active.is-playing .row__num-text { opacity: 0; }

/* now-playing equaliser */
.row__eq {
  position: absolute; inset: 0;
  display: none; align-items: center; justify-content: center;
  gap: 2px;
}
.row.is-active.is-playing .row__eq { display: flex; }
.row__eq i {
  width: 2px; height: 4px;
  background: var(--gold);
  border-radius: 2px;
  animation: vizBar 1s var(--e-io) infinite;
}
.row__eq i:nth-child(2) { animation-delay: .2s; height: 10px; }
.row__eq i:nth-child(3) { animation-delay: .4s; height: 6px; }

.row__thumb {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: 9px;
  overflow: hidden;
  background: var(--ink-700);
  box-shadow: 0 2px 8px rgba(52, 40, 10, .16), inset 0 0 0 1px var(--line);
}
.row__thumb img {
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity .45s var(--e-out), transform .5s var(--e-out);
}
.row__thumb.is-loaded img { opacity: 1; }
.row__btn:hover .row__thumb img { transform: scale(1.06); }

/* graceful fallback if a poster is missing */
.row__thumb.is-fallback::after {
  content: '';
  position: absolute; inset: 0;
  background:
    radial-gradient(circle at 50% 50%, rgba(201, 162, 39, .28) 0 1.5px, transparent 2px),
    linear-gradient(150deg, var(--ink-700), var(--ink-850));
}
.row.is-active .row__thumb {
  box-shadow: 0 2px 10px rgba(52, 40, 10, .20), inset 0 0 0 1.5px rgba(201, 162, 39, .75);
}

.row__dur {
  position: absolute; right: 5px; bottom: 5px;
  padding: 2px 6px;
  border-radius: 5px;
  background: rgba(4, 4, 6, .86);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  font-family: var(--f-sans);
  font-size: 10px; font-weight: 500;
  font-variant-numeric: tabular-nums;
  /* Sits on the poster frame, not on the panel — stays light on its plate. */
  color: #efe9dd;
  letter-spacing: .02em;
}

.row__body { min-width: 0; display: grid; gap: 5px; align-content: center; }
.row__title {
  font-family: var(--f-deva);
  font-size: 14.5px;
  font-weight: 500;
  line-height: 1.45;      /* headroom for matras inside the 2-line clamp */
  color: var(--ivory-2);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
  transition: color .22s;
}
.row.is-active .row__title { color: var(--gold-ink); }
.row__btn:hover .row__title { color: var(--ivory); }

/* one meta line keeps every row the same height whether or not it has a badge */
.row__meta { display: flex; align-items: center; gap: 7px; min-width: 0; }
.row__sub {
  font-family: var(--f-sans);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--muted-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.row__badge {
  flex: none;
  padding: 1.5px 8px;
  border-radius: 99px;
  font-family: var(--f-sans);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--gold-ink);
  background: rgba(201, 162, 39, .15);
  border: 1px solid rgba(201, 162, 39, .34);
}

.list__empty {
  padding: 34px 16px;
  text-align: center;
  font-family: var(--f-deva);
  font-size: 13.5px;
  color: var(--muted-2);
}


/* ---------- editing the sequence ---------------------------------------
 * config.js says what the videos are; this is one visitor's arrangement of
 * them, kept in their own browser. The controls are built into every row
 * and revealed by .list.is-editing rather than added on demand, so turning
 * editing on does not reflow the list under the pointer.
 * ---------------------------------------------------------------------- */
/* Deliberately the same object as the handles on the landing — gold ring,
   gold ink, filling in when it is on. It does the same kind of job, so it
   should not have to be learnt twice. */
.listhead__edit {
  flex: none;
  display: grid; place-items: center;
  width: 30px; height: 30px;
  border-radius: 50%;
  color: var(--gold-ink);
  background: rgba(201, 162, 39, .1);
  border: 1px solid rgba(201, 162, 39, .55);
  transition: color .22s, background .24s, border-color .24s, box-shadow .24s,
              transform .2s var(--e-out);
}
.listhead__edit:hover {
  background: rgba(201, 162, 39, .22);
  border-color: rgba(201, 162, 39, .8);
}
.listhead__edit:active { transform: scale(.92); }
.listhead__edit.is-on {
  color: var(--on-gold);
  background: linear-gradient(160deg, #e8cf85, var(--gold));
  border-color: rgba(232, 207, 133, .75);
  box-shadow: 0 2px 10px rgba(201, 162, 39, .32);
}

.listhead__input {
  flex: 1; min-width: 0;
  padding: 5px 11px;
  border-radius: var(--r-sm);
  font-family: var(--f-deva-display);
  font-size: 17px; font-weight: 700;
  color: var(--ivory);
  background: var(--paper);
  border: 1px solid rgba(201, 162, 39, .45);
  transition: border-color .22s;
}
.listhead__input:focus { border-color: rgba(201, 162, 39, .8); }
.listhead__input::placeholder { color: var(--muted-2); font-weight: 400; }

/* The quiet form of the note above — same words, no card, no animation,
   just there. Marked with the same small gold lozenge the headings use so
   it reads as part of the panel rather than as leftover text. */
.listhead__hint {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-family: var(--f-deva);
  font-size: 11px;
  line-height: 1.55;
  color: var(--muted-2);
}
.listhead__hint::before {
  content: '';
  flex: none;
  width: 5px; height: 5px;
  margin-top: .42em;
  background: var(--gold);
  rotate: 45deg;
  opacity: .75;
}
body.lang-en .listhead__hint { font-family: var(--f-sans); }

.listhead__reset { display: none; }
.listhead.is-editing .listhead__reset {
  display: inline-block;
  justify-self: start;
  padding: 5px 12px;
  border-radius: 99px;
  font-family: var(--f-deva);
  font-size: 11.5px;
  color: var(--gold-ink);
  background: rgba(201, 162, 39, .1);
  border: 1px solid rgba(201, 162, 39, .35);
  transition: background .22s, border-color .22s;
}
.listhead.is-editing .listhead__reset:hover {
  background: rgba(201, 162, 39, .2);
  border-color: rgba(201, 162, 39, .6);
}

/* the row makes room for its controls only while they are shown */
.row { position: relative; display: flex; align-items: center; gap: 3px; }
.row__btn { flex: 1; min-width: 0; }

.row__tools {
  display: none;
  grid-template-columns: auto auto;
  gap: 2px;
  padding-right: 4px;
  align-items: center;
}
.list.is-editing .row__tools { display: grid; }
.list.is-editing .row__btn { grid-template-columns: 22px 92px minmax(0, 1fr); }

.row__tool {
  display: grid; place-items: center;
  width: 25px; height: 25px;
  border-radius: 7px;
  color: var(--muted);
  background: var(--fill-1);
  transition: color .18s, background .18s;
}
.row__tool:hover { color: var(--gold-ink); background: rgba(201, 162, 39, .18); }
.row__tool[data-act="up"]   { grid-area: 1 / 1; }
.row__tool[data-act="down"] { grid-area: 2 / 1; }
.row__tool--del             { grid-area: 1 / 2 / 3 / 3; height: 52px; border-radius: 9px; }
.row__tool--del:hover       { color: #b0472a; background: rgba(176, 71, 42, .12); }

/* editing is a state of the whole panel, so the panel says so */
.listhead.is-editing {
  background: linear-gradient(180deg, rgba(201, 162, 39, .09), var(--paper));
}

/* ---------- dragging a row ---------------------------------------------
 * The whole row is the handle while editing; a drag only begins on
 * movement, so a plain click still plays the video underneath.
 * ---------------------------------------------------------------------- */
.list.is-editing .row { cursor: grab; }
.list.is-editing .row:active { cursor: grabbing; }
.row.is-dragging { opacity: .35; }

/* where it would land, drawn on the row it is over */
.row.is-drop-before::after,
.row.is-drop-after::after {
  content: '';
  position: absolute;
  left: 6px; right: 6px;
  height: 2.5px;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--gold-lite), var(--gold));
  box-shadow: 0 0 8px var(--gold-glow);
}
.row.is-drop-before::after { top: -3px; }
.row.is-drop-after::after  { bottom: -3px; }

/* =====================================================================
 * 8b. SIDE PANELS
 * ---------------------------------------------------------------------
 * Two cards flanking the landing screen — purpose on the left,
 * preparation on the right — inset --edge from the sides and held
 * clear of the mantra dock and the chakra CTA below. Each folds into a
 * round handle at the top-left and grows back out of it.
 *
 * They exist on the landing and nowhere else: pressing the chakra is
 * what says the preamble is done with, so the Poojan view never carries
 * them, and a share link never sees them at all.
 * ===================================================================== */
.sidepanel {
  position: fixed;
  z-index: 40;
  /* Clear of the handles and of the top-right cluster. */
  top: var(--edge-top);
  width: var(--panel-w);
  display: grid;
  pointer-events: none;         /* nothing to catch while it is folding */
}

/* The purpose panel is the preamble, and the preamble is over once the
   chakra is pressed. The preparation panel is not — it answers a question
   that can come up mid-Poojan, so it stays reachable from the header there
   and only its landing handle goes away. */
body.is-poojan .sidepanel--l { display: none !important; }

/* Both run the full length. Two things used to stop them short — the
   chakra in the bottom-right corner and the mantra dock in the
   bottom-left — and neither is down there any more: the chakra rises from
   the middle, and the mantra control moved up into the top-right cluster. */
.sidepanel--l, .sidepanel--r { bottom: var(--edge); }
.sidepanel--l { left: var(--edge); }
.sidepanel--r { right: var(--edge); }
.sidepanel.is-on { pointer-events: auto; }

.sidepanel__card {
  position: relative;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  min-height: 0;
  border-radius: var(--r-lg);
  /* The scroll area can end flush with the rounded edge; without this a
     last line rides out over the border instead of being scrolled to. */
  overflow: hidden;
  border: 1px solid rgba(201, 162, 39, .28);
  background:
    radial-gradient(130% 55% at 50% 0%, rgba(201, 162, 39, .09), transparent 58%),
    linear-gradient(168deg, var(--ink-850), var(--ink-900));
  /* Heavier than the page shadow: this card floats over moving footage,
     and needs its own edge to sit on. */
  box-shadow: 0 24px 60px rgba(24, 18, 4, .3), 0 0 0 1px rgba(255, 255, 255, .9) inset;

  /* Folded state — the card collapses *onto its own handle*.
     Origin at the corner nearest that handle, then translated the exact
     distance from that corner to the button's centre and scaled almost to
     nothing, so the card is visibly travelling into the button rather than
     vanishing where it stood. The fade is held back a moment so the
     journey is seen before the card is gone. */
  opacity: 0;
  transform:
    translate(calc(var(--tool-h) / 2),
              calc(var(--handle-top) + var(--tool-h) / 2 - var(--edge-top)))
    scale(.04);
  transform-origin: top left;
  transition:
    opacity .26s var(--e-out) .13s,
    transform .44s var(--e-io);
}
.sidepanel--r .sidepanel__card {
  transform:
    translate(calc(var(--tool-h) / -2),
              calc(var(--handle-top) + var(--tool-h) / 2 - var(--edge-top)))
    scale(.04);
  transform-origin: top right;
}
/* Opening runs the other way, so it gets its own timing: the card appears
   at once and grows out of the button, with no held-back fade. */
.sidepanel.is-on .sidepanel__card {
  opacity: 1;
  transform: none;
  transition:
    opacity .28s var(--e-out),
    transform .46s var(--e-out);
}

/* gold brackets at the four corners — the same frame the card always had */
.sidepanel__corner {
  position: absolute; z-index: 2;
  width: 16px; height: 16px;
  border: 1px solid var(--gold);
  opacity: .8;
  pointer-events: none;
}
.sidepanel__corner--tl { top: 9px; left: 9px;  border-right: 0; border-bottom: 0; border-top-left-radius: 6px; }
.sidepanel__corner--tr { top: 9px; right: 9px; border-left: 0;  border-bottom: 0; border-top-right-radius: 6px; }
.sidepanel__corner--bl { bottom: 9px; left: 9px;  border-right: 0; border-top: 0; border-bottom-left-radius: 6px; }
.sidepanel__corner--br { bottom: 9px; right: 9px; border-left: 0;  border-top: 0; border-bottom-right-radius: 6px; }

/* ---------- head ------------------------------------------------------ */
.sidepanel__head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 17px 13px 14px 20px;
  border-bottom: 1px solid var(--line-2);
}

.sidepanel__mark {
  display: grid; place-items: center;
  width: 38px; height: 38px;
  flex: none;
  border-radius: 50%;
  color: var(--gold-ink);
  background: rgba(201, 162, 39, .12);
  border: 1px solid rgba(201, 162, 39, .34);
}
.sidepanel__mark .ico { width: 20px; height: 20px; }

.sidepanel__heading { min-width: 0; }

.sidepanel__kicker {
  font-family: var(--f-deva);
  font-size: 10.5px;
  color: var(--gold-ink);
  opacity: .9;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.sidepanel__title {
  font-family: var(--f-deva-display);
  font-weight: 700;
  font-size: 19px;
  line-height: 1.38;
  background: linear-gradient(180deg, #b8901f, #8a6a0d 52%, #6b5008);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* The way out has to be findable at a glance, so it carries the gold
   rather than sitting in the header as a grey hairline. */
.sidepanel__min {
  width: 32px; height: 32px;
  border-radius: 50%;
  color: var(--gold-ink);
  background: rgba(201, 162, 39, .12);
  border: 1px solid rgba(201, 162, 39, .38);
  transition: color .22s, background .24s, border-color .24s, transform .2s var(--e-out);
}
.sidepanel__min:hover {
  color: var(--on-gold);
  background: linear-gradient(160deg, #e8cf85, var(--gold));
  border-color: rgba(232, 207, 133, .75);
}
.sidepanel__min:active { transform: scale(.92); }

/* ---------- body ------------------------------------------------------ */
.sidepanel__scroll {
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;      /* the page behind it stays put */
  padding: 2px 20px 22px;
}

.sidepanel__rule {
  display: flex; align-items: center; justify-content: center;
  gap: 12px; margin: 18px auto 16px; max-width: 200px;
}
.sidepanel__rule span {
  height: 1px; flex: 1;
  background: linear-gradient(90deg, transparent, rgba(201, 162, 39, .55), transparent);
}
.sidepanel__rule i {
  width: 5px; height: 5px; flex: none;
  background: var(--gold); transform: rotate(45deg);
  box-shadow: 0 0 10px var(--gold-glow);
}

/* Ranged left, unlike the old full-width card: centred prose in a 340px
   column gives a ragged left edge the eye has to hunt for on every line.
   Devanagari keeps the extra leading — matras sit well above the baseline. */
.sidepanel__text {
  font-family: var(--f-deva);
  font-size: 14px;
  line-height: 1.95;
  color: var(--ivory-2);
  text-wrap: pretty;
}
.sidepanel__text p + p { margin-top: 13px; }


.sidepanel__steps { display: grid; gap: 9px; margin-top: 16px; }
.sidepanel__steps li {
  position: relative;
  padding-left: 19px;
  font-family: var(--f-deva);
  font-size: 13px;
  line-height: 1.72;
  color: var(--ivory-2);
}
.sidepanel__steps li::before {
  content: '';
  position: absolute; left: 3px; top: .72em;
  width: 5px; height: 5px;
  background: var(--gold);
  rotate: 45deg;
}

.sidepanel__foot {
  margin-top: 18px;
  padding-top: 12px;
  border-top: 1px solid var(--line-2);
  font-family: var(--f-deva);
  font-size: 11px;
  color: var(--muted-2);
}

/* ---------- preparation sections ---------------------------------------
 * One block per page of the source deck: what it is, what to gather, and
 * the part of the Poojan it belongs to. The button is the point of it —
 * reading that you need a kalash is one thing, watching it be filled is
 * another, so every section can hand you straight to its video.
 * ---------------------------------------------------------------------- */
.sidepanel__sections { display: grid; gap: 14px; margin-top: 18px; }

.prep {
  padding: 14px 14px 12px;
  border-radius: var(--r-md);
  background: var(--fill-1);
  border: 1px solid var(--line-2);
}

.prep__head {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 10px;
}
.prep__mark {
  flex: none;
  display: grid; place-items: center;
  width: 30px; height: 30px;
  border-radius: 50%;
  color: var(--gold-ink);
  background: rgba(201, 162, 39, .12);
  border: 1px solid rgba(201, 162, 39, .38);
}
.prep__mark .ico { width: 17px; height: 17px; }
.prep__title {
  font-family: var(--f-deva-display);
  font-size: 14.5px; font-weight: 700;
  line-height: 1.35;
  color: var(--ivory);
}

.prep__items { display: grid; gap: 7px; }
.prep__items li {
  position: relative;
  padding-left: 16px;
  font-family: var(--f-deva);
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--ivory-2);
}
.prep__items li::before {
  content: '';
  position: absolute; left: 2px; top: .72em;
  width: 4px; height: 4px;
  background: var(--gold);
  rotate: 45deg;
}

.prep__cta {
  display: inline-flex; align-items: center; gap: 7px;
  margin-top: 12px;
  padding: 7px 14px 7px 11px;
  border-radius: 99px;
  font-family: var(--f-deva);
  font-size: 12px;
  color: var(--gold-ink);
  background: rgba(201, 162, 39, .12);
  border: 1px solid rgba(201, 162, 39, .42);
  transition: color .2s, background .22s, border-color .22s, transform .18s var(--e-out);
}
.prep__cta:hover {
  color: var(--on-gold);
  background: linear-gradient(160deg, #e8cf85, var(--gold));
  border-color: rgba(232, 207, 133, .75);
}
.prep__cta:active { transform: scale(.97); }

body.lang-en .prep__title { font-family: var(--f-serif); font-weight: 400; font-size: 15.5px; }
body.lang-en .prep__items li,
body.lang-en .prep__cta { font-family: var(--f-sans); }

/* ---------- the handle a panel folds into ------------------------------
 * A round button in the top bar, on the same side as its panel. Up there
 * it covers nothing — which the two earlier attempts, a floating circle
 * at the panel's corner and then a tab on the page edge, both failed to
 * do at these widths.
 *
 * It is one switch, not two controls: it stays put whether the panel is
 * out or folded, and only changes state. Lit gold while the panel is
 * out; quiet, with a breathing pip, while it is away.
 * ---------------------------------------------------------------------- */
.paneldock {
  position: relative;
  display: grid; place-items: center;
  width: var(--tool-h); height: var(--tool-h);
  flex: none;
  border-radius: 50%;
  /* An opaque plate, not a gold tint: this button floats on footage, and a
     10%-alpha wash left it all but invisible against a bright frame. */
  color: var(--gold-deep);
  background: var(--vid-glass);
  border: 1px solid rgba(201, 162, 39, .55);
  transition: color .22s, background .24s, border-color .24s, box-shadow .24s,
              transform .22s var(--e-out);
}
.paneldock .ico { width: 21px; height: 21px; }
.paneldock:hover {
  color: var(--on-gold);
  background: rgba(255, 249, 232, .98);
  border-color: rgba(201, 162, 39, .8);
}
.paneldock:active { transform: scale(.92); }

/* While a panel is out its handle has nothing left to announce: the tip
   says where the panel opens from, and it is already open. Suppressed on
   both handles rather than only the one, so the pair behave alike. */
.paneldock.is-on::before { content: none; }

/* panel out — the lamp is lit */
.paneldock.is-on {
  color: var(--on-gold);
  background: linear-gradient(160deg, #e8cf85, var(--gold));
  border-color: rgba(232, 207, 133, .75);
  box-shadow: 0 2px 12px rgba(201, 162, 39, .32);
}

/* The sequence button opens no panel, so it has no lit state to fall back
   on — its pip breathes only while its own note is up, then settles. */
.paneldock--list .paneldock__pip { display: none; }
body.coach-list-on .paneldock--list .paneldock__pip { display: block; }

/* panel folded — a quiet gold breath, so it reads as something waiting */
.paneldock__pip {
  position: absolute; top: -1px; right: -1px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 0 2px var(--ink-900), 0 0 8px var(--gold-glow);
  animation: breathe 3.4s var(--e-io) infinite;
}
.paneldock.is-on .paneldock__pip { display: none; }

/* ---------- the coach note ---------------------------------------------
 * The preparation panel arrives folded, so nothing would otherwise say
 * which button it lives behind. This hangs under that button, points at
 * it, and retires itself — on its own after a few seconds, or for good
 * once it is dismissed or the panel it names is opened.
 * ---------------------------------------------------------------------- */
.coach {
  position: absolute;
  top: calc(100% + 12px);
  right: 0;
  z-index: 7;
  display: flex; align-items: center; gap: 6px;
  width: max-content;
  max-width: min(74vw, 310px);
  padding: 9px 8px 9px 15px;
  border-radius: 14px;
  background: var(--vid-glass);
  border: 1px solid rgba(201, 162, 39, .5);
  box-shadow: 0 12px 30px rgba(24, 18, 4, .28);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  font-family: var(--f-deva);
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--ivory-2);
  text-align: left;
  opacity: 0;
  transform: translateY(-8px) scale(.97);
  transform-origin: top right;
  transition: opacity .3s var(--e-out), transform .34s var(--e-out);
}
/* Two beats: the note slides down into place, then nods twice toward the
   button it is about. The nod is delayed past the entrance so the two do
   not fight over `transform`. */
.coach.is-on {
  opacity: 1;
  transform: none;
  animation: coachNudge 1.5s var(--e-io) .45s 2;
}
@keyframes coachNudge {
  0%, 100% { transform: translateY(0); }
  45%      { transform: translateY(-5px); }
}

/* and the handle answers, so the eye joins the two together */
body.coach-on .paneldock--r { animation: coachRing 1.5s var(--e-io) .45s 2; }
@keyframes coachRing {
  0%, 100% { box-shadow: 0 0 0 0 rgba(201, 162, 39, .5); }
  60%      { box-shadow: 0 0 0 9px rgba(201, 162, 39, 0); }
}

/* a small beak under the handle it is talking about — the offset says
   which one, counting in from the right end of the cluster */
.coach { --beak: 15px; }
.coach--list { --beak: 65px; }

/* The same note, but standing in the playlist header instead of hanging
   off a fixed cluster. Arriving in edit mode is the moment someone needs
   telling what the mode is for, so it says so the same way the landing
   does — slides in, nods twice, then leaves. */
.coach--inline {
  position: relative;
  top: auto; right: auto;
  width: auto;
  max-width: none;
  --beak: 20px;             /* up at the pencil, at the right of the row */
  transform-origin: top right;
}
.coach::before {
  content: '';
  position: absolute;
  top: -6px; right: var(--beak);
  width: 10px; height: 10px;
  background: var(--vid-glass);
  border-left: 1px solid rgba(201, 162, 39, .5);
  border-top: 1px solid rgba(201, 162, 39, .5);
  transform: rotate(45deg);
}

.coach__text { min-width: 0; }

.coach__close {
  flex: none;
  display: grid; place-items: center;
  width: 26px; height: 26px;
  border-radius: 50%;
  color: var(--muted);
  transition: color .2s, background .2s;
}
.coach__close:hover { color: var(--ivory); background: var(--fill-2); }

body.lang-en .coach { font-family: var(--f-sans); }

.paneldock {
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 6px 20px rgba(24, 18, 4, .26);
}

/* The share button confirms a copy by turning gold for a moment. */
.iconbtn.is-done { color: var(--gold-ink); }


/* =====================================================================
 * 9. TOAST
 * ===================================================================== */
.toast {
  position: fixed; z-index: 95;
  left: 50%; bottom: 34px;
  translate: -50% 0;
  padding: 9px 18px;
  border-radius: 99px;
  background: rgba(250, 250, 248, .96);
  border: 1px solid var(--line);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  font-family: var(--f-deva);
  font-size: 12.5px;
  color: var(--ivory-2);
  box-shadow: 0 12px 34px rgba(52, 40, 10, .18);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .24s var(--e-out), transform .28s var(--e-out);
  pointer-events: none;
  max-width: calc(100vw - 40px);
  text-align: center;
}
.toast.is-on { opacity: 1; transform: none; }


/* =====================================================================
 * 10. FULLSCREEN
 * ===================================================================== */
.player__frame:fullscreen { border-radius: 0; aspect-ratio: auto; width: 100vw; height: 100vh; }
.player__frame:-webkit-full-screen { border-radius: 0; width: 100vw; height: 100vh; }
.player__frame:fullscreen .player__video { height: 100%; }
.player__frame:fullscreen .controls { padding: 60px 34px 22px; }
.player__frame:fullscreen .abpanel,
.player__frame:fullscreen .menu { right: 34px; bottom: 92px; }


/* =====================================================================
 * 11. ANIMATIONS
 * ===================================================================== */
@keyframes riseIn {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: none; }
}
@keyframes breathe {
  0%, 100% { opacity: .5;  transform: scale(.965); }
  50%      { opacity: .95; transform: scale(1.035); }
}

@keyframes spin { to { transform: rotate(360deg); } }
@keyframes vizBar {
  0%, 100% { transform: scaleY(.35); }
  50%      { transform: scaleY(1); }
}
@keyframes centrePulse {
  0%   { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.35); }
}
@keyframes fireCta {
  0%   { transform: scale(1);    filter: brightness(1); }
  40%  { transform: scale(1.09); filter: brightness(1.35); }
  100% { transform: scale(.7);   filter: brightness(2); opacity: 0; }
}

/* =====================================================================
 * 12. DEVANAGARI
 * Devanagari must never be letter-spaced or uppercased — tracking
 * detaches matras from their consonants and breaks conjuncts.
 * ===================================================================== */
.landing__eyebrow, .chakra__label,
.loopchip, .abpanel__title, .abpanel__msg, .field__label,
.meta__cat, .meta__title, .meta__desc,
.listhead__title, .listhead__count, .filter, .row__title, .row__badge,
.upnext__label, .upnext__btn, .tag--loop, .chip, .btn, .toast,
.player__error-title, .listsearch__input,
.sidepanel__kicker, .sidepanel__title, .sidepanel__text, .sidepanel__steps li,
.sidepanel__foot {
  letter-spacing: normal;
  text-transform: none;
}
.landing__eyebrow { word-spacing: .18em; }

/* The brand lines are Devanagari in Hindi and Latin in English, so they get
   the Latin treatment (tracking + caps) only under .lang-en. */
.brand__text strong {
  font-family: var(--f-deva-display); font-weight: 700;
  letter-spacing: normal; text-transform: none;
  font-size: 16px; line-height: 1.55;
}
.brand__text em     { font-family: var(--f-deva); letter-spacing: normal; text-transform: none; line-height: 1.5; }
body.lang-en .brand__text strong {
  font-family: var(--f-title); font-size: 13.5px; font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase; line-height: 1.3;
}
body.lang-en .brand__text em {
  font-family: var(--f-sans); letter-spacing: .2em; text-transform: uppercase;
}

/* --- secondary lines carry the OTHER script ---------------------------
   .row__sub and .meta__title-en show Latin while the UI is Hindi and
   Devanagari while the UI is English, so their treatment has to flip too:
   tracking and caps suit Latin but break Devanagari conjuncts. */
body.lang-en .row__sub,
body.lang-en .meta__title-en {
  font-family: var(--f-deva);
  letter-spacing: normal;
  text-transform: none;
}
body.lang-en .meta__title-en { font-size: 15px; }

/* Rozha One is a Devanagari face — headings fall back to the Latin display
   family once the UI is English. */
body.lang-en .meta__title,
body.lang-en .listhead__title,
body.lang-en .sidepanel__title {
  font-family: var(--f-serif);
}
body.lang-en .sidepanel__title { font-weight: 400; }
body.lang-en .listhead__title { font-size: 17px; letter-spacing: .04em; }

/* In English, UI chrome switches to the sans stack. Content lines
   (.meta__title / .meta__desc / .row__title) stay on the Devanagari stack
   because they still show the Hindi text alongside the translation. */
body.lang-en .landing__eyebrow,

body.lang-en .chakra__label,
body.lang-en .loopchip,
body.lang-en .abpanel__title,
body.lang-en .abpanel__msg,
body.lang-en .field__label,
body.lang-en .meta__cat,
body.lang-en .listhead__title,
body.lang-en .listhead__count,
body.lang-en .filter,
body.lang-en .row__badge,
body.lang-en .upnext__label,
body.lang-en .tag--loop,
body.lang-en .chip,
body.lang-en .btn,
body.lang-en .toast,
body.lang-en .player__error-title,
body.lang-en .listsearch__input,
body.lang-en .sidepanel__kicker,
body.lang-en .sidepanel__text,
body.lang-en .sidepanel__steps li,
body.lang-en .sidepanel__foot,
body.lang-en [data-tip]::before {
  font-family: var(--f-sans);
}
body.lang-en .sidepanel__kicker { letter-spacing: .16em; text-transform: uppercase; }
body.lang-en .sidepanel__text   { line-height: 1.78; }
body.lang-en .sidepanel__steps li { line-height: 1.6; }
body.lang-en .chakra__label { font-weight: 500; letter-spacing: .01em; }
body.lang-en .player__error-title { font-size: 16px; }

/* ---------- reduced motion ---------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }

/* A caption still has to be readable when it lands, and the global rule
   above only shortens the journey — it does not undo the blur and the
   offset the line rests at before it is released. Stated outright. */
.cue { transform: none !important; filter: none !important; }
}

/* =====================================================================
 * 14. POPUP SURFACES — white ground, single gold
 * ---------------------------------------------------------------------
 * Every popup — the two side panels, the custom-loop panel, the menu and
 * the toast — sits on pure white and carries one colour, #b6890d, for its
 * text and its furniture. Kept as one block at the end rather than edited
 * through sections 5 / 8b so the whole treatment can be read, tuned or
 * lifted out in one place.
 * ===================================================================== */
:root {
  --pop-bg:  #ffffff;
  --pop-ink: #b6890d;
  --pop-rgb: 182, 137, 13;
}

/* ---------- the surfaces themselves ----------------------------------- */
.sidepanel__card,
.abpanel,
.menu,
.toast {
  background: var(--pop-bg);
  border-color: rgba(var(--pop-rgb), .32);
}

/* ---------- text ------------------------------------------------------
 * The descendant selector is deliberate: these cards carry prose, lists,
 * labels and inline icons that all took their colour from the ink scale,
 * and the ask is one colour across the whole surface. Anything that must
 * stay off it — the error line, the lit hover states — already carries
 * two classes and outranks this. */
.sidepanel__card, .sidepanel__card *,
.abpanel, .abpanel *,
.menu, .menu *,
.toast {
  color: var(--pop-ink);
}

/* The panel title was a clipped gradient, so its fill has to be handed
   back before a plain colour can show. */
.sidepanel__title {
  background: none;
  color: var(--pop-ink);
  -webkit-text-fill-color: var(--pop-ink);
}

/* ---------- gold furniture -------------------------------------------- */
.sidepanel__corner { border-color: var(--pop-ink); }

.sidepanel__mark,
.sidepanel__min,
.prep__mark,
.prep__cta {
  color: var(--pop-ink);
  background: rgba(var(--pop-rgb), .10);
  border-color: rgba(var(--pop-rgb), .34);
}

.sidepanel__rule span {
  background: linear-gradient(90deg, transparent, rgba(var(--pop-rgb), .55), transparent);
}
.sidepanel__rule i,
.sidepanel__steps li::before,
.prep__items li::before {
  background: var(--pop-ink);
  box-shadow: none;
}

/* Hairlines and the nested preparation cards, so the white ground is not
   broken up by leftovers from the ink scale. */
.sidepanel__head { border-bottom-color: rgba(var(--pop-rgb), .18); }
.sidepanel__foot { border-top-color: rgba(var(--pop-rgb), .18); }
.prep {
  background: rgba(var(--pop-rgb), .05);
  border-color: rgba(var(--pop-rgb), .18);
}


/* =====================================================================
 * 15. ABOUT — the link, and the page behind it
 * ---------------------------------------------------------------------
 * The Purpose card is a narrow column; the About is a long read. So the
 * card carries one line out to it, and the reading happens on a page of
 * its own that takes the whole screen.
 *
 * Colours come from the --pop-* tokens in section 14 — this belongs to
 * the same white-and-single-gold family as every other popup.
 *
 * A note on Devanagari: none of the labels down here are tracked or
 * uppercased. Letter-spacing pushes matras off their consonants and
 * splits conjuncts, so 'संस्थापक' would set as 'सं स्था प क'. The
 * small-caps treatment these labels want is an English-only affair and
 * is applied in the lang-en block at the end.
 * ===================================================================== */

/* ---------- the link on the card -------------------------------------- */
.aboutlink {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  width: 100%;
  margin-top: 20px;
  padding: 13px 15px;
  border-radius: var(--r-md);
  font-family: var(--f-deva);
  font-size: 13px;
  color: var(--pop-ink);
  text-align: left;
  background: rgba(var(--pop-rgb), .05);
  border: 1px solid rgba(var(--pop-rgb), .26);
  transition: background .24s var(--e-out), border-color .24s, transform .24s var(--e-out);
}
.aboutlink:hover {
  background: rgba(var(--pop-rgb), .1);
  border-color: rgba(var(--pop-rgb), .45);
}
.aboutlink:active { transform: scale(.99); }
.aboutlink .ico { flex: none; transition: transform .28s var(--e-out); }
.aboutlink:hover .ico { transform: translateX(3px); }

/* ---------- the page --------------------------------------------------- */
.aboutpage {
  position: fixed; inset: 0; z-index: 60;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  background: var(--pop-bg);
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .32s var(--e-out), transform .38s var(--e-out);
}
.aboutpage.is-on { opacity: 1; transform: none; }

.aboutpage__bar {
  display: flex; align-items: center; gap: 12px;
  padding: 0 clamp(16px, 4vw, 40px);
  height: var(--topbar-h);
  border-bottom: 1px solid rgba(var(--pop-rgb), .18);
}
.aboutpage__mark {
  display: grid; place-items: center;
  width: 30px; height: 30px; flex: none;
  border-radius: 50%;
  color: var(--pop-ink);
  border: 1px solid rgba(var(--pop-rgb), .4);
}
.aboutpage__mark .ico { width: 17px; height: 17px; }
.aboutpage__eyebrow {
  flex: 1; min-width: 0;
  font-family: var(--f-deva);
  font-size: 12px;
  color: var(--pop-ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.aboutpage__close { flex: none; color: var(--pop-ink); }

.aboutpage__scroll {
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: clamp(28px, 5vw, 56px) clamp(18px, 5vw, 40px) clamp(48px, 9vh, 96px);
}
.aboutpage__scroll:focus { outline: none; }

/* One measure down the middle. A page this wide with text running the
   full span of it would be unreadable; 62ch is the line the rest of the
   app's prose already sets to. */
.ab__head, .ab__figure, .ab__verse, .ab__org {
  max-width: 62ch;
  margin-left: auto; margin-right: auto;
}

.ab__rule {
  display: flex; align-items: center; justify-content: center;
  gap: 12px; margin: clamp(30px, 5vh, 46px) auto clamp(18px, 3vh, 26px);
  max-width: 200px;
}
.ab__rule span {
  height: 1px; flex: 1;
  background: linear-gradient(90deg, transparent, rgba(var(--pop-rgb), .55), transparent);
}
.ab__rule i {
  width: 5px; height: 5px; flex: none;
  background: var(--pop-ink); transform: rotate(45deg);
}

/* ---------- masthead --------------------------------------------------- */
.ab__title {
  font-family: var(--f-deva-display);
  font-size: clamp(26px, 4.4vw, 40px);
  font-weight: 600;
  line-height: 1.28;
  color: var(--ivory);
  text-align: center;
}
.ab__lede {
  font-family: var(--f-deva);
  font-size: clamp(14px, 1.5vw, 16px);
  line-height: 1.95;
  color: var(--ivory-2);
  text-align: center;
  margin-top: 16px;
  text-wrap: pretty;
}

.ab__figure {
  margin: clamp(26px, 4vh, 40px) auto 0;
  border-radius: var(--r-lg);
  overflow: hidden;
  border: 1px solid rgba(var(--pop-rgb), .22);
  background: var(--ink-750);
  box-shadow: 0 18px 44px rgba(52, 40, 10, .13);
}
/* The lift on this photograph is baked into the JPEG rather than applied
   here — it costs the browser nothing and looks the same everywhere. */
.ab__figure img { width: 100%; height: auto; display: block; }
.ab__caption {
  font-family: var(--f-deva);
  font-size: 12.5px;
  line-height: 1.75;
  color: var(--muted);
  padding: 12px 16px 14px;
  background: rgba(var(--pop-rgb), .045);
  border-top: 1px solid rgba(var(--pop-rgb), .16);
  text-wrap: pretty;
}

/* ---------- the mantra ------------------------------------------------- */
.ab__eyebrow {
  font-family: var(--f-deva);
  font-size: 12.5px;
  color: var(--pop-ink);
  text-align: center;
  margin-bottom: 16px;
}

/* The one place on the page that gets the display face and the gold at
   size. Five short lines, read as five short lines. */
.ab__mantra {
  font-family: var(--f-deva-display);
  font-size: clamp(18px, 2.4vw, 25px);
  font-weight: 600;
  line-height: 2;
  text-align: center;
  color: var(--pop-ink);
  padding: clamp(22px, 4vw, 36px) clamp(16px, 3vw, 30px);
  border-radius: var(--r-lg);
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(var(--pop-rgb), .1), transparent 70%),
    rgba(var(--pop-rgb), .04);
  border: 1px solid rgba(var(--pop-rgb), .22);
}
.ab__meaning {
  font-family: var(--f-deva);
  font-size: 14px;
  line-height: 1.9;
  color: var(--ivory-2);
  text-align: center;
  margin-top: 18px;
  text-wrap: pretty;
}
.ab__note {
  font-family: var(--f-deva);
  font-size: 13px;
  line-height: 1.85;
  color: var(--muted);
  margin: 16px auto 0;
  max-width: 52ch;
  padding-left: 14px;
  border-left: 2px solid rgba(var(--pop-rgb), .3);
  text-wrap: pretty;
}

/* ---------- the people -------------------------------------------------- */
/* Two up where there is room. Four people in one column on a wide screen
   is a long thin list with a lot of white either side of it. */
.ab__people {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: clamp(16px, 2.5vw, 26px);
  margin-top: 6px;
}
/* A hairline to the left rather than a bullet: four entries of three lines
   each need grouping, and a dot in front of every name would be four dots
   too many. */
.ab__person {
  display: grid; gap: 3px;
  padding-left: 14px;
  border-left: 2px solid rgba(var(--pop-rgb), .22);
}
.ab__name {
  font-family: var(--f-sans);
  font-size: 15px;
  font-weight: 600;
  color: var(--ivory);
}
.ab__role {
  font-family: var(--f-deva);
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--pop-ink);
}
.ab__pnote {
  font-family: var(--f-deva);
  font-size: 12.5px;
  line-height: 1.75;
  color: var(--muted);
  text-wrap: pretty;
}

.ab__place {
  margin-top: clamp(26px, 4vh, 40px);
  padding-top: 16px;
  border-top: 1px solid rgba(var(--pop-rgb), .16);
  font-family: var(--f-deva);
  font-size: 12px;
  color: var(--muted-2);
  text-align: center;
}

/* Nothing behind the page may scroll while it is up. */
body.about-open { overflow: hidden; }

/* ---------- English ----------------------------------------------------- */
/* Latin sets tighter than Devanagari and does not need the leading the
   matras ask for — and here, unlike Devanagari, the small labels can take
   the tracking and the small caps they were designed for. */
body.lang-en .ab__lede,
body.lang-en .ab__meaning,
body.lang-en .ab__note,
body.lang-en .ab__role,
body.lang-en .ab__pnote,
body.lang-en .ab__caption,
body.lang-en .aboutlink       { font-family: var(--f-sans); line-height: 1.72; }
body.lang-en .ab__title       { font-family: var(--f-title); letter-spacing: .01em; }
body.lang-en .ab__mantra      { font-family: var(--f-deva-display); }
body.lang-en .ab__eyebrow,
body.lang-en .ab__place,
body.lang-en .aboutpage__eyebrow {
  font-family: var(--f-sans);
  font-size: 11px;
  letter-spacing: .2em;
  text-transform: uppercase;
}

/* =====================================================================
   HINDI PADHNE LAYAK (6 Oct): Devanagari 10-11px par matra ke saath
   padhne me kathin thi. Sirf Hindi mode me chhote label thode bade;
   English (body.lang-en) jaisa tha waisa.
   ===================================================================== */
body:not(.lang-en) .chip,
body:not(.lang-en) .meta__eyebrow,
body:not(.lang-en) .upnext__label,
body:not(.lang-en) .listhead__count,
body:not(.lang-en) .listhead__hint,
body:not(.lang-en) .field__label,
body:not(.lang-en) .sidepanel__kicker,
body:not(.lang-en) [data-tip]::before { font-size: 12.5px; letter-spacing: 0; }
body:not(.lang-en) .brand__text em { font-size: 12px; }
body:not(.lang-en) .coach { font-size: 13px; }

/* =====================================================================
   PLAYER BAR KAALA (6 Oct, user): safed wash video ke kaale lyrics-band
   ke upar dhundhla lagta tha. Ab kaala wash + safed icon/samay.
   ===================================================================== */
.controls {
  background: linear-gradient(to top, rgba(8, 6, 3, .86) 0%, rgba(8, 6, 3, .55) 50%, transparent 100%);
}
.controls .iconbtn,
.controls .iconbtn--primary,
.controls .iconbtn--ghost { color: rgba(255, 255, 255, .92); }
.controls .iconbtn:hover { color: #fff; background: rgba(255, 255, 255, .14); }
.controls .iconbtn.is-on,
.controls .iconbtn--ghost.is-on { color: #f0c64a; }
.controls .iconbtn.has-preset { color: rgba(240, 198, 74, .7); }
.controls .timecode,
.controls .speedbtn__text { color: rgba(255, 255, 255, .9); }
.controls .scrub__rail { background: rgba(255, 255, 255, .28); }
.controls .scrub__buffer { background: rgba(255, 255, 255, .35); }

/* ---------- about: parivaar slideshow (6 Oct) ---------------------------- */
.ab__slider .ab__stage { position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: #1a140a; }
.ab__slider .ab__stage img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transform: scale(1.04);
  transition: opacity 1.2s ease, transform 6s ease-out;
}
.ab__slider .ab__stage img.is-on { opacity: 1; transform: scale(1); }
.ab__dots {
  position: absolute; left: 0; right: 0; bottom: 12px; z-index: 2;
  display: flex; justify-content: center; gap: 8px;
}
.ab__dot {
  width: 8px; height: 8px; padding: 0; border-radius: 99px; border: 0; cursor: pointer;
  background: rgba(255, 255, 255, .55); box-shadow: 0 1px 4px rgba(0, 0, 0, .35);
  transition: width .3s ease, background .3s ease;
}
.ab__dot.is-on { width: 22px; background: #f0c64a; }
.ab__slider .ab__caption { font-size: 14px; min-height: 3.4em; text-align: center; }
@media (prefers-reduced-motion: reduce) { .ab__slider .ab__stage img { transition: opacity .3s; transform: none; } }
/* slideshow bada dikhe (6 Oct): text ki chaudai se bahar, 920px tak */
.ab__figure.ab__slider { width: min(920px, calc(100vw - 32px)); max-width: none; margin-left: 50%; transform: translateX(-50%); }

/* =====================================================================
   LANDING TEXT BADA (6 Oct, user): CTA, upar ke button, panel ka text.
   ===================================================================== */
.chakra__label { font-size: clamp(16px, 1.75vw, 22px); padding: 18px 44px; }
.prep__title { font-size: 16.5px; }
.prep__items li { font-size: 14.5px; }
.prep__cta { font-size: 13.5px; }
.audiodock__label { font-size: 14px; }
.landing__tools .langbtn { font-size: 13.5px; }
.modebtn { font-size: 1.25em; }
body:not(.lang-en) .sidepanel__kicker { font-size: 13px; }
.sidepanel__title { font-size: 23px; }
.sidepanel__text { font-size: 16px; line-height: 1.9; }
.sidepanel__steps li { font-size: 15px; }
.aboutlink, .aboutlink * { font-size: 14.5px; }
body:not(.lang-en) .coach { font-size: 14px; }

/* ---------- autoplay switch (controls bar) ----------------------------
   An icon alone did not say what it was, so it carries a short word, and
   the word dims with the icon when autoplay is off. */
.iconbtn.autobtn {
  width: auto; padding: 0 9px 0 7px; gap: 4px;
  display: inline-flex; align-items: center;
  border-radius: 999px;
  opacity: .55;
}
.iconbtn.autobtn.is-on { opacity: 1; }
.iconbtn.autobtn .ico { width: 17px; height: 17px; }
.autobtn__label { font-family: var(--f-deva); font-size: 12px; line-height: 1; letter-spacing: .02em; }

/* =====================================================================
 * LANDING — do sahayak button (पूजन की तैयारी · पूजन की सूची), CTA ke upar
 * 8 Oct: pehle ye upar daayein kone me sirf icon (paneldock) the. Ab chakra
 * ke saath ek pankti me, naam ke saath. Jaan-boojh kar CTA se alag: sunehri
 * dhaatu nahi, halka kaanch + sunehra kinara, taaki mukhya button wahi rahe.
 * ===================================================================== */
.landing__quick {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 10px;
  margin-bottom: 14px;
  animation: riseIn 1.1s var(--e-out) backwards .4s;
}
.quickbtn {
  display: inline-flex; align-items: center; gap: 9px;
  height: 42px;
  padding: 0 18px 0 6px;
  border-radius: 99px;
  font-family: var(--f-deva);
  font-size: 15px; font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  color: var(--on-gold);
  background: var(--vid-glass);
  border: 1px solid rgba(201, 162, 39, .6);
  box-shadow: 0 6px 20px rgba(24, 18, 4, .24), inset 0 1px 0 rgba(255, 255, 255, .9);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  transition: transform .3s var(--e-out), background .24s, border-color .24s, box-shadow .24s;
}
.quickbtn[hidden] { display: none; }
.quickbtn__ico {
  display: grid; place-items: center;
  width: 30px; height: 30px; flex: none;
  border-radius: 50%;
  color: var(--on-gold);
  background: linear-gradient(160deg, #f1dc9c, #d4ae45 60%, #b8891c);
  box-shadow: inset 0 1px 0 rgba(255, 252, 235, .8), 0 0 0 1px rgba(146, 106, 14, .45);
}
.quickbtn__ico .ico { width: 17px; height: 17px; }
.quickbtn:hover {
  transform: translateY(-2px);
  background: #fffdf6;
  border-color: rgba(201, 162, 39, .9);
  box-shadow: 0 10px 26px rgba(24, 18, 4, .28), 0 0 22px rgba(232, 207, 133, .35);
}
.quickbtn:active { transform: translateY(1px) scale(.98); transition-duration: .12s; }
.quickbtn:focus-visible { outline: 2px solid var(--gold-deep); outline-offset: 3px; }
/* taiyari panel khula ho to uska button jala hua */
.quickbtn.is-on {
  background: linear-gradient(160deg, #f3e2aa, #e3c46b);
  border-color: rgba(146, 106, 14, .7);
}
body.lang-en .quickbtn { font-family: var(--f-sans); font-size: 14px; font-weight: 600; }
@media (max-width: 520px) {
  .landing__quick { gap: 8px; margin-bottom: 12px; }
  .quickbtn { height: 38px; font-size: 14px; padding: 0 14px 0 5px; gap: 7px; }
  .quickbtn__ico { width: 27px; height: 27px; }
}
