/* RAYARA ANTARANGA · editorial layer
   One typography system, one motion language, one website. */

/* ---------------- global tokens ---------------- */
:root {
  /* ============================ TYPE ============================
     TWO FAMILIES, and no third.

       MARCELLUS (400, its only weight) — a lapidary Roman serif cut from
       inscriptional capitals. It NAMES things: the wordmark, headlines,
       plate and work titles, the held lines over the world, the numerals,
       the giant word.

       KARLA (300 / 400 / 500 from one variable file) — a grotesque with a
       few quirks in it. It EXPLAINS things: reading copy at 300, and every
       label, eyebrow, caption and button at 400.

     Three rules hold it together, and they are not negotiable:
       1. Reading copy is ALWAYS Karla 400, 1.02–1.08rem, line-height
          1.66–1.72 (400 since 19 Sept 2026: over the moving world the 300
          lost its stems). Never heavier, never tighter.
       2. Every label, eyebrow, button and caption is Karla 400 at
          .70–.76rem, uppercase, letter-spacing .14em.
       3. THERE IS NO BOLD ANYWHERE. Hierarchy comes from size and from
          the serif/sans switch, never from weight. --weight-bold is 400
          and exists only so old declarations keep meaning something.

     Kannada stays Noto Sans Kannada and Devanagari Noto Serif Devanagari,
     because neither Latin face carries them; both are always set with a
     reading in Karla beside them.

     ---- the ladder ----
     The small end still steps by 1.2, re-anchored on the new reading size:

         step n  =  1.04rem x 1.2^n

     The display roles do NOT come off the ladder: their clamps are
     authored (see --size-hero / --size-display / --size-plate / the
     numerals), because a lapidary serif at 5vw is composed by eye against
     the frame, not derived. That is the one exception, as the caption
     clamps were before it. */
  --ratio: 1.2;

  --step--2:  .723rem;      /* 11.6px — the label register */
  --step--1:  .867rem;
  --step-0:  1.04rem;       /* 16.6px — reading copy  <- anchor */
  --step-1:  1.248rem;
  --step-2:  1.498rem;
  --step-3:  1.797rem;
  --step-4:  2.157rem;
  --step-5:  2.588rem;
  --step-6:  3.106rem;
  --step-7:  3.727rem;
  --step-8:  4.472rem;
  --step-9:  5.367rem;
  --step-11: 7.728rem;
  --step-13: 11.13rem;

  /* the faces */
  --font-display:    'Marcellus', Georgia, 'Times New Roman', serif;
  --font-body:       'Karla', 'Segoe UI', system-ui, sans-serif;
  --font-micro:      'Karla', 'Segoe UI', system-ui, sans-serif;
  --font-kannada:    'Noto Sans Kannada', 'Karla', sans-serif;
  --font-devanagari: 'Noto Serif Devanagari', serif;

  /* the roles — every font-size in this file names one of these */
  --size-label:   .72rem;    /* caps + .14em, the label register */
  --size-anno:    .76rem;    /* the second label level */
  --size-body:   1.04rem;    /* reading copy, Karla 300 */
  --size-body-sm: .95rem;    /* secondary copy: list entries, notes */
  --size-title:  1.248rem;
  /* authored display clamps (see the note above) */
  --size-plate:   clamp(1.8rem, 4.2vw, 3.4rem);
  --size-display: clamp(1.9rem, 3.8vw, 3.7rem);
  --size-hero:    clamp(1.9rem, 3.9vw, 3.8rem);
  --size-num:     clamp(2.8rem, 7.5vw, 6.4rem);
  --size-giant:   clamp(3.6rem, 10vw, 10.5rem);

  /* weight — Marcellus has one, Karla is used at two.
       400 -> Marcellus, and every label
       300 -> all reading copy
     There is no 500 and no 700 on this site. */
  --weight-display: 400;
  --weight-title:   400;
  --weight-body:    400;
  --weight-bold:    400;

  /* tracking — the serif is set nearly solid, the labels wide */
  --tracking-giant:   -.008em;
  --tracking-display: -.008em;
  --tracking-title:   -.004em;
  --tracking-body:     0;
  --tracking-list:     .04em;
  --tracking-caps:     .14em;
  --tracking-label:    .14em;

  /* leading */
  --leading-giant:   .92;
  --leading-flat:    1;
  --leading-display: 1.04;
  --leading-title:   1.2;
  --leading-body:    1.7;
  --leading-script:  1.9;

  /* color — THE SIX. Old lace, Bone, Dark goldenrod, Kobicha, Coyote, Earth
     Green, and nothing else. On dark ground the ink is Old lace and Bone;
     on the two light grounds (the page, the five words) the ink is Earth
     Green and Kobicha (see body.ui-light). The gold is the one warmth. */
  --lace: #F7F1E1;
  --bone: #E3D8C1;
  --gold: #B4833D;
  --kobicha: #66371B;
  --coyote: #81754B;
  --earth: #3F3F2C;
  --ink: var(--lace);
  --ink-dim: var(--bone);
  --ink-faint: #a89d82;     /* Bone, dimmed toward Coyote */
  --amber: var(--gold);
  --gopi: #c9a468;          /* the drawing hue: Dark goldenrod lifted to read as a hairline on dark stone */
  --ground: #26261c;        /* Earth Green, deepened: the ground under everything */
  --night: #0d0d09;         /* Earth Green at the edge of lamplight: THE ONE DARK. The vigil's air and
                               curtains, the veils into the sanctum, the footer's end, the favicon. No
                               other near-black exists on the site (the old blue-blacks read as a
                               different place each time the frame went dark). */

  /* layout — ONE reading position for the whole story. Every narrative
     block (captions, the Pūrvāśrama layer, the works) sits in this column:
     the left third on desktop, the lower-middle of the frame on a phone.
     It moves only for a storytelling reason (a chapter's name held in the
     centre), never because a new scene began. */
  --gutter: clamp(44px, 5.8vw, 112px);
  --maxw: 34em;
  --col-left: var(--gutter);
  --col-width: min(560px, 40vw);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: auto; }
body {
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-body);
  /* the ladder's anchor step, so anything that sets no size of its own
     inherits step 0 rather than the browser's off-ladder 16px default */
  font-size: var(--size-body);
  font-weight: var(--weight-body);
  line-height: var(--leading-body);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

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

/* the canvas box: the LARGE viewport, so the frame is already painted when
   iOS hides its toolbar mid-scroll (100vh fallback covers old engines).
   Scroll mapping stays on the stable small viewport (scroll.js) — only the
   painted area breathes, never t. */
/* the canvas fills its fixed containing block exactly as the other fixed
   layers do (inset: 0). Sized in vh it could stop short of the bottom of a
   phone screen, where the fixed block is taller than 100vh, and a band of the
   page ground (earth green) showed under the word. min-height keeps it
   under the toolbar as iOS hides it. */
#gl { position: fixed; top: 0; left: 0; width: 100%; height: 100%; min-height: 100lvh; z-index: 1; display: block; }

/* ---------------- opening hero ---------------- */
/* the copy opens well below the wordmark: air between the interface band
   and the editorial block, at every size */
#hero {
  /* below the interface layer (z 6): the phone menu panel must cover it */
  position: fixed; left: var(--gutter); top: max(17vh, 150px); z-index: 5;
  max-width: 760px; width: 46vw; min-width: 0;
  /* real, selectable text — main.js turns pointer-events off once the block
     has faded out with the first scroll */
  pointer-events: auto;
  transition: none;
}
/* a quiet indigo atmosphere behind the copy — readable over the sunrise.
   It ends just under the copy: the risen sun stands clear of it below. */
#hero::before {
  content: ''; position: absolute; z-index: -1; left: -42%; top: -60%; right: -46%; bottom: -52%;
  /* the copy crosses the horizon band, which is the brightest thing in the
     frame. The scrim has to CARRY it, not tint it — so it is strong at the
     centre and very wide, which is what keeps it from reading as a panel. */
  background: radial-gradient(closest-side, rgba(12,14,32,.76) 0%, rgba(12,14,32,.60) 38%, rgba(12,14,32,.28) 66%, rgba(12,14,32,0) 100%);
  pointer-events: none;
}
#hero .hero-eyebrow {
  font-family: var(--font-micro); font-size: var(--size-label); font-weight: var(--weight-bold); letter-spacing: var(--tracking-label);
  color: var(--gopi); margin: 0 0 2.2em;
  text-shadow: 0 1px 12px rgba(10,14,24,.7);
  display: flex; align-items: center; gap: 10px;
}
#hero .hero-eyebrow::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: var(--gopi); flex: none;
}
#hero .hero-heading {
  font-family: var(--font-display);
  font-weight: var(--weight-display); font-size: var(--size-hero);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display); color: var(--ink); margin: 0 0 .7em;
  text-shadow: 0 2px 26px rgba(10,14,24,.6);
  /* MEASURED: "Sri Raghavendra Tirtha" is 10.213em in Marcellus, so at the
     3.9vw display size the longest line is 39.8vw and the 46vw column
     carries it with slack. It wraps rather than running past if a face
     ever measures wider. The break after "of" stays authored (the <br>). */
  white-space: normal;
}
#hero .hero-body {
  font-weight: var(--weight-body); font-size: var(--size-body); line-height: var(--leading-body);
  color: var(--ink);
  max-width: 54ch; margin: 0 0 .9em;
  text-shadow: 0 1px 2px rgba(8,10,22,.9), 0 2px 18px rgba(8,10,22,.85), 0 0 34px rgba(8,10,22,.6);
  text-wrap: pretty;          /* no single word left on the last line */
}

/* the word: one line of flat bone-white type spanning the full viewport.
   The size is REFITTED whenever the face changes: MANTRALAYA in Marcellus
   400 at .04em tracking is measured below, and the vw figure is
   97.5vw / (its width in em) so the first M and final A stay whole at every
   width, with side margins wide enough to absorb the cursor parallax
   (±.6vw, main.js) without ever clipping either letter. */
#word {
  position: fixed; left: 50%; bottom: -2.4vw; transform: translateX(-50%); z-index: 6;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 13.85vw; line-height: var(--leading-flat); letter-spacing: var(--tracking-list);
  color: rgba(227,216,193,.78); white-space: nowrap;
  /* selectable like every other word on the site; main.js turns pointer-events
     off once the word has faded out with the first scroll */
  pointer-events: auto;
  text-shadow: 0 2px 44px rgba(6,9,18,.4);
  transition: none;
  will-change: transform;
}
#word > span { display: inline-block; }
/* the scroll cue: a label and a hairline with light running down it.
   Transform/opacity only; it waits for the heading and leaves on the first
   scroll (body.past-hero, main.js). */
#scroll-cue {
  position: fixed; right: var(--gutter); bottom: calc(11.5vw + 28px); z-index: 6;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  font-family: var(--font-micro); font-size: var(--size-label); letter-spacing: var(--tracking-label);
  text-transform: uppercase; color: var(--ink-dim); pointer-events: none;
  opacity: 0; transform: translate3d(0, 10px, 0);
  transition: opacity 1s cubic-bezier(.16,1,.3,1), transform 1.2s cubic-bezier(.16,1,.3,1);
}
body.hero-in #scroll-cue { opacity: .78; transform: none; transition-delay: 1.4s; }
body.hero-in.past-hero #scroll-cue { opacity: 0; transform: translate3d(0, -10px, 0); transition-delay: 0s; transition-duration: .5s; }
#scroll-cue span { writing-mode: vertical-rl; }
#scroll-cue i { position: relative; display: block; width: 1px; height: 54px; overflow: hidden; background: rgba(227,216,193,.22); }
#scroll-cue i::after {
  content: ''; position: absolute; left: 0; top: 0; width: 1px; height: 100%;
  background: linear-gradient(to bottom, rgba(227,216,193,0), rgba(227,216,193,.95));
  transform: translate3d(0, -100%, 0);
  animation: cue-run 2.4s cubic-bezier(.65,0,.35,1) infinite;
}
@keyframes cue-run { 0% { transform: translate3d(0, -100%, 0); } 60%, 100% { transform: translate3d(0, 100%, 0); } }
/* a phone is scrolled by habit, and the cue would sit on the gateway's pillar */
@media (max-width: 768px) { #scroll-cue { display: none; } }
@media (prefers-reduced-motion: reduce) { #scroll-cue i::after { animation: none; transform: none; } }
body.nowebgl #scroll-cue, body.domonly #scroll-cue { display: none; }

/* pre-dawn: the interface layer waits in the dark and arrives with the light */
body.predawn #ui { opacity: 0; }
#ui { transition: opacity 2.4s ease; }

/* ---- hero entrance — the KAGE register: masked lines rise word by word on
   an expo-out ease, the annotations breathe up after them, the great word
   surfaces last. The copy is HIDDEN from the very first paint and released
   once (body.hero-in, added as the dawn begins) — it only ever travels
   upward, never down into hiding. Transform/opacity only; skipped entirely
   under reduced motion; always visible in the nowebgl/domonly documents. ---- */
#hero .hero-heading .hw { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: .26em; margin-bottom: -.26em; }
@media (prefers-reduced-motion: no-preference) {
  #hero .hero-eyebrow { transition: opacity 1.1s cubic-bezier(.16,1,.3,1); }
  #hero .hero-body { transition: opacity .9s cubic-bezier(.16,1,.3,1) .68s, transform 1.05s cubic-bezier(.16,1,.3,1) .68s; }
  #hero .hero-heading .hw > span {
    display: inline-block;
    transition: transform .82s cubic-bezier(.16,1,.3,1), opacity .5s cubic-bezier(.16,1,.3,1);
    transition-delay: calc(.12s + var(--wd, 0s));
  }
  #hero .hw:nth-of-type(2) > span { --wd: .07s; }
  #hero .hw:nth-of-type(3) > span { --wd: .14s; }
  #hero .hw:nth-of-type(4) > span { --wd: .21s; }
  #hero .hw:nth-of-type(5) > span { --wd: .28s; }
  #hero .hw:nth-of-type(6) > span { --wd: .38s; }
  #hero .hw:nth-of-type(7) > span { --wd: .45s; }
  #hero .hw:nth-of-type(8) > span { --wd: .52s; }
  #word > span { transition: transform 1.5s cubic-bezier(.16,1,.3,1) .55s, opacity 1s cubic-bezier(.16,1,.3,1) .55s; }
  body:not(.hero-in):not(.nowebgl):not(.domonly) #hero .hero-eyebrow { opacity: 0; }
  body:not(.hero-in):not(.nowebgl):not(.domonly) #hero .hero-body { opacity: 0; transform: translateY(26px); }
  body:not(.hero-in):not(.nowebgl):not(.domonly) #hero .hero-heading .hw > span { opacity: 0; transform: translate3d(0, 145%, 0); }
  body:not(.hero-in):not(.nowebgl):not(.domonly) #word > span { opacity: 0; transform: translate3d(0, 22%, 0); }
}

/* tablet + mobile adjustments for the opening layer */
@media (max-width: 1024px) {
  #hero { top: max(17vh, 150px); max-width: none; min-width: 0; width: auto; right: 20vw; }
  /* the tablet override must not be LARGER than the desktop clamp it
     replaces: 6.4vw was 51px at 800 where desktop resolves to 31px */
  #hero .hero-heading { font-size: clamp(1.9rem, 4.6vw, 3.1rem); }
}
@media (max-width: 768px) {
  /* ---- the phone hero is its own composition, not the desktop scaled ----
     One column reading top-down: compact interface band → eyebrow → a
     deliberate three-line headline → two quiet lines of copy → then the
     gateway, which cam00's portrait shot raises to own the lower half.
     Everything above is pinned in px (not vh) so iOS toolbar moves cannot
     re-space the opening frame. */
  #hero { left: 7%; right: 7%; top: calc(96px + var(--safe-t)); max-width: none; width: auto; min-width: 0; }
  #hero .hero-eyebrow { margin-bottom: 1.4em; }
  /* three lines, authored: THE LIFE AND WORKS OF / SRI RAGHAVENDRA / TIRTHA.
     6.55vw holds the first (longest) line whole in the 86vw column. */
  #hero .hero-heading {
    white-space: normal;
    font-size: 7.6vw; line-height: 1.06; letter-spacing: var(--tracking-display);
    margin-bottom: .6em;
  }
  /* the copy supports, the architecture leads: annotation size, short measure */
  #hero .hero-body {
    font-size: var(--size-body-sm); line-height: var(--leading-body);
    max-width: 34ch; color: var(--ink);
  }
  #hero::before { left: -20%; right: -20%; top: -40%; bottom: -30%; }

  /* the word keeps its edge-to-edge measure but sits fully inside the frame:
     the desktop bleed crop read as broken next to the (former) black gap */
  #word { bottom: calc(4px + var(--safe-b)); }
}

/* ---- film grain ----
   One fixed tile over the whole frame, from an inline SVG turbulence: no
   image file and no request. `stitchTiles="stitch"` is what makes the
   240px tile seamless, so the only thing that repeats is noise the eye
   cannot lock onto. The blend mode is the point: `overlay` deepens the
   darks and lifts the lights, where a plain white noise layer would fog
   the whole picture. Static, never animated — moving grain reads as video
   noise rather than stock. Opacity is the dial x .62. */
#grain {
  position: fixed; inset: 0; z-index: 40; pointer-events: none;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNDAiIGhlaWdodD0iMjQwIj48ZmlsdGVyIGlkPSJuIj48ZmVUdXJidWxlbmNlIHR5cGU9ImZyYWN0YWxOb2lzZSIgYmFzZUZyZXF1ZW5jeT0iMC45IiBudW1PY3RhdmVzPSIzIiBzdGl0Y2hUaWxlcz0ic3RpdGNoIi8+PC9maWx0ZXI+PHJlY3Qgd2lkdGg9IjI0MCIgaGVpZ2h0PSIyNDAiIGZpbHRlcj0idXJsKCNuKSIvPjwvc3ZnPg==");
  background-size: 240px 240px;
  opacity: .31;              /* .5 x .62 */
}
@media (max-width: 768px) { #grain { display: none; } }
#vignette { display: none; }
#veil { position: fixed; inset: 0; z-index: 4; pointer-events: none; background: var(--night); opacity: 0; }

/* ---------------- captions / editorial blocks ---------------- */
#captions { position: fixed; inset: 0; z-index: 5; pointer-events: none; }
.cap {
  /* the narrative column: left third, vertically centred */
  position: absolute; left: var(--col-left); top: 50%; transform: translateY(-50%);
  width: var(--col-width); max-width: var(--maxw); text-align: left;
  opacity: 0; will-change: opacity, transform;
  /* the narrative is real, copyable text. The layer above stays inert; each
     visible block accepts the cursor (visibility:hidden releases it again) */
  pointer-events: auto;
}
/* the one permitted break: a name or a number held in the centre of the frame */
.cap.pos-center { left: 50%; top: 50%; transform: translate(-50%, -50%); width: auto; max-width: min(var(--maxw), 82vw); text-align: center; }
/* on the light grounds (a pale veil is up: the page, the five words, the
   morning seam) every caption takes dark ink and drops its shadow */
/* the caption's own shade, as the hero's: a radial that reaches 0 inside
   its box (closest-side), so it has no edge to show, and it fades with the
   block. Enough for the return's lines to be read across the second sunrise. */
.cap .cap-in { position: relative; }
.cap .cap-in::before {
  content: ''; position: absolute; z-index: -1; left: -46%; right: -46%; top: -70%; bottom: -60%;
  background: radial-gradient(closest-side, rgba(13,13,9,.62) 0%, rgba(13,13,9,.44) 40%, rgba(13,13,9,.18) 72%, rgba(13,13,9,0) 100%);
  pointer-events: none;
}
.cap.pos-center .cap-in::before { left: -30%; right: -30%; }
body.ui-light .cap .cap-in::before { display: none; }
body.ui-light .cap { --ink: var(--earth); --ink-dim: #3f3d2f; --ink-faint: #6b6248; --gopi: var(--kobicha); }
body.ui-light .cap * { text-shadow: none; }

/* ---- editorial hierarchy ----
   Four sizes, two weights, one family. Every scene draws from this and
   nothing else; scene personality comes from composition, not new type. */
/* chapter number / location / date marker */
.t-loc {
  font-family: var(--font-micro);
  font-size: var(--size-label); font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  color: var(--gopi); margin-bottom: 1.4em;
  text-shadow: 0 1px 2px rgba(0,0,0,.3);
}
/* scene display — the serif names, so it is set as written, not shouted */
.t-display {
  font-family: var(--font-display);
  font-size: var(--size-display); font-weight: var(--weight-display);
  line-height: 1.1; letter-spacing: var(--tracking-display);
  color: var(--ink); margin-bottom: .4em;
  text-shadow: 0 2px 24px rgba(0,0,0,.4);
}
.t-display.t-xl { font-size: var(--size-hero); line-height: var(--leading-display); }
/* major statement */
.t-sub {
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 2.1vw, 2rem); font-weight: var(--weight-display);
  line-height: 1.32; letter-spacing: -.006em;
  color: var(--ink); margin-bottom: .55em;
  text-shadow: 0 1px 20px rgba(0,0,0,.85);
}
/* body — held to a reading measure everywhere */
.t-body {
  font-size: var(--size-body); font-weight: var(--weight-body);
  line-height: var(--leading-body); color: rgba(247,241,225,.84);
  text-shadow: 0 1px 2px rgba(0,0,0,.3);
  max-width: 58ch;
}
.t-sub { max-width: 38ch; }
.t-loc + .t-loc { margin-top: -.9em; color: var(--ink-faint); }
/* the place's name in Kannada, as a second eyebrow line: the script the
   life was lived in, always beside its reading in Karla */
.t-loc[lang="kn"] { font-family: var(--font-kannada); font-weight: 300; font-size: .82rem; letter-spacing: .12em; text-transform: none; }
/* the works: a Kannada display word, a Devanagari title line, the title and
   the takeaway — the same ladder, nothing new */
.t-kn {
  font-family: var(--font-kannada); font-weight: 300;
  font-size: var(--size-display); line-height: var(--leading-script);
  color: var(--ink); margin: .1em 0 .3em;
  text-shadow: 0 2px 30px rgba(0,0,0,.65);
}
.t-dn {
  font-family: var(--font-devanagari); font-weight: 400;
  font-size: var(--size-title); line-height: var(--leading-script);
  color: var(--gopi); margin: -.2em 0 .8em;
}
.t-display.t-work { margin-bottom: .2em; }
.t-body + .t-body { margin-top: 1em; }
/* the three spacing relationships the copy needs, named once: a paragraph
   that follows a display line, a label that closes a block, a line that
   runs the full column. Nothing in the copy carries an inline style. */
.t-after { margin-top: 1.2em; }
.t-close { margin-top: .9em; }
.t-wide { max-width: none; }
.t-body strong { color: var(--ink); font-weight: var(--weight-bold); }
/* moment of extreme scale */
.t-num {
  font-family: var(--font-display);
  font-size: var(--size-num); font-weight: var(--weight-display);
  line-height: .78; letter-spacing: var(--tracking-display); color: var(--ink); font-variant-numeric: tabular-nums;
  text-shadow: 0 2px 40px rgba(0,0,0,.7);
}
/* a Brindavana title: the site's own scene display (t-display's size,
   sentence case, as it is written), nothing set apart for this chapter */
.t-q {
  font-family: var(--font-display);
  font-size: var(--size-display); font-weight: var(--weight-display);
  line-height: 1.1; letter-spacing: var(--tracking-display);
  color: var(--ink); margin-bottom: .55em; max-width: 14ch; text-wrap: balance;
  text-shadow: 0 2px 24px rgba(0,0,0,.4);
}
.pos-center .t-q, .pos-low .t-q { text-align: center; max-width: 18ch; }
.pos-center .t-q::after, .pos-low .t-q::after {
  content: ''; display: block; width: 44px; height: 2px; background: var(--gopi);
  margin: .7em auto 0; opacity: .8;
}
/* the akṣara inside running copy */
.t-om {
  font-family: var(--font-devanagari); font-weight: 400; font-size: 1.35em; line-height: var(--leading-flat);
  color: var(--gopi);
}
/* an enormous word bleeding past the frame — environment, not caption,
   but still real text: selectable like everything else */
.t-giant {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--size-giant); line-height: var(--leading-giant); letter-spacing: var(--tracking-giant);
  color: rgba(247,241,225,.11); white-space: nowrap;
  text-transform: uppercase;
}
/* tiny contextual annotation — the second information level */
.t-anno {
  font-family: var(--font-micro);
  font-size: var(--size-anno); font-weight: var(--weight-body);
  line-height: 1.7; color: var(--ink-faint); max-width: 34ch;
  text-shadow: 0 1px 10px rgba(0,0,0,.7);
}
.t-anno strong { color: var(--ink-dim); font-weight: var(--weight-bold); }

/* ---------------- persistent UI ---------------- */
#ui { position: fixed; inset: 0; z-index: 6; pointer-events: none; }
#wordmark {
  position: absolute; top: 34px; left: var(--gutter); display: flex; align-items: center; gap: 12px;
  color: var(--ink); opacity: .92; transition: opacity 1.2s;
  pointer-events: auto;   /* its text is copyable like the rest of the site */
}
#wordmark .mark { width: 30px; height: 30px; color: var(--gopi); flex: none; }
#wordmark .wm-text { display: flex; flex-direction: column; gap: 1px; font-family: var(--font-micro); }
#wordmark .wm-text b { font-family: var(--font-display); font-weight: var(--weight-display); font-size: 1.02rem; letter-spacing: .012em; line-height: 1.25; }
#wordmark .wm-text small { font-weight: var(--weight-bold); font-size: .6rem; letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-faint); line-height: 1.5; }

/* top navigation */
#topnav {
  position: absolute; top: 38px; right: var(--gutter); pointer-events: auto;
  display: flex; gap: 30px;
}
/* the menu button exists only on a phone */
#menu-btn { display: none; }
#topnav button {
  background: none; border: none; cursor: pointer; padding: 8px 0;
  font-family: var(--font-micro); font-weight: var(--weight-bold); font-size: var(--size-anno); letter-spacing: var(--tracking-label);
  color: var(--ink-dim); transition: color .4s;
}
#topnav button:hover, #topnav button:focus-visible { color: var(--ink); }
#topnav button:focus-visible { outline: 1px solid rgba(247,241,225,.4); outline-offset: 4px; }
/* the sound control is not a section: a hairline sets it apart from them */
#topnav #sound-btn { margin-left: 4px; padding-left: 30px; position: relative; }
#topnav #sound-btn::before {
  content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 1px; height: 13px; background: currentColor; opacity: .34;
}

#aaradhane-link {
  position: absolute; bottom: calc(30px + var(--safe-b)); right: 30px; pointer-events: auto;
  font-family: var(--font-micro); font-size: var(--size-label); font-weight: var(--weight-bold); letter-spacing: var(--tracking-label); text-transform: uppercase;
  color: var(--ink-dim); text-decoration: none; border-bottom: 1px solid rgba(180,131,61,.5);
  padding-bottom: 3px; opacity: 0; transition: opacity 1s, color .4s;
}
#aaradhane-link:hover { color: var(--ink); }
#aaradhane-link.visible { opacity: .95; }
body.in-footer #aaradhane-link { opacity: 0; pointer-events: none; }

body.ui-quiet #wordmark { opacity: .14; }
body.in-doc #wordmark { opacity: .38; }
body.in-doc #topnav { opacity: .55; transition: opacity .6s; }
body.in-doc #topnav:hover, body.in-doc #wordmark:hover { opacity: 1; }
/* while a pale veil is up (the river's light becoming the yard's), the
   cream interface would vanish: it takes dark ink for that moment */
#wordmark, #topnav button, #menu-btn span { transition: color .6s ease, background-color .6s ease, opacity 1.2s; }
body.ui-light #wordmark { color: var(--earth); }
body.ui-light #wordmark .mark { color: var(--gold); }
body.ui-light #wordmark .wm-text small { color: rgba(63,63,44,.6); }
body.ui-light #topnav button { color: rgba(63,63,44,.75); }
body.ui-light #menu-btn span { background: var(--earth); }
#sound-btn[aria-pressed="true"] { color: var(--gopi); }
/* the phone's compact sound control: bars only, a slash through them when off */
#sound-btn-m { display: none; }
@media (max-width: 768px) {
  #sound-btn-m {
    position: absolute; top: calc(14px + var(--safe-t)); right: 60px; pointer-events: auto;
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; padding: 0; background: none; border: 0; cursor: pointer;
    color: var(--gopi); -webkit-tap-highlight-color: transparent;
  }
  #sound-btn-m[aria-pressed="false"] { color: var(--ink-dim); }
  #sound-btn-m .snd-eq { height: 14px; gap: 3px; }
  #sound-btn-m .snd-eq i { width: 2px; }
  #sound-btn-m .snd-x { position: absolute; width: 20px; height: 1.5px; background: currentColor; transform: rotate(-45deg); }
  body.ui-light #sound-btn-m { color: var(--gold); }
}
/* the playing indicator: three bars, moving only while this tab sounds */
#sound-btn { display: inline-flex; align-items: center; gap: 8px; }
#sound-btn .snd-eq, #sound-btn-m .snd-eq { display: inline-flex; align-items: flex-end; gap: 2px; height: 10px; }
#sound-btn .snd-eq i, #sound-btn-m .snd-eq i { display: block; width: 2px; height: 100%; background: currentColor; transform-origin: 50% 100%; transform: scaleY(.3); }
#sound-btn.playing .snd-eq i, #sound-btn-m.playing .snd-eq i { animation: snd-eq 1.1s ease-in-out infinite; }
#sound-btn.playing .snd-eq i:nth-child(2), #sound-btn-m.playing .snd-eq i:nth-child(2) { animation-delay: -.35s; animation-duration: .9s; }
#sound-btn.playing .snd-eq i:nth-child(3), #sound-btn-m.playing .snd-eq i:nth-child(3) { animation-delay: -.7s; animation-duration: 1.3s; }
@keyframes snd-eq { 0%, 100% { transform: scaleY(.3); } 50% { transform: scaleY(1); } }
@media (prefers-reduced-motion: reduce) { #sound-btn.playing .snd-eq i, #sound-btn-m.playing .snd-eq i { animation: none; transform: scaleY(.8); } }

/* ---------------- footer — the river continuing ----------------
   After the return the dawn frame stays live under the last page: water,
   the far bank, the light. The footer is two lines set on it, and a
   hairline planting along the lower edge in the loader's own hand. It is
   not another scene, and it does not compete with the Brindavana. */
#footer {
  position: relative; z-index: 8;
  /* the last metres of the same journey. The footer sits in the page's own
     flow directly after the story's last scroll (no dead viewport, no second
     scroller): as it rises, the river stays under it and the night ground
     comes up through the frame over the whole run, slowly, until it is the
     ground the last lines stand on. The camera keeps moving under it the
     whole way (main.js footerP). */
  /* the one shade under the last lines: the night colour rising from the
     page's foot, nothing at the footer's top edge (so no band ever crosses
     the frame as it scrolls in), enough for the colophon to be read on the
     dawn water without the river going dark */
  background: linear-gradient(to bottom, rgba(13,13,9,0) 0%, rgba(13,13,9,.16) 38%, rgba(13,13,9,.44) 70%, rgba(13,13,9,.64) 100%);
  /* exactly one viewport tall, its lines at the foot: the story's last scroll
     (t = 1) IS the frame the footer stands in. Shorter than a viewport the
     page could never reach t = 1; taller, and the visitor scrolls on past
     the story to find it. */
  min-height: 100vh; min-height: 100svh; box-sizing: border-box;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: 44vh 0 0;
}
#footer .f-in { position: relative; z-index: 2; text-shadow: 0 1px 14px rgba(0,0,0,.7); }
#footer .f-line {
  position: relative; z-index: 2;
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 18px 40px;
  margin: 0 var(--gutter); padding: 22px 0; border-top: 1px solid var(--line-soft);
}
#footer .f-mark { display: flex; align-items: center; gap: 12px; color: var(--ink); font-family: var(--font-display); font-size: 1.02rem; font-weight: var(--weight-display); letter-spacing: .012em; }
#footer .f-mark svg { width: 28px; height: 28px; color: var(--gopi); flex: none; }
#footer .f-links { display: flex; flex-wrap: wrap; gap: 8px 26px; }
#footer .f-links button, #footer .f-links a { font: inherit; font-family: var(--font-micro); font-size: var(--size-label); font-weight: var(--weight-bold); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-faint); background: none; border: 0; padding: 0; cursor: pointer; text-decoration: none; transition: color .35s; }
#footer .f-links button:hover, #footer .f-links a:hover, #footer .f-links button:focus-visible, #footer .f-links a:focus-visible { color: var(--ink); }
/* the colophon: origin left, the salutation held in the middle, the note right */
#footer .f-base {
  position: relative; z-index: 2;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 20px;
  margin: 0 var(--gutter); padding: 18px 0 calc(34px + var(--safe-b));
  border-top: 1px solid var(--line-soft);
  font-family: var(--font-micro); font-size: var(--size-label); font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  color: var(--ink-faint); opacity: .8;
}
#footer .f-base > :first-child { text-align: left; }
#footer .f-base > :last-child { text-align: right; max-width: 34ch; justify-self: end; }
/* Devanagari never stands alone on this site: it is always set with its
   reading, in Karla, on the line beneath */
#footer .f-seal { text-align: center; }
#footer .f-seal span {
  display: block; font-family: var(--font-devanagari); font-weight: 400;
  font-size: var(--size-title); line-height: var(--leading-script);
  letter-spacing: .04em; text-transform: none; color: rgba(201,164,104,.68);
}
#footer .f-seal small { display: block; margin-top: .5em; font-size: var(--size-label); }

/* ---------------- no-WebGL fallback: the biography as a document ---------- */
body.nowebgl { background: var(--night); }
body.nowebgl #gl, body.nowebgl #veil, body.nowebgl #word, body.nowebgl #scroll-space, body.nowebgl #ground { display: none; }
/* the chapters flow as a document between the hero and the Brindavana's
   captions (main.js moves #movements out of the scroll driver); on the flat
   dark page their scrims are simply not needed */
body.nowebgl #movements { margin-top: 10vh; }
body.nowebgl #hero { position: static; margin: 140px auto 0; padding: 0 var(--gutter); opacity: 1 !important; }
/* the scene's legibility scrim: once #hero is static its offsets resolve
   against the viewport and push the page wide — and the flat document
   background needs no scrim anyway */
body.nowebgl #hero::before { display: none; }
body.nowebgl #captions.static {
  position: static; pointer-events: auto;
  padding: 8vh var(--gutter) 12vh;
}
body.nowebgl #captions.static .static-note {
  max-width: var(--maxw); margin: 0 auto 10vh;
  font-size: var(--size-body); line-height: var(--leading-body); color: var(--ink-faint);
  border-left: 2px solid var(--gopi); padding-left: 18px;
}
body.nowebgl #captions.static .cap {
  position: static; opacity: 1 !important; visibility: visible !important;
  transform: none !important; max-width: var(--maxw);
  margin: 0 auto 14vh; text-align: left;
}
/* in the flowing document, environmental type becomes ordinary headings */
body.nowebgl .t-giant {
  font-size: clamp(var(--step-6), 9vw, var(--step-11)); white-space: normal; color: var(--ink);
  line-height: var(--leading-flat);
}
/* ---------------- THE CHAPTERS — one day on the river ----------------
   The life is read on the bank of the opening's own world while its day
   goes by, in ONE continuous walk of the camera (main.js STATIONS): no
   curtain, no cut, no second world, no card. Every beat is a poster in one
   register: an eyebrow (a gold dot, place and date, the name in Kannada),
   a title in the lapidary serif, one paragraph; the thing to look at stands
   in the world (js/world/stations.js). ONE reading position, the site's
   own: the lower part of the frame on a phone, with the world above the
   words; the left column on a wide frame, with the world to the right. */
:root {
  --pad: clamp(22px, 3.4vw, 56px);
  --line: rgba(247,241,225,.14);
  --line-soft: rgba(247,241,225,.08);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}
/* the night ground: rises only at the tail, over the last chapter, and
   dissolves onto the sanctum (main.js) */
#ground { position: fixed; inset: 0; z-index: 2; background: var(--night); opacity: 0; pointer-events: none; }
#ground.dark { background: var(--night); }
#scroll-space { position: relative; z-index: 3; }
#scroll-space .sp { display: block; }
#movements { position: relative; color: var(--ink); font-family: var(--font-body); }
/* the lead: the dusk falls in view, the moon comes up, before a word */
#movements .mv-lead { height: 150vh; }   /* the walk from the composition to the house's gate, with nothing to read: a slow walk, the first words arriving as the camera does */
#movements .mv-tail { height: 170vh; }
#movements p, #movements h2, #movements h3, #movements ol, #movements figure { margin: 0; padding: 0; }
#movements button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

/* ---- a chapter: a section in the flow is only the SCROLL LENGTH of its
   beat (main.js measures the walk from it); its copy (.sec-in) is fixed in
   the frame at the site's reading position, and movements.js gives it its
   life: rising and fading up as the section arrives, held while it is read,
   dissolving as it leaves. Nothing scrolls. ---- */
#movements .sec { position: relative; min-height: 100svh; }
#movements .sec + .sec { margin-top: 14vh; }
/* a sub-beat (one work, one difference) and a quiet beat (one paragraph)
   are read faster: less scroll each */
#movements .sec.sub, #movements .sec + .sec.sub { min-height: 88svh; margin-top: 6vh; }
#movements .sec.quiet { min-height: 84svh; }
#movements .sec.quiet + .sec, #movements .sec + .sec.quiet { margin-top: 10vh; }
/* the copy block: the lower part of the frame on a phone, the world above
   the words; on a wide frame the left column, the world to the right */
#movements .sec-in {
  position: fixed; z-index: 3; left: 24px; right: 24px;
  bottom: calc(max(9vh, 64px) + var(--safe-b));
  display: flex; flex-direction: column; align-items: flex-start; text-align: left;
  opacity: 0; visibility: hidden; will-change: opacity, transform; pointer-events: none;
  transform: translate3d(0, var(--dy, 0px), 0);   /* the glide (movements.js) */
}
/* ---- THE POOL: the one shade the words are read in ----
   No chapter paints a scrim of its own. A rectangle's edge always shows as
   a band the moment the box moves through the frame (lesson 12). Instead
   ONE fixed layer (#pool, under the chapters, over the world) holds a
   single round pool of the night colour that reaches full transparency at
   its own rim, so it has no edge to show anywhere. movements.js carries it:
   each frame it sits on the copy block that is in the frame, scaled to the
   block, and its strength is the block's presence. Everything it does is a
   transform and an opacity on one composited layer. */
#pool { position: fixed; inset: 0; z-index: 2; overflow: hidden; pointer-events: none; opacity: 0; will-change: opacity; }
#pool i {
  position: absolute; left: 50%; top: 50%; width: 1024px; height: 1024px; margin: -512px 0 0 -512px;
  transform-origin: 50% 50%; will-change: transform;
  /* dense at the heart, a long tail, and NOTHING at the rim: `closest-side`
     puts the last stop on the square's inscribed circle, so the box the
     gradient lives in is transparent wherever it could ever cross the frame */
  background: radial-gradient(circle closest-side, rgba(13,13,9,.88) 0%, rgba(13,13,9,.82) 26%, rgba(13,13,9,.58) 52%, rgba(13,13,9,.25) 76%, rgba(13,13,9,.06) 92%, rgba(13,13,9,0) 100%);
}
#movements .title.sm { font-size: clamp(1.5rem, 5.8vw, 2rem); max-width: 18ch; }
#movements .sub .copy { max-width: 42ch; }
#movements .sec.quiet .copy { max-width: 40ch; }
/* the eyebrow */
#movements .eyebrow { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 14px; margin-bottom: clamp(14px, 2.4vh, 26px); }
#movements .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--gopi); box-shadow: 0 0 10px var(--gopi); flex: none; }
#movements .k { font-family: var(--font-micro); font-size: var(--size-label); font-weight: var(--weight-bold); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-dim); text-shadow: 0 1px 2px rgba(0,0,0,.35); }
#movements .k.kn { font-family: var(--font-kannada); font-weight: 300; font-size: .84rem; letter-spacing: .12em; text-transform: none; color: var(--ink-faint); margin-left: auto; }
/* ---- THE TWO CENTRED BEATS (19 Sept 2026, the owner's eleventh brief):
   the Tattvavāda opening and Hari Sarvottama (.sec.mid, index.html) are
   read in the middle of the frame, set centred, a comfortable measure,
   the world above and around them (their stations put the subject above
   the words, main.js ny). Every other beat keeps the site's column. ---- */
#movements .sec.mid .sec-in { align-items: center; text-align: center; }
#movements .sec.mid .eyebrow { justify-content: center; }
#movements .sec.mid .k.kn { margin-left: 0; }
/* the title: the serif, large; sentence case, as it is written */
#movements .title {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: clamp(1.9rem, 7.6vw, 2.5rem); line-height: 1.08; letter-spacing: var(--tracking-display);
  color: var(--ink); text-shadow: 0 2px 22px rgba(0,0,0,.42); max-width: 15ch; text-wrap: balance;
  margin-bottom: clamp(16px, 2.8vh, 30px);
}
/* the reading copy: Old lace, nearly full, on the pool's shade; the body a
   step quieter. No drop shadow to speak of: legibility is the pool's job. */
#movements .copy { max-width: 46ch; }
#movements .lead { font-size: 1rem; line-height: 1.66; font-weight: var(--weight-body); color: rgba(247,241,225,.94); text-shadow: 0 1px 2px rgba(0,0,0,.3); text-wrap: pretty; }
#movements .body { font-size: 1rem; line-height: 1.66; font-weight: var(--weight-body); color: rgba(247,241,225,.82); text-shadow: 0 1px 2px rgba(0,0,0,.3); text-wrap: pretty; }
#movements .lead + .body, #movements .body + .body { margin-top: .9em; }
#movements .body-lg { font-size: 1.04rem; line-height: 1.66; font-weight: var(--weight-body); color: rgba(247,241,225,.86); text-shadow: 0 1px 2px rgba(0,0,0,.3); max-width: 40ch; text-wrap: pretty; }

/* the four dates */
#movements .dates { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 24px; margin-top: clamp(20px, 3.4vh, 40px); padding-top: 18px; border-top: 1px solid var(--line-soft); }
#movements .dates b { display: block; font-family: var(--font-display); font-size: clamp(1.5rem, 6vw, 2.2rem); font-weight: var(--weight-display); letter-spacing: var(--tracking-display); color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1.05; margin-bottom: 6px; text-shadow: 0 2px 22px rgba(0,0,0,.4); }
#movements .dates span { font-family: var(--font-micro); font-size: var(--size-label); font-weight: var(--weight-bold); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-faint); }

/* the name: the one centred beat, held in the middle of the frame */
#movements .fin .sec-in { left: 24px; right: 24px; bottom: auto; top: 50%; transform: translate3d(0, calc(-50% + var(--dy, 0px)), 0); display: flex; flex-direction: column; align-items: center; text-align: center; }
#movements .fin .eyebrow { justify-content: center; }
#movements .fin .lead { max-width: 30ch; margin-bottom: clamp(22px, 4.5vh, 48px); }
#movements .was { position: relative; margin-bottom: 18px; }
#movements .was::after { content: ''; position: absolute; left: -4px; right: -4px; top: 50%; height: 1px; background: var(--gopi); transform: scaleX(0); transform-origin: left; transition: transform 1.1s var(--ease-out) .7s; }
#movements .sec.on .was::after { transform: scaleX(1); }
#movements .title.name { font-size: clamp(2.4rem, 10.5vw, 7.4rem); line-height: 1.02; max-width: 12ch; text-shadow: 0 2px 34px rgba(0,0,0,.5); }
#movements .fin .body-lg { margin-top: 8px; }

/* the arrow link into the Brindavana */
#movements .arrowlink { display: inline-flex; align-items: center; gap: 14px; margin-top: 24px; font-family: var(--font-micro); font-size: var(--size-label); font-weight: var(--weight-bold); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink); text-shadow: 0 1px 2px rgba(0,0,0,.35); }
#movements .arrowlink .ar { width: 36px; height: 36px; border: 1px solid var(--line); border-radius: 50%; display: grid; place-items: center; transition: background-color .45s var(--ease-out), border-color .45s; }
#movements .arrowlink .ar svg { display: block; width: 12px; height: 12px; }
#movements .arrowlink:hover .ar, #movements .arrowlink:focus-visible .ar { background: var(--ink); border-color: var(--ink); color: var(--night); }

/* ---- arrivals: the block's own fade is scroll-linked (movements.js); inside
   it the eyebrow and the copy breathe up a little after the title, whose
   words rise one by one, whenever the beat arrives (.sec.on) ---- */
#movements [data-rv="up"] { opacity: 0; transform: translate3d(0, 14px, 0); transition: opacity .7s var(--ease-out), transform .9s var(--ease-out); }
#movements .sec.on [data-rv="up"] { opacity: 1; transform: none; transition-delay: .18s; }
#movements .sec.on .eyebrow[data-rv="up"] { transition-delay: .04s; }
#movements .wm { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: .26em; margin-bottom: -.26em; }
#movements .word { display: inline-block; opacity: 0; transform: translate3d(0, 120%, 0); will-change: transform, opacity; transition: transform .1s, opacity .1s; }
#movements .sec.on .word { opacity: 1; transform: none; transition: transform .82s var(--ease-out), opacity .5s var(--ease-out); transition-delay: var(--wd, 0ms); }

/* ---- the rail: one mark per chapter at the right edge, while the chapters are read ---- */
#rail { position: absolute; right: var(--pad); top: 50%; translate: 0 -50%; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; opacity: 0; transition: opacity .8s; pointer-events: none; }
body.in-doc #rail { opacity: 1; pointer-events: auto; }
#rail button { width: 28px; height: 10px; display: flex; align-items: center; justify-content: flex-end; background: none; border: 0; cursor: pointer; padding: 0; }
#rail i { display: block; width: 13px; height: 1px; background: rgba(247,241,225,.3); transition: width .5s var(--ease-out), background-color .5s; }
#rail button.on i { width: 28px; background: var(--ink); }
#rail button:hover i { width: 28px; background: var(--ink-dim); }
#topnav button { position: relative; }
#topnav button.on { color: var(--ink); }
#topnav button.on::after { content: ''; position: absolute; left: 0; right: 0; bottom: 4px; height: 1px; background: var(--gopi); }
/* the vignette: the frame's edges a little darker while the chapters are read */
#vignette { display: block; position: fixed; inset: 0; z-index: 7; pointer-events: none; opacity: 0; transition: opacity 1s ease;
  background: radial-gradient(120% 90% at 50% 45%, rgba(13,13,9,0) 62%, rgba(13,13,9,.3) 100%); }
body.in-doc #vignette { opacity: .5; }
body.nowebgl #vignette, body.nowebgl #rail { display: none; }

@media (prefers-reduced-motion: reduce) {
  #movements [data-rv], #movements .word { opacity: 1; transform: none; transition: none; }
  #movements .was::after { transform: scaleX(1); transition: none; }
}

/* ---- a wide frame: one column at the left (the site's reading position),
   the world to its right; the pool sits on the column, so the frame's right
   half stays open. The five differences alternate: left, right, left, right,
   left (.sec.right), the copy still set left-aligned in its column, the
   subject of each placed on the other side by its station (main.js) ---- */
@media (min-width: 769px) {
  #movements .sec { min-height: 100vh; }
  #movements .sec + .sec { margin-top: 18vh; }
  #movements .sec.sub, #movements .sec + .sec.sub { min-height: 90vh; margin-top: 6vh; }
  #movements .sec.quiet { min-height: 82vh; }
  #movements .sec.quiet + .sec, #movements .sec + .sec.quiet { margin-top: 10vh; }
  /* the column sits LOW in the frame, as the hero's does and as Seijaku's: the sky and the subject above and right of it, the ground under it */
  #movements .sec-in { left: var(--pad); right: auto; bottom: 12vh; width: min(560px, 42vw); }
  #movements .sec.right .sec-in { left: auto; right: var(--pad); }
  #movements .eyebrow { width: 100%; max-width: 30rem; }
  #movements .title { font-size: clamp(2.3rem, 3.9vw, 3.8rem); line-height: 1.04; max-width: 14ch; margin-bottom: clamp(18px, 2.8vh, 32px); }
  #movements .title.sm { font-size: clamp(1.5rem, 2.2vw, 2.15rem); max-width: 17ch; }
  #movements .copy { max-width: 40ch; }
  /* the two centred beats stand in the MIDDLE of the frame, their centre a
     little below the frame's, the sky and the subject above the words and
     the water under them; a wider measure than the column, still
     comfortable to read (a lead of ~52 characters a line) */
  #movements .sec.mid .sec-in { left: 50%; right: auto; top: 58%; bottom: auto; width: min(720px, 60vw); transform: translate3d(-50%, calc(-50% + var(--dy, 0px)), 0); }
  #movements .sec.mid .eyebrow { width: auto; max-width: none; }
  #movements .sec.mid .title { font-size: clamp(2.2rem, 3.6vw, 3.5rem); line-height: 1.06; max-width: 20ch; }
  #movements .sec.mid .title.sm { max-width: 24ch; }
  #movements .sec.mid .copy { max-width: 52ch; }
  #movements .sec.mid.quiet .copy { max-width: 44ch; }
  #movements .lead { font-size: 1.06rem; line-height: 1.7; }
  #movements .body { font-size: 1.02rem; line-height: 1.7; }
  #movements .eyebrow { margin-bottom: clamp(18px, 3vh, 34px); }
  #movements .dates { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px clamp(18px, 2.2vw, 36px); margin-top: clamp(26px, 4.5vh, 52px); width: 100%; max-width: 40rem; }
  #movements .dates b { font-size: clamp(1.5rem, 2vw, 2.1rem); }
  #movements .fin .sec-in { left: 50%; right: auto; width: min(760px, 70vw); transform: translate3d(-50%, calc(-50% + var(--dy, 0px)), 0); }
  #movements .fin .lead { font-size: 1.08rem; }
  #movements .title.name { font-size: clamp(3.4rem, 6.8vw, 7.6rem); max-width: 14ch; }
  #movements .copy .body { max-width: 42ch; }
  #movements .sec.mid .copy .body { max-width: 48ch; }
}
@media (max-width: 768px) {
  #movements .mv-lead { height: 130vh; }
  #rail { display: none; }
  /* the phone's two compositions: the column low and left; for the
     alternate differences it stands to the right, a shorter measure */
  #movements .sec.right .sec-in { left: calc(24px + 10vw); right: 24px; }
  #movements .lead, #movements .body { font-size: .98rem; line-height: 1.62; }
  #movements .copy { max-width: 38ch; }
  /* the name on a phone: the block is tall (a lead, the old name, the new,
     a paragraph), so it stands on the frame's foot like every other beat,
     a little tighter, rather than centred and cut by the header */
  #movements .fin .sec-in { top: auto; bottom: calc(max(8vh, 56px) + var(--safe-b)); transform: translate3d(0, var(--dy, 0px), 0); }
  #movements .fin .lead { font-size: .95rem; margin-bottom: 18px; }
  #movements .was { margin-bottom: 12px; }
  #movements .title.name { font-size: 9.4vw; }
  #movements .fin .body-lg { font-size: .98rem; line-height: 1.6; }
}

/* without WebGL the chapters flow as a document (main.js lifts them out of
   the scroll driver): the night ground is the page, nothing else changes */
body.nowebgl #movements .mv-lead, body.nowebgl #movements .mv-tail { display: none; }
body.nowebgl #pool { display: none; }
body.nowebgl #movements .sec { min-height: 0; padding: 0 var(--pad) 12vh; }
body.nowebgl #movements .sec-in, body.nowebgl #movements .fin .sec-in { position: static; opacity: 1 !important; visibility: visible !important; transform: none !important; pointer-events: auto; width: auto; max-width: 46rem; margin: 0 auto; }

/* ---------------- BrindavanaPreloader — architectural drafting ------------
   Rust ink on warm paper. The drawing is a canvas (js/preloader.js draws it
   from the SVG source, on a worker); this layer only sizes it, sets the paper
   and lifts the sheet away when the world is ready. */
:root {
  --paper: #14140f;          /* the night's charcoal: THE ONE DARK, a step warmer, the sheet the world is drafted on */
  --paper-ink: #c9a468;      /* the drawing hue (--gopi): the lamps' gold as a hairline */
  --paper-cap: #E3D8C1;      /* Bone: the caption */
}
#preloader {
  position: fixed; inset: 0; width: 100vw; height: 100dvh; z-index: 9999;
  overflow: hidden;
  background: var(--paper);
  color: var(--paper-ink);
  display: flex; align-items: center; justify-content: center;
  /* the exit is a page lifted off the world: transform only */
  transition: transform 1.15s cubic-bezier(.76, 0, .24, 1), visibility 0s linear 1.15s;
  will-change: transform;
}
/* paper tooth: the same turbulence as the site grain, warm and faint */
#preloader::before {
  content: ''; position: absolute; inset: 0; pointer-events: none; opacity: .5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .78 0 0 0 0 .64 0 0 0 0 .42 0 0 0 .07 0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* a soft shadow at the lower edge as the sheet lifts */
#preloader::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 18vh; pointer-events: none;
  background: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,.28));
}
#preloader.done { transform: translate3d(0, -100%, 0); visibility: hidden; pointer-events: none; }

#preloader .pre-in {
  position: relative; z-index: 1;
  display: flex; flex-direction: column; align-items: center; gap: clamp(22px, 3.4vh, 36px);
  transition: transform 1.15s cubic-bezier(.76, 0, .24, 1), opacity .7s ease;
}
/* the drawing travels a little slower than the sheet: depth as it goes */
#preloader.done .pre-in { transform: translate3d(0, 42vh, 0); opacity: 0; }
#preloader .pre-mark {
  position: relative;
  height: clamp(420px, 62vh, 600px);
  aspect-ratio: 360 / 600;
}
#preloader .pre-mark svg { position: absolute; inset: 0; width: 100%; height: 100%; visibility: hidden; }
#preloader .pre-mark canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* the hold: only the finished Brindavana on the sheet, drawing a slow breath
   closer while the world waits beneath (transform only) */
#preloader .pre-mark { transform: scale(1); transition: transform 1s cubic-bezier(.33, 0, .2, 1); }
#preloader.held .pre-mark { transform: scale(1.035); transition-duration: var(--hold, 3000ms); }
@media (prefers-reduced-motion: reduce) { #preloader.held .pre-mark { transform: none; } }

/* the caption, set like the palette reference: small, wide, rust */
#preloader .pre-cap {
  margin: 0; font-family: var(--font-micro); font-weight: 400;
  font-size: .78rem; letter-spacing: .34em; text-indent: .34em; text-transform: uppercase;
  color: var(--paper-cap); white-space: nowrap; text-align: center;
  opacity: 0; transform: translate3d(0, 8px, 0);
  animation: pre-cap 1.2s cubic-bezier(.16, 1, .3, 1) .35s forwards;
}
#preloader .pre-cap small { display: block; margin-top: 1.1em; font-size: .62rem; letter-spacing: .3em; opacity: .62; color: var(--paper-ink); }
@keyframes pre-cap { to { opacity: 1; transform: none; } }

/* a stalled load: the caption breathes, so the sheet never reads as frozen */
#preloader.waiting .pre-cap small { animation: pre-breathe 2.4s ease-in-out infinite; }
@keyframes pre-breathe { 0%, 100% { opacity: .62; } 50% { opacity: .25; } }

@media (prefers-reduced-motion: reduce) {
  #preloader, #preloader .pre-in { transition: opacity .4s ease, visibility 0s linear .4s; }
  #preloader.done { transform: none; opacity: 0; }
  #preloader.done .pre-in { transform: none; }
  #preloader .pre-cap { animation: none; opacity: 1; transform: none; }
  #preloader.waiting .pre-cap small { animation: none; }
}

/* tablet */
@media (max-width: 1024px) {
  #preloader .pre-mark { height: clamp(400px, 58vh, 560px); }
}

/* mobile — the primary platform */
@media (max-width: 768px) {
  :root { --maxw: 30em; }
  #preloader .pre-mark { height: min(58vh, calc(66vw * 600 / 360)); }
  #preloader .pre-cap { font-size: .7rem; letter-spacing: .3em; text-indent: .3em; }
  /* compact interface band: same marks, less height — the desktop header
     read as a heavy band across a phone's opening frame */
  #wordmark { top: calc(12px + var(--safe-t)); left: 20px; gap: 10px; }
  #wordmark .mark { width: 26px; height: 26px; }
  #wordmark .wm-text { gap: 2px; }
  #wordmark .wm-text small { font-size: .62rem; }
  /* the narrative column on a phone: the lower-middle of the frame, well
     above the browser's own controls, generous side margins. Fixed
     elements sit inside the small (toolbar-present) viewport, so `bottom`
     here is always above Safari's and Chrome's bars. */
  :root { --col-left: 24px; --col-width: calc(100vw - 48px); }
  .cap {
    left: 24px; right: 24px; width: auto; max-width: none; transform: none;
    top: auto; bottom: calc(max(18vh, 132px) + var(--safe-b));
  }
  .cap.pos-center { left: 24px; right: 24px; top: 50%; bottom: auto; transform: translateY(-50%); width: auto; }
  .t-body { max-width: none; }
  .t-sub { max-width: none; }
  #aaradhane-link { bottom: calc(22px + var(--safe-b)); right: 20px; }
  #footer { padding-top: 30vh; }
  /* every line of the footer centred on a phone */
  #footer .f-line { margin-left: 24px; margin-right: 24px; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 16px; }
  #footer .f-mark { justify-content: center; }
  #footer .f-links { justify-content: center; gap: 10px 22px; }
  /* one column, centred */
  #footer .f-base {
    grid-template-columns: 1fr; justify-items: center; gap: 14px;
    margin-left: 24px; margin-right: 24px; padding-bottom: calc(30px + var(--safe-b));
  }
  #footer .f-base > :first-child, #footer .f-base > :last-child { text-align: center; max-width: none; justify-self: center; }
  /* one clear header row on a phone: the mark left, a menu button right.
     The section links live in a small panel the button opens. */
  #menu-btn {
    display: flex; flex-direction: column; justify-content: center; gap: 7px;
    position: absolute; top: calc(14px + var(--safe-t)); right: 12px;
    width: 44px; height: 44px; padding: 0 10px;
    background: none; border: none; cursor: pointer; pointer-events: auto;
  }
  #menu-btn span {
    display: block; height: 1.5px; background: var(--ink);
    transition: transform .3s cubic-bezier(.16,1,.3,1), opacity .3s;
  }
  #menu-btn span:first-child { width: 24px; }
  #menu-btn span:last-child { width: 16px; }
  body.nav-open #menu-btn span:first-child { transform: translateY(4.25px) rotate(45deg); width: 22px; }
  body.nav-open #menu-btn span:last-child { transform: translateY(-4.25px) rotate(-45deg); width: 22px; }
  #topnav {
    top: calc(64px + var(--safe-t)); right: 0; left: 0; gap: 0;
    flex-direction: column;
    background: rgba(13,13,9,.94);
    border-top: 1px solid rgba(201,164,104,.25);
    border-bottom: 1px solid rgba(247,241,225,.1);
    visibility: hidden; opacity: 0; transform: translateY(-8px);
    transition: opacity .28s cubic-bezier(.16,1,.3,1), transform .28s cubic-bezier(.16,1,.3,1), visibility .28s;
  }
  body.nav-open #topnav { visibility: visible; opacity: 1; transform: none; }
  #topnav button {
    padding: 15px 20px; min-height: 48px; text-align: left;
    border-bottom: 1px solid rgba(247,241,225,.07);
  }
  #topnav button:last-child { border-bottom: none; }
}

/* review aid: ?domonly renders the interface over a transparent ground */
body.domonly { background: transparent; }
body.domonly #gl, body.domonly #grain, body.domonly #vignette, body.domonly #veil { display: none; }
