/* Composer Assistant — the sales page and checkout. Build plan A2.3.
   ---------------------------------------------------------------------------
   THE IDEA THIS PAGE IS BUILT ON

   CA sells two things that are NOT the same kind of thing, and the whole data
   model depends on nobody confusing them (build plan decision 9). A LICENCE is
   bought once and owned forever. A SUBSCRIPTION is metered and runs. So the
   page changes TEMPERATURE between them: the licence section is manuscript
   stock and brass — paper, permanent, still. The generation section is the
   scoring stage at rest, dark, with a live signal colour running through it.

   The two accents are load-bearing, not decoration:
       brass  (--brass)  = you own this
       signal (--signal) = this is running and being counted

   The signature element is the TAKE METER: a tick band under each plan whose
   density shows the size of the monthly allowance, with the real number set in
   mono beneath it. "Takes" is the unit the whole business counts in, and a
   tick ruler is furniture from the composer's own world.

   Deliberately NOT: cream + high-contrast serif + terracotta, or a broadsheet
   hairline grid. The stock here is cool and greyed, the display face is a
   grotesque, and the accents carry meaning rather than mood.
   --------------------------------------------------------------------------- */

/* ⚠️ EVERY COLOUR, THE TYPE STACKS, `body` AND THE FOCUS RING NOW LIVE IN
   static/css/tokens.css, WHICH LOADS BEFORE THIS FILE.

   They moved on 8 Sep 2026. The tokens here were named for what they LOOKED
   like — --ink, --stock, --on-ink — and a token called "ink" cannot become
   white. That is why CA had no light/dark switch and could not grow one: not a
   missing button, a token layer that structurally could not hold two themes.

   ⚠️ NOTHING BELOW MAY DEFINE A RAW COLOUR. If you need one that does not
   exist yet, add it to BOTH themes in tokens.css. A hex typed into this file
   is a value that cannot flip, and it will look correct in exactly one theme.
   Two of them were already here (#a9762c, twice) and this pass removed them. */

.shell {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0 1.5rem;
}

/* ── Masthead ─────────────────────────────────────────────────────────────── */

/* ⚠️ THE DOTTED TICK RULE UNDER THE MASTHEAD WAS REMOVED ON 8 SEP 2026, ON
   MARC'S INSTRUCTION, AND IT MUST NOT COME BACK UNASKED.
   It was a 3px repeating gradient — the take meter's own band promoted to the
   rule of the house — built the same day. He looked at the result and cut it:
   "la línea punteada de arriba". Nothing replaces it: the masthead now meets
   the page with no rule at all, which is the change he asked for. A hairline
   border is a SUBSTITUTION, not a removal, so it is not here either. If the
   header ever needs separating from the content, that is a fresh decision with
   his name on it.

   The `.masthead` rule itself went with it — position:relative and
   border-bottom:0 existed only to carry that ::after, and an empty rule left
   behind is an invitation to refill it. .masthead__inner holds the padding. */

.masthead__inner {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 1.1rem 1.5rem;
  display: flex;
  /* Centre, not baseline: the theme toggle is a bordered pill and a baseline
     would hang it below the wordmark. */
  align-items: center;
  gap: .75rem;
}

/* Everything to the right of the wordmark: the format line where a page wants
   one, the theme switch, and the way into an account. */
.masthead__tools {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 1rem;
}

/* ⚠️ .masthead__link WAS DELETED ON 8 SEP 2026 WITH THE "SIGN IN" LINK IT
   STYLED. Marc's call, and it was checked against CC before it was made:
   app_cc/templates/base.html and its footer carry NO sign-in, log-in or
   account link anywhere in the chrome, and that has been true for years at
   ~130,000 customers. The way back into an account is the receipt and the
   emailed link, not the masthead. Do not reintroduce a nav link here without
   asking him first. */

.wordmark {
  font-family: var(--display);
  font-weight: 800;
  font-size: 1rem;
  letter-spacing: -.01em;
  text-decoration: none;
}

.wordmark__assistant { color: var(--text-muted); font-weight: 600; }

/* No margin-left:auto — .masthead__tools carries it and this sits inside. */
.masthead__formats {
  font-family: var(--data);
  font-size: .7rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.eyebrow {
  font-family: var(--data);
  font-size: .72rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin: 0 0 1.5rem;
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE CHECKOUT — choose on the left, pay on the right, everything at once.

   Geometry taken from CC's own checkout so it feels like the same house:
   a 1200px container, a flexible main column capped at 700px, a ~380px sticky
   sidebar, 30px gutter, stacking below 968px. What differs is which side holds
   what — here the payment sits on the right, as Fede asked.

   This surface is LIGHT. The upsell that follows is dark. That contrast is the
   one carried over from the earlier design and it still earns its place: this
   page sells the thing you OWN, the next sells the thing that RUNS.
   ═══════════════════════════════════════════════════════════════════════════ */

/* No background or colour of its own any more: body carries the surface, and
   the visitor chooses which one. `flex` rather than min-height:100vh, because
   body is now the flex column that keeps the footer at the bottom. */
.co {
  flex: 1 1 auto;
  padding: 2.75rem 1.5rem 4rem;
}

/* ⚠️ .co__intro / .co__title / .co__lede WERE DELETED ON 8 SEP 2026.
   The checkout's headline ("Get Composer Assistant") and its subtitle went
   with them, on Marc's instruction: what the $997 buys is stated ONCE, in the
   stack (checkout_routes.LICENCE_STACK), not paraphrased in a lede above it.
   The page now opens directly on "Your information". If a headline is ever
   wanted back, it is his line to write — do not invent one. */

.co__grid {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  align-items: flex-start;
  gap: 30px;
}

.co__main { flex: 1 1 auto; max-width: 700px; min-width: 0; }

.co__side {
  width: 380px;
  flex: 0 0 380px;
  position: sticky;
  top: 20px;
}

/* ── Steps: choose, then pay ──────────────────────────────────────────────── */

.step__title {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.25rem;
  letter-spacing: -.015em;
  margin: 0 0 1.1rem;
}

.step__back {
  border: 0;
  background: none;
  padding: 0;
  margin: 0 0 1rem;
  cursor: pointer;
  font-family: var(--data);
  font-size: .74rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.step__back:hover { color: var(--text-primary); }

.step__test {
  margin: 0 0 1.1rem;
  font-size: .87rem;
  color: var(--text-muted);
}

.step__error {
  margin: 0 0 1.1rem;
  padding: .9rem 1.1rem;
  border-radius: 8px;
  border-left: 3px solid var(--danger);
  background: var(--danger-bg);
  font-size: .92rem;
}

.step__title--second { margin-top: 2.25rem; }

.step__secure {
  margin: .9rem 0 0;
  text-align: center;
  font-size: .8rem;
  color: var(--text-muted);
}

/* ── Form fields — ours, and the boxes Stripe's inputs sit inside ─────────── */

.field { margin-bottom: 1.1rem; }

.field--row {
  display: flex;
  gap: .9rem;
}

.field__half { flex: 1 1 0; min-width: 0; }

.field__label {
  display: block;
  margin-bottom: .4rem;
  font-size: .85rem;
  font-weight: 500;
  color: var(--text-primary);
}

.field__input,
.cardbox {
  width: 100%;
  padding: .8rem .9rem;
  border: 1px solid var(--border-subtle);
  border-radius: 9px;
  background: var(--bg-card);
  font-family: var(--body);
  font-size: 1rem;
  color: var(--text-primary);
}

.field__input::placeholder { color: var(--text-faint); }

.field__input:focus {
  outline: none;
  border-color: var(--brass);
  box-shadow: 0 0 0 1px var(--brass);
}

/* ⚠️ Stripe mounts ONE input into each of these and manages its height, so the
   box gets a fixed line box rather than padding that would double up. The
   focus ring is ours: Stripe adds .StripeElement--focus to the same node. */
.cardbox {
  line-height: 1.45;
  transition: border-color .12s ease, box-shadow .12s ease;
}

.cardbox.StripeElement--focus {
  border-color: var(--brass);
  box-shadow: 0 0 0 1px var(--brass);
}

.cardbox.StripeElement--invalid {
  border-color: var(--danger);
  box-shadow: 0 0 0 1px var(--danger);
}

.field__help {
  margin: .4rem 0 0;
  font-size: .82rem;
  color: var(--text-muted);
}

.continue {
  display: block;
  width: 100%;
  margin: 1.75rem 0 0;
  padding: 1rem 1.25rem;
  border: 0;
  border-radius: 10px;
  background: var(--brass);
  color: var(--on-brass);
  font-family: var(--body);
  font-weight: 500;
  font-size: 1rem;
  cursor: pointer;
  transition: filter .12s ease;
}

.continue:hover { filter: brightness(1.06); }

.continue:disabled { opacity: .45; cursor: not-allowed; }

/* The button that actually takes the money. Same shape, more weight. */
.continue--pay {
  margin-top: 1.25rem;
  font-family: var(--data);
  font-weight: 600;
  font-size: 1.02rem;
  letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}

/* ── The payment options ──────────────────────────────────────────────────── */

.picks { display: grid; gap: .75rem; }

.pick {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  width: 100%;
  text-align: left;
  padding: 1.15rem 1.25rem;
  border-radius: 12px;
  border: 1px solid var(--border-subtle);
  background: var(--bg-card);
  color: inherit;
  font-family: var(--body);
  cursor: pointer;
  transition: border-color .14s ease, box-shadow .14s ease;
}

.pick:hover { border-color: var(--brass); }

.pick--on {
  border-color: var(--brass);
  box-shadow: 0 0 0 1px var(--brass);
}

.pick:disabled { opacity: .5; cursor: not-allowed; }

.pick__mark {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin-top: .18rem;
  border-radius: 50%;
  border: 1.5px solid var(--border-subtle);
  position: relative;
}

.pick--on .pick__mark { border-color: var(--brass); }

.pick--on .pick__mark::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background: var(--brass);
}

.pick__body { flex: 1 1 auto; min-width: 0; }

.pick__name {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: -.01em;
}

.pick__note {
  display: block;
  margin-top: .3rem;
  font-size: .88rem;
  color: var(--text-muted);
}

.pick__price { flex: 0 0 auto; text-align: right; }

.pick__amount {
  display: block;
  font-family: var(--data);
  font-weight: 600;
  font-size: 1.32rem;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
  color: var(--brass-text);
}

.pick__per {
  display: block;
  margin-top: .2rem;
  font-family: var(--data);
  font-size: .72rem;
  color: var(--text-muted);
}

/* ── Supporting copy on the left ──────────────────────────────────────────── */

.co__pending {
  margin: 1.75rem 0 0;
  padding: 1.1rem 1.25rem;
  border: 1px dashed var(--border-subtle);
  border-radius: 12px;
}

.co__pending-mark {
  margin: 0 0 .35rem;
  font-family: var(--data);
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--brass-text);
}

.co__pending-text {
  margin: 0;
  font-size: .9rem;
  color: var(--text-muted);
}

/* ── What the $997 includes ───────────────────────────────────────────────── */

/* ⚠️ THIS RENDERS ONLY WHEN THERE IS SOMETHING TO RENDER, ON EVERY BOX.
   Until 8 Sep 2026 the block above it was wrapped in {% if payment_mode !=
   'live' %}, so production drew NOTHING between the price picker and the
   Continue button — verified live that day. The list is now server-side data
   (checkout_routes.LICENCE_STACK, empty until Marc writes it), so live and
   test render identically and his list drops in without touching a template. */
.stack {
  margin: 1.75rem 0 0;
  padding: 1.25rem 1.35rem;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
}

.stack__title {
  margin: 0 0 .8rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1rem;
}

.stack__list {
  margin: 0;
  padding-left: 1.05rem;
  font-size: .92rem;
  color: var(--text-muted);
}

.stack__list li { margin-bottom: .4rem; }
.stack__list li:last-child { margin-bottom: 0; }

/* ⚠️ .co__aside / -title / -text WERE DELETED ON 8 SEP 2026 WITH THE "ABOUT
   GENERATING" PARAGRAPH THEY STYLED. Marc's instruction: the webinar explains
   it, and the stack will state it — the checkout does not need a third telling.

   ⚠️ THE FACT ITSELF IS NOT LOST, AND THAT IS WHY THIS WAS SAFE TO CUT.
   Decision 15 (cloud generation is included in the lifetime licence) is still
   on the page, in the order summary on the right: "Cloud generation included".
   Do not delete THAT line as a tidy-up — with this paragraph gone it is the
   only place the page says it, and the whole reason this copy was rewritten in
   session 5 was that getting it wrong either suppresses the sale or sets up a
   refund. And the old rule still stands: the word "plan" appears nowhere on
   this page, not even to deny one. */

/* ── Order summary (the sticky right column) ──────────────────────────────── */

/* ⚠️ THE SHADOW IS NOT ORNAMENT, IT IS THE LIGHT THEME'S ONLY DEPTH CUE.
   A white card on the warm ground is 1.03:1 — fill alone cannot separate them.
   --shadow-card resolves to `none` in dark, where the 1px border already does
   the job. Every raised surface in this file carries it for that reason. */
.summary {
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: 1.4rem 1.4rem 1.5rem;
  box-shadow: var(--shadow-card);
}

.summary__title {
  margin: 0 0 1.1rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.05rem;
}

.summary__lines {
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--border-subtle);
}

.summary__line {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  font-size: .95rem;
  font-variant-numeric: tabular-nums;
}

.summary__line span:last-child { font-family: var(--data); }

/* ⚠️ The instalment route's second and third payments live here. Showing only
   "due today" would let somebody buy a $1,200 plan believing it cost $400. */
.summary__schedule {
  margin: .45rem 0 0;
  font-family: var(--data);
  font-size: .78rem;
  color: var(--text-muted);
}

.summary__total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: 1rem 0 0;
  font-weight: 500;
}

.summary__due {
  font-family: var(--data);
  font-weight: 600;
  font-size: 1.6rem;
  letter-spacing: -.035em;
  font-variant-numeric: tabular-nums;
  color: var(--brass-text);
}

.summary__gets {
  margin: 1.25rem 0 0;
  padding: 1.1rem 0 0 1.05rem;
  border-top: 1px solid var(--border-subtle);
  font-size: .87rem;
  color: var(--text-muted);
}

.summary__gets li { margin-bottom: .35rem; }
.summary__gets li:last-child { margin-bottom: 0; }

.summary__trust {
  margin: .9rem 0 0;
  text-align: center;
  font-size: .8rem;
  color: var(--text-muted);
}

.mono { font-family: var(--data); }

/* ── Offer cards (the upsell page) ────────────────────────────────────────── */

.offers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 1.25rem;
}

/* ⚠️ Self-sufficient on a dark ground. These cards used to take their surface
   from a .movement--ink ancestor that only existed on the old sales page, so on
   the upsell they rendered with no background at all. */
.offer {
  display: flex;
  flex-direction: column;
  padding: 1.9rem 1.75rem 1.75rem;
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  box-shadow: var(--shadow-card);
}

.offer__name {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.22rem;
  letter-spacing: -.01em;
  margin: 0 0 .2rem;
}

.offer__kicker {
  font-family: var(--data);
  font-size: .7rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  margin: 0 0 1.5rem;
  color: var(--text-muted);
}

.offer__price {
  font-family: var(--data);
  font-weight: 600;
  font-size: 2.5rem;
  letter-spacing: -.045em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  margin: 0;
  color: var(--accent-text);
}

.offer__per {
  font-family: var(--data);
  font-size: .82rem;
  margin: .55rem 0 0;
  color: var(--text-muted);
}

/* These four rules each had a second, single-property twin restating their
   colour — leftovers from when they inherited it from a .movement--ink
   ancestor that no longer exists. Merged on 8 Sep 2026. */
.offer__body {
  margin: 1.4rem 0 0;
  font-size: .95rem;
  color: var(--text-muted);
}

.offer__spacer { flex: 1 1 auto; min-height: 1.6rem; }

/* ── The take meter — the signature ───────────────────────────────────────── */

.meter { margin: 1.7rem 0 0; }

.meter__band {
  height: 38px;
  border-radius: 4px;
  background-repeat: repeat-x;
  transform-origin: left center;
  animation: meter-draw .7s cubic-bezier(.2, .8, .3, 1) both;
}

/* Density IS the message: Pro 10X's band is visibly packed against Pro's.
   The exact figure lives in the mono line underneath, where it can be read
   rather than estimated. */
.meter__band--pro {
  background-image: repeating-linear-gradient(90deg,
      var(--signal) 0 2px, transparent 2px 13px);
  opacity: .55;
}

.meter__band--pro10x {
  background-image: repeating-linear-gradient(90deg,
      var(--signal) 0 2px, transparent 2px 5px);
}

.meter__figure {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  margin: .85rem 0 0;
  font-family: var(--data);
  font-variant-numeric: tabular-nums;
}

.meter__count {
  font-weight: 600;
  font-size: 1.32rem;
  color: var(--text-primary);
}

.meter__unit {
  font-size: .76rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-muted);
}

@keyframes meter-draw {
  from { transform: scaleX(0); opacity: 0; }
  to   { transform: scaleX(1); }
}

/* ── Buy buttons ──────────────────────────────────────────────────────────── */

.buy {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  margin-top: 1.75rem;
  padding: .95rem 1.25rem;
  border: 0;
  border-radius: 9px;
  font-family: var(--body);
  font-weight: 500;
  font-size: .97rem;
  text-decoration: none;
  cursor: pointer;
  transition: transform .12s ease, filter .12s ease;
}

.buy__arrow { font-family: var(--data); opacity: .65; }

.buy:hover { transform: translateY(-1px); filter: brightness(1.06); }
.buy:active { transform: translateY(0); }

/* ⚠️ ONE BUTTON, AND THE PAGE DECIDES ITS COLOUR — NOT THE TEMPLATE.
   .buy--brass and .buy--signal were merged into this on 8 Sep 2026. Choosing
   between them by hand is what put a TEAL primary button on sign in, plugin
   sign-in and the receipt while the checkout's was BRASS. Now the button asks
   for the accent and `.surface-run` is the only thing that changes it, so a
   new page cannot pick the wrong one — it can only fail to declare which half
   of the product it is in, and the default is the owned half.

   (.buy--brass had no template using it at all: the checkout's own button is
   .continue. It was already dead when it was merged.)

   ⚠️ IT STILL DOES NOT CHANGE BETWEEN THEMES, AND THAT IS STILL DELIBERATE.
   Both accents resolve to theme-independent fills, so the buy button looks
   identical in light and dark. It is the anchor of every page: the one element
   that stays put when somebody flips the switch. */
.buy--accent { background: var(--accent); color: var(--on-accent); }

.buy--quiet {
  background: transparent;
  color: var(--text-primary);
  border: 1px solid var(--border-subtle);
}

/* ⚠️ REPLACES SIX INLINE style="max-width: 22rem" ATTRIBUTES that were spread
   across five templates on 8 Sep 2026. A measurement repeated by hand in six
   places is a design system leaking; the sixth copy is always the one that
   gets a different number. */
.buy--fit { max-width: 22rem; }

/* ⚠️ WHICH HALF OF THE PRODUCT THIS PAGE IS IN — THE ONE SWITCH FOR ALL OF IT.
   Brass is the default (you own this). Signal is for the page that sells the
   thing which runs and is counted: /checkout/upsell today, A3.4's upgrade page
   later — that page wants this class and nothing else. It is not a theme; both
   themes carry both accents.

   ⚠️ IT SITS ON <body>, and it has to. The masthead is a SIBLING of the page
   content, so a class on the content wrapper could never reach the chrome.

   ⚠️ ALL THREE TOKENS FLIP TOGETHER, AND THAT IS THE FIX. Until 8 Sep 2026
   this line moved --rule-accent alone, so one 3px band changed accent while
   every component around it stayed hardcoded — which is how the identity pages
   ended up teal. Setting one of these without the others reopens exactly that
   gap: --accent-text without --accent gives a teal heading over a brass
   button. */
.surface-run {
  --accent:      var(--signal);
  --accent-text: var(--signal-text);
  --on-accent:   var(--on-signal);
}

.buy:disabled {
  opacity: .45;
  cursor: not-allowed;
  transform: none;
}

/* ── Upsell ───────────────────────────────────────────────────────────────── */

.page__body--wide { max-width: 60rem; }

.offers--upsell { margin: 2.25rem 0 2rem; }

.skip {
  margin: 0;
  text-align: center;
  font-size: .95rem;
}

/* ⚠️ Declining must be as findable as accepting. Quieter, never hidden. */
.skip a {
  color: var(--text-muted);
  text-decoration: underline;
  text-underline-offset: 4px;
}

.skip a:hover { color: var(--text-primary); }

.skip__warning {
  margin: .7rem auto 0;
  max-width: 46ch;
  text-align: center;
  font-size: .84rem;
  color: var(--text-muted);
  opacity: .85;
}

/* ── The page shell — ONE shell, for all eight pages ──────────────────────── */

/* ⚠️ RENAMED FROM .checkout ON 8 SEP 2026. Five of the six pages using that
   name were not checkouts at all — sign in, check your email, signed in,
   plugin sign-in — and a wrong name is an invitation to write a second shell
   for "the pages that aren't checkouts". Which is how .co and .checkout came
   to exist side by side in the first place.

   The old .checkout rule (min-height:100vh + flex column) is GONE: body itself
   is the flex column now, in tokens.css, so every page keeps its footer at the
   bottom without declaring anything. */

.page__body {
  flex: 1 1 auto;
  max-width: 46rem;
  width: 100%;
  margin: 0 auto;
  padding: 3rem 1.5rem 5rem;
}

.page__back {
  display: inline-block;
  font-family: var(--data);
  font-size: .76rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-muted);
  text-decoration: none;
  margin-bottom: 2rem;
}

.page__back:hover { color: var(--accent-text); }

.page__title {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(1.8rem, 4vw, 2.5rem);
  letter-spacing: -.03em;
  margin: 0 0 .5rem;
}

/* ⚠️ THIS LINE USED TO READ `color: var(--signal)` — THE RAW FILL, AS TEXT.
   tokens.css measures raw signal at 1.61:1 on the light ground, so the email
   address under every heading on the identity pages was very nearly invisible
   the moment the light theme shipped. It is the exact trap the --accent /
   --accent-text split exists to prevent, and it was live for a day. */
.page__summary {
  font-family: var(--data);
  font-variant-numeric: tabular-nums;
  color: var(--accent-text);
  margin: 0 0 2.5rem;
  font-size: 1rem;
}

/* Stripe's embedded form mounts here. It brings its own surface, so this
   element only reserves the space and centres it. */
#stripe-checkout { min-height: 22rem; }

.notice {
  border: 1px solid var(--border-subtle);
  border-left: 3px solid var(--brass);
  border-radius: 8px;
  padding: 1.15rem 1.35rem;
  margin: 0 0 2rem;
  font-size: .95rem;
  color: var(--text-muted);
}

.notice strong { color: var(--text-primary); font-weight: 500; }

.notice--bad { border-left-color: var(--danger); }

/* ── The download (templates/login_done.html, A3.2) ───────────────────────────
   ⚠️ THIS IS THE BLOCK THE RECEIPT'S OWN COMMENT ASKED FOR. That section says
   CC's big "Access your purchase" button was deliberately NOT ported because
   "CA has no dashboard and no download until A3, so the button would be a
   promise with nowhere to land — add the button in A3.2, next to step 1, when
   it can actually do something." It can now.

   ⚠️ IT REUSES .buy RATHER THAN GROWING ITS OWN BUTTON, and that is the whole
   discipline of this file: the primary action on every page is one component
   that asks for --accent, and the PAGE decides which accent that is. A second
   button style here is how the eight pages drifted apart the first time.

   ⚠️ THE ONLY NEW IDEA IS THE META LINE, and it carries the two things the
   button cannot: which version this is, and the way to the other platform when
   detection guessed wrong. Mono for the version, because every number in this
   house is mono. Nothing else is added — the closed state of this page was
   already correct and got no new decoration.                                 */

.download { margin: 0 0 2.5rem; }

/* ⚠️ .buy carries margin-top: 1.75rem for the pages that end on it. Here it
   follows .page__summary's own 2.5rem, and the two stack into a gap that
   pushes the one thing this page exists for below the fold on a laptop. */
.download .buy { margin-top: 0; }

.download__meta {
  margin: .85rem 0 0;
  font-size: .87rem;
  color: var(--text-muted);
}

/* Findable, never loud — the same treatment .skip gives declining an offer.
   Somebody whose platform we guessed wrong is the one person on this page who
   genuinely cannot proceed, so this link may not be decorative. */
.download__alt {
  color: var(--text-muted);
  text-decoration: underline;
  text-underline-offset: 4px;
}

.download__alt:hover { color: var(--text-primary); }

/* ── The delivery promise (templates/_delivery.html) ──────────────────────── */

/* The top margin arrived on 8 Sep 2026 when the two notices above became an
   ordered list — a notice box carried its own spacing, an <ol> does not. */
.delivery__note {
  margin: 1.5rem 0 1.25rem;
  font-size: .95rem;
  color: var(--text-muted);
}

/* ⚠️ .delivery__refund AND .delivery__signature WERE DELETED ON 9 SEP 2026 with
   the refund line they styled — templates/_delivery.html carries the reason
   (Fede's call after the first real login on production). Both are in
   scripts/test_theme_system.py's removed-rule guard, so a "restore" is a red
   test rather than a quiet reappearance. */

/* ── Return page ──────────────────────────────────────────────────────────── */

.receipt {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  padding: 2rem 1.85rem;
  margin: 0 0 2rem;
  box-shadow: var(--shadow-card);
}

.receipt__row {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
  padding: .7rem 0;
  border-bottom: 1px solid var(--border-subtle);
  font-family: var(--data);
  font-size: .9rem;
}

.receipt__row:last-child { border-bottom: 0; }
.receipt__key { color: var(--text-muted); }
.receipt__value { text-align: right; }

/* ── The receipt page — /checkout/done ────────────────────────────────────────
   ⚠️ CC'S THANK-YOU ANATOMY, PORTED ON 8 SEP 2026. NEVER IMPORTED (Law One).
   Read from app_cc/templates/checkout/builder_thank_you.html and the
   body.bty-page block of app_cc/static/css/surfaces/checkout.css. The skeleton
   is CC's because it is proven on a page ~130,000 people have been through:
   one celebration mark, a centred hero, an order card holding a confirmation
   number and an itemised list closed by a total, then numbered next-steps.
   Every value here is CA's own — brass and the accent triple, Bricolage and
   Plex, CA's radii and shadows.

   ⚠️ WHAT WAS DELIBERATELY NOT COPIED:
   · CC's gold GRADIENT on the mark and its button. CA's law is that accent
     fills do not flip between themes (tokens.css), and a two-stop gradient
     needs a second fill that would have to. A flat accent circle keeps the
     law and loses nothing at 76px.
   · CC's big "Access your purchase →" button. It goes to a dashboard. CA has
     no dashboard and no download until A3, so the button would be a promise
     with nowhere to land. The numbered steps carry that job instead — add the
     button in A3.2, next to step 1, when it can actually do something.
   · CC's support block. CA has no support address yet, and inventing one on a
     $997 receipt is worse than omitting it.                                  */

.done {
  text-align: center;
  margin: 0 0 2.5rem;
}

/* The one bold element on the page. Everything below it is quiet on purpose —
   spend the boldness once. */
.done__mark {
  width: 76px;
  height: 76px;
  margin: 0 auto 1.5rem;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 30px var(--accent-glow);
}

.done__mark svg { width: 36px; height: 36px; }

.done__title {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(1.9rem, 4.5vw, 2.6rem);
  letter-spacing: -.03em;
  margin: 0 0 .5rem;
}

.done__email {
  margin: 0;
  font-family: var(--data);
  font-variant-numeric: tabular-nums;
  color: var(--accent-text);
  word-break: break-all;
}

/* ── The order card ───────────────────────────────────────────────────────── */

.order {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
  padding: 1.85rem;
  margin: 0 0 2rem;
}

/* A card inside the card, exactly as CC sets its confirmation number: it is
   the one string a buyer reads back to us when something goes wrong, so it is
   findable rather than filed in a row. */
.order__ref {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--bg-panel);
  padding: .9rem;
  margin: 0 0 1.75rem;
  text-align: center;
}

.order__ref-label {
  margin: 0 0 .2rem;
  font-family: var(--data);
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.order__ref-value {
  margin: 0;
  font-family: var(--data);
  font-weight: 600;
  font-size: 1.15rem;
  letter-spacing: .02em;
  color: var(--accent-text);
}

.order__title {
  margin: 0 0 1rem;
  padding-bottom: .7rem;
  border-bottom: 2px solid var(--border-subtle);
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.1rem;
}

.order__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1.5rem;
  padding: .7rem 0;
  border-bottom: 1px solid var(--border-subtle);
  font-size: .93rem;
}

.order__row:last-of-type { border-bottom: 0; }

.order__key { color: var(--text-muted); }

.order__value {
  text-align: right;
  font-family: var(--data);
  font-variant-numeric: tabular-nums;
}

/* ⚠️ THE 2px RULE IS CC'S, AND IT IS DOING WORK. It is the only place on the
   page where a border is heavier than a hairline, which is what makes the last
   row read as a conclusion rather than one more line. */
.order__total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1.5rem;
  margin-top: .4rem;
  padding-top: 1rem;
  border-top: 2px solid var(--border-subtle);
  font-weight: 500;
}

/* ⚠️ THE STRING HERE IS OFFERS[offer]['summary'], WHOLE AND UNPARSED — "$997 ·
   one payment", or "3 × $400 · $1,200 total". It already states the instalment
   TOTAL as well as the instalment, which is the disclosure the checkout's own
   order summary exists to make: showing only what was taken today would let
   somebody who has just committed to $1,200 read $400 and find out later. Do
   not split this string for layout. */
.order__price {
  font-family: var(--data);
  font-weight: 600;
  font-size: 1.2rem;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--accent-text);
}

/* ── Numbered steps (templates/_delivery.html) ────────────────────────────────
   ⚠️ NUMBERED BECAUSE THE CONTENT REALLY IS A SEQUENCE, not for decoration.
   The onboarding session comes first and the licence activates at the class
   after it — Marc separates those two moments explicitly, and a buyer who
   reads them as one will turn up expecting to generate on the 16th. Two grey
   notice boxes said nothing about their order. An ordered list does.

   🚨 THESE ARE `.delivery__step*`, NOT `.step*`, AND THAT COST US A BROKEN
   CHECKOUT. They shipped as .step / .step__title on 8 Sep 2026 and BOTH names
   were already taken: templates/index.html wraps the checkout's two stages in
   <section class="step"> with <h2 class="step__title"> inside, styled at the
   top of this file. Declared again down here, `.step { display: flex }` won on
   source order and laid the entire "Your information" stage out as a
   horizontal row — name, email, price picker and Continue button side by side,
   on the only page that takes money. Marc found it: "el checkout se rompió."

   ⚠️ CC HAD ALREADY SOLVED THIS AND SAID SO IN THE FILE THIS WAS PORTED FROM.
   app_cc/static/css/surfaces/checkout.css scopes the whole thank-you block
   under `body.bty-page` and states the reason in its header comment: "to avoid
   collision with builder_checkout's .product-name / .original-price." The
   warning was read and not applied.

   ⚠️ RENAMED RATHER THAN SCOPED, and deliberately: the checkout held `.step`
   first, a scope only helps the page that remembers to carry the class, and
   these names now match the file that owns them — .delivery__note and
   .delivery__refund were already here. Section 5's duplicate-selector guard
   fails the build if any selector is ever declared twice again.              */

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

.delivery__step {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  margin-bottom: 1.25rem;
}

.delivery__step:last-child { margin-bottom: 0; }

.delivery__step-number {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--data);
  font-weight: 600;
  font-size: .82rem;
  font-variant-numeric: tabular-nums;
}

.delivery__step-body { flex: 1 1 auto; min-width: 0; }

.delivery__step-title {
  margin: 0 0 .2rem;
  font-weight: 500;
  color: var(--text-primary);
}

.delivery__step-text {
  margin: 0;
  font-size: .93rem;
  color: var(--text-muted);
}

/* ── Footer ───────────────────────────────────────────────────────────────── */

.footer {
  border-top: 1px solid var(--border-subtle);
  padding: 2.25rem 0 3rem;
  color: var(--text-muted);
  font-size: .85rem;
}

.footer__inner {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0 1.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: .6rem 1.5rem;
}

.footer__mode {
  font-family: var(--data);
  color: var(--brass-text);
  margin-left: auto;
}

/* ⚠️ .masthead--light, .footer--light AND .buy--quiet-ink WERE DELETED HERE
   ON 8 SEP 2026, AND THEY MUST NOT COME BACK.
   They existed to repaint the chrome when one page used the light surface and
   the rest used the dark one — a per-surface override, hand-applied, which is
   precisely the mechanism that let the eight pages drift apart. A theme system
   makes them not just redundant but harmful: a class that forces a colour is a
   class that ignores the visitor's choice. If a component needs to look
   different, it needs a token, not a modifier. */

/* ── Motion and small screens ─────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .meter__band { animation: none; }
  .buy { transition: none; }
  .buy:hover { transform: none; }
  .pick { transition: none; }
}

/* ⚠️ 968px is CC's own breakpoint for this layout, kept deliberately: below it
   the sidebar stops being a sidebar and the payment card falls under the
   options rather than beside them. A sticky 380px column on a phone is a column
   nobody can read. */
@media (max-width: 968px) {
  .co__grid { flex-direction: column-reverse; }

  .co__main { max-width: none; width: 100%; }

  .co__side {
    width: 100%;
    flex: 1 1 auto;
    position: static;
    margin-bottom: 1.5rem;
  }
}

@media (max-width: 40rem) {
  .co { padding: 1.75rem 1rem 3rem; }
  .masthead__formats { display: none; }

  .pick { flex-wrap: wrap; }
  .pick__price { text-align: left; width: 100%; padding-left: 2rem; }

  /* ⚠️ CC STACKS ITS RECEIPT ROWS AT THE SAME BREAKPOINT, and the reason is
     the long side: "3 × $400 · $1,200 total" and "1 of 3 taken · the rest
     monthly" cannot share a line with their label on a phone without one of
     them wrapping into an unreadable column. Label above, value below, both
     left-aligned. */
  .order { padding: 1.35rem; }

  .order__row,
  .order__total {
    display: block;
  }

  .order__value,
  .order__price {
    text-align: left;
    margin-top: .2rem;
  }
}
