/* ==========================================================================
   Fitness coaching site.
   Visual direction follows the jeffnippard.com reference: neutral grey field,
   near-black type, white pills, mono uppercase micro-labels, one question
   per screen. Fonts are free equivalents, not the originals.
   ========================================================================== */

:root {
  --grey:   #b3b3b3;   /* page field          */
  --dark:   #1c1c1c;   /* type and dark cards */
  --light:  #ffffff;
  --muted:  #787878;
  --olive:  #4e5948;   /* accent              */
  --olive-hi: #5d6a56;
  /* The accent lightened for use ON Slate Ink. Field Olive measures 2.31:1
     against #1c1c1c and is unreadable there; this measures 8.46:1. It is the
     inverse case: on white it is only 2.01:1, so it must never be used on a
     light surface. Dark panels only. */
  --olive-light: #a8bd9d;
  /* featured plan card. Grey rather than the olive accent. White type on this
     measures 8.9:1, so it clears AA comfortably. */
  --plan-featured: #4a4a4a;
  --logo-bg: #e8e8e8;  /* the logo art's own field, so the badge blends */

  /* Secondary body text on the grey field. Sits between Slate Ink and Muted
     Grey: 5.42:1 against the field, so unlike --muted (2.11:1) it is safe for
     prose a visitor actually has to read. */
  --ink-soft: #3a3a3a;
  /* Placeholder text inside white fields. 1.88:1 by design - a placeholder is
     a hint, never content, and anything it says is repeated in a real label. */
  --placeholder: #bdbdbd;
  /* The only red in the system: validation errors. 4.87:1 on the field, and
     never the sole signal - errors also carry text saying what went wrong. */
  --danger: #7a2020;
  /* One step up from Slate Ink, for a surface that must read as raised while
     still sitting on a dark panel. */
  --dark-raised: #2a2a2a;

  /* backdrop photos, see body::before. Opacity is held down by the text-heavy
     pages, where muted captions sit straight on the field with no card behind
     them. Bleed lets the columns drift without ever exposing the edge. */
  /* Measured ceiling. At .34 the worst case body text contrast over the photo
     is 4.61:1, just clear of the 4.5:1 AA threshold. .42 drops it to 3.98:1
     and fails. Re-measure before raising this, do not eyeball it. */
  --photo-opacity: .34;
  --photo-w: clamp(210px, 42vw, 620px);
  /* Bleed has to absorb three things at once: the idle drift (up to 7px), the
     15px reserved by scrollbar-gutter: stable on html, and subpixel rounding.
     At 26px that left ~4px of margin and grey leaked along the right edge.
     If you ever drop scrollbar-gutter, this can come back down. */
  --photo-bleed: 48px;
  /* Pushes the right column further off screen so its outer fade lands beyond
     the edge, leaving stronger photo where the grey was showing through.
     CSS cm is an absolute unit, 1cm = 37.8px, not a physical centimetre.
     Raise to soften less, lower to soften more. */
  --photo-shift-r: 1cm;

  --line: rgba(28, 28, 28, .16);
  --sheet: rgba(255, 255, 255, .55);
  /* ambient, resting shadow for cards; hover states lift into a stronger,
     more diffuse shadow defined alongside each component */
  --shadow-card: 0 2px 10px rgba(28, 28, 28, .08);

  --max: 1120px;
  /* Radius scale. 16px is the card default; the smaller steps exist because a
     22px checkbox or a 64px thumbnail given a card's radius reads as a blob.
     Two values sit deliberately off this scale and are commented where used:
     the logo badge (14px, tuned to the artwork's own corner) and textareas
     (20px, so a tall box does not read as a stretched pill). */
  --radius-xs: 8px;
  --radius-sm: 12px;
  --radius: 16px;
  --pill: 9999px;

  /* Lead paragraph under a heading. One value for the whole site: the hero and
     the product pages used to carry two separate clamps whose upper bounds
     differed by half a pixel, which is drift rather than a decision. Leads
     that simply inherit body size (results, checkout) are left alone. */
  --fs-lead: clamp(1rem, 1.7vw, 1.15rem);

  --sans: "Inter Tight", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* expo easing, the reference leans on this heavily */
  --out:    cubic-bezier(.16, 1, .3, 1);
  --in-out: cubic-bezier(.87, 0, .13, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  /* Reserve the scrollbar gutter so content does not shift sideways when a
     page turns out to be scrollable. No effect where scrollbars overlay. */
  scrollbar-gutter: stable;
}

body {
  margin: 0;
  /* Column layout so full height sections can take exactly what the footer
     leaves, measured rather than guessed. */
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background-color: var(--grey);
  /* dot grid, same idea as the reference, drawn from scratch */
  background-image: radial-gradient(circle at center, rgba(28,28,28,.13) 1.1px, transparent 1.2px);
  background-size: 22px 22px;
  color: var(--dark);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.5;
  letter-spacing: -0.014em;
  -webkit-font-smoothing: antialiased;
}

/* Photo backdrop, every page. Two fixed columns pinned to the outer edges,
   behind all content (z-index -1 keeps them above the body's own field but
   under the in-flow header/main/footer). Purely decorative, so pseudo-elements
   rather than markup, which also keeps them out of the accessibility tree.
   Each is masked twice: a radial that dissolves the inner side into the grey,
   and a linear that fades the bottom out so nothing ends on a hard edge. */
body::before, body::after {
  content: "";
  position: fixed;
  top: calc(var(--photo-bleed) * -1);
  bottom: calc(var(--photo-bleed) * -1);
  width: calc(var(--photo-w) + var(--photo-bleed));
  z-index: -1;
  pointer-events: none;
  background-size: cover;
  background-repeat: no-repeat;
  filter: grayscale(.4) contrast(.94);
  opacity: var(--photo-opacity);
  /* scale answers the pointer, translate is the idle drift. Separate transform
     properties rather than one transform string, so the animation and the
     pointer never overwrite each other. */
  transition: opacity 1.4s var(--out), scale .5s var(--out), transform-origin .5s var(--out);
  -webkit-mask-composite: source-in;
          mask-composite: intersect;
}
/* Only the first page of a visit starts from nothing. app.js drops the class on
   the next frame to run the fade, and leaves it off for every later page, which
   is what stopped the backdrop re-fading on each navigation. */
.photo-intro body::before, .photo-intro body::after { opacity: 0; }

body::before {
  left: calc(var(--photo-bleed) * -1);
  background-image: url("../img/hero-left.webp");
  background-position: 62% center;
  /* grow from the outer edge, so the image expands inward towards the cursor */
  transform-origin: 0% var(--photo-origin-y, 50%);
  scale: var(--photo-scale-l, 1);
  animation: photoDriftL 19s ease-in-out infinite alternate;
  /* Fades on every side. The outer edge used to run at full strength into the
     screen edge and simply get clipped, which read as a hard cutout. The first
     stop sits just inside the bleed so the fade finishes on screen. */
  -webkit-mask-image:
    linear-gradient(to right, transparent 3%, #000 22%, #000 60%, transparent 100%),
    linear-gradient(to bottom, transparent 2%, #000 14%, #000 56%, transparent 96%);
  mask-image:
    linear-gradient(to right, transparent 3%, #000 22%, #000 60%, transparent 100%),
    linear-gradient(to bottom, transparent 2%, #000 14%, #000 56%, transparent 96%);
}
body::after {
  /* Shifted out by --photo-shift-r but deliberately NOT widened. Both columns
     must stay the same size, because background-size: cover derives the figure's
     scale from the box. Widening this one made the right figure render 10%
     larger than the left at some viewports. */
  right: calc((var(--photo-bleed) + var(--photo-shift-r)) * -1);
  background-image: url("../img/hero-right.webp");
  /* Anchored right so the image edge always meets the screen edge. At wide and
     at narrow viewports the element is a different aspect to the photo, and any
     value below 100% lets cover crop the right side away, which left a gap
     against the screen edge and hid the subject. The subject is framed flush
     right in the file to suit this. */
  background-position: 100% center;
  transform-origin: 100% var(--photo-origin-y, 50%);
  scale: var(--photo-scale-r, 1);
  animation: photoDriftR 23s ease-in-out infinite alternate;
  /* mirror of the left column: soft on the outer edge as well as the inner */
  -webkit-mask-image:
    linear-gradient(to left, transparent 3%, #000 22%, #000 60%, transparent 100%),
    linear-gradient(to bottom, transparent 2%, #000 14%, #000 56%, transparent 96%);
  mask-image:
    linear-gradient(to left, transparent 3%, #000 22%, #000 60%, transparent 100%),
    linear-gradient(to bottom, transparent 2%, #000 14%, #000 56%, transparent 96%);
}
/* idle drift, kept well inside --photo-bleed so no edge is ever uncovered */
@keyframes photoDriftL { from { translate: -9px 7px; } to { translate: 8px -10px; } }
@keyframes photoDriftR { from { translate: 9px -8px; } to { translate: -7px 11px; } }

img, svg { max-width: 100%; height: auto; display: block; }

h1, h2, h3 { margin: 0; line-height: 1.05; letter-spacing: -0.035em; font-weight: 700; }

/* Title Case on the main page headings, in both languages.
   Standard Latvian orthography capitalises only the first word of a heading,
   so this is a deliberate house-style choice rather than a grammatical one:
   the site owner wants the two languages to look the same. Applies to the
   page-level h1 only - section headings stay sentence case in both. */
.hero h1,
.results-head h1,
.product-hero h1,
.showcase-text h1,
.legal-sheet h1 { text-transform: capitalize; }
p { margin: 0; }
a { color: inherit; }

:focus-visible { outline: 2px solid var(--dark); outline-offset: 3px; }

.wrap { width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 24px; }

/* main takes the space the footer does not, at every width */
body > main { flex: 1 0 auto; display: flex; flex-direction: column; }
body > .site-footer { flex: none; }

.skip-link { position: absolute; left: -9999px; top: 0; background: var(--dark); color: var(--light); padding: 10px 16px; z-index: 100; }
.skip-link:focus { left: 8px; top: 8px; }

/* mono micro-label, used for eyebrows, counters, button text */
.mono {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* ---------- Header ---------- */

.site-header { position: absolute; top: 0; left: 0; right: 0; z-index: 50; padding: 18px 0; }
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; gap: 16px; }

/* squircle logo badge */
.brand {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  /* the badge takes the logo art's own field colour so the opaque PNG has no
     visible edge inside the rounded square */
  background: var(--logo-bg);
  /* Off-scale on purpose: tuned to the logo artwork's own corner so the
     opaque PNG has no visible edge inside the rounded square. */
  border-radius: 14px;
  overflow: hidden;
  text-decoration: none;
  flex: none;
  transition: transform .4s var(--out);
}
.brand:hover { transform: scale(1.06); }
.brand img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---------- Language switch ---------- */

.lang { display: inline-flex; background: var(--dark); border-radius: var(--pill); padding: 4px; gap: 2px; }
.lang button {
  appearance: none; border: 0; cursor: pointer;
  font-family: var(--mono); font-size: 12px; text-transform: uppercase;
  background: transparent; color: rgba(255,255,255,.6);
  padding: 7px 14px; border-radius: var(--pill); min-width: 46px;
  transition: background .4s var(--out), color .25s ease;
}
.lang button:hover { color: var(--light); }
.lang button[aria-pressed="true"] { background: var(--light); color: var(--dark); }

/* ---------- Pills ---------- */

.pill {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  font-family: var(--mono); font-size: 14px; text-transform: uppercase;
  background: var(--light); color: var(--dark);
  border: 0; border-radius: var(--pill);
  padding: 15px 28px; cursor: pointer; text-decoration: none;
  transition: transform .5s var(--out), background .3s ease, color .3s ease, box-shadow .5s var(--out);
}
.pill:hover { transform: translateY(-2px); box-shadow: 0 8px 22px rgba(28,28,28,.16); }
.pill:active { transform: translateY(0); }
.pill[disabled] { opacity: .4; pointer-events: none; }

.pill-dark { background: var(--dark); color: var(--light); }
.pill-olive { background: var(--olive); color: var(--light); }
.pill-olive:hover { background: var(--olive-hi); }

.pill-lg { padding: 17px 40px; font-size: 15px; }

/* a secondary way out, present but not competing with Continue */
.pill-sm { padding: 11px 22px; font-size: 12px; }
.pill-quiet {
  background: transparent;
  color: var(--muted);
  box-shadow: inset 0 0 0 1.5px rgba(28, 28, 28, .22);
}
.pill-quiet:hover {
  background: var(--light); color: var(--dark);
  box-shadow: inset 0 0 0 1.5px transparent, 0 6px 18px rgba(28, 28, 28, .12);
}
.pill-quiet[aria-pressed="true"] { background: var(--dark); color: var(--light); box-shadow: none; }

/* ghost text link, "← back" */
.back-link {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  font-family: var(--mono); font-size: 12px; text-transform: uppercase;
  color: var(--muted); padding: 10px 14px; border-radius: var(--pill);
  transition: color .3s ease;
}
.back-link:hover { color: var(--dark); }

/* ---------- Landing ---------- */

.hero { flex: 1 0 auto; display: grid; place-items: center; text-align: center; padding: 120px 0 80px; }
.hero-inner { max-width: 860px; margin: 0 auto; }

.eyebrow { color: var(--muted); margin-bottom: 26px; }

.hero h1 { font-size: clamp(2.4rem, 6.2vw, 4.6rem); font-weight: 700; }
/* the payoff line earns the system's one accent color, per the One Accent Rule */
.hero h1 .hero-title-accent { color: var(--olive); }
.hero .sub { margin: 24px auto 0; max-width: 58ch; color: var(--ink-soft); font-size: var(--fs-lead); }
.hero .cta { margin-top: 44px; display: flex; flex-direction: column; align-items: center; gap: 18px; }
.hero-note { color: var(--muted); }

/* ---------- Quiz, one question per screen ---------- */

/* main itself, so it fills what the footer leaves without a magic number */
.quiz-stage {
  justify-content: center;
  padding: 120px 0 56px;
}

.quiz-card { width: 100%; max-width: 620px; margin: 0 auto; text-align: center; }

/* enter / exit motion between questions */
@keyframes qIn  { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.quiz-card.entering { animation: qIn .5s var(--out) both; }
.quiz-card.leaving { opacity: 0; transform: translateY(-10px); transition: opacity .18s ease, transform .18s ease; }

.q-meta { color: var(--muted); margin-bottom: 20px; }
.q-meta .sep { opacity: .5; margin: 0 8px; }

.q-title { font-size: clamp(1.7rem, 4.2vw, 2.7rem); font-weight: 700; overflow-wrap: break-word; }
.q-hint { margin-top: 12px; color: var(--muted); font-size: .95rem; }

.q-body { margin-top: 34px; display: flex; flex-direction: column; gap: 10px; align-items: center; }

/* the stack of answers, centred as a block so every pill is the same width */
.opt-list { width: 100%; display: flex; flex-direction: column; gap: 10px; align-items: stretch; }

/* option pills */
.opt {
  width: 100%;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  font-family: var(--mono); font-size: 13px; text-transform: uppercase; text-align: center;
  background: var(--light); color: var(--dark);
  border: 2px solid transparent; border-radius: var(--pill);
  padding: 15px 24px; cursor: pointer;
  transition: transform .5s var(--out), background .25s ease, color .25s ease, border-color .25s ease, box-shadow .5s var(--out);
}
.opt:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(28,28,28,.15); }
.opt[aria-pressed="true"] { background: var(--dark); color: var(--light); }
.opt.is-locked { opacity: .4; cursor: not-allowed; }
.opt.is-locked:hover { transform: none; box-shadow: none; }

/* text and number entry, pill shaped to match */
.field {
  width: 100%; max-width: 420px;
  font-family: var(--mono); font-size: 15px; color: var(--dark);
  background: var(--light);
  border: 0;
  border-radius: var(--pill);
  padding: 17px 26px; text-align: center;
  box-shadow: 0 1px 2px rgba(28, 28, 28, .05);
  transition: box-shadow .4s var(--out);
}
.field::placeholder { color: var(--placeholder); text-transform: none; }
.field:hover { box-shadow: 0 5px 16px rgba(28, 28, 28, .10); }

/* Pointer focus gets a soft halo rather than a hard rule against the edge. */
.field:focus {
  outline: none;
  box-shadow: 0 0 0 3px rgba(28, 28, 28, .13), 0 8px 22px rgba(28, 28, 28, .12);
}
/* Keyboard focus gets a crisp ring, held off the pill by a gap in the page
   colour. Softer is fine for the mouse, but this one has to be unmissable. */
.field:focus-visible {
  box-shadow: 0 0 0 2px var(--grey), 0 0 0 4px var(--dark), 0 8px 22px rgba(28, 28, 28, .14);
}

textarea.field {
  /* Off-scale on purpose: a tall box at the pill radius reads as a
     stretched capsule rather than a field. */
  border-radius: 20px;
  min-height: 104px; resize: vertical;
  text-align: left; line-height: 1.5;
  padding: 16px 22px;
}

.field-unit { font-family: var(--mono); font-size: 12px; text-transform: uppercase; color: var(--muted); }

.slider-ends { display: flex; justify-content: space-between; gap: 16px; margin-top: 14px; color: var(--muted); }

/* ---------- Pill slider ----------
   Track and thumb are both pills. Tick alignment: the thumb centre travels
   from half-a-thumb in to half-a-thumb from the end, so the tick row is inset
   by (thumb 44 / 2) - (tick 28 / 2) = 8px. That holds at any track width. */

.slider-wrap { width: 100%; max-width: 420px; margin: 0 auto; }

.slider-readout {
  font-size: clamp(3rem, 9vw, 4rem);
  font-weight: 700; line-height: 1; letter-spacing: -0.045em;
  transition: color .25s ease;
}
.slider-readout.is-empty { color: var(--muted); }
.slider-unit { color: var(--muted); margin-top: 8px; margin-bottom: 22px; }

.slider {
  -webkit-appearance: none; appearance: none;
  display: block; width: 100%; height: 56px;
  background: transparent; cursor: pointer; margin: 0;
}
.slider:focus { outline: none; }
.slider:focus-visible::-webkit-slider-runnable-track { outline: 2px solid var(--dark); outline-offset: 3px; }
.slider:focus-visible::-moz-range-track { outline: 2px solid var(--dark); outline-offset: 3px; }

.slider::-webkit-slider-runnable-track {
  height: 56px; border-radius: var(--pill); background: var(--light);
}
.slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 44px; height: 44px; margin-top: 6px;
  border: 0; border-radius: var(--pill); background: var(--dark);
  transition: transform .35s var(--out);
}
.slider:hover::-webkit-slider-thumb { transform: scale(1.07); }
.slider:active::-webkit-slider-thumb { transform: scale(.96); }

.slider::-moz-range-track {
  height: 56px; border-radius: var(--pill); background: var(--light);
}
.slider::-moz-range-thumb {
  width: 44px; height: 44px;
  border: 0; border-radius: var(--pill); background: var(--dark);
  transition: transform .35s var(--out);
}
.slider:hover::-moz-range-thumb { transform: scale(1.07); }

.slider-ticks { display: flex; justify-content: space-between; padding: 0 8px; margin-top: 10px; }
.slider-tick {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  width: 28px; padding: 6px 0; border-radius: var(--pill);
  font-family: var(--mono); font-size: 12px; color: var(--muted);
  transition: color .25s ease;
}
.slider-tick:hover { color: var(--dark); }
.slider-tick[aria-pressed="true"] { color: var(--dark); font-weight: 500; }

.followup { width: 100%; max-width: 420px; margin: 0 auto; display: flex; flex-direction: column; gap: 10px; align-items: center; }

.q-actions { margin-top: 30px; display: flex; flex-direction: column; align-items: center; gap: 6px; }

.error {
  margin-top: 16px;
  font-family: var(--mono); font-size: 12px; text-transform: uppercase;
  color: var(--danger);
}

/* progress rail at the very top */
.rail { position: fixed; top: 0; left: 0; right: 0; height: 10px; background: rgba(28,28,28,.12); z-index: 60; }
/* Scaled rather than widened. This advances on every question, so keeping it
   on the compositor instead of triggering layout each time is worth the
   slightly odd-looking full width plus scaleX(0) starting state. */
.rail-fill {
  height: 100%; width: 100%;
  transform: scaleX(0);
  transform-origin: left center;
  background: var(--dark);
  transition: transform .6s var(--out);
}

/* ---------- Results ---------- */

.results { padding: 130px 0 80px; }
.results-head { text-align: center; max-width: 760px; margin: 0 auto; }
.results-head h1 { font-size: clamp(1.9rem, 4.6vw, 3.1rem); }
.results-head .sub { margin-top: 20px; color: var(--ink-soft); }

/* Pick a plan by photo: the same tilting cover art the plan pages use, each
   one a direct link to its plan, name and price captioned below. */
/* Three across only while there is room for it. Held at three columns down to
   phone widths the tiles collapse to ~80px, which is narrower than the price
   caption under them and far too small for the cover art to read at all. */
.plan-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 52px; }

@media (max-width: 700px) {
  .plan-tiles { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 460px) {
  .plan-tiles {
    grid-template-columns: 1fr;
    max-width: 320px;
    margin-inline: auto;
    gap: 26px;
  }
}
.plan-tiles .tilt {
  display: block; text-decoration: none; color: inherit;
  transition: transform .6s var(--out);
  /* picture and caption fade up together as one unit, each tile a beat behind the last */
  animation: qIn 1.1s var(--out) both;
}
.plan-tiles .tilt:nth-child(2) { animation-delay: .18s; }
.plan-tiles .tilt:nth-child(3) { animation-delay: .36s; }
.plan-tiles .tilt:hover { transform: translateY(-4px); }
.plan-tiles .tilt:focus-visible { outline: 3px solid var(--grey); outline-offset: 3px; border-radius: var(--radius); }

.tile-name { margin-top: 18px; margin-left: 6px; color: var(--muted); font-size: 12px; font-weight: 600; }
.tile-price { margin-top: 4px; margin-left: 6px; font-size: 1.45rem; font-weight: 700; letter-spacing: -0.035em; }
/* only on fixed-term plans, where the amount alone would understate the cost */
.tile-price-meta { margin-top: 2px; margin-left: 6px; font-size: 11px; color: var(--muted); }
/* the cheaper alternative route, quieter than the headline price but present */
.tile-price-alt { margin-top: 3px; margin-left: 6px; font-size: 11px; color: var(--dark); opacity: .78; }

/* ---------- landing: the three plans under the hero ---------- */

.home-plans { padding: 0 0 96px; }
.home-plans .wrap, .home-plans > * { max-width: var(--max); margin-inline: auto; padding-inline: 24px; }
.home-plans-top { text-align: center; max-width: 640px; margin-bottom: 4px; }
.home-plans-top h2 { font-size: clamp(1.6rem, 4vw, 2.2rem); }
.home-plans-top .sub { color: var(--dark); margin-top: 12px; }
.home-plans .plan-tiles { margin-top: 30px; }
.home-plans-cta { text-align: center; margin-top: 38px; }

/* A locked card reads as locked: pulled down and desaturated so it is clearly
   behind something, while staying legible enough to be worth wanting. Hover
   lifts it part of the way back, which signals the card is still clickable
   without pretending it is unlocked. */
.tilt.is-locked .tilt-card img {
  filter: grayscale(.75) brightness(.5) contrast(.95);
  transition: filter .5s var(--out);
}
.tilt.is-locked:hover .tilt-card img { filter: grayscale(.5) brightness(.66) contrast(.95); }

.tilt-lock {
  position: absolute; top: 10px; right: 10px;
  /* room for the longer message without crowding the card edges */
  max-width: calc(100% - 20px);
  display: inline-flex; align-items: center; gap: 6px;
  /* the documented label size - the message is the point of the badge, so it
     is not shrunk to fit; it fits at 12px on the narrowest card */
  font-size: 12px; text-transform: uppercase; letter-spacing: .02em;
  line-height: 1.2;
  background: rgba(28, 28, 28, .86);
  color: var(--light);
  border-radius: var(--pill);
  padding: 6px 12px 6px 10px;
  backdrop-filter: blur(3px);
  z-index: 3;
}
.tilt-lock-icon { display: inline-flex; flex: none; opacity: .9; }

/* Takes the slot the price would occupy, so the cards stay the same height
   whether they are locked or not. */
.tile-locked {
  margin-top: 6px; margin-left: 6px;
  font-size: 11px; text-transform: uppercase;
  color: var(--muted);
}

@media (max-width: 560px) {
  .home-plans { padding-bottom: 64px; }
  .home-plans > * { padding-inline: 18px; }
}

/* answers summary */
.summary { margin-top: 88px; }
.summary-top { text-align: center; }
.summary h2 { font-size: 1.5rem; }
.summary-note { color: var(--muted); margin-top: 10px; }

.summary-group { margin-top: 34px; background: var(--sheet); border-radius: var(--radius); padding: 8px 24px; }
.summary-group h3 { color: var(--muted); padding: 18px 0 12px; }

.summary-row { display: grid; grid-template-columns: minmax(220px, 44%) 1fr; gap: 20px; padding: 15px 0; border-top: 1px solid var(--line); }
/* Answers are typed by the visitor, so a single unbroken word, email or URL
   must wrap instead of widening the grid track and pushing the sheet out.
   `anywhere` rather than `break-word` because it also caps the intrinsic
   width the grid uses to size the column. */
.summary-row dt, .summary-row dd { overflow-wrap: anywhere; }
.summary-row dt { color: var(--muted); font-size: .95rem; }
.summary-row dd { margin: 0; font-weight: 600; }
.summary-actions { margin-top: 34px; text-align: center; }

.empty-state { text-align: center; background: var(--sheet); border-radius: var(--radius); padding: 48px 28px; margin-top: 52px; }
.empty-state p { color: var(--muted); margin-top: 12px; }
.empty-state .pill { margin-top: 26px; }

/* ---------- Product page, the free plan ---------- */

.product { padding: 118px 0 40px; }
.product-sheet { max-width: 820px; margin: 0 auto; }

.product-hero { text-align: center; padding-bottom: 8px; }
.product-hero h1 { font-size: clamp(2.1rem, 5.6vw, 3.4rem); }
.product-price-alt { margin-top: 8px; font-size: 12px; color: var(--dark); opacity: .78; }

.product-lead {
  margin: 22px auto 0; max-width: 54ch;
  font-size: var(--fs-lead); color: var(--ink-soft);
}
.product-cta { margin-top: 32px; display: flex; flex-direction: column; align-items: center; gap: 14px; }

.product-price { margin-top: 30px; }
.product-price-amount {
  display: block;
  font-size: clamp(2.2rem, 5vw, 3rem);
  font-weight: 700; letter-spacing: -0.04em; line-height: 1;
}
.product-price-meta { display: block; margin-top: 8px; color: var(--muted); }

/* ---------- Showcase: cover art beside the name and price ---------- */

.showcase {
  display: grid;
  /* the art takes the larger share, it is the thing being sold */
  grid-template-columns: minmax(0, 1.18fr) minmax(0, .82fr);
  gap: 48px;
  align-items: center;
}

/* The cover earns more room than the prose sheet below it, so let the showcase
   break out past the 820px column. Gated at 1060px because the break-out needs
   820 + 180 = 1000px plus the 48px wrap padding to fit; any narrower and it
   pushes the page sideways. */
@media (min-width: 1060px) {
  .showcase { margin-inline: -90px; }
}

.showcase-art { min-width: 0; }
.showcase-text { min-width: 0; }
.showcase-text h1 { font-size: clamp(1.9rem, 3.8vw, 3rem); }
.showcase-text .product-lead { margin-left: 0; max-width: 44ch; }
.showcase-text .product-cta { align-items: flex-start; }

/* the tilting cover */
.tilt {
  --rx: 0deg; --ry: 0deg; --gx: 50%; --gy: 30%;
  perspective: 1100px;
  width: 100%;
}
.tilt-inner {
  transform: rotateX(var(--rx)) rotateY(var(--ry));
  transform-style: preserve-3d;
  transition: transform .7s var(--out);
  will-change: transform;
}
/* Eased rather than tracking the pointer one-to-one. Following exactly felt
   twitchy; a short ease lets the card lag the cursor slightly and settle. */
.tilt.is-tilting .tilt-inner { transition: transform .28s var(--out); }

/* ---------- Upsell block on the download page ---------- */

.upsell { text-align: center; margin-top: 72px; }
.upsell .eyebrow { margin-bottom: 14px; }
.upsell h2 { font-size: clamp(1.5rem, 3.4vw, 2.3rem); }
.upsell-lead {
  margin: 18px auto 0;
  max-width: 62ch;
  color: var(--ink-soft);
}
/* the cover sits at reading width rather than full bleed, so the copy above
   and the card read as one column */
.upsell-card { max-width: 420px; margin: 34px auto 0; }
.upsell .product-cta { margin-top: 26px; }
.upsell-price {
  font-size: 1.45rem;
  font-weight: 700;
  letter-spacing: -0.035em;
}

/* corner label on a tile, e.g. the most popular plan */
.tilt-badge {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 2;
  padding: 4px 8px;
  border-radius: var(--pill);
  background: var(--light);
  color: var(--dark);
  /* Small on purpose. The tiles get narrow in a three column grid, and at the
     old 11px this ran to 72% of the card width and sat across the subject's
     face. Check it against the narrowest tile, not the widest. */
  font-size: 9px;
  letter-spacing: .04em;
  line-height: 1.25;
  box-shadow: 0 3px 10px rgba(0, 0, 0, .26);
  pointer-events: none;   /* the whole tile is the link */
}

.tilt-card {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  /* deliberately no dark fill: it painted before the photo arrived and read as
     a black flash. The card simply has no body until the image is decoded. */
  box-shadow: 0 28px 64px rgba(28, 28, 28, .34);
  transition: box-shadow .7s var(--out);
}
.tilt.is-tilting .tilt-card { box-shadow: 0 38px 80px rgba(28, 28, 28, .42); }
/* Fades in on decode. With the preload in the page head the image is normally
   ready before first paint, so this only ever covers a slow connection. */
.tilt-card img {
  display: block; width: 100%;
  opacity: 1;
  transition: opacity .35s var(--out);
}
.tilt-card img.is-loading { opacity: 0; transition: none; }

/* plan name across the artwork */
.tilt-caption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 74px 28px 26px;
  /* scrim, so white type holds up over any part of the photo */
  background: linear-gradient(to top, rgba(8,8,8,.86) 0%, rgba(8,8,8,.55) 42%, rgba(8,8,8,0) 100%);
  pointer-events: none;
}
.tilt-caption-text {
  display: block;
  color: var(--light);
  font-size: clamp(2.3rem, 4.9vw, 3.6rem);
  font-weight: 700;
  letter-spacing: -0.038em;
  line-height: 1.02;
  text-wrap: balance;
  text-shadow: 0 2px 18px rgba(0, 0, 0, .5);
}

/* the light, following the cursor across the surface */
.tilt-glare {
  position: absolute; inset: 0;
  /* softened: a sheen that suggests a surface, not a spotlight sweeping over it */
  background: radial-gradient(circle at var(--gx) var(--gy),
              rgba(255, 255, 255, .22), rgba(255, 255, 255, .05) 38%, rgba(255, 255, 255, 0) 68%);
  mix-blend-mode: screen;
  opacity: 0;
  transition: opacity .6s var(--out);
  pointer-events: none;
}
.tilt.is-tilting .tilt-glare { opacity: 1; }


/* food table, scrolls inside its own box on narrow screens */
.table-scroll { margin-top: 22px; overflow-x: auto; border-radius: var(--radius); background: var(--light); }
.food-table { width: 100%; border-collapse: collapse; font-size: .94rem; }
.food-table th, .food-table td { padding: 13px 16px; text-align: left; white-space: nowrap; }
.food-table thead th {
  font-family: var(--mono); font-size: 11px; text-transform: uppercase;
  font-weight: 400; color: var(--muted); border-bottom: 1px solid var(--line);
}
.food-table tbody th { font-weight: 600; }
.food-table tbody tr + tr th, .food-table tbody tr + tr td { border-top: 1px solid var(--line); }
.food-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.table-note { margin-top: 12px; color: var(--muted); }

.product-block { margin-top: 56px; }
.product-block h2 { font-size: clamp(1.3rem, 2.6vw, 1.7rem); }
.product-block > p { margin-top: 16px; max-width: 62ch; }

.feature-grid {
  margin-top: 24px;
  display: grid; gap: 14px;
  grid-template-columns: repeat(2, 1fr);
}
.feature {
  background: var(--light);
  border-radius: var(--radius);
  padding: 24px 22px;
  box-shadow: var(--shadow-card);
  transition: transform .6s var(--out), box-shadow .6s var(--out);
}
.feature:hover { transform: translateY(-3px); box-shadow: 0 14px 34px rgba(28,28,28,.14); }
.feature h3 { font-size: 1.05rem; }
.feature p { margin-top: 9px; color: var(--muted); font-size: .95rem; }

.plain-list { margin: 20px 0 0; padding: 0; list-style: none; max-width: 62ch; }
.plain-list li { position: relative; padding-left: 26px; margin-top: 12px; }
.plain-list li::before {
  content: ""; position: absolute; left: 4px; top: .62em;
  width: 8px; height: 8px; border-radius: var(--pill); background: var(--dark);
}

/* the candid section, dark so it reads as plain speaking, not fine print */
.product-honest {
  background: var(--dark); color: var(--light);
  border-radius: var(--radius); padding: 34px 32px;
}
.product-honest > p { color: rgba(255,255,255,.76); }
.product-honest .plain-list li::before { background: rgba(255,255,255,.6); }
.product-honest .plain-list li { color: rgba(255,255,255,.9); }

.product-close { text-align: center; }
.product-close > p { margin-left: auto; margin-right: auto; }

/* ---------- Legal pages ---------- */

.legal { padding: 118px 0 40px; }

.legal-sheet {
  max-width: 760px;
  margin: 0 auto;
  background: var(--sheet);
  border-radius: var(--radius);
  padding: 52px 48px 44px;
}

.legal-sheet h1 { font-size: clamp(1.8rem, 4.4vw, 2.7rem); }
.legal-updated { color: var(--muted); margin-top: 14px; }

.legal-intro {
  margin-top: 26px;
  font-size: 1.08rem;
  padding-bottom: 26px;
  border-bottom: 1px solid var(--line);
}

.legal-sheet section { margin-top: 38px; }
.legal-sheet h2 { font-size: 1.12rem; letter-spacing: -0.02em; }
.legal-sheet p { margin-top: 14px; }
.legal-sheet ul { margin: 14px 0 0; padding-left: 22px; }
.legal-sheet li { margin-top: 9px; }
/* policy text carries long URLs and an email address */
.legal-sheet p, .legal-sheet li, .legal-sheet a { overflow-wrap: anywhere; }
.legal-sheet a { text-decoration: underline; text-underline-offset: 2px; }
.legal-sheet a:hover { text-decoration-thickness: 2px; }

/* the medical disclaimer and the risk section, called out rather than buried */
.legal-important {
  background: var(--dark);
  color: var(--light);
  border-radius: var(--radius);
  padding: 30px 28px;
  margin-top: 38px;
}
.legal-important h2 { font-size: 1.2rem; }
.legal-important a { color: var(--light); }

.legal-back { margin-top: 48px; }

/* ---------- Footer ---------- */

.site-footer { padding: 34px 0 40px; }
.site-footer .wrap { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; color: var(--muted); }
.site-footer nav { display: flex; gap: 22px; }
.site-footer a { text-decoration: none; }
.site-footer a:hover { color: var(--dark); }

/* ---------- Responsive ---------- */

@media (max-width: 900px) {
  /* content goes full width here, so it lands on the backdrop photos, which
     have to give way to stay behind readable copy */
  :root { --photo-opacity: .29; }
  /* art above the name and price rather than beside it */
  .showcase { grid-template-columns: 1fr; gap: 30px; text-align: center; }
  .showcase-art { max-width: 520px; margin: 0 auto; }
  .showcase-text .product-lead { margin-left: auto; margin-right: auto; }
  .showcase-text .product-cta { align-items: center; }
  .plans { grid-template-columns: 1fr; }
  .plan-tag:empty { display: none; }
  .summary-row { grid-template-columns: 1fr; gap: 4px; }
}

@media (max-width: 560px) {
  :root { --photo-opacity: .26; }
  /* A phone column is far narrower than the photo, so a full-height box makes
     cover bind on height and crop half the figure away. Shortening the box
     lets cover bind on width instead, which shows nearly the whole frame, and
     the mask keeps doing the fading so no hard edge appears. */
  body::before, body::after { bottom: auto; height: calc(62vh + var(--photo-bleed)); }
  /* the right photo sits in the bottom corner instead, so its fades invert:
     solid along the bottom edge, dissolving upward and inward */
  body::after {
    top: auto;
    bottom: calc(var(--photo-bleed) * -1);
    /* Same soft-on-every-side treatment, flipped for a bottom-anchored block:
       the vertical fade runs upward from the bottom edge. */
    -webkit-mask-image:
      linear-gradient(to left, transparent 3%, #000 22%, #000 60%, transparent 100%),
      linear-gradient(to top, transparent 2%, #000 14%, #000 56%, transparent 96%);
    mask-image:
      linear-gradient(to left, transparent 3%, #000 22%, #000 60%, transparent 100%),
      linear-gradient(to top, transparent 2%, #000 14%, #000 56%, transparent 96%);
  }
  .wrap { padding: 0 18px; }
  body { font-size: 16px; }
  .hero { padding: 110px 0 64px; }
  .quiz-stage { padding: 104px 0 56px; }
  .opt { font-size: 12px; padding: 14px 18px; }
  /* ten ticks have to fit a narrow track, keep the thumb-centre offset in
     step: padding = (thumb 44 / 2) - (tick 22 / 2) */
  .slider-tick { width: 22px; font-size: 11px; }
  .slider-ticks { padding: 0 11px; }
  .slider-ends { font-size: 11px; }
  .hero .cta .pill { width: 100%; max-width: 420px; }
  .legal { padding: 100px 0 24px; }
  .legal-sheet { padding: 34px 22px 30px; border-radius: var(--radius-sm); }
  .legal-important { padding: 24px 20px; }
  .product { padding: 100px 0 24px; }
  .product-block { margin-top: 42px; }
  .feature-grid { grid-template-columns: 1fr; }
  .showcase-text .product-cta .pill { width: 100%; }
  .product-honest { padding: 26px 22px; }
  .product-cta .pill { width: 100%; max-width: 420px; }
}

/* ==========================================================================
   Checkout
   The form sits on white sheets like the rest of the site; the summary is the
   one Slate Ink surface, because the money is the thing the page is about and
   it needs a single anchor rather than a fourth identical white panel.
   ========================================================================== */

/* The header is position:absolute, so every page clears it with its own top
   padding. Matches .product rather than inventing a third value. */
.checkout { padding: 118px 0 92px; }

.checkout-head { max-width: 620px; margin-bottom: 34px; }
.checkout-head h1 { font-size: clamp(2.1rem, 5.6vw, 3.1rem); }
.checkout-lead { color: var(--dark); margin-top: 14px; max-width: 46ch; }

.checkout-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 366px;
  gap: 24px;
  align-items: start;
}

/* ---------- form side ---------- */

.checkout-form { display: flex; flex-direction: column; gap: 18px; min-width: 0; }

.co-panel {
  background: var(--light);
  border-radius: var(--radius);
  padding: 26px 26px 28px;
  box-shadow: var(--shadow-card);
}

.co-panel-title { font-size: 1.15rem; margin-bottom: 18px; }

.co-label { display: block; color: var(--muted); margin-bottom: 10px; }

/* The quiz field is centred and capped for one-question-per-screen. On a form
   with a label above it, left-aligned and full width is the readable shape. */
.co-panel .field { max-width: 100%; text-align: left; }

.co-hint { color: var(--muted); font-size: .92rem; margin-top: 12px; }

/* ---------- consent checkboxes ----------
   The native box is kept for semantics and keyboard use, then visually
   replaced by a square that matches the system's ink-fill selected state. */
.co-check {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: 14px;
  align-items: start;
  padding: 12px 0;
  cursor: pointer;
}
.co-check + .co-check { border-top: 1px solid var(--line); }

.co-check input {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap;
}

.co-check-box {
  width: 22px; height: 22px;
  margin-top: 1px;
  border-radius: var(--radius-xs);
  background: var(--light);
  box-shadow: inset 0 0 0 1.5px rgba(28, 28, 28, .28);
  transition: background .3s ease, box-shadow .4s var(--out);
}
/* the tick is drawn, not a glyph, so it inherits the ink colour exactly */
.co-check-box::after {
  content: "";
  display: block;
  width: 11px; height: 6px;
  margin: 5px auto 0;
  border-left: 2px solid var(--light);
  border-bottom: 2px solid var(--light);
  transform: rotate(-45deg) scale(.6);
  opacity: 0;
  transition: opacity .2s ease, transform .4s var(--out);
}
.co-check:hover .co-check-box { box-shadow: inset 0 0 0 1.5px rgba(28, 28, 28, .5); }
.co-check input:checked ~ .co-check-box {
  background: var(--dark);
  box-shadow: inset 0 0 0 1.5px var(--dark);
}
.co-check input:checked ~ .co-check-box::after { opacity: 1; transform: rotate(-45deg) scale(1); }
.co-check input:focus-visible ~ .co-check-box {
  box-shadow: 0 0 0 2px var(--light), 0 0 0 4px var(--dark);
}

.co-check-text { font-size: .95rem; line-height: 1.45; }
.co-check-text a { color: var(--dark); text-underline-offset: 3px; }

/* ---------- error and submit ---------- */

.co-error {
  margin: 0;
  background: var(--dark);
  color: var(--light);
  border-radius: var(--radius);
  padding: 16px 22px;
  font-size: .95rem;
}

/* bad ?plan=: the message plus one way out, nothing else on the page */
.co-deadend { display: flex; flex-direction: column; align-items: flex-start; gap: 22px; }

.co-submit { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 4px; }
.co-pay { min-width: 260px; }
/* aria-busy already conveys this; the dimming is only the visual half */
.co-pay.is-busy { opacity: .55; }

/* ---------- how to pay ----------
   Same selected-state vocabulary as the quiz option pills: white at rest,
   Slate Ink fill when chosen. Rounded rather than full pill, because these
   carry three stacked lines rather than one word. */
.co-choices { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

.co-choice {
  display: flex; flex-direction: column; align-items: flex-start; gap: 5px;
  text-align: left;
  background: var(--light); color: var(--dark);
  border: 0; border-radius: var(--radius-sm);
  padding: 18px 20px 16px;
  cursor: pointer;
  box-shadow: inset 0 0 0 1.5px rgba(28, 28, 28, .16);
  transition: transform .5s var(--out), background .3s ease, color .3s ease, box-shadow .4s var(--out);
}
.co-choice:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1.5px rgba(28,28,28,.4), 0 8px 22px rgba(28,28,28,.12); }
.co-choice:active { transform: translateY(0); }
.co-choice:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--grey), 0 0 0 4px var(--dark); }

.co-choice[aria-pressed="true"] {
  background: var(--dark); color: var(--light);
  box-shadow: inset 0 0 0 1.5px var(--dark);
}

.co-choice-label { font-size: 12px; text-transform: uppercase; opacity: .72; }
.co-choice-meta { font-size: 1.05rem; font-weight: 700; letter-spacing: -.02em; line-height: 1.2; }

/* the saving is the reason to pick this one, so it earns the one accent */
.co-choice-tag {
  font-size: 11px; text-transform: uppercase;
  background: var(--olive); color: var(--light);
  border-radius: var(--pill);
  padding: 4px 10px;
  margin-top: 3px;
}
.co-choice-note { font-size: 11px; text-transform: uppercase; opacity: .6; margin-top: 3px; }

@media (max-width: 460px) {
  .co-choices { grid-template-columns: 1fr; }
}

/* ---------- card fields ----------
   Stripe renders its own inputs inside an iframe here, styled to match the
   site through the Appearance API in checkout.js. Nothing in this block can
   reach inside that iframe, so it only handles the panel around it. */
/* wallet buttons, above the card form */
.co-express { margin-bottom: 4px; }
.co-express-title {
  font-size: 12px; text-transform: uppercase; color: var(--muted);
  text-align: center; margin-bottom: 14px;
}
/* rule with the label sitting in a gap in it, rather than text on a line */
.co-or {
  display: flex; align-items: center; gap: 14px;
  font-size: 11px; text-transform: uppercase; color: var(--muted);
  margin: 22px 0 24px;
}
.co-or::before, .co-or::after {
  content: ""; flex: 1; height: 1px; background: var(--line);
}

.co-pay-hint { margin-top: -8px; margin-bottom: 20px; }
.co-stripe-mount { min-height: 0; }

.co-stripe-loading {
  display: flex; align-items: center; gap: 12px;
  font-family: var(--mono); font-size: 12px; text-transform: uppercase;
  color: var(--muted);
  padding: 18px 0 6px;
}
.co-spinner {
  width: 15px; height: 15px; flex: none;
  border-radius: var(--pill);
  border: 2px solid rgba(28, 28, 28, .18);
  border-top-color: var(--dark);
  animation: co-spin .7s linear infinite;
}
@keyframes co-spin { to { transform: rotate(360deg); } }

/* ---------- payment complete ---------- */

.co-done { max-width: 620px; }
.co-done h1 { font-size: clamp(2.1rem, 5.6vw, 3.1rem); margin-top: 22px; }
.co-done .checkout-lead { margin-bottom: 30px; }

.co-done-mark {
  display: grid; place-items: center;
  width: 62px; height: 62px;
  border-radius: var(--pill);
  background: var(--dark);
  color: var(--light);
  box-shadow: var(--shadow-card);
}
/* the one authored moment on this page: the tick draws itself in once */
.co-done-mark svg path {
  stroke-dasharray: 34;
  stroke-dashoffset: 34;
  animation: co-tick .55s var(--out) .12s forwards;
}
@keyframes co-tick { to { stroke-dashoffset: 0; } }

/* a payment that did not land must not wear the confirmation styling */
.co-done[data-state="failed"] .co-done-mark { background: transparent; color: var(--dark); box-shadow: none; }
.co-done[data-state="failed"] .co-done-mark svg path { animation: none; stroke-dashoffset: 0; }

/* the numbered step list, on the grey field rather than the dark panel */
.co-next-light { margin-top: 4px; }
.co-next-light li { color: var(--dark); font-size: .98rem; padding: 9px 0; }
.co-next-light li::before { background: var(--dark); color: var(--light); }

@media (prefers-reduced-motion: reduce) {
  .co-done-mark svg path { animation: none; stroke-dashoffset: 0; }
  .co-spinner { animation-duration: 1.6s; }
}

/* ---------- summary side ---------- */

.checkout-aside { min-width: 0; }

.co-summary {
  position: sticky; top: 24px;
  background: var(--dark);
  color: var(--light);
  border-radius: var(--radius);
  padding: 26px 24px 28px;
  box-shadow: var(--shadow-card);
}

.co-sum-title {
  font-family: var(--mono); font-size: 12px; font-weight: 400;
  text-transform: uppercase; letter-spacing: .02em;
  color: rgba(255, 255, 255, .58);
  margin-bottom: 18px;
}

.co-order { display: grid; grid-template-columns: 64px 1fr; gap: 16px; align-items: start; }
.co-order-art {
  width: 64px; height: 80px;
  object-fit: cover;
  border-radius: var(--radius-xs);
  background: var(--dark-raised);
}
.co-order-name { font-size: 1.15rem; font-weight: 700; letter-spacing: -.02em; line-height: 1.15; }
.co-order-desc {
  color: rgba(255, 255, 255, .66);
  font-size: .9rem; line-height: 1.4; margin-top: 7px;
}
.co-order-change {
  display: inline-block;
  font-size: 11px; text-transform: uppercase;
  color: rgba(255, 255, 255, .66);
  margin-top: 11px;
  text-underline-offset: 3px;
  transition: color .3s ease;
}
.co-order-change:hover { color: var(--light); }

/* ---------- discount code ---------- */

.co-promo { margin-top: 22px; padding-top: 20px; border-top: 1px solid rgba(255, 255, 255, .18); }
.co-promo-label {
  display: block; font-size: 11px; text-transform: uppercase;
  color: rgba(255, 255, 255, .58); margin-bottom: 9px;
}
.co-promo-row { display: flex; gap: 8px; }

.co-promo-input {
  flex: 1 1 auto; min-width: 0;
  font-size: 12px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--light);
  background: rgba(255, 255, 255, .09);
  border: 0; border-radius: var(--pill);
  padding: 11px 16px;
  transition: background .3s ease, box-shadow .4s var(--out);
}
.co-promo-input::placeholder { color: rgba(255, 255, 255, .4); text-transform: none; letter-spacing: 0; }
.co-promo-input:hover { background: rgba(255, 255, 255, .13); }
.co-promo-input:focus { outline: none; background: rgba(255, 255, 255, .15); }
.co-promo-input:focus-visible { box-shadow: 0 0 0 2px var(--dark), 0 0 0 4px var(--light); }
/* an applied code is a fact, not a field to keep editing */
.co-promo-input[readonly] { background: rgba(255, 255, 255, .06); color: rgba(255, 255, 255, .72); }

.co-promo-apply {
  flex: none;
  font-size: 11px; text-transform: uppercase;
  background: var(--light); color: var(--dark);
  border: 0; border-radius: var(--pill);
  padding: 11px 18px; cursor: pointer;
  transition: opacity .3s ease, transform .5s var(--out);
}
.co-promo-apply:hover { transform: translateY(-1px); }
.co-promo-apply:disabled { opacity: .5; cursor: default; transform: none; }

.co-promo-msg { font-size: .82rem; line-height: 1.4; margin-top: 10px; color: rgba(255, 255, 255, .72); }
/* Olive is the system's one accent and this is exactly the "it worked" signal
   it exists for. Lightened here because it sits on Slate Ink, not on white. */
.co-promo-msg.is-ok { color: var(--olive-light); }

.co-line-promo dt, .co-line-promo dd { color: var(--olive-light); }

.co-lines { margin: 22px 0 0; }
.co-line { display: flex; justify-content: space-between; gap: 16px; padding: 11px 0; }
.co-line dt { color: rgba(255, 255, 255, .78); font-size: .95rem; }
.co-line dd { margin: 0; font-weight: 600; }
.co-line-meta { padding-top: 0; }
.co-line-meta dt {
  font-family: var(--mono); font-size: 11px; text-transform: uppercase;
  color: rgba(255, 255, 255, .5);
}

.co-total {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  border-top: 1px solid rgba(255, 255, 255, .18);
  margin-top: 6px; padding-top: 18px;
}
.co-total .mono { font-size: 12px; text-transform: uppercase; color: rgba(255, 255, 255, .58); }
.co-total-amount { font-size: 1.7rem; font-weight: 700; letter-spacing: -.03em; }

/* the billing schedule, called out rather than buried in the small print */
.co-commit {
  background: rgba(255, 255, 255, .09);
  border-radius: var(--radius-sm);
  padding: 13px 15px;
  margin-top: 16px;
  color: rgba(255, 255, 255, .88);
  font-size: .85rem;
  line-height: 1.45;
}

.co-secure {
  color: rgba(255, 255, 255, .62);
  font-size: .85rem; line-height: 1.45;
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid rgba(255, 255, 255, .18);
}

.co-next-title { color: rgba(255, 255, 255, .58); font-size: 11px; margin-top: 22px; }
.co-next {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  counter-reset: co-step;
}
.co-next li {
  counter-increment: co-step;
  display: grid; grid-template-columns: 22px 1fr; gap: 12px;
  color: rgba(255, 255, 255, .78);
  font-size: .88rem; line-height: 1.45;
  padding: 7px 0;
}
.co-next li::before {
  content: counter(co-step);
  font-family: var(--mono); font-size: 11px;
  display: grid; place-items: center;
  width: 22px; height: 22px;
  border-radius: var(--pill);
  background: rgba(255, 255, 255, .13);
  color: var(--light);
}

@media (max-width: 900px) {
  .checkout-grid { grid-template-columns: 1fr; }
  /* what you are buying and what it costs come before the form asks for
     anything, which is also the order the desktop eye takes them in */
  .checkout-aside { order: -1; }
  .co-summary { position: static; }
}

@media (max-width: 560px) {
  /* still has to clear the absolutely positioned header, same as .product */
  .checkout { padding: 100px 0 68px; }
  .co-panel { padding: 22px 20px 24px; }
  .co-summary { padding: 22px 20px 24px; }
  .co-submit { flex-direction: column; align-items: stretch; }
  .co-pay { width: 100%; min-width: 0; }
  .co-submit .back-link { text-align: center; }
}

/* The footer keeps its own breakpoint. Below 640 the copyright and the three
   legal links cannot sit on one line, and a wrapped row is taller than a
   deliberate stack, so stack before it wraps rather than after. */
@media (max-width: 639px) {
  .site-footer { padding: 24px 0 28px; }
  .site-footer .wrap { flex-direction: column; align-items: flex-start; gap: 12px; }
  .site-footer nav { flex-wrap: wrap; gap: 6px 18px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
  /* the backdrop holds still. Opacity is its own base value rather than an
     animation target, so the photos stay visible with all motion switched off. */
  body::before, body::after { animation: none !important; translate: none !important; scale: 1 !important; }
}
