/* ============================================================================
   PRICING - Backbone.

   Builds on home.css (chrome, .wrap, .btn, .eyebrow, .lede, .sr-only) and the
   tokens backbone.css declares. This file owns only the pricing-specific
   composition: the plan cards, the two-row difference table, the shared-
   capability list and the FAQ. No colour or font of its own — every value
   below is a Backbone token, so both themes invert for free.
   ========================================================================= */

/* `padding-block`, not the `padding` shorthand — see home.css's `.doc-head` comment (2026-08-04
   review): a 3-value shorthand's middle `0` sets left AND right, silently zeroing the horizontal
   inset `.wrap` (the other class on this element) supplies. `padding-block` only ever touches
   top/bottom, so this can't regress into the same bug by omission. */
.pr-head { padding-block: clamp(52px, 7vw, 92px) clamp(20px, 3vw, 30px); }
.pr-head h1 { text-transform: uppercase; letter-spacing: -0.02em; font-weight: 800; }
.pr-head .lede { max-width: 62ch; }

.pr-h2 {
  font-size: clamp(1.3rem, 2.4vw, 1.8rem);
  text-transform: uppercase;
  letter-spacing: -0.01em;
}

/* Same `.wrap`-zeroing shorthand bug (every `.pr-band` section is `<section class="wrap pr-band">`)
   — a 2-value `padding: V 0` sets left/right to that `0` just as surely as the 3-value form does.
   `padding-block` leaves the horizontal inset to `.wrap`, at every width. */
.pr-band { padding-block: clamp(40px, 6vw, 68px); border-top: 1px solid var(--line); }

/* ══ PLAN CARDS ═════════════════════════════════════════════════════════════
   A MONTHLY/ANNUAL segmented toggle used to sit between `.pr-head` and this
   grid, and its own caption admitted that "Annual" was just twelve months at
   the monthly rate with no discount — a control that invited a click and paid
   nothing back. It is gone; the cadence is printed under each price instead.
   The spacing it used to contribute moves here so the rhythm is unchanged. */
/* Same `.wrap`-zeroing shorthand bug as `.pr-head` above (this element is `<section class="wrap
   pr-plans">`) — `padding-block` leaves the horizontal inset to `.wrap`. */
.pr-plans { padding-block: 0 clamp(28px, 4vw, 44px); }
.pr-status { text-align: center; padding: 20px 0; }
/* `minmax(0, 1fr)`, NOT `1fr`. THIS IS THE 1024px REFLOW BUG (AX-7), and it is worth the paragraph.
   `1fr` is shorthand for `minmax(auto, 1fr)`, and on a grid ITEM `auto` means min-content — a FLOOR
   the fr share is not allowed to go under. Every paid card's CTA is a `.btn`, and home.css gives
   `.btn` `white-space: nowrap`, so a card whose CTA reads "Contact us about Personal" (what
   pricing.js renders while checkout is not switched on) has a min-content width of ~337px. Three of
   those plus two 20.48px gaps demand 1005px inside a `.wrap` that is 942px at a 1024px viewport, so
   the third track hung 22px past the viewport and `documentElement.scrollWidth` measured 1046
   against 1025 allowed. Measured, in Chromium: hide `.pr-card-cta` and the tracks fall to the honest
   300.375px each.
   It bit at 1024px and nowhere else because 1440px has room for three min-content tracks and
   <=980px has already dropped to two columns. And it mattered far beyond this page: the reflow spec
   loops routes and aborts on the first failure, so /pricing/ sorting before /terms/,
   /accessibility/, /open/ and /browse/ meant those four were never measured at 1024px at all.
   `minmax(0, 1fr)` removes the floor; `min-width: 0` on the card says the same thing from the item's
   side so a later grid declaration here cannot quietly reintroduce it; and `.pr-card-cta .btn`
   below lets the label wrap instead of overhanging the card it no longer widens. */
.pr-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(14px, 2vw, 22px);
  align-items: stretch;
}
.pr-card {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
  border: 1px solid var(--border);
  background: var(--surface);
  padding: clamp(22px, 2.6vw, 30px);
}
.pr-card-featured {
  border-color: var(--sig);
  background: var(--slab-hi);
  box-shadow: var(--shadow-card);
}
.pr-card-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.pr-card-name {
  font: 700 13px/1 var(--mono);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text);
}
.pr-card-badge {
  flex: none;
  padding: 3px 9px;
  border: 1px solid color-mix(in srgb, var(--sig) 50%, transparent);
  background: color-mix(in srgb, var(--sig) 10%, transparent);
  color: var(--sig-text);
  font: 600 9.5px/1.3 var(--mono);
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
/* Price and cadence are one unit, so they share a wrapper rather than each taking the card's 16px
   flex gap — which would have read as two unrelated lines. */
.pr-card-money { display: flex; flex-direction: column; gap: 7px; }
.pr-card-price { display: flex; align-items: baseline; gap: 6px; }
.pr-card-price b {
  font: 300 clamp(32px, 4vw, 44px)/1 var(--mono);
  letter-spacing: -0.03em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.pr-card-price span { font-size: 12.5px; color: var(--faint); }
/* The billing cadence, stated rather than toggled. --muted, not --faint: this is a fact a buyer has
   to be able to read, and --faint only clears 3.4:1 on the brightest surface. */
.pr-card-cycle {
  margin: 0;
  font: 600 10px/1 var(--mono);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}
.pr-card-tagline { color: var(--muted); font-size: 14px; line-height: 1.5; margin: 0; }
.pr-card-tokens {
  padding: 10px 12px;
  border: 1px dashed var(--control-border);
  background: var(--slab);
  font: 600 12px/1.4 var(--mono);
  letter-spacing: 0.02em;
  color: var(--text);
}
.pr-card-tokens small { display: block; margin-top: 2px; font: 500 10px/1.3 var(--mono); letter-spacing: 0.16em; text-transform: uppercase; color: var(--faint); }

.pr-card-features { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; flex: 1; }
.pr-card-features li { display: flex; align-items: flex-start; gap: 9px; font-size: 13.5px; line-height: 1.5; color: var(--muted); }
.pr-card-features svg { flex: none; width: 15px; height: 15px; margin-top: 2px; color: var(--sig); }

/* The practical volume estimate under the token box. Sentence case and normal tracking on purpose:
   it is a sentence, not a label, and the `.pr-card-tokens small` treatment it nearly lived inside
   is uppercase at 0.16em — which turns a 20-word caveat into an unreadable ransom note. */
.pr-card-est { font-size: 12.5px; line-height: 1.55; color: var(--faint); margin: 0; }

.pr-card-cta { margin-top: auto; display: flex; flex-direction: column; gap: 10px; }
/* The other half of the AX-7 fix above. `.btn` is `white-space: nowrap`, written for one-word
   actions, and these labels are five words ("Contact us about Personal"). Once the track stops being
   floored by that label an un-wrapping button simply overhangs its own card instead of the viewport,
   so it wraps here — the same one-rule escape /home/'s `.try-chip-row .bb-chip-q` already makes, for
   the same reason. `.btn`'s own `min-height: 46px` is left alone — it is the coarse-pointer target
   floor — and only the vertical padding is restored (it is `0` there, correct for a single 1-line
   label) so a label that wraps to two lines grows the box instead of colliding with its border. */
.pr-card-cta .btn {
  width: 100%;
  white-space: normal;
  padding-block: 11px;
  line-height: 1.35;
  text-align: center;
}
.pr-card-note { font-size: 12.5px; line-height: 1.5; color: var(--faint); margin: 0; }

/* Checkout-availability notice under the page lede. Only rendered when a paid plan exists that
   cannot currently be bought, so on a fully configured deployment this selector matches nothing.
   --warn is Backbone's semantic "look at this, it is not an error" token; it is carrying meaning
   here, not decorating. [hidden] is restated because this file sets no `display` on the element,
   but the next person to add one would inherit the classic collision. */
/* Bare 2px left rule + slab, matching `.try-answer.refusal` in home.css — the house idiom for a
   semantically-marked block. It was a full 1px --warn box with a 3px left edge, which read as a
   heavier card than anything around it. */
.pr-avail {
  max-width: 62ch;
  margin: 14px 0 0;
  padding: 11px 14px;
  border-left: 2px solid var(--warn);
  background: var(--slab);
  color: var(--muted);
  font-size: 14px;
  line-height: 1.6;
}
.pr-avail[hidden] { display: none !important; }

/* ══ COMPARISON TABLE ═══════════════════════════════════════════════════════
   Its own scroll container — the page must never scroll sideways because a
   4-column table doesn't fit a phone. */
/* `position: relative` is load-bearing, not cosmetic. The table carries a `<caption class="sr-only">`,
   and .sr-only is `position: absolute`. With no positioned ancestor its containing block was the
   INITIAL containing block, so it escaped this scroll container's clip and came to rest at the
   640px-wide table's static position — pushing the DOCUMENT's scrollWidth to 629px at a 390px
   viewport and making the whole page scroll sideways. Making this element the caption's containing
   block puts it back inside the clip. Verified: 629px → 390px. */
.pr-table-wrap { position: relative; overflow-x: auto; border: 1px solid var(--border); margin-top: 22px; }
.pr-table-wrap:focus-visible { outline: 2px solid var(--sig); outline-offset: -2px; }
.pr-table { width: 100%; min-width: 640px; border-collapse: collapse; font-size: 14px; }
.pr-table th, .pr-table td { padding: 12px 16px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
.pr-table thead th {
  position: sticky; top: 0;
  background: var(--surface2);
  font: 600 10.5px/1.3 var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}
.pr-table tbody th {
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}
.pr-table td { color: var(--muted); }
.pr-table td[data-yes] { color: var(--text); }
/* The "included" tick is the same 15px mark the plan cards use. Without an explicit size an inline
   <svg> that carries only a viewBox falls back to the replaced-element default (300x150) and then
   scales to the cell, which drew a checkmark the height of a paragraph in every row and stretched
   six rows to ~135px each. Sized, and tinted like every other affirmative mark on the page. */
.pr-table td[data-yes] svg { display: block; width: 15px; height: 15px; color: var(--sig); }
.pr-table tbody tr:last-child th, .pr-table tbody tr:last-child td { border-bottom: 0; }
.pr-table tbody tr:hover td, .pr-table tbody tr:hover th { background: color-mix(in srgb, var(--sig) 5%, transparent); }
.pr-check { color: var(--sig); margin-right: 6px; }
.pr-dash { color: var(--faint); }

/* ══ POINT-OF-PURCHASE CONSENT (PY-2 / PY-6) ════════════════════════════════
   California AB 2863 (in force 2025-07-01) is why this is a block of its own and
   not a line in the Terms checkbox: the consent has to attach to the AUTO-RENEWAL
   TERMS THEMSELVES, in visual proximity to them, not to the enclosing agreement.
   So the terms are restated here, beside the box, in the currency and cadence the
   card above is quoting — and the box ships UNCHECKED, always, with no code path
   that can pre-check it.

   Rendered by pricing.js only for a plan that can actually be bought by the
   signed-in account looking at it, so on a deployment where checkout is not
   switched on these selectors match nothing. */
.pr-consent {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px 15px;
  border: 1px solid var(--control-border);
  background: var(--slab);
}
.pr-consent-terms { margin: 0; font-size: 12.5px; line-height: 1.6; color: var(--muted); }
.pr-consent-terms b { color: var(--text); }

/* A real square with a drawn mark, matching my.css `.check-row` — the same control the account
   settings page ships, so a checkbox looks like one thing across the product. `appearance: none`
   means `accent-color` cannot apply, and the drawn mark is painted in --sig-ink ON --sig, which is
   the pair Backbone already contrast-picks. The 44px floor is on the LABEL, which is the whole hit
   area (the <input> is inside it), rather than on the 18px box: growing the box would make a tick
   the size of a word. */
.pr-check {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  min-height: 44px;
  padding-block: 4px;
  cursor: pointer;
}
/* 24px, not the 18px my.css's `.check-row` draws. WCAG 2.2 SC 2.5.8 wants 24x24 or 24px of clear
   spacing, and axe measures the INPUT, not the label wrapped around it — an 18px box with a 12px
   row gap computes to 23.6px of safe space and fails by four tenths of a pixel. Measured, not
   assumed: the same 18px control is a live `serious` violation on /my/ today. */
.pr-check input {
  appearance: none;
  flex: none;
  width: 24px; height: 24px;
  margin: 0;
  border: 1px solid var(--control-border);
  background: var(--surface);
  cursor: pointer;
  transition: background-color 160ms ease, border-color 160ms ease;
}
.pr-check input:hover { border-color: var(--text); }
.pr-check input:checked { background: var(--sig); border-color: var(--sig); }
.pr-check input:checked::after {
  content: "";
  display: block;
  width: 100%; height: 100%;
  /* The drawn tick is a clip-path in percentages, so it scales with the 24px box on its own. */
  background: var(--sig-ink);
  clip-path: polygon(19% 47%, 8% 58%, 40% 88%, 92% 27%, 81% 18%, 39% 66%);
}
.pr-check input:focus-visible { outline: 2px solid var(--sig); outline-offset: 2px; }
/* The unmet-requirement state. --err is carrying meaning, not decoration: this box is the one thing
   between the reader and a recurring charge, so "you have not agreed yet" has to be visible without
   reading the sentence under it. */
.pr-check input[aria-invalid="true"] { border-color: var(--err); box-shadow: 0 0 0 1px var(--err); }
.pr-check span { font-size: 13px; line-height: 1.55; color: var(--muted); }
.pr-check a { color: var(--sig-text); text-underline-offset: 3px; }

/* Announced, not just coloured: the element carries role="alert", so it is read the moment
   pricing.js unhides it. Reserved height is deliberately NOT set — the block only ever appears
   after a click on the button below it, so there is nothing above it to shift. */
.pr-consent-err { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--err); }
.pr-consent-err[hidden] { display: none !important; }

/* ══ RENEWAL / CANCELLATION / WITHDRAWAL BAND ═══════════════════════════════
   Three statements, not a wall: what renewal does, how to stop it, and the EU
   14-day right. Same card vocabulary as the usage band below it — this is the
   same kind of object (a short explanation of one rule), so it is not given a
   new one. */
.pr-terms-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; margin-top: 22px; }
.pr-terms-card { border: 1px solid var(--border); background: var(--surface); padding: 20px; }
.pr-terms-card h3 { font-size: 15px; margin-bottom: 8px; }
.pr-terms-card p { color: var(--muted); font-size: 13.5px; line-height: 1.6; margin: 0; }
.pr-terms-card p + p { margin-top: 10px; }
.pr-terms-card a { color: var(--sig-text); text-underline-offset: 3px; }

/* ══ SHARED CAPABILITIES ════════════════════════════════════════════════════
   The six rows that used to be an identical tick in every column of the table
   above. A real <ul>, not a table: there is nothing to compare across, and the
   whole point is that one statement covers all three plans. */
.pr-shared {
  margin-top: 26px;
  border: 1px solid var(--border);
  background: var(--surface);
  padding: clamp(18px, 2.2vw, 24px);
}
.pr-shared-h {
  margin: 0 0 14px;
  font: 600 10px/1.3 var(--mono);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--sig);
}
.pr-shared-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 11px clamp(16px, 3vw, 40px);
}
.pr-shared-list li { display: flex; align-items: flex-start; gap: 9px; font-size: 13.5px; line-height: 1.5; color: var(--muted); }
/* Sized explicitly, like the table's ticks: an inline <svg> carrying only a viewBox falls back to
   the 300x150 replaced-element default and then scales to its box, drawing a checkmark the height
   of a paragraph. */
.pr-shared-list svg { flex: none; width: 15px; height: 15px; margin-top: 2px; color: var(--sig); }

/* ══ WHAT A QUESTION COSTS — the definition + the worked example ════════════
   Deliberately NOT a new card vocabulary: the three supporting statements below
   the estimator are `.pr-usage-card`s, because they are the same kind of object
   as every other short explanation of one rule on this page. What IS new is the
   estimator itself, which is the page's one interactive control and is allowed
   to read as one.

   `.pr-num` is the shared treatment for a figure written in by pricing.js. It
   is `tabular-nums` and has a min-width so the em-dash placeholder occupies the
   same box the number will — the band must not reflow between the first frame
   and the API's answer, which is the whole reason FALLBACK_PLANS exists. */
.pr-num {
  font-variant-numeric: tabular-nums;
  font-weight: 650;
  color: var(--text);
  display: inline-block;
  min-width: 2ch;
}

.pr-est {
  margin-top: clamp(20px, 3vw, 28px);
  border: 1px solid var(--border);
  background: var(--surface);
  padding: clamp(18px, 2.4vw, 26px);
}
.pr-est-form { margin: 0; }
.pr-est-inputs {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: clamp(14px, 2.4vw, 28px);
}
.pr-est-field { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.pr-est-field > span {
  font-size: 13px;
  line-height: 1.4;
  color: var(--muted);
}
.pr-est-field input {
  width: 7.5rem;
  max-width: 100%;
  /* 44px, not the 35px the padding alone gave: these are the only text inputs on the page and a
     number field is the one control people poke at repeatedly on a phone. WCAG 2.5.8 only asks for
     24px, which this cleared already — 44 is the size that stops it being annoying. */
  min-height: 44px;
  padding: 9px 11px;
  font: 650 17px/1.2 inherit;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 0;
  transition: border-color var(--in-time, 320ms) var(--ease-out, cubic-bezier(.16, 1, .3, 1));
}
.pr-est-field input:hover { border-color: var(--muted); }
.pr-est-field input:focus-visible { outline: 2px solid var(--sig); outline-offset: 2px; }

.pr-est-out {
  margin: clamp(16px, 2.2vw, 22px) 0 0;
  padding-top: clamp(14px, 2vw, 18px);
  border-top: 1px solid var(--border);
  /* Two lines that must not reflow the block when their text length changes as the visitor types —
     the estimator sits mid-page and a jumping paragraph under a control is the classic sin. */
  min-height: 3.4em;
}
.pr-est-line {
  display: block;
  font-size: clamp(16px, 1.9vw, 19px);
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  text-wrap: pretty;
}
.pr-est-plan {
  display: block;
  margin-top: 5px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--sig-text);
  text-wrap: pretty;
}
.pr-est-assume {
  margin: 12px 0 0;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--faint);
  max-width: 78ch;
  text-wrap: pretty;
}

/* ══ USAGE / TOP-UP CARDS ═══════════════════════════════════════════════════ */
.pr-usage-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 22px; }
.pr-usage-card { border: 1px solid var(--border); background: var(--surface); padding: 20px; }
.pr-usage-kicker {
  margin: 0 0 10px;
  font: 600 10px/1 var(--mono);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--sig);
}
.pr-usage-card h3 { font-size: 15px; margin-bottom: 8px; }
.pr-usage-card p { color: var(--muted); font-size: 13.5px; line-height: 1.6; margin: 0; }
.pr-usage-card a { color: var(--sig-text); text-underline-offset: 3px; }

/* ══ FAQ ═════════════════════════════════════════════════════════════════════
   Native <details>/<summary>: real disclosure semantics, keyboard-operable
   and screen-reader-announced with no custom ARIA needed. */
.pr-faq { display: flex; flex-direction: column; gap: 1px; margin-top: 22px; border: 1px solid var(--border); }
.pr-faq details { background: var(--surface); border-bottom: 1px solid var(--border); }
.pr-faq details:last-child { border-bottom: 0; }
.pr-faq summary {
  cursor: pointer;
  list-style: none;
  padding: 16px 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font: 600 14.5px/1.4 var(--sans);
  color: var(--text);
}
.pr-faq summary::-webkit-details-marker { display: none; }
.pr-faq summary::after {
  content: "";
  flex: none;
  width: 9px; height: 9px;
  border-right: 1px solid var(--muted);
  border-bottom: 1px solid var(--muted);
  rotate: 45deg;
  transition: rotate 180ms var(--ease, ease);
}
.pr-faq details[open] summary::after { rotate: 225deg; }
.pr-faq summary:hover { color: var(--sig-text); }
.pr-faq summary:focus-visible { outline: 2px solid var(--sig); outline-offset: -2px; }
.pr-faq details p { margin: 0; padding: 0 18px 18px; color: var(--muted); font-size: 14px; line-height: 1.65; max-width: 68ch; }

/* ══ FINALE ═════════════════════════════════════════════════════════════════ */
.pr-finale { text-align: center; border-top: 1px solid var(--line); }
.pr-finale .statement { max-width: none; margin: 0 auto; }
.pr-finale .statement p {
  margin: 0;
  font-size: clamp(20px, 2.8vw, 32px);
  font-weight: 300;
  line-height: 1.28;
  letter-spacing: -0.01em;
  max-width: 26ch;
  margin-inline: auto;
  text-wrap: pretty;
}
.pr-finale .statement b { font-weight: 700; color: var(--sig-text); }
.pr-finale-cta { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: clamp(28px, 4vw, 40px); }

/* ══ RESPONSIVE ══════════════════════════════════════════════════════════════ */
@media (max-width: 980px) {
  /* `minmax(0, …)` here too, for the AX-7 reason spelled out on `.pr-grid` above: a bare `1fr` in a
     media query would put the min-content floor straight back at every width this block covers. */
  .pr-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .pr-grid .pr-card:last-child { grid-column: 1 / -1; }
  .pr-usage-grid { grid-template-columns: 1fr; }
  .pr-terms-grid { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .pr-grid { grid-template-columns: minmax(0, 1fr); }
  .pr-grid .pr-card:last-child { grid-column: auto; }
  .pr-shared-list { grid-template-columns: 1fr; }
  /* The two estimator fields stack rather than shrink: a number input narrower than its own value
     is a control nobody can read what they typed into. */
  .pr-est-inputs { flex-direction: column; align-items: stretch; }
  .pr-est-field input { width: 100%; }
  /* The output grows a line when it wraps at this width, so the reserved height grows with it. */
  .pr-est-out { min-height: 5em; }
}
@media (max-width: 420px) {
  .pr-table td, .pr-table th { padding: 10px 12px; }
}

/* ══ REDUCED MOTION ══════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  .pr-faq summary::after { transition: none; }
  .pr-check input { transition: none; }
  .pr-est-field input { transition: none; }
}
