/* ==========================================================================
   Frae homepage — overhaul layer. Loaded AFTER /next/base.css.
   Every block names the defect it fixes; delete a block to revert it.
   Tokens (--ink, --vermilion, --ease) come from the base stylesheet.
   ========================================================================== */

/* 0 · Cross-page hand-over ---------------------------------------------------------
   Pages that take part (the homepage and the product pages) opt in to cross-document View Transitions. The browser keeps
   the old page on screen and renders the new one; next/handoff.js then reveals the new page as a layer with the deck's own
   flowing edge by animating ::view-transition-new(root). The default cross-fade is switched off, and the new page is held
   hidden until that animation starts (a skipped transition simply shows the page). Not applied under reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
::view-transition-group(root), ::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
::view-transition-new(root) { clip-path: inset(0 0 0 100%); }
/* going back to the homepage the page you LEAVE is the one that moves (it peels away the way it arrived), so it stays on top
   and the new page is simply there beneath it */
html.vt-back::view-transition-old(root) { z-index: 2; }
html.vt-back::view-transition-new(root) { clip-path: none; }

/* 1 · Cover slide: no nav wordmark ------------------------------------------
   The cover already carries the large mark, so the small one is redundant.
   body.on-hero is set by overhaul.js (and server-rendered on <body> so there is
   no flash). visibility is delayed so the hidden link also leaves the tab order.
   The wordmark is an <a>, so the base sheet's `.nav a { opacity: .74 }` washed the
   logo out on every slide after the cover. Brand colour must never be dimmed. */
.nav .wm { opacity: 1; }
body.on-hero .nav .wm {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .35s ease, visibility 0s linear .35s;
}

/* 2 · Initial Frae loader ---------------------------------------------------
   Sequence: the cream letters appear on the ink ground, then the vermilion rises behind
   them like a liquid (a canvas drawn by overhaul.js: rising level, sloshing surface that
   settles flat), the mark holds, then it glides to the cover's own mark position while the
   ground dissolves into the cover (overhaul.js drives the hand-over).
   The logo FILE is never edited or redrawn. While the red is still absent, an SVG
   colour filter (#loader-letters, in index.html) keeps only the file's cream pixels;
   once the red block has flowed in, the filter is dropped and the approved logo shows
   exactly as supplied (its own red field is the same #E5483F as the block under it).
   Off by default; overhaul.js adds html.is-loading, so no-JS visitors never see it. */
.loader { display: none; }

html.is-loading { overflow: hidden; animation: loader-unlock 0s linear 6s forwards; }
html.is-loading .loader {
  display: block;
  position: fixed;
  inset: 0;
  z-index: 100;
  background-color: var(--ink);                       /* = cover ground, so the dissolve is seamless */
  transition: background-color .7s ease .1s, opacity .4s linear;
  animation: loader-failsafe 0s linear 6s forwards;
}
html.is-loading .loader.is-leaving { background-color: transparent; }   /* ground dissolves into the cover */
html.is-loading .loader.is-fading  { opacity: 0; }                        /* fallback: reduced motion / cover not showing */

/* the cover's own mark stays hidden while the loader's copy travels to its place */
html.is-loading .beat[data-first] .th-wm img { opacity: 0; }

.loader__logo {
  --w: clamp(150px, 26vw, 290px);
  position: absolute;
  width: var(--w);
  aspect-ratio: 561 / 238;                            /* the SVG's own ratio */
  left: calc(50% - var(--w) / 2);
  top: calc(50% - var(--w) * .2121);                  /* half the height: 238 / 561 / 2 */
  transition: left .9s var(--ease), top .9s var(--ease), width .9s var(--ease);
}
.loader__red,
.loader__mark {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}
/* .loader__red is a canvas: the liquid is solid #E5483F, no gradient or tint. When it has filled the
   box, .is-filled swaps it for the same colour as a plain CSS background (crisp when scaled by the glide). */
.loader__logo.is-filled { background: var(--vermilion); }
.loader__logo.is-filled .loader__red { display: none; }
.loader__mark {
  opacity: 0;
  filter: url(#loader-letters);                        /* letters only, until the red is in place */
  animation: loader-letters .45s var(--ease) .1s forwards;
}
.loader__logo.is-filled .loader__mark { filter: none; }  /* the approved logo, exactly as supplied */
.loader__sr {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@keyframes loader-letters { to { opacity: 1; } }
/* Failsafe: if the script dies mid-load the page must not stay covered or locked. */
@keyframes loader-failsafe { to { visibility: hidden; opacity: 0; pointer-events: none; } }
@keyframes loader-unlock { to { overflow: visible; } }

@media (prefers-reduced-motion: reduce) {
  .loader__red  { display: none; }
  .loader__logo { background: var(--vermilion); }
  .loader__mark { animation: none; opacity: 1; filter: none; }
}

/* 3 · Cover product row: highlight, alignment, Arabic direction --------------
   3a. Highlight box must contain the script's ink. Measured (34.56px type):
       Arabic ink descends .26em below the baseline; the box reached only .142em,
       so ~4px of the glyph hung outside it. Extra bottom padding only — the top
       padding must stay equal to the overlay <i> (.04em) so the two text layers
       stay registered. */
.th-products .hl { padding-bottom: .3em; }

/* 3b. Baseline-align the three scripts. Devanagari and Arabic sit at different
       baseline offsets inside identical boxes (font ascent/descent differ), so the
       Arabic read ~2px low. A two-row subgrid lets the scripts share a baseline
       while the Latin labels below share their own row. Longhand gaps override the
       base sheet's `gap` shorthand (which would otherwise set row-gap to 34px). */
.th-products {
  display: grid;
  grid-auto-flow: column;
  grid-template-rows: auto auto auto;                  /* a heading row, then the scripts, then the Latin labels */
  grid-auto-columns: max-content;
  justify-content: start;
  column-gap: clamp(14px, 2.4vw, 34px);
  row-gap: 5px;
}
.th-products .prod { display: grid; grid-template-rows: subgrid; grid-row: 2 / span 2; }
/* the heading of the row: "Our Products :" (the Frae cover; the label style the rest of the page uses) */
.th-plabel { grid-column: 1 / span 3; grid-row: 1; margin-bottom: clamp(6px, 1vh, 12px); font-family: var(--display); font-size: var(--t-label); font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--fg-3); }
html[lang=hi] .th-plabel { letter-spacing: 0; text-transform: none; }
.th-products .prod .s { align-self: baseline; }

/* 3c. Arabic highlight sweeps right→left (reading direction), on entrance and on
       hover. Mirror of the base `sweep` keyframes. */
.ar .hl > i { clip-path: inset(0 0 0 100%); }
.beat.live .ar .hl > i { animation-name: sweep-rtl; }
.ar .hl:hover > i,
.ar .hl:focus-visible > i { clip-path: inset(0 0 0 0); }
@keyframes sweep-rtl {
  0%   { clip-path: inset(0 0 0 100%); }
  36%  { clip-path: inset(0 0 0 0); }
  60%  { clip-path: inset(0 0 0 0); }
  to   { clip-path: inset(0 100% 0 0); }
}

/* 4 · No page scrollbar ------------------------------------------------------
   The deck is driven by click, keys, wheel and touch; the native bar only added
   chrome beside the cover. Scrolling itself is unchanged. */
html { scrollbar-width: none; }
html::-webkit-scrollbar { display: none; }

/* 5 · Life: wire the deck engine's reveal hooks -------------------------------
   The engine tags every .b block with --bi (reading order) and toggles .live on the
   slide that has arrived, but the base stylesheet never consumed either, so no slide
   ever assembled. Reveal = rise + fade, staggered by --bi (capped), replayed on every
   visit because the engine drops .live when a slide leaves. Reduced motion: the base
   sheet's `.b { opacity: 1 !important; transform: none !important }` already wins. */
.beat .b { opacity: 0; }
.beat.live .b {
  animation: b-rise .85s var(--ease) calc(min(var(--bi, 0) * 75ms, 700ms) + 140ms) both;
}
@keyframes b-rise { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }

/* the cover's mark is handed over by the loader (section 2); it must never animate itself */
#b00 .th-wm.b { opacity: 1; animation: none; }

/* rules draw in from the left; eyebrow diamond pops, its dash draws */
.beat .rule.b { transform-origin: left center; }
.beat.live .rule.b { animation-name: b-draw; }
@keyframes b-draw { from { opacity: 1; transform: scaleX(0); } to { opacity: 1; transform: none; } }

.beat .eyebrow:before { transform: scale(0); transition: transform .6s var(--ease) .25s, background-color .5s ease; }
.beat.live .eyebrow:before{ transform: none; }
.beat .eyebrow s { transform: scaleX(0); transform-origin: left center; transition: transform .9s var(--ease) .45s, background-color .5s ease; }
.beat.live .eyebrow s{ transform: none; }

/* the contour artwork drifts slowly while its slide is showing (transform only: GPU, no repaint) */
.beat.live .motif:before{ animation: motif-drift 32s ease-in-out infinite alternate; }
@keyframes motif-drift {
  from { transform: translate3d(-1.4%, -1%, 0) scale(1.02); }
  to   { transform: translate3d(1.4%, 1%, 0) scale(1.07); }
}

/* hover: cards and buttons lift. `translate` is its own property, so it neither fights
   the reveal's `transform` nor needs the originals' transitions rewritten (they are repeated). */
.prod-card { transition: background-color .35s ease, border-color .35s ease, color .35s ease, translate .4s var(--ease); }
.prod-card:hover, .prod-card:focus-visible { translate: 0 -4px; }
.btn { transition: background-color .35s ease, color .35s ease, border-color .35s ease, translate .35s var(--ease); }
.btn:hover, .btn:focus-visible { translate: 0 -2px; }

@media (prefers-reduced-motion: reduce) {
  .beat.live .motif:before{ animation: none; }
  .beat .eyebrow:before, .beat .eyebrow s { transform: none; transition: none; }
  .prod-card:hover, .prod-card:focus-visible, .btn:hover, .btn:focus-visible { translate: none; }
}

/* 6 · Contour field + liquid ground, behind EVERY slide ---------------------------
   One fixed canvas (created by field.js) paints the slide ground and the drifting contour lines.
   Between slides of different tone the next ground rises through the old like a liquid, driven by
   the scroll position. It replaces the base sheet's .ground colour and the static wave watermark.
   No script / no canvas support: neither rule below applies and the original look remains. */
.field-bg { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; display: block; }
html.has-field .ground { background-color: transparent !important; }
html.has-field .motif { display: none; }

/* Zone tones. The base sheet recolours the nav, footer and hint from the body's tone, which flips at the
   MIDPOINT of a slide change. With a liquid ground that is wrong for the edges: the top of the screen is
   still the old colour until the liquid reaches it. field.js tags each of these with the tone of the ground
   actually behind it; these are the base sheet's own tone tokens, applied per element. */
[data-zone="ink"]       { --fg: var(--paper); --fg-2: #D8D3C7; --fg-3: #ADA79A; --line: #332F2B; --accent: var(--vermilion); --accent-text: var(--vermilion-lt); --hl-bg: var(--paper); --hl-fg: var(--ink); }
[data-zone="paper"]     { --fg: var(--ink); --fg-2: #3A3833; --fg-3: var(--ink-muted); --line: var(--paper-rule); --accent: var(--vermilion); --accent-text: var(--ink); --hl-bg: var(--ink); --hl-fg: var(--paper); }
[data-zone="vermilion"] { --fg: var(--paper); --fg-2: var(--paper); --fg-3: var(--ink); --line: rgba(247, 244, 237, .4); --accent: var(--paper); --accent-text: var(--ink); --hl-bg: var(--ink); --hl-fg: var(--paper); }

.menu-btn[data-zone] { color: var(--fg); }
.nav .pm[data-zone] { color: var(--fg); }   /* the product's mark takes the zone's colour, so it changes where its own background changes (field.js) */
/* English only (the reviewer, 18 Oct 2026): i18n.js no longer draws the language switcher, so its empty slot in the menu goes too (the markup is still emitted by the page generators) */
.langs, .lang-li, #navlist li:has(> .langs) { display: none !important; }
/* phones narrower than 440 px: after the cover the top bar holds the logo, the product's mark, the call-to-action and the menu button, and that is wider than the screen (measured: Samanvay needs 438 px, Saksham 424 px).
   The menu button was squeezed to 18 px at 390 px and pushed off the screen from 360 px down (x = 359 on a 360 px screen, so the menu could not be opened). The bar's call-to-action goes at these widths
   (the cover, the last slide and the page's own buttons still carry it) and the menu button keeps its 44 px at the right edge. */
@media (max-width: 900px) { .nav .menu-btn { flex-shrink: 0; } }
/* phone menu open: its Ink panel fills the top bar, so the product's mark and Saksham's breadcrumb read in Paper whatever the slide's tone (they kept the slide's dark ink on a paper slide: about 1.2:1 on the panel) */
@media (max-width: 900px) { .nav:has(.menu-btn[aria-expanded="true"]) :is(.pm, .dn-sw, .dn-now) { color: var(--paper) !important; } }
/* 20 Oct 2026 (the CEO): the call-to-action is no longer dropped at these widths, it moves into the menu (deck.js, ctaIntoMenu) and reads as the
   menu's last item, set apart by a rule above it. The selector below still hides it if it is in the BAR (a direct child of .nav) — so if the script
   never runs, the menu button keeps its place at the right edge exactly as before, and nothing is pushed off the screen. */
@media (max-width: 440px) { .nav > .nav-cta--bar { display: none !important; } .nav .menu-btn { margin-left: auto; } }
@media (max-width: 440px) {
  .nav ul .nav-cta-li { margin-top: 6px; padding-top: 14px; border-top: 1px solid var(--line); }
  .nav ul .nav-cta-li .nav-cta--bar { display: inline-flex; align-items: center; min-height: 44px; }
}
/* phones and tablets: a slide's box starts below the whole top bar and ends above the footer. Measured on 360x640: the bar's logo ends at 60 px and the footer starts at 592 px, while the box ran from 54 to 599 px
   (the first line touched the logo, the last line was printed over by the footer); on 390x844 both were already clear, so those sizes do not change */
@media (max-width: 900px) { .frame { padding-top: max(clamp(52px, 8.4vh, 72px), 72px); padding-bottom: max(clamp(40px, 6.4vh, 56px), 124px); } }
/* ...and 124 px at the bottom: the previous/next arrows (44 px, 65 px above the bottom; the cover's 52 px button the same) stand at the two corners over the footer's top, and the content used to run under them (the
   first letters of a link under an arrow took the tap: "Open Tamkeen", a line of Samanvay's slide 5). The slide's box now ends above them, and a scrolling slide fades out at that edge. */
/* phones: a slide's frame marked [data-scroll] (deck.js; the slides of Saksham have their own region and are not marked) scrolls when its content is taller than the screen. The box is the frame between
   its padding (72 px at the top, 124 px at the bottom), the content fades out under the top bar and the footer while it scrolls, and a short slide stays centred (safe center, below) */
@media (max-width: 900px) {
  .frame[data-scroll] { overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; scrollbar-width: thin;
    justify-content: flex-start !important; justify-content: safe center !important;   /* safe center: a short slide stays centred, a tall one starts at the top (plain center would put its top beyond reach); flex-start is the fallback of a browser without safe; !important because a page's own sheet sets center on its frames */
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, transparent 58px, #000 72px, #000 calc(100% - 124px), transparent calc(100% - 112px));
            mask-image: linear-gradient(to bottom, transparent 0, transparent 58px, #000 72px, #000 calc(100% - 124px), transparent calc(100% - 112px)); }
}
/* landscape phones (under 900 px wide and under 500 px tall): the arrows stand in the side margins, so the slide keeps side gutters wide enough for them (60 px: they run from 8 to 52 px) and only the footer's
   56 px at the bottom, not 124 px; the box is 68 px taller (194 px at 390 px high would show three lines) */
@media (max-width: 900px) and (max-height: 500px) {
  .frame { padding-left: max(var(--gut), 60px); padding-right: max(var(--gut), 60px); padding-bottom: max(clamp(40px, 6.4vh, 56px), 56px); }
  .frame[data-scroll] { -webkit-mask-image: linear-gradient(to bottom, transparent 0, transparent 58px, #000 72px, #000 calc(100% - 56px), transparent calc(100% - 44px));
                                mask-image: linear-gradient(to bottom, transparent 0, transparent 58px, #000 72px, #000 calc(100% - 56px), transparent calc(100% - 44px)); }
}
.deck-foot__legal[data-zone], .deck-foot__links[data-zone] { color: var(--fg-3); }

/* the published version, stamped into dist by scripts/assemble-v2.mjs (VEL-CAP-0558). Quiet: it is for support and for telling
   two deploys apart, not something to read before the legal line. */
.deck-foot__ver{font-variant-numeric:tabular-nums;letter-spacing:.04em;opacity:.55;margin-right:.6ch}
body.on-hero .deck-foot [data-zone] { --fg: var(--ink); --fg-3: var(--ink-muted); }   /* on the cover the footer sits on the Paper panel */

/* Pause control (WCAG 2.2.2). Not shown to sighted pointer users by design; it is a real button that is
   reachable with Tab, appears when focused, and is announced to screen readers. */
.field-pause {
  position: fixed; z-index: 60; left: var(--gut); bottom: clamp(60px, 9vh, 88px);
  width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%);
  border: 0; background: transparent; color: var(--paper);
}
.field-pause:focus-visible {
  width: 40px; height: 40px; margin: 0; overflow: visible; clip-path: none;
  display: grid; place-items: center; cursor: pointer;
  background: var(--ink); border: 1px solid var(--paper-rule);
}
.field-pause::before { content: ""; width: 10px; height: 12px; border-left: 3px solid currentColor; border-right: 3px solid currentColor; }
.field-pause.is-paused::before { width: 12px; height: 14px; border: 0; background: currentColor; clip-path: polygon(0 0, 100% 50%, 0 100%); }

/* 7 · Cover layout: stage + docked Paper panel ---------------------------------
   Stage (top): the cover mark over the contour field, with hairline column guides.
   Panel (bottom): a full-bleed PAPER block holding the label, the statement and the three
   products, ruled into the same columns as the guides. Paper, not Vermilion: the brand pack
   reserves vermilion for one accent per layout (here the logo field) and rates Ink on Paper
   at 16.3:1. Only strings that already exist are used, so nothing new needs translating. */
:root { --cover-cols: var(--gut) minmax(0, 2fr) minmax(0, 1fr) var(--gut); }

#b00 .frame { display: grid; grid-template-rows: 1fr auto; justify-content: stretch; padding: 0; }
#b00 .frame > .th-stage,
#b00 .frame > .th-panel { max-width: none; width: 100%; margin: 0; position: relative; z-index: 1; }

.th-stage {
  display: flex; align-items: center;
  padding: clamp(78px, 9.6vh, 120px) var(--gut) clamp(24px, 4vh, 48px);
}
.th-stage > .th-wm { position: relative; z-index: 1; }

.th-panel {
  /* the panel reads on Paper whatever the body tone is */
  --fg: var(--ink); --fg-2: #3A3833; --fg-3: var(--ink-muted); --line: var(--paper-rule);
  --hl-bg: var(--ink); --hl-fg: var(--paper); --accent-text: var(--ink);
  background: var(--paper); color: var(--ink);
  display: grid; grid-template-columns: var(--cover-cols); align-items: end;
  padding: clamp(26px, 4.4vh, 46px) 0 clamp(54px, 7.6vh, 76px);   /* bottom leaves room for the fixed footer line */
}
.th-panel__lead { grid-column: 2; }
.th-panel__lead,
.th-panel > .th-products { padding-inline: clamp(20px, 3vw, 44px); }
.th-panel > .th-products { grid-column: 3; margin: 0; align-self: stretch; align-content: end; }
.th-panel .th-punch { margin-top: clamp(12px, 1.8vw, 24px); }
.th-panel .th-name { margin-top: 0; }

/* the panel waits below the fold until the cover is live */
#b00:not(.live) .th-panel { transform: translateY(100%); }

/* the panel rises into place as the loader hands over */
.beat.live .th-panel { animation: panel-up .95s var(--ease) .1s both; }
@keyframes panel-up { from { transform: translateY(100%); } to { transform: none; } }

/* narrower desktops and tablets: one column; guides keep only the outer gutters */
@media (max-width: 1100px) {
  :root { --cover-cols: var(--gut) minmax(0, 1fr) var(--gut); }
  .th-panel { align-items: start; row-gap: clamp(14px, 2.4vh, 24px); }
  .th-panel__lead { grid-column: 2; }
  .th-panel > .th-products { grid-column: 2; grid-row: 2; padding-block: clamp(10px, 1.6vh, 16px) 0; border-top: 1px solid var(--paper-rule); align-self: auto; }
}

@media (prefers-reduced-motion: reduce) {
  .beat.live .th-panel { animation: none; }
}

/* 8 · Nav: spaced uppercase links, centred between mark and actions (desktop) ---------
   Inter 600 with tracking, matching the brand's Label style (labels are the one uppercase
   style in the pack; nav links are treated as labels). Devanagari must not be letter-spaced. */
@media (min-width: 901px) {
  .nav ul { flex: 1; display: flex; align-items: center; gap: clamp(22px, 2.6vw, 44px); }
  .nav ul > li:first-child { margin-left: auto; }          /* two auto margins centre the links */
  .nav ul > li:nth-last-child(2) { margin-left: auto; }     /* ...in the space between mark and actions (the call to action is the last link, before the language switch) */
  .nav ul a { font-size: 12px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; opacity: 1; color: var(--fg-2); }
  .nav ul a:hover, .nav ul a:focus-visible { color: var(--fg); }
  .nav ul > li:nth-last-child(2) a { padding-bottom: 5px; border-bottom: 1px solid var(--line); }
  .langs { margin-left: 0; }

  /* Final (Vermilion) slide. Paper on Vermilion is only 3.59:1, so the base sheet backs the nav with
     Ink: one backing on the <ul>, which used to hug a compact link group. With the links now spread
     (centred group + actions) that backing became a full-width bar. Back each group instead: the
     <li>s sit edge to edge, so the centre links form one Ink chip and CTA + language the other. */
  body[data-tone] .nav ul { background: transparent; padding: 0; gap: 0; align-items: stretch; }   /* never the base sheet's whole-list backing */
  .nav ul > li { display: flex; align-items: center; padding: 9px clamp(11px, 1.3vw, 22px); color: var(--fg); transition: background-color .35s ease; }   /* constant spacing; the Ink backing fades in */
  .nav ul > li[data-zone="vermilion"] { background: var(--hl-bg); }
  .nav ul > li[data-zone="vermilion"] a { color: var(--hl-fg); }
}
html[lang=hi] .nav ul a { letter-spacing: 0; text-transform: none; font-size: 14px; }

/* 9 · Hint pill and footer on the new cover -----------------------------------------
   The pill was Ink-on-Vermilion, which the brand pack disallows, and it would now sit on the
   panel. It inverts the ground instead (Paper on Ink, Ink on Paper) and clears the panel;
   overhaul.js publishes the panel height as --panel-h. On the cover the footer line sits on
   Paper, so it takes Ink Muted (6.88:1). */
.hint { background: var(--ink); color: var(--paper); border: 1px solid #332F2B; }   /* a dark box on every slide */
body.on-hero .hint { bottom: calc(var(--panel-h, 0px) + 22px); }
body.on-hero .deck-foot { --fg: var(--ink); --fg-3: var(--ink-muted); }

/* 10 · The cover has no "back": the left-edge chevron is hidden while the cover shows, and the deck
   engine's step() no longer wraps from the cover to the last slide (see the inline engine in index.html).
   Home / End still jump explicitly. */
body.on-hero .edge-l { display: none; }

/* 11 · "White boxes" on Ink slides are dark -----------------------------------------------------
   On the Ink slides every Paper-filled box is now Ink: the stack slide's layer cards (the base sheet hard-codes them
   Paper with Ink titles), the hint pill, and the active language button. Ink on Ink has no edge, so each keeps a
   hairline (#332F2B, the Ink-tone line colour) and still reads as a box. The cover's Paper panel is a separate,
   deliberate choice and is unchanged. */
.beat[data-tone="ink"] .layer { background: var(--ink); border-color: var(--line); }
.beat[data-tone="ink"] .layer h3 { color: var(--paper); }
li[data-zone="ink"] .langs button[aria-current="true"] { background: transparent; color: var(--paper); border-color: var(--paper); }

/* 12 · A slide that holds the visitor (<section data-hold>, next/deck.js): no "next" chevron and no hint while it does */
body[data-gated] .edge-r, body[data-gated] .hint { display: none; }

/* 13 · The click strips at the two borders are the same size (next/deck.js zone(): same clamp). Only they move the deck on a click, so
   selecting and copying text in the middle of a page is safe. */
.edge { width: clamp(80px, 10vw, 180px); }

/* 14 · The invitation on the first slide of a page that has more (next/deck.js syncFirst): a square button with a large arrow, at the vertical centre of the right-hand gutter (the middle of the screen, where the strip's own chevron appears; the scroll hint is kept up at the foot).
   It sits in the strip that already moves the deck on (section 13) and does the same: a click, a tap or Enter goes to the next slide. It is drawn as a button (a ruled box, lightly filled, filled solid on hover, on focus and
   while the pointer is anywhere in the right-hand strip), and it keeps to the gutter (--gut, the page's side margin), so it never lies over a page's content. It reads the tokens of the slide it sits on (--fg on --ground).
   Hidden while a loading screen is up and while a slide holds the visitor. On the homepage it stands on the cover, just above the Paper panel. The arrow's nudge (not the box) is stilled under reduced motion. */
.cue { --cue: clamp(46px, calc(var(--gut) - 16px), 72px); position: fixed; right: 4px; top: 50%; margin-top: calc(var(--cue) / -2); z-index: 49; box-sizing: border-box; width: var(--cue); height: var(--cue); padding: 0; cursor: pointer;
  color: var(--fg); background: color-mix(in srgb, var(--fg) 14%, transparent); border: 1.5px solid var(--fg);
  opacity: 0; visibility: hidden; transition: opacity .6s ease .5s, visibility 0s linear 1.1s, background-color .2s ease, color .2s ease, transform .15s ease; }
body.at-first .edge-r, body.at-first.hint-r .edge-r { opacity: 0; }   /* the button takes the strip's chevron's place while the first slide shows */
body.at-first .cue { opacity: 1; visibility: visible; transition-delay: .5s, 0s, 0s, 0s, 0s; }
.cue i { position: absolute; left: 21%; right: 21%; top: 50%; height: 3px; margin-top: -1.5px; background: currentColor; animation: cue-nudge 2s var(--ease) infinite; }
.cue i::after { content: ""; position: absolute; right: 0; top: 50%; width: 20px; height: 20px; margin-top: -10px; border: solid currentColor; border-width: 3px 3px 0 0; transform: translateX(-2px) rotate(45deg); }
@keyframes cue-nudge { 0%, 100% { transform: translateX(-4px); } 50% { transform: translateX(4px); } }
.cue:hover, .cue:focus-visible, body.hint-r .cue { background: var(--fg); color: var(--ground); }
.cue:active { transform: scale(.95); }
.cue:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
html.is-loading .cue, html.is-loading .hint, body[data-gated] .cue { opacity: 0 !important; visibility: hidden !important; transition: none; }
@media (max-width: 900px) { .cue { --cue: 52px; right: 8px; top: auto; margin-top: 0; bottom: 65px; } body.on-hero .cue { bottom: calc(var(--panel-h, 0px) + 29px); }   /* a phone's page runs to its edges: the button waits at the foot, beside the hint */
  .cue i { left: 18%; right: 18%; } .cue i::after { width: 16px; height: 16px; margin-top: -8px; } }
@media (prefers-reduced-motion: reduce) { .cue i { animation: none; } .cue { transition-duration: .01s; } }
@media print { .cue { display: none; } }

/* 15 · A product's own small mark, next to the Frae mark, once the cover has gone (the cover carries the large one): Saksham's icon, Samanvay's name. It takes the visitor back to the product's first slide;
   the Frae mark still opens the Frae homepage. (A page with no cover of its own, Founding or the readiness check, shows it all the time.) */
.nav .pm { pointer-events: auto; display: flex; align-items: center; gap: 10px; min-height: 44px; margin-left: clamp(12px, 1.4vw, 22px); padding-left: clamp(12px, 1.4vw, 22px); border-left: 1px solid var(--line); line-height: 1;
  color: var(--fg); transition: opacity .35s ease, visibility 0s; }
.nav .pm:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.nav .pm:hover { opacity: .8; }
body.at-hero .nav .pm { opacity: 0; visibility: hidden; pointer-events: none; transition: opacity .35s ease, visibility 0s linear .35s; }
.nav .pm b { font-family: var(--display); font-weight: 600; font-size: clamp(16px, 1.3vw, 19px); letter-spacing: -.02em; }

/* 16 · "Request a proposal" (Saksham) and "Register your interest" (Samanvay) on every slide after the cover (the cover has its own button, so body.at-hero hides this one): a button in the middle of the footer band,
   where nothing else lives (the legal line is at the left, the legal links at the right, and the two click strips at the borders stay clear of it, so a click there never goes to it by mistake). The nav has no room for it
   at laptop widths (it carries six links), so on a phone it is a compact link beside the menu button instead. The product's own button tokens (--btn-bg, --btn-fg and the hover pair, set on body[data-tone]). */
.nav .nav-cta--bar { display: none; }
.pcta { position: fixed; left: 50%; bottom: 11px; transform: translateX(-50%); z-index: 48; display: inline-flex; align-items: center; gap: 10px; padding: 9px 20px; background: var(--btn-bg); color: var(--btn-fg);
  font-family: var(--display); font-size: 14px; font-weight: 600; line-height: 1.2; letter-spacing: -.005em; text-decoration: none; white-space: nowrap; transition: background-color .3s ease, color .3s ease, opacity .35s ease; }
.pcta i { font-style: normal; transition: transform .2s ease; }
.pcta:hover, .pcta:focus-visible, .nav .nav-cta--bar:hover, .nav .nav-cta--bar:focus-visible { background: var(--btn-hv-bg); color: var(--btn-hv-fg); }
.pcta:hover i { transform: translateX(3px); }
.pcta:focus-visible, .nav .nav-cta--bar:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
body.at-hero .pcta, body.at-hero .nav .nav-cta--bar, html.is-loading .pcta, body[data-gated] .pcta { opacity: 0; visibility: hidden; pointer-events: none; }
@media (max-height: 800px) { .pcta { bottom: 9px; padding: 7px 16px; font-size: 13px; } }
@media (max-width: 900px) {
  .pcta { display: none; }
  .nav .nav-cta--bar { display: inline-block; align-self: center; margin-left: auto; margin-right: 10px; padding: 9px 12px; background: var(--btn-bg); color: var(--btn-fg); font-family: var(--display); font-size: 12px; font-weight: 600; line-height: 1; letter-spacing: .01em; white-space: nowrap; text-decoration: none; opacity: 1; pointer-events: auto; transition: background-color .3s ease, color .3s ease, opacity .35s ease; }
}
/* between a phone and a laptop the legal line and the legal links give the centre to the button: the line sets in two rows, the links in two */
@media (min-width: 901px) and (max-width: 1180px) { body:has(.pcta) .deck-foot__legal { max-width: 28%; } body:has(.pcta) .deck-foot__links { max-width: 32%; } }
@media print { .pcta { display: none; } }

/* 17 · Previous and next on every slide after the first (next/deck.js): bare arrows, one at each edge at the vertical centre, in the page's side margin (--gut) so they lie over no content. No box, no fill: they are
   drawn like the arrow in the hero's button but without the button. Real <button>s underneath. They read the tokens of the slide they sit on (--fg). The first slide has the hero's arrow button instead, so the previous
   arrow is not there and the next one is not (body.at-first); the last slide has no next (body.at-last); a slide that holds the visitor has no next either (body[data-gated]). On a phone they stand at the two bottom corners.
   The chevrons that used to show when the pointer was over an edge strip are redundant now and are not drawn. */
.arw { --arw: clamp(36px, calc(var(--gut) - 14px), 56px); position: fixed; top: 50%; margin-top: calc(var(--arw) / -2); z-index: 48; width: var(--arw); height: var(--arw); padding: 0; background: transparent; border: 0; color: var(--fg); cursor: pointer;
  opacity: 0; visibility: hidden; transition: opacity .35s ease, visibility 0s linear .35s, color .5s ease; }
.arw--prev { left: 4px; } .arw--next { right: 4px; }
.arw i { position: absolute; left: 6px; right: 6px; top: 50%; height: 2px; margin-top: -1px; background: currentColor; transition: transform .25s ease; }
.arw i::after { content: ""; position: absolute; top: 50%; width: 14px; height: 14px; margin-top: -7px; border: solid currentColor; }
.arw--next i::after { right: 0; border-width: 2px 2px 0 0; transform: translateX(-1px) rotate(45deg); }
.arw--prev i::after { left: 0; border-width: 0 0 2px 2px; transform: translateX(1px) rotate(45deg); }
.arw--next:hover i, .arw--next:focus-visible i { transform: translateX(4px); } .arw--prev:hover i, .arw--prev:focus-visible i { transform: translateX(-4px); }
.arw:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
body:not(.at-first) .arw--prev, body:not(.at-first):not(.at-last) .arw--next { opacity: .9; visibility: visible; transition-delay: .2s, 0s, 0s; }
body:not(.at-first) .arw:hover, body:not(.at-first) .arw:focus-visible { opacity: 1; }
html.is-loading .arw, body[data-gated] .arw--next { opacity: 0 !important; visibility: hidden !important; transition: none; }
body.has-arw .edge { display: none; }
@media (max-width: 900px) { .arw { --arw: 44px; top: auto; margin-top: 0; bottom: 65px; } .arw--prev { left: 8px; } .arw--next { right: 8px; } }
@media (prefers-reduced-motion: reduce) { .arw, .arw i { transition-duration: .01s; } }
@media print { .arw { display: none; } }
