/* The pricing page, layered on top of style.css.
 *
 * This used to sit on `landing.css` and wear the poster's clothes: ink and parchment, Palatino,
 * gold, hard-shadowed square buttons. That was a defensible choice while the only way in was from
 * the landing page, and it stopped being one once the dashboard grew an upsell panel whose "See
 * what Plus does" button lands here. Somebody on the light theme went from a light sans-serif app
 * to a dark serif poster in one click, and the two stylesheets did not even disagree cleanly:
 * `landing.css` has no `data-theme` rules at all, so the ground stayed ink while `ui.css`, which
 * this page has always loaded, repainted its dialogs and buttons for whichever theme was chosen.
 * A page half in one palette and half in the other reads as broken rather than as different.
 *
 * So everything here is written against the app's tokens and nothing else. There is no colour
 * literal below, which is the property that makes the light theme work: `style.css` redefines
 * `--bg`, `--surface`, `--border`, `--text*` and `--gold*` under `:root[data-theme="light"]`, and
 * a page built only out of those follows along for free. The one rule worth holding to is the
 * app's about the accent: `--gold` is spent on things you press, and `--gold-ink` is the paler
 * sand used when the same idea has to be said in text. Borrowing a fill colour for a heading is
 * how a page ends up with nothing on it able to look more important than anything else.
 *
 * The vocabulary here is deliberately the dashboard upsell panel's, see `.upsell` in `ui.css`:
 * same eyebrow, same tick, same gold-mixed border on the one card being argued for. Those two
 * panels make the same pitch, and a visitor who sees both should not have to work out whether they
 * are looking at the same product. */

/* --- The page frame -------------------------------------------------------------------------- */

/* `style.css` lays the body out as a flex row that centres one app-shaped child, which is right for
   the trainer and wrong for a document read top to bottom. Back to block flow, and the column is
   re-established per child below so the back link, the hero and the footer share one left edge. */
body.pricing-page {
  display: block;
  padding: 28px 24px 96px;
}

/* Same measure as the hero, so the link sits at the column's left edge rather than at the window's.
   On a wide screen those are a couple of hundred pixels apart, and the version pinned to the window
   reads as something that fell off the page. */
.back-link,
.foot {
  display: block;
  width: min(1080px, 100%);
  margin-inline: auto;
}

.back-link {
  margin-bottom: 26px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-decoration: none;
  color: var(--text-dim);
}

.back-link:hover { color: var(--text); }
.back-link:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: 4px; }

.hero { width: 100%; }

.pricing-hero {
  width: min(1080px, 100%);
  margin-inline: auto;
  text-align: center;
}

.foot {
  margin-top: 44px;
  font-size: 12px;
  text-align: center;
  color: var(--text-faint);
}

/* `<code>` in the footer holds a real figure, 6.1M labelled puzzles, and it is the one number down
   there worth reading, so it takes the ink form of the accent rather than the body colour. */
.foot code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--gold-ink);
}

/* --- Headings and running text --------------------------------------------------------------- */

/* Matched to `.upsell-eyebrow` in `ui.css`, down to the tracking. It is the same label doing the
   same job one page over. */
.eyebrow {
  margin: 0 0 16px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-ink);
}

/* The poster's title was a 52px serif at weight 400 leaning on a drop shadow. The app has no drop
   shadows on type and no serif, so weight has to do that work instead. `--text-bright` rather than
   `--text`: this is the one line on the page that should be the brightest thing in view. */
.page-title {
  margin: 0;
  font-size: clamp(28px, 4.4vw, 44px);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--text-bright);
}

.blurb {
  margin: 16px auto 0;
  max-width: 62ch;
  font-size: clamp(14px, 1.6vw, 16px);
  line-height: 1.6;
  color: var(--text-dim);
}

.pricing-hero .blurb { margin-top: 18px; }

/* A section break in the middle of a long document, not a second title. Tracked out and small, the
   way every other section label in the app is, but in `--text-faint` rather than the accent: there
   is already one gold eyebrow at the top of this page, and a second would make the two read as a
   pair of headings ranking the same. */
.section-title {
  margin: 68px 0 20px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* The two lines under the cards: what cancelling does, and where to redeem a code. Small print in
   the literal sense, so it takes the faintest token that still clears AA. */
.cta-aside {
  margin: 18px 0 0;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-faint);
}

.cta-aside .linkish { font-size: inherit; }

/* --- Monthly / yearly ------------------------------------------------------------------------ */

/* Two segments in one bordered strip rather than two buttons, because they are one choice. The
   inactive half is not disabled-looking. It is a real option, just not the one selected. The 3px
   of padding on the strip is what lets the selected segment sit inside the border as an inlaid
   pill instead of painting over it. */
.billing-toggle {
  display: inline-flex;
  gap: 3px;
  margin: 30px 0 0;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--surface);
}

.cycle-btn {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 9px 20px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-dim);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 120ms linear, color 120ms linear;
}

.cycle-btn:hover { color: var(--text); background: var(--raised); }

.cycle-btn.is-on {
  background: var(--gold);
  color: var(--on-gold);
  font-weight: 700;
}

/* The pressed segment is a gold fill, so hovering it must not repaint it as an unpressed one. */
.cycle-btn.is-on:hover { background: var(--gold); color: var(--on-gold); }

.cycle-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* De-emphasised by size and weight, and **not** by `opacity`.
 *
 * It was `opacity: 0.78`, falling to 0.72 on the selected segment, which is the obvious way to say
 * "quieter than the label beside it" and the wrong one here. `opacity` fades the ink toward
 * whatever is behind it without changing the computed colour, so this read 3.08:1 on the light
 * theme and 3.21:1 on the dark one while the stylesheet still claimed a passing token. Both are
 * under AA, on the smallest type in the control. `style.css` carries the same finding about
 * disabled buttons, so this is the house position rather than a new one.
 *
 * Inheriting the colour is what makes both states safe: on the unselected segment that is
 * `--text-dim` at 7.05:1, and on the selected one `--on-gold` at 5.20:1. Measured with
 * `contrast_audit.js`. */
.cycle-save {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
}

/* The launch offer, once, under the toggle and above both cards. It is the one line on the page
   making a claim about time, so it takes the accent as ink; not a box, because a boxed banner on a
   page that is already two boxes reads as a third plan. Hidden and empty when no offer is running,
   so nothing here has to know whether there is one. */
.sale-banner {
  max-width: 50ch;
  margin: 20px auto 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--gold-ink);
}

/* --- The two plans --------------------------------------------------------------------------- */

.plans {
  margin: 30px 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 18px;
  text-align: left;
}

.plan {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 24px 22px 26px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
}

/* The paid card is marked by a warmer edge and a wash off its own corner, not by being bigger or by
   moving. A scaled-up card in a two-card grid throws the row's baselines out and makes the free
   tier look like a mistake, which is the wrong message when the free tier is what earns the trust.
   The mix and the gradient are lifted from `.upsell` so the two panels are recognisably one idea. */
.plan-featured {
  border-color: color-mix(in srgb, var(--gold) 38%, var(--border));
  background:
    linear-gradient(135deg, color-mix(in srgb, var(--gold) 7%, transparent), transparent 62%),
    var(--surface);
}

/* Tucked into the corner the border already turns, and given that corner's radius so it does not
   cut a square across a rounded edge. */
.plan-flag {
  position: absolute;
  top: -1px;
  right: -1px;
  padding: 5px 11px;
  border-radius: 0 10px 0 10px;
  background: var(--gold);
  color: var(--on-gold);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.plan-name {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-ink);
}

.plan-for {
  margin: 10px 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-dim);
  /* Two cards whose descriptions run to different line counts would put their prices at different
     heights, and a price is the thing the eye jumps between. */
  min-height: 2.9em;
}

.plan-price {
  margin: 18px 0 0;
  display: flex;
  align-items: baseline;
  gap: 8px;
  color: var(--text-bright);
}

/* `tabular-nums` so the figure does not re-space itself when the cycle switch swaps $6.99 for
   $5.99. Without it the two are different widths and the card twitches on every press. */
.plan-price .amount {
  font-size: 42px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

/* The list price an offer is off, struck through and sat beside the figure being charged. Half the
   size, because it is context for the big number rather than a second one competing with it, and
   `text-decoration-thickness` is pinned: the default is derived from the font size, so at this size
   the line comes out hairline and reads as a rendering artefact rather than as a strikethrough. */
.plan-price .amount-was {
  font-size: 21px;
  font-weight: 600;
  line-height: 1;
  color: var(--text-faint);
  text-decoration-thickness: 2px;
}

.plan-price .per {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-faint);
}

.plan-cycle {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--text-faint);
}

.plan-cta {
  margin: 22px 0 0;
  padding: 11px 14px;
  font-size: 14.5px;
}

/* The plan you are already on. It keeps the button's shape because the two cards' buttons sit at
   the same height and one of them turning into a line of text would knock them out of line, but it
   stops looking like something to press, because there is nothing to press it for. */
.plan-cta-current {
  cursor: default;
  background: var(--raised);
  color: var(--text-dim);
}

/* Whatever the base button does on hover, this does not: a control that responds to the mouse is
   making an offer. The second selector is not redundant. `.btn-primary:hover` in `style.css` is a
   class plus a pseudo-class exactly as `.plan-cta-current:hover` is, so it would win on order. */
.plan-cta-current:hover,
.btn-primary.plan-cta-current:hover {
  background: var(--raised);
  color: var(--text-dim);
}

.plan-points {
  margin: 22px 0 0;
  padding: 20px 0 0;
  border-top: 1px solid var(--border);
  list-style: none;
  display: grid;
  gap: 10px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-dim);
}

/* A hanging indent, not a two-column grid. The bullets have `<strong>` and `<em>` inside them, and
   as grid items every one of those became a cell of its own, so the card came out as a column of
   single words. Inline flow with the tick in a fixed-width box is the same picture and cannot come
   apart on the markup. */
.plan-points li {
  padding-left: 22px;
  text-indent: -22px;
}

.plan-points strong { color: var(--text); font-weight: 700; }
.plan-points em { font-style: italic; }

.tick {
  display: inline-block;
  width: 22px;
  text-indent: 0;
  font-weight: 700;
  color: var(--gold-ink);
}

.plan-aside { margin-top: 22px; text-align: center; }

/* --- The comparison -------------------------------------------------------------------------- */

/* The table is the widest thing on the page and the first to run out of room. It scrolls inside its
   own box rather than pushing the document sideways. */
.table-scroll {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
}

.compare {
  width: 100%;
  min-width: 560px;
  border-collapse: collapse;
  text-align: left;
  font-size: 13px;
  color: var(--text-dim);
}

.compare thead th {
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text);
}

/* The two value columns are equal and narrower than the label, so the answers line up under their
   headings instead of drifting with the length of the question. */
.compare thead th:nth-child(2),
.compare thead th:nth-child(3) { width: 26%; }

.compare tr.group th {
  padding: 20px 18px 8px;
  border-bottom: 1px solid var(--border);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold-ink);
  background: var(--sunken);
}

.compare tbody th[scope="row"] {
  padding: 13px 18px;
  font-weight: 600;
  color: var(--text);
  vertical-align: top;
}

.compare td {
  padding: 13px 18px;
  vertical-align: top;
}

.compare tbody tr:not(.group) + tr:not(.group) th,
.compare tbody tr:not(.group) + tr:not(.group) td {
  border-top: 1px solid var(--border);
}

/* The Plus column is the one being argued for, so it is the one lit. A faint wash rather than a
   colour change on the text, which would make half the table look like links. `color-mix` against
   the surface rather than a flat alpha over it: the old rule was gold at 4.5% opacity, which on the
   light theme lands on a near-white card and disappears. */
.compare tbody td:last-child {
  color: var(--text);
  background: color-mix(in srgb, var(--gold) 6%, var(--surface));
}

.compare thead th:last-child { background: color-mix(in srgb, var(--gold) 9%, var(--surface)); }

/* An em dash on its own reads as missing data. Dimming it says "deliberately not in this tier". It
   stays at `--text-faint` rather than going fainter still: this is the one glyph in the table
   carrying a whole cell's meaning, so "too faint to be sure whether that is a dash or an empty
   cell" is the wrong failure to have on a pricing comparison. */
.compare td.no { color: var(--text-faint); }

.row-note {
  display: block;
  margin-top: 4px;
  max-width: 42ch;
  /* Explicit, because these sit inside `th[scope="row"]`, which is bold above. */
  font-weight: 400;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--text-faint);
}

/* --- Narrow screens -------------------------------------------------------------------------- */

@media (max-width: 640px) {
  body.pricing-page { padding: 20px 16px 72px; }
  .billing-toggle { display: flex; width: 100%; }
  .cycle-btn { flex: 1; justify-content: center; padding: 10px 8px; }
  .plan-for { min-height: 0; }
  .section-title { margin-top: 52px; }
}

@media (prefers-reduced-motion: reduce) {
  .cycle-btn { transition: none; }
}
