/*
 * Storefront styles. Builds on tokens.css.
 *
 * Design brief: a visitor arriving from Google on a theme page has never heard
 * of us and is about to type a card number. Every component below exists to
 * answer one of the three questions they are actually asking —
 *
 *   "Is this a real business?"  -> topbar, footer depth, contact routes,
 *                                  consistent craft (spacing, radii, states)
 *   "What exactly do I get?"    -> checklists, buy-box meta, guarantee panel
 *   "Is paying here safe?"      -> secure notes at the point of payment,
 *                                  named gateways, refund terms in plain text
 *
 * Rule followed throughout: reassurance appears NEXT TO the action it
 * reassures, not in a section further down the page that nobody scrolls to.
 */

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: -999px;
  background: var(--color-primary); color: #fff;
  padding: var(--space-30) var(--space-40);
  border-radius: var(--radius-sm); z-index: 100;
}
.skip:focus { left: var(--space-40); top: var(--space-40); }

/* Inline SVG icons. Stroke-based so they inherit `color` and stay crisp at
   any size; sized in `em` so an icon always matches the text beside it. */
.icon {
  inline-size: 1em; block-size: 1em;
  flex: none;
  vertical-align: -0.125em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------------------------------------------------------------- topbar */

/* The first thing above the fold. Three verifiable facts, no marketing —
   this strip is doing the work a "trusted seller" badge pretends to do. */
.topbar {
  background: var(--color-ink-deep);
  color: #d4d4d8;
  font-size: var(--size-tiny);
}
@media (prefers-color-scheme: dark) {
  .topbar { border-bottom: 1px solid var(--color-border); }
}
.topbar-inner {
  display: flex; flex-wrap: wrap;
  align-items: center; justify-content: center;
  gap: var(--space-30) var(--space-50);
  padding-block: var(--space-20);
}
.topbar-item { display: inline-flex; align-items: center; gap: 0.4em; white-space: nowrap; }
.topbar-item .icon { color: #7fd6a8; }
.topbar a { color: #fff; text-underline-offset: 2px; }

/* Below ~34rem only the first item fits comfortably; the rest are noise. */
@media (max-width: 34rem) {
  .topbar-item:nth-child(n + 3) { display: none; }
}

/* ---------------------------------------------------------------- header */

.site-header {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  position: sticky; top: 0; z-index: 20;
}
/* A soft edge under the sticky bar so page content reads as passing beneath
   it rather than colliding with it. Kept as a gradient rather than box-shadow
   so it never draws over the topbar above. */
.site-header::after {
  content: ""; position: absolute; inset-inline: 0; top: 100%; block-size: 12px;
  background: linear-gradient(rgb(16 23 32 / 7%), transparent);
  pointer-events: none;
}

.header-inner {
  display: flex; align-items: center; gap: var(--space-50);
  padding-block: var(--space-30); flex-wrap: wrap;
}
.brand {
  font-family: var(--font-display);
  font-size: var(--size-m); font-weight: 750;
  letter-spacing: var(--tracking-tight);
  color: var(--color-text); text-decoration: none;
}
.brand:hover { color: var(--color-primary); }
/* An uploaded logo is constrained by HEIGHT, whatever it was uploaded at — the
   header row must not change size because someone exported at 2x. The width
   attribute the template writes is only there to reserve space while it
   loads. */
.brand-logo { display: flex; align-items: center; }
.brand-logo img { display: block; height: 2.25rem; width: auto; max-width: 14rem; object-fit: contain; }

.site-header nav {
  display: flex; gap: var(--space-20);
  margin-inline-end: auto;
}
.site-header nav a {
  text-decoration: none; color: var(--color-text);
  font-weight: 550;
  padding: var(--space-20) var(--space-30);
  border-radius: var(--radius-sm);
  transition: background var(--transition), color var(--transition);
}
.site-header nav a:hover { background: var(--color-surface-2); color: var(--color-primary); }
/* Set by the templates on the section the page belongs to. */
.site-header nav a[aria-current] { color: var(--color-primary); background: var(--color-accent-soft); }

.header-actions { display: flex; align-items: center; gap: var(--space-30); }
.header-actions a {
  text-decoration: none; font-size: var(--size-xs);
  display: inline-flex; align-items: center; gap: 0.4em;
  color: var(--color-text); font-weight: 550;
  padding: var(--space-20) var(--space-30);
  border-radius: var(--radius-sm);
}
.header-actions a:hover { color: var(--color-primary); background: var(--color-surface-2); }

/* The cart is the one header control that should look like a control. */
.header-actions .cart {
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
}
.header-actions .cart:hover { border-color: var(--color-primary); }
.cart-count {
  display: inline-grid; place-items: center;
  min-inline-size: 1.35em; block-size: 1.35em; padding-inline: 0.3em;
  border-radius: var(--radius-pill);
  background: var(--color-primary); color: #fff;
  font-size: 0.75em; font-weight: 700; line-height: 1;
}

.currency select {
  font: inherit; font-size: 0.9em;
  padding: var(--space-20) var(--space-30);
  border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  background: var(--color-surface); color: var(--color-text);
  cursor: pointer;
}
.currency select:hover { border-color: var(--color-border-strong); }

/* Under 46rem the nav drops to its own full-width row and scrolls sideways
   rather than collapsing behind a hamburger — no JS, and the destinations
   stay visible, which matters more than tidiness on a shop. */
@media (max-width: 46rem) {
  .header-inner { gap: var(--space-30); }
  .site-header nav {
    order: 3; flex-basis: 100%;
    margin-inline-end: 0;
    overflow-x: auto; scrollbar-width: none;
    padding-block-end: var(--space-20);
  }
  .site-header nav::-webkit-scrollbar { display: none; }
  .header-actions { margin-inline-start: auto; }
  .header-actions .acct span { display: none; }
}

/* ------------------------------------------------------------------ hero */

/*
 * Dark hero.
 *
 * The page alternates near-black and light bands. The hero being the darkest
 * thing on the page does two jobs: the blue CTA inside it has nothing to
 * compete with, and the white content below reads as bright and open by
 * contrast. A hero on white has neither.
 */
.hero {
  position: relative; overflow: hidden;
  background: var(--color-ink);
  color: var(--color-on-ink);
  padding-block: var(--space-80) var(--space-70);
}
/* Two soft radial washes in the brand hues, lifting the flat black without a
   stock photo. Cheap, GPU-free, invisible as a distinct shape. */
.hero::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(55rem 28rem at 8% -15%, rgb(26 108 245 / 26%), transparent 62%),
    radial-gradient(40rem 24rem at 95% 5%, rgb(124 58 237 / 20%), transparent 60%);
}
.hero > * { position: relative; }

.hero-inner { display: grid; gap: var(--space-60); align-items: center; }
@media (min-width: 60rem) {
  .hero-inner { grid-template-columns: 1.05fr 0.95fr; gap: var(--space-70); }
}

.hero h1 {
  font-size: var(--size-xl); max-width: 16ch;
  margin-block-end: var(--space-30);
  color: var(--color-on-ink);
}
.hero .lede { color: var(--color-on-ink-muted); }
.lede { font-size: var(--size-s); color: var(--color-text-muted); max-width: 58ch; }

/* Small capsule above the h1 — states the category before the headline has
   to. Reads as a product, not a blog. */
.hero-badge {
  display: inline-flex; align-items: center; gap: 0.45em;
  background: rgb(255 255 255 / 10%); color: #fff;
  border: 1px solid rgb(255 255 255 / 18%);
  padding: var(--space-20) var(--space-40);
  border-radius: var(--radius-pill);
  font-size: var(--size-tiny); font-weight: 650;
  letter-spacing: 0.01em;
  margin-block-end: var(--space-40);
}

.hero-cta { display: flex; flex-wrap: wrap; gap: var(--space-40); margin-block: var(--space-50) var(--space-40); }
.hero-note {
  font-size: var(--size-tiny); color: var(--color-on-ink-muted);
  display: flex; align-items: center; gap: 0.45em;
}
.hero-note .icon { color: #4ade80; }

/* On the dark hero the ghost button needs a light outline, not a grey one. */
.hero .btn-ghost {
  background: rgb(255 255 255 / 8%); color: #fff;
  border-color: rgb(255 255 255 / 25%);
}
.hero .btn-ghost:hover {
  background: rgb(255 255 255 / 14%); color: #fff;
  border-color: rgb(255 255 255 / 45%);
}

/* ------------------------------------------------------------ trust strip */

.trust-strip {
  display: grid; gap: var(--space-40);
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  list-style: none; padding: 0; margin: 0;
}
.trust-item {
  display: flex; gap: var(--space-30); align-items: flex-start;
}
.trust-item .icon {
  font-size: 1.35rem;
  color: var(--color-success);
  margin-block-start: 0.1em;
}
.trust-item strong { display: block; font-weight: 650; line-height: 1.3; }
/* `display: block` is doing real work: as an inline span this text was laid
   out against the parent's 26px strut instead of its own 13px one, so every
   description came out with a full extra line of leading and the four items
   read as loose, unfinished paragraphs. */
.trust-item span {
  display: block;
  font-size: var(--size-tiny); line-height: 1.5;
  color: var(--color-text-muted);
  margin-block-start: 0.15em;
}

/* On the hero this becomes a light card floating on the dark band, so it
   reads as a summary of the offer rather than four stray lines of text.
   `color` is reset explicitly: the hero sets white text on its whole
   subtree, which would be invisible on this card. */
.trust-card {
  background: var(--color-surface);
  color: var(--color-text);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  padding: var(--space-50);
  display: grid; gap: var(--space-40);
}
.trust-card .trust-strip { grid-template-columns: 1fr; gap: var(--space-40); }
@media (min-width: 30rem) and (max-width: 60rem) {
  .trust-card .trust-strip { grid-template-columns: 1fr 1fr; }
}
.trust-card-foot {
  border-top: 1px solid var(--color-border);
  padding-block-start: var(--space-40);
  font-size: var(--size-tiny); color: var(--color-text-muted);
}

/* Full-width band of the same items, used below the fold on other pages. */
.trust-band {
  background: var(--color-surface-2);
  border-block: 1px solid var(--color-border);
  padding-block: var(--space-60);
}

/* ----------------------------------------------------------------- bands
 *
 * Full-bleed background strips. The page reads as a sequence of distinct
 * sections rather than one long scroll, and each band tells the eye that the
 * subject has changed. Three tones only — grey, lavender, near-black — used
 * in rotation. A fourth would stop meaning anything.
 */
.band-muted { background: var(--color-surface-2); }
.band-lavender { background: var(--color-lavender); }
.band-ink {
  background: var(--color-ink);
  color: var(--color-on-ink);
}
.band-ink h1, .band-ink h2, .band-ink h3 { color: var(--color-on-ink); }
.band-ink .muted, .band-ink p { color: var(--color-on-ink-muted); }
.band-ink .eyebrow-label { color: #8ab4fb; }

/* --------------------------------------------------------------- sections */

.section { padding-block: var(--space-70); }
.section > h2 { font-size: var(--size-l); }

/*
 * Statement on the left, supporting grid on the right.
 *
 * The "everything included" pattern: one confident sentence carrying the
 * offer, with the detail beside it rather than beneath. Stacks on narrow
 * screens, where the sentence reads first and the grid follows.
 */
.split-head { display: grid; gap: var(--space-60); align-items: start; }
@media (min-width: 60rem) {
  .split-head { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); gap: var(--space-70); }
}
.split-head > div:first-child h2 { max-width: 18ch; }
.split-head .features { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }

/* Heading on the left, "see all" on the right, aligned on the baseline. */
.section-head {
  display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: var(--space-30) var(--space-50);
  margin-block-end: var(--space-50);
}
.section-head h2 { margin: 0; }
.section-head p { margin: var(--space-20) 0 0; color: var(--color-text-muted); max-width: 60ch; }
.section-head > div { min-inline-size: 0; }
.section-link { font-weight: 600; text-decoration: none; white-space: nowrap; display: inline-flex; align-items: center; gap: 0.35em; }
.section-link:hover { gap: 0.6em; }
.section-link .icon { transition: transform var(--transition); }

.eyebrow-label {
  display: block;
  font-size: var(--size-tiny); font-weight: 700;
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
  color: var(--color-primary);
  margin-block-end: var(--space-20);
}

/* ------------------------------------------------------------------ btns */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5em;
  background: var(--color-primary); color: #fff;
  padding: 0.7rem var(--space-50);
  border: 1px solid transparent; border-radius: var(--radius-sm);
  font: inherit; font-weight: 650; line-height: 1.3;
  text-decoration: none; cursor: pointer;
  box-shadow: var(--shadow-1);
  transition: background var(--transition), box-shadow var(--transition),
    transform var(--transition);
}
.btn:hover {
  background: var(--color-primary-strong); color: #fff;
  box-shadow: var(--shadow-2);
}
.btn:active { transform: translateY(1px); box-shadow: var(--shadow-1); }
.btn:focus-visible { outline: var(--focus-ring); outline-offset: 2px; }
@media (prefers-color-scheme: dark) {
  /* The dark-mode primary is a light blue; white text on it fails AA. */
  .btn, .btn:hover { color: #08121f; }
}

.btn-ghost {
  background: var(--color-surface); color: var(--color-text);
  border-color: var(--color-border-strong);
  box-shadow: none;
}
.btn-ghost:hover {
  background: var(--color-surface-2); color: var(--color-primary);
  border-color: var(--color-primary); box-shadow: none;
}
@media (prefers-color-scheme: dark) {
  .btn-ghost, .btn-ghost:hover { color: var(--color-text); }
  .btn-ghost:hover { color: var(--color-primary); }
}

/* Reserved for the single most important action on a page — the one that
   takes money. Green because it inherits the reassurance colour. */
.btn-buy { background: var(--color-success); }
.btn-buy:hover { background: color-mix(in srgb, var(--color-success) 85%, #000); }
@media (prefers-color-scheme: dark) {
  .btn-buy, .btn-buy:hover { color: #06170f; }
}

.btn-lg { padding: 0.9rem var(--space-60); font-size: var(--size-s); }
.btn-sm { padding: var(--space-20) var(--space-40); font-size: 0.9em; }
.btn-block { inline-size: 100%; }

/* --------------------------------------------------------------- pricing */

.pricing-head { max-width: 46rem; }
.pricing-head h1 { margin-block-end: var(--space-30); }
.pricing-foot { margin-block-start: var(--space-50); display: flex; gap: 0.5em; align-items: flex-start; }
.pricing-foot .icon { color: var(--color-success); margin-block-start: 0.2em; flex: none; }

/* Segmented control. Two links, not a JS toggle — the page is server-rendered
   and a price that needs JavaScript to appear is a price nobody sees when the
   script fails. */
.billing-toggle {
  display: inline-flex; gap: var(--space-10);
  background: rgb(255 255 255 / 10%);
  border: 1px solid rgb(255 255 255 / 18%);
  border-radius: var(--radius-pill);
  padding: var(--space-10);
  margin-block-start: var(--space-50);
}
.billing-toggle a {
  display: inline-flex; align-items: center; gap: 0.5em;
  padding: var(--space-20) var(--space-50);
  border-radius: var(--radius-pill);
  text-decoration: none; font-weight: 650; font-size: var(--size-tiny);
  color: rgb(255 255 255 / 78%);
}
.billing-toggle a:hover { color: #fff; background: rgb(255 255 255 / 8%); }
.billing-toggle a[aria-current] { background: #fff; color: var(--color-ink); }
.save-pill {
  background: var(--color-success); color: #fff;
  border-radius: var(--radius-pill);
  padding: 0.1em 0.55em; font-size: 0.9em; font-weight: 700;
}
.billing-toggle a[aria-current] .save-pill { background: var(--color-success); color: #fff; }

/*
 * Tier grid.
 *
 * auto-fit rather than a fixed column count so three tiers and five both look
 * deliberate — the owner can add a tier in the admin without anyone editing
 * CSS.
 */
.plan-grid {
  display: grid; gap: var(--space-50);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  align-items: start;
}
.plan {
  position: relative;
  background: var(--color-lavender);
  border: 1px solid transparent;
  border-radius: var(--radius-lg);
  padding: var(--space-50);
  display: grid; gap: var(--space-30);
}
/* The recommended tier is the only dark card, so the eye lands on it without
   needing a bigger size or a louder colour. */
.plan-featured {
  background: var(--color-ink); color: var(--color-on-ink);
  box-shadow: var(--shadow-3);
}
.plan-featured h2, .plan-featured .plan-price strong { color: var(--color-on-ink); }
.plan-featured .plan-tagline, .plan-featured .plan-price span,
.plan-featured .checklist span, .plan-featured .plan-sites { color: var(--color-on-ink-muted); }
.plan-featured .checklist .icon { color: #4ade80; }

.plan-flag {
  position: absolute; inset-block-start: calc(var(--space-30) * -1);
  inset-inline-start: var(--space-50);
  background: var(--color-primary); color: #fff;
  font-size: var(--size-tiny); font-weight: 700;
  padding: 0.15em 0.7em; border-radius: var(--radius-pill);
}
.plan h2 { font-size: var(--size-m); margin: 0; }
.plan-tagline { margin: 0; font-size: var(--size-tiny); color: var(--color-text-muted); }
.plan-price { margin: var(--space-20) 0 0; display: flex; align-items: baseline; gap: 0.3em; }
.plan-price strong { font-size: var(--size-l); font-family: var(--font-display); letter-spacing: var(--tracking-tight); }
.plan-price span { color: var(--color-text-muted); font-size: var(--size-tiny); }
.plan-sites { margin: 0; font-size: var(--size-tiny); display: flex; align-items: center; gap: 0.4em; }
.plan-sites .icon { color: var(--color-success); }
.plan form { margin: var(--space-20) 0 0; }
.plan .checklist { margin-block-start: var(--space-20); }
.plan-soon { margin: var(--space-20) 0 0; }

/* On a dark page the lavender tier card and the dark featured card converge;
   a border keeps them separable. */
@media (prefers-color-scheme: dark) {
  .plan { border-color: var(--color-border); }
  .plan-featured { border-color: var(--color-border-strong); }
}

/* ---------------------------------------------------------------- badges */

.badge {
  display: inline-flex; align-items: center; gap: 0.35em;
  padding: 0.15em 0.6em;
  border-radius: var(--radius-pill);
  font-size: var(--size-tiny); font-weight: 650; line-height: 1.6;
  background: var(--color-surface-2); color: var(--color-text-muted);
  border: 1px solid var(--color-border);
}
.badge-sale { background: color-mix(in srgb, var(--color-sale) 12%, transparent); color: var(--color-sale); border-color: color-mix(in srgb, var(--color-sale) 30%, transparent); }
.badge-ok { background: var(--color-success-soft); color: var(--color-success); border-color: color-mix(in srgb, var(--color-success) 30%, transparent); }

/* ----------------------------------------------------------------- cards */

.cards { grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); }
.card {
  position: relative;
  background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  overflow: hidden; display: flex; flex-direction: column;
  transition: border-color var(--transition), box-shadow var(--transition),
    transform var(--transition);
}
.card:hover {
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-3);
  transform: translateY(-3px);
}
/* Screenshot-led product: the image is the pitch, so it gets the space and a
   slow zoom on hover to signal the whole card is clickable. */
.card-media {
  display: block; aspect-ratio: 4 / 3; overflow: hidden;
  background: var(--color-surface-2);
  border-bottom: 1px solid var(--color-border);
}
.card-media img {
  width: 100%; height: 100%; object-fit: cover; object-position: top center;
  transition: transform 400ms cubic-bezier(0.4, 0, 0.2, 1);
}
.card:hover .card-media img { transform: scale(1.04); }

.card-badges {
  position: absolute; inset-block-start: var(--space-30); inset-inline-start: var(--space-30);
  display: flex; gap: var(--space-20); z-index: 1;
}
.card-badges .badge { background: var(--color-surface); box-shadow: var(--shadow-1); }
.card-badges .badge-sale { background: var(--color-sale); color: #fff; border-color: transparent; }

.card-body {
  padding: var(--space-40); display: flex; flex-direction: column;
  gap: var(--space-30); flex: 1;
}
.card-body h3 { font-size: var(--size-s); margin: 0; letter-spacing: normal; }
.card-body h3 a { text-decoration: none; color: var(--color-text); }
.card:hover .card-body h3 a { color: var(--color-primary); }
.card-body p { margin: 0; font-size: 0.925em; line-height: 1.55; }

/* Price and CTA pinned to the bottom so a grid of cards with uneven copy
   still lines up. */
.card-foot {
  margin-block-start: auto;
  padding-block-start: var(--space-30);
  border-top: 1px solid var(--color-border);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-30);
}
.card-cta { font-size: var(--size-tiny); font-weight: 650; text-decoration: none; }

.price { font-size: var(--size-s); font-weight: 700; letter-spacing: var(--tracking-tight); }
.price .was { color: var(--color-text-muted); font-size: 0.75em; font-weight: 500; margin-inline-end: var(--space-20); }
.price-lg { font-size: var(--size-l); }

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

.breadcrumbs {
  font-size: var(--size-tiny); color: var(--color-text-muted);
  margin-block-end: var(--space-40);
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5em;
}
.breadcrumbs a { color: var(--color-text-muted); text-decoration: none; }
.breadcrumbs a:hover { color: var(--color-primary); text-decoration: underline; }
.breadcrumbs span[aria-hidden] { opacity: 0.5; }

.product-main {
  display: grid; gap: var(--space-60);
  grid-template-columns: 1fr;
}
@media (min-width: 60rem) {
  .product-main { grid-template-columns: minmax(0, 1.5fr) minmax(21rem, 1fr); align-items: start; }
}
.product-media img {
  width: 100%; border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-2);
  display: block;
}
.product-buy { display: flex; flex-direction: column; gap: var(--space-40); }
.product-buy h1 { font-size: var(--size-l); margin: 0; }
.product-links { display: flex; flex-wrap: wrap; gap: var(--space-30); align-items: center; }
.small { font-size: var(--size-tiny); }

/*
 * The buy box.
 *
 * Sticky on desktop so the price and the button stay reachable through a long
 * theme description — the commonest reason a product page loses a sale is the
 * buyer scrolling past the CTA and not coming back. Sticky is disabled below
 * 60rem, where the box sits inline above the description instead.
 */
.buy-box {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
  padding: var(--space-50);
  display: grid; gap: var(--space-40);
}
@media (min-width: 60rem) {
  .buy-box { position: sticky; top: 5.5rem; }
}
.buy-price { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--space-30); }
.buy-save { font-size: var(--size-tiny); font-weight: 650; color: var(--color-sale); }
.buy-box form { margin: 0; }
/*
 * The subscribe alternatives under the main buy button.
 *
 * Visually subordinate on purpose: outright purchase is the primary action and
 * keeps the solid button, while these are ghosts. The "or" rule separates the
 * two commitments so nobody reads a subscription as the price of the theme.
 */
.buy-alt { display: grid; gap: var(--space-30); }
.buy-alt-or {
  display: flex; align-items: center; gap: var(--space-30);
  font-size: var(--size-tiny); color: var(--color-text-muted);
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
}
.buy-alt-or::before, .buy-alt-or::after {
  content: ""; flex: 1; block-size: 1px; background: var(--color-border);
}
.sub-option { margin: 0; }
.buy-alt p { margin: 0; }

.buy-meta {
  display: grid; gap: var(--space-20);
  font-size: var(--size-tiny); color: var(--color-text-muted);
}
.buy-divider { border: 0; border-top: 1px solid var(--color-border); margin: 0; }

/* Padlock + gateway names directly under the button. This is the single
   highest-value piece of copy on the page and it must never be more than a
   few pixels from the thing it reassures. */
.secure-note {
  display: flex; align-items: flex-start; gap: 0.5em;
  font-size: var(--size-tiny); color: var(--color-text-muted);
  line-height: 1.5;
}
.secure-note .icon { color: var(--color-success); font-size: 1.05em; margin-block-start: 0.15em; }

/* Payment marks. See payMarks() for why these are drawn and not brand files.
   Card-shaped tiles, because that is the shape buyers have been trained to
   scan for under a pay button. */
.pay-marks {
  display: flex; flex-wrap: wrap; gap: var(--space-20); align-items: center;
  list-style: none; padding: 0; margin: 0;
}
.pay-mark {
  inline-size: 2.5rem; block-size: 1.625rem;
  display: grid; place-items: center;
  background: #fff;
  border: 1px solid var(--color-border);
  border-radius: 5px;
  overflow: hidden;
}
/* The tiles keep a white ground in dark mode: these are the brands' own
   colours, and they are drawn for light backgrounds. */
@media (prefers-color-scheme: dark) {
  .pay-mark { border-color: var(--color-border-strong); }
}
.pm-svg { inline-size: 100%; block-size: 100%; display: block; }
.pm-stroke {
  fill: none; stroke: #3c4257; stroke-width: 1.4;
  stroke-linecap: round; stroke-linejoin: round;
}
.pm-word {
  font-size: 0.625rem; font-weight: 800; line-height: 1;
  letter-spacing: 0.01em; font-family: var(--font-body);
}
.pm-visa { color: #1a1f71; font-style: italic; letter-spacing: 0.04em; }
.pm-upi { color: #097939; letter-spacing: 0.06em; }
.pm-paypal { font-style: italic; letter-spacing: -0.01em; }
.pm-paypal b { color: #003087; font-weight: 800; }
.pm-paypal i { color: #009cde; font-weight: 800; font-style: italic; }

/* Green-tinted reassurance panel. Used for the refund/guarantee promise and
   nothing else — if it appears twice on a page it stops being a signal. */
.guarantee {
  display: flex; gap: var(--space-40); align-items: flex-start;
  background: var(--color-success-soft);
  border: 1px solid color-mix(in srgb, var(--color-success) 25%, transparent);
  border-radius: var(--radius);
  padding: var(--space-40);
}
.guarantee .icon { font-size: 1.5rem; color: var(--color-success); flex: none; }
.guarantee h3 { font-size: var(--size-xs); margin: 0 0 var(--space-20); letter-spacing: normal; }
.guarantee p { margin: 0; font-size: var(--size-tiny); color: var(--color-text-muted); }

/* Ticked list. The tick is the point: it converts a feature list into a list
   of things the buyer is being given. */
.checklist { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--space-30); }
.checklist li { display: flex; gap: var(--space-30); align-items: flex-start; }
.checklist .icon { color: var(--color-success); font-size: 1.1em; margin-block-start: 0.2em; }
.checklist strong { font-weight: 650; }

/* Native scroll-snap strip, replacing the Jetpack/Swiper carousel. */
.gallery-strip {
  display: flex; gap: var(--space-40);
  overflow-x: auto; scroll-snap-type: x mandatory;
  padding-block: var(--space-50);
  scrollbar-width: thin;
}
/*
 * Below the two-column breakpoint the strip bleeds to the viewport edge, so a
 * half-visible next image signals "swipe me". Scoped to single-column only:
 * at wider sizes this is a grid child and the negative margin would push it
 * out of its own column and under the buy box.
 */
@media (max-width: 59.99rem) {
  .gallery-strip {
    margin-inline: calc(var(--space-50) * -1);
    padding-inline: var(--space-50);
  }
}
.gallery-strip img {
  flex: 0 0 min(80%, 30rem);
  scroll-snap-align: center;
  border-radius: var(--radius);
  border: 1px solid var(--color-border);
}

/* --------------------------------------------------------------- panels */

.panel {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-50);
}
.panel > :last-child { margin-block-end: 0; }

/* Icon-led value props. Three or four, never more — a wall of benefits reads
   as a wall of claims. */
.features { display: grid; gap: var(--space-50); grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.feature { display: grid; gap: var(--space-30); align-content: start; }

/*
 * Icon tile.
 *
 * A saturated rounded square with a white glyph. The colour is assigned per
 * feature and never reused for a different one, so the tile works as a marker
 * a returning visitor recognises rather than as decoration. Defaults to blue;
 * add a --tile-* modifier to vary. White glyphs clear the 3:1 contrast that
 * non-text graphics require against every tile colour defined in tokens.css.
 */
.feature-icon {
  display: grid; place-items: center;
  inline-size: 2.75rem; block-size: 2.75rem;
  border-radius: var(--radius);
  background: var(--tile-blue); color: #fff;
  font-size: 1.35rem;
  box-shadow: var(--shadow-1);
}
/* Blue is also the default, but naming it in the markup keeps the colour
   assignment visible at the call site instead of implied by omission. */
.tile-blue { background: var(--tile-blue); }
.tile-violet { background: var(--tile-violet); }
.tile-teal { background: var(--tile-teal); }
.tile-orange { background: var(--tile-orange); }
.tile-green { background: var(--tile-green); }
.tile-pink { background: var(--tile-pink); }
.tile-ink { background: var(--tile-ink); }
/* On a dark band the near-black tile would disappear into the background. */
.band-ink .tile-ink { background: #2f2f38; }
.feature h3 { font-size: var(--size-xs); margin: 0; letter-spacing: normal; }
.feature p { margin: 0; color: var(--color-text-muted); font-size: 0.925em; }

/* Numbered "how buying works" row. Removing uncertainty about what happens
   after the payment is itself a conversion feature. */
.steps { display: grid; gap: var(--space-50); grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); counter-reset: step; list-style: none; padding: 0; margin: 0; }
.steps li { counter-increment: step; display: grid; gap: var(--space-30); align-content: start; }
.steps li::before {
  content: counter(step);
  display: grid; place-items: center;
  inline-size: 2rem; block-size: 2rem;
  border-radius: var(--radius-pill);
  background: var(--color-primary); color: #fff;
  font-weight: 700; font-size: 0.9rem;
}
@media (prefers-color-scheme: dark) { .steps li::before { color: #08121f; } }
.steps strong { display: block; }
.steps p { margin: 0; color: var(--color-text-muted); font-size: 0.925em; }

/*
 * Closing call to action.
 *
 * Full-bleed and quiet rather than a loud coloured card: by this point in the
 * page the visitor has been shown everything, and the only thing that needs
 * to be loud is the button. A dark badge, one line, one blue CTA.
 */
.cta-band { text-align: center; padding-block: var(--space-80); }
.cta-mark {
  display: inline-grid; place-items: center;
  inline-size: 3rem; block-size: 3rem;
  border-radius: var(--radius-pill);
  background: var(--color-ink); color: #fff;
  font-size: 1.5rem;
  margin-block-end: var(--space-40);
}
.cta-band h2 { margin-block-end: var(--space-30); }
.cta-band p { color: var(--color-text-muted); max-width: 52ch; margin-inline: auto; }
.cta-band .btn { margin-block-start: var(--space-40); }
@media (prefers-color-scheme: dark) {
  .cta-mark { background: #2f2f38; }
}

/* FAQ. Objection handling in the buyer's own words — cheaper than a support
   ticket and it keeps them on the page instead of leaving to ask. */
.faq { display: grid; gap: var(--space-30); }
.faq details {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  transition: border-color var(--transition);
}
.faq details[open] { border-color: var(--color-border-strong); box-shadow: var(--shadow-1); }
.faq summary {
  cursor: pointer; padding: var(--space-40);
  font-weight: 650; list-style: none;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-40);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; flex: none;
  inline-size: 0.55em; block-size: 0.55em;
  border-inline-end: 2px solid currentColor; border-block-end: 2px solid currentColor;
  transform: rotate(45deg) translate(-0.15em, -0.15em);
  transition: transform var(--transition); opacity: 0.55;
}
.faq details[open] summary::after { transform: rotate(-135deg) translate(-0.1em, -0.1em); }
.faq summary:hover { color: var(--color-primary); }
.faq-body { padding: 0 var(--space-40) var(--space-40); color: var(--color-text-muted); }
.faq-body > :last-child { margin-block-end: 0; }

/* ----------------------------------------------------------------- prose */

/* Primary category, sitting above the post title. */
.eyebrow {
  font-size: var(--size-tiny);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-weight: 650;
  margin-block-end: var(--space-20);
}
.eyebrow a { color: var(--color-primary); text-decoration: none; }
.eyebrow a:hover { color: var(--color-link-hover); }

.post-hero { margin: var(--space-50) 0; max-width: 72ch; }
.post-hero img {
  width: 100%; height: auto; display: block;
  border-radius: var(--radius-lg); border: 1px solid var(--color-border);
}

.prose { max-width: 72ch; font-size: 1.0625rem; line-height: 1.75; }
.prose img { border-radius: var(--radius); }
.prose h2 { font-size: var(--size-l); margin-block-start: var(--space-60); }
.prose h3 { font-size: var(--size-m); margin-block-start: var(--space-50); }
.prose pre {
  background: #0f1720; color: #e6edf3;
  padding: var(--space-40); border-radius: var(--radius);
  font-size: 0.875em; line-height: 1.6;
  border: 1px solid #22303f;
}
.prose :not(pre) > code {
  background: var(--color-surface-2); border: 1px solid var(--color-border);
  padding: 0.1em 0.35em; border-radius: var(--radius-sm);
}
.prose blockquote {
  border-inline-start: 3px solid var(--color-primary);
  margin-inline: 0; padding: var(--space-20) 0 var(--space-20) var(--space-50);
  color: var(--color-text-muted); font-size: var(--size-s);
}

/* [su_spoiler] -> <details>. 100 uses across the theme documentation pages. */
.su-spoiler {
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  margin-block: var(--space-40);
  background: var(--color-surface);
}
.su-spoiler > summary {
  cursor: pointer; padding: var(--space-40);
  font-weight: 650; list-style-position: inside;
}
.su-spoiler > summary:hover { color: var(--color-link); }
.su-spoiler-body { padding: 0 var(--space-40) var(--space-40); }
.su-spoiler-body pre { white-space: pre-wrap; }

.su-heading { margin-block-start: var(--space-60); }
.su-button { display: inline-block; }

figure { margin-inline: 0; }
figcaption { font-size: var(--size-tiny); color: var(--color-text-muted); padding-block-start: var(--space-20); }

/* ------------------------------------------------------------- listings */

/* Article cards.
 *
 * Picture first, then the headline, then one line of meta — the order a
 * browsing reader actually scans in. The image is what makes an archive look
 * like a publication rather than a sitemap, so it gets the top of the card and
 * a fixed 16:9 box: uniform boxes are what let a row of cards read as one row
 * instead of a ragged edge. */
.post-cards { grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); }

.post-card {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  overflow: hidden;
  transition: border-color var(--transition), box-shadow var(--transition),
    transform var(--transition);
}
.post-card:hover {
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-3);
  transform: translateY(-3px);
}

.post-card-media {
  position: relative; display: block;
  aspect-ratio: 16 / 9; overflow: hidden;
  background: var(--color-surface-2);
  border-bottom: 1px solid var(--color-border);
}
.post-card-media img {
  width: 100%; height: 100%; object-fit: cover; object-position: top center;
  transition: transform 400ms cubic-bezier(0.4, 0, 0.2, 1);
}
.post-card:hover .post-card-media img { transform: scale(1.04); }

/* Stand-in for a post with no usable picture. Not a grey box: a coloured tile
   keyed to the post id, so the grid stays even and the gap looks intended
   rather than broken. */
.post-card-tile {
  display: grid; place-items: center; block-size: 100%;
  background:
    radial-gradient(120% 120% at 80% 0%, hsl(var(--tile-hue) 82% 62%) 0%, transparent 60%),
    linear-gradient(145deg, hsl(var(--tile-hue) 70% 46%), hsl(calc(var(--tile-hue) + 26) 62% 34%));
}
.post-card-tile .icon {
  inline-size: 2.25rem; block-size: 2.25rem;
  color: #fff; opacity: 0.85; stroke-width: 1.25;
}

/* Category, over the image, bottom-left — the reading order puts it just
   before the headline it qualifies. */
.post-card-tag {
  position: absolute; inset-block-end: var(--space-30); inset-inline-start: var(--space-30);
  max-inline-size: calc(100% - 2 * var(--space-30));
  padding: 0.2em 0.7em; border-radius: var(--radius-pill);
  background: var(--color-primary); color: #fff;
  font-size: var(--size-tiny); font-weight: 650; line-height: 1.7;
  letter-spacing: 0.01em;
  box-shadow: var(--shadow-1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.post-card-body {
  display: flex; flex-direction: column; gap: var(--space-30);
  padding: var(--space-40); flex: 1;
}
.post-card-title {
  margin: 0; font-size: var(--size-s); line-height: 1.35;
  letter-spacing: var(--tracking-tight);
}
.post-card-title a {
  color: var(--color-text); text-decoration: none;
  /* Two lines, then ellipsis. Titles here run from four words to twenty, and
     an unclamped one pushes its card's footer out of line with its row. */
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
}
.post-card:hover .post-card-title a { color: var(--color-primary); }
/* The title link is the card's hit area: stretched over the whole card so the
   picture and the footer are clickable without a second link for a screen
   reader to read out. */
.post-card-title a::after { content: ''; position: absolute; inset: 0; }

.post-card-foot {
  margin-block-start: auto;
  padding-block-start: var(--space-30);
  border-top: 1px solid var(--color-border);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-30);
  font-size: var(--size-tiny);
}
.post-card-meta {
  display: inline-flex; align-items: center; gap: 0.4em;
  color: var(--color-text-muted); min-inline-size: 0;
}
.post-card-meta .icon { inline-size: 1em; block-size: 1em; flex: none; }
.post-card-cta {
  display: inline-flex; align-items: center; gap: 0.35em;
  color: var(--color-primary); font-weight: 650; white-space: nowrap;
}
.post-card-cta .icon {
  inline-size: 1em; block-size: 1em;
  transition: transform var(--transition);
}
.post-card:hover .post-card-cta .icon { transform: translateX(3px); }

@media (prefers-reduced-motion: reduce) {
  .post-card, .post-card-media img, .post-card-cta .icon { transition: none; }
  .post-card:hover { transform: none; }
  .post-card:hover .post-card-media img { transform: none; }
  .post-card:hover .post-card-cta .icon { transform: none; }
}

/* --------------------------------------------------------------- pager */

.pager {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-40); flex-wrap: wrap;
  margin-block-start: var(--space-60);
  padding-block-start: var(--space-50);
  border-top: 1px solid var(--color-border);
}
.pager-nums { display: flex; align-items: center; gap: var(--space-20); flex-wrap: wrap; }
.pager-num {
  display: inline-grid; place-items: center;
  min-inline-size: 2.25rem; padding: 0.35rem 0.6rem;
  border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  text-decoration: none; color: var(--color-text); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.pager-num:hover { border-color: var(--color-border-strong); background: var(--color-surface-2); }
.pager-num.is-current {
  background: var(--color-primary); border-color: var(--color-primary); color: #fff;
}
.pager-gap { color: var(--color-text-muted); padding-inline: var(--space-10); }
.pager-step {
  font-weight: 650; text-decoration: none;
  padding: 0.35rem 0.75rem; border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
}
.pager-step:hover { border-color: var(--color-border-strong); background: var(--color-surface-2); }

/* Article rows as cards. A bare <ul> of links reads as a sitemap; this reads
   as a maintained publication, which is itself a trust signal. */
.post-list { list-style: none; padding: 0; display: grid; gap: var(--space-40); }
.post-list > li {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: var(--space-40) var(--space-50);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.post-list > li:hover { border-color: var(--color-border-strong); box-shadow: var(--shadow-1); }
.post-list a {
  font-size: var(--size-s); text-decoration: none; font-family: var(--font-display);
  font-weight: 650; letter-spacing: var(--tracking-tight); color: var(--color-text);
}
.post-list a:hover { color: var(--color-primary); }
.post-list li > .muted { font-size: var(--size-tiny); display: block; margin-block-start: var(--space-10); }
.post-list p { margin-block: var(--space-20) 0; font-size: 0.925em; }

.muted { color: var(--color-text-muted); }
mark { background: color-mix(in srgb, var(--color-accent) 32%, transparent); color: inherit; border-radius: 2px; }

.search { display: flex; gap: var(--space-30); margin-block: var(--space-50); flex-wrap: wrap; }
.search input {
  flex: 1 1 18rem; font: inherit;
  padding: 0.7rem var(--space-40);
  border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  background: var(--color-surface); color: var(--color-text);
}
.search input:focus-visible { border-color: var(--color-primary); box-shadow: var(--ring-soft); outline: none; }

.comments { margin-block-start: var(--space-70); max-width: 72ch; }
.comments ul { list-style: none; padding: 0; display: grid; gap: var(--space-40); }
.comments li {
  border: 1px solid var(--color-border); border-radius: var(--radius);
  background: var(--color-surface); padding: var(--space-40);
}
.comments li strong { display: inline-block; }

/* Empty states should offer a way forward, never just say "nothing". */
.empty {
  text-align: center; padding: var(--space-70) var(--space-50);
  border: 1px dashed var(--color-border-strong); border-radius: var(--radius-lg);
  color: var(--color-text-muted); background: var(--color-surface);
}
/* The muted colour is for the explanatory copy, not the heading above it. */
.empty h1, .empty h2 { color: var(--color-text); }
.empty > :last-child { margin-block-end: 0; }

/* ---------------------------------------------------------------- footer */

.site-footer {
  border-top: 1px solid var(--color-border);
  margin-block-start: var(--space-80);
  padding-block: var(--space-70) var(--space-50);
  background: var(--color-surface);
}
.footer-grid {
  display: grid; gap: var(--space-60);
  grid-template-columns: 1fr;
  margin-block-end: var(--space-60);
}
@media (min-width: 46rem) {
  .footer-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 64rem) {
  /* Brand column wider than the link columns — it carries the sentence that
     tells a first-time visitor who they are buying from. */
  .footer-grid { grid-template-columns: 1.6fr repeat(3, 1fr); gap: var(--space-50); }
}
.footer-brand p { color: var(--color-text-muted); font-size: 0.925em; max-width: 34ch; }
.footer-brand .brand { font-size: var(--size-s); display: inline-block; margin-block-end: var(--space-30); }
.footer-col h2 {
  font-size: var(--size-tiny); text-transform: uppercase;
  letter-spacing: var(--tracking-wide); color: var(--color-text-muted);
  margin-block-end: var(--space-30); font-weight: 700;
}
.footer-col nav { display: grid; gap: var(--space-30); margin: 0; }
.site-footer a { text-decoration: none; font-size: 0.925em; color: var(--color-text); }
.site-footer a:hover { color: var(--color-primary); text-decoration: underline; }
.site-footer .social { display: flex; flex-wrap: wrap; gap: var(--space-40); }
.site-footer .social a { color: var(--color-text-muted); }

.footer-bottom {
  border-top: 1px solid var(--color-border);
  padding-block-start: var(--space-40);
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: var(--space-30) var(--space-50);
  font-size: var(--size-tiny); color: var(--color-text-muted);
}
.footer-bottom p { margin: 0; }

/* Legacy Shortcodes-Ultimate grid, used by old post content. */
.su-row { display: grid; gap: var(--space-50); grid-template-columns: 1fr; margin-block: var(--space-50); }
@media (min-width: 48rem) {
  .su-row { grid-template-columns: repeat(6, 1fr); }
  .su-col-1-1 { grid-column: span 6; }
  .su-col-1-2 { grid-column: span 3; }
  .su-col-1-3 { grid-column: span 2; }
  .su-col-2-3 { grid-column: span 4; }
  .su-col-1-4 { grid-column: span 1; }
  .su-col-3-4 { grid-column: span 4; }
}

/* ------------------------------------------------------- account & forms */

.narrow { max-width: var(--content-narrow); }

/* Checkout runs as ONE column at ONE width.
   The form carried .form-wide's 32rem cap while the order summary above it and
   the trust panels below ran to the 42rem page width, so the page stacked
   three different right edges down its length. Everything now lines up with
   the form, which is the element whose width is actually load-bearing —
   32rem is a comfortable measure for labelled inputs, and widening it to match
   the panels would have been the wrong direction. */
.checkout-col { max-width: 32rem; }
.checkout-foot {
  display: grid; gap: var(--space-50);
  margin-block-start: var(--space-60);
}
.form { display: grid; gap: var(--space-30); max-width: 26rem; }
.form label { font-weight: 600; font-size: 0.9em; }
.form input,
.form select,
.form textarea {
  font: inherit; padding: 0.7rem var(--space-40);
  border: 1px solid var(--color-border-strong); border-radius: var(--radius-sm);
  background: var(--color-surface); color: var(--color-text);
  inline-size: 100%; box-sizing: border-box;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.form input:hover,
.form select:hover,
.form textarea:hover { border-color: var(--color-text-muted); }
.form input:focus-visible,
.form select:focus-visible,
.form textarea:focus-visible {
  border-color: var(--color-primary); box-shadow: var(--ring-soft); outline: none;
}
.form textarea { resize: vertical; min-block-size: 4.5rem; }
.form input[readonly] { background: var(--color-surface-2); color: var(--color-text-muted); cursor: not-allowed; }
.form button { justify-self: start; margin-block-start: var(--space-30); }

/* The checkout form carries six fields, not one — it needs the extra width. */
.form-wide { max-width: 32rem; }
.billing {
  border: 1px solid var(--color-border); border-radius: var(--radius);
  padding: var(--space-50); background: var(--color-surface);
}
.billing legend { font-weight: 700; padding-inline: var(--space-30); }
.billing > * + * { margin-block-start: var(--space-40); }
.billing label { display: block; margin-block-end: var(--space-20); font-weight: 600; font-size: 0.9em; }
.row-2 { display: grid; gap: var(--space-40); grid-template-columns: 1fr 1fr; }
@media (max-width: 30rem) { .row-2 { grid-template-columns: 1fr; } }

.error {
  background: var(--color-danger-soft);
  border: 1px solid color-mix(in srgb, var(--color-danger) 35%, transparent);
  border-inline-start: 3px solid var(--color-danger);
  color: var(--color-danger);
  padding: var(--space-40); border-radius: var(--radius);
}
.notice {
  background: var(--color-accent-soft);
  border: 1px solid color-mix(in srgb, var(--color-primary) 25%, transparent);
  border-radius: var(--radius); padding: var(--space-50);
  margin-block: var(--space-50);
}
.notice h2 { margin-block-start: 0; font-size: var(--size-m); }
hr { border: 0; border-top: 1px solid var(--color-border); margin-block: var(--space-60); }

/* --------------------------------------------------- account: subscriptions */

.account-actions { display: flex; flex-wrap: wrap; gap: var(--space-30); }

.sub-list { display: grid; gap: var(--space-50); margin-block: var(--space-50); }
.sub-card { display: grid; gap: var(--space-40); }
.sub-card-head {
  display: flex; flex-wrap: wrap; gap: var(--space-30);
  align-items: start; justify-content: space-between;
}
.sub-card-head h2 { font-size: var(--size-m); margin: 0; }
.sub-card-head p { margin: var(--space-10) 0 0; }

/* Label/value pairs rather than a table: three facts do not need a grid
   header, and this reflows to one column on a phone without scrolling. */
.sub-facts {
  display: grid; gap: var(--space-20) var(--space-50);
  grid-template-columns: auto 1fr;
  margin: 0; font-size: 0.95em;
}
.sub-facts dt { color: var(--color-text-muted); }
.sub-facts dd { margin: 0; font-weight: 600; }

/* Cancel is a text button, not a red danger button. It is a legitimate thing
   for a customer to want, and dressing it up as destructive to discourage
   clicking is a dark pattern — the promise on the pricing page is that
   cancelling is easy. */
.sub-cancel {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-30);
  padding-block-start: var(--space-30);
  border-top: 1px solid var(--color-border);
}

.sub-invoices summary {
  cursor: pointer; font-size: var(--size-tiny); font-weight: 650;
  color: var(--color-text-muted);
}
.sub-invoices summary:hover { color: var(--color-primary); }
.sub-invoices .table-wrap { margin-block-start: var(--space-30); }

/* ------------------------------------------------------- cart & checkout */

/*
 * Progress rail.
 *
 * Four steps, always all four visible. Hiding the remaining steps to make the
 * flow "feel shorter" backfires: the buyer cannot tell whether they are two
 * clicks or ten from being charged, and the safe assumption is ten.
 */
/* Sized to fit all four steps on one line inside the 32rem checkout column —
   a progress bar that wraps onto two rows stops reading as a progress bar.
   flex-wrap stays as the fallback for a genuinely narrow phone. */
.progress {
  display: flex; flex-wrap: wrap; gap: var(--space-20) var(--space-30);
  list-style: none; padding: 0;
  margin: 0 0 var(--space-50);
  counter-reset: prog;
  font-size: var(--size-tiny);
}
.progress li {
  counter-increment: prog;
  display: flex; align-items: center; gap: 0.4em;
  color: var(--color-text-muted);
}
.progress li::before {
  content: counter(prog);
  display: grid; place-items: center;
  flex: none;
  inline-size: 1.4rem; block-size: 1.4rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-border-strong);
  font-weight: 700; font-size: 0.75rem;
  background: var(--color-surface);
}
/* Chevron between steps, suppressed after the last one. */
.progress li::after {
  content: ""; inline-size: 0.85rem; block-size: 1px; flex: none;
  background: var(--color-border-strong);
  margin-inline-start: var(--space-10);
}
.progress li:last-child::after { display: none; }
.progress li[data-state="done"] { color: var(--color-success); }
.progress li[data-state="done"]::before {
  content: "✓";
  background: var(--color-success); border-color: var(--color-success); color: #fff;
}
.progress li[data-state="current"] { color: var(--color-text); font-weight: 650; }
.progress li[data-state="current"]::before {
  background: var(--color-primary); border-color: var(--color-primary); color: #fff;
}
@media (prefers-color-scheme: dark) {
  .progress li[data-state="current"]::before { color: #08121f; }
  .progress li[data-state="done"]::before { color: #06170f; }
}

/* Items on the left, a summary that stays put on the right. */
.checkout-layout { display: grid; gap: var(--space-60); align-items: start; }
@media (min-width: 60rem) {
  .checkout-layout { grid-template-columns: minmax(0, 1.6fr) minmax(19rem, 1fr); }
}
.order-summary {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
  padding: var(--space-50);
  display: grid; gap: var(--space-40);
}
@media (min-width: 60rem) { .order-summary { position: sticky; top: 5.5rem; } }
.order-summary h2 { font-size: var(--size-xs); margin: 0; letter-spacing: normal; }
/* Inside the summary card the totals list is already framed by the card. */
.order-summary .totals {
  margin: 0; max-width: none; padding: 0;
  background: none; border: 0;
}
.order-summary .pay-marks { justify-content: flex-start; }

.order-review { display: grid; gap: var(--space-40); margin-block-end: var(--space-50); }
.order-review h2 { font-size: var(--size-xs); margin: 0; letter-spacing: normal; }
.order-review .totals { margin: 0; max-width: none; }
.order-review > p { margin: 0; }

.checklist.small li { font-size: var(--size-tiny); }

/* The receipt block on the thank-you page. The tick is doing real work here:
   it is the confirmation the buyer came to this page to see. */
.receipt {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
  padding: var(--space-60) var(--space-50);
  text-align: center;
  margin-block-end: var(--space-50);
}
.receipt-mark {
  display: inline-grid; place-items: center;
  inline-size: 3.5rem; block-size: 3.5rem;
  border-radius: var(--radius-pill);
  background: var(--color-success-soft); color: var(--color-success);
  font-size: 1.75rem;
  margin-block-end: var(--space-40);
}
.receipt-mark.is-pending { background: var(--color-warning-soft); color: var(--color-warning); }
.receipt h1 { font-size: var(--size-l); }
.receipt .btn { margin-block-start: var(--space-30); }

.cart-item { display: flex; align-items: center; gap: var(--space-40); }
.cart-thumb img {
  width: 72px; height: 54px; object-fit: cover; object-position: top center;
  border-radius: var(--radius-sm); border: 1px solid var(--color-border); display: block;
}
.cart-item a { font-weight: 600; text-decoration: none; color: var(--color-text); }
.cart-item a:hover { color: var(--color-primary); }
.linkbtn {
  background: none; border: 0; padding: 0; font: inherit;
  color: var(--color-text-muted); text-decoration: underline; cursor: pointer;
  font-size: var(--size-tiny);
}
.linkbtn:hover { color: var(--color-danger); }

.coupon-form {
  display: flex; gap: var(--space-30); align-items: end; flex-wrap: wrap;
  margin-block: var(--space-50);
}
.coupon-form label { display: block; font-size: 0.9em; font-weight: 600; margin-block-end: var(--space-20); }
.coupon-form input {
  font: inherit; padding: 0.7rem var(--space-40);
  border: 1px solid var(--color-border-strong); border-radius: var(--radius-sm);
  background: var(--color-surface); color: var(--color-text);
}
.coupon-form input:focus-visible { border-color: var(--color-primary); box-shadow: var(--ring-soft); outline: none; }

.totals {
  display: grid; grid-template-columns: 1fr auto;
  gap: var(--space-30) var(--space-50);
  max-width: 24rem; margin-block: var(--space-50);
  padding: var(--space-50);
  background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: var(--radius);
}
.totals dt { color: var(--color-text-muted); }
.totals dd { margin: 0; text-align: right; font-weight: 600; }
.totals .grand {
  font-size: var(--size-s); font-weight: 700; color: var(--color-text);
  border-top: 1px solid var(--color-border); padding-block-start: var(--space-30);
}
.ok { color: var(--color-success); }

.checkout-items {
  list-style: none; padding: var(--space-40); display: grid; gap: var(--space-30);
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius);
}
.checkout-items li { display: flex; justify-content: space-between; gap: var(--space-40); }

.methods {
  border: 1px solid var(--color-border); border-radius: var(--radius);
  padding: var(--space-50); background: var(--color-surface);
}
.methods legend { font-weight: 700; padding-inline: var(--space-30); }
/* Each method is a full-width hit target, not a 13px radio dot. */
.method {
  display: flex; align-items: center; gap: var(--space-40);
  padding: var(--space-40);
  border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  cursor: pointer; font-weight: 600;
  transition: border-color var(--transition), background var(--transition);
}
.method + .method { margin-block-start: var(--space-30); }
.method:hover { border-color: var(--color-border-strong); background: var(--color-surface-2); }
.method:has(input:checked) {
  border-color: var(--color-primary);
  background: var(--color-accent-soft);
  box-shadow: var(--ring-soft);
}
.method input { accent-color: var(--color-primary); inline-size: 1.1rem; block-size: 1.1rem; }

/* --------------------------------------------------------------- contact
 *
 * The form asks two topic-specific questions — a company for a business
 * inquiry, an order number for a support request — and asking both of every
 * sender is how a four-field form becomes a six-field form nobody finishes.
 *
 * They are revealed by the topic select with :has(), so the page still needs
 * no JavaScript. The whole block is inside @supports selector(:has(*)): where
 * :has() is unsupported the rules never apply, both fields stay visible, and
 * the form is merely longer rather than missing an input the sender can never
 * reach. Never hide a field by default and reveal it conditionally — that
 * fails the wrong way round.
 */

.contact-head { padding-block-end: 0; max-width: var(--content-narrow); }

.contact-grid {
  display: grid; gap: var(--space-60);
  grid-template-columns: minmax(0, 1fr) 20rem;
  align-items: start;
}
@media (max-width: 60rem) {
  .contact-grid { grid-template-columns: 1fr; }
}

/* Fills its column: the 32rem cap from .form-wide is for a full-width page. */
.contact-form { max-width: none; gap: var(--space-40); }
.contact-form .error { margin-block-end: var(--space-40); }

.field { display: grid; gap: var(--space-20); }
.field-note { font-size: var(--size-tiny); color: var(--color-text-muted); }
.field-optional { font-weight: 400; color: var(--color-text-muted); }
.topic-hint {
  display: flex; align-items: start; gap: var(--space-20);
  margin: 0; font-size: var(--size-tiny); color: var(--color-text-muted);
}
.topic-hint .icon { flex: none; opacity: 0.6; }

@supports selector(:has(*)) {
  .contact-form .field-company,
  .contact-form .field-order,
  .contact-form .topic-hint { display: none; }

  .contact-form:has(#topic option[value="business"]:checked) .field-company { display: grid; }
  .contact-form:has(#topic option[value="support"]:checked) .field-order { display: grid; }

  .contact-form:has(#topic option[value="query"]:checked) .topic-hint-query,
  .contact-form:has(#topic option[value="support"]:checked) .topic-hint-support,
  .contact-form:has(#topic option[value="business"]:checked) .topic-hint-business,
  .contact-form:has(#topic option[value="general"]:checked) .topic-hint-general { display: flex; }
}

.contact-aside { display: grid; gap: var(--space-40); }
.contact-aside h2 { font-size: var(--size-s); margin-block-start: 0; }
.contact-steps {
  margin: 0; padding-inline-start: 1.1rem;
  display: grid; gap: var(--space-30);
  font-size: var(--size-tiny); color: var(--color-text-muted);
}

.contact-done { text-align: center; padding-block: var(--space-50); }
.contact-done-mark {
  display: inline-grid; place-items: center;
  inline-size: 3.5rem; block-size: 3.5rem; margin-block-end: var(--space-40);
  border-radius: 50%; background: var(--color-success); color: #fff;
}
.contact-done-mark .icon { inline-size: 1.75rem; block-size: 1.75rem; stroke-width: 3; }
.contact-done-links {
  display: flex; gap: var(--space-30); justify-content: center; flex-wrap: wrap;
  margin-block-start: var(--space-50);
}
