/* ════════════════════════════════════════════════════════════════════════════
   toUnknown · Анапанасати — v3
   ────────────────────────────────────────────────────────────────────────────
   Same course, same words, same photographs. Black end to end, the way the
   original is, built as an iPhone app rather than a page.

   The four references, each governing the layer it is actually good at:

   · iOS 16 UI Kit (Figma, EAoV0hhaac9Rr8dZ5uIp5u) — the chrome. Tab bar with
     icon over label on a blurred material; large-title collapse; inset-grouped
     lists whose separators start at the text edge, never the card edge; 44pt
     minimum targets; the system spring.
   · Aman — the air. A very fine serif at display sizes, micro-labels
     letterspaced to a whisper, and photography that fades out instead of
     stopping on a line.
   · Hyris (U1CORE) — the data. Hairline rows read label-left / value-right on
     night panels; section heads set small and wide rather than large and loud.
   · Meditation app kits — the softness: large radii, calm cards, nothing sharp.

   ── what changed from v2, and why ──────────────────────────────────────────
   v2 alternated night and paper. That broke two things at once: eleven of the
   twelve gain icons are pure white line art (measured luma 255) and vanished on
   the white cards, and the alternation fought the original, which is black
   throughout. v3 is black throughout, so white line art reads everywhere.

   The exception is deliberate: pkg-uchenik and pkg-master are near-black
   artwork (luma 5 and 26). Those two cards stay white — the one light surface
   in the app, which is also where the eye should land.

   Type is Alumni Sans for titles and for the sacred lines, Onest for text —
   two families — see the TYPE BRANDBOOK block below, which is the only place a size
   or a face is decided.

   The page is an app: twelve screens grouped into five tabs, switched rather
   than scrolled. See the .scr[data-tab] rules and the runtime in index.html.
   ════════════════════════════════════════════════════════════════════════════ */

:root{
  /* ══ TWO TEMPERATURES ════════════════════════════════════════════════
     The teal was already here — the dharma wheel is #00748C — but it was an
     orphan: the one cool thing on a warm page. It becomes the air instead.

       BLUE is the world. The ground, the glass, the scrims behind
            photography, the deep places. You do not touch it.
       GOLD is the hand. Labels, buttons, the price, the Buddha's light.
            Everything you can act on, and nothing you cannot.

     That is the luxury-marque split: a deep blue body, warm metal on the
     details your hand actually meets. The ground below is not blue so much
     as it is *not neutral* — barely enough cast to feel cool, never enough
     to read as a colour. */
  --sea:#00748C;                 /* the wheel's own teal — the brand blue */
  --sea-hi:#4FB3CC;              /* lifted, for anything that must be read */
  --sea-lo:#0B2530;              /* the deep, for scrims under photography */

  /* one ground, and the three lifts above it that iOS uses for depth */
  --bg:#06090C; --lift-1:#0E1318; --lift-2:#151C22;
  --hair:rgba(180,215,230,.10);
  /* The faintest ink was .38, which composites to (94,98,101) on this ground —
     3.24:1, where small text needs 4.5. It carried the hero note, the fine
     print, the bio, the footer and every retreat duration, so a good part of
     the explanatory copy sat under the legibility floor. At .50 it measures
     4.87:1 and passes; the quiet register survives, it just stops being too
     quiet to read. */
  --ink:#F2F0EA; --ink-2:rgba(238,243,245,.62); --ink-3:rgba(238,243,245,.50);

  /* the one light surface in the app, for the near-black package artwork */
  --paper:#F7F5F0; --paper-ink:#141310;
  --bone:#E8E8E2;  /* the quiet fill, from the reference's material list */ --paper-ink-2:rgba(20,19,16,.62);
  --paper-hair:rgba(20,19,16,.13);

  /* one accent, reserved for meaning */
  --gold:#C9A24C; --gold-hi:#E7C77E;
  /* --gold-lo is only ever used on the light package cards. At #8E6C22 it
     measured 4.46:1 on #F7F5F0 — a hair under the 4.5 normal text needs.
     #7F5F17 clears it at 5.3:1 and is otherwise indistinguishable. */
  --gold-lo:#7F5F17;

  --mat:rgba(6,11,15,.66);
  --blur:saturate(180%) blur(22px);

  /* Glass, as the reference app uses it: a barely-there white fill lifted over
     a real backdrop blur, edged with a hairline and an inner top highlight so
     the panel catches light along its upper rim. Depth comes from the blur and
     the rim, never from a heavy border. */
  /* Blur is spent only where something non-uniform actually passes behind the
     surface: the sticky nav, the floating tab bar, and the bento cells, which
     sit over a photograph. Everywhere else these panels rest on flat opaque
     ground, where saturate(178%) blur(30px) costs a compositor pass every
     frame and produces an image identical to no filter at all. Rarity is also
     what keeps the effect legible as an effect — glass on everything is just
     a surface treatment. */
  --glass:rgba(158,206,224,.055);
  --glass-hi:rgba(158,206,224,.095);
  --glass-brd:rgba(158,206,224,.115);
  /* Real glass is lit twice: a bright specular line where the top curve
     catches light, and a dim return along the bottom where light bends back
     through the edge. That double highlight is what separates glass from a
     translucent rectangle. Saturation goes past 100% because glass
     concentrates the colour behind it rather than washing it out. */
  --glass-rim:
    inset 0 .5px 0 rgba(214,238,247,.20),
    inset 0 -.5px 0 rgba(214,238,247,.055),
    0 1px 24px -12px rgba(0,8,12,.75);
  --glass-blur:saturate(178%) blur(30px);

  --r-s:12px; --r-m:18px; --r-l:24px; --r-xl:32px; --r-full:999px;

  /* ══ TYPE BRANDBOOK ══════════════════════════════════════════════════
     Two faces, three jobs, and nothing set outside them. Every size below
     is a token — if a rule needs type, it takes one of these, so the page
     cannot drift back into a dozen one-off clamps.

       DISPLAY · Alumni Sans — the brand voice, and the reason it is this
                 one: the course already owns a wordmark, and that wordmark
                 is tall, narrow and uniform. Of every condensed face on
                 Google Fonts only a handful carry Cyrillic at all — Bebas
                 Neue, Anton, Archivo Narrow, Saira Condensed and Barlow
                 Condensed do not, so most of the obvious answers were never
                 available. This is the closest of the ones that are, which
                 makes it the brand's voice rather than merely a choice.
       TEXT    · Onest — Cyrillic-native, quiet, and built for small sizes.
                 Everything read at length or touched with a finger.
       SACRED  · Alumni Sans 200 — the vow, the pull-quotes, Socrates, the
                 ocean verse. Not a third family: the same face as the
                 titles, in its lightest weight, lowercase, opened right up.

                 Getting here cost five faces and a lot of them. Jost held
                 the titles and the sacred lines, Forum held the section
                 heads, four serifs went through the sacred slot and none
                 held. Five families is a collection, not a brand. Two is the
                 luxury discipline — three is a magazine.

                 What separates the two registers is not the face, it is the
                 setting. Titles are uppercase and tight. These lines are
                 lowercase, 200, tracked to .06em, and given room to breathe.
                 Same voice, spoken differently.

     All three carry the full cyrillic and cyrillic-ext subsets.

     ── the scale ──────────────────────────────────────────────────────────
       --t-hero    the name, once per page          800
       --t-kicker  the line above the name          600
       --t-h2      a screen's title                 300
       --t-caps    a title set as spaced capitals   700
       --t-lead    the paragraph under a title      300
       --t-body    running text                     300
       --t-label   micro-labels and eyebrows        500

     ── the steps ──────────────────────────────────────────────────────────
     Every size on this page is one of iOS's text styles, in points, and
     nothing sits between them or below them:

       11  Caption 2   labels, eyebrows, tab bar     ← the floor
       12  Caption 1   fine print, package meta
       13  Footnote    list cells, FAQ bodies, bio
       15  Subheadline running text, nav title
       16  Callout     the verse under a title
       17  Body        the sacred lines at rest
       20  Title 3     pull-quotes, stat values
       22  Title 2     the ocean verse
       28  Title 1     section titles at full width
       34+ Large Title the name, and IN LAK'ECH

     Sixteen sizes used to be in play here, including four at 9px — below
     Caption 2, which is the smallest style iOS ships. They were snapped onto
     these steps rather than nudged, so the page cannot drift off the scale
     one clamp at a time. */
  /* ── one column, so these are values, not curves ──────────────────────
     Every one of these used to be a clamp, and every clamp was pinned to its
     own minimum: the app is a 430px column, so 5.4cqw is 23px and the 54px
     maximum was dead code. The scale that shipped ran 11 → 24px — a range of
     2.2× — which is why the page read flat however carefully it was set.

     The reference asks for architecture: "Huge / tiny. Wide / compressed.
     Dense / empty. That contrast creates luxury." So the titles are given
     their real size and the labels stay on the floor, opening the range to
     11 → 40px. Still every value an iOS step. */
  --t-hero:28px;      /* Title 1 — the wreath was narrowed to allow it */
  --t-kicker:11px;
  --t-h2:26px;        /* a step under the hero, so the opening still leads */
  --t-caps:19px;      /* the same head, set as capitals, so it needs the size */
  --t-lead:13px;      /* Footnote — the quiet against which a title is loud */
  --t-body:15px;
  --t-label:11px;
  /* Two families, declared once. Noto Serif Devanagari is not a third — it
     renders one word, आनापानसति, which neither of the two can set at all.
     The reasoning for both is in the TYPE BRANDBOOK block above. */
  --display:"Alumni Sans",-apple-system,"Helvetica Neue",sans-serif;
  /* Not a third brand face. A logotype is a mark, not type: it is drawn once,
     used in one place, and every serious house lets it sit outside the text
     system for exactly that reason. It sets the name and nothing else. */
  --logotype:"Forum",Georgia,"Times New Roman",serif;
  --ui:"Onest",-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",Roboto,sans-serif;
  --devanagari:"Noto Serif Devanagari",Georgia,serif;

  --spring:cubic-bezier(.32,.72,0,1);
  --pad:clamp(20px,5.4cqw,40px);
  --gutter:clamp(22px,2.9cqw,42px);
  --navh:50px; --tabh:56px;
}

/* ══ ONE LAYOUT: THE PHONE ═══════════════════════════════════════════════
   This is an iOS app, not a page that also works on a phone. So it is held to
   a phone's width at every viewport and centred on the ground, the way a
   simulator sits on a desk. Every desktop breakpoint has been removed rather
   than overridden — a media query keys off the viewport, so on a wide screen
   they would keep firing and try to lay a three-column grid inside a 430px
   column. There is one layout now and it is this one. */
:root{--app:430px}
*{box-sizing:border-box}
/* iOS and Android paint a translucent blue rectangle over whatever you touch,
   and it ignores border-radius — so on a pill button or a round tab icon it
   flashes as a hard square. It was only cleared on .btn, which left the logo,
   the nav links, the tab bar and every list row showing it. Cleared globally;
   the pressed states this app draws itself are the feedback. */
html{-webkit-tap-highlight-color:transparent}
a,button,summary,label,[role="button"]{-webkit-tap-highlight-color:transparent}
/* The wordmark bleeds past the viewport on purpose, the way it does in the
   original. Clipping on body alone does not contain it — the overflow escapes
   to the document — so the root clips too, or the page scrolls sideways. */
html{-webkit-text-size-adjust:100%; scroll-behavior:smooth; overflow-x:clip;
  /* the ground the app column sits on — a shade below the app itself, so on a
     wide screen the phone reads as an object resting on a surface rather than
     a narrow page floating in white */
  background:#030507; color-scheme:dark}
body{margin:0 auto; overflow-x:clip; background:var(--bg); color:var(--ink);
  width:min(var(--app),100%); position:relative;
  /* every cqw below resolves against this column, not the window */
  container-type:inline-size; container-name:app;
  font:300 var(--t-body)/1.75 var(--ui); letter-spacing:.004em;
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
  padding-bottom:calc(var(--tabh) + env(safe-area-inset-bottom) + 20px)}
img{max-width:100%; height:auto; display:block}
a{color:var(--gold-hi); text-decoration:none}
b,strong{font-weight:600; color:var(--ink)}
.wrap{width:min(1000px,100%); margin:0 auto; padding-left:var(--pad); padding-right:var(--pad)}
.narrow{width:min(660px,100%); margin-inline:auto}

/* ───────────────────────── iOS navigation bar ─────────────────────────
   Translucent material over the content, hairline base, and an inline title
   that fades in only once the large title has scrolled away. Opacity, not
   layout, so nothing reflows as it crosses. */
.nav{position:sticky; top:0; z-index:80; width:100%; background:var(--mat);
  -webkit-backdrop-filter:var(--blur); backdrop-filter:var(--blur);
  border-bottom:.5px solid transparent;
  transition:border-color .45s var(--spring)}
.nav.lift{border-bottom-color:var(--hair)}
.nav .bar{display:flex; align-items:center; gap:16px; height:var(--navh)}
/* 44pt hit areas, without letting the target change how the bar looks: the
   mark and the pill stay their drawn size and grow their touchable box. */
.nav .mark{flex:0 0 auto; display:grid; place-items:center;
  width:44px; height:44px; margin-left:-9px;
  transition:transform .45s var(--spring)}
.nav .mark img{width:26px; height:26px}
.nav .mark:active{transform:scale(.92)}
.nav .title{flex:1; min-width:0; text-align:center;
  font:500 15px/1.2 var(--ui); letter-spacing:-.01em; color:var(--ink);
  opacity:0; transform:translateY(4px);
  transition:opacity .4s var(--spring), transform .4s var(--spring)}
.nav.show-title .title{opacity:1; transform:none}
.nav .links{display:none!important; gap:clamp(13px,1.9cqw,26px); flex:1}
.nav .links a{font:400 11px/1 var(--ui); letter-spacing:.15em; text-transform:uppercase;
  color:var(--ink-3); transition:color .3s var(--spring)}
.nav .links a:hover{color:var(--gold-hi)}
.nav .cta{flex:0 0 auto; display:inline-flex; align-items:center; min-height:36px;
  padding:0 16px; border-radius:var(--r-full);
  font:500 13px/1 var(--ui); letter-spacing:0;
  background:rgba(201,162,76,.16); color:var(--gold-hi);
  border:.5px solid rgba(201,162,76,.34); position:relative;
  transition:background .3s var(--spring), color .3s var(--spring)}
/* the pill is drawn at 34px because that is what an iOS bar button looks like;
   the box that actually receives the tap is 44 */
.nav .cta::after{content:""; position:absolute; left:0; right:0; top:50%;
  height:44px; transform:translateY(-50%)}
.nav .cta:hover{background:var(--gold); color:#100E08}
/* ───────────────────────── iOS tab bar ─────────────────────────
   The kit's TabBar component: icon over label, five tabs, the active one
   tinted and seated on a soft pill, floating clear of the home indicator. */
.tabs{position:fixed; z-index:90; left:50%; transform:translateX(-50%);
  max-width:calc(var(--app) - 26px);
  bottom:calc(9px + env(safe-area-inset-bottom));
  display:flex; gap:2px; padding:5px;
  width:min(420px,calc(100vw - 26px));
  background:rgba(16,23,29,.80);
  -webkit-backdrop-filter:var(--blur); backdrop-filter:var(--blur);
  border:.5px solid var(--hair); border-radius:var(--r-l);
  box-shadow:inset 0 .5px 0 rgba(255,255,255,.10), 0 14px 38px -12px rgba(0,0,0,.8)}
/* The same gold gradient the wide cells carry, turned on its side and laid
   along the top lip of the bar — so the one control that is always on screen
   is lit from the brand rather than outlined in it. Fades at both ends; a rule
   that reaches the corners would read as a border. */
.tabs::before{content:""; position:absolute; left:22%; right:22%; top:0; height:1px;
  border-radius:1px; pointer-events:none;
  background:linear-gradient(90deg,rgba(201,162,76,0),rgba(201,162,76,.55) 50%,rgba(201,162,76,0))}
.tabs a{flex:1; display:flex; flex-direction:column; align-items:center; gap:3px;
  min-height:44px; padding:6px 2px 5px; border-radius:14px;
  color:var(--ink-3); font:500 11px/1.2 var(--ui); letter-spacing:0;
  transition:background .35s var(--spring), color .35s var(--spring)}
.tabs a svg{width:21px; height:21px; stroke-width:1.5}
.tabs a.on{background:rgba(201,162,76,.15); color:var(--gold-hi)}
.tabs a.on svg{stroke-width:1.9}

/* ───────────────────────── screens ─────────────────────────
   One ground, so no screen needs a background of its own. Depth comes from the
   lifts and the hairlines, the way it does in a dark iOS app.

   The page is an app: five tabs, and only the screens belonging to the current
   tab are in the layout. Every screen stays in the DOM — with JavaScript off,
   .no-js leaves them all visible and the page reads as one document, so a
   crawler and a reader without scripts lose nothing. */
.scr{padding:clamp(34px,4.6cqw,70px) 0; position:relative}
.js .scr[data-tab]{display:none}
.js .scr[data-tab].on{display:block}
/* the incoming screen arrives on the system spring, the way a pushed view does */
.js .scr[data-tab].on.enter{animation:screen-in .46s var(--spring) both}
@keyframes screen-in{
  from{opacity:0; transform:translate3d(0,10px,0) scale(.994)}
  to  {opacity:1; transform:none}}
@media (prefers-reduced-motion:reduce){
  .js .scr[data-tab].on.enter{animation:none}}

/* the desktop nav marks the current tab the same way the tab bar does */
.nav .links a.on{color:var(--gold-hi)}

/* Two screens carry a photograph. It is a layer, masked at both ends, never a
   background that stops on a line. */
.scr.pic{isolation:isolate}
.scr.pic::before{content:""; position:absolute; inset:0; z-index:-1;
  background:center/cover no-repeat; opacity:.5;
  -webkit-mask-image:linear-gradient(180deg,rgba(0,0,0,0) 0,#000 22%,#000 78%,rgba(0,0,0,0) 100%);
  mask-image:linear-gradient(180deg,rgba(0,0,0,0) 0,#000 22%,#000 78%,rgba(0,0,0,0) 100%)}
.scr.stars::before{background-image:url('/assets/bg-stars.webp?v=b7eada3fe7')}
.scr.ocean::before{background-image:url('/assets/bg-ocean.jpg?v=743b96f07b')}
.scr.hero::before{opacity:.72;
  -webkit-mask-image:linear-gradient(180deg,#000 0,#000 74%,rgba(0,0,0,0) 100%);
  mask-image:linear-gradient(180deg,#000 0,#000 74%,rgba(0,0,0,0) 100%)}

/* The original centres every screen — heading, label, lead and pull-quote all
   sit on the axis, and only the structured blocks (lists, cards, the author's
   two columns) read from the left. */
.scr{text-align:center}
.scr .list,.scr .faq,.scr .tier ul,.scr .marks,.scr .bio,.scr .folds,
.scr .social,.scr .fact,.scr .author{text-align:left}
.scr .lead,.scr .closing,.scr .say{margin-inline:auto}

/* Aman's micro-label: tiny, wide, gold, always above the head */
/* and once more above the micro-label, this time as a short centred stroke —
   the gold appears three ways across the app and is never the same shape twice */
/* The label is a flex row, so the stroke has to claim a full line of its own
   or it lands beside the words instead of above them — but flex-basis:100%
   beats any width you give it, so the stroke cannot be sized as a box. It is
   painted instead: a full-width, zero-ink element carrying a 34px background
   centred on it. */
.eyebrow::before{content:""; flex:0 0 100%; height:1px; margin:0 0 11px;
  background:linear-gradient(90deg,rgba(201,162,76,0),var(--gold) 50%,rgba(201,162,76,0))
    center/34px 1px no-repeat}
.eyebrow{margin:0 0 14px; font:500 var(--t-label)/1.5 var(--ui); letter-spacing:.38em;
  text-transform:uppercase; color:var(--gold);
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:8px}
.eyebrow .ic{width:15px; height:15px; object-fit:contain; flex:0 0 auto; opacity:.9}

/* Heads are set in the fine serif and kept small — Hyris sets its sections
   small and wide, and Cyrillic caps at display size shout. */
/* The heads are cut in the same face as the name, so the header cannot read
   as an ornament bolted onto a page set in something else. Held a step below
   the hero so the opening still dominates, and given a little positive
   tracking, because a condensed face packs hard if you let it. */
h2{margin:0 0 18px; font:400 var(--t-h2)/1.2 var(--display);
  letter-spacing:.02em; color:var(--ink); text-wrap:balance}
h2.caps{font:400 var(--t-caps)/1.34 var(--display);
  letter-spacing:.15em; text-transform:uppercase}
/* A one-word title set in capitals is a different object from a sentence: it
   needs air between the letters or it reads as a block. Larger, and widely
   spaced. */
h2.solo{font:300 clamp(34px,4.2cqw,42px)/1.1 var(--display); letter-spacing:.2em;
  text-transform:uppercase}
/* Not every screen has earned a title. The nav bar names the screen and the
   tab bar names it again, so a display-size head on top of those says the same
   word three times at once — iOS gets away with a large title because it IS
   the nav title, growing and collapsing into the same slot, never both at
   once. Here they are two separate things on screen together.

   So a screen whose head only repeats the chrome gets a marker instead: small,
   wide, quiet, enough to open the screen and no more. What this buys is not
   tidiness, it is contrast — the plates and the blessing are the only large
   type left, so they land as moments instead of as more of the same. */
h2.quiet{margin:0 0 clamp(14px,1.8cqw,20px);
  font:500 12px/1.5 var(--ui); letter-spacing:.3em; text-transform:uppercase;
  color:var(--ink-3)}
.lead{margin:0; color:var(--ink-2); max-width:58ch; text-wrap:pretty;
  font:300 var(--t-lead)/1.78 var(--ui)}
.say{margin:clamp(18px,2.4cqw,28px) 0 0;
  font:200 20px/1.44 var(--display); letter-spacing:.06em; color:var(--ink);
  letter-spacing:.02em; text-wrap:balance}
/* A line meant to be read slowly: sacred face, centred, balanced. Replaces the
   one inline font rule that used to live in the markup and bypass all of this. */
.verse{margin:clamp(9px,1.4cqw,15px) auto 0; max-width:30ch;
  font:200 17px/1.52 var(--display); letter-spacing:.06em; color:var(--ink-2);
  letter-spacing:.015em; text-wrap:balance}

/* ───────────────────────── hero ───────────────────────── */
/* The header is sticky, so it takes its 51px out of the flow above this
   section — which means 100svh here is one viewport STARTING 51px down, and
   the opening has been overshooting the fold by exactly that much all along.
   The chevron was landing under the tab bar because of it. */
.hero{position:relative; min-height:calc(100svh - var(--navh)); display:flex;
  flex-direction:column; justify-content:center; text-align:center;
  padding-top:28px;
  /* the tab bar floats over the screen, so the screen has to reserve its
     height — otherwise the auto margin under the cue pushes it clean behind it */
  padding-bottom:calc(var(--tabh) + 34px)}
/* The tab system sets `.js .scr[data-tab].on{display:block}`, three classes
   plus an attribute, which has been quietly outranking `.hero{display:flex}`
   ever since it was added — so this screen was never a flex container and its
   justify-content:center never did anything. Every pixel of leftover height
   fell to the bottom, which is the gap that kept showing up under the chevron.
   Matched specificity, and the centring works. */
.js .scr[data-tab].on.hero{display:flex}
/* Same collision as the opening: .finale asks for a centred flex column and
   the tab rule's display:block outranks it, so the centring did nothing and
   its 70svh left the leftover height in one lump under the button. */
.js .scr[data-tab].on.finale{display:flex}
/* The screen is a column whose only child is the wrap, so the wrap has to
   become the column too — otherwise nothing inside it can be placed against
   the screen's height. Content starts at the top, where the opening had been
   carrying a hundred and forty pixels of nothing above the label, and the
   scroll cue is pushed to the floor by an auto margin. */
.hero > .wrap{flex:1; display:flex; flex-direction:column; justify-content:flex-start}
.hero .chev{margin-top:auto; margin-bottom:2px}
/* The branches are a wreath, so every line of the title block sits inside
   their arc — not just the one word they happen to flank. The block is held
   narrow enough to clear the leaf tips at any width, and the leaves are
   centred on the whole block rather than on the headline alone. */
/* The leaves were sized first and the name had to fit whatever was left,
   which pinned it at 24px — off the scale and the smallest title on a
   screen that is meant to open on a name. The order is reversed here: the
   name takes Title 1 and the wreath is drawn to hold it. */
.crest{position:relative; padding:0 clamp(66px,17cqw,206px);
  display:flex; align-items:center; justify-content:center}
.crest .branch{position:absolute; top:50%; width:clamp(60px,16cqw,196px); opacity:.95;
  pointer-events:none; animation:sway 8s ease-in-out infinite}
/* Orientation follows the source: in the original the LEFT copy carries
   flip_h:true and the right flip_h:false, so the cupped edges face inward. */
.crest .branch.l{left:0; transform:translateY(-50%) scaleX(-1); animation-name:sway-flip}
.crest .branch.r{right:0; transform:translateY(-50%); animation-delay:-4s}
@keyframes sway{0%,100%{transform:translateY(-50%) scale(1)}50%{transform:translateY(-50%) scale(1.03)}}
@keyframes sway-flip{0%,100%{transform:translateY(-50%) scaleX(-1) scale(1)}
                     50%{transform:translateY(-50%) scaleX(-1) scale(1.03)}}
/* the title sits above the wreath, not under it */
/* On a phone the block is held narrow so it clears the leaf tips. On a wide
   screen the wreath opens up and there is far more room between the tips than
   30ch uses, which left the subtitle stacked in three short lines for no
   reason. The cap grows with the space. */
.crest-txt{position:relative; z-index:1; width:100%; max-width:32ch; margin-inline:auto}
/* Poster register: the label, the name and the line under it are one packed
   block, set heavy and tight, rather than three whispers spaced apart. */
  /* Steps out of the title block's measure. That measure exists to keep the
     NAME clear of the leaf tips and has nothing to say about this line, which
     sits above them and reads as one thing or not at all. */
  .hero .kicker{margin:0 0 0 50%; transform:translateX(-50%);
  white-space:nowrap; width:max-content; max-width:none;
  font:600 var(--t-kicker)/1.35 var(--ui);
  letter-spacing:.055em; text-transform:uppercase; color:var(--ink)}
/* Sanskrit gravity in Cyrillic. Devanagari reads as Devanagari because of the
   shirorekha — the head-line every word hangs from — not because of its
   letterforms, which is why no Cyrillic face could ever carry the feeling. So
   the line is drawn rather than chosen, over the display face. It was first
   built to fade at the centre and return — a breath inside the word — but at
   this size the break read as a space and the name came apart into two. One
   line, then, and it fades at both ends instead, where nothing is at stake. */
.hero .pali{margin:clamp(10px,1.3cqw,15px) 0 clamp(9px,1.1cqw,13px); font:400 clamp(13px,1.5cqw,17px)/1.4 var(--devanagari);
  letter-spacing:.09em; color:var(--gold)}
.hero h1{display:flex; justify-content:center; align-items:flex-start;
  margin:0; font:400 clamp(30px,8.6cqw,42px)/1.06 var(--logotype);
  letter-spacing:.11em; color:var(--ink)}
/* the rule is the span's own top edge, so it spans exactly the word and not a
   pixel more; drawn as a background rather than a border so it can fade out at
   the tips instead of stopping dead */
.hero h1 span{padding-top:.36em; background:linear-gradient(90deg,
    rgba(201,162,76,0),var(--gold) 14%,var(--gold) 86%,rgba(201,162,76,0)) top/100% 1px no-repeat}
/* tracking hangs a .11em space off the last letter; pulled back so the rule
   ends where the letter does and the name stays optically centred */
.hero h1 span{margin-right:-.11em}
/* the reference rules this line above and below, and the lower rule is gold */
/* Set in the same register as the facts pane below it — the display face,
   opened up, on the ink rather than at label grey — so the two things that
   flank the invitation read as one system instead of two afterthoughts. */
/* The title block is held to 32ch so the NAME clears the leaf tips, but the
   leaves stop at the name's baseline and this line sits under them — so it was
   being squeezed by a constraint that does not apply to it, and in a condensed
   face (where a ch is a much narrower thing) that meant four lines instead of
   two. It steps out of the parent measure to its own, the same way the
   wordmark strip does. */
.hero .under{margin:11px 0 0 50%; transform:translateX(-50%);
  width:min(330px,86vw); max-width:none; padding:9px 14px 10px; text-wrap:balance;
  font:300 clamp(13px,1.45cqw,15px)/1.5 var(--display); letter-spacing:.05em;
  color:var(--ink-2);
  border-top:.5px solid rgba(255,255,255,.15);
  border-bottom:1px solid rgba(201,162,76,.62)}
.note{margin:13px auto 0; max-width:62ch;
  font:300 clamp(11px,1cqw,12px)/1.78 var(--ui); color:var(--ink-3)}
.buddha{position:relative; width:clamp(146px,22cqw,250px); margin:clamp(24px,3.2cqw,44px) auto 0;
  isolation:isolate}
/* A lamp behind the head is the cheap way to say "sacred": it lights the air
   around an object instead of lighting the object, and every meditation app on
   the store does it. What reads as expensive is specular — a highlight that
   travels ACROSS a surface and tells you what the surface is made of.

   So the halo is gone, and in its place a single sweep of warm light crosses
   the carving. It is masked by the figure's own alpha, so it runs over the
   face and the curls and stops exactly where the bronze stops — never a band
   of light moving across a rectangle. Screen blend, so it only ever adds.

   It crosses in two and a half seconds and then rests for six. Rarity is the
   whole effect: light that sweeps constantly is a loading spinner. */
.buddha .head{filter:saturate(1.1) contrast(1.03)
  drop-shadow(0 3px 26px rgba(160,116,30,.28))}
/* Enlightenment, not product lighting. The gold sweep that used to cross the
   face is gone — a bar of light travelling over a surface is how you shoot a
   watch, and it slid over the eyes and the mouth.

   What is here now is soft, white, and stays ON the head. Two layers, both
   masked to the figure, so the light lands on the curls and stops at the
   bronze: nothing rises off the crown into the air, and the face is never
   touched. An unmasked bloom above the head was tried and removed — it read
   as a lamp behind the object rather than the object being lit, which is the
   thing this was replacing in the first place. The four-point spark went with
   it: at this size it read as a plus sign sitting on his head.

   Both breathe across eleven seconds, half a cycle apart, so neither peaks
   with the other and nothing pulses in unison. */
.buddha::before{content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  /* screen blend adds light, so past about .8 the curls stop being curls and
     the crown goes to flat paper. It peaks below that and rolls off over a
     longer distance instead, which keeps the carving readable inside the glow. */
  background:linear-gradient(176deg,
    rgba(255,255,255,.76) 0%, rgba(255,255,255,.62) 9%,
    rgba(255,254,250,.44) 18%, rgba(255,253,247,.26) 27%,
    rgba(255,252,244,.13) 35%, rgba(255,252,244,.04) 42%,
    rgba(255,252,244,0) 50%);
  -webkit-mask:url("/assets/buddha.webp?v=e21f43e1ed") center/contain no-repeat;
  mask:url("/assets/buddha.webp?v=e21f43e1ed") center/contain no-repeat;
  mix-blend-mode:screen; animation:crown 9s ease-in-out infinite}
/* A soft pool of light gathered on the crown itself — masked, so it cannot
   spill past the silhouette. It breathes IN PHASE with the layer above it.
   They were offset half a cycle so neither would peak with the other, which
   sounded like refinement and was the bug: as one dimmed the other brightened,
   the total light stayed flat, and the pulse nobody could see was the pulse
   cancelling itself out. */
.buddha::after{content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:radial-gradient(58% 30% at 50% 8%,
    rgba(255,255,255,.70) 0%, rgba(255,254,250,.40) 32%,
    rgba(255,253,247,.15) 56%, rgba(255,252,244,0) 80%);
  -webkit-mask:url("/assets/buddha.webp?v=e21f43e1ed") center/contain no-repeat;
  mask:url("/assets/buddha.webp?v=e21f43e1ed") center/contain no-repeat;
  mix-blend-mode:screen;
  animation:crown 9s ease-in-out infinite}

/* The breath is what makes it read as alive rather than as a white patch. It
   runs from under a third to full, on an ease, so there is no moment where it
   is visibly turning around — calm, but plainly happening. */
@keyframes crown{0%,100%{opacity:.26}50%{opacity:1}}
.buddha .head{position:relative; width:100%}
.hero .vow{margin:clamp(20px,2.8cqw,34px) auto 0; max-width:26ch; text-wrap:balance;
  font:200 17px/1.46 var(--display); letter-spacing:.06em; color:var(--gold-hi);
  letter-spacing:.02em}
/* Pinning this to the foot of the screen was tried and abandoned: the header
   is sticky and eats 51px of flow, so the section's own bottom edge sits below
   the fold and anything anchored to it lands under the tab bar. The cue stays
   in the flow, and the screen is sized so the slack around it is shared evenly
   top and bottom — which is air, rather than the one-sided hole it was.

   It no longer carries .rv either. Two motion systems on one element fought:
   .rv holds a transform and transitions it away on arrival, the nudge holds a
   loop, and the element sat pinned at .rv's start value — an inline
   transform:none could not shift it, which is the signature of a transition
   still holding the property. A scroll cue that already breathes does not also
   need to be revealed. The nudge animates `translate` rather than `transform`
   regardless, so it composes instead of competing. */
.chev{width:clamp(22px,2.4cqw,34px); margin:clamp(14px,2cqw,22px) auto 0; opacity:.55;
  filter:brightness(2.6); animation:nudge 2.8s ease-in-out infinite}
@keyframes nudge{0%,100%{translate:0 0;opacity:.5}50%{translate:0 5px;opacity:.85}}
.fine{margin:14px 0 0; font:300 11px/1.7 var(--ui); color:var(--ink-3)}

/* ───────── capsules: the reference app's core unit ─────────
   In Hyris every fact is a glass capsule with a micro-label sitting above its
   value — "Remote / $3k+ Salary", "Top Match / +6 New Today" — never a row of
   text on a rule. This page had hairline rows instead, which is why it read as
   a document where the reference reads as an app. The capsule is now the unit:
   a soft-cornered pill, barely-there fill over a real blur, hairline edge, and
   an inner top rim so it catches light along its upper curve. */
/* Four separate pills made four separate objects out of one fact — what the
   course is. They are one object now: a single pane divided by hairlines, the
   way iOS groups a set of readings rather than boxing each of them. The rules
   are inset from the edge and stop short at top and bottom, so the pane reads
   as divided rather than as a table with a grid drawn on it. The values take
   the engineered face, which is what gives a number presence at this size. */
.stats{position:relative; margin:clamp(20px,2.8cqw,36px) auto 0; width:min(560px,100%);
  display:grid; grid-template-columns:1fr 1fr;
  background:var(--glass); border:.5px solid var(--glass-brd);
  border-radius:var(--r-l); overflow:hidden;
  box-shadow:var(--glass-rim)}
.stats::before{content:""; position:absolute; left:26%; right:26%; top:0; height:1px;
  border-radius:1px; z-index:1;
  background:linear-gradient(90deg,rgba(201,162,76,0),rgba(201,162,76,.5) 50%,rgba(201,162,76,0))}
.stats .row{position:relative; display:flex; flex-direction:column; align-items:center;
  gap:clamp(4px,.7cqw,7px); text-align:center;
  padding:clamp(11px,1.5cqw,15px) clamp(9px,1.2cqw,14px);
  transition:background .45s var(--spring)}
@media (hover:hover){.stats .row:hover{background:rgba(255,255,255,.032)}}
.stats .row:nth-child(-n+2)::after{content:""; position:absolute;
  left:13px; right:13px; bottom:0; height:.5px; background:var(--hair)}
.stats .row:nth-child(odd)::before{content:""; position:absolute;
  top:13px; bottom:13px; right:0; width:.5px; background:var(--hair)}
.stats .k{font:500 9px/1.3 var(--ui); letter-spacing:.24em; text-transform:uppercase;
  color:var(--gold); opacity:.7}
.stats .v{font:400 clamp(15px,1.6cqw,17px)/1.2 var(--display); letter-spacing:.03em;
  color:var(--ink)}

/* ───────── chips: the small capsules that tag a card ─────────
   "Onsite", "Full Time", "$5k/Mo" in the reference — a fact reduced to a word,
   sitting in a pill under the thing it describes. */
.chips{display:flex; flex-wrap:wrap; gap:6px; margin:10px 0 16px;
  justify-content:center}
.chip{display:inline-flex; align-items:center; min-height:28px; padding:0 12px;
  border-radius:var(--r-full); white-space:nowrap;
  font:500 10.5px/1 var(--ui); letter-spacing:.07em; text-transform:uppercase;
  background:var(--glass); border:.5px solid var(--glass-brd); color:var(--ink-2);
}
/* the one chip that carries the price reads in the accent, as the reference does */
.chip.key{background:rgba(201,162,76,.16); border-color:rgba(201,162,76,.32);
  color:var(--gold-hi); font-weight:600}
/* on the light package cards the same chips invert */
.tier.light .chip{background:rgba(20,19,16,.05); border-color:var(--paper-hair);
  color:var(--paper-ink-2)}
.tier.light .chip.key{background:rgba(127,95,23,.12); border-color:rgba(127,95,23,.28);
  color:var(--gold-lo)}

/* the corner control the reference puts on every card */
.tier{position:relative}
.card-go{position:absolute; top:14px; right:14px; width:34px; height:34px;
  display:grid; place-items:center; border-radius:50%;
  background:var(--glass); border:.5px solid var(--glass-brd); color:var(--ink-3);
  transition:background .35s var(--spring), transform .35s var(--spring)}
.card-go svg{width:15px; height:15px}
.tier.light .card-go{background:rgba(20,19,16,.05); border-color:var(--paper-hair);
  color:var(--paper-ink-2)}

/* ───────────────────────── buttons ─────────────────────────
   Measured off apple.com rather than remembered: a true capsule, the label at
   17px in the REGULAR weight with no tracking at all, and sentence case. The
   geometry here was already right; the voice was not. Semibold letterspaced
   capitals are an editorial habit — Apple never shouts at you from a control.

   Two fills, and they are not interchangeable:

     GOLD is warmth, and it is spent twice — on the invitation at the top of
          the app and the blessing at the bottom. Those are the brand's two
          emotional moments and gold belongs to them.
     BONE does the work: the packages, the practice, the reviews. It is the
          quieter of the two and, on this ground, the higher-contrast one —
          which is the point the direction reference makes when it says the
          look is not gold and not a colourful CTA.

   Anything secondary is not a fill at all: label, accent colour, chevron. */
.btn{display:inline-flex; align-items:center; justify-content:center; gap:8px;
  min-height:50px; padding:0 clamp(22px,3cqw,30px); border-radius:var(--r-full);
  font:400 17px/1 var(--ui); letter-spacing:0;
  -webkit-tap-highlight-color:transparent; cursor:pointer;
  transition:transform .32s var(--spring), background .32s var(--spring),
             color .32s var(--spring), opacity .32s var(--spring),
             box-shadow .32s var(--spring)}
.btn:active{transform:scale(.965); opacity:.86; transition-duration:.09s}
.btn:focus-visible{outline:2px solid var(--gold-hi); outline-offset:3px}

/* warm — the invitation and the blessing, and nowhere else */
.btn.gold{background:var(--gold); color:var(--paper-ink);
  box-shadow:inset 0 .5px 0 rgba(255,243,214,.55),
             0 8px 26px -14px rgba(201,162,76,.70)}
.btn.gold:hover{background:#D9B463;
  box-shadow:inset 0 .5px 0 rgba(255,246,224,.65),
             0 10px 32px -14px rgba(201,162,76,.85)}

/* quiet — every action that is work rather than invitation */
.btn.bone{background:var(--bone); color:var(--paper-ink);
  box-shadow:inset 0 .5px 0 #fff, 0 10px 28px -16px rgba(0,0,0,.9)}
.btn.bone:hover{background:#F4F4EE;
  box-shadow:inset 0 .5px 0 #fff, 0 12px 32px -16px rgba(0,0,0,.95)}

/* secondary — Apple's other type: a label, the accent, and a chevron */
.btn.link{background:none; color:var(--gold-hi); padding-inline:12px; min-height:44px}
.btn.link:hover{color:#F3DCA8}
.btn.link::after{content:""; width:7px; height:12px; flex:0 0 auto;
  background:currentColor;
  -webkit-mask:no-repeat center/7px 12px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 7 12'%3E%3Cpath d='M1 1l5 5-5 5' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  mask:no-repeat center/7px 12px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 7 12'%3E%3Cpath d='M1 1l5 5-5 5' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  transition:transform .32s var(--spring)}
.btn.link:hover::after{transform:translateX(3px)}
/* on the light package cards the secondary takes the dark accent */
.tier.light .btn.link{color:var(--gold-lo)}
/* The kit's fourth type, Plain, is deliberately not implemented: this page has
   no tertiary action, and an unused variant is just dead weight in the sheet. */
.cta-row{display:flex; flex-wrap:wrap; gap:10px; justify-content:center;
  margin:clamp(20px,2.6cqw,30px) 0 0}
.center{text-align:center}
.center .cta-row,.hero .cta-row,.finale .cta-row,.band .cta-row{justify-content:center}
.center .lead{margin-inline:auto}

/* ───────── iOS inset-grouped list, on a lift rather than on paper ─────────
   The gain icons are white line art, so this card is dark; on the white card
   v2 used they were invisible. The separator is inset to the text edge — the
   detail that makes an iOS list read as a list. */
.list{margin:clamp(20px,2.6cqw,32px) 0 0; background:var(--glass);
  border:.5px solid var(--glass-brd); border-radius:var(--r-l); overflow:hidden;
  box-shadow:var(--glass-rim)}
/* Heights come straight off the kit's TableView-cell: 44 for a single line,
   57 once the label wraps. The separator starts at the text edge, never the
   card edge — the detail that makes an iOS list read as a list. */
.list .item{display:flex; align-items:center; gap:14px; padding:12px 16px;
  min-height:57px; position:relative; transition:background .32s var(--spring)}
@media (hover:hover){.list .item:hover{background:rgba(255,255,255,.035)}}
.list .item + .item::before{content:""; position:absolute; left:52px; right:0; top:0;
  height:.5px; background:var(--hair)}
.list .item img{width:24px; height:24px; object-fit:contain; flex:0 0 auto; opacity:.92}
.list .item span{font:300 13px/1.6 var(--ui); color:var(--ink-2); letter-spacing:0}
/* Some of these rows carry a step number instead of a drawing. It occupies the
   same 24px column the icon does, so the separator inset and the text edge stay
   where they were — a numeral is just another mark in that slot. Tabular figures
   keep 01 and 06 the same width. */
.list .item:has(.n){align-items:flex-start}
.list .item .n{flex:0 0 auto; width:24px; text-align:center; margin-top:1px;
  font:500 11px/1.6 var(--ui); letter-spacing:.06em; color:var(--gold);
  font-variant-numeric:tabular-nums}
.list .item b{font-weight:500; color:var(--ink)}
/* the day-by-day fold sets a description under the day's name, so its rows
   breathe a little more than the retreat list they share a component with */
.folds[open] .rl{margin-top:4px}
/* ───────────────────────── figures ─────────────────────────
   One drawing, presented once. v2 printed the same scribble twice at two sizes
   — 219×175 and 590×471, aspect 1.251 and 1.252 — which read as a mistake
   because it was one. */
.figure{margin:clamp(22px,3cqw,38px) 0 0; text-align:center}
.figure img{width:min(420px,74%); margin:0 auto; opacity:.92}
.figure figcaption{margin:14px auto 0; max-width:34ch;
  font:300 12px/1.7 var(--ui); letter-spacing:.03em; color:var(--ink-3)}
/* The original sets this wordmark at 480 on a 1024 desktop canvas — 47%,
   centred — and lets it run to 407 on a 320 phone canvas, wider than the
   screen. So it is modest on a wide viewport and full-bleed on a narrow one,
   which is the opposite of what a plain width:100% does. */
/* Centred with a negative margin, not a transform. Every block below the
   opening now carries the reveal class, and that class animates `transform` —
   so a translateX(-50%) used for centring is simply overwritten and the
   wordmark slides off to one side. Half of the 18% overhang on each side does
   the same job and nothing can take it away. */
.strip{display:block; margin:clamp(14px,2cqw,24px) 0 clamp(16px,2.2cqw,26px) -9%;
  width:118%; max-width:none;
  opacity:.92;
  -webkit-mask-image:linear-gradient(90deg,rgba(0,0,0,0) 0,#000 12%,#000 88%,rgba(0,0,0,0) 100%);
  mask-image:linear-gradient(90deg,rgba(0,0,0,0) 0,#000 12%,#000 88%,rgba(0,0,0,0) 100%)}
/* ───────────────────────── video ─────────────────────────
   A player is a hard-edged black rectangle by nature, so it is given the same
   radius as every other card and left alone — a mask over an iframe would only
   fight the controls. */
.vid{position:relative; aspect-ratio:16/9; border-radius:var(--r-l); overflow:hidden;
  background:#000; border:.5px solid var(--glass-brd); box-shadow:var(--glass-rim)}
.vid iframe{position:absolute; inset:0; width:100%; height:100%; border:0}
/* A cover for an embed whose thumbnail belongs to someone else. It is graded
   the same way the author's plate is, so a loud third-party still cannot break
   the page's temperature, and the blur on the button is one of the few places
   it is earned — it sits over a photograph. */
.vid .facade{position:absolute; inset:0; width:100%; height:100%; padding:0; border:0;
  background:none; cursor:pointer; display:block; overflow:hidden;
  -webkit-tap-highlight-color:transparent}
.vid .facade img{width:100%; height:100%; object-fit:cover; object-position:center;
  filter:brightness(.92);
  transition:transform 1.1s var(--spring), filter .7s var(--spring)}
.vid .facade .play{position:absolute; left:50%; top:50%; translate:-50% -50%;
  width:62px; height:62px; border-radius:50%; display:grid; place-items:center;
  background:rgba(12,18,22,.34); border:.5px solid rgba(255,255,255,.42);
  -webkit-backdrop-filter:var(--blur); backdrop-filter:var(--blur);
  box-shadow:inset 0 .5px 0 rgba(255,255,255,.30), 0 10px 30px -14px rgba(0,0,0,.9);
  transition:transform .5s var(--spring), background .5s var(--spring)}
.vid .facade .play::after{content:""; width:0; height:0; margin-left:5px;
  border-left:15px solid var(--paper);
  border-top:10px solid transparent; border-bottom:10px solid transparent}
@media (hover:hover){
  .vid .facade:hover img{transform:scale(1.03); filter:brightness(1)}
  .vid .facade:hover .play{transform:scale(1.06); background:rgba(12,18,22,.46)}
}
.vid .facade:active .play{transform:scale(.95)}
.vid .facade:focus-visible{outline:2px solid var(--gold-hi); outline-offset:-3px}
.vid.one{margin:clamp(20px,2.7cqw,34px) auto 0; max-width:780px}
/* the review shelf pages the same way */
.vid-grid{display:grid; grid-auto-flow:column; grid-auto-columns:min(82%,320px);
  gap:clamp(10px,1.4cqw,16px); margin:clamp(16px,2.2cqw,24px) 0 0;
  overflow-x:auto; overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory; scroll-padding-inline:var(--pad);
  padding-inline:var(--pad); margin-inline:calc(-1 * var(--pad));
  scrollbar-width:none; -webkit-overflow-scrolling:touch}
.vid-grid::-webkit-scrollbar{display:none}
.vid-grid > *{scroll-snap-align:center}
.minor{margin:clamp(24px,3cqw,36px) 0 0; font:500 11px/1.5 var(--ui);
  letter-spacing:.22em; text-transform:uppercase; color:var(--gold)}

/* ───────────────────────── the mosaic ─────────────────────────
   The reference's second device: photographs tiled edge to edge, in unequal
   sizes, with no gaps at all. The absence of gutters is the whole point — gaps
   would make it a gallery of pictures, while a continuous surface makes it one
   picture made of many, which is what reads as editorial rather than as a grid
   of thumbnails.

   Two tiles are given double width so the rhythm never settles into a chequer­
   board. On a phone it runs two columns; from 700px it opens to four and the
   spans start to tell. */
.mosaic{position:relative; display:grid; gap:0; margin:clamp(20px,2.8cqw,34px) 0 0;
  margin-inline:calc(-1 * var(--pad));
  grid-template-columns:repeat(2,1fr); grid-auto-rows:clamp(96px,26cqw,150px);
  /* Top and bottom only, for the same reason as the portrait: photographs
     dissolving at their vertical edges read as a failed load, not as soft. */
  -webkit-mask-image:linear-gradient(180deg,rgba(0,0,0,0) 0,#000 9%,#000 91%,rgba(0,0,0,0) 100%);
  mask-image:linear-gradient(180deg,rgba(0,0,0,0) 0,#000 9%,#000 91%,rgba(0,0,0,0) 100%)}
/* The set has to read as one surface. Grading each tile with hue-rotate did
   not do that: some of these frames are already black and white and some are
   not, so a hue shift bit on half of them and left the rest grey — the tint
   landed unevenly, which is worse than no tint.

   So every tile is taken fully to grey first, which makes them all the same
   material whatever they started as, and the blue is laid over the whole
   surface once as a single wash. One cast, one exposure, one surface. */
/* Back to grey, and held back as well. Several of these frames were shot in
   black and white to begin with, so colour only ever returned on some of them
   — which is the uneven look this was trying to fix in the first place. Grey
   makes every tile the same material whatever it started as, and 70% keeps the
   surface quiet behind the words. */
.mosaic img{width:100%; height:100%; object-fit:cover; display:block;
  opacity:.7; filter:grayscale(1) contrast(1.04) brightness(.86);
  transition:opacity .7s var(--spring), filter .7s var(--spring), transform .7s var(--spring)}
/* the tiles that break the rhythm */
.mosaic img:nth-child(1){grid-column:span 2}
.mosaic img:nth-child(6){grid-row:span 2}
@media (hover:hover){
  .mosaic img:hover{opacity:1; filter:grayscale(.2) contrast(1.02) brightness(1);
    transform:scale(1.03)}
}
/* ───────────────────────── the plate ─────────────────────────
   The luxury-marque treatment: a cinematic photograph running the full width of
   the screen with the title laid over it — light weight, wide tracking, upper
   case — and a small line of capitals beneath. Nothing else on it. The whole
   effect depends on three things and no more:

     · the photograph bleeds to both edges and fades at every one, so it never
       ends on a cut;
     · the type is set thin and opened right up — luxury sets its titles wide
       and quiet, never bold and tight;
     · a slow scrim under the text only, so the words hold at any exposure
       without greying the whole picture.

   This is what makes a screen feel like a guest arriving rather than a page
   loading. */
.plate{position:relative; margin:0 0 clamp(20px,2.8cqw,34px);
  margin-inline:calc(-1 * var(--pad));
  isolation:isolate; overflow:hidden}
/* The picture came flat greyscale, and thin capitals over flat grey is the
   recipe for a memorial plaque. A cold duotone fixed the flatness and bought
   something worse — a blue cast reads as morgue light, not as calm. So the
   grade is warm now and barely there: a few points of sepia to put blood back
   in the skin, a little contrast, no hue shift. Laid on with filters rather
   than an overlay, because an overlay would be a hard rectangle over an image
   that does not end on a cut.

   It fades top and bottom only. The left and right fades went because a
   photograph dissolving at its own vertical edges does not read as soft — it
   reads as a picture that failed to load, and the sides are exactly where the
   eye checks an image for quality. Top and bottom it meets the ground, so
   there it must fade; at the sides it meets the frame, so there it must not.

   The top ramp is long and eased: nothing above his head ends anywhere, it
   simply thins out until it is gone. */
.plate img{width:100%; height:clamp(300px,52vh,520px); object-fit:cover;
  object-position:center;
  filter:grayscale(1) sepia(.16) contrast(1.09) brightness(1.02);
  -webkit-mask-image:linear-gradient(180deg,
    rgba(0,0,0,0) 0%, rgba(0,0,0,.04) 5%, rgba(0,0,0,.13) 9%, rgba(0,0,0,.28) 13%,
    rgba(0,0,0,.48) 17%, rgba(0,0,0,.70) 21%, rgba(0,0,0,.88) 25%, #000 30%,
    #000 84%, rgba(0,0,0,0) 100%);
  mask-image:linear-gradient(180deg,
    rgba(0,0,0,0) 0%, rgba(0,0,0,.04) 5%, rgba(0,0,0,.13) 9%, rgba(0,0,0,.28) 13%,
    rgba(0,0,0,.48) 17%, rgba(0,0,0,.70) 21%, rgba(0,0,0,.88) 25%, #000 30%,
    #000 84%, rgba(0,0,0,0) 100%)}
/* the scrim sits under the words only, not over the picture */
.plate figcaption{position:absolute; left:0; right:0; bottom:0; z-index:1;
  padding:clamp(28px,5cqw,56px) var(--pad) clamp(20px,3.4cqw,38px);
  background:linear-gradient(180deg,rgba(6,15,20,0) 0,rgba(6,15,20,.55) 60%,rgba(5,12,17,.82) 100%);
  text-align:center}
.plate .plate-t{margin:0; color:var(--ink);
  font:300 clamp(32px,4.4cqw,44px)/1.04 var(--display);
  letter-spacing:.13em; text-transform:uppercase}
.plate .plate-s{margin:clamp(8px,1.2cqw,13px) auto 0; max-width:44ch;
  font:400 11px/1.6 var(--ui); letter-spacing:.2em; text-transform:uppercase;
  color:var(--ink-2)}
/* ───────────────────────── author ───────────────────────── */
/* The portrait is a plate now — full-bleed above the text — so this is a
   single column holding what used to sit beside it. */
.author{margin:clamp(20px,2.8cqw,34px) 0 0}
/* A long list of credentials is read, not scanned, so it takes Footnote with
   generous leading rather than Subheadline packed tight. */
/* Set smaller and marked with a drawn rule rather than an em dash. A typed
   dash carries the line's own weight and colour and sits on the baseline, so
   at this size it reads as punctuation someone forgot to remove; a hairline
   can be given the brand's gold, held to a fixed length, and aligned to the
   x-height of the first line instead of the text baseline. */
/* The row is NOT a flex container. It was, and the moment a link went inside
   one of these lines the browser split the text into anonymous flex items
   around it — three boxes with a 12px gap between them, each wrapping in its
   own narrow column. Text with an inline element in it has to stay in normal
   flow, so the marker is positioned instead of laid out. */
.marks{list-style:none; margin:0; padding:0; display:grid; gap:11px;
  font:300 12px/1.72 var(--ui); color:var(--ink-2); letter-spacing:.008em}
.marks li{position:relative; padding-left:23px}
.marks li::before{content:""; position:absolute; left:0; top:.72em;
  width:11px; height:1px; border-radius:1px; background:var(--gold); opacity:.62}
.marks a{color:var(--gold-hi); text-decoration:none;
  border-bottom:.5px solid rgba(231,199,126,.38)}
.marks a:hover{color:#F3DCA8}
.bio{margin:16px 0 0; font:300 12px/1.72 var(--ui); color:var(--ink-3)}
.social{list-style:none; margin:22px 0 0; padding:0; background:var(--glass);
  border:.5px solid var(--glass-brd); border-radius:var(--r-l); overflow:hidden;
  box-shadow:var(--glass-rim)}
.social a{display:flex; align-items:center; gap:12px; padding:11px 16px; min-height:44px;
  position:relative; color:var(--ink-2); font:400 13px/1.4 var(--ui);
  transition:background .3s var(--spring), color .3s var(--spring)}
.social a:hover{background:rgba(255,255,255,.05); color:var(--gold-hi)}
/* the kit's disclosure chevron is 20×22 and sits at the trailing edge */
.social a::after{content:""; margin-left:auto; flex:0 0 auto; width:20px; height:22px;
  background:currentColor; color:var(--ink-3); opacity:.55;
  -webkit-mask:no-repeat center/7px 12px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 7 12'%3E%3Cpath d='M1 1l5 5-5 5' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  mask:no-repeat center/7px 12px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 7 12'%3E%3Cpath d='M1 1l5 5-5 5' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}
.social li + li a::before{content:""; position:absolute; left:48px; right:0; top:0;
  height:.5px; background:var(--hair)}
/* these mark files are white line art, so on the dark row they need no filter */
.social a img{width:17px; height:17px; object-fit:contain; opacity:.75}
.social a:hover img{opacity:1}
.folds{margin:20px 0 0; padding:15px 17px; border-radius:var(--r-l);
  background:var(--glass); border:.5px solid var(--glass-brd);
  box-shadow:var(--glass-rim)}
.folds summary{cursor:pointer; list-style:none; font:500 13px/1.5 var(--ui);
  color:var(--ink-2); display:flex; align-items:center; justify-content:space-between;
  gap:14px; min-height:44px}
.folds summary::-webkit-details-marker{display:none}
.folds summary::after{content:"⌄"; color:var(--gold)}
.folds[open] summary::after{content:"⌃"}
/* Twenty-four retreats over thirteen years is a record, not a paragraph, so
   it is set as one: the date in its own column in tabular figures so the
   years stack and the eye can run down them, the place beside it, and the
   duration under the place where it belongs to it rather than floating at the
   end of a sentence. Hairlines between, inset to nothing — the rows are close
   enough that a rule is all the separation they need. */
.folds ul{margin:12px 0 0; padding:0; list-style:none}
.folds li{display:grid; grid-template-columns:70px 1fr; gap:12px;
  padding:9px 0; position:relative}
.folds li + li::before{content:""; position:absolute; left:0; right:0; top:0;
  height:.5px; background:var(--hair)}
.folds .dt{font:500 10px/1.6 var(--ui); letter-spacing:.06em; color:var(--gold);
  font-variant-numeric:tabular-nums; white-space:nowrap}
.folds .pl{font:400 12px/1.5 var(--ui); color:var(--ink-2)}
.folds .rl{display:block; margin-top:2px;
  font:300 11px/1.5 var(--ui); color:var(--ink-3)}
/* Three of these retreats have a film. The row says so with a mark rather
   than a word — an arrow leaving its box, which is the one glyph that reads
   as "this goes somewhere else" without needing a language. The words are
   still there for a screen reader, which cannot see a mark. */
.folds .ext{color:var(--gold-hi); text-decoration:none;
  border-bottom:.5px solid rgba(231,199,126,.34)}
.folds .ext:hover{color:#F3DCA8; border-bottom-color:rgba(243,220,168,.6)}
.folds .ext .go{display:inline-block; width:9px; height:9px; margin-left:5px;
  vertical-align:baseline; background:currentColor;
  -webkit-mask:no-repeat center/9px 9px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M3 1h6v6M9 1 1.6 8.4' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  mask:no-repeat center/9px 9px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M3 1h6v6M9 1 1.6 8.4' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  transition:transform .32s var(--spring)}
.folds .ext:hover .go{transform:translate(2px,-2px)}
/* said for assistive tech, drawn for nobody */
.sr{position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0}
.socrates{margin:22px 0 0; font:200 16px/1.52 var(--display); letter-spacing:.06em;
  color:var(--ink); letter-spacing:.01em}

/* ───────────────────────── ocean interlude ───────────────────────── */
.band{text-align:center; padding:clamp(36px,4.6cqw,68px) 0}
/* A whale at depth is never quite still: a long, slow drift with a touch of
   roll, on a cycle far too slow to read as animation and just long enough to
   feel alive. Reduced-motion users get the still frame. */
.band img{width:min(560px,84cqw); margin:0 auto; opacity:.96}
.band .whale{animation:swim 14s ease-in-out infinite; transform-origin:60% 50%}
@keyframes swim{
  0%,100%{transform:translate3d(0,0,0) rotate(0deg)}
  25%    {transform:translate3d(-1.6%,-2.2%,0) rotate(-1.1deg)}
  50%    {transform:translate3d(0,-3.4%,0) rotate(0deg)}
  75%    {transform:translate3d(1.6%,-2.2%,0) rotate(1.1deg)}}
/* This is a line of verse, not a heading — so it takes the sacred face, and it
   breaks where the measure says rather than where a <br> once forced it. */
.band p{margin:clamp(14px,2cqw,24px) auto 0; max-width:22ch;
  font:200 22px/1.4 var(--display); letter-spacing:.06em; color:var(--ink);
  letter-spacing:.015em; text-wrap:balance}

/* ───────────────────────── избавься ───────────────────────── */
/* Six identical squares is a spreadsheet. This is a bento: the first and the
   last run the full width and turn on their side — drawing left, words beside
   it — while the four between them stay upright. The rhythm is wide, pair,
   pair, wide, which gives the block a beginning and an end instead of just
   stopping when the items run out. */
.free{display:grid; grid-template-columns:repeat(2,1fr); gap:clamp(9px,1.3cqw,15px);
  margin:clamp(20px,2.8cqw,34px) 0 0}
.free .cell{position:relative; overflow:hidden;
  padding:clamp(16px,2cqw,26px) 12px; border-radius:var(--r-xl); text-align:center;
  background:var(--glass); border:.5px solid var(--glass-brd);
  -webkit-backdrop-filter:var(--glass-blur); backdrop-filter:var(--glass-blur);
  box-shadow:var(--glass-rim);
  transition:background .5s var(--spring), transform .5s var(--spring),
             border-color .5s var(--spring)}
@media (hover:hover){
  .free .cell:hover{background:var(--glass-hi); transform:translateY(-3px);
    border-color:rgba(201,162,76,.30)}
  .free .cell:hover img{transform:scale(1.06)}
}
.free .cell:active{transform:scale(.985); transition-duration:.1s}
.free .cell img{width:clamp(48px,6.2cqw,70px); height:clamp(48px,6.2cqw,70px);
  object-fit:contain; margin:0 auto clamp(9px,1.3cqw,13px);
  transition:transform .6s var(--spring)}
.free .cell h3{margin:0; font:500 clamp(11px,1cqw,11px)/1.55 var(--ui);
  letter-spacing:.16em; text-transform:uppercase; color:var(--ink-2)}

/* the two wide ones */
.free .cell:first-child,.free .cell:last-child{grid-column:1 / -1;
  display:flex; align-items:center; gap:clamp(16px,2.6cqw,28px); text-align:left;
  padding:clamp(18px,2.2cqw,28px) clamp(20px,2.6cqw,30px)}
.free .cell:first-child img,.free .cell:last-child img{margin:0; flex:0 0 auto;
  width:clamp(62px,8cqw,88px); height:clamp(62px,8cqw,88px)}
.free .cell:first-child h3,.free .cell:last-child h3{
  font-size:clamp(13px,1.4cqw,15px); letter-spacing:.14em; color:var(--ink)}
/* The mark used to be a straight stroke pinned to the left edge, which meant
   it could never do anything with the corner — and the corner is the most
   expensive part of one of these cards. So the gold rides a ring laid exactly
   on the card's own outline: an inset layer with border-radius inherited,
   padded, and masked against itself so only the padding survives. That is what
   makes the light follow the radius instead of cutting across it.

   It does not run the whole lap. A light circling the card continuously is a
   loading spinner, and it draws the eye away from the words. Instead a short
   arc wakes up, swipes ONE corner, and goes out — visible for about a second
   in every fifteen, dark the rest of the time.

   The two cells take different corners and different periods, thirteen seconds
   against nineteen. Because those do not divide into one another, the pair
   almost never fires together and the rhythm does not repeat for minutes,
   which is what reads as "every so often" rather than as a loop.

   The angle is a registered custom property — the only way an angle
   interpolates rather than jumping. Unsupported, it holds at its initial value
   with opacity 0, so the effect is simply absent rather than broken. */
@property --edge{syntax:"<angle>"; inherits:false; initial-value:315deg}
.free .cell:first-child::after,.free .cell:last-child::after{content:"";
  position:absolute; inset:0; border-radius:inherit; padding:1.5px;
  pointer-events:none; opacity:0;
  background:conic-gradient(from var(--edge),
    var(--gold-hi) 0deg, rgba(201,162,76,.45) 5deg, rgba(201,162,76,0) 13deg,
    rgba(201,162,76,0) 347deg, rgba(201,162,76,.45) 355deg,
    var(--gold-hi) 360deg);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite:exclude}
/* The arc does not stop and restart at a corner. It keeps going — one full
   lap, every lap — and fades out while it is still travelling, so the light
   leaves the way a real reflection does rather than switching off. It waits
   for the reveal class, so the first pass happens as the section arrives
   rather than several screens earlier with nobody watching.

   The two cells start at opposite corners on thirteen and nineteen seconds.
   Those do not divide into one another, so the pair drifts and the rhythm does
   not repeat for minutes. */
.free .cell.in:first-child::after{animation:sweep-tl 13s linear infinite}
.free .cell.in:last-child::after{animation:sweep-br 19s linear infinite}
@keyframes sweep-tl{
  0%  {--edge:315deg; opacity:0}
  5%  {opacity:1}
  46% {opacity:.42}
  78% {opacity:0}
  100%{--edge:675deg; opacity:0}}
@keyframes sweep-br{
  0%  {--edge:135deg; opacity:0}
  5%  {opacity:1}
  46% {opacity:.42}
  78% {opacity:0}
  100%{--edge:495deg; opacity:0}}


/* ───────────────────────── segmented picker ─────────────────────────
   The one component in the iOS 16 kit that this page was missing. Read off
   the kit's own cover, where five instances agree: 343 × 32 on a 393pt
   canvas — so it is inset 25pt each side and exactly 32 tall, which is what
   makes it read as a control rather than a row of buttons.

   It drives the package shelf: three packages, three segments, and the shelf
   scrolls to the one you press. The shelf still swipes — the picker is the
   second way in, not a replacement, which is how iOS uses it. */
.seg{display:grid; grid-auto-flow:column; grid-auto-columns:1fr;
  width:min(343px,100%); height:32px; margin:clamp(18px,2.4cqw,26px) auto 0;
  padding:2px; border-radius:9px;
  background:var(--glass); border:.5px solid var(--glass-brd);
  box-shadow:var(--glass-rim)}
.seg button{border:0; background:none; cursor:pointer; border-radius:7px;
  font:500 13px/1 var(--ui); letter-spacing:0; color:var(--ink-2);
  -webkit-tap-highlight-color:transparent;
  transition:background .28s var(--spring), color .28s var(--spring),
             box-shadow .28s var(--spring)}
.seg button[aria-selected="true"]{background:rgba(158,206,224,.14); color:var(--ink);
  box-shadow:inset 0 .5px 0 rgba(214,238,247,.22), 0 1px 3px rgba(0,8,12,.5)}
.seg button:active{transform:scale(.97)}
.seg button:focus-visible{outline:2px solid var(--gold-hi); outline-offset:2px}

/* ───────────────────────── packages ─────────────────────────
   Two of the three package drawings are near-black (measured luma 5 and 26),
   so those cards are the one light surface in the app — which also puts the
   light exactly where the decision is made. The third carries a photograph and
   stays on a lift. */
/* A shelf, not a stack. Three package cards stacked vertically ran the Курс
   screen to 3,426px — a page, not an app screen. Paged horizontally with
   scroll-snap it is one screenful, which is how iOS shows a card shelf
   everywhere from the App Store to Fitness. The rail bleeds to both edges so a
   card is always half-visible at the margin, which is what tells a thumb there
   is more to the right. */
.tiers{display:grid; grid-auto-flow:column; grid-auto-columns:min(78%,320px);
  gap:clamp(12px,1.7cqw,20px); margin:clamp(22px,3cqw,36px) 0 0;
  overflow-x:auto; overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory; scroll-padding-inline:var(--pad);
  padding-inline:var(--pad); margin-inline:calc(-1 * var(--pad));
  scrollbar-width:none; -webkit-overflow-scrolling:touch}
.tiers::-webkit-scrollbar{display:none}
.tiers > *{scroll-snap-align:center}
.tier{display:flex; flex-direction:column; border-radius:var(--r-xl);
  padding:clamp(18px,2.1cqw,26px); background:var(--glass);
  border:.5px solid var(--glass-brd); box-shadow:var(--glass-rim)}
.tier.light{background:var(--paper); border-color:transparent; color:var(--paper-ink);
  box-shadow:0 26px 60px -30px rgba(0,0,0,.9)}
.tier.light .name{color:var(--paper-ink)}
.tier.light .fine{color:var(--paper-ink-2)}
.tier.light ul{color:var(--paper-ink-2)}
.tier.light h4{color:var(--gold-lo)}
.tier.light ul li::before{color:var(--paper-ink-2)}
.tier .art{width:auto; height:clamp(118px,15cqw,168px); object-fit:contain;
  margin:2px auto clamp(16px,2cqw,24px); display:block}
/* ── the package card, set as a document rather than a pile of paragraphs ──
   A card has four registers and they now look like four: the name, the tags,
   the part headings, and the lines under them. Each is separated from the next
   by size and by tracking rather than by space alone, which is what lets the
   card stay compact without reading as cramped. */
.tier .name{margin:0; font:400 clamp(22px,2.5cqw,26px)/1.14 var(--display);
  letter-spacing:.16em; color:var(--ink); text-align:center}

/* Each part gets a hairline over it, so the eye can see where theory ends and
   practice begins without reading a word. The rule is the divider; the label
   sits on it small and wide and never has to shout to be found. */
.tier h4{position:relative; margin:clamp(16px,2cqw,22px) 0 10px;
  padding-top:clamp(13px,1.6cqw,17px);
  font:500 10px/1.5 var(--ui); letter-spacing:.26em;
  text-transform:uppercase; color:var(--gold)}
.tier h4::before{content:""; position:absolute; left:0; right:0; top:0; height:.5px;
  background:var(--hair)}
.tier h4:first-of-type{margin-top:clamp(14px,1.8cqw,18px)}
.tier.light h4::before{background:var(--paper-hair)}

.tier ul{list-style:none; margin:0; padding:0; display:grid; gap:9px;
  font:300 12.5px/1.66 var(--ui); color:var(--ink-2); letter-spacing:.004em}
.tier ul li{display:flex; gap:10px}
/* A typed plus carries the font's weight and sits on the baseline. Drawn from
   two hairlines instead, it can be given its own weight, its own colour and an
   alignment to the x-height of the line it belongs to. */
.tier ul li::before{content:""; flex:0 0 auto; width:9px; height:9px;
  margin-top:.52em; color:var(--sea-hi); opacity:.8;
  background:linear-gradient(currentColor,currentColor) center/9px 1px no-repeat,
             linear-gradient(currentColor,currentColor) center/1px 9px no-repeat}
.tier.light ul li::before{color:var(--gold-lo); opacity:.7}

.tier .fine{margin:clamp(14px,1.8cqw,18px) 0 clamp(16px,2cqw,20px);
  font:300 11px/1.72 var(--ui); color:var(--ink-3); letter-spacing:.004em}
.tier .btn{margin-top:auto; width:100%; padding-inline:12px}
/* on the light card the filled button inverts, or it would vanish */
/* On the light card, bone-on-bone would vanish — the primary inverts to ink.
   The secondary keeps its accent, darkened for the paper. */
.tier.light .btn.bone{background:var(--paper-ink); color:var(--paper);
  box-shadow:inset 0 .5px 0 rgba(255,255,255,.14), 0 8px 22px -14px rgba(0,0,0,.5)}
.tier.light .btn.bone:hover{background:#22201B}

/* ───────────────────────── facts: Hyris rows ───────────────────────── */
.facts{margin:clamp(20px,2.8cqw,34px) 0 0; text-align:left}
.fact{break-inside:avoid; padding:16px 0; border-top:.5px solid var(--hair)}
.fact h3{margin:0 0 8px; font:500 11px/1.6 var(--ui); letter-spacing:.18em; color:var(--gold)}
.fact p{margin:0; font:300 13px/1.85 var(--ui); color:var(--ink-2)}
.closing{margin:clamp(24px,3.2cqw,40px) auto 0; max-width:34ch; text-align:center;
  text-wrap:balance;
  font:400 clamp(12px,1.5cqw,15px)/1.8 var(--ui); letter-spacing:.12em; color:var(--ink-2)}

/* ───────────────────────── FAQ: iOS inset list ───────────────────────── */
.faq{margin:clamp(20px,2.6cqw,32px) 0 0; background:var(--glass);
  border:.5px solid var(--glass-brd); border-radius:var(--r-l); overflow:hidden;
  box-shadow:var(--glass-rim)}
.faq details{position:relative}
.faq details + details::before{content:""; position:absolute; left:18px; right:0; top:0;
  height:.5px; background:var(--hair)}
.faq summary{cursor:pointer; list-style:none; padding:14px 17px; min-height:52px;
  display:flex; justify-content:space-between; gap:15px; align-items:center;
  font:400 13px/1.6 var(--ui); letter-spacing:0; color:var(--ink);
  transition:background .3s var(--spring)}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{background:rgba(255,255,255,.04)}
.faq summary::after{content:""; flex:0 0 auto; width:20px; height:22px;
  background:currentColor; color:var(--ink-3); opacity:.55;
  -webkit-mask:no-repeat center/7px 12px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 7 12'%3E%3Cpath d='M1 1l5 5-5 5' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  mask:no-repeat center/7px 12px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 7 12'%3E%3Cpath d='M1 1l5 5-5 5' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  transition:transform .35s var(--spring)}
.faq details[open] summary::after{transform:rotate(90deg)}
.faq details p{margin:0; padding:0 18px 16px; font:300 13px/1.82 var(--ui);
  color:var(--ink-2); max-width:74ch}
.faq details p + p{padding-top:0}

/* ───────────────────────── finale ─────────────────────────
   The white plate is knocked out of lakech.webp itself, so the wheel needs no
   mask and can be shown whole. Masking the old JPG to a disc cut a drawing
   that fills 63%×88% of its frame down to a token inside a glowing ring. */
.finale{min-height:70svh; display:flex; flex-direction:column; justify-content:center;
  text-align:center}
/* The line under this reads "slow your ageing", so the wheel turns at the
   speed that sentence describes: one revolution in four minutes. You cannot
   catch it moving — you can only notice, if you come back to it, that it is
   not where it was. That is the whole idea, and it is also why it is not a
   spinner: anything fast enough to read as motion would say the opposite. */
/* Two rotations, and they cannot share one element: a single transform can
   only run one animation, so the run-up lives on the wrapper and the endless
   turn on the image, and the two compose.

   The wrapper spins it up — two and a half turns in six seconds on a hard
   ease-out, so it arrives fast and is visibly losing speed the whole way —
   and holds where it stops. The image then carries on at one revolution every
   four minutes, forever. That is the line underneath rendered as motion:
   it does not stop, it just stops hurrying. */
/* Tried turning: a run-up into a four-minute revolution, to echo the line
   underneath. It reads as a loading spinner on a page that is otherwise still,
   and the wheel is the last thing before the invitation, so movement there
   competes with the button. Static, as it was. */
.lakech{display:block; width:clamp(104px,14cqw,152px);
  margin:0 auto clamp(18px,2.4cqw,28px);
  filter:drop-shadow(0 0 26px rgba(0,150,180,.28))}
/* the blessing is the last thing read, so it is set in the title face like the
   name it answers to — not in the interface face at display weight */
.finale h2{margin:0 0 15px; font:300 clamp(34px,4.2cqw,42px)/1.1 var(--display);
  letter-spacing:.2em}
.finale p{margin:0 0 7px; color:var(--ink-2); font-size:15px}
.finale .thanks{font:200 20px/1.46 var(--display); letter-spacing:.06em; color:var(--ink)}

footer{color:var(--ink-3); border-top:.5px solid var(--hair);
  padding:clamp(30px,3.8cqw,48px) 0 clamp(28px,3.4cqw,42px); text-align:center;
  font:300 12px/1.7 var(--ui)}
footer a{color:var(--ink-3)}
footer a:hover{color:var(--gold-hi)}
footer .row{display:flex; gap:clamp(4px,1.4cqw,18px); justify-content:center; flex-wrap:wrap;
  margin:0 0 8px; font:400 11px/1 var(--ui); letter-spacing:.15em; text-transform:uppercase}
/* footer links carry their own touchable height rather than sitting as 10px slivers */
footer .row a{display:inline-flex; align-items:center; min-height:44px; padding:0 7px}

/* ───────────────────────── arrival ───────────────────────── */
/* Things arrive; they do not appear. Items in a list arrive one after the
   next — a stagger short enough to read as one movement, long enough that the
   eye follows it down the list. */
/* Cheap motion is a fade and a slide, over in a third of a second. This is the
   same distance travelled across more than a second, with a scale so small it
   is never seen as a scale — only felt as the thing settling into its size
   rather than arriving at its place. Nothing about it is quick. */
.rv{opacity:0; transform:translateY(18px) scale(.986); transform-origin:50% 100%;
  transition:opacity 1.05s var(--spring), transform 1.05s var(--spring)}
.rv.in{opacity:1; transform:none}
.list .item.rv,.free .cell.rv,.fact.rv{transition-delay:calc(var(--i,0) * 62ms)}
.list .item:nth-child(1){--i:0}  .list .item:nth-child(2){--i:1}
.list .item:nth-child(3){--i:2}  .list .item:nth-child(4){--i:3}
.list .item:nth-child(5){--i:4}  .list .item:nth-child(6){--i:5}
.list .item:nth-child(7){--i:6}  .list .item:nth-child(8){--i:7}
.list .item:nth-child(9){--i:8}  .list .item:nth-child(10){--i:9}
.list .item:nth-child(11){--i:10}.list .item:nth-child(12){--i:11}
.free .cell:nth-child(1){--i:0} .free .cell:nth-child(2){--i:1}
.free .cell:nth-child(3){--i:2} .free .cell:nth-child(4){--i:3}
.free .cell:nth-child(5){--i:4} .free .cell:nth-child(6){--i:5}
.fact:nth-child(1){--i:0} .fact:nth-child(2){--i:1}
.fact:nth-child(3){--i:2} .fact:nth-child(4){--i:3}
@media (prefers-reduced-motion:reduce){
  *{transition:none!important; animation:none!important; scroll-behavior:auto}
  .rv{opacity:1; transform:none}
  /* the crown light is a place, not a movement — without the breath it just
     holds, so it stays */
  .buddha::before,.buddha::after{animation:none}
}
