/* ---------- Tokens (lifted from kami / luo for Tang brand consistency) ---------- */

:root {
  --parchment:    #f5f4ed;
  --ivory:        #faf9f5;
  --warm-sand:    #e8e6dc;

  --brand:        #1B365D;
  --brand-light:  #2D5A8A;
  --brand-tint:   #EEF2F7;

  --near-black:   #141413;
  --dark-warm:    #3d3d3a;
  --olive:        #504e49;
  --stone:        #6b6a64;

  --border-soft:  #f1eee5;
  --line:         #d8d5c8;
  --line-faint:   #edebe1;
  /* Card edge: one step darker than --border-soft so light cards keep a
     visible top edge on the parchment page background; derives from the
     base tokens so the high-contrast override scales it automatically. */
  --border-card:  color-mix(in srgb, var(--border-soft) 70%, var(--line));

  --serif: Charter, Georgia, "Source Han Serif SC", "Noto Serif CJK SC", "Songti SC", Palatino, serif;
  --sans: var(--serif);
  --ui: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Arial, sans-serif;
  --mono: "JetBrains Mono", "Fira Code", "SF Mono", Consolas, Monaco, monospace;
  --poem-serif: var(--serif);
  --price-serif: Charter, Georgia, serif;

  /* Dark surface for product screenshots, matches the macOS app chrome */
  --shot-bg: #141318;

  /* Mole's fur brown-black: nav pill + footer band */
  --mole-dark: #33302a;
  --mole-ink:  #f4f2ec;

  /* Vertical rhythm: one gap between the hero, every top-level section, and the
     footer. It must beat the 28px head-to-content gap by a wide margin, or the
     section head reads as the tail of the section above it. */
  --section-gap: 76px;
}

/* Chinese serif, self-hosted. iOS ships NO Chinese serif: PingFang, a sans, is
   its only CJK face, while macOS has Songti. So the Chinese pages set their
   Latin words in Charter and their Chinese ones in a sans on every iPhone, one
   sentence in two voices, and looked nothing like the same page on a Mac. The
   font stacks below cannot fix that, because there is no serif on the device to
   fall back to; the page has to carry one. Source Han Serif (Adobe, OFL),
   subsetted by site/build_fonts.py to the characters these pages actually use
   and served from our own origin, so no third-party CDN sits in front of the
   page. unicode-range keeps it to CJK: Latin stays Charter, and the English,
   Japanese and Korean pages never download it (they contain no character in
   these ranges, or have a system serif of their own).
   src local() first: a Mac with Source Han Serif installed downloads nothing. */
@font-face {
  font-family: "Mole Serif SC";
  src: local("Source Han Serif SC"), local("Noto Serif CJK SC"),
       url("./fonts/mole-serif-sc-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+2E80-2EFF, U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF;
}
@font-face {
  font-family: "Mole Serif SC";
  src: local("Source Han Serif SC SemiBold"), local("Noto Serif CJK SC SemiBold"),
       url("./fonts/mole-serif-sc-semibold.woff2") format("woff2");
  font-weight: 500 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+2E80-2EFF, U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF;
}
@font-face {
  font-family: "Mole Serif TC";
  src: local("Source Han Serif TC"), local("Noto Serif CJK TC"),
       url("./fonts/mole-serif-tc-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+2E80-2EFF, U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF;
}
@font-face {
  font-family: "Mole Serif TC";
  src: local("Source Han Serif TC SemiBold"), local("Noto Serif CJK TC SemiBold"),
       url("./fonts/mole-serif-tc-semibold.woff2") format("woff2");
  font-weight: 500 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+2E80-2EFF, U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
/* iOS Safari inflates text on its own unless told the page is already mobile
   sized ("auto" is the default and is what made the phone type read a size
   above the ladder). */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* Safari paints its elastic overscroll from the page root. Keep the normal
     canvas on parchment, then switch it to the footer band while the footer is
     visible so pulling past either edge continues the surface already there. */
  background: var(--parchment);
}
html.footer-in-view {
  background: var(--mole-dark);
}

/* Type ladder. Every font-size on the site is one of these; no in-between values
   (12.5 / 13.5 / 14.5 had drifted in per component and read as noise, not as
   hierarchy). Charter carries a tall x-height, so 15px body already sets larger
   than 15px in a sans would.
     96 / 64  hero wordmark (desktop / phone)
     52 / 46  price
     32 / 26  section title
     22 / 21 / 20  contact title, tagline, footer wordmark
     18       short pull-quote, planet frame title
     17       section lede
     16       FAQ question
     15       body: planet points, FAQ answer, quotes, buttons
     14       secondary prose: footer links, card descriptions
     13       meta: trust row, gallery tabs, handles, stats
     12       floor: uppercase micro-labels and badges only, never prose */
body {
  background: var(--parchment);
  /* Full-bleed footer uses the 50vw margin trick; clip the scrollbar-width overshoot */
  overflow-x: clip;
  color: var(--brand);
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.55;
  letter-spacing: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

html[lang="zh-CN"] {
  /* "Mole Serif SC" is the shipped subset and sits ahead of the system names:
     it is the only serif an iPhone has, and on a Mac it renders the same face
     the Chinese pages were designed in. PingFang (sans) is gone from the stack;
     it was never a fallback, it was the bug. */
  --serif: Charter, Georgia, "Mole Serif SC", "Songti SC", serif;
  --sans: "PingFang SC", "Hiragino Sans GB", -apple-system, BlinkMacSystemFont, sans-serif;
  --poem-serif: "Kaiti SC", STKaiti, "Mole Serif SC", "Songti SC", serif;
}
html[lang="zh-CN"] body {
  font-family: var(--serif);
  line-height: 1.75;
}
html[lang="zh-CN"] .fcard-points li,
html[lang="zh-CN"] .price-vs,
html[lang="zh-CN"] .price-value,
html[lang="zh-CN"] .price-trial,
html[lang="zh-CN"] .price-terms,
html[lang="zh-CN"] .btn-primary,
html[lang="zh-CN"] .btn-ghost,
html[lang="zh-CN"] .faq-answer {
  font-variant-numeric: lining-nums tabular-nums;
}
html[lang="zh-CN"] .gallery-caption .line,
html[lang="zh-CN"] .fcard-poem {
  font-family: var(--poem-serif);
  font-style: normal;
}
html[lang="zh-CN"] .foot .ethos,
html[lang="zh-CN"] .help-shot figcaption {
  font-style: normal;
}
html[lang="zh-CN"] .hero h1 {
  font-family: Georgia, "Mole Serif SC", "Songti SC", serif;
}
html[lang="zh-CN"] .btn-primary,
html[lang="zh-CN"] .btn-ghost {
  font-family: var(--serif);
  font-variant-numeric: tabular-nums;
}

html:is([lang="zh-Hant"], [lang="zh-TW"]) {
  --serif: Charter, Georgia, "Mole Serif TC", "Songti TC", serif;
  --sans: "PingFang TC", -apple-system, BlinkMacSystemFont, sans-serif;
  --poem-serif: "Kaiti TC", STKaiti, "Mole Serif TC", "Songti TC", serif;
}
html:is([lang="zh-Hant"], [lang="zh-TW"]) body { font-family: var(--serif); line-height: 1.75; }
/* Source Han Serif already gives Han glyphs a full em. Keep prose at its natural
   spacing, remove the Latin title's negative tracking, and soften the wide
   uppercase tracking used by the two-character footer headings. */
html:is([lang="zh-CN"], [lang="zh-Hant"], [lang="zh-TW"]) .section-title {
  letter-spacing: 0;
}
html:is([lang="zh-CN"], [lang="zh-Hant"], [lang="zh-TW"]) .foot-col-title {
  letter-spacing: 0.6px;
}
html:is([lang="zh-Hant"], [lang="zh-TW"]) .fcard-points li,
html:is([lang="zh-Hant"], [lang="zh-TW"]) .price-vs,
html:is([lang="zh-Hant"], [lang="zh-TW"]) .price-value,
html:is([lang="zh-Hant"], [lang="zh-TW"]) .price-trial,
html:is([lang="zh-Hant"], [lang="zh-TW"]) .price-terms,
html:is([lang="zh-Hant"], [lang="zh-TW"]) .btn-primary,
html:is([lang="zh-Hant"], [lang="zh-TW"]) .btn-ghost,
html:is([lang="zh-Hant"], [lang="zh-TW"]) .faq-answer {
  font-variant-numeric: lining-nums tabular-nums;
}
html:is([lang="zh-Hant"], [lang="zh-TW"]) .gallery-caption .line,
html:is([lang="zh-Hant"], [lang="zh-TW"]) .fcard-poem {
  font-family: var(--poem-serif);
  font-style: normal;
}
html:is([lang="zh-Hant"], [lang="zh-TW"]) .foot .ethos,
html:is([lang="zh-Hant"], [lang="zh-TW"]) .help-shot figcaption { font-style: normal; }
html:is([lang="zh-Hant"], [lang="zh-TW"]) .hero h1 {
  font-family: Georgia, "Mole Serif TC", "Songti TC", serif;
}
html:is([lang="zh-Hant"], [lang="zh-TW"]) .btn-primary,
html:is([lang="zh-Hant"], [lang="zh-TW"]) .btn-ghost {
  font-family: var(--serif);
  font-variant-numeric: tabular-nums;
}

html[lang="ja"] {
  --serif: "Hiragino Mincho ProN", "Yu Mincho", "Noto Serif CJK JP", Georgia, serif;
  --sans: "Hiragino Kaku Gothic ProN", -apple-system, BlinkMacSystemFont, sans-serif;
  --poem-serif: "Hiragino Mincho ProN", "Yu Mincho", serif;
}
html[lang="ja"] body { font-family: var(--serif); line-height: 1.75; }
html[lang="ja"] .gallery-caption .line,
html[lang="ja"] .fcard-poem {
  font-family: var(--poem-serif);
  font-style: normal;
}
html[lang="ja"] .foot .ethos,
html[lang="ja"] .help-shot figcaption { font-style: normal; }
html[lang="ja"] .btn-primary,
html[lang="ja"] .btn-ghost {
  font-family: Georgia, "Hiragino Mincho ProN", "Yu Mincho", serif;
  font-variant-numeric: tabular-nums;
}

html[lang="ko"] {
  --serif: "AppleMyungjo", "Nanum Myeongjo", "Batang", Georgia, serif;
  --sans: "Apple SD Gothic Neo", -apple-system, BlinkMacSystemFont, sans-serif;
  --poem-serif: "AppleMyungjo", "Nanum Myeongjo", serif;
}
html[lang="ko"] body { font-family: var(--serif); line-height: 1.75; }
html[lang="ko"] .gallery-caption .line,
html[lang="ko"] .fcard-poem {
  font-family: var(--poem-serif);
  font-style: normal;
}
html[lang="ko"] .foot .ethos,
html[lang="ko"] .help-shot figcaption { font-style: normal; }
html[lang="ko"] .btn-primary,
html[lang="ko"] .btn-ghost {
  font-family: "Apple SD Gothic Neo", Georgia, serif;
  font-variant-numeric: tabular-nums;
}

html[lang="zh-CN"] .legal p, html:is([lang="zh-Hant"], [lang="zh-TW"]) .legal p,
html[lang="ja"] .legal p, html[lang="ko"] .legal p { line-height: 1.8; }
html[lang="zh-CN"] .faq-answer, html:is([lang="zh-Hant"], [lang="zh-TW"]) .faq-answer,
html[lang="ja"] .faq-answer, html[lang="ko"] .faq-answer { line-height: 1.75; }
html[lang="ja"] .fcard-points li { line-height: 1.7; }

html[lang="de"] { hyphens: auto; -webkit-hyphens: auto; }

a {
  color: var(--brand);
  text-decoration: none;
  transition: color 0.15s;
}
a:hover { color: var(--brand-light); }
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--brand) 52%, white);
  outline-offset: 3px;
}

.page:focus { outline: none; }

.skip-link {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 100;
  padding: 9px 13px;
  border: 1px solid var(--brand);
  border-radius: 999px;
  background: var(--ivory);
  color: var(--brand);
  font-family: var(--ui);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  transform: translateY(-72px);
  transition: transform 0.15s ease;
}
.skip-link:focus {
  transform: translateY(0);
}

.lang-switch {
  position: relative;
  z-index: 20;
  font-family: var(--ui);
  letter-spacing: 0;
  text-transform: none;
}

.lang-trigger {
  min-height: 24px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 0;
  border: 0;
  border-radius: 0;
  color: var(--stone);
  background: transparent;
  box-shadow: none;
  cursor: pointer;
  font: inherit;
  line-height: 1;
  transition: border-color 0.15s, box-shadow 0.15s, color 0.15s, background 0.15s;
}
.lang-trigger::after {
  content: "";
  width: 4px;
  height: 4px;
  margin-top: -2px;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  opacity: 0.55;
  transform: rotate(45deg);
  transition: transform 0.18s ease, opacity 0.18s ease;
}
.lang-trigger:hover,
.lang-switch.is-open .lang-trigger {
  color: var(--brand);
  background: transparent;
  box-shadow: none;
}
.lang-switch.is-open .lang-trigger::after {
  margin-top: 2px;
  opacity: 0.7;
  transform: rotate(225deg);
}
.lang-trigger:focus-visible,
.lang-menu a:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--brand) 38%, transparent);
  outline-offset: 3px;
}
.lang-current-code {
  display: none;
}
.lang-current-name {
  display: inline;
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
}

.lang-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 150px;
  display: grid;
  gap: 1px;
  padding: 6px;
  border: 1px solid color-mix(in srgb, var(--border-soft) 88%, var(--ivory));
  border-radius: 8px;
  background: color-mix(in srgb, var(--ivory) 92%, transparent);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 8px 24px rgba(20, 19, 19, 0.08);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(-4px);
  transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s ease;
}
/* Invisible bridge across the 8px gap so the cursor can travel from the
   trigger into the menu without losing :hover and collapsing it. */
.lang-menu::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -10px;
  height: 10px;
}
.lang-switch.is-open .lang-menu {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0);
}
.lang-switch:hover .lang-menu,
.lang-switch:focus-within .lang-menu {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0);
}
.lang-menu a {
  min-height: 32px;
  display: flex;
  align-items: center;
  padding: 6px 10px;
  border-radius: 6px;
  color: var(--olive);
  font-size: 13px;
  line-height: 1.35;
  transition: color 0.15s, background 0.15s, box-shadow 0.15s;
}
.lang-menu a:hover {
  color: var(--brand);
  background: color-mix(in srgb, var(--brand-tint) 36%, transparent);
}
.lang-menu a.active {
  color: var(--brand);
  font-weight: 600;
  background: color-mix(in srgb, var(--brand-tint) 48%, transparent);
  box-shadow: none;
}
.lang-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lang-code {
  display: none;
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

.page {
  max-width: 1120px;
  margin: 0 auto;
  /* Keep the visible document on parchment when the mobile body canvas turns
     dark to tint the browser-owned area below the footer. */
  background: var(--parchment);
  /* Top padding matches .nav-wrap's sticky offset so the pill never drifts. */
  padding: 16px 64px 84px;
  animation: fadeIn 0.4s ease-out;
}

/* ---------- Hero ---------- */

.hero {
  padding-bottom: 28px;
  border-bottom: 1px solid var(--border-soft);
  margin-bottom: var(--section-gap);
}

/* ---------- Sticky pill nav (parchment glass, matches the Tang palette) ---------- */

.nav-wrap {
  position: sticky;
  top: 16px;
  z-index: 60;
  /* Pull the pill out by its own padding so the logo and the buttons line up
     with the content column edges below. */
  margin: 0 -14px 40px;
}
/* 60 is the home page's gap, not the site's: the hero opens with a 96px wordmark
   and needs the extra air, while every other page opens with a 13px breadcrumb
   or a 32px title, under which 60 reads as a hole. #page-home is the home
   container and takes [hidden] when the in-page router switches to a legal view,
   so those views get 40 too. */
.nav-wrap:has(+ #page-home:not([hidden])) { margin-bottom: 60px; }
/* A full-bleed parchment veil behind the pill: solid across the pill, fading out
   just below it, so page content scrolling under the sticky nav is covered
   cleanly instead of bleeding through the translucent glass. */
.nav-wrap::before {
  content: "";
  position: absolute;
  left: 50%;
  top: -40px;
  transform: translateX(-50%);
  width: 100vw;
  height: calc(100% + 40px + 22px);
  background: linear-gradient(180deg, var(--parchment) 0%, var(--parchment) 72%, transparent 100%);
  z-index: -1;
  pointer-events: none;
}
.site-nav {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 10px 14px;
  /* Tallest control (the 33px CTA pills) plus the vertical padding sets the
     bar's border-box height even while the pills are hidden, so their
     return on scroll never nudges it. */
  min-height: 55px;
  border-radius: 999px;
  /* Echoes the app's TopTabBar: a quiet translucent track with a hairline
     border and no drop shadow; content sits left, actions right. */
  background: color-mix(in srgb, var(--ivory) 80%, transparent);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border: 1px solid color-mix(in srgb, var(--border-soft) 80%, transparent);
  color: var(--brand);
  font-family: var(--serif);
}
.nav-brand {
  display: flex;
  align-items: center;
  gap: 9px;
  color: var(--brand);
  min-width: 0;
}
.nav-brand:hover { color: var(--brand); }
.nav-brand img {
  width: 26px;
  height: 26px;
  display: block;
}
.nav-brand b {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.1px;
  line-height: 1;
}
.nav-links {
  display: flex;
  gap: 2px;
  margin: 0 0 0 16px;
}
.nav-links a {
  color: var(--dark-warm);
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
  padding: 8px 11px;
  border-radius: 999px;
  white-space: nowrap;
}
.nav-links a:hover {
  color: var(--brand);
  background: color-mix(in srgb, var(--brand-tint) 62%, transparent);
}
.nav-actions {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: 0 0 auto;
  margin-left: auto;
}
.nav-buy {
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  padding: 9px 15px;
  border-radius: 999px;
  background: var(--brand);
  color: var(--ivory);
  border: 1px solid var(--brand);
  white-space: nowrap;
  transition: background 0.15s, border-color 0.15s;
}
.nav-buy:hover {
  background: var(--brand-light);
  border-color: var(--brand-light);
  color: var(--ivory);
}
.nav-download {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  padding: 9px 14px;
  border-radius: 999px;
  color: var(--brand);
  background: transparent;
  border: 1px solid var(--brand);
  white-space: nowrap;
  transition: background 0.15s;
}
.nav-download:hover {
  background: var(--brand-tint);
  color: var(--brand);
}
.nav-download svg { display: block; margin-top: -1px; }
/* Hero CTA visible -> the nav keeps only links; buttons return after scrolling. */
html.js .site-nav.hide-cta .nav-buy,
html.js .site-nav.hide-cta .nav-download {
  display: none;
}
.site-nav .lang-switch {
  font-family: var(--serif);
}
.site-nav .lang-trigger {
  min-height: 30px;
  padding: 0 4px;
  gap: 6px;
}
.lang-globe {
  display: block;
  opacity: 0.75;
}
.site-nav .lang-current-name {
  font-size: 13px;
}

/* Anchor targets clear the sticky pill */
#overview, #features, #voices, #pricing, #faq {
  scroll-margin-top: 84px;
}

.version-link {
  color: var(--stone);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}
.version-link:hover {
  color: var(--brand);
}
/* Dot at the version's top-right corner: signals a newer build is available on
   the /releases page. Amber for a Preview build; add `is-stable` for a normal
   release (green). It clears once the visitor has clicked this exact version
   (the `seen` class, set from localStorage in template.html). */
.version-link.has-update {
  position: relative;
}
.version-link.has-update::after {
  content: "";
  position: absolute;
  /* Optically centered on the text line; a superscript offset read as a
     stray pixel floating off the link's top-right corner. */
  top: 50%;
  margin-top: -3px;
  right: -10px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #f5a623;
}
.version-link.has-update.is-stable::after {
  background: #3d9b56;
}
.version-link.has-update.seen::after {
  display: none;
}

.hero h1 {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 96px;
  line-height: 1.02;
  letter-spacing: -1.4px;
  margin: 0 0 40px;
  color: var(--brand);
}
.hero h1 .cn {
  display: inline-block;
  margin-left: 18px;
  letter-spacing: 0;
  color: var(--brand);
  font-weight: 400;
}

.hero .tagline {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 21px;
  line-height: 1.4;
  color: var(--olive);
  /* The trust row is a caption to this line, not a third block: keep it close
     here and let the 32px below it carry the break before the buttons. */
  margin: 0 0 16px;
  max-width: 940px;
  text-wrap: pretty;
}
.hero .tagline .tagline-cluster {
  display: inline-block;
  white-space: nowrap;
  word-break: keep-all;
}
.text-cluster {
  display: inline-block;
  white-space: nowrap;
}
html[lang="zh-CN"] .hero .tagline,
html:is([lang="zh-Hant"], [lang="zh-TW"]) .hero .tagline {
  word-break: keep-all;
}
/* A Han / kana / hangul glyph fills its em box while Charter's x-height is
   about half of it, so the 21px that reads right in English reads oversized
   and cramped in CJK. Step the desktop tagline down one notch for CJK; the
   max-width mobile blocks below already take it lower on phones, and the
   min-width guard keeps this strictly desktop so it never fights them. */
@media (min-width: 881px) {
  html:is([lang="zh-CN"], [lang="zh-Hant"], [lang="zh-TW"], [lang="ja"], [lang="ko"]) .hero .tagline {
    font-size: 18px;
  }
}
html[lang="zh-CN"] .section-lede,
html[lang="zh-CN"] .fcard-points li,
html[lang="zh-CN"] .faq-answer,
html:is([lang="zh-Hant"], [lang="zh-TW"]) .section-lede,
html:is([lang="zh-Hant"], [lang="zh-TW"]) .fcard-points li,
html:is([lang="zh-Hant"], [lang="zh-TW"]) .faq-answer {
  text-wrap: pretty;
  line-break: strict;
}

.hero-offer {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 18px;
  align-items: baseline;
  margin: 0 0 32px;
  font-family: var(--serif);
  font-size: 13px;
  line-height: 1.35;
  color: var(--stone);
}
.price-token,
.hero-trust,
.hero-trust > * {
  display: inline-flex;
  align-items: baseline;
}
.price-token {
  gap: 6px;
  color: var(--dark-warm);
  cursor: help;
}
.price-token b {
  color: var(--dark-warm);
  font-weight: 500;
}
.hero-trust {
  gap: 0;
  color: var(--stone);
}
.hero-trust > * + *::before {
  content: "·";
  margin: 0 10px;
  color: color-mix(in srgb, var(--stone) 58%, transparent);
}
.tip-target {
  position: relative;
}
.tip-target::after {
  content: attr(data-tip);
  display: block;
  box-sizing: border-box;
  position: absolute;
  left: 50%;
  bottom: calc(100% + 6px);
  z-index: 40;
  width: max-content;
  max-width: calc(100vw - 32px);
  padding: 5px 9px;
  border: 1px solid color-mix(in srgb, var(--border-soft) 76%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--ivory) 90%, white 10%);
  box-shadow: 0 4px 14px rgba(20, 19, 19, 0.075);
  color: var(--olive);
  font-family: var(--ui);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1.15;
  text-align: center;
  text-transform: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 3px);
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.tip-target:hover::after,
.tip-target:focus-visible::after {
  opacity: 1;
  transform: translate(-50%, 0);
}
.hero-offer .price-token::after {
  top: calc(100% + 5px);
  bottom: auto;
}
.version-tag.tip-target::after {
  top: calc(100% + 6px);
  bottom: auto;
}
.price-token s {
  color: var(--stone);
  font-size: 13px;
  text-decoration-thickness: 1px;
  text-decoration-color: color-mix(in srgb, var(--stone) 78%, transparent);
}
.hero-cta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px 24px;
  margin-top: 0;
}
.hero .btn-primary.tip-target::after {
  top: calc(100% + 6px);
  bottom: auto;
}

/* ---------- Buttons ---------- */

.btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: var(--brand);
  color: var(--ivory);
  font-family: var(--serif);
  font-weight: 600;
  font-size: 15px;
  letter-spacing: 0.2px;
  padding: 13px 28px;
  border-radius: 999px;
  border: 1.5px solid var(--brand);
  transition: background 0.15s, border-color 0.15s, transform 0.15s;
  cursor: pointer;
  min-width: 158px;
}
.btn-primary:hover {
  background: var(--brand-light);
  border-color: var(--brand-light);
  color: var(--ivory);
  transform: translateY(-1px);
}

.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-family: var(--serif);
  font-weight: 500;
  font-size: 15px;
  color: var(--brand);
  background: transparent;
  padding: 13px 28px;
  border-radius: 999px;
  border: 1.5px solid var(--brand);
  transition: background 0.15s, color 0.15s, transform 0.15s;
  cursor: pointer;
  min-width: 158px;
}
.btn-ghost:hover {
  background: var(--brand-tint);
  color: var(--brand);
  transform: translateY(-1px);
}

/* ---------- Section primitives ---------- */

section { margin-bottom: var(--section-gap); }
/* One head-to-content gap for every section (gallery, planets, voices, price,
   FAQ). The page runs on four steps: 8 between the eyebrow and the title, 12
   from the title to its lede, 24 from the whole head to the content it
   introduces, 76 between sections. The head belongs to what follows, so its
   gap below stays well under the gap above it; at 32 the lede floated between
   the title and the content instead of reading as the title's caption. */
.section-head { margin-bottom: 24px; }
.section-num {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 15px;
  color: var(--brand);
  letter-spacing: 0.4px;
  margin: 0 0 8px;
}
.section-title {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 32px;
  line-height: 1.2;
  color: var(--brand);
  margin: 0;
  letter-spacing: -0.3px;
  text-wrap: balance;
}
.section-lede {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.55;
  color: var(--olive);
  margin: 12px 0 0;
}

/* ---------- Product gallery (centerpiece) ---------- */

.gallery {
  --gallery-motion: cubic-bezier(0.4, 0, 0.2, 1);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 24px;
  align-items: baseline;
  margin: 0;
  padding: 0;
}

.gallery-frame {
  grid-column: 1 / -1;
  position: relative;
  background: var(--shot-bg);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(20, 19, 19, 0.10);
  cursor: pointer;
}
.gallery-panel {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  visibility: hidden;
  z-index: 1;
  /* A restrained dissolve with enough scale to soften the cut without reading
     as a zoom. Scale stays above 1 so the frame never flashes at the edges. */
  transform: scale(1.008);
  transition:
    opacity 680ms var(--gallery-motion),
    transform 760ms var(--gallery-motion),
    visibility 680ms;
  will-change: opacity, transform;
}
.gallery-panel.is-active {
  opacity: 1;
  visibility: visible;
  position: relative;
  z-index: 2;
  transform: scale(1);
}
.gallery-panel.was-active {
  opacity: 0;
  visibility: visible;
  position: absolute;
  inset: 0;
  z-index: 3;
  transform: scale(1.004);
  pointer-events: none;
}
.gallery-panel picture {
  display: block;
}
.gallery-panel img {
  width: 100%;
  height: auto;
  display: block;
}
/* The worlds panel plays a film, then crossfades in place to the About art.
   Video and still occupy the exact same box (absolute), so one dissolves into
   the other rather than stacking; the aspect-ratio keeps the frame stable. */
.gallery-panel-video {
  aspect-ratio: 2584 / 1741;
}
.gallery-video,
.gallery-video-still {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  background: var(--shot-bg);
  transition: opacity 600ms ease;
}
.gallery-video { opacity: 1; }
.gallery-video-still { opacity: 0; }
.gallery-video-still img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
}
.gallery-panel-video.show-still .gallery-video { opacity: 0; }
.gallery-panel-video.show-still .gallery-video-still { opacity: 1; }

.gallery-caption {
  grid-column: 1;
  grid-row: 2;
  min-height: 48px;
  padding: 12px 2px 0;
  display: flex;
  align-items: baseline;
  gap: 14px;
  transition: opacity 260ms var(--gallery-motion);
}
.gallery.is-caption-out .gallery-caption {
  opacity: 0;
  transition-duration: 140ms;
}
.gallery-caption .title {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 17px;
  color: var(--brand);
  margin: 0;
  letter-spacing: 0.1px;
  flex: 0 0 auto;
}
.gallery-caption .line {
  font-family: var(--serif);
  font-size: 14px;
  color: var(--olive);
  margin: 0;
  font-style: italic;
}
.gallery-tabs {
  grid-column: 2;
  grid-row: 2;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 12px;
  justify-content: flex-end;
}
.gallery-tabs button {
  appearance: none;
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  background: transparent;
  color: var(--olive);
  font-family: var(--serif);
  font-size: 13px;
  line-height: 1;
  padding: 8px 12px;
  cursor: pointer;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
.gallery-tabs button:hover {
  color: var(--brand);
  border-color: var(--line);
}
.gallery-tabs button.is-active {
  color: var(--ivory);
  background: var(--brand);
  border-color: var(--brand);
}
.gallery-tabs button.is-active:hover {
  color: var(--ivory);
  background: var(--brand-light);
  border-color: var(--brand-light);
}
/* Tighten the global focus halo around small gallery pills. */
.gallery-tabs button:focus-visible {
  outline-offset: 1px;
}

/* ---------- Planets (the five tools) ---------- */

/* Alternating cinema rows: each planet frame carries its own name (top-left)
   and poem (bottom), so mirrored rows keep a stable anchor while the copy
   column stays a quiet list of four points. Both tracks are capped and the row
   is justified to the container edges, so the slack lands in the gutter: a
   free-growing copy column would leave the points stranded against a void. */
.feature-cards {
  display: flex;
  flex-direction: column;
  gap: 52px;
}
.fcard {
  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 584px);
  justify-content: space-between;
  gap: 24px 48px;
  align-items: center;
}
.fcard:nth-child(even) {
  grid-template-columns: minmax(0, 584px) minmax(0, 320px);
}
.fcard:nth-child(even) .fcard-media {
  order: 2;
}
.fcard-media {
  position: relative;
  margin: 0;
  width: 100%;
  border-radius: 16px;
  overflow: hidden;
  background: var(--shot-bg);
  box-shadow: 0 1px 2px rgba(20, 19, 19, 0.06);
}
.fcard-media img {
  display: block;
  width: 100%;
  height: auto;
}
/* Bottom scrim so the poem stays legible over any planet at any length. */
.fcard-media::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 46%;
  background: linear-gradient(to top, rgba(9, 8, 11, 0.72), rgba(9, 8, 11, 0));
  pointer-events: none;
  z-index: 1;
}
/* The planet's poem lives inside the frame, like the app's landing pages. */
.fcard-poem {
  position: absolute;
  z-index: 2;
  left: 0;
  right: 0;
  bottom: 11px;
  padding: 0 20px;
  text-align: center;
  font-family: var(--serif);
  font-size: 13px;
  font-style: italic;
  line-height: 1.45;
  color: rgba(244, 242, 236, 0.82);
}
.fcard-body {
  min-width: 0;
}
/* The name sits inside the frame's top-left, movie-title style, so the copy
   below is just the four points and every card saves a title row. */
.fcard-name {
  position: absolute;
  top: 13px;
  left: 18px;
  z-index: 2;
  font-family: var(--serif);
  font-weight: 500;
  font-size: 18px;
  color: rgba(244, 242, 236, 0.94);
  text-shadow: 0 1px 10px rgba(9, 8, 11, 0.55);
  margin: 0;
  line-height: 1.2;
}
.fcard-points {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 20px;
}
.fcard-points li {
  position: relative;
  padding-left: 19px;
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.6;
  color: var(--dark-warm);
}
.fcard-points li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 0.58em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--dark-warm);
  opacity: 0.55;
}
/* ---------- Pricing ---------- */

/* Price section: hairline top + bottom borders frame an editorial spread.
   Keep the price dominant, then explain the unlocked utility surface before
   trial/refund details. */
/* Quiet two-column plan: a modest price on the left, the value list on the
   right; benefits carry the weight instead of a poster-sized number. */
/* Centered focal block: the price and the CTA sit on the page's axis so the
   whole section reads as the moment of the page, framed by hairlines. */
/* The one framed block on the page: a warm ivory transition and a near-paper
   hairline give pricing a clear boundary without adding a shadow or glow. */
.price-card {
  width: 100%;
  padding: 50px 48px 48px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  border-radius: 20px;
  /* A whisper of a hairline in the shared card tone: close to the parchment so
     the edge is barely there, just enough to trace the block. */
  border: 1px solid var(--border-card);
  background: linear-gradient(180deg, var(--parchment) 0%, var(--ivory) 100%);
}
.price-lead {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 24px;
}
.price-amount {
  font-family: var(--price-serif);
  font-weight: 500;
  font-size: 52px;
  line-height: 1;
  color: var(--brand);
  margin: 0;
  letter-spacing: -1.2px;
  display: inline-flex;
  align-items: baseline;
  gap: 0.02em;
  font-variant-numeric: lining-nums tabular-nums;
}
.price-amount .price-currency {
  font-size: 0.58em;
  color: color-mix(in srgb, var(--brand) 72%, transparent);
}
.price-vs {
  font-family: var(--serif);
  font-size: 15px;
  color: var(--olive);
  margin: 12px 0 0;
  line-height: 1.5;
  white-space: nowrap;
}
.price-vs s {
  color: var(--stone);
  text-decoration-thickness: 1px;
  text-decoration-color: var(--stone);
  margin: 0 2px;
}
.price-vs .price-highlight {
  color: var(--brand);
  font-weight: 500;
}
.price-card .btn-primary {
  margin: 0;
  min-width: 220px;
  padding: 13px 40px;
  font-size: 15px;
  justify-content: center;
}
.price-benefits {
  list-style: none;
  /* The 40px sat on .price-more (the withdrawn five-Mac link) and vanished
     with it, collapsing the button onto the list. It belongs to this gap, not
     to whatever happens to be rendered in between. */
  margin: 40px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 300px));
  justify-content: center;
  gap: 24px 48px;
  text-align: left;
}
.price-benefits li {
  display: flex;
  align-items: center;
  gap: 10px;
}
/* A tidy filled disc with a crisp ivory tick, instead of the faint ring. */
.pb-check {
  flex: 0 0 auto;
  color: var(--brand-light);
}
.pb-check circle { fill: currentColor; }
.pb-line {
  font-family: var(--serif);
  font-size: 14px;
  color: var(--olive);
  line-height: 1.4;
  min-width: 0;
}

/* ---------- Team purchase ---------- */

/* A quiet footnote under the benefits, never a second call to action: one buyer
   in a hundred needs it, and a competing button would tax the other ninety-nine.
   It sits after the benefit list rather than under the button, where the
   withdrawn five-Mac link used to be, so the read stays buy -> what you get. */
/* 40 matches the gap .price-benefits keeps below the buy button: inside this card
   40 is the step between blocks, 24 is the step between rows of one block. At 24
   the team line read as a seventh benefit. */
.price-bulk {
  margin-top: 40px;
  width: 100%;
}
/* Without JS the stepper cannot compute a price, so the whole block stays away
   rather than showing a dead control. */
html:not(.js) .price-bulk { display: none; }
.bulk-toggle {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  /* var(--serif), not var(--sans): on Latin pages the two are the same token, so
     the mistake was invisible there, but zh overrides --sans to PingFang and this
     sentence became the only sans text in a card set entirely in Song. The
     summary line showed it worst, Charter digits against sans Han in one line. */
  font-family: var(--serif);
  font-size: 13px;
  line-height: 1.5;
  /* Now a full sentence, so it must wrap: a button does not wrap on its own in
     every engine, and on a 375px screen this line is wider than the card. */
  white-space: normal;
  max-width: 34em;
  color: var(--brand);
  cursor: pointer;
  transition: color 0.2s ease;
  /* Kill the grey flash iOS/Android paint on tap, same as the FAQ summary, and
     stop a long press from selecting the sentence: both read as a glitch on a
     control whose only job is to open a panel. The number input keeps both, it
     has to be selectable to be editable. */
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
}
.bulk-toggle:hover { color: var(--brand-light); }
/* The sentence is written for meaning first: buying happens mostly on a desktop,
   where it holds one line, and a phone getting two lines costs less than dropping
   the reassurance a team buyer came for (maintainer call). This balances those two
   lines instead of leaving a stub. Deliberately NOT on zh / ja: CJK breaks at any
   character, so balancing splits words down the middle ("一个许可 / 证"), which is
   worse than the ragged line it fixes. */
html:not([lang^="zh"]):not([lang^="ja"]) .bulk-toggle { text-wrap: balance; }
/* CJK gets neither: with no spaces to aim at, `balance` and `pretty` both pick a
   break inside a word ("一个许 / 可证", "各自激 / 活"). Marking the trailing clause
   unbreakable is enough on its own: plain greedy fill then cannot fit it on the
   first line, so the phone breaks at the comma, where a reader would. */
.bulk-clause { white-space: nowrap; }
/* Collapsed it is an affordance, so it takes the site's link colour. Expanded it
   is the panel's title and steps back to near-black: a blue heading over a blue
   button gave the block two competing accents and read as a second offer. */
.bulk-toggle[aria-expanded="true"] { color: var(--near-black); }
.bulk-toggle[aria-expanded="true"]:hover { color: var(--olive); }
.bulk-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  margin-top: 16px;
  animation: bulk-in 0.18s ease-out;
}
.bulk-panel[hidden] { display: none; }
@keyframes bulk-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}
.bulk-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 16px;
}
/* Pill, like every other control on the site (both buttons, the nav, the price
   token). A square-cornered stepper next to a pill button read as two systems. */
.bulk-stepper {
  display: flex;
  align-items: center;
  padding: 0 4px;
  border: 1px solid var(--border-card);
  border-radius: 999px;
  background: var(--ivory);
}
.bulk-step {
  appearance: none;
  background: none;
  border: 0;
  width: 36px;
  height: 32px;
  font-family: var(--ui);
  font-size: 15px;
  line-height: 1;
  color: var(--olive);
  cursor: pointer;
  transition: color 0.2s ease;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
}
.bulk-step:hover:not(:disabled) { color: var(--brand); }
.bulk-step:disabled { color: var(--stone); opacity: 0.4; cursor: default; }
/* An input styled down to look like the number it replaced: the stepper is the
   frame, so the field brings no chrome of its own. 40px holds three digits. */
.bulk-count {
  width: 40px;
  padding: 0;
  border: 0;
  background: none;
  text-align: center;
  font-family: var(--ui);
  font-size: 15px;
  color: var(--near-black);
  font-variant-numeric: tabular-nums;
}
.bulk-count:focus { outline: none; }
.bulk-count:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 4px;
}
.bulk-summary {
  margin: 0;
  font-family: var(--serif);
  font-size: 13px;
  color: var(--near-black);
  white-space: nowrap;
}
/* The card's own .btn-primary is the offer; this one is the way out of a panel
   the visitor already opted into, so it borrows the site's secondary button and
   sizes down a step: at full .btn-ghost scale two pills stacked 200px apart read
   as two competing offers. */
.bulk-checkout {
  -webkit-tap-highlight-color: transparent;
  font-size: 14px;
  padding: 9px 24px;
  /* Below .btn-ghost's 158, but not free: a three-character CJK label
     ("去结账") shrinks to a pebble next to the stepper without a floor. */
  min-width: 132px;
}
@media (prefers-reduced-motion: reduce) {
  .bulk-panel { animation: none; }
}

/* ---------- FAQ ---------- */

.faq {
  border-top: 1px solid var(--border-soft);
  width: 100%;
  /* Lets the [open] answer animate from height:0 to its intrinsic height in
     browsers that support ::details-content (Safari 18.4+, Chrome 129+);
     older browsers simply open instantly. */
  interpolate-size: allow-keywords;
}
.faq-item {
  border-bottom: 1px solid var(--line-faint);
  padding: 20px 0;
}
/* Collapsed by default: only the question shows; the summary row toggles. */
.faq-item > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  cursor: pointer;
  list-style: none;
  /* Kill the grey flash iOS/Android paint on tap. */
  -webkit-tap-highlight-color: transparent;
}
.faq-item > summary::-webkit-details-marker { display: none; }
/* A thin plus that spins a third of a turn into an x when the item opens:
   the whole glyph rotates as one, rather than each bar morphing. */
.faq-chevron {
  position: relative;
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  margin-right: 10px;
  transform: rotate(0deg);
  transition: transform 0.32s cubic-bezier(0.34, 1.3, 0.5, 1);
}
.faq-item[open] .faq-chevron { transform: rotate(135deg); }
.faq-chevron::before,
.faq-chevron::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 13px;
  height: 1.4px;
  border-radius: 1px;
  background: color-mix(in srgb, var(--stone) 68%, transparent);
  transform: translate(-50%, -50%);
  transition: background 0.2s ease;
}
.faq-chevron::after { transform: translate(-50%, -50%) rotate(90deg); }
/* Hover feedback only where a real pointer can hover; on touch, a tap must not
   leave a stuck brand-light color on the question or the plus glyph. */
@media (hover: hover) {
  .faq-item > summary:hover h3 { color: var(--brand-light); }
  .faq-item > summary:hover .faq-chevron::before,
  .faq-item > summary:hover .faq-chevron::after {
    background: var(--brand-light);
  }
}
.faq-item h3 {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 16px;
  line-height: 1.35;
  color: var(--near-black);
  margin: 0;
  letter-spacing: 0.1px;
  text-wrap: balance;
}
.faq-item::details-content {
  height: 0;
  overflow: clip;
  opacity: 0;
  transition: height 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.26s ease, content-visibility 0.3s allow-discrete;
}
.faq-item[open]::details-content {
  height: auto;
  opacity: 1;
}
.faq-answer {
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.6;
  color: var(--olive);
  margin: 12px 0 4px;
}
@media (prefers-reduced-motion: reduce) {
  .faq-chevron { transition: none; }
  .faq-item::details-content { transition: none; }
}

/* ---------- Contact cards (below the FAQ) ---------- */

/* Left-aligned like every other section head, so the FAQ list above and the
   cards below share one axis. */
.contact {
  margin-top: 48px;
  text-align: left;
}
.contact-title {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 22px;
  color: var(--brand);
  margin: 0;
}
.contact-sub {
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.55;
  color: var(--olive);
  margin: 8px 0 0;
}
.contact-sub a {
  color: var(--brand);
}
.contact-sub a:hover { color: var(--brand-light); }
.contact-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-top: 24px;
  text-align: left;
}
/* Same base chrome and hover as .quote-card, so every card on the page
   answers the cursor identically. */
.contact-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 18px 20px;
  border: 1px solid var(--border-card);
  border-radius: 14px;
  background: linear-gradient(180deg, var(--parchment) 0%, var(--ivory) 100%);
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.contact-card:hover {
  border-color: var(--line);
  box-shadow: 0 2px 8px rgba(20, 19, 19, 0.05);
}
/* Head row mirrors the Voices wall author pattern: avatar + stacked name/handle. */
.contact-head {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--brand);
}
.contact-avatar {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--warm-sand);
}
/* The CLI mark is already a round transparent PNG; no extra shaping. */
.contact-card-gh .contact-avatar {
  border-radius: 0;
  background: transparent;
  object-fit: contain;
}
.contact-meta {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.contact-head b {
  font-family: var(--ui);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.1px;
  line-height: 1.3;
  color: var(--near-black);
}
.contact-handle {
  font-family: var(--ui);
  font-size: 13px;
  color: var(--stone);
  line-height: 1.3;
}
.contact-glyph {
  flex: 0 0 auto;
  margin-left: auto;
  color: var(--stone);
  opacity: 0.8;
}
.contact-stat {
  flex: 0 0 auto;
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 700;
  color: var(--brand);
  background: var(--brand-tint);
  padding: 3px 10px;
  border-radius: 999px;
  white-space: nowrap;
}
.contact-desc {
  margin: 4px 0 0;
  font-family: var(--serif);
  font-size: 14px;
  line-height: 1.55;
  color: var(--olive);
}

.report-tree dt {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 16px;
  color: var(--brand);
  margin: 24px 0 8px;
  letter-spacing: 0.1px;
}
.report-tree dt:first-of-type { margin-top: 0; }
.report-tree dd {
  font-family: var(--serif);
  font-size: 14px;
  line-height: 1.6;
  color: var(--olive);
  margin: 0;
  padding-left: 16px;
  border-left: 2px solid var(--border-soft);
  max-width: 820px;
}

/* ---------- Footer (full-bleed mole brown-black band) ---------- */

footer.foot {
  /* Break out of .page to a full-bleed band; the negative bottom margin
     swallows .page's bottom padding so the band reaches the viewport edge. */
  margin: var(--section-gap) calc(50% - 50vw) -84px;
  /* The wordmark is the first thing in the band and carries its own margin of
     0, so this top padding is the only air above it. */
  padding: 60px calc(50vw - 50%) 20px;
  background: var(--mole-dark);
  font-family: var(--serif);
  font-size: 13px;
  color: color-mix(in srgb, var(--mole-ink) 72%, transparent);
}
/* One row, five columns: the brand block is simply the first column, top-aligned
   with the link columns, so nothing floats on its own. */
.foot-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 56px;
}
.foot .mark {
  flex: 0 1 300px;
  min-width: 220px;
}
.foot .mark .wm-name {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 20px;
  line-height: 1.1;
  color: #fff;
  margin: 0;
  letter-spacing: -0.2px;
}
.foot .mark .wm-sub {
  font-family: var(--serif);
  font-size: 14px;
  line-height: 1.5;
  color: color-mix(in srgb, var(--mole-ink) 62%, transparent);
  margin: 8px 0 0;
}
.foot .wm-version {
  margin: 8px 0 0;
}
/* Reads as prose ("v1.10.0 · Release notes"), same serif voice as the column
   links; only the digits keep tabular figures. */
.foot .version-link {
  font-family: var(--serif);
  font-size: 13px;
  font-weight: 500;
  font-variant-numeric: lining-nums tabular-nums;
  color: color-mix(in srgb, var(--mole-ink) 58%, transparent);
}
.foot .version-link:hover {
  color: #fff;
}
.foot-cols {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: repeat(4, minmax(110px, 1fr));
  gap: 12px 32px;
}
.foot-col {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}
.foot-col-title {
  font-family: var(--serif);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: color-mix(in srgb, #fff 92%, transparent);
  margin: 0 0 4px;
}
.foot-col a {
  color: color-mix(in srgb, var(--mole-ink) 68%, transparent);
  font-size: 14px;
  line-height: 1.35;
}
.foot-col a:hover {
  color: #fff;
}
.foot-bottom {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px 24px;
  flex-wrap: wrap;
  margin-top: 32px;
}
.foot-official {
  margin: 0;
  font-size: 13px;
  color: color-mix(in srgb, var(--mole-ink) 50%, transparent);
}
.foot-official b {
  font-weight: 600;
  color: color-mix(in srgb, var(--mole-ink) 72%, transparent);
}
.foot .ethos {
  margin: 0;
  font-style: italic;
  color: color-mix(in srgb, var(--mole-ink) 50%, transparent);
}

/* ---------- Legal pages (Terms / Privacy / Refund) ---------- */

.legal {
  max-width: 820px;
}
.aff .aff-lead {
  font-family: var(--serif);
  font-size: 18px;
  line-height: 1.6;
  color: var(--dark-warm);
  margin: 8px 0 28px;
  max-width: 34em;
}
.aff-facts {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 0;
  margin: 0 0 32px;
}
.aff-facts li {
  font-family: var(--mono);
  font-size: 14px;
  letter-spacing: 0.3px;
  color: var(--brand);
  background: rgba(27, 54, 93, 0.06);
  border-radius: 999px;
  padding: 6px 13px;
}
.aff-cta {
  margin: 0 0 16px;
}
.aff-steps {
  margin: 8px 0 0;
  padding-left: 22px;
}
.aff-steps li {
  margin: 8px 0;
  font-family: var(--serif);
  color: var(--dark-warm);
  line-height: 1.6;
}
.aff-hint {
  font-family: var(--serif);
  font-size: 14px;
  color: var(--stone);
  margin: 0;
  max-width: 42em;
}
.aff-terms {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--stone);
  letter-spacing: 0.3px;
  margin-top: 44px;
}
#page-releases {
  max-width: none;
}
#page-releases h2 {
  font-size: 26px;
  font-family: var(--mono);
  color: var(--brand);
  margin: 40px 0 12px;
  letter-spacing: -0.3px;
}
#page-releases h2:first-of-type { margin-top: 0; }
#page-releases h2 .meta {
  font-family: var(--serif);
  font-size: 14px;
  color: var(--stone);
  font-weight: 400;
  letter-spacing: 0.4px;
  margin-left: 10px;
}
.version-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 8px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.4px;
  border-radius: 999px;
  vertical-align: 2px;
  text-decoration: none;
}
.version-tag.is-preview {
  color: #a64f00;
  background: rgba(255, 168, 56, 0.16);
}
a.version-tag.is-preview {
  transition: background 0.15s ease;
}
a.version-tag.is-preview:hover {
  background: rgba(255, 168, 56, 0.28);
}
#page-releases hr {
  border: none;
  border-top: 1px solid rgba(109,108,102,0.12);
  margin: 32px 0;
}
/* Preview builds are not on the Sparkle feed, so their release entry carries a
   manual download pill straight to Mole-preview.dmg. */
#page-releases .release-dl {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: 10px;
  padding: 2px 10px;
  font-family: var(--ui);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.2px;
  color: #fff;
  background: var(--brand-light);
  border-radius: 999px;
  text-decoration: none;
  vertical-align: middle;
  transition: background 0.15s ease;
}
#page-releases .release-dl:hover { background: var(--brand); }
#page-releases .release-dl svg { width: 13px; height: 13px; }
#page-releases ol {
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
  counter-reset: release-item;
}
#page-releases ol li {
  position: relative;
  padding: 0 0 0 28px;
  margin: 0;
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.65;
  color: var(--dark-warm);
  counter-increment: release-item;
}
#page-releases ol li + li {
  margin-top: 4px;
}
#page-releases ol li::before {
  content: counter(release-item) ".";
  position: absolute;
  left: 0;
  top: 0;
  width: 24px;
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.65;
  color: var(--stone);
  font-variant-numeric: tabular-nums;
}
#page-releases ol li b {
  font-weight: 600;
  color: var(--near-black);
  font-family: var(--serif);
}
#page-releases ol li code {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--brand);
  background: var(--brand-tint);
  padding: 1px 5px;
  border-radius: 3px;
}

/* ---------- Doc pages: Help & Docs two-column ---------- */

/* Help and Docs are dense, multi-section pages. They drop the 720px legal
   width and use the full content column: a sticky section index on the left,
   prose on the right (the index reserves ~240px, so the body still lands at a
   readable ~760px). Terms / Privacy / Refund stay narrow as plain .legal. */
#page-help,
#page-docs { max-width: none; }
.doc-layout {
  display: flex;
  align-items: flex-start;
  gap: 52px;
}
.doc-toc {
  flex: 0 0 200px;
  position: sticky;
  /* Clears the sticky nav pill: it parks at top:16 and stands 55px tall, so
     anything under 71 slides behind it. At 32 the first two TOC items were
     hidden once the page scrolled. */
  top: 88px;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.doc-toc a {
  font-family: var(--serif);
  font-size: 14px;
  line-height: 1.4;
  color: var(--stone);
  padding: 8px 12px;
  border-left: 2px solid transparent;
  border-radius: 0 6px 6px 0;
  transition: color 0.15s, background 0.15s, border-color 0.15s;
}
.doc-toc a:hover {
  color: var(--brand);
  background: color-mix(in srgb, var(--ivory) 64%, transparent);
}
.doc-toc a.is-active {
  color: var(--brand);
  font-weight: 600;
  background: transparent;
}
.doc-body {
  flex: 1 1 auto;
  min-width: 0;
}
.doc-body h2:first-of-type { margin-top: 0; }
.doc-body h2,
.doc-body h3 { scroll-margin-top: 88px; }

.legal h1,
.legal .legal-title {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 32px;
  margin: 0 0 8px;
  color: var(--brand);
}
.legal .meta {
  font-family: var(--serif);
  font-size: 13px;
  color: var(--stone);
  letter-spacing: 0.4px;
  margin: 0 0 24px;
}
/* Help and Releases put a lede sentence in .meta where Terms / Privacy / Docs
   put a date, so it carries the landing page's lede voice (16px olive) and its
   head rhythm (12 under the title, 24 above the content) instead of the 13px
   metadata voice. */
#page-help .meta,
#page-releases .meta {
  font-size: 16px;
  color: var(--olive);
  letter-spacing: 0;
  margin: 12px 0 24px;
}
.legal h2 {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 18px;
  color: var(--brand);
  margin: 32px 0 8px;
  letter-spacing: 0.1px;
}
.legal h3 {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 16px;
  color: var(--brand);
  margin: 28px 0 8px;
  letter-spacing: 0.1px;
}
.legal h4 {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 14px;
  color: var(--brand);
  margin: 24px 0 8px;
  letter-spacing: 0;
}
.legal p {
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.65;
  color: var(--dark-warm);
  margin: 0 0 16px;
}
/* The standalone partner terms use bare lists for contract clauses. Keep their
   prose voice local to that document so blog Markdown lists stay untouched. */
.pt-shell .legal ol:not([class]) li,
.pt-shell .legal ul:not([class]) li {
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.65;
  color: var(--dark-warm);
}
html[lang="zh-CN"] .pt-shell .legal ol:not([class]) li,
html[lang="zh-CN"] .pt-shell .legal ul:not([class]) li {
  line-height: 1.8;
}
/* `overflow-wrap: anywhere` is load-bearing, not polish: body has
   `overflow-x: clip`, so a token wider than the column is TRUNCATED with no way
   to scroll or select the tail. Help ships the support diagnostic command and
   Docs the install one-liner, both single unbreakable ~50-60 char URLs against a
   346px column on a 390px phone. Blog code got this in the same range; these two
   are the longest URLs on the site and were left out. */
.legal code {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--brand);
  background: var(--brand-tint);
  padding: 1px 6px;
  border-radius: 3px;
  overflow-wrap: anywhere;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.ui-label {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.88em;
  line-height: 1.25;
  color: var(--brand);
  background: var(--brand-tint);
  border: 1px solid var(--border-soft);
  border-radius: 4px;
  padding: 1px 6px;
  font-style: normal;
  white-space: nowrap;
}
.help-steps {
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.7;
  color: var(--dark-warm);
  margin: 0 0 20px;
  padding-left: 22px;
}
.help-steps li {
  margin-bottom: 16px;
}
.help-shot {
  margin: 20px 0 24px;
  padding: 0;
}
.help-shot img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 6px;
  border: 1px solid var(--border-soft);
  box-shadow: 0 1px 3px rgba(20, 19, 19, 0.08);
}
.help-shot figcaption {
  font-family: var(--serif);
  font-size: 13px;
  font-style: italic;
  color: var(--stone);
  margin-top: 8px;
  text-align: center;
}

/* ---------- Testimonials wall ---------- */

/* GitHub community card: people-forward (many contributor faces), small stats */
.gh-head {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 16px;
}
.gh-logo {
  width: 24px;
  height: 24px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--near-black);
}
.gh-logo svg { width: 23px; height: 23px; }
.gh-head b {
  font-family: var(--serif);
  font-size: 15px;
  font-weight: 600;
  color: var(--near-black);
}
.gh-avatars {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  row-gap: 8px;
  margin-bottom: 12px;
}
.gh-av {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  margin-right: -7px;
  border: 2px solid var(--ivory);
  object-fit: cover;
  background: var(--warm-sand);
}
.gh-av:last-child { margin-right: 0; }
.gh-people {
  margin: 0 0 12px;
  font-family: var(--serif);
  font-size: 15px;
  color: var(--dark-warm);
}
.gh-people b {
  color: var(--near-black);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.gh-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
}
.gh-stats span {
  font-family: var(--ui);
  font-size: 13px;
  color: var(--stone);
  white-space: nowrap;
}
.gh-stats b {
  color: var(--olive);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* 'Search for more': one quiet line under everything */
.voices-search {
  margin: 16px 0 0;
  text-align: center;
  font-family: var(--serif);
  font-size: 13px;
  color: var(--stone);
}
.voices-search-links {
  white-space: nowrap;
}
.search-link {
  font-family: var(--ui);
  font-size: 13px;
  font-weight: 600;
  color: var(--brand);
}
.search-link:hover { color: var(--brand-light); }

.quotes {
  position: relative;
  column-width: 272px;
  column-gap: 12px;
}
/* JS row-major masonry: flex columns, append-only fill, so revealing more cards
   never reshuffles the ones already on screen (CSS multicol can't promise that). */
.quotes.is-masonry {
  column-width: auto;
  display: flex;
  align-items: flex-start;
  gap: 12px;
}
.quotes.is-masonry .quotes-col {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.quotes.is-masonry .quote-card {
  margin: 0;
}
.quote-card {
  display: block;
  break-inside: avoid;
  margin: 0 0 12px;
  padding: 15px 16px 13px;
  background: linear-gradient(180deg, var(--parchment) 0%, var(--ivory) 100%);
  border: 1px solid var(--border-card);
  border-radius: 14px;
  text-decoration: none;
  color: inherit;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.quote-card:hover {
  border-color: var(--line);
  box-shadow: 0 2px 8px rgba(20, 19, 19, 0.05);
}
.quote-text {
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.5;
  color: var(--dark-warm);
  margin: 0 0 12px;
  overflow-wrap: break-word;
}
.quote-card.is-short .quote-text {
  font-size: 18px;
  line-height: 1.5;
  color: var(--near-black);
}
.quote-author {
  display: flex;
  align-items: center;
  gap: 9px;
}
.quote-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  flex: 0 0 auto;
  object-fit: cover;
  background: var(--warm-sand);
}
.quote-avatar-fallback {
  display: inline-block;
}
.quote-meta {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.quote-name {
  font-family: var(--ui);
  font-weight: 500;
  font-size: 14px;
  color: var(--near-black);
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.quote-handle {
  font-family: var(--ui);
  font-size: 13px;
  color: var(--stone);
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.quotes.is-collapsed {
  overflow: clip;
}
.quotes.is-collapsed::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 96px;
  background: linear-gradient(to bottom, rgba(245, 244, 237, 0), var(--parchment));
  pointer-events: none;
}
.quotes-more {
  display: flex;
  align-items: center;
  gap: 9px;
  width: fit-content;
  margin: 34px auto 0;
  padding: 11px 26px;
  font-family: var(--ui);
  font-size: 14px;
  font-weight: 600;
  color: var(--brand);
  background: var(--ivory);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  box-shadow: 0 1px 2px rgba(20, 19, 19, 0.05);
  cursor: pointer;
  transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.quotes-more::after {
  content: "";
  width: 7px;
  height: 7px;
  border-right: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  transition: transform .2s ease;
}
.quotes-more.is-expanded::after {
  transform: rotate(-135deg) translate(-1px, -1px);
}
.quotes-more:hover {
  border-color: var(--brand);
  box-shadow: 0 5px 16px rgba(27, 54, 93, 0.12);
  transform: translateY(-1px);
}

/* verified check after the name */
.quote-verified {
  display: inline-block;
  width: 13px;
  height: 13px;
  margin-left: 4px;
  vertical-align: -1px;
  background: var(--brand);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M22.25 12l-2.4-2.75.33-3.64-3.57-.81L14.74 1.6 12 2.79 9.26 1.6 7.4 4.8l-3.57.8.33 3.65L1.75 12l2.41 2.75-.33 3.65 3.57.81L9.26 22.4 12 21.2l2.74 1.19 1.87-3.2 3.57-.81-.33-3.64L22.25 12zm-11.39 4.32L7 12.45l1.41-1.41 2.45 2.44 5.34-5.34 1.41 1.42-6.75 6.76z'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M22.25 12l-2.4-2.75.33-3.64-3.57-.81L14.74 1.6 12 2.79 9.26 1.6 7.4 4.8l-3.57.8.33 3.65L1.75 12l2.41 2.75-.33 3.65 3.57.81L9.26 22.4 12 21.2l2.74 1.19 1.87-3.2 3.57-.81-.33-3.64L22.25 12zm-11.39 4.32L7 12.45l1.41-1.41 2.45 2.44 5.34-5.34 1.41 1.42-6.75 6.76z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* YouTube review cards */
.video-card { padding: 0; overflow: hidden; }
.video-thumb {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  background: var(--warm-sand);
  overflow: hidden;
}
.video-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.video-play {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: rgba(20, 19, 19, 0.62);
  transition: background .18s ease, transform .18s ease;
}
.video-play::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 52%;
  transform: translate(-50%, -50%);
  border-style: solid;
  border-width: 7px 0 7px 12px;
  border-color: transparent transparent transparent #fff;
}
.video-card:hover .video-play {
  background: var(--brand);
  transform: translate(-50%, -50%) scale(1.06);
}
.video-title {
  margin: 16px 18px 12px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.video-card .quote-author { margin: 0 18px 16px; }
.quote-avatar-yt {
  position: relative;
  background: #ff0033;
}
.quote-avatar-yt::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 53%;
  transform: translate(-50%, -50%);
  border-style: solid;
  border-width: 5px 0 5px 8px;
  border-color: transparent transparent transparent #fff;
}

/* ---------- Responsive ---------- */

@media (max-width: 880px) {
  :root { --section-gap: 64px; }
  .page {
    padding: 16px 28px 80px;
  }
  .hero { padding-bottom: 32px; }
  .hero h1 {
    font-size: 64px;
    letter-spacing: -1px;
  }
  .hero h1 .cn { margin-left: 12px; }
  .hero .tagline { font-size: 18px; }

  .section-title { font-size: 26px; }

  .gallery {
    grid-template-columns: minmax(0, 1fr);
  }
  .gallery-caption,
  .gallery-tabs {
    grid-column: 1;
    grid-row: auto;
  }
  .gallery-tabs { gap: 6px; justify-content: flex-start; }
  .gallery-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    padding-bottom: 6px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .gallery-tabs::-webkit-scrollbar { display: none; }
  .gallery-tabs button {
    flex: 0 0 auto;
    padding: 8px 10px;
  }

  .feature-cards { gap: 44px; }
  .fcard,
  .fcard:nth-child(even) {
    grid-template-columns: 1fr;
    gap: 16px;
  }
  .fcard:nth-child(even) .fcard-media { order: 0; }

  .price-card {
    padding: 34px 22px 30px;
    border-radius: 16px;
  }
  .price-lead { margin-bottom: 18px; }
  .price-benefits {
    grid-template-columns: minmax(0, 320px);
    justify-content: center;
    gap: 16px;
  }
  /* The card compresses everything at this width (padding 50/48 -> 34/30, benefit
     rows 24 -> 16), and this gap has to compress with it: measured, the team line
     sat 40 below rows that are 16 apart, which reads as a hole rather than a
     block break. */
  .price-bulk { margin-top: 24px; }
  /* 16px is the iOS threshold: focusing a smaller field zooms the whole page and
     the buyer has to pinch back out. It is a control, not prose, so this sits
     outside the reading ladder. */
  .bulk-count { font-size: 16px; }
  html[lang="en"] #pricing .section-title {
    font-size: 20px;
    white-space: nowrap;
  }
  .price-amount { font-size: 46px; }
  .price-vs { font-size: 14px; }
  .price-card .btn-primary { margin: 0; min-width: 200px; }
  .price-benefits { margin-top: 32px; }

  .doc-layout {
    flex-direction: column;
    gap: 0;
  }
  .doc-toc {
    position: static;
    flex: none;
    width: 100%;
    margin-bottom: 24px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border-soft);
  }
  .doc-toc a { border-left: 0; border-radius: 6px; }

  footer.foot {
    padding-top: 40px;
  }
  .foot-top {
    display: block;
  }
  .foot-cols {
    grid-template-columns: repeat(2, minmax(140px, 1fr));
    gap: 24px 32px;
    width: 100%;
  }
  .foot .mark {
    margin-bottom: 32px;
  }
  .foot-bottom {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .nav-links { display: none; }
  .site-nav { gap: 12px; }
}

@media (max-width: 640px) {
  /* Some iOS browsers paint the bottom safe area from body instead of html or
     a dynamically updated theme-color. The page above remains parchment via
     .page; only the browser-owned canvas beyond its bottom inherits this. */
  body.footer-in-view {
    background: var(--mole-dark);
  }

  /* Chinese prose drops one ladder step on a phone. A Han character fills its em
     box, so 15px of Chinese carries far more visual weight than 15px of Charter,
     whose x-height is half that: the same size that reads right on the English
     page reads oversized on the Chinese one, and the 1.75 leading that gives a
     Chinese column air on a wide screen turns into slack in a 390px one. Latin
     pages and every desktop width are untouched; the section title stays at 26 so
     the head keeps its distance from the body. */
  html:is([lang="zh-CN"], [lang="zh-Hant"], [lang="zh-TW"]) body {
    font-size: 14px;
    line-height: 1.7;
  }
  html:is([lang="zh-CN"], [lang="zh-Hant"], [lang="zh-TW"]) .hero .tagline { font-size: 16px; }
  html:is([lang="zh-CN"], [lang="zh-Hant"], [lang="zh-TW"]) .section-lede { font-size: 15px; }
  html:is([lang="zh-CN"], [lang="zh-Hant"], [lang="zh-TW"]) .fcard-points li,
  html:is([lang="zh-CN"], [lang="zh-Hant"], [lang="zh-TW"]) .faq-answer {
    font-size: 14px;
    line-height: 1.7;
  }
  html:is([lang="zh-CN"], [lang="zh-Hant"], [lang="zh-TW"]) .pt-shell .legal p,
  html:is([lang="zh-CN"], [lang="zh-Hant"], [lang="zh-TW"]) .pt-shell .legal ol:not([class]) li,
  html:is([lang="zh-CN"], [lang="zh-Hant"], [lang="zh-TW"]) .pt-shell .legal ul:not([class]) li {
    font-size: 14px;
    line-height: 1.7;
  }
  /* The footer stays off the body step-down, so its heavier Han voices read
     oversized on a phone the same way the prose did: the 20px wordmark and the
     four column-link stacks. Drop those one ladder step for Chinese only; the
     13px bottom line (official notice / ethos) is already at the prose floor
     and is left alone. */
  html:is([lang="zh-CN"], [lang="zh-Hant"], [lang="zh-TW"]) .foot .mark .wm-name {
    font-size: 18px;
  }
  html:is([lang="zh-CN"], [lang="zh-Hant"], [lang="zh-TW"]) .foot .mark .wm-sub,
  html:is([lang="zh-CN"], [lang="zh-Hant"], [lang="zh-TW"]) .foot-col a {
    font-size: 13px;
  }
  .section-num {
    display: none;
  }
  .contact-cards {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 480px) {
  .page {
    padding-left: 22px;
    padding-right: 22px;
  }
  html[lang="zh-CN"] .page,
  html:is([lang="zh-Hant"], [lang="zh-TW"]) .page {
    padding-left: 20px;
    padding-right: 20px;
  }
  .nav-wrap {
    margin: 0 -11px 24px;
  }
  .site-nav {
    gap: 8px;
    padding: 7px 11px;
    /* The compact phone bar does not need the desktop CTA height reservation. */
    min-height: 0;
  }
  .nav-brand b { font-size: 15px; }
  .nav-brand img { width: 23px; height: 23px; }
  .nav-actions { gap: 10px; margin-left: auto; }
  .nav-buy,
  .nav-download {
    font-size: 12px;
    padding: 8px 11px;
  }
  .version-link {
    font-size: 12px;
    white-space: nowrap;
  }
  .lang-trigger {
    min-height: 22px;
    gap: 4px;
  }
  .lang-current-code {
    display: inline;
    font-size: 12px;
    font-weight: 600;
    line-height: 1;
  }
  .lang-current-name {
    display: none;
  }
  .hero .tagline { font-size: 17px; }
  .voices-search-lead,
  .voices-search-links {
    display: block;
  }
  .voices-search-links {
    margin-top: 8px;
  }
  .hero-offer { gap: 6px 12px; margin-bottom: 28px; }
  .hero-trust {
    flex-wrap: wrap;
    gap: 4px 14px;
  }
  .hero-trust > * + *::before {
    content: none;
  }
  .tip-target::after {
    display: none;
  }
  .hero-cta {
    width: 100%;
    flex-direction: row;
    align-items: center;
    flex-wrap: nowrap;
    gap: 6px;
  }
  .hero-cta .btn-primary,
  .hero-cta .btn-ghost {
    width: auto;
    min-width: 0;
    min-height: 46px;
    flex: 1 1 0;
    padding: 11px 10px;
    font-size: 14px;
    justify-content: center;
    line-height: 1.1;
    text-align: center;
    white-space: nowrap;
  }
  .gallery-caption {
    min-height: auto;
  }
  /* On a phone the stacked name + line read as two competing captions, and
     the active tab pill already names the tool, so keep the line only. */
  .gallery-caption .title { display: none; }
  .price-terms {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 3px 14px;
    max-width: 360px;
  }
  html[lang="zh-CN"] .price-terms,
  html:is([lang="zh-Hant"], [lang="zh-TW"]) .price-terms {
    max-width: 380px;
    word-break: keep-all;
  }
  .price-terms .sep {
    display: none;
  }
  html[lang="zh-CN"] .section-lede,
  html[lang="zh-CN"] .fcard-points li,
    html[lang="zh-CN"] .faq-answer,
  html:is([lang="zh-Hant"], [lang="zh-TW"]) .section-lede,
  html:is([lang="zh-Hant"], [lang="zh-TW"]) .fcard-points li,
    html:is([lang="zh-Hant"], [lang="zh-TW"]) .faq-answer {
    text-wrap: wrap;
    line-break: loose;
  }
}

@media (max-width: 340px) {
  html[lang="en"] #pricing .section-title {
    font-size: 17px;
  }
  .contact-card {
    min-width: 0;
  }
  .contact-head {
    display: grid;
    grid-template-columns: 34px minmax(0, 1fr) auto;
    align-items: center;
  }
  .contact-avatar {
    grid-column: 1;
    grid-row: 1 / span 2;
  }
  .contact-meta {
    grid-column: 2;
    grid-row: 1;
  }
  .contact-glyph {
    grid-column: 3;
    grid-row: 1;
    justify-self: end;
    margin-left: 0;
  }
  .contact-stat {
    grid-column: 2 / 4;
    grid-row: 2;
    justify-self: start;
  }
  .foot-cols {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 24px 20px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .gallery-panel,
  .gallery-caption {
    transition: none;
    transform: none;
  }
}

/* ============================================================== */
/* Hero glyph load + orbit. Gallery motion is handled above by    */
/* the product-stage horizontal transition.                       */
/* ============================================================== */

.hero h1 {
  opacity: 0;
  transform: translateY(10px);
  filter: blur(6px);
  animation: hero-rise 900ms cubic-bezier(0.16, 1, 0.3, 1) 120ms forwards;
}
@keyframes hero-rise {
  to {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
}

.cn-orbit {
  position: relative;
  display: inline-block;
}
.cn-orbit::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 5px;
  height: 5px;
  margin: -2.5px 0 0 -2.5px;
  border-radius: 50%;
  background: var(--brand);
  opacity: 0.55;
  animation: cn-orbit 14s linear infinite;
  pointer-events: none;
}
@keyframes cn-orbit {
  from { transform: rotate(0deg)   translateX(64px) rotate(0deg); }
  to   { transform: rotate(360deg) translateX(64px) rotate(-360deg); }
}

@media (max-width: 880px) {
  .cn-orbit::after { animation-name: cn-orbit-sm; }
  @keyframes cn-orbit-sm {
    from { transform: rotate(0deg)   translateX(40px) rotate(0deg); }
    to   { transform: rotate(360deg) translateX(40px) rotate(-360deg); }
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 0.01ms !important;
  }
  .hero h1 {
    animation: none;
    opacity: 1;
    transform: none;
    filter: none;
  }
  .cn-orbit::after {
    animation: none;
    opacity: 0;
  }
}

@media (prefers-reduced-transparency: reduce) {
  .lang-menu,
  .tip-target::after {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: var(--ivory);
  }
  .site-nav {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: var(--ivory);
  }
}

/* Confirmation pill shown after a mailto click copies the address. */
.copy-toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%) translateY(6px);
  background: var(--near-black);
  color: var(--ivory);
  font: 500 13px/1 var(--ui);
  padding: 10px 18px;
  border-radius: 999px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
  z-index: 1000;
}
.copy-toast.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .copy-toast {
    transition: none;
    transform: translateX(-50%);
  }
}

@media (prefers-contrast: more) {
  :root {
    --stone: #4a4944;
    --olive: #33332f;
    --border-soft: #b8b5a8;
    --line: #9f9b8d;
  }
  .btn-primary,
  .btn-ghost,
  .gallery-tabs button,
  .price-card,
  .gallery-frame {
    border-width: 2px;
  }
  .gallery-tabs button.is-active {
    box-shadow: inset 0 -3px 0 var(--brand);
  }
}
/* ============ Blog ============ */
/* Blog reuses the .legal + .doc-body reading system (h1 / h2 / h3, prose, TOC);
   only the grouped index, the article metadata, and the closing CTA are
   blog-specific. The article title takes --poem-serif so Chinese articles later
   render in Kaiti while English stays on Charter. */
/* Blog pages run at the full .page width like #page-releases: the 820px legal
   column read as a mismatch against the site chrome. The title fills the line
   before wrapping (balance made it break early). */
.legal.blog,
.legal.blog-index {
  max-width: none;
}
.blog .blog-title {
  font-family: var(--poem-serif);
  font-size: 32px;
  line-height: 1.2;
}
.blog .blog-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  font-family: var(--serif);
  font-size: 13px;
  line-height: 1.5;
  color: var(--stone);
  letter-spacing: 0.4px;
  margin: 0 0 24px;
}
.blog .blog-meta > span {
  white-space: nowrap;
}
.blog-cover {
  width: 100%;
  aspect-ratio: 16 / 7;
  margin: 0 0 32px;
  border-radius: 14px;
  overflow: hidden;
  background: var(--brand-tint);
}
.blog-cover img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
@media (max-width: 640px) {
  .blog-cover { aspect-ratio: 16 / 9; }
}
.blog-crumb {
  font-family: var(--serif);
  font-size: 13px;
  line-height: 1.4;
  color: var(--stone);
  margin: 0 0 16px;
}
.blog-crumb a { color: var(--brand); }
.blog-crumb a:hover { color: var(--brand-light); }
.blog-crumb-sep { margin: 0 7px; color: var(--line); }
.blog-related {
  margin: 76px 0 0;
  padding-top: 32px;
  border-top: 1px solid var(--border-card);
}
.blog-related-title {
  font-family: var(--poem-serif);
  font-size: 22px;
  line-height: 1.2;
  margin: 0 0 24px;
}
.blog-related-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
.blog-related-list a {
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: 100%;
  padding: 18px 18px 20px;
  border: 1px solid var(--border-card);
  border-radius: 14px;
  background: linear-gradient(180deg, var(--parchment) 0%, var(--ivory) 100%);
  text-decoration: none;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.blog-related-list a:hover {
  border-color: var(--line);
  box-shadow: 0 2px 8px rgba(20, 19, 19, 0.05);
}
.blog-related-cat {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  color: var(--stone);
}
.blog-related-name {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 16px;
  line-height: 1.35;
  color: var(--near-black);
  flex: 1 1 auto;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  transition: color 0.15s ease;
}
.blog-related-list a:hover .blog-related-name { color: var(--brand-light); }
.blog-related-meta {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.3px;
  color: var(--stone);
  margin-top: auto;
}
@media (max-width: 640px) {
  .blog-related-list { grid-template-columns: 1fr; gap: 14px; }
}
.blog-diagram {
  width: 100%;
  max-width: 100%;
  margin: 24px 0 32px;
}
.blog-diagram img,
.blog-diagram video {
  display: block;
  width: 100%;
  height: auto;
}
.blog-diagram figcaption {
  font-family: var(--serif);
  font-size: 13px;
  font-style: italic;
  line-height: 1.5;
  color: var(--stone);
  margin-top: 8px;
}
.blog-cta {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 24px;
  margin: 44px 0 0;
  padding: 16px 22px;
  border: 1px solid var(--border-card);
  border-radius: 12px;
  background: var(--line-faint);
}
.blog-cta-copy { min-width: 0; }
/* Home-page latest-posts section: the page's numbered section grammar with
   deliberately quiet one-line rows, closing the page before the footer. */
.blog-latest-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.blog-latest-list a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}
.blog-latest-title {
  font-family: var(--serif);
  font-size: 16px;
  line-height: 1.5;
}
.blog-latest-date {
  flex: none;
  font-family: var(--serif);
  font-size: 13px;
  color: var(--stone);
}
/* The section title doubles as the entry to the full blog index: it keeps the
   title color and only reveals the affordance on hover, no extra link row. */
.blog-latest .section-title a {
  color: inherit;
}
.blog-latest .section-title a:hover {
  color: var(--brand);
}
@media (max-width: 480px) {
  .blog-latest-list a {
    flex-direction: column;
    gap: 4px;
  }
}
/* Doubled class beats `.legal p`'s bottom margin, which otherwise pushes the
   text off the CTA row's vertical center. */
.blog-cta .blog-cta-text {
  font-family: var(--serif);
  font-size: 16px;
  line-height: 1.5;
  color: var(--dark-warm);
  margin: 0;
}
.blog-cta-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
/* Match the site button system: primary lightens on hover, ghost keeps a strong
   navy border and fills with brand-tint, so both read clearly as buttons. */
.blog-cta-btn,
.blog-cta-btn-secondary {
  flex: none;
  font-family: var(--ui);
  font-size: 14px;
  font-weight: 600;
  border-radius: 999px;
  padding: 8px 20px;
  border: 1.5px solid var(--brand);
  text-decoration: none;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.blog-cta-btn {
  color: var(--ivory);
  background: var(--brand);
}
.blog-cta-btn:hover {
  background: var(--brand-light);
  border-color: var(--brand-light);
  color: var(--ivory);
  transform: translateY(-1px);
}
.blog-cta-btn-secondary {
  color: var(--brand);
  background: transparent;
}
.blog-cta-btn-secondary:hover {
  background: var(--brand-tint);
  color: var(--brand);
  transform: translateY(-1px);
}
@media (max-width: 640px) {
  .blog-cta {
    grid-template-columns: 1fr;
    gap: 16px;
  }
}
.blog-index-title {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 32px;
  color: var(--near-black);
  letter-spacing: -0.3px;
  margin: 0 0 8px;
}
.blog-index-intro {
  font-family: var(--serif);
  font-size: 16px;
  color: var(--stone);
  margin: 0 0 24px;
}
.blog-group + .blog-group {
  margin-top: 76px;
}
.blog-group-head {
  max-width: 760px;
  margin: 0 0 24px;
}
.blog-group-title {
  font-family: var(--poem-serif);
  font-size: 22px;
  line-height: 1.2;
  color: var(--near-black);
  margin: 0 0 8px;
}
.blog-group-description {
  font-family: var(--serif);
  font-size: 14px;
  line-height: 1.55;
  color: var(--stone);
  margin: 0;
}
/* 12px, the floor of the 12-24 in-block band and what the voices wall already
   uses between its cards (.quotes.is-masonry gap, its column gap, and
   .quote-card's own margin are all 12). These cards carry a border and a fill,
   so they cannot fuse the way a prose list does. It shipped at 32px/28px, wide
   enough that the cards read as unrelated tiles rather than one wall. */
.blog-cards {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
@media (max-width: 1024px) {
  .blog-cards { grid-template-columns: repeat(2, 1fr); }
}
/* Each post is one card in the homepage card language (contact cards): the
   same gradient, border, radius, and hover, with the art flush to the top. */
.blog-card {
  border: 1px solid var(--border-card);
  border-radius: 14px;
  background: linear-gradient(180deg, var(--parchment) 0%, var(--ivory) 100%);
  overflow: hidden;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.blog-card:hover {
  border-color: var(--line);
  box-shadow: 0 2px 8px rgba(20, 19, 19, 0.05);
}
.blog-card a {
  display: flex;
  flex-direction: column;
  height: 100%;
  text-decoration: none;
}
.blog-card-media {
  display: block;
  aspect-ratio: 16 / 9;
  background: var(--brand-tint);
  border-bottom: 1px solid var(--line-faint);
  overflow: hidden;
}
.blog-card-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.35s ease;
}
.blog-card a:hover .blog-card-media img { transform: scale(1.03); }
.blog-card-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 14px 18px 16px;
}
.blog-card-title {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 17px;
  line-height: 1.3;
  color: var(--near-black);
  letter-spacing: 0.1px;
  margin: 0 0 4px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  transition: color 0.15s ease;
}
.blog-card a:hover .blog-card-title { color: var(--brand-light); }
.blog-card-desc {
  font-family: var(--serif);
  font-size: 14px;
  line-height: 1.55;
  color: var(--dark-warm);
  margin: 0 0 12px;
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.blog-card-date {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.3px;
  color: var(--stone);
  margin-top: auto;
}
@media (max-width: 640px) {
  .blog-cards { grid-template-columns: 1fr; gap: 24px; }
}
.legal.blog .doc-body pre {
  margin: 0 0 20px;
  padding: 14px 16px;
  background: rgba(20, 19, 19, 0.04);
  border: 0;
  border-radius: 10px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.legal.blog .doc-body pre code {
  display: block;
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.7;
  color: var(--dark-warm);
  background: none;
  border: 0;
  padding: 0;
  white-space: pre;
}
/* Inline code in blog prose matches the block: warm, borderless, same family
   as the page instead of the site-wide blue chip (that stays on legal/docs). */
.legal.blog .doc-body :not(pre) > code {
  color: var(--dark-warm);
  background: rgba(20, 19, 19, 0.05);
  border-radius: 4px;
  padding: 1px 6px;
  overflow-wrap: anywhere;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
/* Comparison tables keep their natural column widths on narrow screens, but
   scroll inside the reading column instead of widening the whole page. */
.legal.blog .doc-body table {
  display: block;
  width: 100%;
  max-width: 100%;
  margin: 0 0 24px;
  overflow-x: auto;
  border-collapse: collapse;
  -webkit-overflow-scrolling: touch;
}
.legal.blog .doc-body th,
.legal.blog .doc-body td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--border-soft);
  font-family: var(--serif);
  font-size: 13px;
  line-height: 1.45;
  text-align: left;
  vertical-align: top;
}
.legal.blog .doc-body th {
  color: var(--brand);
  font-weight: 600;
}
