/* plan-checkout.css — the close.
 *
 * Values follow the approved artefact. Palette is the platform's warm set,
 * declared locally rather than assumed: this renders inside app.html, whose
 * shell uses some of the same token names for different colours.
 */
.ock-overlay{
  --k-ink:#2a2030; --k-ink2:#5a4d62; --k-ink3:#8b7e92; --k-ink4:#b8acbb;
  --k-line:#ebe1c9; --k-linestrong:#d8cdaf; --k-cream:#faf6ec; --k-cream2:#f3ecdb;
  --k-accent:#6a4cf1; --k-accentsoft:#ece6ff; --k-accentdeep:#4a32b8;
  /* 🚨 THE BUY BUTTON IS PINK ON EVERY OFFER, AND IT IS ITS OWN TOKEN.
     Alex, 2026-09-11, walking the sequence: *"the UX does feel a bit
     disruptive at the moment. It feels like, 'What am I being shown?'...
     Maybe the button colour on the offer for the leads needs to be updated to
     the same pink. At least I think their styling needs to be consistent
     throughout."*

     He is describing a real flip. A coach walks leads offer -> $37 -> $88 ->
     confirmation, and the primary button went VIOLET -> pink -> pink -> violet.
     The two upsell pages carry `--pink:#ec1075`; this screen was using
     `--k-accent` (#6a4cf1) for its buy button, so the money button changed
     colour twice inside one sequence.

     ⚠️ A SEPARATE TOKEN, NOT A REDEFINITION OF --k-accent. `--k-accent` paints
     the rest of this screen - the selected tier, the focus ring, the soft
     washes - and Alex asked for the BUTTON. Repainting the whole checkout pink
     would be a different change he did not ask for, and would lose the app's
     own colour from a screen that sits inside the app.

     So: pink means "this takes money", the app's violet still means "carry on
     into the product" (the confirmation's own button stays violet on purpose).
     That distinction is now consistent across every step instead of random. */
  --k-buy:#ec1075; --k-buydeep:#c50c60;
  --k-good:#4f7c54; --k-goodsoft:#e4ecdc; --k-gold:#b8860b; --k-goldsoft:#faf0d8;
  --k-live:#ec1075; --k-bad:#b4232a;
  position:fixed; inset:0; z-index:9600;
  background:rgba(20,12,30,.55); backdrop-filter:blur(6px);
  display:flex; align-items:center; justify-content:center; padding:20px;
  font-family:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
  color:var(--k-ink);
}
.ock-overlay[hidden]{display:none;}
body.ock-open{overflow:hidden;}

.ock-panel{
  background:#fff; border-radius:18px; width:100%; max-width:1000px;
  max-height:calc(100vh - 40px); display:flex; flex-direction:column;
  overflow:hidden; box-shadow:0 40px 100px -30px rgba(42,32,48,.55);
}
.ock-load{margin:64px auto; color:var(--k-ink3); font-size:14px; text-align:center;}

.ock-bar{
  display:flex; align-items:center; gap:10px; flex:0 0 auto;
  padding:11px 16px; border-bottom:1px solid var(--k-line); background:var(--k-cream); font-size:12.5px;
}
.ock-back{
  display:inline-flex; align-items:center; gap:6px; cursor:pointer; font-family:inherit;
  border:1px solid var(--k-linestrong); background:#fff; border-radius:7px; padding:4px 9px;
  font-size:11.5px; color:var(--k-ink2);
}
.ock-back:hover{color:var(--k-ink);}
.ock-ttl{font-weight:650;}
/* Holds the ✕'s place so the title stays centred without one. */
.ock-x-sp{width:26px; height:26px; flex:0 0 auto;}
.ock-x{
  margin-left:auto; width:30px; height:30px; border-radius:50%; border:0; cursor:pointer;
  background:var(--k-cream2); color:var(--k-ink2);
  display:flex; align-items:center; justify-content:center;
}
.ock-x:hover{background:var(--k-ink); color:var(--k-cream);}

/* ── THE COUNTDOWN (2026-09-08, the campaign discount bands) ────────────
   Alex: *"the offer will be available and time-sensitive so we must be able to
   set an expiry… there should be a countdown timer on the page."*

   ⚠️ A STRIP, NOT A BADGE, and it sits under the title bar so it is on every
   screen of the flow — the bump, the plans and the card. Somebody who reaches
   the card three minutes later must still be able to see how long they have,
   and a deadline that appears once and then hides is a deadline nobody plans
   around.

   ⚠️ Gold, not red. The colour is doing "this ends" and not "something is
   wrong"; --k-gold is the same pair the launch badge already uses, so a
   deadline reads as part of the offer rather than as an error. It only turns
   red once it HAS expired, which is the one moment it is bad news. */
.ock-clock{
  display:flex; align-items:center; justify-content:center; gap:9px;
  flex:0 0 auto; padding:11px 16px;
  border-bottom:1px solid var(--k-line);
  background:var(--k-goldsoft); color:var(--k-gold);
  font-size:13px; font-weight:650; letter-spacing:.01em;
}
.ock-clock-lab{opacity:.85;}
/* ⚠️ TABULAR NUMERALS AND A FIXED WIDTH, OR IT WOBBLES. Alex asked for a real
   second-by-second countdown (2026-09-08), and a proportional font re-lays the
   whole row out every time a 1 becomes a 2 — which reads as the page glitching
   once a second rather than as a clock. `tabular-nums` gives every digit the
   same advance; the mono stack is the same one the explainer's counter uses. */
.ock-clock-num{
  font-family:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  font-variant-numeric:tabular-nums; font-size:15.5px; font-weight:700;
  letter-spacing:.02em; color:var(--k-ink);
}
@media(max-width:640px){
  .ock-clock{padding:10px 12px; gap:7px; font-size:12px;}
  .ock-clock-num{font-size:15px;}
}
/* A quiet pulse. Slow enough to read as a clock rather than an alarm, and it
   stops entirely once the offer is over — a dot still ticking under "this offer
   has expired" would be the screen contradicting itself. */
.ock-clock-dot{
  width:6px; height:6px; border-radius:50%; background:currentColor;
  animation:ock-clock-pulse 2s ease-in-out infinite;
}
@keyframes ock-clock-pulse{ 0%,100%{opacity:1;} 50%{opacity:.25;} }

.ock-clock-out{ background:#fdeaea; color:#a33; }
.ock-clock-out .ock-clock-dot{ animation:none; opacity:.45; }
.ock-clock-out .ock-clock-num{ display:none; }

/* ⚠️ Respect the OS setting. A pulsing dot is decoration; the words carry the
   whole message without it. */
@media (prefers-reduced-motion:reduce){
  .ock-clock-dot{ animation:none; }
}

/* ⚠️ THE COLUMNS SCROLL, THE PANEL DOES NOT. Nine tier rows plus the order
   block is taller than a laptop; only this region moves. */
.ock-cols{
  flex:1 1 auto; overflow-y:auto; overscroll-behavior:contain;
  display:grid; grid-template-columns:1fr;
}
@media(min-width:880px){ .ock-cols{grid-template-columns:1.15fr .85fr;} }
.ock-l{padding:24px 26px;}
.ock-r{padding:24px 26px; background:var(--k-cream); border-top:1px solid var(--k-line);}
@media(min-width:880px){ .ock-r{border-top:0; border-left:1px solid var(--k-line);} }
@media(max-width:640px){ .ock-l,.ock-r{padding:18px 16px;} }

.ock-h{
  font-family:Fraunces,Georgia,serif; font-weight:800; font-size:27px;
  letter-spacing:-.022em; line-height:1.1; margin:0 0 5px;
}
@media(max-width:640px){ .ock-h{font-size:22px;} }
.ock-sub{font-size:13.5px; color:var(--k-ink2); margin:0 0 18px;}

.ock-iv{display:inline-flex; gap:3px; padding:3px; background:var(--k-cream2); border-radius:9px; margin:0 0 16px;}
.ock-iv button{
  border:0; cursor:pointer; font-family:inherit; font-size:11.5px; font-weight:600;
  padding:6px 13px; border-radius:6px; background:transparent; color:var(--k-ink3);
  transition:background .15s, color .15s;
}
.ock-iv button.on{background:#fff; color:var(--k-ink); box-shadow:0 1px 3px rgba(42,32,48,.13);}
.ock-save{
  font-family:"JetBrains Mono",ui-monospace,monospace; font-size:9px;
  letter-spacing:.06em; color:var(--k-good); margin-left:5px;
}

.ock-tiers{display:grid; gap:9px; margin:0 0 4px;}
.ock-tier{
  display:flex; gap:12px; align-items:flex-start; text-align:left; width:100%;
  border:1.5px solid var(--k-line); background:#fff; border-radius:12px; padding:13px 14px;
  cursor:pointer; font-family:inherit; transition:border-color .15s, background .15s;
}
.ock-tier:hover{border-color:var(--k-linestrong);}
.ock-tier.on{border-color:var(--k-accent); background:var(--k-accentsoft);}
.ock-radio{
  width:17px; height:17px; border-radius:50%; border:1.5px solid var(--k-linestrong);
  flex:0 0 auto; margin-top:2px; background:#fff; position:relative;
}
.ock-tier.on .ock-radio{border-color:var(--k-accent);}
.ock-tier.on .ock-radio::after{content:""; position:absolute; inset:3px; border-radius:50%; background:var(--k-accent);}
.ock-body{flex:1; min-width:0;}
.ock-nm{display:flex; align-items:center; gap:8px; flex-wrap:wrap; font-size:14.5px; font-weight:700; line-height:1.2;}
.ock-pop{
  font-family:"JetBrains Mono",ui-monospace,monospace; font-size:8.5px;
  letter-spacing:.09em; text-transform:uppercase; padding:2px 6px; border-radius:4px;
  background:var(--k-goldsoft); color:var(--k-gold);
}
.ock-bl{display:block; font-size:12.5px; color:var(--k-ink2); margin:3px 0 6px; line-height:1.4;}
.ock-caps{display:flex; flex-wrap:wrap; gap:4px 12px; font-size:11.5px; color:var(--k-ink3);}
.ock-caps b{color:var(--k-ink2); font-weight:600; font-variant-numeric:tabular-nums;}
.ock-pr{text-align:right; flex:0 0 auto;}
.ock-pr b{display:block; font-size:17px; font-weight:700; line-height:1.1; font-variant-numeric:tabular-nums;}
.ock-u{display:block; font-size:11px; color:var(--k-ink3);}
/* ⚠️ "paid annually" rides UNDER the monthly figure, never replaces it. */
.ock-pa{
  display:block; font-size:9.5px; color:var(--k-good); margin-top:2px;
  font-family:"JetBrains Mono",ui-monospace,monospace; letter-spacing:.03em;
}

.ock-next{
  background:var(--k-goodsoft); border:1px solid rgba(79,124,84,.26);
  border-radius:11px; padding:12px 14px; margin-top:16px;
}
.ock-nk{
  font-family:"JetBrains Mono",ui-monospace,monospace; font-size:9.5px;
  letter-spacing:.09em; text-transform:uppercase; color:var(--k-good); margin:0 0 6px;
}
.ock-next ul{margin:0; padding:0; list-style:none; display:grid; gap:5px;}
.ock-next li{font-size:12.5px; color:var(--k-ink2); display:flex; gap:7px; align-items:flex-start; line-height:1.4;}
.ock-next li::before{content:"\2713"; color:var(--k-good); font-weight:700; flex:0 0 auto;}

.ock-sh{
  font-family:"JetBrains Mono",ui-monospace,monospace; font-size:10px;
  letter-spacing:.1em; text-transform:uppercase; color:var(--k-ink3); margin:0 0 11px;
}
.ock-srow{display:flex; justify-content:space-between; gap:12px; font-size:13.5px; padding:4px 0;}
.ock-srow b{font-variant-numeric:tabular-nums;}
.ock-free{color:var(--k-good);}
.ock-tot{border-top:1px solid var(--k-linestrong); margin-top:8px; padding-top:10px; font-weight:700; font-size:15px;}
.ock-note{font-size:11.5px; color:var(--k-ink3); margin:9px 0 0; line-height:1.5;}
.ock-note b{color:var(--k-ink2);}

.ock-cardrow{
  display:flex; align-items:center; gap:11px; background:#fff;
  border:1.5px solid var(--k-line); border-radius:11px; padding:11px 13px; margin:16px 0 0;
}
.ock-brand{
  width:34px; height:23px; border-radius:4px; flex:0 0 auto;
  background:linear-gradient(135deg,#1a1f71,#2b3a9e); color:#fff;
  font-size:8px; font-weight:800; letter-spacing:.03em;
  display:flex; align-items:center; justify-content:center; text-transform:uppercase;
}
.ock-ctxt{flex:1; min-width:0;}
.ock-l1{display:block; font-size:13px; font-weight:600; line-height:1.25;}
.ock-l2{display:block; font-size:11px; color:var(--k-ink3); line-height:1.3;}
.ock-chg{
  flex:0 0 auto; background:none; border:0; cursor:pointer; font-family:inherit;
  font-size:12px; color:var(--k-ink3);
  text-decoration:underline; text-decoration-color:var(--k-linestrong);
}
.ock-chg:hover{color:var(--k-accent);}

.ock-field{margin-top:16px;}
.ock-flabel{display:block; font-size:12px; font-weight:600; color:var(--k-ink2); margin:0 0 6px;}
.ock-cardel{
  border:1.5px solid var(--k-line); border-radius:10px; background:var(--k-cream2);
  padding:13px 14px; transition:border-color .15s, background .15s, box-shadow .15s;
}
.ock-cardel.ock-focus{border-color:var(--k-accent); background:#fff; box-shadow:0 0 0 4px rgba(106,76,241,.12);}

.ock-err{margin:11px 0 0; font-size:13px; color:var(--k-bad);}
/* The node is now always rendered so a failure can be reported by writing text
   into it rather than rebuilding the panel (that rebuild was a render loop —
   see mountCardElement). Empty means no error, and no error must take no space
   or every panel gains 11px of nothing. */
.ock-err:empty{display:none;}

.ock-go{
  margin-top:15px; width:100%; background:var(--k-buy); color:#fff; border:0;
  cursor:pointer; font-family:inherit; border-radius:999px; padding:14px 20px;
  font-size:15px; font-weight:700; box-shadow:0 12px 28px -10px var(--k-buy);
  display:flex; align-items:center; justify-content:center; text-align:center; line-height:1.3;
}
.ock-go:hover{background:var(--k-buydeep);}
.ock-go[disabled]{opacity:.6; cursor:default;}
.ock-pan{
  text-align:center; margin:8px 0 0; font-size:11px; color:var(--k-good);
  font-family:"JetBrains Mono",ui-monospace,monospace; letter-spacing:.04em;
}
.ock-trust{display:flex; justify-content:center; flex-wrap:wrap; gap:5px 14px; margin:11px 0 0; font-size:11px; color:var(--k-ink3);}
.ock-trust span{display:inline-flex; align-items:center; gap:5px;}
.ock-trust span::before{content:""; width:5px; height:5px; border-radius:50%; background:var(--k-good);}

/* Under the button, not above it: they are for the person who has stalled,
   and someone who has stalled is looking at the button. */
.ock-tst{display:grid; gap:9px; margin-top:18px;}
.ock-t{background:#fff; border:1px solid var(--k-line); border-radius:11px; padding:12px 13px;}
.ock-st{color:#d9a441; font-size:10px; letter-spacing:2px; margin:0;}
.ock-q{font-size:12.5px; color:var(--k-ink2); line-height:1.5; margin:6px 0 8px;}
.ock-w{display:flex; align-items:center; gap:7px; margin:0;}
.ock-av{width:26px; height:26px; border-radius:50%; flex:0 0 auto; overflow:hidden; background:var(--k-cream2);}
.ock-av img{width:100%; height:100%; object-fit:cover; display:block;}
.ock-n{display:block; font-size:11.5px; font-weight:650; line-height:1.2;}
.ock-n em{display:block; font-style:normal; font-weight:400; font-size:10px; color:var(--k-ink3);}

@media (max-width:640px){
  .ock-overlay{padding:0;}
  /* 🚨 THE SAME `100vh` FAULT THE OFFER PANEL BELOW ALREADY FIXED. The note
     under `.ock-panel.ock-offer` describes this exactly — mobile browser chrome
     makes `100vh` taller than what is visible, so the bar crops under the
     address bar — and then the fix was applied only to the offer, leaving the
     ORDINARY full-bleed checkout with the original bug. Same correction here,
     and `height:100%` of a `position:fixed; inset:0` overlay needs no viewport
     unit at all. */
  .ock-panel{
    max-width:none; border-radius:0;
    height:100%; max-height:100%;
    height:100dvh; max-height:100dvh;
  }
  /* ⚠️ …BUT NOT THE OFFER. See the note where `ock-offer` is set. It keeps its
     tint, its corners and its edges on a phone, so it reads as a modal over
     the community screen rather than a new place the app has taken them.
     `100dvh` because mobile browser chrome makes `100vh` taller than what is
     actually visible — which is how the top bar ended up cropped under the
     address bar in Alex's screenshot. */
  .ock-overlay:has(.ock-offer){padding:14px;}
  .ock-panel.ock-offer{
    max-height:calc(100dvh - 28px); height:auto; border-radius:16px;
  }
}
/* `:has()` is the clean expression of "the overlay containing the offer", and
   it is supported everywhere this app runs — but a browser without it would
   silently fall back to the full-bleed rule above, which is the very thing
   being fixed. So the padding is also set from the overlay's own class, which
   plan-checkout.js puts there at open time and needs no selector support. */
@media (max-width:640px){
  .ock-overlay.ock-has-offer{padding:14px;}
}
@media (prefers-reduced-motion:reduce){ .ock-tier,.ock-iv button,.ock-go{transition:none;} }

/* ── Billing address (country · line 1 · postal code) ──────────────────
   Alex, 2026-08-25: *"Put the postal code back in but make sure that it
   geo-detects… first line of address and postcode just maximises the chance of
   approval."* Rationale and the Stripe quotes behind it:
   docs/projects/billing/STRIPE-AUTH-RESEARCH.md.

   Markup comes from the SHARED module (js/billing-address-fields.js) with
   prefix `ock`, so these rules dress a block the homepage modal also uses in
   its own palette. Only the skin lives here; the behaviour lives once. */
.ock-addr { display: flex; flex-direction: column; gap: 10px; margin-bottom: 12px; }
.ock-addr .ock-field { display: flex; flex-direction: column; gap: 5px; }
.ock-addr label {
  font-size: 11.5px; font-weight: 600; letter-spacing: .01em; color: var(--k-ink3);
}
.ock-addr input,
/* A long country name truncates with an ELLIPSIS, not mid-word. Same rule as
   the subnav labels: a cut you cannot see reads as the real text. */
.ock-addr select {
  text-overflow: ellipsis;
  font-family: inherit; font-size: 14.5px; color: var(--k-ink);
  background: #fff; border: 1px solid var(--k-line); border-radius: 9px;
  padding: 10px 12px; width: 100%;
  /* ⚠️ The Stripe Element next to these is 14.5px on a 1px --k-line border with
     the same radius. Any drift here and the address block reads as a different
     form bolted on above the card, which is exactly what it must not look like. */
  transition: border-color .14s, box-shadow .14s;
}
.ock-addr select {
  appearance: none; -webkit-appearance: none;
  /* The caret is a data URI: the CSP blocks external images, and a select with
     no affordance reads as a disabled text box. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238b7e92' stroke-width='2.4'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center;
  padding-right: 34px;
}
.ock-addr input:focus,
.ock-addr select:focus {
  outline: none; border-color: var(--k-accent);
  box-shadow: 0 0 0 3px var(--k-accentsoft);
}
.ock-addr [hidden] { display: none; }

/* The Back slot when there is nothing behind this checkout.

   ⚠️ A SPACER, NOT `display:none`. `.ock-bar` centres its title between the two
   controls; removing the left one shunts the title off-centre and the ✕ looks
   misplaced. Only Outreach has an explainer to go back to, so every other plan
   renders this instead. Width matches `.ock-back`'s rendered box. */
.ock-back-sp { display: inline-block; width: 58px; flex: 0 0 auto; }

/* Country + postcode share a row: see billing-address-fields.js. Stacked, the
   block cost 244px and pushed the mobile submit button ~200px below the fold. */
.ock-addr .ock-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
/* 🚨 `min-width:0` OR THE COLUMNS ARE NOT EQUAL. A grid item defaults to
   `min-width:auto`, so the text input refuses to shrink below its
   min-content width (~20 characters) and eats the row — which squeezed
   the country select to 84px and rendered "United Kingdom" as "Unite".
   The same flexbox/grid default that made the subnav label overflow. */
.ock-addr .ock-row > * { min-width: 0; }
@media (max-width: 359px) { .ock-addr .ock-row { grid-template-columns: 1fr; } }

/* ── The community launch offer ────────────────────────────────────────
   Shown only when `/api/subscription/overview` returned a `launch_offer` on
   the plan card, which the SERVER decided from the customer id. Brief:
   docs/projects/lead-desk/OFFER-DESIGN.md.

   ⚠️ `.ock-was` sits INSIDE `.ock-pr`, which is `text-align:right` and whose
   `b` is `display:block` — so the struck figure needs to be a block too or it
   shares a line with the price it is supposed to be crossed out above. */
.ock-lock{
  margin:10px 0 0; padding:9px 11px; border-radius:8px;
  background:var(--good-bg,#ecfdf5); border:1px solid var(--good,#059669);
  color:var(--good,#059669); font-size:13px; line-height:1.45; font-weight:500;
}
.ock-lock b{font-weight:700;}
.ock-was{
  display:block; font-size:12px; line-height:1.2;
  color:var(--text-4,#a29ec0); text-decoration:line-through;
  font-variant-numeric:tabular-nums;
}

/* ── Two steps, plan then card (§COMMUNITY-LAUNCH) ─────────────────────
   Only the offer screen carries `.ock-2step`; the ordinary checkout keeps its
   two columns side by side. ⚠️ These rules must out-specify `.ock-cols` and
   come after it, which is why they live at the end of the file — the same
   cascade trap CODING-STANDARDS records for `.cc-page .btn`. */
/* Two screens. The card is not a third — it appears BENEATH the plans on the
   second one, which keeps the tiers a scroll away instead of a back button. */
.ock-cols.ock-2step{display:block;}
.ock-cols.ock-2step .ock-bump,
.ock-cols.ock-2step .ock-l,
.ock-cols.ock-2step .ock-r{display:none;}
.ock-cols.ock-2step.ock-step-1 .ock-bump{display:block;}
.ock-cols.ock-2step.ock-step-2 .ock-l{display:block;}
.ock-cols.ock-2step.ock-step-2.ock-picked .ock-r{display:block;}
.ock-continue{margin-top:16px;}

/* ── The risk, taken off before the prices go on ───────────────────── */
.ock-risk{
  margin:0 0 16px; padding:14px 16px; border-radius:12px;
  background:var(--k-goodsoft,#e4ecdc); border:1px solid var(--k-good,#4f7c54);
}
.ock-rh{margin:0 0 4px; font-size:17px; font-weight:750; color:var(--k-good,#4f7c54);}
.ock-rp{margin:0; font-size:13.5px; line-height:1.5; color:var(--k-ink2,#5a4d62);}
.ock-rp b{color:var(--k-ink,#2a2030); font-weight:650;}

/* The reason to pick up rather than down. Quiet, because it is a condition
   rather than a boast — but it is the sentence that decides the tier. */
.ock-lockin{
  margin:14px 0 0; padding:11px 13px; border-radius:10px;
  background:var(--k-accentsoft,#ece6ff);
  font-size:13px; line-height:1.5; color:var(--k-accentdeep,#4a32b8);
}
.ock-tst-plans{margin-top:16px;}

/* ── Screen one: the bump ──────────────────────────────────────────────
   One number, one promise, one button. Everything here is sized against the
   per-lead figure rather than against the panel, because that figure is the
   argument and the rest is context for it. */
.ock-bump{padding:30px 26px 26px; max-width:620px; margin:0 auto; text-align:center;}
.ock-eye{
  display:inline-flex; align-items:center; gap:7px;
  margin:0 0 12px; padding:5px 12px 5px 8px; border-radius:999px;
  font-size:11.5px; letter-spacing:.07em; text-transform:uppercase; font-weight:650;
  color:var(--k-good,#4f7c54); background:var(--k-goodsoft,#e4ecdc);
}
.ock-tick{display:inline-flex; align-items:center; justify-content:center;}
/* ⚠️ BALANCED, BECAUSE THIS HEADLINE HAS FOUR VERSIONS AND ONE OF THEM ORPHANS.
   The greeting degrades through four sentences of different lengths, and the
   shortest — "Your community needs people in it." — broke with "it." alone on
   its own line at 390px. `balance` evens the lines instead of filling the first;
   browsers without it are exactly where they were. */
.ock-bh{text-wrap:balance;margin:0 0 10px; font-size:25px; line-height:1.25; font-weight:700; letter-spacing:-.01em;}
/* The fork in the road. Deliberately smaller than the headline and larger than
   the terms below the price — it is the sentence that turns an interruption
   into a decision, and it has to be read. */
.ock-blead{
  margin:0 auto 20px; max-width:470px;
  font-size:15.5px; line-height:1.5; color:var(--k-ink2,#5a4d62);
}
.ock-blead b{color:var(--k-ink,#2a2030); font-weight:650;}
/* ⚠️ THE UNIT IS AS BIG AS THE NUMBER. "$0.32" alone means nothing; "$0.32 per
   lead" is the whole offer. Alex: *"that line should be … equally prominent."* */
.ock-lead{
  margin:0 0 18px; padding:18px 16px 14px;
  background:var(--k-cream,#faf6ec); border:1px solid var(--k-line,#ebe1c9); border-radius:14px;
}
.ock-lrow{
  display:flex; align-items:baseline; justify-content:center; flex-wrap:wrap; gap:10px;
}
/* Who the leads are, under the number that prices them. Quiet on purpose: the
   figure is the headline and this is the reason to believe it. */
/* ⚠️ THE TEXT IS ONE FLEX ITEM, NOT THREE. Written without the wrapping span,
   the <b> made the line three items and flexbox laid them out as three columns
   — "Each one / targeted on / the" stacked beside "goals and / the pain".
   Caught by rendering it. Anything with inline emphasis inside a flex row needs
   its own box. */
.ock-lmatch{
  display:flex; align-items:center; justify-content:center; gap:7px;
  margin:12px 0 0; padding-top:11px; border-top:1px solid var(--k-line,#ebe1c9);
  font-size:13px; line-height:1.45; color:var(--k-ink3,#8b7e92); text-align:left;
}
.ock-lmatch span{flex:0 1 auto;}
.ock-lmatch svg{flex:0 0 auto; color:var(--k-accent,#6a4cf1);}
.ock-lmatch b{color:var(--k-ink,#2a2030); font-weight:650;}
.ock-lwas{
  font-size:26px; font-weight:600; color:var(--k-ink4,#b8acbb);
  text-decoration:line-through; font-variant-numeric:tabular-nums;
}
.ock-lnow{
  font-size:46px; font-weight:800; line-height:1; letter-spacing:-.02em;
  color:var(--k-accent,#6a4cf1); font-variant-numeric:tabular-nums;
}
.ock-lunit{font-size:22px; font-weight:700; color:var(--k-ink,#2a2030);}
.ock-bl1 b{white-space:nowrap;}
.ock-bl1{margin:0 0 6px; font-size:15px; line-height:1.5; color:var(--k-ink2,#5a4d62);}
.ock-bl2{margin:0 0 22px; font-size:15px; line-height:1.5; color:var(--k-ink2,#5a4d62);}
.ock-byes{width:100%; max-width:380px; margin:0 auto;}
/* ⚠️ THE WAY OUT IS PLAIN TEXT, NOT A GREYED BUTTON. Alex asked for something
   *"a bit more subtle"* than confirmshaming: it names the price in their own
   words and does not sulk. It is findable, which is the point — the screen is
   already hard to leave by accident. */
.ock-bno{
  display:block; margin:14px auto 0; background:none; border:none; padding:8px;
  font:inherit; font-size:13px; color:var(--k-ink3,#8b7e92); text-decoration:underline;
  cursor:pointer;
}
.ock-bno:hover{color:var(--k-ink,#2a2030);}
.ock-tst-bump{margin-top:26px; text-align:left;}
/* The leads page video test's explainer (plan-checkout.js explainerHtml).
   Between the line that names the work and the price, the width of the price
   box, so it reads as part of the argument rather than an interruption of it.
   16:9 held by padding rather than aspect-ratio, because the runtime mounts the
   <video> absolutely inside `.video-player`. */
.ock-vid{margin:0 0 18px;}
.ock-vid-frame{
  position:relative; width:100%; padding-top:56.25%; overflow:hidden;
  border-radius:14px; background:#f5f4ef;
  box-shadow:0 10px 28px -12px rgba(42,32,48,.45), 0 0 0 1px var(--k-line,#ebe1c9);
}
.ock-vid-frame .video-player{position:absolute; inset:0;}
.ock-vid-facade{
  position:absolute; inset:0; width:100%; height:100%; padding:0; border:0; cursor:pointer;
  background:#f5f4ef center/cover no-repeat;
}
.ock-vid-play{
  /* In the ring at the centre of the poster, where the leads are heading.
     ⚠️ DARK, NOT THE ACCENT. Alex, 2026-09-29: the purple *"matches the same
     colour as the leads"* (the $0.32 above it), so it read as part of the price
     rather than as a video. A dark disc with a white triangle is what a video
     looks like everywhere, and it competes with neither the price nor the pink
     Yes button. */
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  display:inline-flex; align-items:center; justify-content:center;
  width:64px; height:64px; border-radius:50%; padding-left:4px;
  color:#fff; background:rgba(21,23,43,.86);
  box-shadow:0 8px 24px rgba(21,23,43,.35), 0 0 0 4px rgba(255,255,255,.95);
  transition:transform .15s ease;
}
.ock-vid-facade:hover .ock-vid-play{transform:translate(-50%,-50%) scale(1.06);}
.ock-vid-facade:focus-visible{outline:3px solid var(--k-accent,#6a4cf1); outline-offset:3px;}
.ock-vid-cap{
  margin:9px 0 0; font-size:13px; line-height:1.4; color:var(--k-ink3,#8b7e92);
}
.ock-vid-len{
  display:inline-block; margin-left:6px; padding:1px 7px; border-radius:999px;
  font-size:11.5px; font-weight:650; font-variant-numeric:tabular-nums;
  color:var(--k-ink2,#5a4d62); background:var(--k-cream,#faf6ec); border:1px solid var(--k-line,#ebe1c9);
}
.ock-vid-sound{
  /* The autoplay version's way to the sound: top left, over the film, never
     over the words it is showing. It starts the film again from the top. */
  position:absolute; left:10px; top:10px; z-index:6;
  display:inline-flex; align-items:center; gap:7px;
  padding:7px 12px 7px 10px; border:0; border-radius:999px; cursor:pointer;
  font:inherit; font-size:12.5px; font-weight:650; color:#fff;
  background:rgba(29,22,36,.78); box-shadow:0 4px 14px rgba(0,0,0,.25);
}
.ock-vid-sound:hover{background:rgba(29,22,36,.92);}
.ock-vid-sound:focus-visible{outline:3px solid var(--k-accent,#6a4cf1); outline-offset:2px;}
.ock-vid-sound[hidden]{display:none;}
@media (prefers-reduced-motion:reduce){ .ock-vid-play{transition:none;} }
@media (max-width:520px){
  .ock-bump{padding:22px 18px;}
  .ock-vid-play{width:50px; height:50px; box-shadow:0 5px 14px rgba(21,23,43,.3), 0 0 0 3px rgba(255,255,255,.95);}
  .ock-vid-play svg{width:18px; height:18px;}
  .ock-bh{font-size:21px;}
  .ock-blead{font-size:14.5px;}
  .ock-lnow{font-size:38px;}
  .ock-lwas{font-size:21px;}
  .ock-lunit{font-size:18px;}
}

/* The per-lead figure on each tier card — the only number that ranks the
   three honestly. See the note in plan-checkout.js. */
/* ⚠️ AS PROMINENT AS THE MONTHLY FIGURE, NOT A FOOTNOTE UNDER IT. The whole
   argument for the top tier is that its per-lead price is the lowest, and a
   12px line under an 18px one loses that argument before it is read. */
.ock-pl{
  display:block; margin-top:5px; font-size:12px; color:var(--k-ink2,#5a4d62);
  font-variant-numeric:tabular-nums;
}
.ock-pl b{display:block; font-size:18px; font-weight:750; color:var(--k-accent,#6a4cf1);}

/* Screen three: the answer to the fear, before the field that causes it. */
.ock-payh{margin:0 0 4px; font-size:22px; line-height:1.2; font-weight:750;}
.ock-pays{margin:0 0 16px; font-size:14px; line-height:1.5; color:var(--k-ink2,#5a4d62);}

/* An initials avatar, for a quote whose photograph is unresolved. */
.ock-ini{
  display:flex; align-items:center; justify-content:center; width:100%; height:100%;
  border-radius:50%; background:var(--k-accentsoft,#ece6ff); color:var(--k-accentdeep,#4a32b8);
  font-size:11px; font-weight:700; letter-spacing:.03em;
}
.ock-toplans{
  background:none; border:none; padding:4px 0; margin:0 0 10px;
  font:inherit; font-size:13px; color:var(--text-3,#77738f); cursor:pointer;
}
.ock-toplans:hover{color:var(--text,#1c1a2e);}

/* ── The two screens on the way out ────────────────────────────────────
   ⚠️ POLISHED DELIBERATELY, NOT LEFT PLAIN. Alex, 2026-09-07: *"Are those two
   steps actually looking nice? I think we could polish it up a little bit."*
   These are the last things somebody sees before deciding against us, which is
   exactly the moment the product should look like it was cared about. They stay
   small and centred, because each is one question rather than a screen. */
.ock-confirm{max-width:400px; margin:0 auto; padding:30px 24px 26px; text-align:center;}
.ock-confirm-wide{max-width:440px;}
.ock-cmark{
  width:46px; height:46px; margin:0 auto 14px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:var(--k-goldsoft,#faf0d8); color:var(--k-gold,#b8860b);
}
/* The same disc, in the one place on this panel where the news is good. Green
   rather than gold because a tick in a warning colour reads as "done, but…". */
.ock-cmark-ok{background:var(--k-goodsoft,#e4ecdc); color:var(--k-good,#4f7c54);}

.ock-ch{margin:0 0 8px; font-size:21px; line-height:1.25; font-weight:700; letter-spacing:-.01em;}
.ock-cp{margin:0 0 20px; font-size:14.5px; line-height:1.55; color:var(--k-ink2,#5a4d62);}
/* ⚠️ AFTER .ock-cp, NOT BEFORE IT. The element carries both classes, they have
   equal specificity, so source order is the whole of the cascade here. */
.ock-cnext{margin:-8px 0 20px; font-size:14px;}
.ock-cbtns{display:flex; flex-direction:column; gap:6px;}
.ock-cdecline{
  background:none; border:none; padding:11px; font:inherit; font-size:13px;
  color:var(--k-ink3,#8b7e92); text-decoration:underline; cursor:pointer;
}
.ock-cdecline:hover{color:var(--k-ink,#2a2030);}

/* The reason list. Buttons rather than a select, because a tap is the whole
   interaction and a dropdown asks for two — and a visible dot, because the
   choice now survives until Send and has to be legible while it does. */
.ock-reasons{display:flex; flex-direction:column; gap:7px; margin:0 0 14px; text-align:left;}
/* ⚠️ `text-align:left` EXPLICITLY. `.ock-confirm` centres its children, and a
   row long enough to wrap then centres its second line under its first — which
   made "I'm not sure it works for my kind of coaching" the only ragged item in
   a list of six. Flex aligns the box, not the text inside it. */
.ock-reason{
  display:flex; align-items:center; gap:11px; width:100%; cursor:pointer; text-align:left;
  font:inherit; font-size:14px; line-height:1.35; padding:12px 14px; border-radius:11px;
  color:var(--k-ink,#2a2030); border:1px solid var(--k-line,#ebe1c9); background:#fff;
  transition:border-color .12s, background .12s;
}
.ock-reason:hover{border-color:var(--k-linestrong,#d8cdaf); background:var(--k-cream,#faf6ec);}
.ock-rdot{
  width:17px; height:17px; flex:0 0 auto; border-radius:50%;
  border:1.5px solid var(--k-linestrong,#d8cdaf); background:#fff;
  transition:border-color .12s, box-shadow .12s;
}
.ock-reason.on{border-color:var(--k-accent,#6a4cf1); background:var(--k-accentsoft,#ece6ff);}
.ock-reason.on .ock-rdot{
  border-color:var(--k-accent,#6a4cf1);
  box-shadow:inset 0 0 0 3.5px #fff, inset 0 0 0 9px var(--k-accent,#6a4cf1);
}
.ock-rnote{
  display:block; width:100%; box-sizing:border-box; margin:0 0 14px; padding:10px 12px;
  border:1px solid var(--k-line,#ebe1c9); border-radius:10px; resize:vertical;
  font:inherit; font-size:14px; color:var(--k-ink,#2a2030); background:#fff;
}
.ock-rnote:focus{outline:none; border-color:var(--k-accent,#6a4cf1);}
/* ⚠️ DISABLED UNTIL SOMETHING IS PICKED, AND IT SAYS SO. A greyed button with
   no explanation is a dead end; "Pick one" is the instruction. */
.ock-rsend{width:100%;}
.ock-rsend[disabled]{opacity:.4; cursor:default; box-shadow:none;}

/* A door's own "what comes with this" line (challenge.js passes the Show Up
   Weekly & Grow bonus as `bonusLine`; no other door does). */
.ock-bonus { margin: 0 0 12px; padding: 10px 12px; border-radius: 10px; background: #ecfdf5; color: #065f46; font-size: 14.5px; line-height: 1.45; font-weight: 600; }
.ock-bonusrow b.ock-free { color: #059669; }
/* N1: the bonus door's close, one line and one button. */
.ock-keep .ock-ch { font-size: 20px; line-height: 1.35; }
.ock-kmark { background: var(--k-goodsoft, #e4ecdc); color: var(--k-good, #4f7c54); font-size: 20px; }
