/*
 * Copyright (c) 2026. Y-Trace Pty Ltd. All rights reserved.
 *
 * apisprime.com.au marketing homepage — styles.
 * Design source of truth: 00_marketing/04_homepage/02_design-output/
 * ApisPrime Homepage.dc.html (claude.design export, 2026-08-17).
 *
 * Two-world palette: dark brand shell (nav/hero/final CTA/footer) around
 * light product sections. Self-hosted subset fonts; no external requests.
 */

/* ---- Fonts (subset TTFs, Latin-1 + punctuation, built from
        frontend/assets/google_fonts via fontTools.subset) ------------------ */
@font-face { font-family: 'Plus Jakarta Sans'; src: url('fonts/PlusJakartaSans-Bold.ttf') format('truetype'); font-weight: 700; font-display: swap; }
@font-face { font-family: 'Plus Jakarta Sans'; src: url('fonts/PlusJakartaSans-ExtraBold.ttf') format('truetype'); font-weight: 800; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('fonts/Inter-Regular.ttf') format('truetype'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('fonts/Inter-Medium.ttf') format('truetype'); font-weight: 500; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('fonts/Inter-SemiBold.ttf') format('truetype'); font-weight: 600; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('fonts/Inter-Bold.ttf') format('truetype'); font-weight: 700; font-display: swap; }

/* ---- Tokens ------------------------------------------------------------- */
:root {
  --brand-orange: #F89000;
  --honey: #FBA81C;
  --honey-700: #F2960A;
  --honey-300: #FFC75A;
  --honey-50: #FEF3DC;
  --honey-50-border: #F5E6BD;
  --ink-900: #2A2826;
  --ink-800: #494949;
  --ink-600: #6E6E6E;
  --ink-200: #EFEAE6;
  --ink-kicker: #8A5A0A;         /* kicker/accent ink on light — AA-safe */
  --paper: #FAF7F7;
  --surface: #FFFFFF;
  --night-900: #0E0D0C;
  --night-800: #151312;
  --night-100: #F0F0F0;
  --night-muted: #8f8a85;
  --btn-primary-text: #4A3206;
  --hd: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --bd: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  /* Hexagon lattice, the brand texture (thin #F89000 strokes) */
  --hex: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='56' height='96' viewBox='0 0 56 96'><g fill='none' stroke='%23F89000' stroke-width='1.4'><polygon points='0,-32 -28,-16 -28,16 0,32 28,16 28,-16'/><polygon points='56,-32 28,-16 28,16 56,32 84,16 84,-16'/><polygon points='28,16 0,32 0,64 28,80 56,64 56,32'/><polygon points='0,64 -28,80 -28,112 0,128 28,112 28,80'/><polygon points='56,64 28,80 28,112 56,128 84,112 84,80'/></g></svg>");
}

/* ---- Reset / base ------------------------------------------------------- */
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
html, body { margin: 0; padding: 0; }
body {
  /* Paper, not night. The dark value survived the v1.10 A1 hero flip and was
     still showing through the ONE strip nothing else paints: the sticky nav
     before it turns opaque. Result was a near-black bar carrying ink-900
     text — the low-contrast header the user reported. */
  background: var(--paper);
  color: var(--ink-800);
  font: 400 18px/1.6 var(--bd);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img, video { max-width: 100%; display: block; }
a { color: var(--brand-orange); text-decoration: none; }
button { font: inherit; cursor: pointer; }
:focus-visible { outline: 2px solid var(--honey); outline-offset: 3px; border-radius: 4px; }
h1, h2, h3, h4, p, ul { margin: 0; }
ul { padding: 0; list-style: none; }
section { scroll-margin-top: 92px; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 500;
  background: var(--honey); color: var(--btn-primary-text);
  font: 600 15px/1 var(--bd); padding: 12px 18px; border-radius: 0 0 10px 0;
}
.skip-link:focus { left: 0; }

.wrap { max-width: 1200px; margin: 0 auto; }

/* ---- Buttons ------------------------------------------------------------ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 11px;
  border: 1px solid transparent; border-radius: 999px; text-align: center;
  transition: filter .15s ease, background .15s ease, border-color .15s ease;
  min-height: 46px;
}
.btn--primary {
  font: 700 16px/1 var(--bd); color: var(--btn-primary-text);
  background: var(--honey); padding: 13px 26px;
  box-shadow: 0 0 34px rgba(248, 144, 0, .22);
}
.btn--primary:hover { background: var(--honey-700); color: var(--btn-primary-text); }
.btn--hero {
  font: 700 18px/1 var(--bd); padding: 19px 34px; min-height: 56px;
  box-shadow: 0 0 44px rgba(248, 144, 0, .30);
}
.btn--ghost-dark {
  /* Name kept for markup stability; look flipped to ink-on-honey when the
     hero went light (v1.10 A1) — this class only ever appears over the hero/nav. */
  font: 600 16px/1 var(--bd); color: var(--ink-900);
  border-color: rgba(42, 40, 38, .35); background: transparent; padding: 13px 24px;
}
.btn--ghost-dark:hover { border-color: rgba(42, 40, 38, .62); background: rgba(255, 255, 255, .45); color: var(--ink-900); }
.btn--ghost-hero { font-size: 18px; padding: 19px 30px; min-height: 56px; }
/* Nav pair (Log in / Sign up): the body sizes would push the header past its
   72px row and crowd the burger on tablets, so both shrink together — never
   one of them, or they stop reading as a pair. */
.btn--nav { font-size: 15px; padding: 10px 18px; min-height: 40px; }
.btn--primary.btn--nav { box-shadow: 0 0 20px rgba(248, 144, 0, .20); }
.play-dot {
  width: 22px; height: 22px; border-radius: 999px; background: var(--brand-orange);
  display: inline-flex; align-items: center; justify-content: center; flex: none;
}
.play-dot svg { width: 9px; height: 10px; display: block; }

/* ---- Announcement bar --------------------------------------------------- */
.announce {
  position: relative; background: linear-gradient(90deg, var(--honey-700), var(--honey-300));
  display: flex; align-items: center; justify-content: center; gap: 14px;
  padding: 11px 56px; text-align: center;
}
.announce[hidden] { display: none; }
.announce__text { font: 600 15px/1.3 var(--bd); color: var(--btn-primary-text); }
.announce__link {
  font: 700 15px/1.3 var(--bd); color: var(--btn-primary-text);
  text-decoration: underline; text-underline-offset: 3px;
}
.announce__close {
  position: absolute; right: 18px; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px; border: 0; border-radius: 999px;
  background: rgba(74, 50, 6, .12); color: var(--btn-primary-text);
  font: 600 16px/1 var(--bd);
  display: flex; align-items: center; justify-content: center;
}

/* ---- Nav ---------------------------------------------------------------- */
.nav { position: sticky; top: 0; z-index: 120; }
.nav__bg {
  /* ALWAYS on (user, 2026-08-19). It used to fade in past 620px of scroll,
     which left the bar transparent over a dark body for the whole first
     screen and made the header hard to read. One appearance, everywhere. */
  position: absolute; inset: 0; opacity: 1;
  background: rgba(254, 243, 220, .88); /* honey-50 blur — nav sits on the honey hero (v1.10 A1) */
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(42, 40, 38, .10);
}
.nav__row {
  position: relative; height: 78px; padding: 0 60px;
  display: flex; align-items: center; justify-content: space-between; gap: 32px;
  max-width: 1440px; margin: 0 auto;
}
.lockup { display: flex; align-items: center; gap: 11px; }
.lockup img { width: 34px; height: 34px; }
/* A console-uploaded mark is whatever shape the admin gave us — usually a wide
   lockup, not a square emblem. Pin the height to the row, let the width
   follow, and cap it so a very wide file cannot push the nav links off the
   edge. Never squash it into the 34x34 box. */
.lockup img.lockup__mark--custom {
  width: auto; height: 34px; max-width: 190px; object-fit: contain;
}
.lockup span {
  font: 800 20px/1 var(--hd); letter-spacing: .04em; color: var(--ink-900); white-space: nowrap;
}
.lockup b { font-weight: 800; color: var(--brand-orange); }
.nav__links { display: flex; align-items: center; gap: 36px; }
.nav__links a {
  font: 500 17px/1 var(--bd); color: var(--ink-800);
  border-bottom: 2px solid transparent; padding-bottom: 3px;
}
.nav__links a:hover { color: var(--ink-900); border-bottom-color: var(--brand-orange); }
.nav__actions { display: flex; align-items: center; gap: 12px; }
.nav__burger {
  display: none; width: 44px; height: 44px; border: 1px solid rgba(42, 40, 38, .25);
  border-radius: 12px; background: transparent;
  flex-direction: column; align-items: center; justify-content: center; gap: 5px;
}
.nav__burger span { width: 18px; height: 2px; background: var(--ink-900); display: block; }
.nav__menu {
  display: none; position: absolute; top: 100%; left: 0; right: 0;
  background: rgba(254, 243, 220, .98); border-bottom: 1px solid rgba(42, 40, 38, .10);
  padding: 10px 20px 18px; flex-direction: column;
}
.nav__menu.is-open { display: flex; }
.nav__menu a {
  font: 500 18px/1 var(--bd); color: var(--ink-800); padding: 15px 4px;
  border-bottom: 1px solid rgba(42, 40, 38, .08);
}
.nav__menu a:last-child { border-bottom: 0; }

/* ---- Hero --------------------------------------------------------------- */
.hero {
  position: relative; padding: 74px 60px 0; overflow: hidden;
  /* v1.10 A1 (user): the night hero read heavy — honey-led like the app's
     gradient header, fading to paper so the page below connects. */
  background: linear-gradient(180deg, var(--honey-300) 0%, var(--honey-50) 62%, var(--paper) 100%);
}
.hero::before {
  content: ""; position: absolute; inset: 0; opacity: .10;
  background-image: var(--hex); background-size: 56px 96px;
}
.hero::after {
  content: ""; position: absolute; top: -180px; left: 50%; transform: translateX(-50%);
  width: 900px; height: 420px; pointer-events: none;
  background: radial-gradient(ellipse at center, rgba(255, 255, 255, .55), rgba(255, 255, 255, 0) 68%);
}
.hero__inner {
  position: relative; z-index: 1; max-width: 1000px; margin: 0 auto; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 24px;
}
.kicker {
  font: 700 13px/1.4 var(--bd); letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-kicker); /* AA-safe on the honey hero and light sections alike */
}
.hero h1 {
  font: 800 clamp(38px, 5vw, 72px)/1.06 var(--hd); letter-spacing: -.02em;
  color: var(--ink-900); text-wrap: balance;
}
.hero__sub { max-width: 800px; font: 400 clamp(17px, 1.5vw, 21px)/1.6 var(--bd); color: var(--ink-800); text-wrap: pretty; }
.hero__ctas { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 6px; flex-wrap: wrap; }
.hero__micro { font: 400 15px/1.5 var(--bd); color: var(--ink-600); }

/* ---- Hero video --------------------------------------------------------- */
.demo { position: relative; z-index: 1; max-width: 1200px; margin: 56px auto 0; padding-bottom: 74px; }
.demo__glow {
  position: relative; border-radius: 20px; padding: 10px;
  background: linear-gradient(180deg, rgba(248, 144, 0, .55), rgba(248, 144, 0, .10));
  box-shadow: 0 0 70px rgba(248, 144, 0, .20);
}
.demo__frame {
  position: relative; width: 100%; aspect-ratio: 16 / 9; border-radius: 13px;
  overflow: hidden; background: var(--night-800);
}
.demo__frame video,
/* the iframe a YouTube/Vimeo embed swaps in — same box as the <video> it
   replaces, or the provider player collapses to its default 300x150 */
.demo__frame iframe { width: 100%; height: 100%; object-fit: cover; border: 0; display: block; }
.demo__poster { position: absolute; inset: 0; }
.demo__poster[hidden] { display: none; }
.demo__play {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: clamp(62px, 8vw, 104px); height: clamp(62px, 8vw, 104px);
  border-radius: 999px; border: 0; background: rgba(251, 168, 28, .95);
  color: var(--btn-primary-text);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 14px 50px rgba(0, 0, 0, .45);
  transition: transform .15s ease;
}
.demo__play:hover { transform: translate(-50%, -50%) scale(1.05); }
.demo__play svg { width: 30%; height: 34%; }
.demo__chip {
  position: absolute; left: 22px; bottom: 20px;
  display: flex; align-items: center; gap: 10px;
  background: rgba(14, 13, 12, .72); border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 999px; padding: 9px 16px; pointer-events: none; max-width: calc(100% - 44px);
}
.demo__chip b { font: 600 14px/1.3 var(--bd); color: #FFFFFF; }
.demo__chip span { font: 400 14px/1 var(--bd); color: var(--night-muted); flex: none; }
.demo__bar {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 20px 22px;
  background: linear-gradient(180deg, rgba(14, 13, 12, 0), rgba(14, 13, 12, .86));
  display: flex; align-items: center; gap: 16px;
}
.demo__bar[hidden] { display: none; }
.demo__toggle {
  width: 40px; height: 40px; border-radius: 999px; border: 0; flex: none;
  background: rgba(255, 255, 255, .94); color: var(--night-900);
  display: flex; align-items: center; justify-content: center;
}
.demo__toggle svg { width: 13px; height: 14px; }
.demo__track {
  flex: 1; height: 5px; border-radius: 999px; background: rgba(255, 255, 255, .24);
  overflow: hidden; border: 0; padding: 0; display: block; position: relative;
}
.demo__fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: var(--honey); border-radius: 999px; }
.demo__time { font: 500 14px/1 var(--bd); color: var(--night-100); flex: none; font-variant-numeric: tabular-nums; }

/* ---- Light sections shared ---------------------------------------------- */
.sec { padding: 100px 60px; border-top: 1px solid var(--ink-200); }
.sec--paper { background: var(--paper); }
.sec--white { background: var(--surface); }
.sec-head { display: flex; flex-direction: column; gap: 14px; align-items: center; text-align: center; margin-bottom: 64px; }
.kicker--light { color: var(--ink-kicker); }
h2.display {
  font: 800 clamp(28px, 3.4vw, 46px)/1.12 var(--hd); letter-spacing: -.02em; color: var(--ink-900);
  text-wrap: balance;
}

/* ---- Problem ------------------------------------------------------------ */
.problem { background: var(--paper); padding: 104px 60px; }
.problem p {
  max-width: 1020px; margin: 0 auto; text-align: center; text-wrap: pretty;
  font: 700 clamp(23px, 2.6vw, 36px)/1.42 var(--hd); letter-spacing: -.015em; color: var(--ink-900);
}

/* ---- Steps -------------------------------------------------------------- */
.steps__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.step {
  background: var(--paper); border: 1px solid var(--ink-200); border-radius: 18px;
  padding: 36px 32px 34px; display: flex; flex-direction: column; gap: 14px;
}
.step__num {
  font: 800 15px/1 var(--hd); color: var(--ink-kicker);
  background: var(--honey-50); border: 1px solid var(--honey-50-border);
  width: 44px; height: 44px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
}
.step h3 { margin-top: 6px; font: 700 27px/1.2 var(--hd); letter-spacing: -.01em; color: var(--ink-900); }
.step p { font: 400 18px/1.62 var(--bd); color: var(--ink-800); text-wrap: pretty; }

/* ---- Pillars ------------------------------------------------------------ */
.pillar { padding: 100px 60px; border-top: 1px solid var(--ink-200); }
.pillar:nth-child(odd) { background: var(--paper); }
.pillar:nth-child(even) { background: var(--surface); }
.pillar__grid {
  max-width: 1200px; margin: 0 auto;
  display: grid; grid-template-columns: 1fr 1fr; gap: 88px; align-items: center;
}
.pillar--flip .pillar__text { order: 2; }
.pillar__text { display: flex; flex-direction: column; gap: 18px; max-width: 540px; }
.pillar__text h3 {
  font: 800 clamp(28px, 2.9vw, 40px)/1.14 var(--hd); letter-spacing: -.02em;
  color: var(--ink-900); text-wrap: balance;
}
.pillar__text p { font: 400 19px/1.65 var(--bd); color: var(--ink-800); text-wrap: pretty; }
.pillar__media { display: flex; justify-content: center; }
.phone {
  position: relative; width: 332px; height: 676px; border-radius: 44px;
  background: var(--night-900); padding: 11px; box-shadow: 0 26px 60px rgba(42, 40, 38, .20);
}
.phone::before {
  content: ""; position: absolute; top: 11px; left: 50%; transform: translateX(-50%);
  width: 112px; height: 26px; border-radius: 0 0 16px 16px; background: var(--night-900); z-index: 5;
}
.phone__screen { position: relative; width: 100%; height: 100%; border-radius: 34px; overflow: hidden; background: var(--paper); }
.phone__screen img, .phone__screen video, .phone__screen iframe { width: 100%; height: 100%; object-fit: cover; object-position: top center; border: 0; display: block; }
.wide {
  position: relative; width: 100%; aspect-ratio: 16 / 9; border-radius: 18px; overflow: hidden;
  background: var(--night-800); box-shadow: 0 18px 44px rgba(42, 40, 38, .16);
}
.wide img, .wide video, .wide iframe { width: 100%; height: 100%; object-fit: cover; border: 0; display: block; }
.media-fallback {
  width: 100%; height: 100%; position: relative;
  background: var(--honey-50); border: 1px solid var(--honey-50-border);
  display: flex; align-items: center; justify-content: center;
}
.media-fallback::before {
  content: ""; position: absolute; inset: 0; opacity: .30;
  background-image: var(--hex); background-size: 56px 96px;
}
.media-fallback::after {
  content: ""; width: 64px; height: 72px; background: var(--brand-orange); opacity: .22;
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
}

/* ---- Tiles -------------------------------------------------------------- */
.tiles { background: var(--surface); padding: 96px 60px; border-top: 1px solid var(--ink-200); }
.tiles__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 24px; }
.tile {
  border: 1px solid var(--ink-200); border-radius: 18px; padding: 30px 26px;
  display: flex; flex-direction: column; gap: 12px; background: var(--surface);
  box-shadow: 0 8px 28px rgba(42, 40, 38, .05);
}
.tile h4 { margin-top: 4px; font: 700 20px/1.3 var(--hd); color: var(--ink-900); }
.tile p { font: 400 18px/1.6 var(--bd); color: var(--ink-800); }
.tile__icon {
  width: 46px; height: 52px; background: var(--honey-50); border: 1px solid var(--honey-50-border);
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
  display: flex; align-items: center; justify-content: center; gap: 3px; color: var(--ink-kicker);
}
.tile__icon svg { width: 22px; height: 22px; display: block; }

/* ---- Pricing ------------------------------------------------------------ */
.pricing { background: var(--paper); padding: 104px 60px; border-top: 1px solid var(--ink-200); }
.pricing .sec-head { margin-bottom: 56px; }
.pricing__sub { font: 400 19px/1.6 var(--bd); color: var(--ink-600); }
/* The column count is STATED, not inferred, because inferring it broke twice.
   First it was a hard `repeat(3, 1fr)` left behind when v1.10 retired Free,
   which left a card-shaped hole beside the two survivors. The auto-fit rule
   that replaced it then broke the other way the moment the catalog grew back
   to three tiers: `auto-fit` counts repetitions against a track's MAX sizing
   function when that max is a definite length, so `minmax(280px, 384px)` was
   planned in 384px units — 3x384 + 2x28 = 1208px inside a 1200px `.wrap`.
   Eight pixels short, so the browser made two tracks and the third tier
   dropped to its own row (measured on the live site: computed value was
   literally `384px 384px`).

   `:has()` counts the cards instead, which works for both the pre-rendered
   fallback below and whatever renderPlans() paints from the live catalog, so
   app.js needs to know nothing about layout. Up to 4 because that is where
   renderPlans slices.

   Do NOT add a two-column step for tablets: with three tiers that recreates
   exactly the orphaned-third-card look this rule exists to prevent. Three
   across, then straight to one at 1100px.

   `stretch` — not `start` — gives the cards a common height, which lets the
   `margin-top:auto` already on the CTA line the buttons up instead of
   floating one of them mid-card.

   The max-width caps go with the column counts: 1fr tracks have no ceiling of
   their own, and without these two tiers stretched to 586px each (the state
   the pre-rendered fallback below is in whenever the API is down). 796px is
   2x384 + one gap — the width the old rule produced — and 1200px fills .wrap,
   giving 381px at three tiers and 279px at four. */
/* ONE ROW, ALWAYS — and it scrolls sideways when the tiers do not fit.
   Never wraps to a second row, never squeezes the cards narrower to make them
   fit. (Product decision, 2026-09-07.) A wrapped pricing table reads as
   "3 plans, and an afterthought"; a squeezed one is unreadable at the exact
   moment someone is comparing numbers.

   Four things here are load-bearing and each one breaks something if dropped:

   1. `justify-content: safe center` — NOT plain `center`. When flex content
      overflows a scroll container, plain centring pushes the FIRST item's left
      edge to a negative offset that no browser lets you scroll back to: the
      cheapest tier becomes permanently unreachable. `safe` falls back to
      flex-start exactly when overflowing. A browser too old for the keyword
      drops the whole declaration and gets flex-start always — left-aligned
      when there is room, which is a cosmetic loss, not a trap.
   2. `padding-top` — `.price-card__badge` is absolutely positioned at
      `top: -15px`, i.e. it sticks OUT of the card. Setting overflow-x makes
      overflow-y compute to `auto`, so without room above, the "Most popular"
      badge is either clipped or drags a vertical scrollbar in beside it. The
      side padding does the same job for the featured card's 44px shadow.
   3. `min-width` on the card (below) — flex items shrink by default, so
      without it the cards would quietly narrow to fit instead of scrolling,
      which is the thing this layout exists to stop.
   4. A VISIBLE scrollbar. macOS hides overlay scrollbars until you scroll, so
      a strip that scrolls with no cue is a strip nobody scrolls. */
.pricing__grid {
  display: flex;
  /* The first pass tuned these numbers so four cards would fit inside
     `.wrap`'s 1200px — which meant 279px cards, and at 279 the longest
     feature line ("1000 voice inspections / month") and the longest button
     label ("Start with Enterprise") both wrapped to two lines. That is
     exactly the squeeze this layout was changed to stop; avoiding a scrollbar
     was never worth it. The card width below now comes from what the content
     needs, and the strip is allowed out of `.wrap` (see `.pricing .wrap`) so
     a wide monitor can still show all four without scrolling. */
  gap: 24px;
  align-items: stretch;
  justify-content: safe center;
  max-width: 1500px;
  margin: 0 auto;
  padding: 22px 6px 8px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  scrollbar-color: var(--ink-200) transparent;
}
.pricing__grid::-webkit-scrollbar { height: 8px; }
.pricing__grid::-webkit-scrollbar-track { background: transparent; }
.pricing__grid::-webkit-scrollbar-thumb {
  background: var(--ink-200); border-radius: 999px;
}
.pricing__grid::-webkit-scrollbar-thumb:hover { background: var(--ink-400, #B9B2AC); }

/* `.wrap` caps everything at 1200px, which for this one strip means a 1920
   monitor scrolls a catalogue it has ample room for. Lift the cap here and
   re-apply it to the two things that actually want it — the heading and the
   footnote — rather than reaching for a 100vw full-bleed trick, which counts
   the scrollbar and can push the whole page sideways. */
.pricing .wrap { max-width: none; }
.pricing .sec-head { max-width: 1200px; margin-left: auto; margin-right: auto; }
.price-card {
  /* 340, MEASURED: the longest feature line renders 253px wide at this font,
     plus a 16px bullet + gap and the card's own 64px of horizontal padding =
     333. 340 leaves a little air. The longest CTA ("Start with Enterprise")
     needs 281 and fits inside that.
     Fixed, not flexible: growing makes two tiers into billboards and
     shrinking is the thing this layout exists to prevent. */
  flex: 0 0 340px;
  scroll-snap-align: center;
  position: relative; background: var(--surface); border: 1px solid var(--ink-200);
  border-radius: 18px; padding: 38px 32px; display: flex; flex-direction: column; gap: 22px;
  box-shadow: 0 8px 28px rgba(42, 40, 38, .07);
}
.price-card--featured { border: 2px solid var(--honey); box-shadow: 0 16px 44px rgba(248, 144, 0, .18); }
.price-card__badge {
  position: absolute; top: -15px; left: 32px;
  font: 700 13px/1 var(--bd); letter-spacing: .1em; text-transform: uppercase;
  color: var(--btn-primary-text); background: var(--honey); border-radius: 999px; padding: 8px 14px;
}
.price-card__head { display: flex; flex-direction: column; gap: 8px; }
.price-card__tier {
  font: 700 15px/1 var(--bd); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-600);
}
.price-card--featured .price-card__tier { color: var(--ink-kicker); }
.price-card__price { display: flex; align-items: baseline; gap: 6px; }
.price-card__price b { font: 800 52px/1 var(--hd); letter-spacing: -.02em; color: var(--ink-900); }
.price-card__price span { font: 500 18px/1 var(--bd); color: var(--ink-600); }
.price-card__trial {
  align-self: flex-start; font: 600 14px/1 var(--bd); color: var(--ink-kicker);
  background: var(--honey-50); border: 1px solid var(--honey-50-border);
  border-radius: 999px; padding: 7px 12px;
}
.price-card__rule { height: 1px; background: var(--ink-200); }
.price-card ul { display: flex; flex-direction: column; gap: 12px; }
.price-card li { font: 400 18px/1.5 var(--bd); color: var(--ink-800); display: flex; gap: 10px; }
.price-card li::before { content: "·"; color: var(--ink-kicker); font-weight: 700; }
.price-card__cta {
  margin-top: auto; font: 700 17px/1 var(--bd); min-height: 52px; padding: 16px 24px;
  border-radius: 999px; display: flex; align-items: center; justify-content: center;
  color: var(--ink-900); background: var(--surface); border: 1px solid #C9C4BF;
  transition: filter .15s ease;
}
.price-card__cta:hover { filter: brightness(.96); }
.price-card__cta--solid {
  color: var(--btn-primary-text); background: var(--honey); border-color: transparent;
}
.pricing__footnote {
  margin: 34px auto 0; max-width: 860px; text-align: center;
  font: 400 18px/1.6 var(--bd); color: var(--ink-600);
}

/* ---- Get the app -------------------------------------------------------- */
/* Honey ground, between paper Pricing and white FAQ: it reads as a moment to
   act rather than a fourth content section in a row. */
.getapp {
  background: var(--honey-50); padding: 92px 60px;
  border-top: 1px solid var(--honey-50-border);
}
.getapp__grid {
  display: grid; grid-template-columns: minmax(0, 1fr) 500px;
  gap: 64px; align-items: center;
}
.getapp h2.display { margin-top: 14px; text-align: left; }
.getapp__body {
  font: 400 19px/1.6 var(--bd); color: var(--ink-800); margin-top: 16px; max-width: 46ch;
}
.getapp__btns { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 28px; }

/* Deliberately NOT the official App Store / Google Play badge lockups: that
   artwork is not in this repo, both companies publish strict rules for it, and
   a hand-drawn imitation is the thing they police. These are the site's own
   button — .btn's pill shape and transition — carrying only the platform glyph
   and its name. Swap in the real badges if and when the assets are obtained. */
.storebtn {
  background: var(--ink-900); color: #FFFFFF;
  padding: 14px 26px; font: 700 17px/1 var(--bd);
}
.storebtn:hover { filter: brightness(1.4); }
.storebtn svg { width: 20px; height: 20px; fill: currentColor; flex: none; }
/* .btn sets display:inline-flex, which beats the UA [hidden] rule — without
   this, the button for an unpublished store would still render. */
.storebtn[hidden] { display: none; }

.getapp__fine { font: 400 15px/1.5 var(--bd); color: var(--ink-600); margin-top: 20px; }

.getapp__codes {
  background: var(--surface); border: 1px solid var(--honey-50-border); border-radius: 20px;
  padding: 28px; display: grid; grid-template-columns: 1fr 1fr; gap: 22px;
  box-shadow: 0 14px 40px rgba(42, 40, 38, .09);
}
.codebox { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.codebox__lab { display: flex; align-items: center; gap: 7px; color: var(--ink-900); }
.codebox__lab svg { width: 16px; height: 16px; fill: currentColor; }
.codebox__lab b { font: 700 14px/1 var(--bd); }
/* White ground and the quiet zone in the SVG are not decoration — a phone
   camera reading a code off a screen needs both. */
.codebox__img { background: #FFFFFF; padding: 6px; border-radius: 8px; }
.codebox__img[hidden] { display: none; }
.codebox__img img { width: 150px; height: 150px; display: block; }
.codebox__soon {
  width: 162px; height: 162px; border: 1px dashed var(--ink-200); border-radius: 12px;
  display: grid; place-items: center;
  font: 500 14px/1 var(--bd); color: var(--ink-600);
}
.codebox__soon[hidden] { display: none; }
.codebox__hint { font: 400 13px/1.4 var(--bd); color: var(--ink-600); text-align: center; }
.getapp__scan {
  grid-column: 1 / -1; border-top: 1px solid var(--ink-200); padding-top: 14px;
  text-align: center; font: 400 14px/1.5 var(--bd); color: var(--ink-600);
}

/* A QR code is useless on the device you would install from. Ask about the
   INPUT, not the viewport: a tablet at 900px CAN install the app and a desktop
   window dragged narrow cannot, so a pixel breakpoint gets both cases wrong.
   The buttons work everywhere and stay. */
@media (pointer: coarse) {
  .getapp__codes { display: none; }
  .getapp__grid { grid-template-columns: minmax(0, 1fr); }
}

/* ---- Downloads ("Guides") ------------------------------------------------ */
/* Paper ground between the honey "Get the app" band and the white FAQ, so the
   page keeps alternating rather than running two coloured bands together. */
.guides {
  background: var(--paper); padding: 92px 60px;
  border-top: 1px solid var(--ink-200);
}
.guides__inner { max-width: 820px; }
.guides h2.display { margin-top: 14px; text-align: left; }
.guides__sub {
  font: 400 17px/1.6 var(--bd); color: var(--ink-600);
  margin-top: 14px; max-width: 62ch;
}
.guides__grid { display: flex; flex-direction: column; gap: 14px; margin-top: 32px; }

/* The whole row is the link, not a small "Download" word at the end: this
   gets tapped by someone in gloves, and a 64px-tall target beats a 60px-wide
   one. `.guide__cta` is a label, not a second control. */
.guide {
  display: flex; align-items: center; gap: 18px;
  padding: 20px 22px; text-decoration: none;
  background: var(--surface); border: 1px solid var(--ink-200);
  border-radius: 14px; color: inherit;
  transition: border-color .15s ease, transform .15s ease;
}
.guide:hover { border-color: var(--honey-300); transform: translateY(-1px); }
.guide__icon {
  flex: 0 0 auto; width: 42px; height: 42px; border-radius: 10px;
  background: var(--honey-50); display: grid; place-items: center;
}
.guide__icon svg { width: 22px; height: 22px; fill: var(--honey-700); }
.guide__text { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 auto; }
.guide__title { font: 700 17px/1.3 var(--bd); color: var(--ink-900); }
.guide__desc { font: 400 15px/1.45 var(--bd); color: var(--ink-600); }
.guide__desc:empty { display: none; }
.guide__meta { font: 400 13px/1.4 var(--bd); color: var(--ink-600); }
.guide__cta {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 8px;
  font: 700 15px/1 var(--bd); color: var(--honey-700);
  padding: 12px 18px; border: 1px solid var(--honey-50-border);
  border-radius: 999px; background: var(--honey-50);
}
.guide__cta svg { width: 16px; height: 16px; fill: currentColor; }

/* ---- FAQ ---------------------------------------------------------------- */
.faq { background: var(--surface); padding: 104px 60px; border-top: 1px solid var(--ink-200); }
.faq__inner { max-width: 720px; margin: 0 auto; }
.faq__inner h2 { text-align: center; margin-bottom: 40px; }
.faq__list { display: flex; flex-direction: column; border-top: 1px solid var(--ink-200); }
.faq-item { border-bottom: 1px solid var(--ink-200); }
.faq-item__q {
  width: 100%; background: transparent; border: 0; padding: 24px 0;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  text-align: left; min-height: 56px;
}
.faq-item__q span { font: 700 21px/1.4 var(--hd); color: var(--ink-900); }
.faq-item__icon {
  flex: none; width: 32px; height: 32px; border-radius: 999px;
  background: #F1EDEA; color: var(--ink-600);
  font: 700 18px/1 var(--bd);
  display: flex; align-items: center; justify-content: center;
}
.faq-item__icon::before { content: "+"; }
.faq-item__q[aria-expanded="true"] .faq-item__icon { background: var(--honey-50); color: var(--ink-kicker); }
.faq-item__q[aria-expanded="true"] .faq-item__icon::before { content: "\2212"; }
.faq-item__a { padding: 0 56px 26px 0; font: 400 18px/1.65 var(--bd); color: var(--ink-800); }
.faq-item__a[hidden] { display: none; }

/* ---- Final CTA ---------------------------------------------------------- */
.final { position: relative; background: var(--night-900); padding: 110px 60px; overflow: hidden; }
.final::before {
  content: ""; position: absolute; inset: 0; opacity: .05;
  background-image: var(--hex); background-size: 56px 96px;
}
.final__mark {
  position: absolute; right: -70px; top: 50%; transform: translateY(-50%);
  width: 420px; height: 420px; opacity: .07;
}
.final__inner {
  position: relative; max-width: 940px; margin: 0 auto; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 20px;
}
.final h2 {
  font: 800 clamp(30px, 3.5vw, 50px)/1.14 var(--hd); letter-spacing: -.02em;
  color: #FFFFFF; text-wrap: balance;
}
.final__sub { font: 400 clamp(17px, 1.5vw, 20px)/1.6 var(--bd); color: var(--night-100); }
.final .btn--hero { margin-top: 10px; padding: 19px 36px; }
.final__contact { font: 500 17px/1.5 var(--bd); color: var(--brand-orange); }
.final__contact:hover { color: var(--honey-300); }

/* ---- Footer ------------------------------------------------------------- */
.footer { background: var(--night-800); padding: 72px 60px 40px; border-top: 1px solid rgba(255, 255, 255, .08); }
.footer__grid {
  max-width: 1200px; margin: 0 auto;
  display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 48px;
}
.footer__brand { display: flex; flex-direction: column; gap: 14px; }
/* `:not(.lockup__mark--custom)` 不是装饰 —— 没有它，这一条会**赢**，
   把管理员上传的宽版 logo（通常 380x80）压进 34x34 的方框，在页脚变成一条
   辨认不出的碎屑。页头是对的，因为页头没有这样一条。

   两条特异性都是 (0,2,1)，这一条写在后面所以胜出（styles.css:158 是 custom
   规则，它上面的注释白纸黑字写着 "Never squash it into the 34x34 box." ——
   注释说的是对的，代码没做到）。

   为什么不直接删掉这一条（它的声明和 :153 的 `.lockup img` 一字不差）：
   它的特异性同时压过了移动端媒体查询里那条 `.lockup img { …30px }`，删掉会顺带
   把页脚的**内置**标在手机上从 34px 改成 30px —— 那是另一件事，不该搭车。
   加 :not() 只排除 custom 那一种，内置标的行为一个像素都不变。 */
.footer__brand .lockup img:not(.lockup__mark--custom) { width: 34px; height: 34px; }
.footer__tagline { font: 400 16px/1.6 var(--bd); color: var(--night-100); }
.footer__copy { font: 400 15px/1.6 var(--bd); color: var(--night-muted); }
.footer__badges { display: flex; gap: 12px; margin-top: 6px; flex-wrap: wrap; }
.footer__badges[hidden] { display: none; }
.footer__badges a {
  width: 150px; height: 50px; border: 1px solid rgba(255, 255, 255, .22); border-radius: 999px;
  display: flex; align-items: center; justify-content: center; gap: 9px;
  font: 600 14px/1 var(--bd); color: var(--night-100);
  transition: border-color .15s ease, background .15s ease;
}
.footer__badges a:hover { border-color: rgba(255, 255, 255, .45); background: rgba(255, 255, 255, .05); }
.footer__badges svg { width: 17px; height: 17px; fill: currentColor; flex: none; }
/* display:flex above beats the UA [hidden] rule — without this, a badge with
   no configured URL would still render (and keep its placeholder href). */
.footer__badges a[hidden] { display: none; }
.footer__badges a:hover { border-color: rgba(255, 255, 255, .5); color: #FFFFFF; }
.footer__col { display: flex; flex-direction: column; gap: 14px; }
.footer__col h4 {
  font: 700 13px/1 var(--bd); letter-spacing: .14em; text-transform: uppercase; color: var(--night-muted);
}
.footer__col a { font: 400 16px/1.3 var(--bd); color: var(--night-100); }
.footer__col a:hover { color: #FFFFFF; }

/* ---- Responsive --------------------------------------------------------- */
/* The pricing strip is the widest thing on the page, and the section's 60px
   side padding is what decides whether the current four tiers fit or clip.
   At 1280 (a very common laptop) they missed by 12px — not "they don't fit",
   just "off by a sliver", which reads as a rendering bug rather than as an
   invitation to scroll. Giving the strip back 64px of room moves the honest
   scroll threshold below ~1216, where four cards genuinely stop fitting.
   Only the padding changes; the centred heading above it does not move. */
@media (max-width: 1400px) {
  .pricing { padding-left: 28px; padding-right: 28px; }
}

@media (max-width: 1100px) {
  .pillar__grid { gap: 48px; }
  /* Nothing to restate here any more: the strip is one flex row at every
     width and scrolls sideways when the tiers do not fit. What used to live
     here was `grid-template-columns: 1fr` — a vertical stack below 1100px —
     plus `.price-card--featured { order: -1 }` to drag Pro to the top of it.
     Both are gone: stacking IS the thing this layout was changed to stop, and
     reordering by "featured" breaks the price ladder people read left to
     right. */
  /* Below this the copy column would be ~416px beside a 500px code card, so
     stack instead and let the codes sit under the text. */
  .getapp__grid { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .getapp__codes { max-width: 500px; }
}

@media (max-width: 860px) {
  section { scroll-margin-top: 76px; }
  .guides { padding: 64px 20px; }
  /* Below ~430px a pill on the right leaves the title ~150px and it wraps to
     four lines. The row is the link either way, so drop the label rather than
     shrink the thing people read. */
  .guide { gap: 12px; padding: 16px; }
  /* Below 860px — the same breakpoint the rest of the page goes to its phone
     layout at, not a separate one for this row. Drop the WORD, never the
     affordance: the row is the link either way, but a card with nothing that
     looks tappable is a card nobody taps. The arrow stays, as a round icon on
     the right. (The comment here used to say "~430px", which was the width
     the arithmetic was done at and not the width the rule fires at — Codex,
     2026-09-07.) */
  .guide__cta { padding: 11px; gap: 0; }
  .guide__cta b { display: none; }
  .guide__cta svg { width: 18px; height: 18px; }
  .nav__row { height: 64px; padding: 0 16px; }
  .nav__links { display: none; }
  .nav__burger { display: flex; }
  .nav .btn--primary { display: none; }         /* hero CTAs never ride the header */
  /* One action fits beside the burger on a phone, and Sign up wins it: a
     returning user already knows where the menu is, a first-time visitor is
     the one who needs an obvious next step. Both are still in the menu. */
  .nav__actions .btn--ghost-dark { display: none; }
  .nav .btn--primary.btn--nav { display: inline-flex; padding: 10px 16px; min-height: 40px; }
  .lockup img { width: 30px; height: 30px; }
  /* D-16：手机上这个上限**必须跟着视口走**，写死 150px 会把页头撑破。
     2026-09-09 在真浏览器上量到（用 data: URI 就地复刻 applyLogo，
     并先断言图真的渲染出来了：naturalWidth=380、盒宽 143）：
         390px → 横向溢出 32px · 360px → 62px · 320px → 102px
     而不传自定义 logo 时三个宽度都不溢出。被挤出视口的是 `.nav__actions`
     —— 也就是 **Sign up 按钮和汉堡菜单**，用户既看不见也点不到。

     算法：页头里除 mark 之外的部分固定占 279px（字标 + 间距 + 那两个控件），
     所以能给 mark 的宽度是 `100vw - 279px`。留 6px 余量取 285，
     于是 320 → 35px · 360 → 75px · 390 → 105px，都在实测需要的
     ≤41 / ≤81 / ≤111 之内；视口够宽时仍然封顶 150px（min() 取小的那个）。
     用 min() 而不是再加一层媒体查询，是因为断点在哪取决于**字标的实际宽度**，
     那是字体决定的，写死断点会在换字体那天悄悄失效。 */
  .lockup img.lockup__mark--custom {
    width: auto; height: 30px; max-width: min(150px, calc(100vw - 285px));
  }
  .lockup span { font-size: 17px; }
  .btn--ghost-dark { font-size: 15px; padding: 12px 16px; min-height: 44px; }

  .hero { padding: 44px 20px 0; }
  .hero__inner { text-align: left; align-items: flex-start; gap: 18px; }
  .hero h1 { line-height: 1.08; }
  .hero__ctas { flex-direction: column; align-items: stretch; width: 100%; gap: 10px; }
  .hero__ctas .btn { width: 100%; min-height: 52px; font-size: 17px; padding: 17px 24px; }
  .hero__micro { font-size: 14px; }
  .demo { margin-top: 24px; padding-bottom: 40px; }
  .demo__glow { border-radius: 16px; padding: 6px; }
  .demo__frame { border-radius: 11px; }
  .demo__chip { left: 12px; bottom: 10px; padding: 7px 12px; }
  .demo__chip b { font-size: 12px; }
  .demo__chip span { font-size: 12px; }
  .demo__bar { padding: 12px 14px; gap: 10px; }

  .sec, .pillar, .tiles, .pricing, .faq, .problem, .getapp { padding: 44px 20px; }
  .getapp h2.display { font-size: 28px; }
  .getapp__body { font-size: 16px; }
  .getapp__btns { margin-top: 22px; }
  .storebtn { width: 100%; }
  .sec-head { margin-bottom: 28px; align-items: flex-start; text-align: left; }
  .steps__grid { grid-template-columns: 1fr; gap: 14px; }
  .step { padding: 22px; gap: 10px; }
  .step__num { width: 38px; height: 38px; font-size: 13px; }
  .step h3 { font-size: 22px; margin-top: 0; }
  .step p { font-size: 16px; }

  .pillar__grid { grid-template-columns: 1fr; gap: 14px; }
  .pillar--flip .pillar__text { order: 0; }
  .pillar__text { max-width: none; gap: 14px; }
  .pillar__text p { font-size: 17px; line-height: 1.62; }
  .pillar__media { margin-top: 4px; }
  .phone {
    width: 100%; height: auto; aspect-ratio: 3 / 4; border-radius: 18px;
    background: var(--surface); padding: 0; border: 1px solid var(--ink-200);
    box-shadow: none;
  }
  .phone::before { display: none; }
  .phone__screen { border-radius: 18px; }

  .tiles__grid { grid-template-columns: 1fr; gap: 14px; }
  .tile { padding: 22px; gap: 10px; }
  .tile h4 { font-size: 19px; margin-top: 0; }
  .tile p { font-size: 16px; }
  .tile__icon { width: 40px; height: 45px; }

  .pricing .sec-head { margin-bottom: 20px; }
  .pricing__sub { font-size: 16px; }
  /* Narrower cards on a phone, but never narrower than one comfortably
     readable card — the strip scrolls instead. 300px leaves ~1.3 cards
     visible at 390px, which is what tells a thumb there is more to the
     right without any extra chrome. */
  .pricing__grid { gap: 16px; padding: 22px 4px 8px; }
  /* 300 on a phone, not 340: at 390px a 340 card leaves no room for the next
     one to peek, and that peek is the only thing telling a thumb there is
     more to the right. A long feature line wrapping on a phone is normal;
     a strip that looks like it ends at card one is not. */
  .price-card { flex: 0 0 300px; }
  .price-card { padding: 24px; gap: 16px; }
  .price-card__price b { font-size: 40px; }
  .price-card li { font-size: 16px; }
  .price-card ul { gap: 9px; }
  .price-card__cta { font-size: 16px; min-height: 48px; padding: 15px 20px; }
  .pricing__footnote { margin-top: 20px; font-size: 15px; text-align: left; }

  .faq__inner h2 { text-align: left; margin-bottom: 22px; }
  .faq-item__q { padding: 18px 0; min-height: 44px; gap: 16px; }
  .faq-item__q span { font-size: 18px; }
  .faq-item__icon { width: 30px; height: 30px; font-size: 17px; }
  .faq-item__a { font-size: 16px; padding: 0 40px 18px 0; }

  .final { padding: 52px 20px; }
  .final__inner { text-align: left; align-items: flex-start; gap: 16px; }
  .final__mark { right: -60px; top: auto; bottom: -40px; transform: none; width: 240px; height: 240px; }
  .final .btn--hero { width: 100%; }

  .footer { padding: 36px 20px 30px; }
  .footer__grid { grid-template-columns: 1fr 1fr; gap: 24px; }
  .footer__brand { grid-column: 1 / -1; gap: 10px; }
  .footer__col a { font-size: 15px; }
  .footer__col h4 { font-size: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; animation: none !important; }
}
