/* Pegasus Cool — native stylesheet.
 *
 * EDITING THIS FILE: rename it to assets/styles-<md5[:8]>.css afterwards and
 * update every page's <link>. The fingerprint must live in the PATH — the
 * Cloudflare zone ignores query strings when caching, so ?v= busting does
 * nothing, and its browser-TTL floor rewrites small max-ages. A fresh path
 * sidesteps both and inherits the /assets/* immutable rule.
 *
 * Every value here was measured off the original Framer pages (see
 * design-spec/*.json), so the rebuild matches the published design rather than
 * approximating it. Nothing loads from a third-party origin.
 */

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

:root {
  --page: #fdfdfc;          /* home */
  --page-doc: #ffffff;      /* policy + product pages */
  --surface: #f5f5f5;
  --line: #dedede;
  --ink: #161616;           /* home */
  --ink-doc: #171717;       /* documents */
  --muted: #6b6e73;          /* 5.0:1 on the doc page; the measured #7d7f83 was 3.9:1 */
  --subtle: rgba(64, 64, 64, 0.75);  /* composites to 4.95:1; 0.6 was 3.35:1 */
  --accent: #ff9601;

  /* Derived surfaces. These were literals until the dark scheme needed them
     to move; the light values are unchanged from the measurements. */
  --ink-invert: #ffffff;    /* text sitting on an --ink fill */
  --surface-hover: #efefef;
  --line-strong: #d2d2d2;
  --wash: rgba(22, 22, 22, 0.04);      /* hover tint on a transparent control */
  --wash-strong: rgba(22, 22, 22, 0.06);
  --glass: rgba(255, 255, 255, 0.86);  /* the floating language pill */
  --glass-saturate: 1.6;
  --glass-shadow: 0 1px 2px rgba(22, 22, 22, 0.06), 0 8px 24px rgba(22, 22, 22, 0.08);
  --field: rgba(163, 163, 163, 0.12);  /* form input wash */
  --blue: #0071e3;                     /* submit button */
  --focus: #2f80ed;
  --error-fill: rgba(255, 108, 71, 0.08);
  --error-line: rgba(255, 108, 71, 0.35);
  /* PegasusOCR's hero wash. A whole gradient rather than a colour, because
     dark needs different stops, not the same stops in a different colour. */
  --mark-wash: radial-gradient(closest-side,
      rgba(242, 205, 231, 0.92) 0%,
      rgba(240, 224, 248, 0.68) 46%,
      rgba(244, 240, 254, 0.32) 70%,
      transparent 100%);
  --mark-shadow: 0 18px 40px rgba(94, 49, 245, 0.28);

  /* Follows the reader's system appearance. Also tells the browser to paint
     its own furniture — scrollbars, the caret, form controls, the canvas
     before the stylesheet lands — in the matching scheme. */
  color-scheme: light dark;

  --radius: 12px;         /* was 6 — the whole site moves to rounder corners */
  --radius-lg: 12px;      /* was 8 */
  --radius-icon: 14px;    /* was 10 */

  --sans: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  /* Han glyphs fall back to the reader's system font, exactly as they did on
     Framer — no CJK webfont is shipped. */
  --han: "PingFang TC", "PingFang SC", "Hiragino Sans CNS", "Microsoft JhengHei",
         "Noto Sans CJK TC", "Source Han Sans TC", sans-serif;
  --font: var(--sans), var(--han);
}

/* ------------------------------------------------------------ dark scheme
 *
 * These are the studio's own dark values, not new ones. The Framer project
 * carried a seven-token dark set — recoverable from the mirror in git — which
 * was declared across the whole project and applied on none of the pages that
 * shipped. Every light value in it matches a token here exactly, because the
 * light tokens were measured off that same design:
 *
 *   #fdfdfc -> #161616    #ffffff -> #2b2b2b    #f5f5f5 -> #1c1c1c
 *   #dedede -> #282828    #dbdbdb -> #3d3d3d    #161616 -> #ffffff
 *   #7d7f83 -> #7c7f82
 *
 * Two departures, both forced:
 *
 *  - --page-doc collapses onto --page rather than taking #2b2b2b. In light the
 *    document pages are a hair *brighter* than home (#ffffff vs #fdfdfc, 1.01:1)
 *    and nothing rests on it; transposing that gap into dark makes it 1.28:1,
 *    and worse, it puts the card surface *below* the page it sits on, so every
 *    card on a document page reads as a hole. #2b2b2b is not discarded — it is
 *    the hover step, which is exactly its relationship to #1c1c1c.
 *  - --muted lands on #818487 rather than #7c7f82. The original is 4.49:1 on
 *    this page, which misses AA by a hundredth; five shades up clears it on the
 *    card surface too. It is still the design's grey.
 *
 * `screen and` is load-bearing: prefers-color-scheme still matches while
 * printing, so an unscoped block would put white text on the white paper that
 * @media print forces — on the three legal documents, of all pages.
 */

@media screen and (prefers-color-scheme: dark) {
  :root {
    --page: #161616;
    --page-doc: #161616;
    --surface: #1c1c1c;
    --line: #282828;
    --ink: #ffffff;
    --ink-doc: #ffffff;
    --muted: #818487;
    --subtle: rgba(235, 235, 245, 0.6);
    --accent: #ff9f0a;        /* the same orange, at Apple's dark-mode value */

    --ink-invert: #161616;
    --surface-hover: #2b2b2b;
    --line-strong: #3d3d3d;
    /* Hover tints invert with everything else: light lays ink over the page,
       dark lays light over it. Both land one step off the surface. */
    --wash: rgba(255, 255, 255, 0.06);
    --wash-strong: rgba(255, 255, 255, 0.09);
    /* A raised material sits *above* its canvas here, where in light it sat
       below one. The hairline carries the edge in both, because an ambient
       shadow that reads on white is invisible on near-black. */
    --glass: rgba(28, 28, 30, 0.86);
    --glass-saturate: 1.2;
    --glass-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 8px 24px rgba(0, 0, 0, 0.45);
    --field: rgba(235, 235, 245, 0.09);
    --blue: #0071e3;          /* unchanged: 4.70:1 label, 3.85:1 against this page */
    --focus: #4c9aff;
    --error-fill: rgba(255, 108, 71, 0.14);
    --error-line: rgba(255, 108, 71, 0.45);
    /* The wash should glow out of the canvas rather than sit on it, so the
       near-white stops become the icon's own violet. */
    --mark-wash: radial-gradient(closest-side,
        rgba(122, 74, 255, 0.34) 0%,
        rgba(94, 49, 245, 0.20) 46%,
        rgba(94, 49, 245, 0.08) 70%,
        transparent 100%);
    --mark-shadow: 0 18px 40px rgba(94, 49, 245, 0.42);
  }
}

/* ------------------------------------------------------------ typefaces */

@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/inter-400.woff2") format("woff2");
  unicode-range: U+0-FF, U+131, U+152-153, U+2BB-2BC, U+2C6, U+2DA, U+2DC,
                 U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
                 U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/inter-600.woff2") format("woff2");
  unicode-range: U+0-FF, U+131, U+152-153, U+2BB-2BC, U+2C6, U+2DA, U+2DC,
                 U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
                 U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Inter;
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/fonts/inter-700.woff2") format("woff2");
  unicode-range: U+0-FF, U+131, U+152-153, U+2BB-2BC, U+2C6, U+2DA, U+2DC,
                 U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
                 U+2215, U+FEFF, U+FFFD;
}
/* Subset to the ten glyphs in "Pegasus Cool" — the logotype is its only use. */
@font-face {
  font-family: "Cubic 11";
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/assets/fonts/cubic11-logotype.woff") format("woff");
}

/* ---------------------------------------------------------------- reset */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--page-doc);
  color: var(--ink-doc);
  font-family: var(--font);
  font-size: 16px;
  line-height: 24px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img { display: block; max-width: 100%; }
a { color: inherit; }

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

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

/* The skip link is the only focusable .visually-hidden element. Focused, it
   must actually appear (WCAG 2.4.7) — restore a box instead of the 1px clip. */
a.visually-hidden:focus-visible {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 60;
  width: auto;
  height: auto;
  margin: 0;
  padding: 10px 16px;
  overflow: visible;
  clip-path: none;
  background: var(--surface);
  color: var(--ink);
  border-radius: var(--radius);
  box-shadow: inset 0 0 0 1px var(--line), var(--glass-shadow);
}

/* --------------------------------------------------------- home: canvas */

.page-home { background: var(--page); color: var(--ink); }

/* Graph-paper wash across the top of the home page: 10px minor grid, 50px
   major grid, faded out downward so the app list sits on flat colour. */
.hero-grid {
  position: absolute;
  inset: 0 0 auto;
  height: 675px;
  pointer-events: none;
  background-image:
    linear-gradient(var(--surface) 2px, transparent 2px),
    linear-gradient(90deg, var(--surface) 2px, transparent 2px),
    linear-gradient(var(--surface) 1px, transparent 1px),
    linear-gradient(90deg, var(--surface) 1px, var(--page) 1px);
  background-size: 50px 50px, 50px 50px, 10px 10px, 10px 10px;
  background-position: -2px -2px, -2px -2px, -1px -1px, -1px -1px;
}
.hero-grid::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, var(--page) 0%, rgba(22, 22, 22, 0) 100%);
}

/* --------------------------------------------------------- home: layout */

.wrap {
  position: relative;
  max-width: 640px;
  margin: 0 auto;
  padding: 0 36px;
}

.home {
  display: flex;
  flex-direction: column;
  gap: 64px;
  padding-top: 100px;
  padding-bottom: 160px;
}

.home-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  padding: 0 12px;
}

.home-intro {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 400px;
}

.logotype {
  margin: 0;
  font-family: "Cubic 11", var(--font);
  font-size: 36px;
  font-weight: 400;
  line-height: 44px;
  letter-spacing: -0.4px;
  text-align: center;
  color: var(--ink);
}

.home-lede {
  margin: 0;
  font-size: 16px;
  line-height: 24px;
  text-align: center;
  color: var(--ink);
}

.home-actions {
  display: flex;
  gap: 16px;
}

/* --------------------------------------------------------- home: buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 40px;
  padding: 0 24px;
  border: 0;
  border-radius: var(--radius);
  /* Framer paints this hairline on an ::after overlay, so it adds no layout
     width. An inset shadow matches that without shifting the content box. */
  box-shadow: inset 0 0 0 1px var(--line);
  background: var(--surface);
  color: var(--ink);
  font: 600 14px/16px var(--font);
  letter-spacing: -0.2px;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.15s ease, box-shadow 0.15s ease;
}
.btn:hover { background: var(--surface-hover); box-shadow: inset 0 0 0 1px var(--line-strong); }

.btn--ghost {
  position: relative;
  background: transparent;
  /* Framer hangs the icon outside the button and reserves 40px of left
     padding for it, so the label centres in the remaining box. The 112px is
     fixed in the original too — it is identical on the English page, where
     the neighbouring button is half again as wide. */
  width: 112px;
  padding: 0 20px 0 40px;
  gap: 0;
}
.btn--ghost:hover { background: var(--wash); }

.btn__icon {
  position: absolute;
  left: 19px;
  top: 50%;
  transform: translateY(-50%);
  width: 20px;
  height: 20px;
}

/* Confirmation state after the address is copied. */
.btn[data-copied="true"] { box-shadow: inset 0 0 0 1px var(--ink); }

/* ---------------------------------------------------------- home: ticker */

.app-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.ticker {
  height: 80px;
  padding: 16px;
  border-radius: var(--radius);
  box-shadow: inset 0 0 0 1px var(--line);
  background: var(--surface);
  overflow: hidden;
}

.ticker__viewport {
  height: 48px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 10%, #000 90%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0%, #000 10%, #000 90%, transparent 100%);
}

/* Two identical runs scroll as one track; translating by exactly one run's
   width makes the loop seamless. `--run` is set from the item count so the
   maths stays in one place. */
.ticker__track {
  display: flex;
  width: max-content;
  gap: 24px;
  animation: ticker-scroll 40s linear infinite;
}
.ticker__run {
  display: flex;
  gap: 24px;
  flex: none;
}
.ticker__item {
  display: block;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-icon);
  overflow: hidden;
  flex: none;
}
.ticker__item img { width: 48px; height: 48px; object-fit: cover; }

@keyframes ticker-scroll {
  from { transform: translateX(0); }
  /* One run plus the gap that follows it. */
  to { transform: translateX(calc(-1 * var(--run-width))); }
}

@media (prefers-reduced-motion: reduce) {
  .ticker__track { animation: none; }
}

/* ----------------------------------------------------------- home: cards */

.app-card {
  display: flex;
  align-items: center;
  gap: 24px;
  /* Not a fixed height: on the English page the first tagline wraps to two
     lines and the card grows to 98.5px, exactly as in the original. */
  min-height: 96px;
  padding: 16px 32px 16px 16px;
  border-radius: var(--radius);
  box-shadow: inset 0 0 0 1px var(--line);
  background: var(--surface);
}

.app-card__icon {
  flex: none;
  width: 64px;
  height: 64px;
  border-radius: var(--radius);
}

.app-card__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}

.app-card__name {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  line-height: 22.5px;
  letter-spacing: -0.4px;
  color: var(--ink);
}

.app-card__tagline {
  margin: 0;
  font-size: 14px;
  line-height: 21px;
  color: var(--muted);
}

.app-card__action {
  flex: none;
  min-width: 104px;
}
.app-card__action .app-card__arrow { display: none; }

/* ---------------------------------------------------------- home: footer */

.site-footer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  font-size: 14px;
  line-height: 24px;
}

.site-footer__copy { margin: 0; color: var(--muted); }

.site-footer__link {
  color: var(--ink);
  line-height: 20px;
  text-decoration: none;
}
.site-footer__link:hover { text-decoration: underline; }

/* ------------------------------------------------------- document pages */

/* 852px of text plus the 24px gutters the original leaves at 1280. */
.doc {
  max-width: 900px;
  margin: 0 auto;
  padding: 96px 24px 96px;
  color: var(--ink-doc);
}

/* Base body rule first; the date and lede modifiers below deliberately carry
   equal-or-higher specificity so they win regardless of source order. */
.doc p {
  margin: 24px 0 0;
  font-size: 16px;
  line-height: 24px;
}

/* Framer set these as one text block per section, so a section heading sits
   8px above its body and 32px below the previous one. */
.doc h2 + p,
.doc h2 + ul { margin-top: 8px; }

.doc h2 {
  margin: 32px 0 0;
  font-size: 26px;
  font-weight: 600;
  line-height: 34px;
  letter-spacing: -0.2px;
}

p.doc__date {
  margin: 0;
  font-size: 14px;
  line-height: 20px;
  color: var(--subtle);
}

.doc h1 {
  margin: 16px 0 0;
  font-size: 42px;
  font-weight: 600;
  line-height: 50px;
  letter-spacing: -0.2px;
}

p.doc__lede {
  margin-top: 12px;
  font-size: 17px;
  line-height: 26px;
}
p.doc__lede + h2 { margin-top: 24px; }

/* A standalone closing note, set off from the last section. Only the first
   paragraph carries the wider offset; the rest read as one block. */
p.doc__closing { margin-top: 40px; }
p.doc__closing + p.doc__closing { margin-top: 24px; }

/* Framer rendered these as plain line-broken text. Keeping them as a list is
   better for screen readers; the markers are suppressed so the page looks
   identical to the original. */
.doc__list {
  margin: 24px 0 0;
  padding: 0;
  list-style: none;
}
/* The privacy policy's data table. Tokens carry the dark scheme; the wrapper
   scrolls horizontally on a phone so the document itself never widens. */
.doc__tablewrap { margin: 16px 0 0; overflow-x: auto; }
.doc table {
  width: 100%;
  min-width: 760px;
  border-collapse: collapse;
  font-size: 14px;
  line-height: 20px;
}
.doc th,
.doc td {
  padding: 10px 12px;
  border: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}
.doc th { background: var(--surface); font-weight: 600; white-space: nowrap; }

/* Bare URLs are printed as their own link text in the legal copy; at 320px the
   longest of them is wider than the column, and an unbreakable word widens the
   document itself. break-word splits only when a word cannot fit alone. */
.doc { overflow-wrap: break-word; }

.doc__list li {
  margin: 0;
  font-size: 16px;
  line-height: 24px;
}

.doc a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

/* --------------------------------------------------------- product page */

.product {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  max-width: 1280px;
  margin: 0 auto;
  /* Bottom padding clears the floating language pill (36px tall, 24px inset),
     so it can never sit over the footer links when scrolled to the end. */
  padding: 0 72px 72px;
}

.product-head {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  height: 48px;
  padding: 34px 0;
  box-sizing: content-box;
}
.product-head__icon { width: 40px; height: 40px; border-radius: 9px; }
.product-head__name {
  margin: 0;
  font-size: 21px;
  font-weight: 700;
  line-height: 26px;
  color: var(--ink-doc);
}

.product-hero {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: 48px;
  flex: 1 1 auto;
  padding: 48px 0;
}

/* The screenshot is a transparent PNG of two floating panels, so on bare white
   it reads as an unplaced asset rather than part of the layout. Setting it on
   the same card surface the home page uses grounds it and fills the column. */
.product-hero__media {
  padding: 32px 28px;
  border-radius: 16px;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line);
}

.product-hero__media img {
  width: 100%;
  height: auto;
}

/* The PickC hero is an opaque recording that fills its own frame, so it wants
   no card behind it — the surface exists only to ground a transparent still. */
.product-hero__media--video {
  padding: 0;
  background: none;
  box-shadow: none;
}

.product-hero__video {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 20px;
  background: var(--surface);
}

/* The videos are paused by script, not here — `animation: none` never applied
   to a playing <video>, and the poster fallback this block claimed was never
   happening. See the reduced-motion handler in tools/build-site.mjs. */

.product-hero__body { max-width: 544px; }

.product-hero__body h1 {
  margin: 0;
  font-size: 42px;
  font-weight: 600;
  line-height: 50px;
  letter-spacing: -0.2px;
  color: var(--ink-doc);
}

/* Only the unclassed pitch paragraphs. Matching every <p> here made this rule
   (0,1,1) outrank the single-class rules for .product-badge and .product-note,
   which then rendered as hero body copy — 17px where they declare 12 and 14.
   Every other paragraph inside the hero carries a class and owns its size. */
.product-hero__body > p:not([class]) {
  margin: 12px 0 0;
  font-size: 17px;
  line-height: 26px;
  color: var(--ink-doc);
}

/* A short qualifier above the heading, e.g. "Best". */
.product-badge {
  display: inline-block;
  margin: 0 0 14px;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: 12px;
  font-weight: 600;
  line-height: 16px;
  color: var(--ink-doc);
}

/* Status note for an archived product.
 *
 * Deliberately quiet. As a filled panel with an accent rule it was the loudest
 * thing on the page — louder than the headline, and its orange competed with
 * the download button for the same attention. The page should have one focal
 * point; here the only colour is the 7px dot. */
.product-notice { margin: 0 0 20px; }

.product-notice__label {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 600;
  line-height: 18px;
  color: var(--ink-doc);
}
.product-notice__label::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
}
/* Must not inherit the hero's 18px body sizing. */
.product-hero__body .product-notice__text {
  margin: 6px 0 0;
  font-size: 14px;
  line-height: 21px;
  color: var(--muted);
}

.btn-cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 32px;
  padding: 12px 20px;
  border-radius: var(--radius-lg);
  /* Each product page sets --cta to its own app accent; Pegasus Calendar
     inherits the site orange, PickC uses near-black as it always did. */
  background: var(--cta, var(--accent));
  color: var(--cta-ink, #fff);
  font-size: 17px;
  font-weight: 600;
  line-height: 26px;
  text-decoration: none;
  transition: filter 0.15s ease;
}
.btn-cta:hover { filter: brightness(0.95); }
.btn-cta svg { width: 20px; height: 20px; }

.product-note {
  max-width: 408px;
  font-size: 14px;
  line-height: 20px;
  color: var(--subtle);
}
.product-hero__body .product-note { margin-top: 20px; }

.product-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-top: 24px;
  font-size: 14px;
  line-height: 20px;
}
.product-footer__copy { margin: 0; color: var(--subtle); }
.product-footer__links { display: flex; gap: 24px; }
.product-footer__links a { color: var(--ink-doc); text-decoration: none; }
.product-footer__links a:hover { text-decoration: underline; }

/* ------------------------------------------------------ language switch */

/* Three locales, so a two-state toggle no longer works: there is no obvious
   "other" language to flip to. A segmented control shows all three at once and
   switches in a single tap, with no menu to open first. Built from the site's
   own card surface and hairline rather than the glass effect the migration
   script had injected. */
.lang-switch {
  position: fixed;
  right: max(24px, env(safe-area-inset-right) + 24px);
  bottom: max(24px, env(safe-area-inset-bottom) + 24px);
  z-index: 50;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: var(--glass);
  box-shadow: inset 0 0 0 1px var(--line), var(--glass-shadow);
  -webkit-backdrop-filter: saturate(var(--glass-saturate)) blur(12px);
  backdrop-filter: saturate(var(--glass-saturate)) blur(12px);
}

.lang-switch__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  height: 28px;
  padding: 0 9px;
  border-radius: 999px;
  font: 600 13px/1 var(--font);
  letter-spacing: 0.01em;
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.15s ease, background-color 0.15s ease;
}

/* The current locale is a <span>, not a link — there is nowhere to go. */
.lang-switch__item[aria-current] {
  background: var(--ink-doc);
  color: var(--ink-invert);
}

a.lang-switch__item:hover { color: var(--ink-doc); background: var(--wash-strong); }

/* A fixed control only has a genuinely empty right-hand lane once the
   1136px product band, its 72px gutter and the 114px control all fit beside
   one another. Below that point it sits in the document's top-right corner
   and scrolls away, so it cannot cover legal copy, FAQs or product media. */
@media (max-width: 1411px) {
  .lang-switch {
    position: absolute;
    top: max(12px, env(safe-area-inset-top) + 12px);
    bottom: auto;
    right: max(12px, env(safe-area-inset-right) + 12px);
    left: auto;
  }
}

/* ------------------------------------------------------------ ≤ 809px */

@media (max-width: 809px) {
  .wrap { padding: 0 24px; max-width: none; }

  .home { padding-top: 72px; padding-bottom: 96px; gap: 48px; }
  .home-head { padding: 0; }
  .logotype { font-size: 32px; line-height: 40px; }

  .app-card {
    align-items: flex-start;
    gap: 20px;
    padding: 16px;
  }
  .app-card__icon { width: 48px; height: 48px; }

  /* The pill collapses to a square arrow, as on the original. */
  .app-card__action {
    min-width: 0;
    width: 48px;
    height: 48px;
    padding: 0;
    gap: 0;
  }
  .app-card__action .app-card__label { display: none; }
  .app-card__action .app-card__arrow { display: block; width: 16px; height: 16px; }

  .site-footer {
    flex-direction: column;
    gap: 8px;
  }

  .doc { padding: 72px 24px 72px; }
  .doc h1 { font-size: 30px; line-height: 38px; }
  .doc__lede { font-size: 17px; line-height: 27px; }
  .doc h2 { font-size: 22px; line-height: 30px; }

  .product { padding: 16px 24px 72px; }
  .product-hero {
    grid-template-columns: 1fr;
    gap: 32px;
    padding: 24px 0;
  }
  /* Screenshot after the pitch on a phone, so the headline leads. */
  .product-hero__media { order: 2; padding: 24px 20px; }
  .product-hero__body { order: 1; max-width: none; }
  .product-hero__body h1,
  .product-hero__body h1[data-size] { font-size: 28px; line-height: 36px; }
  .product-hero__body > p:not([class]) { font-size: 17px; line-height: 27px; }
  .product-footer {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
  .product-footer__links { flex-wrap: wrap; gap: 16px 20px; }

}

/* ------------------------------------------------------------ ≤ 400px */

@media (max-width: 400px) {
  .home-actions { width: 100%; }
  .home-actions .btn { flex: 1 1 0; padding: 0 12px; }
}

/* --------------------------------------------------------------- print */

@media print {
  .lang-switch, .hero-grid { display: none; }
  body { background: #fff; color: var(--ink-doc); }
  /* The dark block above is scoped to `screen`, so the tokens are already the
     light ones here; this only stops the browser painting its own furniture
     dark on a page that is about to be white. */
  :root { color-scheme: light; }
  .doc { padding: 0; max-width: none; }
}

/* ------------------------------------------------------------ not found */

.notfound {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding-top: 180px;
  padding-bottom: 200px;
  text-align: center;
}

.notfound__code {
  margin: 0;
  font-family: "Cubic 11", var(--font);
  font-size: 36px;
  line-height: 44px;
  letter-spacing: -0.4px;
  color: var(--muted);
}

.notfound__title {
  margin: 0;
  font-size: 26px;
  font-weight: 600;
  line-height: 34px;
  letter-spacing: -0.2px;
  color: var(--ink);
}

.notfound__body {
  margin: 0;
  max-width: 400px;
  font-size: 16px;
  line-height: 24px;
  color: var(--muted);
}

.notfound .btn { margin-top: 12px; }

@media (max-width: 809px) {
  .notfound { padding-top: 120px; padding-bottom: 140px; }
  .notfound__code { font-size: 32px; line-height: 40px; }
  .notfound__title { font-size: 24px; line-height: 32px; }
}

/* ------------------------------------------------- product page: sections */

/* Measured off the originals rather than invented.
 *
 * At 1280 the page reserves 72px gutters, so a band's content is 1136px wide.
 * Running text is then held to 852px and centred inside that, while feature
 * grids use the full 1136. Getting this backwards — text at 1136, media at
 * full width — was what made these two pages read as a different site. */

.product-hero--centered,
.section {
  padding: var(--band, 64px) 0;
  text-align: center;
}

.product-hero--centered {
  display: block;
  gap: 0;
}

/* 852px of running text, centred in the 1136px band. */
.product-hero--centered .product-hero__body,
.section__heading,
.section__lede,
.section__note {
  max-width: 852px;
  margin-left: auto;
  margin-right: auto;
}

.product-hero--centered .product-hero__body {
  display: block;
  padding: 0;
}

.product-hero--centered .product-hero__body h1,
.section__heading {
  margin: 0 auto;
  font-weight: 600;
  letter-spacing: -0.4px;
  color: var(--ink-doc);
}
/* Framer sizes the first section's heading larger than the rest. */
h1[data-size="60"], h2[data-size="60"] { font-size: 52px; line-height: 60px; }
h1[data-size="48"], h2[data-size="48"] { font-size: 42px; line-height: 50px; }

/* Split heroes become two columns at 810px. Grow their headings with the
   available viewport instead of jumping from the 28px phone size straight to
   the 1280px display size inside a ~309px text column. The values meet the
   desktop ramp exactly at 1280px. */
@media (min-width: 810px) {
  .product-hero--split h1[data-size="60"] {
    font-size: clamp(32px, 4.0625vw, 52px);
    line-height: clamp(40px, calc(4.0625vw + 8px), 60px);
  }
  .product-hero--split h1[data-size="48"] {
    font-size: clamp(32px, 3.28125vw, 42px);
    line-height: clamp(40px, calc(3.28125vw + 8px), 50px);
  }
}

.product-hero--centered .product-hero__body > p:not([class]),
.section__lede {
  margin: 12px auto 0;
  font-size: 17px;
  line-height: 26px;
  color: var(--ink-doc);
}

/* The requirement line under the button: 14px and muted, not hero body copy.
   Selector matches the hero paragraph rule's specificity so it still wins. */
.product-hero--centered .product-hero__body .product-note,
.section__note {
  max-width: 852px;
  margin: 44px auto 0;
  font-size: 14px;
  line-height: 20px;
  color: var(--subtle);
}
.section__note { margin-top: 48px; }

.product-hero--centered .btn-cta { margin-top: 36px; }

/* Hero and wide-media visuals share the 852px column; only grids go wider. */
.product-hero--centered .product-hero__media,
.section__media {
  max-width: 852px;
  margin: 48px auto 0;
  padding: 0;
  background: none;
  box-shadow: none;
}

/* The width/height attributes describe the painted box, which Framer gives a
   fixed aspect and fills — the encoded files are not all that shape. The
   browser derives the ratio from those attributes; `cover` then fills the box
   instead of letterboxing, which was costing every card ~100px of height. */
.media {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
  border-radius: 16px;
  background: var(--surface);
}

/* PegasusOCR's hero emblem.
 *
 * The original is the app icon floating in a soft pink-to-lavender wash about
 * 560x300, with a dozen small icons orbiting it. Those are drawn inline by
 * Framer and cannot be recovered, so they are dropped rather than faked — but
 * the wash is what gives the hero its weight, and that is reproduced here. The
 * glow is a pseudo-element so it can spill past the block without moving the
 * heading below it. */
.product-hero--centered .product-hero__body .product-mark {
  position: relative;
  display: block;
  width: 170px;
  height: 170px;
  margin: 65px auto 59px;
}
.product-hero--centered .product-hero__body .product-mark::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  /* Capped at the viewport: at 390 the full 560 hangs 85px past the right edge
     and the whole document scrolls sideways. The gradient fades to transparent
     well before its own edge, so clamping it is invisible. */
  width: min(560px, 100vw);
  height: 320px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--mark-wash);
  pointer-events: none;
}
.product-hero--centered .product-hero__body .product-mark img {
  position: relative;
  display: block;
  margin: 0 auto;
  top: 50%;
  transform: translateY(-50%);
  border-radius: 27px;
  box-shadow: var(--mark-shadow);
}

.section__eyebrow {
  display: inline-block;
  margin: 0 0 16px;
  padding: 4px 8px;
  border-radius: 10px;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: 12px;
  font-weight: 600;
  line-height: 16px;
  color: var(--ink-doc);
}

/* ---------------------------------------------------------- feature grid */

/* Full 1136px band width, 24px gutters: two 556px columns or three 363px. */
.feature-grid {
  display: grid;
  gap: 48px 24px;
  margin: 48px 0 0;
  padding: 0;
  list-style: none;
  text-align: left;
}
.feature-grid[data-columns="2"] { grid-template-columns: repeat(2, 1fr); }
.feature-grid[data-columns="3"] { grid-template-columns: repeat(3, 1fr); }

.feature__media { overflow: hidden; border-radius: 16px; }

.feature__title {
  margin: 24px 0 0;
  font-size: 22px;
  font-weight: 600;
  line-height: 30px;
  letter-spacing: -0.2px;
  color: var(--ink-doc);
}

.feature__text {
  margin: 8px 0 0;
  font-size: 16px;
  line-height: 24px;
  color: var(--ink-doc);
}

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

/* 1022px wide, 16px padding, 8px between items. */
.faq {
  max-width: 1022px;
  margin: 48px auto 0;
  text-align: left;
}

.faq__item {
  border-radius: 16px;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line);
}
.faq__item + .faq__item { margin-top: 8px; }

.faq__question {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 16px 48px 16px 16px;
  font-size: 16px;
  font-weight: 600;
  line-height: 24px;
  color: var(--ink-doc);
  cursor: pointer;
  list-style: none;
  position: relative;
}
.faq__question::-webkit-details-marker { display: none; }

/* The original marks each question with a small circled query glyph. */
.faq__question::before {
  content: "?";
  flex: none;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
}

.faq__question::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 20px;
  width: 8px;
  height: 8px;
  margin-top: -6px;
  border-right: 1.5px solid var(--muted);
  border-bottom: 1.5px solid var(--muted);
  transform: rotate(45deg);
  transition: transform 0.15s ease;
}
.faq__item[open] .faq__question::after { transform: rotate(-135deg); margin-top: -2px; }

.faq__answer {
  margin: 0;
  padding: 0 16px 16px;
  font-size: 16px;
  line-height: 24px;
  color: var(--ink-doc);
}

/* A page-level rights notice: its own band, left aligned, above the footer. */
.product-disclaimer {
  /* Unlike the running text this is a one-line rights notice; held to the
     852px measure the English wraps, so it gets the full band instead. */
  max-width: none;
  margin: 70px 0 32px;
  padding: 0;
  text-align: left;
  font-size: 14px;
  line-height: 20px;
  color: var(--subtle);
}

@media (max-width: 809px) {
  .product-hero--centered,
  .section { padding: calc(var(--band, 64px) * 0.6) 0; }

  .product-hero--centered .product-hero__body h1[data-size],
  .section__heading[data-size] { font-size: 28px; line-height: 36px; }

  .product-hero--centered .product-hero__body > p:not([class]),
  .section__lede { font-size: 17px; line-height: 27px; }

  .feature-grid,
  .feature-grid[data-columns="2"],
  .feature-grid[data-columns="3"] { grid-template-columns: 1fr; gap: 40px; margin-top: 32px; }
  .feature__title { font-size: 20px; line-height: 28px; }

  .product-hero--centered .product-hero__media,
  .section__media { margin-top: 32px; }
  .faq { margin-top: 32px; }
}

/* --------------------------------------------------------------- form page */

/* Measured off the original: a 568px column centred at 1280, 15px between
   rows, fields on a 12%-black wash with an 8px radius. */
.form-page {
  max-width: 568px;
  margin: 0 auto;
  padding: 96px 24px 120px;
  text-align: center;
}

.form-page__heading {
  margin: 0;
  font-size: 32px;
  font-weight: 600;
  line-height: 38px;
  letter-spacing: -0.2px;
  color: var(--ink-doc);
}

.form-page__lede {
  margin: 12px 0 0;
  font-size: 17px;
  line-height: 26px;
  color: var(--ink-doc);
}

/* The success handler sets the hidden attribute; without this, display:grid
   below wins and the "hidden" form stays fully visible. */
.form[hidden] { display: none; }

.form {
  display: grid;
  gap: 15px;
  margin-top: 24px;
  text-align: left;
}

.form__input {
  display: block;
  width: 100%;
  padding: 15px;
  border: 0;
  border-radius: 12px;
  background: var(--field);
  color: var(--ink-doc);
  font: 400 16px/22.4px var(--font);
  resize: vertical;
}
.form__input::placeholder { color: var(--muted); }
.form__input:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.form__submit {
  padding: 15px;
  border: 0;
  border-radius: 12px;
  /* Apple's button blue. The coral it replaces gave white 16px text only
     2.80:1 against its fill, below the 4.5:1 AA needs; this is 4.70:1. The
     error state below stays warm — a failure should not read as blue. */
  background: var(--blue);
  color: #fff;
  font: 600 16px/22.4px var(--font);
  cursor: pointer;
  transition: filter 0.15s ease;
}
.form__submit:hover { filter: brightness(0.95); }
.form__submit:disabled { cursor: default; filter: saturate(0.4); }

.form__status {
  margin: 24px 0 0;
  padding: 16px;
  border-radius: 16px;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: 16px;
  line-height: 24px;
  color: var(--ink-doc);
  text-align: left;
}
.form__status--error {
  background: var(--error-fill);
  box-shadow: inset 0 0 0 1px var(--error-line);
}

@media (max-width: 809px) {
  .form-page { padding: 64px 24px 96px; }
  .form-page__heading { font-size: 26px; line-height: 32px; }
  .form-page__lede { font-size: 17px; line-height: 27px; }
}

/* ---------------------------------------------------------- locale router */

.router {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  max-width: 640px;
  margin: 0 auto;
  padding: 200px 24px 220px;
  text-align: center;
}
.router__title {
  margin: 0;
  font-family: "Cubic 11", var(--font);
  font-size: 36px;
  font-weight: 400;
  line-height: 44px;
  letter-spacing: -0.4px;
  color: var(--ink);
}
.router__lede { margin: 0; font-size: 16px; line-height: 24px; color: var(--muted); }
.router__links { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 20px; }

@media (max-width: 809px) {
  .router { padding: 120px 24px 140px; }
  .router__title { font-size: 32px; line-height: 40px; }
  .router__links { flex-direction: column; width: 100%; }
}


/* ------------------------------------------- dark scheme: component rules
 *
 * Everything a token swap could express is above. These are the cases where
 * the dark value is not a different colour for the same job, but a different
 * job — a fill that has to invert, a hover that has to change direction, a
 * bright rectangle that needs an edge it never needed on white.
 */

@media screen and (prefers-color-scheme: dark) {
  /* Each product's accent is its app icon's own colour, chosen against white.
     Three of the four have no separation from a near-black page: PickC's
     near-black measures 1.05:1 and WhiteNight's indigo 1.60:1 — a button with
     legible text that is not visibly a button. The dark fills are emitted
     alongside the light ones by tools/build-site.mjs; see CTA_DARK there for
     how each value was chosen. */
  .btn-cta {
    background: var(--cta-dark, var(--cta, var(--accent)));
    color: var(--cta-ink-dark, var(--cta-ink, #fff));
  }

  /* Hover has to reverse. Darkening a fill moves it *toward* a dark page,
     which reads as the button receding rather than responding. */
  .btn-cta:hover,
  .form__submit:hover:not(:disabled) { filter: brightness(1.12); }

  /* Screen recordings and screenshots are light-appearance macOS UI, so they
     land as bright rectangles. The plate behind them is now dark and no longer
     gives them an edge, so they get their own hairline. */
  .product-hero__video,
  .feature__media,
  .section__media .media { box-shadow: 0 0 0 1px var(--line); }

  /* --muted lightened for light AA sits at 4.3:1 on the dark field wash. */
  .form__input::placeholder { color: #8f9296; }
}

/* ------------------------------------------------------ top-level footers
 * Footers sit after <main> so they map to the contentinfo landmark (a footer
 * nested in main does not). These rules reproduce the geometry they had
 * inside it — measured before the move: home footer y 1172/1116, short
 * product page y 784 — and give the document pages a footer they never had.
 * The 116px/148px terms are the footer's own box (24 + content + 72), which
 * keeps short product pages pinning it to the viewport bottom as before. */
main.home { padding-bottom: 0; }
body > .site-footer { margin-top: 64px; padding-bottom: 160px; }

main.product { padding-bottom: 0; min-height: calc(100vh - 116px); }
body > .product-footer { max-width: 1280px; margin: 0 auto; padding: 24px 72px 72px; }

.doc { padding-bottom: 48px; }
main.form-page { padding-bottom: 48px; }
main.notfound { padding-bottom: 96px; }
body > .doc-foot { max-width: 900px; padding: 24px 24px 72px; }

@media (max-width: 809px) {
  body > .site-footer { margin-top: 48px; padding-bottom: 96px; }
  main.product { min-height: calc(100vh - 148px); }
  body > .product-footer { padding: 24px 24px 72px; }
  body > .doc-foot { padding: 24px 24px 72px; }
}

/* ---------------------------------------------------------- card radii
 * The measured Framer radii (6/8/10) were retired at the owner's request; the
 * tokens above carry the control tier (12) and the icon tier (14), and the
 * card surfaces sit one tier up. */
.ticker,
.app-card { border-radius: 16px; }
.app-card__icon { border-radius: 14px; }
