/* ────────────────────────────────────────────────────────────────
   Basava Silk Creations
   Bone ground, ink type, photography-led. Catalogue, not a store.

   ASAGIRI (asagiri-38matcha.aura.build), measured off the live page.
   The first pass read the extracted tokens and kept Basava's moss ground
   everywhere; that was wrong, and looked it. On the real page the ground is
   bone and carries ~55% of the height. Jade-dark appears exactly twice — under
   the pinned sequence and the numbered grid, ~15% — and ink once, under the
   footer, ~5%. Dark is punctuation here, not the default.

   Color   bone #F4F0E6 / #ECE6D7 / #FBF9F2 · stone #CDBFA6 · ink #23271F
           jade #5F7A52 (accent on light) · jade-dark #3A4A31 (dark bands)
           zari #C9A227 kept as Basava's own mark on saree details
   Type    Instrument Serif (display) · Hanken Grotesk 300 (body, labels, UI)
           EB Garamond (--prose, long-form) · Noto Serif Kannada (all Kannada)
   Ground  Sections inherit a semantic token set; .on-dark and friends
           re-point it, so components are never written twice.
   ──────────────────────────────────────────────────────────────── */

:root{
  /* Asagiri's palette, as measured off the live page rather than the extract.
     The ground is bone and it carries 55% of the page; jade-dark appears only
     under the pinned sequence and the numbered grid (~15%), ink only under the
     footer (~5%). Getting that ratio wrong is what made the first pass read as
     "very green" — the accent treatment had been applied to everything. */
  --bone:#F4F0E6; --bone-2:#ECE6D7; --bone-3:#FBF9F2;
  --stone:#CDBFA6; --stone-d:#A9997D;
  --ink:#23271F; --ink-2:#41463A;
  --jade:#5F7A52; --jade-d:#3A4A31; --jade-l:#86A074;
  --gold:#B89B5E;
  /* Basava's own zari, kept for the saree-specific marks — it is literally the
     colour of the metallic thread the borders are woven with. */
  --zari:#C9A227; --maroon:#6B1F2A;

  /* Semantic layer. Dark bands re-point these rather than restating rules,
     so every component works on either ground without being written twice. */
  --ground:var(--bone);
  --ground-lift:var(--bone-3);
  --text:var(--ink);
  --text-soft:var(--ink-2);
  --text-dim:rgba(35,39,31,.55);
  --heading:var(--ink);
  --accent:var(--jade);
  --rule:rgba(35,39,31,.14);
  --rule-strong:rgba(35,39,31,.26);
  --panel:rgba(35,39,31,.045);

  --display:"Instrument Serif",Georgia,"Times New Roman",serif;
  --sans:"Hanken Grotesk",system-ui,-apple-system,sans-serif;
  --body:"Hanken Grotesk",system-ui,-apple-system,sans-serif;
  --prose:"EB Garamond","Iowan Old Style",Georgia,serif;

  --t-hero:clamp(2.6rem,7.4vw,7rem);
  --t-h1:clamp(2.1rem,5vw,4.4rem);
  --t-h2:clamp(1.8rem,3.8vw,3.2rem);
  --t-h3:clamp(1.1rem,1.7vw,1.5rem);
  --t-lede:clamp(1rem,1.4vw,1.2rem);
  --t-body:1rem;
  --t-label:.72rem;
  --t-eyebrow:.66rem;

  --measure:34em;
  --pad:clamp(22px,6vw,96px);
  --gutter:clamp(32px,6vw,90px);
  --r-sm:3px; --r-md:6px; --r-full:100px;
  --e-standard:cubic-bezier(.25,.1,.25,1);
  --d-sm:.25s; --d-md:.3s; --d-lg:.5s; --d-xl:.8s;
}

/* The only places that go dark, matching Asagiri's own distribution: the
   pinned sequence, the numbered grid, the footer — plus the memorial. */
.on-dark,.band--ink,.ritual,.prov,.site-foot,.hero{
  --ground:var(--jade-d);
  --ground-lift:#2C3826;
  --text:var(--bone);
  --text-soft:var(--bone-2);
  --text-dim:rgba(244,240,230,.6);
  --heading:var(--bone);
  --accent:var(--stone);
  --rule:rgba(244,240,230,.18);
  --rule-strong:rgba(244,240,230,.32);
  --panel:rgba(244,240,230,.06);
}
.band--ink,.site-foot{--ground:var(--ink);--ground-lift:#2C3826}

html[lang="kn"]{
  --display:"Noto Serif Kannada","Cormorant Garamond",Georgia,serif;
  --body:"Noto Serif Kannada","EB Garamond",Georgia,serif;
  --sans:"Noto Serif Kannada","Hanken Grotesk",system-ui,sans-serif;
  --measure:32em;
  --t-eyebrow:.76rem;
  --t-label:.8rem;
}
html[lang="kn"] body{line-height:1.85}
html[lang="kn"] h1,html[lang="kn"] h2,html[lang="kn"] h3{line-height:1.35}
html[lang="kn"] .eyebrow,html[lang="kn"] .btn,html[lang="kn"] .prov span,
html[lang="kn"] .piece .spec,html[lang="kn"] .site-foot h4,
html[lang="kn"] .numgrid span,html[lang="kn"] .step .n,
html[lang="kn"] .worn .role,html[lang="kn"] .press .when,
html[lang="kn"] .awards .when,html[lang="kn"] .award-video-meta{letter-spacing:.06em}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important}
}

body{
  margin:0;background:var(--ground);color:var(--text);
  font-family:var(--body);font-size:var(--t-body);line-height:1.75;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}

/* Instrument Serif ships one weight (400), so headings stop asking for 500. */
h1,h2,h3,h4{margin:0;font-family:var(--display);font-weight:400;line-height:1.06;
  text-wrap:balance;color:var(--heading);letter-spacing:.005em}
h3,h4{line-height:1.2}
/* Each clause of a page's headline is its own block, so the load timeline can
   stagger the lines in. build.mjs breaks them at the author's own asterisks in
   content/*.json — never at a measured position — so no word is cut in half and
   no Kannada conjunct or vowel sign is ever separated from its consonant. */
h1 .hl{display:block}
/* The signature Asagiri move: one clause of the headline set in italic. */
h1 em,h2 em,h3 em,.lede em{font-style:italic;color:var(--accent)}
/* Kannada has no italic tradition, and Noto Serif Kannada ships no italic face —
   the browser would synthesise a slant, which looks like a rendering fault on
   this script. Same accent, carried by colour alone. */
html[lang="kn"] h1 em,html[lang="kn"] h2 em,
html[lang="kn"] h3 em,html[lang="kn"] .lede em{font-style:normal;color:var(--accent)}
p{margin:0;text-wrap:pretty}
ul{margin:0;padding:0;list-style:none}
img{display:block;max-width:100%;height:auto}
a{color:var(--heading)}
:focus-visible{outline:2px solid var(--zari);outline-offset:3px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

.wrap{max-width:1180px;margin:0 auto;padding:0 var(--pad)}
.eyebrow{display:inline-block;font-family:var(--sans);font-size:var(--t-eyebrow);
  letter-spacing:.42em;text-transform:uppercase;color:var(--accent);font-weight:500}
.rule{height:1px;background:var(--rule);border:0;margin:0}

/* Copy still awaiting the family's own words. Visibly unfinished on purpose —
   these must not read as final text. Delete nothing: replacing the source
   string in content/*.json removes the styling automatically. */
.todo{color:var(--text-dim);font-style:italic;
  border-bottom:1px dotted rgba(201,162,39,.5)}

/* ── scroll reveals ────────────────────────────────────────────
   The hidden state is scoped to html.js-motion, which motion.js only sets when
   GSAP is present and reduced motion is not requested. Without that guard a
   failed CDN or a no-JS visitor would be left staring at an invisible page. */
html.js-motion [data-rv]{opacity:0;transform:translateY(52px)}
/* Hairline grids — .press, .checks, .gens — are 1px gaps over a rule-coloured
   backdrop, and the big photo in a .split fills its half exactly. Sliding any
   of those exposes the surface behind it, so they are marked data-rv="fade"
   and only ever change opacity. */
html.js-motion [data-rv="fade"]{transform:none}
/* The entrance block is held back by opacity alone, and not in order to animate
   it — motion.js plays it with .from(), so its resting state in the DOM is
   already the finished state. This exists only to stop a flash of the settled
   hero in the gap between first paint and GSAP arriving. The timeline sets it
   back to 1 as its first act; if the timeline never runs, the head script's
   dead-man switch drops html.js-motion and this rule stops applying. */
html.js-motion [data-entrance]{opacity:0}

/* Print has no scrolling, so nothing would ever cross a trigger and half the
   page would come out of the printer blank. Release every held-back state. */
@media print{
  html.js-motion [data-rv],html.js-motion [data-entrance]{opacity:1 !important;transform:none !important}
}

/* ── Lenis smooth scroll ────────────────────────────────────────
   Lenis drives the real scroll position, so ScrollTrigger needs no proxy. It
   does need the browser's own smooth scrolling out of the way, or the two
   fight over every anchor jump. All of it hangs off html.lenis, a class Lenis
   adds only once motion.js has actually constructed an instance — if the
   library never arrives none of this applies and native scrolling stands.
   Deliberately NOT copying Asagiri's `.lenis iframe{pointer-events:none}`:
   the only iframe here is the map on /contact, and it is meant to be used. */
html.lenis{scroll-behavior:auto}
html.lenis,html.lenis body{height:auto}
html.lenis.lenis-smooth [data-lenis-prevent]{overscroll-behavior:contain}
html.lenis.lenis-stopped{overflow:hidden}

/* ── skip link ── */
.skip{position:absolute;left:-9999px;top:0;z-index:99;background:var(--heading);
  color:var(--ground-lift);padding:12px 20px;text-decoration:none;border-radius:var(--r-full)}
.skip:focus{left:12px;top:12px}

/* ── photo frames ─────────────────────────────────────────────
   A figure either holds a real photograph or, until one exists,
   a labelled panel naming the photograph that belongs there.
   Corners stay square: Asagiri's own image radius profile is square, and
   only its step cards take the 6px. */
.shot{position:relative;margin:0;overflow:hidden;background:var(--panel)}
.shot img{width:100%;height:100%;object-fit:cover}
.shot--empty{display:grid;place-items:center;text-align:center;padding:28px;
  background-image:
    repeating-linear-gradient(90deg,var(--rule) 0 1px,transparent 1px 7px),
    repeating-linear-gradient(0deg,var(--rule) 0 1px,transparent 1px 10px);
  background-blend-mode:multiply}
.shot--empty::after{content:"";position:absolute;inset:14px;border:1px solid var(--rule-strong);
  pointer-events:none}
.shot--empty figcaption{position:relative;max-width:26ch;font-family:var(--sans);font-size:.68rem;
  letter-spacing:.24em;line-height:2.1;text-transform:uppercase;color:var(--text-soft);font-weight:300}

/* ── header ── */
.site-head{position:sticky;top:0;z-index:20;background:rgba(244,240,230,.86);backdrop-filter:blur(10px);
  border-bottom:1px solid var(--rule);transition:background var(--d-lg) var(--e-standard)}
.head-row{display:flex;align-items:center;justify-content:space-between;gap:20px;
  padding:18px 0;flex-wrap:wrap}
.mark{display:inline-flex;align-items:baseline;gap:11px;text-decoration:none;color:var(--heading)}
.mark img{max-height:44px;width:auto}
.mark b{font-family:var(--display);font-size:1.55rem;font-weight:400;letter-spacing:.14em}
.mark .slot{font-family:var(--sans);font-size:.58rem;letter-spacing:.24em;text-transform:uppercase;
  color:var(--text-soft);border:1px dashed var(--rule-strong);padding:4px 8px;
  border-radius:var(--r-full);font-weight:300}
.head-right{display:flex;align-items:center;gap:clamp(18px,3vw,34px);flex-wrap:wrap}
.site-nav ul{display:flex;gap:clamp(16px,2.4vw,32px);flex-wrap:wrap}
.site-nav a{font-family:var(--sans);font-size:.8rem;font-weight:300;letter-spacing:.14em;
  text-transform:uppercase;text-decoration:none;color:var(--text);padding:4px 0;
  border-bottom:1px solid transparent;transition:color var(--d-md) var(--e-standard)}
.site-nav a:hover{border-bottom-color:var(--zari)}
.site-nav a[aria-current="page"]{color:var(--heading);border-bottom-color:var(--heading)}
.lang{font-family:var(--sans);font-size:.7rem;font-weight:300;letter-spacing:.18em;
  text-transform:uppercase;text-decoration:none;color:var(--text-soft);
  border:1px solid var(--rule-strong);padding:8px 16px;white-space:nowrap;
  border-radius:var(--r-full);transition:all var(--d-md) var(--e-standard)}
.lang:hover{color:var(--ground-lift);background:var(--heading);border-color:var(--heading)}

/* ── buttons — Asagiri's pill ── */
.btn{display:inline-flex;align-items:center;gap:.6rem;font-family:var(--sans);
  font-size:var(--t-label);font-weight:300;letter-spacing:.18em;text-transform:uppercase;
  text-decoration:none;padding:.95rem 1.9rem;border-radius:var(--r-full);
  border:1px solid transparent;cursor:pointer;
  /* Named properties rather than `all`. The hero buttons are animated in by the
     load timeline, which writes opacity and transform inline — and `all` would
     transition into those written values, so the buttons visibly faded out and
     dropped before their own entrance played. Only the three colours actually
     change on hover, so only those need to be transitioned. */
  transition:background-color var(--d-md) var(--e-standard),
             border-color var(--d-md) var(--e-standard),
             color var(--d-md) var(--e-standard)}
/* Solid fill inverts against whatever ground it sits on; the ghost borrows the
   rule colour so it works on bone and on jade-dark without a variant. */
.btn--fill{background:var(--ink);color:var(--bone)}
.btn--fill:hover{background:var(--jade-d)}
.on-dark .btn--fill,.hero .btn--fill{background:var(--bone);color:var(--ink)}
.on-dark .btn--fill:hover,.hero .btn--fill:hover{background:#fff}
.btn--ghost{color:var(--text);background:transparent;border-color:var(--rule-strong)}
.btn--ghost:hover{background:var(--panel);border-color:var(--text)}
.btn--wa{border-color:#2E9E52;background:#2E9E52;color:#fff}
.btn--wa:hover{background:#25843F;border-color:#25843F}
.btn--wa svg{flex:none}

/* ── hero ── */
.hero{position:relative;display:grid;place-items:center;text-align:center;
  min-height:clamp(460px,80vh,760px);padding:clamp(64px,10vw,96px) var(--pad)}
/* The home hero runs the full height of the screen. svh rather than vh so the
   mobile URL bar collapsing does not shove the buttons off-screen. The copy is
   bottom-weighted on purpose: the weaver sits in the upper half of the frame,
   and centred type lands straight across his face. */
.hero:not(.hero--page){
  min-height:100vh;min-height:100svh;
  align-items:end;padding-bottom:clamp(56px,9vh,112px)}

/* …and the header floats over it, so "full screen" really is the whole screen.
   Subtracting the header height instead would need a magic number per
   breakpoint, and the header is not a predictable height — it is 76px wide-
   screen, 115px on a phone, but 135px around 700px where it wraps onto three
   rows. Taking it out of flow sidesteps all of that. The hero's own scrim
   already lays down enough contrast at the top for the nav to read. Interior
   pages, which have no full-height hero, keep the solid sticky bar.
   Floating over a photograph, it also has to invert: the bar is bone with ink
   type everywhere else, but bone type here. The .on-dark token set does that
   in one line rather than restating every nav rule. */
body:has(.hero:not(.hero--page)) .site-head{
  position:absolute;top:0;left:0;right:0;
  background:transparent;border-bottom-color:transparent;
  --text:var(--bone);--text-soft:var(--bone-2);--heading:var(--bone);
  --rule-strong:rgba(244,240,230,.32)}
.hero .shot{position:absolute;inset:0;padding:0}
.hero .shot::after{inset:26px}
/* A hero always carries bone type, because it always sits on a photograph.
   Until that photograph exists the placeholder has to hold the same ground —
   left tinted from the page it would be bone-on-bone, and the headline would
   simply vanish. */
.hero .shot--empty{background:var(--ink)}
/* The weaver sits high in the frame, so a wide viewport has to hold the top of
   the photograph: centre it and his forehead crops away, and the headline —
   which lands mid-height — falls across his face instead of his chest. */
.hero .shot img{filter:brightness(.82) saturate(.94);object-position:50% 8%}
/* A gradient scrim rather than a flat brightness knock-down: the photograph
   keeps its highlights and the type still clears contrast. Only once a real
   photograph is in place — over a placeholder panel this would dim the label
   that is the whole point of the panel. */
.hero:not(:has(.shot--empty))::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(118% 86% at 50% 40%,rgba(36,37,28,.04) 0%,rgba(36,37,28,.48) 58%,rgba(36,37,28,.80) 100%),
    /* The ghost button sits low over a sunlit kurta, so the bottom of the ramp
       has to carry most of the contrast on its own. */
    linear-gradient(180deg,rgba(36,37,28,.58) 0%,rgba(36,37,28,.08) 24%,rgba(36,37,28,.42) 58%,rgba(36,37,28,.72) 80%,rgba(36,37,28,.90) 100%);
}
.hero .shot--empty figcaption{position:absolute;left:clamp(24px,5vw,58px);bottom:clamp(24px,4vw,44px);
  max-width:30ch;text-align:left;font-size:.64rem;letter-spacing:.2em;line-height:2;opacity:.75}
/* While a hero photo is still missing, its caption sits in the bottom-left
   corner. Reserve room for it so it never collides with the buttons above.
   Once a real image lands the caption disappears and so does this padding. */
.hero:has(.shot--empty){padding-bottom:clamp(150px,18vw,210px)}
.hero-copy{position:relative;z-index:1;max-width:960px}
.hero h1{font-size:var(--t-hero);letter-spacing:-.012em;line-height:.98}
.hero .lede{font-family:var(--body);font-style:italic;font-size:var(--t-lede);line-height:1.6;
  color:var(--text);max-width:38em;margin:26px auto 36px}
.hero-cta{display:flex;gap:14px;justify-content:center;flex-wrap:wrap}
/* Over a photograph the outlined button needs a ground of its own: a scrim
   tuned for the type still leaves this sitting on a sunlit kurta. */
.hero .btn--ghost{background:rgba(35,39,31,.42);backdrop-filter:blur(3px);border-color:rgba(244,240,230,.5)}
.hero .btn--ghost:hover{background:rgba(244,240,230,.18);border-color:var(--bone)}

/* Interior pages get a shorter, left-aligned hero. */
.hero--page{min-height:clamp(320px,52vh,520px);text-align:left;justify-items:start}
.hero--page .hero-copy{max-width:44rem}
.hero--page h1{font-size:var(--t-h1);margin-top:16px;line-height:1.02}
.hero--page .lede{margin:22px 0 0;font-size:var(--t-lede);text-align:left}
.hero--page .wrap{width:100%}

/* ── section rhythm ── */
.band{padding:clamp(72px,10vw,132px) 0}
.band--lift{background:var(--bone-3)}
.band--deep{background:var(--bone-2)}
.band--ink{background:var(--ink)}
.head-block{max-width:var(--measure);margin-bottom:clamp(40px,5vw,64px)}
.head-block h1{font-size:var(--t-h1);margin-top:18px}
.head-block h2{font-size:var(--t-h2);margin-top:18px}
.head-block p{color:var(--text-soft);margin-top:20px}

/* ── split panel: the story's repeating unit ── */
.split{display:grid;grid-template-columns:1fr 1fr;align-items:stretch}
.split .pane{display:flex;flex-direction:column;justify-content:center;gap:20px;
  padding:clamp(56px,8vw,96px) var(--gutter)}
.split .pane > p{max-width:var(--measure);color:var(--text)}
.split h2{font-size:var(--t-h2)}
.split .shot{min-height:clamp(320px,52vw,620px)}
.split--flip .pane{order:2}
.split .btn{align-self:start;margin-top:10px}

/* ── four generations ── */
.gens{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--rule-strong)}
.gen{background:var(--ground);padding:clamp(26px,3vw,34px) clamp(22px,2.4vw,28px);
  display:flex;flex-direction:column;gap:9px}
.band--lift .gen{background:var(--ground-lift)}
.gen .roman{font-family:var(--sans);font-size:.7rem;letter-spacing:.34em;color:var(--zari);
  font-weight:500}
.gen h3{font-size:var(--t-h3)}
.gen p{font-size:.97rem;color:var(--text-soft)}

/* ── craft notes ── */
.notes{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(32px,4vw,44px) clamp(28px,3vw,40px)}
.notes .shot{aspect-ratio:4/3;margin-bottom:20px}
.notes h3{font-size:var(--t-h3);margin-bottom:9px}
.notes p{font-size:1rem;color:var(--text-soft)}

/* ── the pinned craft sequence ────────────────────────────────
   Asagiri's `.ritual`: a horizontal track of steps that scrubs sideways while
   the section is pinned. Built the other way round from the original — the
   default here is a plain scroll-snap row that works with no JS at all, and
   motion.js upgrades it to the pinned scrub by adding .is-pinned. Fall back,
   and you still get a usable, swipeable sequence rather than a broken one. */
/* Owns its vertical rhythm rather than borrowing .band's — when pinned the
   section is exactly 100vh, and band padding would eat a third of it. */
.ritual{background:var(--ground);position:relative;padding:clamp(72px,10vw,132px) 0}
.ritual-head{margin-bottom:clamp(28px,4vw,44px)}
.ritual-head h2{font-size:var(--t-h2);margin-top:16px}
.track-wrap{overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.track-wrap::-webkit-scrollbar{display:none}
.track{display:flex;gap:clamp(1.5rem,3vw,3rem);padding:0 var(--pad) clamp(24px,4vw,40px)}
.step{background:var(--ground-lift);flex:0 0 auto;width:min(76vw,520px);scroll-snap-align:center;position:relative;
  border-radius:var(--r-md);overflow:hidden;
  display:flex;flex-direction:column}
.step .shot{aspect-ratio:4/5;flex:none}
.step-body{padding:clamp(20px,2.6vw,30px)}
.step .n{display:block;font-family:var(--sans);font-size:.66rem;letter-spacing:.34em;
  text-transform:uppercase;color:var(--zari);font-weight:500;margin-bottom:12px}
.step h3{font-size:var(--t-h3);margin-bottom:10px}
.step p{font-size:.96rem;color:var(--text-soft)}
.step--intro{background:transparent;justify-content:center}
.step--intro .step-body{padding-left:0}
.step--intro p{font-family:var(--body);font-style:italic;font-size:var(--t-lede);color:var(--text)}

/* The pinned upgrade. Only ever applied by motion.js, and only above 940px. */
html.js-motion .ritual.is-pinned{height:100vh;padding:clamp(40px,6vh,80px) 0;
  display:flex;flex-direction:column;justify-content:center;overflow:hidden}
html.js-motion .ritual.is-pinned .track-wrap{flex:1;min-height:0;overflow:hidden;
  scroll-snap-type:none}
html.js-motion .ritual.is-pinned .track{height:100%;align-items:stretch;will-change:transform}
html.js-motion .ritual.is-pinned .step{height:100%}
html.js-motion .ritual.is-pinned .step .shot{flex:1;aspect-ratio:auto}

/* ── numbered checklist (how to spot a genuine Ilkal) ── */
.checks{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--rule-strong)}
.checks li{background:var(--ground);padding:clamp(24px,3vw,32px);display:flex;gap:18px;
  font-size:1rem;color:var(--text)}
.band--lift .checks li{background:var(--ground-lift)}
.checks .n{font-family:var(--sans);font-size:.72rem;font-weight:500;letter-spacing:.2em;
  color:var(--zari);flex:none;font-variant-numeric:tabular-nums;padding-top:.45em}
/* Variant carrying a heading per point, for the manufacturer argument. */
.checks--titled li{flex-direction:row;align-items:baseline}
.checks--titled b{display:block;font-family:var(--display);font-weight:400;font-size:var(--t-h3);
  color:var(--heading);margin-bottom:10px;line-height:1.16}
.checks--titled span:last-child{color:var(--text-soft)}
.band--deep .checks li{background:var(--ground-lift)}

/* ── glossary ── */
.gloss{display:grid;grid-template-columns:repeat(2,1fr);column-gap:clamp(32px,5vw,64px)}
.gloss div{display:grid;grid-template-columns:minmax(9em,auto) 1fr;gap:6px 24px;
  padding:20px 0;border-top:1px solid var(--rule)}
.gloss dt{font-family:var(--display);font-size:1.28rem;color:var(--heading)}
.gloss dd{margin:0;font-size:.97rem;color:var(--text-soft)}

/* The FAQ borrows the glossary's rules and rhythm, but a question is a sentence
   rather than a term: one column throughout, and the answer sits under the
   question instead of beside it.
   Doubled class on purpose. The breakpoint below sets .gloss back to two columns
   and it sits later in the file, so a single .gloss--faq would tie on
   specificity and lose. .gloss.gloss--faq outranks it at every width. */
.gloss.gloss--faq,.gloss.gloss--faq div{grid-template-columns:1fr}
.gloss.gloss--faq div{gap:10px;padding:24px 0}
.gloss.gloss--faq dt{font-size:1.34rem;max-width:36em}
.gloss.gloss--faq dd{max-width:54em;line-height:1.72}

/* ── collection ── */
.coll{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(38px,5vw,52px) clamp(24px,3vw,34px)}
.piece .shot{aspect-ratio:3/4;margin-bottom:18px}
.piece h3{font-size:var(--t-h3)}
.piece .spec{font-family:var(--sans);font-size:.66rem;font-weight:300;letter-spacing:.24em;
  text-transform:uppercase;color:var(--stone);margin:9px 0 12px}
.piece p{font-size:.97rem;color:var(--text-soft);margin-bottom:14px}
.piece .enq{display:inline-block;font-family:var(--sans);font-size:.68rem;font-weight:300;
  letter-spacing:.18em;text-transform:uppercase;text-decoration:none;color:var(--heading);
  border-bottom:1px solid var(--rule-strong);padding-bottom:4px;
  transition:all var(--d-md) var(--e-standard)}
.piece .enq:hover{color:var(--zari);border-bottom-color:var(--zari)}
.coll-note{margin-top:clamp(40px,5vw,56px);padding-top:24px;border-top:1px solid var(--rule);
  font-style:italic;color:var(--text-soft);max-width:48em}

/* ── in memoriam ───────────────────────────────────────────────
   A quiet panel on the darkest ground the palette has. Deliberately
   narrower and calmer than the sections around it. */
.memoriam{display:grid;grid-template-columns:minmax(0,240px) 1fr;
  gap:clamp(26px,4vw,54px);align-items:start;max-width:56em}
.memoriam-shot{aspect-ratio:3/4}
.memoriam h2{font-size:clamp(1.6rem,3vw,2.4rem);margin-top:14px}
.memoriam .dates{font-family:var(--sans);font-size:.68rem;font-weight:300;letter-spacing:.28em;
  text-transform:uppercase;color:var(--zari);margin:14px 0 22px}
.memoriam p{color:var(--text-soft);margin-bottom:16px;max-width:var(--measure)}
.memoriam .credit{margin:24px 0 0;padding-top:18px;border-top:1px solid var(--rule);
  font-style:italic;font-size:.92rem;color:var(--text-dim)}

/* ── worn by ───────────────────────────────────────────────────
   The Kolhapur alankar leads on a panel of its own; the public
   figures follow in an even grid so no one is ranked above another. */
.sub-head{font-size:clamp(1.4rem,2.8vw,2rem);margin-bottom:clamp(24px,3vw,34px)}

.worn-lead{display:grid;grid-template-columns:minmax(0,.9fr) 1fr;gap:clamp(28px,4vw,60px);
  align-items:center;margin-bottom:clamp(46px,6vw,72px)}
.worn-lead .shot{aspect-ratio:4/5}
.worn-lead-copy{display:flex;flex-direction:column;gap:13px}
.worn-lead-copy h3{font-size:clamp(1.6rem,3.2vw,2.4rem)}
.worn-lead-copy p{color:var(--text-soft);max-width:var(--measure)}

.worn{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(24px,3vw,34px)}
/* Three brothers, not four names — the grid narrows so the portraits stay
   the same weight as the ones on the Recognition page. */
.worn--three{grid-template-columns:repeat(3,1fr);max-width:64em}
.worn .shot{aspect-ratio:3/4;margin-bottom:16px}
.worn h3,.worn h4{font-size:var(--t-h3)}
.worn .role{font-family:var(--sans);font-size:.64rem;font-weight:300;letter-spacing:.2em;
  text-transform:uppercase;color:var(--zari);margin:10px 0 12px;line-height:1.8}
.worn .note{font-size:.94rem;color:var(--text-soft)}
.today-close{margin-top:clamp(36px,4vw,48px);padding-top:22px;border-top:1px solid var(--rule);
  font-style:italic;color:var(--text-soft);max-width:48em}

/* ── awards ────────────────────────────────────────────────────
   Same panel-then-list shape as "worn by" above it, so the page keeps one
   rhythm — but the panel is landscape rather than portrait, because its
   photograph doubles as the poster for a 16:9 video. */
.award-lead{display:grid;grid-template-columns:minmax(0,1.25fr) 1fr;gap:clamp(28px,4vw,60px);
  align-items:center;margin-bottom:clamp(38px,4.5vw,56px)}
.award-lead-copy{display:flex;flex-direction:column;gap:13px}
.award-lead-copy h3{font-size:clamp(1.6rem,3.2vw,2.4rem)}
.award-lead-copy p{color:var(--text-soft);max-width:var(--measure)}

/* The video facade. Still an anchor to YouTube at this point — the few lines in
   footer() swap it for a player on click — so the report is reachable with no
   JS, and nothing third-party is fetched until someone asks for it. */
.award-video{position:relative;display:block;text-decoration:none;
  border-radius:var(--r-md);overflow:hidden;background:var(--ink)}
.award-video .shot{aspect-ratio:16/9;margin:0}
.award-video img{transition:transform var(--d-xl) var(--e-standard)}
.award-video:hover img{transform:scale(1.03)}
/* The label sits over a lit stage, so it cannot rely on the photograph being
   dark where it lands — same reasoning as the hero scrim. */
.award-video::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(35,39,31,0) 40%,rgba(35,39,31,.30) 62%,rgba(35,39,31,.82) 100%)}
.award-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:1;
  width:clamp(52px,5.6vw,70px);aspect-ratio:1;border-radius:50%;
  background:rgba(244,240,230,.92);display:grid;place-items:center;
  transition:transform var(--d-md) var(--e-standard),background var(--d-md) var(--e-standard)}
.award-play::before{content:"";width:0;height:0;border-style:solid;margin-left:4px;
  border-width:9px 0 9px 15px;border-color:transparent transparent transparent var(--ink)}
.award-video:hover .award-play{background:var(--bone);transform:translate(-50%,-50%) scale(1.06)}
.award-video-copy{position:absolute;z-index:1;display:flex;flex-direction:column;gap:5px;
  left:clamp(18px,2.4vw,28px);bottom:clamp(15px,2vw,22px);right:clamp(18px,2.4vw,28px)}
.award-video-label{font-family:var(--display);font-size:clamp(1.05rem,1.7vw,1.3rem);
  line-height:1.25;letter-spacing:.01em;color:var(--bone);
  transition:color var(--d-md) var(--e-standard)}
.award-video:hover .award-video-label{color:var(--zari)}
.award-video-meta{font-family:var(--sans);font-size:.64rem;font-weight:300;letter-spacing:.24em;
  text-transform:uppercase;color:rgba(244,240,230,.78)}
/* What the facade becomes. It replaces the anchor, so it inherits the same
   grid cell and has to carry the same shape itself. */
.award-frame{display:block;width:100%;aspect-ratio:16/9;border:0;
  border-radius:var(--r-md);background:var(--ink)}

/* Rows, not cells — a grid fed a variable number of items shows its empty
   cells as a slab of the container's own background. Borrows the glossary's
   rules and rhythm: metadata left, the award itself right. */
.awards{display:grid}
.awards li{border-top:1px solid var(--rule);padding:clamp(22px,2.6vw,30px) 0;
  display:grid;grid-template-columns:minmax(0,16em) 1fr;
  column-gap:clamp(28px,4vw,56px);row-gap:9px;align-items:baseline}
.awards .pub{grid-area:1/1;font-family:var(--display);font-size:1.24rem;
  letter-spacing:.03em;color:var(--zari)}
.awards h3{grid-area:1/2;font-size:1.16rem;line-height:1.34}
.awards .when{grid-area:2/1;font-family:var(--sans);font-size:.64rem;font-weight:300;
  letter-spacing:.24em;text-transform:uppercase;color:var(--text-dim);line-height:1.9}
.awards .note{grid-area:2/2;font-size:.94rem;color:var(--text-soft);max-width:48em}

/* ── media coverage ── */
.press{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--rule-strong)}
.press li{background:var(--ground);padding:clamp(26px,3vw,36px);
  display:flex;flex-direction:column;gap:11px}
.band--lift .press li{background:var(--ground-lift)}
.band--deep .press li{background:var(--ground-lift)}
.press .pub{font-family:var(--display);font-size:1.24rem;letter-spacing:.03em;color:var(--zari)}
.press h3{font-size:1.16rem;line-height:1.34}
.press h3 a{text-decoration:none;border-bottom:1px solid var(--rule-strong);padding-bottom:2px}
.press h3 a:hover{color:var(--zari);border-bottom-color:var(--zari)}
.press .note{font-size:.9rem;color:var(--text-soft)}
/* Date sits on the baseline of the card whatever the headline length. */
.press .when{font-family:var(--sans);font-size:.64rem;font-weight:300;letter-spacing:.24em;
  text-transform:uppercase;color:var(--text-soft);margin-top:auto;padding-top:16px}

/* ── provenance strip — Asagiri's numbered grid ────────────────
   Same markup as before; restyled as `.numgrid`: no dividing rules, big serif
   numerals, wide-tracked sans labels beneath, centred on the deep ground. */
.prov{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(28px,4vw,48px);
  background:var(--ground);padding:clamp(64px,8vw,104px) var(--pad);
  max-width:1180px;margin:0 auto;text-align:center}
.prov div{background:none;padding:0}
.prov b{display:block;font-family:var(--display);font-size:clamp(2rem,4vw,3.4rem);
  font-weight:400;color:var(--heading);margin-bottom:14px;line-height:1.04}
.prov span{font-family:var(--sans);font-size:var(--t-eyebrow);font-weight:300;
  letter-spacing:.28em;text-transform:uppercase;color:var(--stone)}

/* ── closing call ── */
.close-call{text-align:center;max-width:44em;margin:0 auto}
.close-call h2{font-size:var(--t-h2)}
.close-call p{color:var(--text-soft);margin:20px 0 34px}

/* ── contact ── */
.contact-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(40px,6vw,80px);align-items:start}
.contact-block + .contact-block{margin-top:40px}
.contact-block h2,.contact-block h3{font-size:var(--t-h3);margin-bottom:16px}
.contact-block address{font-style:normal;color:var(--text);line-height:2}
.contact-block ul li{padding:7px 0;color:var(--text)}
/* Scoped away from anything that brings its own box. Unqualified, this rule is
   (0,1,1) and beat .btn's padding — the WhatsApp button kept its 15.2px top pad
   but got 2px at the bottom, sitting its label visibly low in the pill. The
   underline it also forced was invisible there only because .btn--wa paints the
   border the same green as the fill. */
.contact-block a:not(.btn):not(.place){text-decoration:none;
  border-bottom:1px solid var(--rule-strong);padding-bottom:2px}
.contact-block a:not(.btn):not(.place):hover{color:var(--zari);border-bottom-color:var(--zari)}
.contact-actions{display:flex;gap:14px;flex-wrap:wrap;margin-top:26px}
.reply-note{margin-top:16px;font-size:.9rem;font-style:italic;color:var(--text-soft)}
/* No CSS filter on this one: it is a Google Maps frame, and their terms do not
   allow altering how the map itself is presented. The border and radius are
   ours, the pixels inside are theirs. */
.map{border:1px solid var(--rule-strong);border-radius:var(--r-md);width:100%;aspect-ratio:4/3}

/* ── the address, as a link to the Google Maps listing ── */
.place,.foot-place{display:block;text-decoration:none;border-bottom:0}
.place address,.foot-place address{font-style:normal}
.place-cue{display:inline-flex;align-items:center;gap:7px;margin-top:14px;
  font-family:var(--sans);font-size:.8rem;font-weight:300;letter-spacing:.06em;
  color:var(--accent);border-bottom:1px solid currentColor;padding-bottom:3px;
  transition:color var(--d-md) var(--e-standard)}
.place-cue svg{flex:none}
.place address{color:var(--text);line-height:2}
.place:hover address,.foot-place:hover address{color:var(--zari)}
.place:hover .place-cue,.foot-place:hover .place-cue{color:var(--zari)}
.foot-place address{color:var(--text-soft);line-height:1.95}
.foot-place .place-cue{color:var(--stone)}
/* Kannada has no italic and hates tracking — see the html[lang="kn"] block.
   Noto Serif Kannada ships no italic face, so an unguarded font-style:italic
   gets synthesised into a sheared oblique that mangles the conjuncts. Every
   italic rule needs its counterpart here. */
html[lang="kn"] .place-cue{letter-spacing:.02em}
html[lang="kn"] .reply-note{font-style:normal}
.tips li{display:flex;gap:16px;padding:14px 0;border-top:1px solid var(--rule);color:var(--text-soft)}
.tips .n{font-family:var(--sans);font-size:.72rem;font-weight:500;letter-spacing:.2em;
  color:var(--zari);flex:none;font-variant-numeric:tabular-nums;padding-top:.5em}

/* ── footer ──
   Asagiri's silhouette: the wordmark alone on the left with room to breathe,
   the link columns gathered into a tight block hard against the right edge, and
   a wide gap between the two. Four evenly-spread columns — what this was — fills
   the width but says nothing; the imbalance is the whole composition. */
.site-foot{background:var(--ink);border-top:1px solid var(--rule);
  padding:clamp(56px,6vw,76px) 0 40px}
.foot-grid{display:grid;grid-template-columns:minmax(240px,1fr) auto;
  gap:clamp(40px,6vw,96px);align-items:start}
/* auto-width columns, so the group is only as wide as its content and sits
   flush right rather than stretching to fill. */
.foot-cols{display:grid;grid-template-columns:repeat(3,minmax(0,max-content));
  gap:clamp(28px,4vw,56px)}
.foot-cols > div{min-width:0;max-width:19em}

.site-foot h3{font-size:clamp(1.7rem,3.4vw,2.5rem);margin-bottom:16px;letter-spacing:.01em}
/* Weight 300 and .24em, off the reference. The 500 this was reads as a label
   shouting over the links below it; at 300 the head recedes and the column
   reads as one thing. */
.site-foot h4{font-family:var(--sans);font-size:var(--t-eyebrow);font-weight:300;letter-spacing:.24em;
  text-transform:uppercase;color:var(--stone);margin-bottom:20px}
.foot-brand p{color:var(--text-soft);max-width:28em;font-size:.94rem;line-height:1.8}
.site-foot ul{display:flex;flex-direction:column;gap:10px}
.site-foot li{color:var(--text-soft)}
.site-foot a{text-decoration:none;color:var(--text);transition:color var(--d-md) var(--e-standard)}
.site-foot a:hover{color:var(--zari)}
/* The link columns sit back at 72% rather than full bone: on this ground a
   column of solid cream reads as loud as the wordmark, and the reference keeps
   the hierarchy by dimming the links, not by shrinking the head. */
.foot-cols a{font-size:.86rem;font-weight:300;line-height:1.5;color:rgba(244,240,230,.72)}
.foot-cols a:hover{color:var(--zari)}
/* Same size and tone as the links, but the address keeps its own looser leading
   — four stacked lines at the link rhythm read as a list, not an address. */
.foot-place address{font-size:.86rem;font-weight:300;line-height:1.8;
  color:rgba(244,240,230,.72)}

/* The map plate, filling the space the wordmark leaves under it. */
.foot-map{margin-top:clamp(24px,2.6vw,30px);max-width:296px}
/* Direct child only: the credit below carries its own <a>, and the plate rules
   (line-height:0, the border) would collapse that link's text to nothing. */
.foot-map>a{display:block;line-height:0;border-radius:var(--r-sm);overflow:hidden;
  border:1px solid var(--rule);transition:border-color var(--d-md) var(--e-standard)}
.foot-map>a:hover{border-color:var(--zari)}
.foot-map img{width:100%;height:auto;
  transition:transform var(--d-xl) var(--e-standard)}
.foot-map>a:hover img{transform:scale(1.04)}
/* Matched to .foot-fine — the two smallest lines in the footer should agree.
   Scoped through .foot-brand to outrank `.foot-brand p`, which is a class plus
   an element and would otherwise win on specificity and hand this the tagline's
   .94rem body size. */
.foot-brand .foot-map-credit{margin-top:9px;font-family:var(--sans);font-size:.6rem;
  font-weight:300;letter-spacing:.04em;line-height:1.6;color:var(--stone-d)}
.foot-map-credit a{color:inherit}

/* Sentence case, near-zero tracking, warm --stone-d. Uppercase at .16em is what
   made this line shout; the reference sets the same .66rem in plain sentence
   case and lets it sit quietly under the rule. Kannada gains here too — it has
   no case for uppercase to act on, and the tracking was mangling it. */
.foot-fine{display:flex;justify-content:space-between;gap:18px;flex-wrap:wrap;
  margin-top:clamp(40px,5vw,56px);padding-top:22px;border-top:1px solid var(--rule);
  font-family:var(--sans);font-size:.66rem;font-weight:300;letter-spacing:.04em;
  color:var(--stone-d)}

/* ── responsive ─────────────────────────────────────────────── */
@media (max-width:940px){
  .split,.split--flip{grid-template-columns:1fr}
  .split .pane,.split--flip .pane{order:0}
  .split .shot{min-height:min(64vw,380px)}
  .gens,.notes,.coll,.prov,.checks,.gloss,.contact-grid{grid-template-columns:repeat(2,1fr)}
  .worn,.press{grid-template-columns:repeat(2,1fr)}
  .memoriam{grid-template-columns:1fr;max-width:44em}
  .memoriam-shot{max-width:200px}
  .worn-lead{grid-template-columns:1fr;gap:26px}
  /* The video keeps its 16:9 and goes full width; the copy follows it, because
     a poster you are being asked to click should not be the second thing. */
  .award-lead{grid-template-columns:1fr;gap:26px}
  /* Stays portrait when the panel stacks. The landscape crop this used to take
     was shaped for the placeholder; the actual Kolhapur photograph is 3:4, and
     16/10 threw away half of it — the top of the prabhavali and, worse, the
     drape of the saree the panel exists to show. Full width at 4/5 is tall on a
     phone, and that is the correct trade for the one photograph on this page
     that is evidence rather than decoration. */
  .worn-lead .shot{aspect-ratio:4/5;max-width:420px}
  /* The two halves stack, and the column group stops hugging the right edge and
     goes back to filling the width it now has to itself. */
  .foot-grid{grid-template-columns:1fr}
  .foot-cols{grid-template-columns:repeat(3,1fr)}
  .foot-cols > div{max-width:none}
  .foot-map{max-width:400px}
  .gloss div{grid-template-columns:1fr}
  /* Never pin below this width: pinning a full-height section on a phone traps
     the scroll and is the single most complained-about scroll pattern there is. */
  html.js-motion .ritual.is-pinned{height:auto;display:block}
  html.js-motion .ritual.is-pinned .track-wrap{overflow-x:auto;scroll-snap-type:x mandatory}
  html.js-motion .ritual.is-pinned .track{height:auto;transform:none !important}
  html.js-motion .ritual.is-pinned .step,
  html.js-motion .ritual.is-pinned .step .shot{height:auto}
  html.js-motion .ritual.is-pinned .step .shot{aspect-ratio:4/5;flex:none}
}
@media (max-width:640px){
  /* A sticky header that wraps onto three rows costs too much of a small
     screen, so on phones it scrolls away and nav sits on one line with
     the language toggle. */
  .site-head{position:static}
  .head-row{gap:12px;padding:14px 0}
  .head-right{width:100%;justify-content:space-between;gap:12px}
  .site-nav{min-width:0;flex:1}
  .site-nav ul{gap:13px;flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
  .site-nav ul::-webkit-scrollbar{display:none}
  /* Uppercase and tracked, six items no longer fit a phone at the desktop size.
     The row still scrolls, but a nav that visibly cuts "CONTA…" reads as broken
     rather than swipeable, so it is sized to fit instead. */
  .site-nav a{font-size:.6rem;letter-spacing:.05em;white-space:nowrap}
  .lang{flex:none;padding:6px 12px;font-size:.62rem}
  .coll,.notes,.gens,.prov,.checks,.contact-grid{grid-template-columns:1fr}
  /* .worn stays two-up on phones — one portrait per row is overbearing. */
  .press{grid-template-columns:1fr}
  /* A 16em metadata column and a headline cannot share 320px. The row stacks,
     and the date moves under the award it belongs to rather than floating
     above it in a column that is no longer there. */
  .awards li{grid-template-columns:1fr;row-gap:7px}
  .awards .pub{grid-area:auto}
  .awards h3{grid-area:auto}
  .awards .note{grid-area:auto}
  .awards .when{grid-area:auto;margin-top:4px}
  .gloss{grid-template-columns:1fr}
  /* Explore and Reach us pair up; Visit takes the full width below them,
     because the four address lines are what break first in a narrow column. */
  .foot-cols{grid-template-columns:1fr 1fr;gap:32px 28px}
  .foot-cols > div:nth-child(2){grid-column:1/-1;order:1}
  .hero .lede{font-size:1.02rem}
  .eyebrow{letter-spacing:.3em}
  .step{width:82vw}
}
