/* ==========================================================================
   TOKI — marketing site
   --------------------------------------------------------------------------
   Dark by default, because the product is: the tokens below are the app's
   Charcoal palette (client_app/lib/core/theme/theme_catalog.dart) verbatim, so
   the site and the app cannot drift apart. The light theme is the app's
   Daylight palette, same rule.

   The one idea the whole design runs on: TOKI is two voices. Speaker A is
   teal, Speaker B is violet, everywhere — the hero, the steps, the language
   grid, the use-case cards. Red stays what it is in the app: the brand, and
   the live microphone. It is never decoration.
   ========================================================================== */

@import url("fonts.css");

/* --------------------------------------------------------------- tokens */

:root {
  /* Charcoal — the app's dark theme, token for token. */
  --bg:            #16171B;
  --surface:       #1D1F24;
  --surface-alt:   #26282F;
  --surface-sunk:  #121317;
  --line:          #32353D;
  --line-strong:   #464A55;
  --text:          #F3F3F5;
  --text-2:        #AFB1BB;
  --text-3:        #82858F;
  --brand:         #FF4747;
  --brand-strong:  #E01F1F;
  --brand-text:    #FF4747;
  --brand-subtle:  #2B171A;
  --on-brand:      #FFFFFF;
  --a:             #2DD4BF;   /* Speaker A */
  --b:             #A99BFF;   /* Speaker B */
  --success:       #34D399;
  --warning:       #E0A034;

  --a-wash:        rgba(45, 212, 191, .12);
  --b-wash:        rgba(169, 155, 255, .12);
  --brand-wash:    rgba(255, 71, 71, .12);
  --glass:         rgba(29, 31, 36, .72);
  --shadow-1:      0 1px 2px rgba(0, 0, 0, .4);
  --shadow-2:      0 8px 24px -8px rgba(0, 0, 0, .55);
  --shadow-3:      0 32px 64px -24px rgba(0, 0, 0, .7);
  --cta-shadow:    0 6px 20px -8px rgba(224, 31, 31, .8);
  --cta-shadow-hi: 0 12px 28px -10px rgba(224, 31, 31, .9);

  /* Type. Inter carries everything; Barlow Condensed is the eyebrow/stat
     voice, borrowed from brivfy.com so the two products read as siblings. */
  --sans: "Inter", "Noto Sans Thai", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --cond: "Barlow Condensed", "Inter", system-ui, sans-serif;
  --deva: "Noto Sans Devanagari", "Nirmala UI", "Kohinoor Devanagari", system-ui, sans-serif;
  --thai: "Noto Sans Thai", "Leelawadee UI", "Thonburi", system-ui, sans-serif;

  /* A 1.22 scale, each step fluid between a 360px phone and a 1440px desktop.
     The two display steps are capped deliberately low for their size: the hero
     headline is three lines of it, and at 90px that was the entire viewport. */
  --step--1: clamp(.82rem, .79rem + .13vw, .89rem);
  --step-0:  clamp(1rem, .96rem + .18vw, 1.08rem);
  --step-1:  clamp(1.12rem, 1.06rem + .28vw, 1.3rem);
  --step-2:  clamp(1.35rem, 1.22rem + .55vw, 1.7rem);
  --step-3:  clamp(1.7rem, 1.42rem + 1.15vw, 2.4rem);
  --step-4:  clamp(2rem, 1.6rem + 1.75vw, 3.15rem);
  --step-5:  clamp(2.5rem, 1.75rem + 3.1vw, 4.4rem);

  --gutter: clamp(1.15rem, .6rem + 2.4vw, 2.5rem);
  --section-y: clamp(4rem, 2.8rem + 4.4vw, 7rem);
  --wide: 1200px;
  --narrow: 720px;

  --r-sm: 10px;
  --r:    16px;
  --r-lg: 24px;
  --r-xl: 34px;

  --ease: cubic-bezier(.22, .61, .36, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);

  color-scheme: dark;
}

/* Daylight — the app's light theme. Only the tokens change; nothing below
   this block knows which theme is running. */
:root[data-theme="light"] {
  --bg:            #F6F6F8;
  --surface:       #FFFFFF;
  --surface-alt:   #F0F0F3;
  --surface-sunk:  #EAEAEF;
  --line:          #E2E2E8;
  --line-strong:   #C9C9D2;
  --text:          #16161A;
  --text-2:        #4A4A56;
  --text-3:        #6E6E7A;
  --brand:         #FF3131;
  --brand-strong:  #E01F1F;
  --brand-text:    #C41A1A;
  --brand-subtle:  #FFECEC;
  --a:             #0E8C7F;
  --b:             #6D5BD6;
  --success:       #0F6E4F;
  --warning:       #9A6300;
  --a-wash:        rgba(14, 140, 127, .1);
  --b-wash:        rgba(109, 91, 214, .1);
  --brand-wash:    rgba(255, 49, 49, .1);
  --glass:         rgba(255, 255, 255, .78);
  --shadow-1:      0 1px 2px rgba(16, 17, 27, .06);
  --shadow-2:      0 8px 24px -8px rgba(16, 17, 27, .14);
  --shadow-3:      0 32px 64px -24px rgba(16, 17, 27, .2);
  color-scheme: light;
}

/* ----------------------------------------------------------------- base */

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* The sticky header is 64px; anchored sections must clear it. */
  scroll-padding-top: 5.5rem;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: var(--step-0);
  line-height: 1.65;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  margin: 0;
  line-height: 1.08;
  letter-spacing: -.025em;
  font-weight: 800;
  text-wrap: balance;
}
h1 { font-size: var(--step-5); letter-spacing: -.038em; }
h2 { font-size: var(--step-4); letter-spacing: -.032em; }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); letter-spacing: -.02em; }

p { margin: 0; text-wrap: pretty; }
ul, ol { margin: 0; padding: 0; }
img, video, svg { display: block; max-width: 100%; }
img, video { height: auto; }

a { color: var(--brand-text); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--brand); }

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
  border-radius: 4px;
}

::selection { background: var(--brand); color: #fff; }

.skip {
  position: absolute; left: 50%; top: -100px; transform: translateX(-50%);
  z-index: 200; background: var(--brand-strong); color: #fff;
  padding: .7rem 1.2rem; border-radius: 0 0 var(--r-sm) var(--r-sm);
  font-weight: 600; text-decoration: none; transition: top .18s var(--ease);
}
.skip:focus { top: 0; color: #fff; }

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

/* ------------------------------------------------------------- layout */

.wrap { width: min(100% - var(--gutter) * 2, var(--wide)); margin-inline: auto; }
.wrap--narrow { width: min(100% - var(--gutter) * 2, var(--narrow)); }

section { position: relative; }
.band { padding-block: var(--section-y); }
.band--sunk { background: var(--surface-sunk); }
.band--tight { padding-block: clamp(3rem, 2rem + 4vw, 5rem); }

.rule { border: 0; border-top: 1px solid var(--line); margin: 0; }

/* Section headers -------------------------------------------------------- */

.eyebrow {
  font-family: var(--cond);
  font-weight: 700;
  font-size: clamp(.9rem, .85rem + .2vw, 1.02rem);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--brand-text);
  margin-bottom: .85rem;
  display: flex; align-items: center; gap: .6rem;
}
.eyebrow::before {
  content: ""; width: 26px; height: 2px; background: var(--brand);
  border-radius: 2px; flex: none;
}

.head { max-width: 54ch; margin-bottom: clamp(2.2rem, 1.5rem + 2.2vw, 3.2rem); }
.head p { color: var(--text-2); font-size: var(--step-1); margin-top: 1.05rem; }

/* A centred header needs a wider box for the heading than for the paragraph
   under it, or the paragraph turns into a narrow column of five short lines. */
.head--center { max-width: 68ch; margin-inline: auto; text-align: center; }
.head--center .eyebrow { justify-content: center; }
.head--center p { max-width: 56ch; margin-inline: auto; }

/* Heading left, standfirst right, sharing a baseline. Stacks below 900px into
   exactly what .head already does, so the markup is identical either way. */
@media (min-width: 900px) {
  .head--split {
    max-width: none;
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
    column-gap: clamp(2rem, 4vw, 4.5rem);
    align-items: end;
  }
  .head--split .eyebrow { grid-column: 1; grid-row: 1; }
  .head--split h2 { grid-column: 1; grid-row: 2; }
  .head--split p { grid-column: 2; grid-row: 2; margin-top: 0; max-width: 44ch; }
}

/* --------------------------------------------------------------- buttons */

.btn {
  --btn-bg: var(--brand-strong);
  --btn-fg: #fff;
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  padding: .92rem 1.6rem;
  background: var(--btn-bg); color: var(--btn-fg);
  border: 1px solid transparent; border-radius: 999px;
  font: inherit; font-weight: 650; letter-spacing: -.01em;
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: transform .18s var(--ease), box-shadow .18s var(--ease),
              background-color .18s var(--ease), border-color .18s var(--ease);
  box-shadow: var(--cta-shadow);
}
.btn:hover { color: var(--btn-fg); transform: translateY(-1px); box-shadow: var(--cta-shadow-hi); }
.btn:active { transform: translateY(0); }

.btn--ghost {
  --btn-bg: transparent; --btn-fg: var(--text);
  border-color: var(--line-strong); box-shadow: none;
}
.btn--ghost:hover { background: var(--surface-alt); border-color: var(--text-3); box-shadow: none; }

.btn--lg { padding: 1.06rem 1.9rem; font-size: var(--step-1); }
.btn--sm { padding: .58rem 1.05rem; font-size: var(--step--1); }

.btn svg { flex: none; }

/* ---------------------------------------------------------------- header */

.header {
  position: sticky; top: 0; z-index: 100;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color .25s var(--ease), border-color .25s var(--ease);
}
.header.is-stuck {
  background: var(--glass);
  border-bottom-color: var(--line);
  backdrop-filter: blur(14px) saturate(1.4);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
}
/* The gap was 1.6rem when the nav held six entries. The seventh ("What else
   we do") costs about 140px and .wrap caps the bar at 1200px however wide the
   window is, so the room has to come from somewhere -- here and in .nav a's
   padding. Below --nav-collapse it comes from the burger instead. */
.header__bar { display: flex; align-items: center; gap: 1.15rem; height: 64px; }

.brand { display: flex; align-items: center; gap: .55rem; flex: none; text-decoration: none; }
.brand img { width: 88px; height: auto; }

/* The wordmark is brand red in BOTH lockup files; only the glyph changes —
   white in the on-dark file, black in the on-light one. Using one file for both
   themes does not dim the mark, it deletes it: the "o" disappears completely
   against the matching ground. So the whole lockup swaps with the theme.
   The hidden one is lazy, so in the default dark theme it is never fetched. */
.brand__mark--light { display: none; }
:root[data-theme="light"] .brand__mark--dark { display: none; }
:root[data-theme="light"] .brand__mark--light { display: block; }
.brand__tag {
  font-family: var(--cond); font-weight: 700; text-transform: uppercase;
  letter-spacing: .1em; font-size: .72rem; color: var(--text-3);
  border-inline-start: 1px solid var(--line); padding-inline-start: .6rem; margin-top: 2px;
}

.nav { display: flex; align-items: center; gap: .18rem; margin-inline-start: auto; }
.nav a {
  color: var(--text-2); text-decoration: none; font-size: var(--step--1);
  font-weight: 550; padding: .5rem .52rem; border-radius: 999px;
  /* Both are load-bearing: without them the row silently reflows onto two
     lines at the 1200px cap and the header grows by 24px. */
  flex: none; white-space: nowrap;
  transition: color .16s var(--ease), background-color .16s var(--ease);
}
.nav a:hover { color: var(--text); background: var(--surface-alt); }
.nav a[aria-current="true"] { color: var(--text); }

/* ------------------------------------------------------- promo nav entry */
/* The one nav entry that is not about TOKI. It has to read as a different
   kind of thing than the six links beside it without shouting over the "Try
   for free" button two positions to its right, so it is a bordered pill in
   the brand wash rather than another colour.

   The height of .promo__viewport is the whole trick: it is fixed, the strip
   inside it is taller than it, and only the strip moves. Nothing in the
   header can be pushed by a slide changing, whatever the slide contains. */

.nav__promo {
  /* One slide's height, and the only number the cycler depends on. site.js
     moves the strip by whole multiples of it, so a percentage translate (which
     would resolve against the *strip's* height, and so change every time a
     slide is added) is never used. */
  --promo-h: 20px;
  position: relative;
  display: flex; align-items: center; flex: none;
  padding: .42rem .8rem;
  border-radius: 999px;
  border: 1px solid var(--brand-wash);
  background: var(--brand-wash);
  color: var(--text-2);
  font-size: var(--step--1); font-weight: 600;
  text-decoration: none;
  overflow: hidden;
  transition: border-color .2s var(--ease), color .2s var(--ease);
}
.nav__promo:hover { color: var(--text); border-color: var(--brand); background: var(--brand-wash); }
.nav__promo[aria-current="true"] { color: var(--text); border-color: var(--brand); }

/* A slow highlight crossing the pill, so it catches the eye once in a while
   rather than blinking. Purely decorative and behind the text. */
.nav__promo::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 38%, var(--brand-wash) 50%, transparent 62%);
  transform: translateX(-100%);
  animation: promoSheen 7s var(--ease) infinite;
  pointer-events: none;
}
@keyframes promoSheen {
  0%, 62% { transform: translateX(-100%); }
  88%, 100% { transform: translateX(100%); }
}

.promo__viewport {
  display: block; position: relative;
  height: var(--promo-h);
  overflow: hidden;
  line-height: var(--promo-h);
}
/* Every slide is exactly one viewport tall, which is what lets site.js step
   the strip without measuring anything. */
.promo__slide {
  /* Centred so the mark, which is narrower than the label that sets the pill's
     width, sits in the middle of the pill rather than against its left edge. */
  display: flex; align-items: center; justify-content: center;
  height: var(--promo-h); white-space: nowrap;
}
.promo__strip {
  display: block;
  transition: transform .5s cubic-bezier(.65, 0, .35, 1);
}
/* Set by site.js while it snaps the clone back to the real first slide. */
.promo__strip.is-instant { transition: none; }

/* The Brivfy mark is an RGB file with a white background and no alpha (see
   .sibling for the same problem solved the same way), so it carries its own
   small white plate instead of sitting on a dark ground as a white box. */
.promo__mark {
  height: 16px; width: auto;
  background: #fff; border-radius: 3px;
  padding: 1px 4px;
}

@media (prefers-reduced-motion: reduce) {
  .nav__promo::after { animation: none; display: none; }
  .promo__strip { transition: none; }
}

.header__actions { display: flex; align-items: center; gap: .55rem; flex: none; }

.iconbtn {
  display: grid; place-items: center; width: 38px; height: 38px;
  border-radius: 999px; border: 1px solid var(--line);
  background: transparent; color: var(--text-2); cursor: pointer;
  transition: color .16s var(--ease), border-color .16s var(--ease), background-color .16s var(--ease);
}
.iconbtn:hover { color: var(--text); border-color: var(--line-strong); background: var(--surface-alt); }
.iconbtn svg { width: 18px; height: 18px; }
/* One button, two glyphs: the button shows the theme it will switch *to*.
   Dark is running, so it offers the sun; light is running, so it offers the moon. */
:root[data-theme="light"] .iconbtn__sun { display: none; }
:root:not([data-theme="light"]) .iconbtn__moon { display: none; }

.langswitch {
  display: inline-flex; align-items: center; gap: .3rem;
  border: 1px solid var(--line); border-radius: 999px; padding: 3px;
}
.langswitch a {
  padding: .3rem .62rem; border-radius: 999px; font-size: .78rem; font-weight: 650;
  color: var(--text-3); text-decoration: none; line-height: 1.4;
}
.langswitch a[aria-current="true"] { background: var(--surface-alt); color: var(--text); }

.burger { display: none; }

@media (max-width: 1240px) {
  .nav {
    position: fixed; inset: 64px 0 auto; z-index: 99;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--surface); border-bottom: 1px solid var(--line);
    padding: .6rem var(--gutter) 1.2rem;
    box-shadow: var(--shadow-3);
    display: none;
  }
  .nav.is-open { display: flex; animation: dropIn .22s var(--ease-out); }
  .nav a { padding: .85rem .4rem; font-size: var(--step-0); border-radius: var(--r-sm); }
  /* In the stacked sheet the pill would be the one bordered row in a list of
     plain links. It keeps the cycler and drops the chrome. */
  .nav__promo {
    padding: .85rem .4rem; border-radius: var(--r-sm);
    border-color: transparent; background: transparent;
    font-size: var(--step-0); font-weight: 550;
  }
  .nav__promo::after { display: none; }
  .nav__promo { --promo-h: 24px; }
  .promo__slide { justify-content: flex-start; }
  .promo__mark { height: 18px; }
  .burger { display: grid; margin-inline-start: auto; }
  .header__bar { gap: .75rem; }
}

/* The primary call to action stays in the header at every width. It used to be
   hidden below 1000px, which removed the only "Try for free" button a phone
   reader could reach without scrolling the whole page. */
@media (max-width: 420px) {
  .btn--nav { padding: .52rem .85rem; font-size: .8rem; }
  .brand img { width: 74px; }
}
@keyframes dropIn { from { opacity: 0; transform: translateY(-8px); } }

@media (max-width: 560px) {
  .brand__tag, .langswitch--header { display: none; }
}

/* ------------------------------------------------------------------ hero */

.hero {
  position: relative; overflow: hidden;
  padding-top: clamp(2.5rem, 1rem + 5vw, 5rem);
  padding-bottom: clamp(3rem, 2rem + 4vw, 5.5rem);
}

/* Two soft lights, one per speaker colour, plus the brand behind the phone.
   Pure CSS gradients — no image request, and they recolour with the theme. */
.aurora { position: absolute; inset: -20% -10% auto; height: 900px; z-index: 0; pointer-events: none; }
.aurora::before, .aurora::after { content: ""; position: absolute; border-radius: 50%; filter: blur(90px); }
.aurora::before {
  width: 620px; height: 620px; inset-inline-start: -8%; top: 0; opacity: .22;
  background: radial-gradient(circle, var(--a) 0%, transparent 68%);
}
.aurora::after {
  width: 720px; height: 720px; inset-inline-end: -6%; top: -6%; opacity: .2;
  background: radial-gradient(circle, var(--brand) 0%, transparent 66%);
}
:root[data-theme="light"] .aurora::before { opacity: .3; }
:root[data-theme="light"] .aurora::after { opacity: .22; }

/* A very fine grain over the whole page. Kills the banding that big blurred
   gradients produce on 8-bit panels, and gives the dark ground some tooth. */
.grain {
  position: fixed; inset: 0; z-index: 1; pointer-events: none; opacity: .028;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
}

.hero__grid {
  position: relative; z-index: 2;
  display: grid; gap: clamp(2.5rem, 1rem + 6vw, 4.5rem);
  grid-template-columns: minmax(0, 1.08fr) minmax(0, .92fr);
  align-items: center;
}
/* Stacked, and the copy stays first. Leading with the phone looked good in a
   mockup and meant a phone reader met a 667px-tall video before the headline. */
@media (max-width: 940px) {
  .hero__grid { grid-template-columns: 1fr; }
  .hero .phone { width: min(240px, 62vw); }
}

.hero h1 { margin-bottom: 1.15rem; }
.hero h1 em { font-style: normal; color: var(--brand-text); }
.hero__sub { font-size: var(--step-1); color: var(--text-2); max-width: 40ch; }

.hero__cta { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 2rem; }
.hero__fine {
  margin-top: 1.1rem; color: var(--text-3); font-size: var(--step--1);
  display: flex; flex-wrap: wrap; gap: .3rem .95rem; align-items: center;
}
.hero__fine span { display: inline-flex; align-items: center; gap: .4rem; }
.hero__fine svg { width: 15px; height: 15px; color: var(--success); flex: none; }

/* Live language cycler under the headline ------------------------------- */

.cycler {
  margin-top: 2.4rem; padding: 1.05rem 1.25rem;
  border: 1px solid var(--line); border-radius: var(--r);
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  max-width: 34rem;
}
.cycler__label {
  font-family: var(--cond); text-transform: uppercase; letter-spacing: .13em;
  font-size: .76rem; font-weight: 700; color: var(--text-3);
  display: flex; align-items: center; gap: .5rem; margin-bottom: .5rem;
}
.cycler__dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--brand);
  animation: pulse 1.9s var(--ease) infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.75); } }

/* Progressive enhancement, and the fix for the page's only layout shift.
   The <ul> of fourteen sentences is the real content for a reader — or a
   crawler — without JavaScript. With JavaScript it is redundant, and leaving it
   in the flow until site.js ran pushed the whole hero down on every load. The
   head script stamps `js` on <html> before first paint, so exactly one of the
   two is ever laid out, and the cycling line is in the markup (not created by
   script) so its box is reserved from the first frame. */
html.js [data-cycler-source] { display: none; }
html:not(.js) .cycler__line { display: none; }

.cycler__line { display: grid; grid-template-areas: "s"; min-height: 3.4em; align-items: start; }
.cycler__line > * { grid-area: s; }
.cycler__text {
  font-size: var(--step-1); font-weight: 600; letter-spacing: -.015em; line-height: 1.45;
  opacity: 0; transform: translateY(6px);
  transition: opacity .42s var(--ease), transform .42s var(--ease);
}
.cycler__text.is-in { opacity: 1; transform: none; }
.cycler__text.is-out { opacity: 0; transform: translateY(-6px); }
.cycler__text:lang(hi) { font-family: var(--deva); }
.cycler__text:lang(th) { font-family: var(--thai); }
.cycler__lang {
  display: block; margin-top: .35rem; font-size: .8rem; font-weight: 600;
  font-family: var(--sans); color: var(--a); letter-spacing: .02em;
}

/* Phone -------------------------------------------------------------- */

.phone {
  position: relative; width: min(300px, 78vw); margin-inline: auto;
  border-radius: 42px; padding: 10px;
  background: linear-gradient(160deg, #3a3d46, #16171b 45%, #2a2d35);
  box-shadow: var(--shadow-3), 0 0 0 1px rgba(255, 255, 255, .06) inset;
}
.phone::after {                       /* screen glare */
  content: ""; position: absolute; inset: 10px; border-radius: 33px;
  background: linear-gradient(147deg, rgba(255, 255, 255, .13), transparent 42%);
  pointer-events: none; z-index: 3;
}
.phone__screen {
  position: relative; border-radius: 33px; overflow: hidden;
  background: #16171B; aspect-ratio: 720 / 1600;
}
.phone__screen video, .phone__screen img { width: 100%; height: 100%; object-fit: cover; }
.phone__notch {
  position: absolute; top: 9px; left: 50%; transform: translateX(-50%);
  width: 86px; height: 22px; border-radius: 999px; background: #0c0d10; z-index: 2;
}
.phone__glow {
  position: absolute; inset: -12% -18%; z-index: -1; border-radius: 50%;
  background: radial-gradient(closest-side, var(--brand-wash), transparent 75%);
  filter: blur(30px);
}

/* "Real recording" badge pinned under the phone */
.realbadge {
  position: absolute; z-index: 4; left: 50%; bottom: -18px; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: .45rem; white-space: nowrap;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 999px; padding: .45rem .85rem;
  font-size: .76rem; font-weight: 600; color: var(--text-2);
  box-shadow: var(--shadow-2);
}
.realbadge b { color: var(--text); font-weight: 700; }
.realbadge .rec {
  width: 7px; height: 7px; border-radius: 50%; background: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-wash);
  animation: pulse 1.6s var(--ease) infinite;
}

/* ------------------------------------------------------------ proof strip */

.proof {
  position: relative; z-index: 2;
  display: grid; gap: 1px; background: var(--line);
  grid-template-columns: repeat(4, 1fr);
  border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden;
  margin-top: clamp(3.5rem, 2rem + 3vw, 5rem);
}
@media (max-width: 760px) { .proof { grid-template-columns: repeat(2, 1fr); } }
.proof__cell { background: var(--surface); padding: 1.5rem 1.4rem; }
.proof__n {
  font-family: var(--cond); font-weight: 700; font-size: clamp(2rem, 1.4rem + 2.2vw, 3rem);
  line-height: 1; letter-spacing: -.01em; color: var(--text);
}
.proof__n span { color: var(--brand-text); }
.proof__k { color: var(--text-2); font-size: var(--step--1); margin-top: .45rem; }

/* ----------------------------------------------------------------- cards */

.grid { display: grid; gap: clamp(1rem, .6rem + 1.4vw, 1.5rem); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 290px), 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr)); }

.card {
  position: relative; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: clamp(1.4rem, 1.1rem + .9vw, 2rem);
  transition: border-color .2s var(--ease), transform .2s var(--ease), box-shadow .2s var(--ease);
}
.card:hover { border-color: var(--line-strong); transform: translateY(-2px); box-shadow: var(--shadow-2); }
.card h3 { font-size: var(--step-1); margin-bottom: .6rem; }
.card p { color: var(--text-2); font-size: var(--step-0); }

.card__ico {
  width: 44px; height: 44px; border-radius: 13px; display: grid; place-items: center;
  margin-bottom: 1.05rem; background: var(--brand-wash); color: var(--brand-text);
}
.card__ico svg { width: 22px; height: 22px; }
.card__ico--a { background: var(--a-wash); color: var(--a); }
.card__ico--b { background: var(--b-wash); color: var(--b); }

.card__tag {
  display: inline-block; margin-bottom: .8rem;
  font-family: var(--cond); font-weight: 700; text-transform: uppercase;
  letter-spacing: .11em; font-size: .74rem; color: var(--text-3);
}

/* Numbered steps --------------------------------------------------------- */

.step__n {
  font-family: var(--cond); font-weight: 700; font-size: 1.15rem; letter-spacing: .08em;
  color: var(--brand-text); display: flex; align-items: center; gap: .6rem; margin-bottom: .9rem;
}
.step__n::after { content: ""; height: 1px; flex: 1; background: var(--line); }
.step__clip {
  border-radius: var(--r); overflow: hidden; border: 1px solid var(--line);
  background: var(--surface-sunk); margin-bottom: 1.15rem; aspect-ratio: 16 / 11;
}
.step__clip video, .step__clip img { width: 100%; height: 100%; object-fit: cover; object-position: center 20%; }

/* ---------------------------------------------------------- conversation */

.convo {
  display: grid; gap: clamp(2rem, 1rem + 4vw, 3.5rem);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); align-items: center;
}
@media (max-width: 900px) { .convo { grid-template-columns: 1fr; } }
/* A 300px phone is 667px tall next to two chat bubbles; it dwarfs them. */
.convo .phone { width: min(258px, 74vw); }

.thread { display: flex; flex-direction: column; gap: 1rem; }
.bubble {
  border-radius: var(--r-lg); padding: 1.1rem 1.25rem; max-width: 94%;
  border: 1px solid;
  opacity: 0; transform: translateY(14px);
  transition: opacity .5s var(--ease-out), transform .5s var(--ease-out);
}
.bubble.is-shown { opacity: 1; transform: none; }
.bubble--a { align-self: flex-start; background: var(--a-wash); border-color: color-mix(in srgb, var(--a) 34%, transparent); }
.bubble--b { align-self: flex-end;   background: var(--b-wash); border-color: color-mix(in srgb, var(--b) 34%, transparent); }
.bubble__who {
  display: flex; align-items: center; gap: .45rem; font-weight: 700; font-size: .82rem;
  letter-spacing: .02em; margin-bottom: .6rem;
}
.bubble--a .bubble__who { color: var(--a); }
.bubble--b .bubble__who { color: var(--b); }
.bubble__who svg { width: 15px; height: 15px; }
.bubble__who time { margin-inline-start: auto; color: var(--text-3); font-weight: 500; font-size: .76rem; }
.bubble__said { color: var(--text-2); font-style: italic; font-size: var(--step--1); margin-bottom: .5rem; }
.bubble__out { font-size: var(--step-1); font-weight: 600; letter-spacing: -.01em; line-height: 1.45; }
.bubble__out:lang(hi) { font-family: var(--deva); line-height: 1.7; }
.bubble__out:lang(th) { font-family: var(--thai); line-height: 1.7; }
.bubble__said:lang(hi) { font-family: var(--deva); }
.bubble__said:lang(th) { font-family: var(--thai); }

.speakerkey { display: flex; flex-wrap: wrap; gap: .5rem .9rem; margin-top: 1.4rem; font-size: var(--step--1); color: var(--text-3); }
.speakerkey span { display: inline-flex; align-items: center; gap: .4rem; }
.speakerkey i { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }

.callout {
  border-inline-start: 3px solid var(--brand); background: var(--brand-subtle);
  border-radius: 0 var(--r-sm) var(--r-sm) 0; padding: 1rem 1.2rem;
  color: var(--text-2); font-size: var(--step--1); margin-top: 1.6rem;
}
.callout strong { color: var(--text); }

/* ------------------------------------------------------------- languages */

/* 160px is chosen so a 1200px container fits exactly seven, and the fourteen
   languages land as two full rows rather than 6 + 6 + a stub. */
.langs {
  display: grid; gap: .6rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 160px), 1fr));
}
.lang {
  display: flex; flex-direction: column; gap: .1rem;
  padding: .95rem 1.05rem; border-radius: var(--r);
  border: 1px solid var(--line); background: var(--surface);
  transition: border-color .18s var(--ease), background-color .18s var(--ease);
}
.lang:hover { border-color: var(--a); background: var(--a-wash); }
.lang__native { font-weight: 700; font-size: var(--step-0); letter-spacing: -.01em; }
.lang__native:lang(th) { font-family: var(--thai); }
.lang__native:lang(hi) { font-family: var(--deva); }
.lang__en { color: var(--text-3); font-size: .8rem; }

/* --------------------------------------------------------------- privacy */

.split {
  display: grid; gap: clamp(1.6rem, 1rem + 3vw, 3rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
}
.ticklist { list-style: none; display: grid; gap: 1rem; }
.ticklist li { display: grid; grid-template-columns: 22px 1fr; gap: .85rem; align-items: start; }
.ticklist svg { width: 20px; height: 20px; margin-top: .3rem; }
.ticklist--yes svg { color: var(--success); }
.ticklist--no svg { color: var(--warning); }
.ticklist b { display: block; font-weight: 650; }
.ticklist span { color: var(--text-2); font-size: var(--step--1); }

/* ------------------------------------------------------------------- faq */

.faq { display: grid; gap: .55rem; }
details.qa {
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--surface); overflow: hidden;
  transition: border-color .18s var(--ease);
}
details.qa[open] { border-color: var(--line-strong); }
details.qa summary {
  cursor: pointer; list-style: none; padding: 1.15rem 1.3rem;
  font-weight: 650; font-size: var(--step-0); letter-spacing: -.01em;
  display: flex; align-items: center; gap: 1rem;
}
details.qa summary::-webkit-details-marker { display: none; }
details.qa summary::after {
  content: ""; margin-inline-start: auto; flex: none;
  width: 11px; height: 11px;
  border-inline-end: 2px solid var(--text-3); border-bottom: 2px solid var(--text-3);
  transform: rotate(45deg) translate(-2px, -2px); transition: transform .2s var(--ease);
}
details.qa[open] summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
details.qa .qa__a { padding: 0 1.3rem 1.25rem; color: var(--text-2); }
details.qa .qa__a p + p { margin-top: .7rem; }

/* --------------------------------------------------------------- get app */

.getapp {
  border: 1px solid var(--line); border-radius: var(--r-xl);
  background:
    radial-gradient(120% 140% at 12% 0%, var(--brand-wash), transparent 55%),
    radial-gradient(110% 130% at 92% 100%, var(--a-wash), transparent 58%),
    var(--surface);
  padding: clamp(2rem, 1.4rem + 3vw, 3.6rem);
  display: grid; gap: clamp(1.8rem, 1rem + 3vw, 3rem);
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); align-items: center;
}
@media (max-width: 860px) { .getapp { grid-template-columns: 1fr; } }

.stores { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: 1.6rem; }
.store {
  display: inline-flex; align-items: center; gap: .7rem;
  border: 1px solid var(--line-strong); border-radius: 14px;
  padding: .62rem 1.05rem; background: var(--surface-alt);
  color: var(--text-3); text-decoration: none; cursor: not-allowed;
  position: relative;
}
.store svg { width: 24px; height: 24px; flex: none; }
.store__t { display: block; font-size: .64rem; letter-spacing: .09em; text-transform: uppercase; line-height: 1.35; }
.store__n { display: block; font-weight: 700; font-size: .96rem; color: var(--text-2); line-height: 1.2; letter-spacing: -.01em; }
.store__soon {
  position: absolute; top: -9px; inset-inline-end: 8px;
  background: var(--warning); color: #16171B; font-size: .6rem; font-weight: 800;
  letter-spacing: .07em; text-transform: uppercase; padding: .12rem .45rem; border-radius: 5px;
}

.qr {
  display: grid; gap: .8rem; justify-items: center; text-align: center;
  border: 1px dashed var(--line-strong); border-radius: var(--r-lg);
  padding: 1.4rem; background: color-mix(in srgb, var(--surface-sunk) 65%, transparent);
}
.qr img { width: 136px; height: 136px; border-radius: 12px; }
.qr p { font-size: var(--step--1); color: var(--text-3); }

/* --------------------------------------------------------------- sibling */
/* The Brivfy panel — the one block in this file that does NOT follow the
   theme.

   Everything above reads the token block and therefore flips with
   `data-theme`. This panel deliberately does not, for three reasons that all
   point the same way:

     1. Brivfy's red is #DB1A1B. TOKI's --brand-strong is #E01F1F. Rendered
        side by side they are the same colour, so hue cannot be the thing that
        says "different product" — a change of *ground* has to be.
     2. brivfy-lockup.png is RGB with no alpha channel: it carries a white
        background baked in. On TOKI's charcoal that is a white box. Same
        brand trap documented for the TOKI lockups in docs/Website.md; there
        the fix was two files, but we do not get to author a second file for
        someone else's mark.
     3. White is Brivfy's own ground. Their logo goes on it unaltered, which
        is both the honest treatment and the one that needs no maintenance
        when they revise the mark — swap the PNG and nothing else moves.

   So the colours below are literals, on purpose, and must stay literals.
   Sampled from the mark itself (#DB1A1B) and from the Daylight palette for
   the neutrals, so the panel reads as a light-theme island rather than as a
   second design system. */

/* The band behind the panel is charcoal in BOTH themes — also a literal, and
   for the same reason the panel is white.

   A white panel on Charcoal is unmissable. A white panel on Daylight's
   --bg (#F6F6F8) is a white panel on a white page: the shadow does nearly
   nothing, the whole "this is a different product" signal evaporates, and
   the block degrades into just another card. Pinning the band dark makes the
   contrast identical in both themes, and in light mode the dark strip is
   itself a deliberate break — the reader has finished with TOKI, and the page
   says so before the footer. In dark mode it equals --bg, so nothing
   changes there. */
.band--sib { background: #16171B; }

.sibling {
  --sib-bg:    #FFFFFF;
  --sib-sunk:  #F4F4F7;
  --sib-ink:   #16161A;
  --sib-ink-2: #4A4A56;
  --sib-ink-3: #6E6E7A;
  --sib-line:  #E4E4EA;
  --sib-red:   #DB1A1B;

  background: var(--sib-bg);
  color: var(--sib-ink);
  border-radius: var(--r-xl);
  padding: clamp(1.9rem, 1.2rem + 3vw, 3.4rem);
  display: grid;
  gap: clamp(2rem, 1rem + 3.4vw, 3.4rem);
  grid-template-columns: minmax(0, 1.08fr) minmax(0, .92fr);
  align-items: center;
  /* Lifted off the dark page rather than outlined: a border would read as a
     card in TOKI's system, and the point is that this is not one. */
  box-shadow: var(--shadow-3);
}
@media (max-width: 880px) { .sibling { grid-template-columns: 1fr; } }

.sibling__eyebrow {
  font-family: var(--cond);
  font-weight: 700;
  font-size: clamp(.9rem, .85rem + .2vw, 1.02rem);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--sib-red);
  margin-bottom: 1.1rem;
  display: flex; align-items: center; gap: .6rem;
}
.sibling__eyebrow::before {
  content: ""; width: 26px; height: 2px; background: var(--sib-red);
  border-radius: 2px; flex: none;
}

/* Fixed display width, so the 300px source is always drawn at 2x and the
   wordmark stays crisp. Height follows from the file's own aspect ratio. */
.sibling__logo { display: inline-block; }
.sibling__logo img { width: 150px; height: auto; }

.sibling h2 { color: var(--sib-ink); font-size: var(--step-3); margin-top: 1.3rem; }
.sibling__lede { color: var(--sib-ink-2); font-size: var(--step-1); margin-top: 1rem; max-width: 46ch; }

.sibling__list {
  list-style: none; display: grid; gap: .75rem;
  margin-top: 1.6rem; max-width: 46ch;
}
.sibling__list li {
  display: grid; grid-template-columns: 20px 1fr; gap: .7rem;
  align-items: start; color: var(--sib-ink-2); font-size: var(--step-0);
}
.sibling__list svg { width: 20px; height: 20px; color: var(--sib-red); margin-top: .18rem; }
.sibling__list b { color: var(--sib-ink); font-weight: 650; }

.sibling__cta { display: flex; flex-wrap: wrap; gap: .7rem; align-items: center; margin-top: 1.9rem; }

/* Brivfy's own red on Brivfy's own CTA. The shadow is re-tinted to match —
   inheriting --cta-shadow would put a TOKI-red glow under a Brivfy button. */
.btn--sib {
  --btn-bg: var(--sib-red);
  --btn-fg: #fff;
  box-shadow: 0 6px 20px -8px rgba(219, 26, 27, .8);
}
.btn--sib:hover { box-shadow: 0 12px 28px -10px rgba(219, 26, 27, .9); }

/* Same shape as .store, but these are real listings, so they are links that
   behave like links — not the not-allowed cursor TOKI's own placeholders use. */
.sibling__store {
  display: inline-flex; align-items: center; gap: .6rem;
  border: 1px solid var(--sib-line); border-radius: 14px;
  padding: .55rem .95rem; background: var(--sib-sunk);
  color: var(--sib-ink-2); text-decoration: none;
  transition: border-color .18s var(--ease), background-color .18s var(--ease);
}
.sibling__store:hover { color: var(--sib-ink); border-color: var(--sib-ink-3); background: #fff; }
.sibling__store svg { width: 21px; height: 21px; flex: none; }
.sibling__store b { display: block; font-weight: 700; font-size: .92rem; line-height: 1.2; letter-spacing: -.01em; }
.sibling__store small { display: block; font-size: .62rem; letter-spacing: .09em; text-transform: uppercase; line-height: 1.35; color: var(--sib-ink-3); }

/* The art: the *format* of a Brivfy story, not a story. Deliberately
   abstract — text bars rather than invented headlines, because a mocked-up
   news card with words in it would be a fabricated article. The category
   chips below are the real ones from brivfy.com. */
.sibling__art { position: relative; display: grid; justify-items: center; }

.sibling__stack { position: relative; width: min(100%, 320px); }

.sibling__card {
  background: var(--sib-bg); border: 1px solid var(--sib-line);
  border-radius: var(--r); padding: 1.1rem 1.15rem;
  box-shadow: 0 10px 26px -16px rgba(16, 17, 27, .5);
}
/* The two behind are inert decoration; only the front card carries content. */
.sibling__card--back {
  position: absolute; inset-inline: 0; top: 0; height: 100%;
  background: var(--sib-sunk);
}
.sibling__card--b1 { transform: translateY(-14px) rotate(-2.4deg); }
.sibling__card--b2 { transform: translateY(-7px) rotate(1.6deg); }
.sibling__card--front { position: relative; }

.sibling__chip {
  display: inline-block; font-family: var(--cond); font-weight: 700;
  font-size: .8rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--sib-red); background: rgba(219, 26, 27, .09);
  padding: .18rem .55rem; border-radius: 6px;
}

.sibling__bars { display: grid; gap: .5rem; margin-top: .9rem; }
.sibling__bar { height: 9px; border-radius: 999px; background: var(--sib-ink); opacity: .82; }
.sibling__bars--head .sibling__bar:nth-child(2) { width: 72%; }
.sibling__bars--body { gap: .42rem; margin-top: 1rem; }
.sibling__bars--body .sibling__bar { height: 6px; background: var(--sib-ink-3); opacity: .35; }
.sibling__bars--body .sibling__bar:nth-child(2) { width: 94%; }
.sibling__bars--body .sibling__bar:nth-child(3) { width: 88%; }
.sibling__bars--body .sibling__bar:nth-child(4) { width: 46%; }

.sibling__count {
  display: flex; align-items: baseline; gap: .35rem;
  margin-top: 1.15rem; padding-top: .9rem; border-top: 1px solid var(--sib-line);
  font-family: var(--cond); color: var(--sib-red);
}
.sibling__count b { font-size: 2.1rem; font-weight: 700; line-height: 1; letter-spacing: -.02em; }
.sibling__count span { font-size: .82rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; }

.sibling__cats {
  display: flex; flex-wrap: wrap; gap: .4rem; justify-content: center;
  margin-top: 1.6rem; max-width: 320px;
}
.sibling__cats li {
  list-style: none; font-size: .74rem; font-weight: 600; letter-spacing: .02em;
  color: var(--sib-ink-3); border: 1px solid var(--sib-line);
  border-radius: 999px; padding: .22rem .62rem;
}

/* ---------------------------------------------------------------- footer */

.footer {
  background: var(--surface-sunk); border-top: 1px solid var(--line);
  padding-block: clamp(3rem, 2rem + 3vw, 4.5rem) 2rem;
}
.footer__grid {
  display: grid; gap: 2.2rem;
  grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr));
}
@media (max-width: 860px) { .footer__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .footer__grid { grid-template-columns: 1fr; } }

.footer h2 {
  font-family: var(--cond); font-size: .95rem; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; color: var(--text-3); margin-bottom: 1rem;
}
.footer ul { list-style: none; display: grid; gap: .6rem; }
.footer li a { color: var(--text-2); text-decoration: none; font-size: var(--step--1); }
.footer li a:hover { color: var(--text); text-decoration: underline; }
.footer__about p { color: var(--text-3); font-size: var(--step--1); margin-top: 1rem; max-width: 34ch; }
.footer__legal {
  margin-top: 2.8rem; padding-top: 1.6rem; border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: .8rem 1.6rem; align-items: center;
  color: var(--text-3); font-size: .82rem;
}
.footer__legal address { font-style: normal; }

/* --------------------------------------------------------------- article */
/* Shared by the legal pages, About and Contact. */

.doc { padding-block: clamp(3rem, 2rem + 3vw, 5rem) var(--section-y); }
.doc h1 { font-size: var(--step-4); margin-bottom: .5rem; }
.doc .doc__meta { color: var(--text-3); font-size: var(--step--1); margin-bottom: 2.5rem; }
.doc h2 {
  font-size: var(--step-2); margin: 2.8rem 0 .8rem; padding-top: 1.6rem;
  border-top: 1px solid var(--line);
}
.doc h3 { font-size: var(--step-1); margin: 1.8rem 0 .5rem; }
.doc p, .doc li { color: var(--text-2); }
.doc p + p, .doc ul + p, .doc p + ul, .doc p + ol, .doc ol + p { margin-top: .9rem; }
.doc ul, .doc ol { padding-inline-start: 1.3rem; display: grid; gap: .45rem; }
.doc ul { list-style: disc; }
.doc ol { list-style: decimal; }
.doc strong { color: var(--text); font-weight: 650; }
.doc table { border-collapse: collapse; width: 100%; margin: 1.2rem 0; font-size: var(--step--1); }
.doc th, .doc td { border: 1px solid var(--line); padding: .65rem .85rem; text-align: start; vertical-align: top; color: var(--text-2); }
.doc th { background: var(--surface-alt); color: var(--text); font-weight: 650; }
.doc .notice {
  background: var(--brand-subtle); border: 1px solid color-mix(in srgb, var(--brand) 35%, transparent);
  border-radius: var(--r); padding: 1.05rem 1.2rem; margin: 1.4rem 0;
}
.doc .notice strong { color: var(--brand-text); }
.doc__tablewrap { overflow-x: auto; }
.doc__toc {
  border: 1px solid var(--line); border-radius: var(--r); background: var(--surface);
  padding: 1.2rem 1.4rem; margin-bottom: 2.5rem;
}
.doc__toc h2 {
  border: 0; margin: 0 0 .7rem; padding: 0; font-size: .95rem; font-family: var(--cond);
  letter-spacing: .13em; text-transform: uppercase; color: var(--text-3);
}
.doc__toc ol { list-style: none; padding: 0; gap: .4rem; }
.doc__toc a { font-size: var(--step--1); }

/* ------------------------------------------------------- non-Latin scripts */

/* Thai stacks vowels and tone marks above and below the line, so the Latin
   leading crowds them; and the subset we ship tops out at 700, which with
   font-synthesis off means an 800 heading silently renders at 700 anyway.
   Both are stated here rather than left to the fallback. */
html[lang="th"] body { line-height: 1.85; }
html[lang="th"] h1,
html[lang="th"] h2,
html[lang="th"] h3,
html[lang="th"] h4 { font-weight: 700; line-height: 1.35; letter-spacing: 0; }
html[lang="th"] .proof__n,
html[lang="th"] .eyebrow,
html[lang="th"] .sibling__eyebrow,
html[lang="th"] .footer h2 { letter-spacing: .04em; }

/* The Brivfy panel's condensed voice, in Thai. Barlow Condensed carries no
   Thai glyphs, so these would fall through the whole --cond stack to whatever
   the system offers; naming --thai gets the face the rest of the page uses.
   .sibling__count b is exempt on purpose — it is the numeral 50, which should
   stay condensed. */
html[lang="th"] .sibling__eyebrow,
html[lang="th"] .sibling__chip,
html[lang="th"] .sibling__count span { font-family: var(--thai); }

/* Neither Thai nor Devanagari has a real italic; asking for one gets a slanted
   synthetic that reads as broken rather than as a quotation. */
:lang(th), :lang(hi) { font-style: normal !important; }

/* ------------------------------------------------------------- animation */

.reveal { opacity: 0; transform: translateY(18px); }
.reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity .7s var(--ease-out), transform .7s var(--ease-out);
}
.reveal.d1 { transition-delay: .07s; }
.reveal.d2 { transition-delay: .14s; }
.reveal.d3 { transition-delay: .21s; }

/* Anyone who has asked their OS for less motion gets a site that does not
   move: no reveals, no cycling headline, no autoplaying loops (site.js checks
   the same query before it calls play()). */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  .reveal, .bubble, .cycler__text { opacity: 1; transform: none; }
}

/* Printing a legal page should produce a legal page, not a dark rectangle. */
@media print {
  .header, .footer__grid, .aurora, .grain, .skip, .langswitch, .iconbtn { display: none !important; }
  body { background: #fff; color: #000; }
  .doc p, .doc li, .doc td, .doc th { color: #000; }
  a { color: #000; text-decoration: underline; }
}
