/* Snapline — purchase pages.
 *
 * The page is a capture selection drawn on the site's daylight canvas: the
 * offer sits in the one bone-white pane, inside an iris-blue marquee with
 * eight handles and a live dimension readout. That device is the product's
 * own most recognizable artifact, it is doing the layout's actual work —
 * framing the one thing on the page — and it is the only place any boldness
 * is spent. Everything around it stays quiet.
 *
 * Tokens and grammar match landing.css (the daylight-studio dialect); this
 * sheet restates the subset a purchase page needs rather than importing
 * 1,500 lines of demo machinery.
 */

:root {
  /* Daylight ground: sky canvas, bone-white pane, charcoal button the only
     dense dark. Depth comes from the canvas→card shift, not borders. */
  --paper: #ebf5ff;
  --card: #fafdff;
  --paper-raised: #f3f9ff;
  --ink: #0a0d12;
  --ink-soft: #535862;
  --rule: #dbe8f5;

  --charcoal: #181d27;
  --fog: #93979f;

  --radius-card: 32px;
  --ease-settle: cubic-bezier(0.16, 1, 0.3, 1);
  /* Lets the FAQ's ::details-content ease to block-size: auto. */
  interpolate-size: allow-keywords;

  /* Iris blue: the selection marquee, and the page's single vivid accent. */
  --marquee: #0069e0;
  --marquee-deep: #0055b8;

  --display: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --ui: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --shadow-window: 0 1px 2px rgba(10, 13, 18, 0.06), 0 12px 32px -8px rgba(4, 69, 144, 0.16);
  --shadow-card: 0 1px 2px rgba(10, 13, 18, 0.07), 0 8px 24px -6px rgba(4, 69, 144, 0.2);
  /* The pressed-into-page ring under the charcoal button. */
  --shadow-press: 0 1px 2px rgba(10, 13, 18, 0.8), 0 0 0 1px #0a0d12;

  /* The iris pill: the filled call-to-action (Download, Buy) wears the marquee
     as a graded fill — sky-lit at the top, deepening to the hover blue at the
     foot — with a glass highlight along the rim and a soft blue glow, no dark ring. The
     gradient is twice the pill's height so hover slides it, not swaps it. */
  --cta: linear-gradient(180deg, #4aa2ff 0%, #0069e0 50%, #0052b3 100%);
  --shadow-cta: inset 0 1px 0 rgba(255, 255, 255, 0.34),
    0 2px 6px -1px rgba(0, 105, 224, 0.28), 0 10px 22px -8px rgba(0, 105, 224, 0.5);
  --shadow-cta-hover: inset 0 1px 0 rgba(255, 255, 255, 0.4),
    0 4px 10px -2px rgba(0, 105, 224, 0.32), 0 16px 32px -10px rgba(0, 105, 224, 0.6);

  --step: 8px;
  --measure: 62ch;
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--ui);
  font-size: 17px;
  line-height: 1.6;
  letter-spacing: -0.01em;
  font-variant-ligatures: none;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }

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

/* Announced to screen readers, invisible to everyone else. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ── The menu bar ──────────────────────────────────────────────────────────
   The landing page's floating white pill, verbatim, with the same menu
   (assets/menu.css) and the same Download pill, so no one wonders whether
   they left the site at the moment they pay. */

.menubar {
  position: sticky;
  top: 12px;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 22px;
  height: 56px;
  max-width: 1160px;
  width: calc(100% - 28px);
  margin: 14px auto 0;
  padding: 0 10px 0 22px;
  background: rgba(255, 255, 255, 0.88);
  border-radius: 9999px;
  box-shadow: 0 1px 2px rgba(4, 69, 144, 0.06), 0 8px 24px -12px rgba(4, 69, 144, 0.18);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  font-size: 13.5px;
}

.menubar__mark {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -0.01em;
  text-decoration: none;
}

.menubar__logo { display: block; width: 20px; height: 20px; }

.menubar__spacer { margin-left: auto; }

/* The header's Download pill — the landing's iris .btn--small, restated. */
.btn--small {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 36px;
  padding: 0 18px;
  background-color: var(--marquee);
  background-image: var(--cta);
  background-size: 100% 200%;
  background-position: 0 0;
  color: #fff;
  border: 0;
  border-radius: 9999px;
  font: inherit;
  font-size: 0.88rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  text-decoration: none;
  text-shadow: 0 1px 1px rgba(0, 45, 110, 0.3);
  cursor: pointer;
  transition: background-color 140ms ease, background-position 220ms ease, transform 140ms ease, box-shadow 140ms ease;
  box-shadow: var(--shadow-cta);
}

.btn--small:hover {
  background-color: var(--marquee-deep);
  background-position: 0 100%;
  transform: translateY(-1px);
  box-shadow: var(--shadow-cta-hover);
}

.btn--small:active {
  transform: translateY(0);
  box-shadow: var(--shadow-cta);
}

.btn--small:focus-visible { outline-offset: 3px; }


/* ── The selection ─────────────────────────────────────────────────────────
   `selection` is the positioning context for the handles and the readout;
   `selection__pane` is the bone-white rectangle that holds the offer. Square
   corners on purpose: a capture selection is the one deliberately sharp
   rectangle in the rounded system. */

.stage {
  display: flex;
  justify-content: center;
  padding: clamp(40px, 9vh, 88px) 20px clamp(20px, 4vh, 36px);
}

/* Sized to the measure of the copy inside it rather than to the viewport: a
   selection dragged wider than its content reads as a mistake, and this one is
   the page's whole device. */
.selection {
  position: relative;
  width: min(600px, 100%);
}

/* /buy/ carries the itemized plan, which earns a wider drag than the
   single-paragraph offers on /renew/ and /success/. */
.selection--wide { width: min(680px, 100%); }

.selection__pane {
  --pad: clamp(28px, 5vw, 56px);
  position: relative;
  background: var(--card);
  color: var(--ink);
  border: 1.5px solid var(--marquee);
  padding: var(--pad);
  clip-path: inset(0);
}

/* The thing being bought, shown as itself. Top-right, where the offer copy
   leaves the pane empty; pulled slightly past the padding because the icon's
   artwork carries its own margin inside the bitmap. */
.selection__appicon {
  position: absolute;
  top: calc(var(--pad) - 8px);
  right: calc(var(--pad) - 8px);
  width: 64px;
  height: 64px;
}

/* On /buy/ the icon rides the captured card instead: a small badge on the
   corner of the Quick Access card, the app claiming its own capture. */
.selection__appicon--badge {
  top: calc(var(--pad) - 22px);
  right: calc(var(--pad) + 116px);
  width: 44px;
  height: 44px;
  z-index: 2;
}

/* What a capture becomes, shown honestly: a mini Quick Access card — the
   captured window as a thumbnail with its action row. Greeked content, real
   chrome, same recreated-macOS language as the landing demos. */
.qcapture {
  position: absolute;
  top: calc(var(--pad) - 10px);
  right: calc(var(--pad) - 6px);
  margin: 0;
  width: 148px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
}

.qcapture__win {
  display: block;
  width: 100%;
  background: #fff;
  border-radius: 8px;
  box-shadow: var(--shadow-window);
  overflow: hidden;
}

.qcapture__bar {
  display: flex;
  align-items: center;
  gap: 5px;
  height: 18px;
  padding: 0 8px;
  background: linear-gradient(#f7f7f8, #efeff1);
  border-bottom: 1px solid #e3e3e6;
}

.qcapture__bar i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
}

.qcapture__bar i:nth-child(1) { background: #ff5f57; }
.qcapture__bar i:nth-child(2) { background: #febc2e; }
.qcapture__bar i:nth-child(3) { background: #28c840; }

.qcapture__body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px;
}

.qcapture__line {
  display: block;
  height: 7px;
  border-radius: 4px;
  background: #e4ecf7;
}

.qcapture__actions {
  font-size: 11px;
  color: var(--ink-soft);
  background: #fff;
  border-radius: 9999px;
  padding: 4px 12px;
  box-shadow: var(--shadow-card);
  white-space: nowrap;
}

/* The drag: the selection opens from its centre once, on load. Nothing else
   on the page moves. */
@media (prefers-reduced-motion: no-preference) {
  .selection__pane {
    animation: drag-open 460ms cubic-bezier(0.22, 0.8, 0.3, 1) both;
  }
  .selection__handle,
  .selection__readout {
    animation: settle 200ms ease-out 380ms both;
  }
}

@keyframes drag-open {
  from { clip-path: inset(46% 46% 46% 46%); }
  to   { clip-path: inset(0); }
}

@keyframes settle {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Eight, not four — a macOS selection carries handles at the corners *and*
   the edge midpoints, and the eight together are what make the rectangle read
   as a selection at a glance rather than as a card with a blue border. */
.selection__handle {
  position: absolute;
  width: 9px;
  height: 9px;
  background: var(--marquee);
  border: 1px solid rgba(255, 255, 255, 0.85);
  box-shadow: 0 0 0 1px rgba(0, 105, 224, 0.25);
}

.selection__handle--tl { top: -5px; left: -5px; }
.selection__handle--tr { top: -5px; right: -5px; }
.selection__handle--bl { bottom: -5px; left: -5px; }
.selection__handle--br { bottom: -5px; right: -5px; }
.selection__handle--tm { top: -5px; left: 50%; margin-left: -5px; }
.selection__handle--bm { bottom: -5px; left: 50%; margin-left: -5px; }
.selection__handle--ml { left: -5px; top: 50%; margin-top: -5px; }
.selection__handle--mr { right: -5px; top: 50%; margin-top: -5px; }

/* The dimension HUD, where macOS puts it: just outside the corner you dragged
   to. It reads the pane's real rendered size, so it is true at every width. */
.selection__readout {
  position: absolute;
  right: 0;
  bottom: -30px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--marquee);
  font-variant-numeric: tabular-nums;
}

/* ── The offer ─────────────────────────────────────────────────────────── */

.headline {
  font-family: var(--display);
  font-size: clamp(2.1rem, 5.6vw, 3rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.08;
  margin: 0 0 calc(var(--step) * 2);
  text-wrap: balance;
}

.standfirst {
  font-size: 1.06rem;
  color: var(--ink-soft);
  margin: 0 0 calc(var(--step) * 4);
  max-width: 46ch;
  text-wrap: pretty;
}

/* Amount and list price share the first line; the tax note takes a full line
   of its own beneath them. Beside the amount it wraps mid-phrase at almost
   every width, and a caption broken over four lines reads as a layout bug. */
.price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 12px;
  margin-bottom: calc(var(--step) * 3);
}

.price__amount {
  font-family: var(--display);
  font-size: clamp(2.3rem, 6vw, 3rem);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.price__amount[data-state="loading"] {
  color: transparent;
  /* The static price keeps its line box; min-height guards the empty case. */
  min-height: 1em;
  background: linear-gradient(90deg, var(--rule), #f0f1f4, var(--rule));
  border-radius: 4px;
  min-width: 3.6ch;
  animation: shimmer 1.1s linear infinite;
  background-size: 200% 100%;
}

@keyframes shimmer {
  to { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .price__amount[data-state="loading"] { animation: none; }
}

/* The list price, struck through beside what is actually charged. Quiet on
   purpose — the number being paid is the one that matters, and a loud "was"
   reads as a sales tactic rather than a fact. */
.price__was {
  font-size: 1.15rem;
  color: var(--ink-soft);
  text-decoration-thickness: 1px;
  font-variant-numeric: tabular-nums;
}

.price__was[hidden] { display: none; }

.price__unit {
  flex-basis: 100%;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink-soft);
}

/* When the launch price is ending, the page says so beside the price: the
   instant on the reader's own clock, and how long is left. launch.js writes
   it and takes it away; the markup never names the launch price, so ending
   the launch touches no page. Quiet like the struck-through list price, and
   for the same reason: it is a fact about the price, not a sales device.
   The time left is the one thing set in full ink. */
.price__ends {
  flex-basis: 100%;
  margin: 0;
  font-size: 0.92rem;
  color: var(--ink-soft);
}

.price__ends strong {
  color: var(--ink);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.price__ends[hidden] { display: none; }

/* The iris pill — the same call to action the rest of the site presses: the
   marquee blue as a graded fill, the one saturated fill on the page. */
.buy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 28px;
  background-color: var(--marquee);
  background-image: var(--cta);
  background-size: 100% 200%;
  background-position: 0 0;
  color: #fff;
  border: 0;
  border-radius: 9999px;
  font: inherit;
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  text-shadow: 0 1px 1px rgba(0, 45, 110, 0.3);
  cursor: pointer;
  transition: background-color 140ms ease, background-position 220ms ease, transform 140ms ease, box-shadow 140ms ease;
  box-shadow: var(--shadow-cta);
}

.buy:hover:not(:disabled) {
  background-color: var(--marquee-deep);
  background-position: 0 100%;
  transform: translateY(-1px);
  box-shadow: var(--shadow-cta-hover);
}

.buy:active:not(:disabled) {
  transform: translateY(0);
  box-shadow: var(--shadow-cta);
}

.buy:focus-visible { outline-offset: 3px; }

.buy:disabled {
  background-color: #8f97a5;
  background-image: none;
  text-shadow: none;
  cursor: default;
  box-shadow: none;
}

/* While the checkout is still arriving the disabled button says so, instead
   of sitting grey and unexplained. checkout.js lifts aria-busy when the
   button goes live or the fallback takes over; gating on :disabled keeps a
   stale-cached checkout.js from spinning on an enabled button. */
.buy[aria-busy="true"]:disabled::after {
  content: "";
  width: 13px;
  height: 13px;
  margin-left: 10px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.4);
  border-top-color: #fff;
  animation: spin 700ms linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .buy[aria-busy="true"]:disabled::after { animation: none; }
}

/* Who takes the money and what undoes it, in one quiet line where the
   decision is being made — not three clicks away in the footer. */
.trust {
  margin: calc(var(--step) * 1.5) 0 0;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}

.trust a {
  text-decoration-color: rgba(10, 13, 18, 0.3);
  white-space: nowrap;
}

.assurance {
  margin: calc(var(--step) * 2) 0 0;
  font-size: 0.92rem;
  color: var(--ink-soft);
  max-width: 44ch;
}

/* The one condition a purchase can get wrong, carried at full ink above the
   price rather than as fine print below the button (/renew/). It wears the
   marquee as a left edge — the page's single accent, doing the same job it
   does everywhere else: marking the thing to read. */
.requirement {
  margin: calc(var(--step) * -2) 0 calc(var(--step) * 4);
  padding: 10px 0 10px 14px;
  border-left: 2px solid var(--marquee);
  font-size: 0.95rem;
  color: var(--ink);
  max-width: 46ch;
  text-wrap: pretty;
}

.requirement strong { font-weight: 600; }

/* Mono and factual, the site's fine-print voice. */
.fine {
  margin: calc(var(--step) * 2) 0 0;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}

.fallback {
  margin: calc(var(--step) * 2) 0 0;
  padding: 12px 14px;
  border: 1px solid #f0c98a;
  background: #fdf6e9;
  border-radius: 8px;
  font-size: 0.94rem;
  color: #6b4f18;
}

.fallback[hidden] { display: none; }

/* ── The offer, itemized (/buy/) ──────────────────────────────────────────
   The pane reads top to bottom like a checkout summary: what it is, what it
   costs, what you get, what's optional — split by hairlines, never boxes. */

.rule {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: calc(var(--step) * 3) 0;
}

.plan {
  list-style: none;
  margin: 0;
  padding: 0;
}

.plan li {
  position: relative;
  padding: 0 0 0 30px;
  margin: 0 0 calc(var(--step) * 2);
}

.plan li:last-child { margin-bottom: 0; }

/* The bullet is the selection's own 9px handle — the same square that marks
   the marquee corners marks what the selection contains. */
.plan li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 7px;
  width: 9px;
  height: 9px;
  background: var(--marquee);
  border: 1px solid rgba(255, 255, 255, 0.85);
  box-shadow: 0 0 0 1px rgba(0, 105, 224, 0.25);
}

.plan__title {
  display: block;
  font-weight: 500;
  letter-spacing: -0.01em;
}

.plan__body {
  display: block;
  font-size: 0.92rem;
  color: var(--ink-soft);
  text-wrap: pretty;
}

.tryfirst {
  margin: 0 0 calc(var(--step) * 3);
  font-size: 0.95rem;
  color: var(--ink-soft);
}

.tryfirst a { text-decoration-color: rgba(10, 13, 18, 0.3); }

/* ── Below the selection ──────────────────────────────────────────────────
   Outside the marquee: context, not the offer. It stays on the sky canvas
   and keeps its voice down. */

/* The one line under the selection, centered like the readout's caption:
   currency and system facts that belong to the page, not the offer. */
.postscript {
  margin: 0 auto;
  padding: clamp(36px, 6vh, 56px) 20px 0;
  max-width: 600px;
  text-align: center;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}

/* Section headings below the selection — the landing's display voice at a
   size that stays under the pane's h1. */
.section-title {
  font-family: var(--display);
  font-size: clamp(1.6rem, 3.6vw, 2.2rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.15;
  text-align: center;
  margin: 0 0 calc(var(--step) * 2);
  text-wrap: balance;
}

.guarantee {
  max-width: 640px;
  margin: 0 auto;
  padding: clamp(48px, 8vh, 88px) 20px 0;
  text-align: center;
}

.guarantee p {
  margin: 0 auto;
  max-width: 46ch;
  color: var(--ink-soft);
  text-wrap: pretty;
}

.guarantee a { text-decoration-color: rgba(10, 13, 18, 0.3); }

/* ── FAQ ──────────────────────────────────────────────────────────────────
   The landing's FAQ grammar, restated: each question a bone-white card,
   answers easing open where the browser can. */

.faq {
  max-width: 680px;
  margin: 0 auto;
  padding: clamp(48px, 8vh, 88px) 20px clamp(56px, 10vh, 96px);
}

.faq .section-title { margin-bottom: calc(var(--step) * 4); }

.faq__item {
  background: var(--card);
  border-radius: var(--radius-card);
  padding: 0 clamp(22px, 3vw, 32px);
  margin-bottom: 14px;
}

.faq__item summary {
  list-style: none;
  cursor: pointer;
  padding: 20px 36px 20px 0;
  font-weight: 500;
  font-size: 1.04rem;
  letter-spacing: -0.015em;
  position: relative;
  transition: color 120ms ease;
}

.faq__item summary::-webkit-details-marker { display: none; }

.faq__item summary:hover { color: var(--marquee-deep); }

.faq__item summary::after {
  content: "";
  position: absolute;
  right: 8px;
  top: 50%;
  width: 8px;
  height: 8px;
  border-right: 1.5px solid var(--ink-soft);
  border-bottom: 1.5px solid var(--ink-soft);
  transform: translateY(-70%) rotate(45deg);
  transition: transform 400ms var(--ease-settle);
}

.faq__item[open] summary::after { transform: translateY(-30%) rotate(225deg); }

@media (prefers-reduced-motion: no-preference) {
  .faq__item::details-content {
    opacity: 0;
    block-size: 0;
    overflow-y: clip;
    transition:
      content-visibility 550ms allow-discrete,
      opacity 550ms var(--ease-settle),
      block-size 550ms var(--ease-settle);
  }

  .faq__item[open]::details-content {
    opacity: 1;
    block-size: auto;
  }
}

.faq__item p {
  /* Padding, not margin: a bottom margin collapses out of ::details-content
     and the answer lands flush on the card's edge. */
  margin: 0;
  padding: 0 24px 24px 0;
  font-size: 0.97rem;
  color: var(--ink-soft);
  max-width: 58ch;
  text-wrap: pretty;
}

.faq__item a { text-decoration-color: rgba(10, 13, 18, 0.3); }

.terms {
  max-width: min(600px, 100%);
  margin: 0 auto;
  padding: clamp(28px, 6vh, 56px) 20px clamp(56px, 10vh, 96px);
  display: grid;
  gap: 28px;
  /* Three or one, never two-and-an-orphan. */
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}

/* Four terms make a 2×2, never a 3-and-an-orphan — the orphan would be the
   try-first term, which deserves better than a leftover slot. */
.terms--four { grid-template-columns: repeat(2, 1fr); }

.term__title {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--marquee-deep);
  margin: 0 0 8px;
}

.term__body {
  margin: 0;
  font-size: 0.95rem;
  color: var(--ink-soft);
  text-wrap: pretty;
}

.term__body a { text-decoration-color: rgba(10, 13, 18, 0.3); }

.footer {
  border-top: 1px solid var(--rule);
  padding: 20px;
  text-align: center;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.03em;
  color: var(--ink-soft);
}

.footer a { text-decoration-color: rgba(10, 13, 18, 0.3); }

@media (max-width: 640px) {
  /* Too narrow for the captured card and the copy to share the pane. */
  .qcapture { display: none; }
  .selection__appicon--badge {
    top: calc(var(--pad) - 8px);
    right: calc(var(--pad) - 8px);
    width: 56px;
    height: 56px;
  }
}

@media (max-width: 560px) {
  .selection__handle { display: none; }
  .selection__readout { display: none; }
  .selection__pane { border-radius: 12px; }
  /* Too narrow to float beside the headline without colliding with it — the
     icon joins the flow above the headline instead. */
  .selection__appicon {
    position: static;
    width: 52px;
    height: 52px;
    margin: -4px 0 12px -4px;
  }
  .terms { grid-template-columns: 1fr; }
}
