/* TellMabel marketing design system — from design_handoff_tellmabel v2.
   Fonts (Newsreader + Hanken Grotesk) load via a Google Fonts <link> in the head.
   Phone-mock internals use the system font stack so they read as real iMessage screenshots. */

:root {
  --nude:#ECDCCF; --cream:#F6F0E7; --white:#FFFFFF;
  --maroon:#5C2A31; --deep:#3A2328; --footer:#2A1B1F;
  --body:#6A554F; --body2:#7A655E; --muted:#8A7068; --muted2:#9A8478;
  --eyebrow:#7A5A35; --salmon:#D87E7E; --on-salmon:#4A2129;
  /* A lighter step of the salmon, for the shallow end of a ramp of otherwise-equal buttons (the account
     page's plan picker). Carries --on-salmon at 7.3:1, so it stays a real button, not a ghost one. */
  --salmon-soft:#EBB0A8;
  --card-border:#ECE0D0; --line:#E0D6C8; --hair:#E2D8C8;
  --serif:'Newsreader', Georgia, 'Times New Roman', serif;
  --sans:'Hanken Grotesk', -apple-system, system-ui, Segoe UI, Roboto, sans-serif;
  --card-shadow:0 18px 50px rgba(60,35,30,.16);
  --phone-shadow:0 22px 48px rgba(50,28,24,.30);
}

* { box-sizing:border-box; }
html { scroll-behavior:smooth; }
body { margin:0; font-family:var(--sans); color:var(--body); background:var(--nude);
  font-size:16px; line-height:1.5; -webkit-font-smoothing:antialiased; }
svg { display:block; }
a { color:inherit; }

/* ---- shared bits ---- */
.mk-eyebrow { font:700 12px var(--sans); letter-spacing:.12em; color:var(--eyebrow); text-transform:uppercase; }
.mk-serif { font-family:var(--serif); color:var(--maroon); font-weight:600; }
.mk-ava { border-radius:50%; overflow:hidden; display:flex; align-items:center; justify-content:center; flex:none; }
.mk-ava svg { width:120%; height:120%; }
.mk-ava.on-nude { background:var(--nude); }
.mk-ava.on-white { background:var(--white); }

.mk-btn { display:flex; align-items:center; justify-content:center; gap:8px; text-decoration:none;
  border:0; cursor:pointer; font-family:var(--sans); font-weight:700; border-radius:15px; padding:16px 24px;
  font-size:17px; width:100%; }
.mk-btn-primary { background:var(--salmon); color:var(--on-salmon); }
.mk-btn-secondary { background:var(--maroon); color:#F6E9DF; }
.mk-btn:focus-visible { outline:3px solid var(--maroon); outline-offset:2px; }
/* Busy state for a button that hands off to something slow we don't own — today only "go to Stripe",
   which is ~0.8s of our own API round trips before Stripe's page even starts loading. The spinner is a
   real child element, not a ::after, because .mk-btn is already a flex row with a gap: it lines up next
   to the label for free, and the label stays real text for screen readers. */
.mk-btn[aria-busy="true"] { opacity:.72; cursor:default; }
.mk-spin { width:17px; height:17px; flex:0 0 auto; border-radius:50%; border:2px solid currentColor;
  border-top-color:transparent; animation:mk-spin .7s linear infinite; }
@keyframes mk-spin { to { transform:rotate(360deg); } }
/* Reduced motion gets a slow sweep rather than nothing: a frozen ring next to "Taking you to Stripe…"
   reads as hung, which is the opposite of what this element is for. */
@media (prefers-reduced-motion: reduce) { .mk-spin { animation-duration:2.4s; } }

/* ---- header / footer ---- */
.mk-header { display:flex; align-items:center; justify-content:space-between; padding:16px 22px; }
.mk-brand { display:flex; align-items:center; gap:8px; text-decoration:none; }
.mk-brand .mk-ava { width:28px; height:28px; background:var(--white); }
.mk-wordmark { font-family:var(--serif); font-size:20px; font-weight:600; color:var(--maroon); }
/* Compliance "pill": the Trust & compliance link + A2P badge grouped into one salient rounded chip in
   the top-right — the badge falls inline to the right of the text. Shared by the mobile header link
   (.mk-navlink) and the desktop nav item (.mk-nav-compliance). */
.mk-navlink, .mk-nav-compliance { display:flex; flex-direction:row; align-items:center; gap:8px; white-space:nowrap;
  background:var(--white); border:1px solid #E6D6C7; border-radius:999px; padding:4px 8px 4px 15px;
  box-shadow:0 2px 9px rgba(50,28,24,.08); color:var(--maroon); font:600 12.5px var(--sans); text-decoration:none; }
.mk-nav-badge { width:36px; height:36px; display:block; flex:none; }
.mk-nav-desktop { display:none; align-items:center; gap:28px; font:500 14.5px var(--sans); color:var(--body); }
.mk-nav-desktop a { text-decoration:none; }
/* .mk-nav-compliance shares the pill styling above (grouped with .mk-navlink). */
.mk-nav-desktop .mk-btn { width:auto; padding:11px 20px; font-size:15px; border-radius:11px; }

.mk-footer { background:var(--footer); padding:16px 26px 28px; display:flex; flex-direction:column; gap:12px; align-items:center; justify-content:center; }
.mk-footer .mk-wordmark { font-size:16px; color:#cdb9b0; }
.mk-footer-login { font-family:var(--sans); font-size:13px; font-weight:600; color:#e8dcd4; text-decoration:none; border:1px solid rgba(255,255,255,.22); border-radius:999px; padding:6px 18px; transition:background .15s ease, border-color .15s ease; }
.mk-footer-login:hover { background:rgba(255,255,255,.08); border-color:rgba(255,255,255,.4); }
/* legal disclosure: text on the left, A2P 10DLC badge to the right of it (stacks on mobile) */
.mk-legal-row { display:flex; flex-direction:column; gap:16px; align-items:center; }
.mk-legal-text { flex:1; min-width:0; }
.mk-legal-badge { flex:none; }
.mk-legal-badge img { width:104px; height:104px; display:block; }
@media (min-width:760px){
  .mk-legal-row { flex-direction:row; align-items:center; gap:32px; }
  .mk-legal-badge img { width:124px; height:124px; }
}

/* simple content page (e.g. /compliance) */
.mk-page-title { font-family:var(--serif); font-weight:600; color:var(--maroon); font-size:34px; line-height:1.12; margin:6px 0 0; }
.mk-page-body { max-width:680px; }
.mk-page-body p { font-size:16px; line-height:1.6; color:var(--body); margin:14px 0 0; }
.mk-page-body h2 { font-family:var(--serif); color:var(--maroon); font-weight:600; font-size:22px; margin:30px 0 0; }
.mk-page-body a { color:var(--maroon); }
.mk-page-body ul, .mk-page-body ol { margin:12px 0 0; padding-left:22px; }
.mk-page-body li { font-size:16px; line-height:1.6; color:var(--body); margin:8px 0 0; }
.mk-page-body strong { color:var(--deep); font-weight:600; }
.mk-page-body em { font-style:italic; }
.mk-placeholder { display:inline-block; background:#FBF3EF; border:1px dashed #C9A24A; color:#9a6a4a;
  border-radius:7px; padding:4px 10px; font-size:12.5px; margin-top:8px; }
/* compliance disclosure (business identity + SMS program) preserved in the footer for 10DLC */
.mk-legal { background:var(--footer); color:#a8938c; padding:22px 26px 6px; font-size:11.5px; line-height:1.6; }
.mk-legal .mk-inner { max-width:1180px; }
.mk-legal p { margin:0 0 10px; }
.mk-legal strong { color:#cdb9b0; font-weight:600; }
.mk-legal a { color:#b89a92; }
@media (min-width:900px){ .mk-legal { padding:34px 48px 6px; } }

/* ---- sections ---- */
.mk-section { padding:34px 26px; }
.mk-nude { background:var(--nude); } .mk-cream { background:var(--cream); }
.mk-deep { background:var(--deep); color:#F6E9DF; text-align:center; }
.mk-inner { max-width:1180px; margin:0 auto; }

/* ---- hero ---- */
.mk-hero { padding:14px 26px 30px; }
.mk-h1 { font-family:var(--serif); font-size:clamp(30px, 9.5vw, 40px); line-height:1.04; font-weight:600; color:var(--maroon); margin:0; }
/* Each sentence on its own line; nowrap keeps "Stop texting yourself." from breaking mid-line on mobile
   (the clamp above scales the size down so it always fits the viewport width). */
.mk-h1 span { display:block; white-space:nowrap; }
/* A SENTENCE headline, not a two-beat one (2026-08-19). The base .mk-h1 size is tuned for a punchy
   22-character line ("Stop texting yourself.") held on one row by the nowrap above; the hero copy is now
   a sentence long enough that at that size it overflows the viewport on mobile and runs to four or five
   enormous lines on desktop. This variant carries no <span> children on purpose — it WRAPS, and the
   smaller clamp lands it at about two lines in both places while staying the biggest type on the page.
   Re-check both widths when the sentence changes length; if the headline ever goes back to two short
   beats, drop this class rather than re-tuning it. */
.mk-h1-long { font-size:clamp(28px, 8vw, 36px); line-height:1.12; }
.mk-sub { font-size:16.5px; line-height:1.5; color:var(--body); margin:16px 0 0; max-width:520px; }
.mk-hero .mk-btn { margin-top:22px; }
.mk-trust { text-align:center; font:500 12.5px var(--sans); color:var(--muted); margin-top:12px; }
.mk-trust b { font-weight:600; color:var(--body); }
.mk-hero-media { display:flex; align-items:flex-end; justify-content:center; margin-top:28px; }
/* margin:10px 0 0 — the zero bottom is load-bearing. As a <p> it carried a ~13px UA bottom margin that
   nothing asked for, on top of whatever padding the section below it already had. */
.mk-caption { text-align:center; font:500 13.5px var(--sans); color:var(--muted); margin:10px 0 0; }
/* The homepage hero alone: its caption is answered by the signup band immediately below, so it closes
   tight instead of at the full section gap. Every other hero is followed by a change of subject and
   keeps the standard padding. */
.mk-hero-tight { padding-bottom:16px; }

.mk-mabel { flex:none; position:relative; z-index:2; margin-right:-10px; width:118px; }
.mk-mabel img { width:100%; height:auto; display:block; animation:mabelbob 4.5s ease-in-out infinite; }
@keyframes mabelbob { 0%,100%{transform:translateY(0) rotate(0)} 50%{transform:translateY(-8px) rotate(-1.6deg)} }
@media (prefers-reduced-motion:reduce){ .mk-mabel img { animation:none; } }

/* ---- iPhone hero video (spokesperson clip masked to the screen shape) ---- */
.mk-phone { flex:none; position:relative; z-index:1; width:246px; background:#0d0d0f; border-radius:34px;
  padding:8px; box-shadow:var(--phone-shadow); }
/* Dark screen background so any frame the video hasn't painted yet reads as a phone, not a white flash. */
.mk-screen { position:relative; background:#0d0d0f; border-radius:27px; overflow:hidden; }
/* The source is 9:16 (404x720); width:100%/height:auto keeps its natural aspect, so no cropping. */
.mk-hero-video { display:block; width:100%; height:auto; }
.mk-hero-sound { position:absolute; right:10px; bottom:16px; width:34px; height:34px; border-radius:50%;
  border:0; padding:0; background:rgba(13,13,15,.55); display:flex; align-items:center; justify-content:center; cursor:pointer; }
.mk-hero-sound .on { display:none; }
.mk-hero-sound.is-on .on { display:block; }
.mk-hero-sound.is-on .off { display:none; }
.mk-home-ind { position:absolute; left:50%; bottom:6px; transform:translateX(-50%);
  width:86px; height:4px; border-radius:2px; background:rgba(255,255,255,.65); }

/* ---- how it works ---- */
.mk-steps { display:flex; flex-direction:column; gap:22px; margin-top:18px; }
.mk-step { display:flex; gap:14px; align-items:flex-start; }
.mk-num { width:34px; height:34px; border-radius:50%; background:var(--maroon); color:var(--cream);
  font:600 15px var(--sans); display:flex; align-items:center; justify-content:center; flex:none; }
.mk-step-t { font:600 17px var(--sans); color:var(--deep); }
.mk-step-d { font-size:14.5px; line-height:1.45; color:var(--body); margin-top:3px; }
.mk-kicker { text-align:center; font-size:14px; color:var(--muted); line-height:1.5; max-width:42ch; margin:22px auto 0; }

/* ---- what people text (cards) ---- */
.mk-cards { display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-top:18px; }
.mk-card { background:var(--white); border-radius:16px; padding:16px; }
.mk-card-t { font:600 15px var(--sans); color:var(--deep); }
.mk-card-d { font-size:13px; color:var(--body2); margin-top:5px; line-height:1.4; }

/* ---- private by design ---- */
.mk-private .mk-eyebrow { text-align:center; } /* section rhythm: eyebrows center like mk-calls/mk-persist */
.mk-checks { display:flex; flex-direction:column; gap:14px; margin-top:18px; }
.mk-check { display:flex; gap:11px; align-items:flex-start; }
.mk-check svg { flex:none; margin-top:1px; }
.mk-check div { font-size:14.5px; color:var(--deep); line-height:1.4; }
.mk-check b { font-weight:600; }

/* ---- pricing: one card, with a billing-period switch above it ----
   The switch is a native radio group (.mk-pp-r), visually hidden but still focusable — display:none
   would drop it out of the tab order and take the keyboard with it. Its :checked state does all the
   work, so the whole control needs no JavaScript and no inline script under our CSP.
   The pairs below are POSITIONAL: radio N lights tab N and reveals panel N. One pair per plan in
   PLANS (stripePrices.ts) — a fourth plan needs a fourth pair added here. */
.mk-plan-picker { position:relative; max-width:430px; margin:0 auto; }
.mk-pp-r { position:absolute; width:1px; height:1px; opacity:0; margin:0; pointer-events:none; }
.mk-pp-tabs { display:grid; grid-template-columns:repeat(3,1fr); gap:4px; padding:4px; margin-bottom:18px;
  background:var(--cream); border:1px solid var(--line); border-radius:999px; }
.mk-pp-tab { padding:10px 6px; border-radius:999px; text-align:center; cursor:pointer; user-select:none;
  font:600 14.5px var(--sans); color:var(--muted); transition:background .15s ease, color .15s ease; }
.mk-pp-tab:hover { color:var(--maroon); }
.mk-pp-panel { display:none; }
/* checked: the tab reads as pressed and its panel is the one on screen */
.mk-pp-r:nth-of-type(1):checked ~ .mk-pp-tabs .mk-pp-tab:nth-child(1),
.mk-pp-r:nth-of-type(2):checked ~ .mk-pp-tabs .mk-pp-tab:nth-child(2),
.mk-pp-r:nth-of-type(3):checked ~ .mk-pp-tabs .mk-pp-tab:nth-child(3) {
  background:var(--white); color:var(--maroon); box-shadow:0 1px 3px rgba(60,35,30,.14); }
.mk-pp-r:nth-of-type(1):checked ~ .mk-pp-panels .mk-pp-panel:nth-child(1),
.mk-pp-r:nth-of-type(2):checked ~ .mk-pp-panels .mk-pp-panel:nth-child(2),
.mk-pp-r:nth-of-type(3):checked ~ .mk-pp-panels .mk-pp-panel:nth-child(3) { display:block; }
/* keyboard focus lands on the invisible radio, so the ring has to be drawn on its tab */
.mk-pp-r:nth-of-type(1):focus-visible ~ .mk-pp-tabs .mk-pp-tab:nth-child(1),
.mk-pp-r:nth-of-type(2):focus-visible ~ .mk-pp-tabs .mk-pp-tab:nth-child(2),
.mk-pp-r:nth-of-type(3):focus-visible ~ .mk-pp-tabs .mk-pp-tab:nth-child(3) {
  outline:2px solid var(--maroon); outline-offset:2px; }
.mk-price { position:relative; background:var(--white); border-radius:20px; padding:24px; text-align:center; box-shadow:var(--card-shadow); }
.mk-price-badge { position:absolute; top:-11px; left:50%; transform:translateX(-50%); background:var(--salmon);
  color:var(--on-salmon); font:700 11px var(--sans); letter-spacing:.04em; padding:4px 12px; border-radius:999px; text-transform:uppercase; }
.mk-price-name { font-family:var(--serif); font-size:18px; color:var(--maroon); }
.mk-price-amt { display:flex; align-items:baseline; justify-content:center; gap:4px; margin-top:8px; }
.mk-price-amt .n { font-family:var(--serif); font-size:34px; font-weight:600; color:var(--deep); }
.mk-price-amt .per { font-size:15px; color:var(--muted); }
/* What you get, under the price. Left-aligned inside a centred card on purpose: ten centred lines of
   ragged text is a poem, not a list you can scan. The bold lead is the claim, the rest is the proof. */
.mk-feats { list-style:none; margin:18px 0 4px; padding:0 2px; display:grid; gap:10px; text-align:left; }
.mk-feat { display:grid; grid-template-columns:20px 1fr; gap:10px; align-items:start;
  font-size:13.5px; line-height:1.45; color:var(--body2); }
/* the check only — the platform glyphs live inside the text and align themselves */
.mk-feat > svg { margin-top:1px; }
/* <strong> is the claim, <b> is emphasis inside a detail ("Messages", "CarPlay") — two elements rather
   than two classes, so neither rule can out-specify the other by accident. */
.mk-feat strong { font-weight:600; color:var(--maroon); }
.mk-feat b { font-weight:600; color:var(--body); }
/* A platform glyph and its name travel together: inline-flex so the pair wraps as one unit and the icon
   sits on the text's centre line rather than its baseline. */
.mk-brand { display:inline-flex; align-items:center; gap:4px; white-space:nowrap; }
.mk-brand + .mk-brand { margin-left:2px; }
.mk-brand svg { flex:none; }
.mk-price .mk-btn { margin-top:16px; padding:14px; font-size:16px; border-radius:13px; }
.mk-cta-note { display:block; font-size:12px; font-weight:500; opacity:.82; margin-top:2px; }
.mk-price-fine { text-align:center; font-size:12.5px; color:var(--muted2); margin-top:12px; }
/* prominent trial line at the top of the pricing section */
.mk-trial-lead { font-family:var(--serif); color:var(--maroon); font-size:clamp(22px, 6vw, 28px);
  font-weight:500; line-height:1.3; margin:12px 0 6px; max-width:560px; }
.mk-trial-lead strong { font-weight:600; }
/* THE EVIDENCE CARD above the plan picker (2026-08-18). See planValueSummary in web/templates.ts.
   Deliberately quiet — it is the thing the price is read AGAINST, so it must not compete with the
   price for attention. No accent fill, no icon, no border-left rule: a bordered box with the counts
   set large enough to read at a glance and nothing else asking to be looked at. */
.mk-value-card { background:var(--white); border:1px solid var(--card-border); border-radius:16px;
  padding:16px 18px; margin:14px 0 4px; max-width:560px; }
.mk-value-h { font-family:var(--serif); font-size:15px; font-weight:600; color:var(--muted2);
  text-transform:uppercase; letter-spacing:.06em; margin:0 0 8px; }
.mk-value-list { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:5px; }
.mk-value-list li { font-size:16px; line-height:1.35; color:var(--maroon); }
.mk-value-list strong { font-weight:600; font-variant-numeric:tabular-nums; }
/* THE DAY-ZERO FORK (/start, 2026-08-18). Two real options, and the CSS has to keep them real: the
   free card gets the page's full-width primary button, and the paid half is the account page's compact
   price cards (2026-08-19) — visible and one tap, but a third of the height. Free is what the landing
   page promised, and the fork exists to make the OTHER option visible, not to bury this one. Anything
   that dims, shrinks or greys the free half turns an honest choice into a pattern.
   The free button's label is a sentence ("Continue to Mabel without paying"), so it is allowed to wrap
   on a narrow screen rather than being shortened back into an ambiguous verb. */
.mk-fork-free { background:var(--white); border-radius:20px; padding:22px; box-shadow:var(--card-shadow);
  margin-top:16px; }
.mk-fork-h { font-family:var(--serif); color:var(--maroon); font-size:22px; font-weight:600; margin:0 0 4px; }
.mk-fork-sub { margin:0 0 16px; font-size:15px; color:var(--body2); line-height:1.4; }
.mk-fork-free .mk-btn { display:block; text-align:center; text-decoration:none; padding:15px;
  border-radius:13px; line-height:1.25; }
/* The "or" rule. Equal weight either side — it separates two choices, it does not step down to a
   lesser one. */
.mk-fork-or { display:flex; align-items:center; gap:12px; margin:20px 0 4px; color:var(--muted2);
  font-size:13px; letter-spacing:.08em; text-transform:uppercase; }
.mk-fork-or::before, .mk-fork-or::after { content:""; flex:1; height:1px; background:var(--line); }
/* The looping demo under the fork (/start, 2026-08-19): the homepage's phone screen, same markup and
   same mabel-demo.js. Its own view height rather than the hero's — the hero grows to 468px at 900px
   wide, which is right beside a full-height illustration and absurd in a 520px app column. */
.mk-fork-demo { display:flex; flex-direction:column; align-items:center; gap:12px; margin-top:30px; }
.mk-fork-demo-h { margin:0; color:var(--muted2); font-size:13px; letter-spacing:.08em;
  text-transform:uppercase; text-align:center; }
.fk-thread .mk-fork-thread-view { height:330px; }
@media (max-width:380px) { .fk-thread .mk-fork-thread-view { height:300px; } }
/* Pricing header: the centred eyebrow + serif heading pair every other section opens with. It gets its
   own centring parent (like .mk-signup-head) rather than centring the section, because the cards below
   need the full inner width and mk-calls-h is capped at 18ch. */
.mk-price-head { display:flex; flex-direction:column; align-items:center; text-align:center;
  margin:0 auto 26px; }
.mk-price-head .mk-calls-h { margin-bottom:0; }

/* ---- faq ---- */
.mk-faq { display:flex; flex-direction:column; margin-top:14px; }
.mk-q { border-top:1px solid var(--hair); padding:15px 0; }
.mk-q:last-child { border-bottom:1px solid var(--hair); }
.mk-q-t { font:600 15px var(--sans); color:var(--deep); }
.mk-q-d { font-size:13.5px; color:var(--body2); margin-top:5px; line-height:1.45; }

/* ---- final cta ---- */
.mk-final-h { font-family:var(--serif); font-size:30px; font-weight:600; color:#F6E9DF; line-height:1.1; margin:0; }
.mk-final-sub { font-family:var(--serif); font-size:17px; font-weight:500; color:#D8A79A; margin:10px 0 0; }
.mk-deep .mk-btn { margin-top:22px; max-width:420px; margin-left:auto; margin-right:auto; }

/* ============ DESKTOP ============ */
@media (min-width:900px) {
  .mk-header { padding:20px 48px; border-bottom:1px solid #e0d2c2; max-width:1320px; margin:0 auto; }
  .mk-wordmark { font-size:23px; }
  .mk-brand .mk-ava { width:32px; height:32px; }
  .mk-navlink { display:none; }
  .mk-nav-desktop { display:flex; }

  .mk-section { padding:56px 48px; }
  .mk-hero { padding:56px 48px 50px; }
  .mk-hero-tight { padding-bottom:22px; }
  .mk-hero-grid { max-width:1320px; margin:0 auto; display:grid; grid-template-columns:1fr 540px; gap:30px; align-items:center; }
  .mk-h1 { font-size:clamp(42px, 4.6vw, 62px); line-height:1.04; }
  .mk-h1-long { font-size:clamp(38px, 3.9vw, 52px); line-height:1.12; }
  .mk-h1 span { white-space:normal; } /* wide desktop column fits each line; avoid overflow if it narrows */
  .mk-sub { font-size:19px; margin-top:22px; }
  .mk-hero-cta-row { display:flex; align-items:center; gap:16px; margin-top:30px; }
  .mk-hero-cta-row .mk-btn { width:auto; padding:16px 28px; }
  .mk-hero-cta-row .mk-trust { margin:0; text-align:left; font-size:14px; }
  .mk-hero-media { margin-top:0; }
  .mk-mabel { width:210px; margin-right:-12px; }
  .mk-mabel img { animation-duration:5s; }
  .mk-phone { width:300px; border-radius:40px; padding:9px; box-shadow:0 28px 60px rgba(50,28,24,.30); }
  .mk-screen { border-radius:32px; }

  .mk-steps { flex-direction:row; gap:26px; }
  .mk-step { flex-direction:column; }
  .mk-cards { grid-template-columns:repeat(4,1fr); }
  /* The grid lives on .mk-checks (the items' direct parent) — on .mk-checks-inner it had a single
     child, so every check stacked in the left 1fr track and the right column sat empty. */
  .mk-checks-inner { max-width:900px; margin:0 auto; }
  .mk-checks { display:grid; grid-template-columns:1fr 1fr; gap:16px 40px; }
  .mk-faq-inner { max-width:760px; margin:0 auto; }
  .mk-final-h { font-size:44px; }
  .mk-footer { padding:26px 48px; }
}

/* ===== App screens: signup / verify (cream, focused, mobile-canonical) ===== */
body.mk-app { background:var(--cream); }
.mk-app-header { display:flex; align-items:center; gap:10px; padding:14px 22px 4px; max-width:520px; margin:0 auto; }
.mk-app-header .mk-wordmark { font-size:18px; }
.mk-back { display:inline-flex; align-items:center; color:var(--maroon); text-decoration:none; }
.mk-app-main { max-width:520px; margin:0 auto; padding:12px 26px 44px; }

.mk-reassure { display:flex; align-items:center; gap:13px; margin:6px 0 6px; }
.mk-reassure .mk-ava { width:56px; height:56px; background:var(--nude); }
.mk-reassure-title { font-family:var(--serif); font-size:22px; color:var(--maroon); font-weight:600; line-height:1.15; }
.mk-reassure-sub { font-size:14px; color:var(--body); margin-top:2px; line-height:1.4; }

.mk-plan-note { font-size:13px; color:var(--body2); margin:0 0 16px; }
.mk-plan-note strong { color:var(--maroon); }
.mk-plan-note a { color:var(--maroon); }

.mk-form-card { background:var(--white); border-radius:20px; padding:22px; box-shadow:var(--card-shadow); }
.mk-field-label { font:600 13px var(--sans); color:var(--deep); }
.mk-input-group { display:flex; align-items:center; gap:8px; border:1.5px solid var(--line); border-radius:13px; padding:12px 15px; margin-top:8px; background:#fff; }
.mk-input-group.err { border-color:#C2544C; }
.mk-input-prefix { font:600 15px var(--sans); color:var(--muted2); flex:none; }
.mk-input { border:0; outline:0; background:transparent; font:400 17px var(--sans); color:var(--deep); flex:1; min-width:0; letter-spacing:.02em; }
.mk-input::placeholder { color:#b8a99e; }
.mk-field-err { font:500 12.5px var(--sans); color:#B3423A; margin-top:7px; }

.mk-consent { display:flex; gap:11px; align-items:flex-start; margin-top:16px; }
.mk-consent input { flex:none; width:20px; height:20px; margin-top:2px; accent-color:var(--maroon); }
.mk-consent-copy { font-size:12px; line-height:1.5; color:var(--body2); }
.mk-consent-copy a { color:var(--maroon); }
.mk-optional { color:var(--eyebrow); font-weight:700; text-transform:uppercase; letter-spacing:.06em; font-size:10.5px; }

/* Click-wrap notice under the signup CTA. Replaces the old Terms checkbox: submitting the form IS the
   acceptance, so this has to sit with the button and stay legible — conspicuousness is what makes it
   enforceable. Same type size as .mk-consent-copy; do not shrink it below that. */
.mk-clickwrap { margin-top:14px; font-size:12px; line-height:1.5; color:var(--body2); text-align:center; }
.mk-clickwrap a { color:var(--maroon); text-decoration:underline; }

.mk-form-card .mk-btn { margin-top:18px; padding:15px; border-radius:13px; }
.mk-btn:disabled, .mk-btn.is-disabled { background:#EBD5CE; color:#B18C82; cursor:default; }

.mk-foot-note { display:flex; align-items:center; justify-content:center; gap:7px; margin-top:18px; font-size:12.5px; color:var(--muted); }
/* Compliance signal under the signup foot-note. One quiet grey line — the seal read as a fake award to
   consumers; this keeps the reassurance for the one carrier reviewer who looks, without the billboard. */
.mk-compliance-line { text-align:center; margin-top:16px; font-size:11px; color:var(--muted2); }
.mk-compliance-line a { color:var(--muted2); text-decoration:underline; text-underline-offset:2px; }
.mk-alt { text-align:center; font-size:13px; color:var(--body); margin-top:16px; }
.mk-alt a { color:var(--maroon); font-weight:600; }

/* Verification code: ONE wide field (see codeFieldHtml() in templates.ts for why it is not six boxes).
   padding-left equals letter-spacing on purpose: centred text includes the trailing letter-space in its
   width, which pushes the digits half a space left of true centre — an equal left pad cancels it exactly. */
.mk-code-field { margin-top:10px; }
.mk-code-input { box-sizing:border-box; display:block; width:100%; height:58px; padding:0 0 0 .3em;
  border:1.5px solid var(--line); border-radius:12px; background:#fff; outline:0;
  text-align:center; font:600 29px var(--sans); color:var(--deep);
  letter-spacing:.3em; font-variant-numeric:tabular-nums; }
.mk-code-input::placeholder { color:#DDD1C6; font-weight:600; }
.mk-code-input:focus { border-color:var(--maroon); box-shadow:0 0 0 3px rgba(92,42,49,.10); }
.mk-code-field.err .mk-code-input { border-color:#C2544C; }
.mk-resend { text-align:center; font:500 13px var(--sans); color:var(--body); margin-top:14px; }
.mk-resend button { background:none; border:0; color:var(--maroon); font-weight:700; cursor:pointer; padding:0; font-size:13px; font-family:var(--sans); }
.mk-resend button:disabled { color:var(--muted2); cursor:default; }
.mk-msg { text-align:center; font:500 13px var(--sans); color:var(--maroon); margin-top:14px; min-height:1.1em; }
.mk-msg.error { color:#B3423A; }

/* ===== Account / payment-success page ===== */
.mk-acc-hero { text-align:center; padding:14px 0 8px; }
.mk-badge { width:64px; height:64px; border-radius:50%; background:var(--maroon); display:flex; align-items:center; justify-content:center; margin:6px auto 0; }
.mk-acc-h { font-family:var(--serif); font-size:34px; font-weight:600; color:var(--maroon); line-height:1.05; margin:16px 0 0; text-align:center; }
.mk-acc-h.mk-left { text-align:left; font-size:26px; margin:8px 0 6px; }
.mk-acc-sub { font-size:15.5px; color:var(--body); margin:8px 0 0; line-height:1.45; text-align:center; }
.mk-app-main .mk-form-card { margin-top:16px; }
.mk-card-h { font-family:var(--serif); font-size:18px; color:var(--maroon); font-weight:600; margin-bottom:4px; }
.mk-acc-note { font-size:14px; line-height:1.5; color:var(--body2); margin:8px 0 0; }
.mk-acc-note strong { color:var(--deep); font-weight:600; }

/* Account-page cards run tighter than the signup forms sharing .mk-form-card: the page is a utility
   screen, and the goal is info line + plan + contact photo all visible without scrolling. */
.mk-tight { padding:14px 18px; }
.mk-app-main .mk-form-card.mk-tight { margin-top:12px; }
.mk-acc-line { display:flex; flex-wrap:wrap; align-items:center; gap:4px 18px; font-size:14.5px; color:var(--body2); }
.mk-acc-line b { color:var(--deep); font-weight:600; }
.mk-acc-item { display:inline-flex; align-items:center; gap:6px; }
.mk-acc-check { flex:none; }
.mk-acc-off { color:var(--muted2); font-weight:600; }

.mk-contact-hint { font-size:12.5px; color:var(--muted2); margin:2px 0 0; }
.mk-photo-grid { display:grid; grid-template-columns:repeat(2, 1fr); gap:10px; margin-top:10px; }
.mk-photo-card { position:relative; display:block; width:100%; padding:0; border:1px solid var(--hair); border-radius:12px; overflow:hidden; background:var(--white); cursor:pointer; text-align:left; font:inherit; transition:transform .12s ease; }
.mk-photo-card:active { transform:scale(.96); }
.mk-photo-card img { display:block; width:100%; height:auto; aspect-ratio:1/1; object-fit:cover; transition:opacity .12s ease; }
/* Busy = the beat between tap and the share sheet (the full-res fetch). The tapped tile dims and
   spins so the tap visibly landed; account.js clears it the moment the sheet is invoked. */
.mk-photo-card.is-busy img { opacity:.5; }
.mk-photo-card.is-busy::after { content:''; position:absolute; top:calc(50% - 27px); left:calc(50% - 11px); width:22px; height:22px; border:2.5px solid var(--maroon); border-top-color:transparent; border-radius:50%; animation:mk-spin .7s linear infinite; }
@keyframes mk-spin { to { transform:rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .mk-photo-card.is-busy::after { animation:none; border-top-color:var(--maroon); opacity:.6; } }
.mk-photo-label { display:flex; align-items:center; justify-content:space-between; gap:6px; padding:7px 10px; }
.mk-photo-label b { font:600 13px var(--sans); color:var(--deep); }
.mk-photo-hex { font-size:11px; color:var(--muted2); letter-spacing:.03em; }

.mk-acc-tz { margin-top:12px; }
.mk-tz-row { display:flex; align-items:center; gap:8px; margin-top:8px; }
.mk-tz-row .mk-btn { margin-top:0; }
.mk-select { flex:1; min-width:0; border:1.5px solid var(--line); border-radius:12px; padding:11px 12px; font:400 15px var(--sans); color:var(--deep); background:#fff; }
.mk-btn-sm { width:auto; padding:11px 16px; font-size:14px; border-radius:12px; }
.mk-muted { display:block; font-size:12.5px; color:var(--muted); margin-top:8px; }
.mk-acc-link { margin-top:12px; }
.mk-acc-link a { color:var(--maroon); font-weight:600; text-decoration:none; }

/* Free-tier "Your plan": three micro price cards, one tap each straight to Stripe (2026-08-09).
   Stays 3-across at EVERY width — the panel replaced a two-line paragraph and has to keep that
   footprint, and stacking on mobile would triple its height on the narrow screens that are most of
   this page's traffic. The sizes below are what fits three cards on a 320px viewport. */
.mk-miniplans { display:grid; grid-template-columns:repeat(3, 1fr); gap:8px; margin-top:8px; }
.mk-miniplan { display:flex; flex-direction:column; align-items:center; border:1px solid var(--line);
  border-radius:12px; padding:9px 5px 8px; text-align:center; }
.mk-miniplan-name { font:600 12.5px var(--sans); color:var(--muted); }
.mk-miniplan-price { font:600 20px var(--serif); color:var(--deep); line-height:1.15; white-space:nowrap; }
.mk-miniplan-per { font:600 11.5px var(--sans); color:var(--muted2); margin-left:1px; }
/* Not .mk-btn: that one is a 17px full-width block built for a page's single primary action, and three
   of them side by side would be a wall. Same focus ring, same busy dimming, a third of the weight. */
.mk-miniplan-btn { width:100%; margin-top:7px; border:0; border-radius:9px; padding:8px 4px;
  font:700 13px var(--sans); cursor:pointer; }
.mk-miniplan-soft { background:var(--salmon-soft); color:var(--on-salmon); }
.mk-miniplan-mid { background:var(--salmon); color:var(--on-salmon); }
.mk-miniplan-deep { background:var(--maroon); color:#F6E9DF; }
.mk-miniplan-btn:focus-visible { outline:3px solid var(--maroon); outline-offset:2px; }
.mk-miniplan-btn[disabled] { opacity:.6; cursor:default; }
/* Label for the row below it, so it reads left and quiet like a field label rather than centred like
   a footnote. Doubles as the error slot (account.js), which is why it keeps a reserved height — a line
   appearing and disappearing under the state note would jump the cards on every failed tap. */
.mk-miniplan-note { font-size:12.5px; line-height:1.45; color:var(--muted); margin:10px 0 0; min-height:1.1em; }
.mk-miniplan-note.error { color:#B3423A; }

/* Tap-to-copy starter prompts, woven between the gallery's rows (2026-08-10). `grid-column:1/-1` is the
   whole trick: they are children of .mk-photo-grid, so they span both columns and the two-up rhythm of
   the photos is never broken. Deliberately NOT a card — bordered rows in a section of their own read as
   a second gallery competing with the first. Type carries it instead: a small uppercase lead-in, then
   the sentence in the brand serif, italic and quoted, so it reads as something SAID rather than a
   control. Generous vertical padding is the separation the border used to give. */
.mk-idea { grid-column:1 / -1; display:block; width:100%; text-align:center; cursor:pointer;
  background:none; border:0; border-radius:12px; padding:14px 8px 16px; margin:0; font:inherit;
  color:var(--deep); transition:background .12s ease; }
.mk-idea-lead { display:block; font:700 11px var(--sans); letter-spacing:.1em; text-transform:uppercase;
  color:var(--eyebrow); margin-bottom:5px; }
.mk-idea-quote { font:italic 400 15.5px/1.5 var(--serif); color:var(--maroon); }
.mk-idea-icon { display:inline-block; vertical-align:-2px; margin-left:7px; color:var(--muted2); }
.mk-idea:focus-visible { outline:3px solid var(--maroon); outline-offset:2px; }
.mk-idea:active { background:var(--cream); }
/* Copied: the line itself is the receipt. It reverts after a beat (account.js) so ten lines can't
   accumulate ten ticks and stop telling you which one you just took. */
.mk-idea.is-copied { background:#FBF1EC; }
.mk-idea.is-copied .mk-idea-icon { color:var(--maroon); }
.mk-idea-i-done { display:none; }
.mk-idea.is-copied .mk-idea-i-copy { display:none; }
.mk-idea.is-copied .mk-idea-i-done { display:block; }
.mk-idea-msg { font-size:12.5px; line-height:1.45; color:var(--muted2); margin:10px 0 0; min-height:1.1em; }
.mk-idea-msg.error { color:#B3423A; }
.mk-acc-actions { text-align:center; margin-top:24px; }
.mk-textbtn { background:none; border:0; color:var(--maroon); font:600 14px var(--sans); cursor:pointer; text-decoration:underline; }

/* Self-serve deletion: the entry button sits under Log out, quieter than it; the confirm card it
   expands is the one red thing on the page (same red as .mk-msg.error). */
.mk-danger-entry { margin-top:14px; }
.mk-textbtn-danger { color:#B3423A; font-weight:500; font-size:13px; }
.mk-app-main .mk-form-card.mk-danger { border:1px solid #E3B9B4; }
.mk-danger .mk-card-h, .mk-danger .mk-acc-note strong { color:#B3423A; }
.mk-btn-danger { background:#B3423A; color:#FBEFE9; }
.mk-danger .mk-keep { margin-top:12px; }

/* /checkout plan radios (returning-user resubscribe) */
.mk-plan-radios { display:flex; flex-direction:column; gap:10px; margin-top:10px; }
.mk-plan-radio { display:grid; grid-template-columns:auto 1fr; column-gap:11px; row-gap:3px; align-items:center;
  border:1px solid var(--line); border-radius:12px; padding:14px; cursor:pointer; }
.mk-plan-radio:has(input:checked) { border-color:var(--salmon); box-shadow:0 0 0 1px var(--salmon); }
.mk-plan-radio input { grid-row:1 / span 2; accent-color:var(--maroon); }
.mk-plan-radio-main { display:flex; align-items:baseline; justify-content:space-between; gap:8px; }
.mk-plan-radio-name { font:600 15px var(--sans); color:var(--deep); }
.mk-plan-radio-price { font:600 15px var(--sans); color:var(--maroon); white-space:nowrap; }
.mk-plan-radio-sub { grid-column:2; color:var(--muted); font-size:12.5px; }

/* content pages (terms / privacy / sms-terms / about) rendered in the marketing chrome */
.mk-page-body h1 { font-family:var(--serif); color:var(--maroon); font-weight:600; font-size:30px; line-height:1.12; margin:0 0 6px; }
.mk-page-body address { font-style:normal; color:var(--body); line-height:1.6; margin-top:8px; }
.mk-page-body .business-info { list-style:none; padding-left:0; margin:12px 0 0; }
.mk-page-body .business-info li { margin:4px 0; }
.mk-page-body .muted { color:var(--muted); font-size:14px; }
.mk-page-body .draft { background:#FBF3EF; border:1px solid #E8C24A; padding:8px 12px; border-radius:8px; font-size:13px; }

/* Hero mockup carousel — a cream "device showcase" that crossfades phone screens (driven by carousel.js).
   Each slide is centered; iframes hold the standalone mockups (scaled to fit) and the threadMock slide is
   the existing class-styled phone. The cream card matches the mockups' own background so edges blend. */
.mk-carousel { position:relative; flex:none; z-index:1; width:264px; height:496px; border-radius:34px; overflow:hidden; background:#ECDCCF; box-shadow:0 20px 48px rgba(50,28,24,.22); }
.mk-cslide { position:absolute; inset:0; display:flex; align-items:center; justify-content:center; opacity:0; transition:opacity .7s ease; }
.mk-cslide.is-active { opacity:1; }
.mk-cslide iframe { flex:none; border:0; width:446px; height:904px; transform:scale(.55); transform-origin:center; pointer-events:none; background:transparent; }
.mk-cslide .mk-phone { transform:scale(.86); }
@media (prefers-reduced-motion:reduce){ .mk-cslide { transition:none; } }
@media (min-width:900px){
  .mk-carousel { width:300px; height:576px; }
  .mk-cslide iframe { transform:scale(.64); }
  .mk-cslide .mk-phone { transform:scale(.96); }
}

/* "Really important reminders" calling-feature section */
.mk-calls { text-align:center; display:flex; flex-direction:column; align-items:center; }
.mk-calls-h { font-family:var(--serif); color:var(--maroon); font-weight:600; font-size:30px; line-height:1.14; margin:8px 0 12px; max-width:18ch; text-wrap:balance; }
.mk-calls-sub { color:var(--body); font-size:16px; line-height:1.55; max-width:46ch; margin:0 0 30px; }
@media (min-width:900px){ .mk-calls-h { font-size:40px; } .mk-calls-sub { font-size:17px; } }

/* "She doesn't mind asking twice" — persistence section on the deep band, where the bright phone
   showcase pops. Mirrors mk-calls-h/sub but with light-on-deep text. */
.mk-persist { text-align:center; display:flex; flex-direction:column; align-items:center; }
.mk-persist .mk-eyebrow { color:#D8A79A; }
.mk-persist-h { font-family:var(--serif); color:#F6E9DF; font-weight:600; font-size:30px; line-height:1.14; margin:8px 0 12px; max-width:18ch; text-wrap:balance; }
.mk-persist-sub { color:#E7D3CA; font-size:16px; line-height:1.55; max-width:48ch; margin:0 0 30px; }
/* On the deep band the phone floats free — drop the nude "showcase card" bg + shadow (the tan box). */
.mk-persist .mk-carousel { background:transparent; box-shadow:none; }
@media (min-width:900px){ .mk-persist-h { font-size:40px; } .mk-persist-sub { font-size:17px; } }

/* ---- UGC testimonials ("Real people, real reminders") — swipeable vertical-video cards ----
   Swiping is native CSS scroll-snap (no JS); ugc.js only handles tap-to-play. Sits on the deep berry
   band (like the final CTA) so the video cards pop between the cream #calls and nude #pricing bands.
   The track bleeds to the viewport edge on mobile so the next card peeks = swipe affordance. */
.mk-ugc { text-align:center; }
.mk-ugc .mk-eyebrow { color:#D8A79A; }
.mk-ugc-h { font-family:var(--serif); color:#F6E9DF; font-weight:600; font-size:30px; line-height:1.14; margin:8px 0 4px; text-wrap:balance; }
.mk-ugc-track { display:flex; gap:14px; overflow-x:auto; scroll-snap-type:x mandatory; -webkit-overflow-scrolling:touch; padding:22px 26px 6px; margin:0 -26px; scrollbar-width:none; }
.mk-ugc-track::-webkit-scrollbar { display:none; }
.mk-ugc-card { flex:none; width:min(64vw, 240px); margin:0; scroll-snap-align:center; }
.mk-ugc-frame { position:relative; aspect-ratio:9/16; border-radius:18px; overflow:hidden; background:#2A1B1F; box-shadow:0 14px 34px rgba(0,0,0,.35); }
@supports not (aspect-ratio: 9/16) { .mk-ugc-frame::before { content:''; display:block; padding-top:177.78%; } }
.mk-ugc-frame iframe { position:absolute; inset:0; width:100%; height:100%; border:0; }
.mk-ugc-poster { position:absolute; inset:0; width:100%; border:0; padding:0; background:none; cursor:pointer; display:block; }
.mk-ugc-poster img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.mk-ugc-poster:focus-visible { outline:3px solid #F6E9DF; outline-offset:2px; border-radius:18px; }
.mk-ugc-badge { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:56px; height:56px; border-radius:50%; background:var(--salmon); display:flex; align-items:center; justify-content:center; box-shadow:0 8px 22px rgba(0,0,0,.35); }
.mk-ugc-badge svg { margin-left:3px; }
.mk-ugc-name { font:600 14.5px var(--sans); color:#EBD5CE; margin-top:10px; text-align:center; }
@media (min-width:900px){
  .mk-ugc-h { font-size:40px; }
  .mk-ugc-card { width:206px; }
  .mk-ugc-track { padding-left:48px; padding-right:48px; margin:0 -48px; }
}
/* Center the row when it fits without justify-content:center (which clips the left edge of an
   overflowing overflow-x scroller): auto margins on the end cards absorb spare space when the row
   fits and resolve to 0 when it overflows, keeping every card scrollable. */
.mk-ugc-card:first-child { margin-left:auto; }
.mk-ugc-card:last-child { margin-right:auto; }

/* Desktop prev/next arrows: a mouse can't swipe and the track's scrollbar is hidden. Markup ships
   [hidden]; ugc.js unhides them only while the track overflows, and :not([hidden]) keeps the UA's
   display:none authoritative so they never appear on phones (or when everything fits). */
.mk-ugc-wrap { position:relative; }
.mk-ugc-arrow { display:none; position:absolute; z-index:2; top:50%; transform:translateY(-50%); width:46px; height:46px; border-radius:50%; border:0; background:var(--salmon); cursor:pointer; align-items:center; justify-content:center; box-shadow:0 8px 22px rgba(0,0,0,.35); }
.mk-ugc-arrow-prev { left:-12px; }
.mk-ugc-arrow-next { right:-12px; }
.mk-ugc-arrow-prev svg { transform:scaleX(-1); }
.mk-ugc-arrow:disabled { opacity:.35; cursor:default; }
.mk-ugc-arrow:focus-visible { outline:3px solid #F6E9DF; outline-offset:2px; }
@media (min-width:640px){ .mk-ugc-arrow:not([hidden]) { display:flex; } }

/* Tiny salient pills labelling the SMS + voice consent boxes on signup */
.mk-consent-tag { display:inline-block; background:var(--salmon); color:#fff; font:700 9.5px var(--sans); letter-spacing:.04em; text-transform:uppercase; padding:2px 8px; border-radius:100px; margin-right:6px; vertical-align:1.5px; white-space:nowrap; }

/* ---------------------------------------------------------------------------
   Capture landing page (LANDING_VARIANT=capture).

   One screen, one job: face → headline → phone field → button, nothing else clickable. Sized so the
   button is above the fold on a small phone (iPhone SE, 667px tall) without scrolling — that is the
   whole point of the page, so if you add anything here, re-check that.

   Reuses .mk-form-card / .mk-btn / .mk-foot-note from the app screens; only the page shell and the
   proof strip are new.
--------------------------------------------------------------------------- */
.cap-body { background:var(--cream); }
.cap-main { max-width:460px; margin:0 auto; padding:26px 24px 40px; }

/* Proof strip: the creator's face, first thing on the page, for message match with the ad. */
.cap-proof { display:flex; align-items:center; gap:13px; margin-bottom:20px; }
.cap-face {
  width:76px; height:76px; flex:none; border-radius:50%; object-fit:cover;
  background:var(--nude); box-shadow:0 6px 18px rgba(60,35,30,.16);
}
.cap-quote p {
  margin:0 0 3px; font-family:var(--serif); font-size:16px; line-height:1.35;
  color:var(--deep); font-style:italic;
}
.cap-quote span { font-size:12px; color:var(--muted); }

.cap-h1 {
  font-family:var(--serif); font-size:34px; line-height:1.12; font-weight:600;
  letter-spacing:-0.02em; color:var(--maroon); margin:0 0 20px;
}

/* The form card carries the page here, so let it sit tight under the headline. */
.cap-main .mk-form-card { margin-top:0; }
.cap-main .mk-msg { text-align:center; }

@media (max-width:380px) {
  .cap-main { padding:18px 18px 32px; }
  .cap-h1 { font-size:29px; margin-bottom:16px; }
  .cap-face { width:64px; height:64px; }
  .cap-quote p { font-size:15px; }
}
@media (min-width:520px) {
  .cap-main { padding-top:44px; }
  .cap-h1 { font-size:38px; }
}

/* ---- Capture page: example text thread -------------------------------------
   A phone Messages screen, not a decorative mockup: it teaches the interaction (plain English in,
   confirmation back, reminder arrives later) before anyone reads a word of copy.

   Fixed height with the thread bottom-anchored, so bubbles animating in push upward like a real
   conversation instead of resizing the page and shoving the CTA around mid-scroll. Nothing below this
   block may move when the animation runs — that's the constraint to preserve if you edit it.
--------------------------------------------------------------------------- */
.cap-demo {
  background:var(--white); border-radius:20px; overflow:hidden;
  box-shadow:var(--card-shadow); margin:0 0 18px;
}
.cap-demo-bar {
  display:flex; align-items:center; gap:8px; padding:9px 14px;
  background:#F3EDE4; border-bottom:1px solid var(--hair);
}
.cap-demo-back { color:var(--muted2); font-size:21px; line-height:1; flex:none; }
.cap-demo-id { display:flex; align-items:center; gap:8px; flex:1; justify-content:center; }
.cap-demo-id .mk-ava { width:26px; height:26px; flex:none; }
.cap-demo-num {
  display:flex; flex-direction:column; line-height:1.15;
  font-size:13px; font-weight:600; color:var(--deep);
}
.cap-demo-num small { font-size:10.5px; font-weight:400; color:var(--muted2); }
.cap-demo-spacer { width:16px; flex:none; }

/* Bottom-anchored viewport: the thread grows from the bottom edge, older lines slide off the top. */
.cap-demo-view { height:248px; overflow:hidden; display:flex; }
.cap-demo-thread {
  display:flex; flex-direction:column; justify-content:flex-end; gap:5px;
  width:100%; padding:12px 13px 14px;
}
.cap-demo-label { text-align:center; font-size:10.5px; color:var(--muted2); margin-bottom:2px; }
.cap-demo-label b { font-weight:600; color:var(--muted); }
.md-ts { text-align:center; font-size:10.5px; color:var(--muted2); margin:6px 0 2px; }
.md-ts b { font-weight:600; color:var(--muted); }

.md-row { display:flex; animation:md-pop .22s ease-out; }
.md-row--in { justify-content:flex-start; }
.md-row--out { justify-content:flex-end; }
.md-bubble {
  max-width:80%; padding:8px 12px; border-radius:17px; font-size:13.5px; line-height:1.35;
}
.md-bubble--in { background:#EFE8DE; color:var(--deep); border-bottom-left-radius:5px; }
.md-bubble--out { background:var(--maroon); color:var(--cream); border-bottom-right-radius:5px; }

.md-typing {
  display:flex; gap:4px; align-items:center; padding:11px 13px;
  background:#EFE8DE; border-radius:17px; border-bottom-left-radius:5px;
}
.md-dot { width:6px; height:6px; border-radius:50%; background:var(--muted2); animation:md-blink 1.3s infinite; }
.md-dot:nth-child(2) { animation-delay:.18s; }
.md-dot:nth-child(3) { animation-delay:.36s; }

@keyframes md-pop { from { opacity:0; transform:translateY(6px); } to { opacity:1; transform:none; } }
@keyframes md-blink { 0%,60%,100% { opacity:.32; } 30% { opacity:1; } }

/* Reduced motion: mabel-demo.js renders the thread statically, so kill the entrance/typing animation
   and let the viewport grow to fit instead of clipping messages the visitor can no longer watch. */
@media (prefers-reduced-motion: reduce) {
  .md-row { animation:none; }
  .md-dot { animation:none; }
  .cap-demo-view { height:auto; }
}

@media (max-width:380px) {
  .cap-demo-view { height:224px; }
  .md-bubble { font-size:13px; }
}

/* ---------------------------------------------------------------------------
   Friction-killer homepage (LANDING_VARIANT=friction).

   The page IS the phone screen: one 412px column, no nav, no footer, nothing clickable but the field.
   Everything above the signup card exists to answer "what do I even say to her?" before the visitor
   has to read a word of explainer copy.

   The demo thread here is deliberately NOT brand-coloured like the capture page's — it uses the system
   font stack and iMessage's own green/grey so it reads as a screenshot of a real conversation rather
   than a branded illustration. That's the point of it; don't "fix" it to match the palette.
--------------------------------------------------------------------------- */
.fk-body { background:var(--nude); font-family:var(--sans); }
.fk-main { max-width:412px; margin:0 auto; padding-bottom:8px; }

.fk-header { display:flex; align-items:center; justify-content:space-between; padding:10px 20px 4px; }
/* Trust chip: wordmark-height pill with the A2P seal falling inline to its right. Shared — the
   friction-killer homepage header links it to #trust, the app header (/welcome) wears it as a badge. */
.mk-pill {
  display:flex; align-items:center; gap:7px; white-space:nowrap; text-decoration:none;
  background:var(--white); border:1px solid #E6D6C7; border-radius:999px; padding:4px 8px 4px 13px;
  box-shadow:0 2px 9px rgba(50,28,24,.08); color:var(--maroon); font:600 12px var(--sans);
}
.mk-pill svg { display:block; flex:none; }

.fk-greet { display:flex; align-items:center; gap:13px; padding:16px 22px 0; }
.fk-greet-img { width:78px; height:78px; object-fit:contain; object-position:bottom; flex:none; }
.fk-greet-h { font-family:var(--serif); font-size:24px; font-weight:600; color:var(--maroon); line-height:1.1; margin:0; }
.fk-greet-sub { font-size:15px; color:var(--body); line-height:1.4; margin:3px 0 0; }

.fk-block { padding:16px 22px 0; }

/* ---- demo thread: iMessage chrome ---- */
.fk-thread { margin:0; font-family:-apple-system, 'SF Pro Text', 'Helvetica Neue', system-ui, sans-serif; }
.fk-thread-bar {
  display:flex; align-items:center; gap:6px; padding:8px 12px;
  background:#F7F7F7; border-bottom:1px solid #D8D8D8;
}
.fk-thread-back { flex:none; width:26px; display:flex; justify-content:center; }
.fk-thread-id { flex:1; min-width:0; display:flex; flex-direction:column; align-items:center; gap:2px; }
.fk-thread-id .mk-ava { width:38px; height:38px; background:#fff; border:1px solid #ececec; }
.fk-thread-name { display:flex; align-items:center; gap:3px; font-size:12px; font-weight:600; color:#000; }
.fk-thread-name span { color:#9b9b9f; font-weight:400; }
.fk-thread-spacer { flex:none; width:26px; }

.fk-thread .cap-demo-view { height:300px; background:#fff; }
.fk-thread .cap-demo-thread { gap:6px; padding:12px 12px 14px; }
.fk-thread .md-ts { font-size:11px; color:#8E8E93; }
.fk-thread .md-ts b { font-weight:600; color:#3a3a3c; }
.fk-thread .md-bubble {
  max-width:80%; padding:8px 13px 9px; border-radius:20px; font-size:15px; line-height:1.34;
  white-space:pre-line; word-wrap:break-word;
}
.fk-thread .md-bubble--out { background:#34C759; color:#fff; border-bottom-right-radius:7px; }
.fk-thread .md-bubble--in { background:#E9E9EB; color:#1c1c1e; border-bottom-left-radius:7px; }
.fk-thread .md-typing { padding:11px 14px; background:#E9E9EB; border-radius:20px; border-bottom-left-radius:7px; }
.fk-thread .md-dot { background:#8E8E93; }

/* ---- inline signup card: field and button on one row, code revealed below ---- */
.fk-card { padding:18px; }
.fk-phone-row { display:flex; gap:8px; align-items:stretch; margin-top:8px; }
.fk-phone-row .mk-input-group { flex:1; min-width:0; margin-top:0; }
/* min-width holds the slot while the label cycles "Send code" -> "Resend 29s" -> "Resend", so the
   countdown never squeezes the number the visitor just typed. */
.fk-card .fk-phone-row .fk-send {
  width:auto; min-width:112px; white-space:nowrap; padding:0 15px; margin-top:0;
  border-radius:13px; font-size:15px;
}
/* Left-aligned here (not centred like the app screens) because it sits under a left-aligned field and
   reads as part of the form. Same type size as everywhere else — see .mk-clickwrap. */
.fk-card .mk-clickwrap { text-align:left; margin-bottom:0; }
.fk-sent {
  display:flex; align-items:center; gap:8px; margin-top:2px; padding-top:16px;
  border-top:1px solid var(--card-border); font:500 13.5px var(--sans); color:var(--body2);
}
.fk-sent svg { flex:none; }
.fk-sent b { color:var(--deep); font-weight:600; }
.fk-card #code-step .mk-field-label { margin-top:16px; }
.fk-card #code-step .mk-btn { margin-top:16px; }
/* The status line only exists once there is something to say. Elsewhere .mk-msg reserves a line so the
   layout doesn't jump; on this card that reserved line plus the two default <p> margins left ~45px of
   blank white under the click-wrap, which read as a mistake. Collapse it until it has text. */
.fk-card .mk-msg { margin:12px 0 0; }
/* Collapsed, not display:none — the element stays in the a11y tree so its aria-live announcement still
   fires the moment signup.js writes into it. */
.fk-card .mk-msg:empty { min-height:0; margin:0; }

/* ---- trust ---- */
.fk-trust { padding:18px 22px 26px; }
.fk-chips { display:flex; flex-wrap:wrap; gap:8px; justify-content:center; }
.fk-chip { background:rgba(92,42,49,.08); color:var(--maroon); border-radius:999px; padding:7px 13px; font:600 13px var(--sans); }
.fk-priv {
  display:flex; align-items:center; justify-content:center; gap:6px; text-align:center;
  font:500 12.5px var(--sans); color:var(--muted); margin:13px 0 0;
}
.fk-priv svg { flex:none; }
.fk-company { display:flex; align-items:center; justify-content:center; gap:11px; margin-top:14px; text-decoration:none; }
.fk-company svg { display:block; flex:none; }
.fk-company span { font:500 12px var(--sans); color:var(--muted2); text-align:left; line-height:1.4; }

@media (max-width:380px) {
  .fk-greet, .fk-block { padding-left:16px; padding-right:16px; }
  .fk-trust { padding-left:16px; padding-right:16px; }
  .fk-greet-img { width:66px; height:66px; }
  .fk-greet-h { font-size:22px; }
  .fk-card { padding:16px; }
  .fk-thread .cap-demo-view { height:262px; }
  .fk-thread .md-bubble { font-size:14.5px; }
  .mk-code-input { height:52px; font-size:25px; }
}

/* ---------------------------------------------------------------------------
   Demo-led homepage hero + signup band (LANDING_VARIANT=homepage).

   The friction page's demo thread moved into the sales hero's right column and its signup card into a
   full-bleed band underneath. Nothing new is styled here — only the geometry that changes when those
   pieces stop being the whole page: the thread gains a phone bezel around it, and the card gains a strip
   of its own. These rules come after the .fk-* block on purpose; they share its specificity and win on
   source order.
--------------------------------------------------------------------------- */
/* The screen holds a white Messages thread, not the dark spokesperson video, so the bezel colour that
   .mk-screen paints to hide an unpainted video frame would show through as a black gutter here. */
.mk-screen-thread { background:#fff; }
/* Taller than the friction page's bare thread (300px): inside a bezel, a squat screen reads as a widget
   rather than a phone. Still shorter on small screens than the 468px the design asks for, so the signup
   band below it starts within the first scroll rather than a full screen down. */
.fk-thread .mk-hero-thread-view { height:330px; }

/* The band. Full-bleed, the same nude as the hero, and since 2026-07-28 with NO hairline and no eyebrow
   above its heading: it is the hero's conclusion, not a new subject, and both were drawing a line under
   the caption where the reader should just keep going. Everything else on the page still announces itself
   with an eyebrow; this one section deliberately doesn't. */
/* Bottom padding back to 48px on 2026-08-01, reversing the 16px of 07-30: that tightening existed only
   because the band ENDED with the registration line and fine print belongs against the edge it is
   printed above. The line now prints inside the card, so the band ends with the trust bar again — the
   arrangement 48px was written for — and 16px under a row of trust claims crowds them into the brown
   example strip. */
.mk-signup-band { background:var(--nude); padding:18px 22px 48px; }
.mk-signup-card { max-width:620px; margin:0 auto; }
/* Centres the heading the way .mk-calls does for the other sections — mk-calls-h is capped at 18ch, so
   without a centring parent it would sit left of a card that is centred. */
.mk-signup-head { display:flex; flex-direction:column; align-items:center; text-align:center;
  margin:0 auto 20px; }
.mk-signup-head .mk-calls-h { margin-bottom:0; }
/* The free-entry promise, directly under the heading that asks for a phone number. Muted and smaller
   than the heading on purpose: it answers the "what will this cost me" objection without competing
   with the ask itself. */
.mk-signup-sub { margin:10px 0 0; font-size:1.02rem; color:var(--muted); }

/* The registration line, printed at the foot of the signup card itself (moved inside it 2026-08-01; it
   closed the band under the trust bar from 07-30). Set as a stamp, not a sentence: bold, uppercase,
   widely tracked — the typography of something printed on a certificate, which is the whole job of the
   line. The hairline above it is .fk-sent's, the card's own way of marking off a footer band, so the
   stamp reads as printed on the card rather than as a fifth line of the form.

   ONE LINE AT EVERY WIDTH, phones included — which is what makes it read as fine print rather than as a
   short paragraph. The size is therefore not a clamp between two guesses but a fit: the string measures
   about 46em set like this, so dividing the available width by 50 sizes it to its container with ~8% in
   hand for a fallback font rendering wider than Hanken Grotesk, and 10px is the ceiling it stops at once
   there is room to spare.

   What it divides changed with the move. The line used to span the band, so the width was the viewport
   less the band's padding; inside the card it gets the CARD's inner width, which is the smaller of
   620px - 36px of card padding (584px) and the viewport less that padding plus the band's 22px sides
   (100vw - 80px). Below 380px the card's padding drops to 16px, which only makes the true width larger
   than this figure — the arithmetic stays conservative, never optimistic, because the failure mode of
   optimism is an overflowing nowrap.

   The cost of the move is real and was accepted: a 620px container instead of the viewport means the
   ceiling is reached later and phones set it smaller than before (~5.6px at 360px, against ~6.2px in the
   band). Genuinely small — but the alternative at 77 characters is two lines, and this line's whole job
   is to look like the small print on a licence. If legibility ever wins over the stamp, delete the
   nowrap and the font-size fit and let it set two lines at 10px; nothing else here depends on it.

   Neutral ink, NOT the gold of .mk-eyebrow, even though the two share a shape. The band deliberately
   opens with no eyebrow (see .mk-signup-band), and gold is how this page announces a new section — the
   last line of one is not that.

   Uppercased in CSS, sentence case in the HTML: screen readers pronounce some all-caps strings letter by
   letter, and the claim should be spoken as the sentence it is. */
.fk-card .mk-signup-official {
  margin:14px 0 0; padding-top:13px; border-top:1px solid var(--card-border);
  text-align:center; white-space:nowrap;
  font-family:var(--sans); font-weight:700;
  font-size:min(10px, calc(min(584px, 100vw - 80px) / 50));
  letter-spacing:.03em; line-height:1.5; text-transform:uppercase; color:var(--body2); }
/* The status line sits directly above the stamp and collapses when empty (.fk-card .mk-msg:empty), so
   the stamp's own top margin is the entire gap in the common case — but when signup.js writes an error
   into it, .mk-msg's 12px would otherwise stack against the stamp's 14px. Nothing to fix: they are
   separated by the hairline, and 26px above a rule reads as deliberate. Noted so it isn't "tidied". */

/* Trust bar: four claims under the signup card, one row on desktop, wrapping on narrow screens. Labels
   don't wrap internally (a two-line "Encrypted &amp; Secure" reads as two claims), so the row breaks
   between items instead. The column gap is fluid because the four labels total ~800px and the desktop
   content box is 804px at the 900px breakpoint — a fixed 40px gap fits by two pixels, i.e. it wraps the
   moment a fallback font renders a hair wider. Shrinking the gap on narrower viewports keeps the single
   row real rather than nominal, and gives phones tighter pairs.

   Phones want two rows of two, and the two long labels ("Encrypted & Secure" + "We Never Sell Your
   Information") are the pair that doesn't fit at 13px — they were taking a line each. The label size is
   therefore fluid below 449px as well, which is the only way to pair them without wrapping a label or
   cutting the copy. Both clamps hold their old value from 449px/550px up, so desktop is untouched.
   Everything here is a best effort at a pairing, never a guarantee: flex-wrap means the failure mode on
   an unusually narrow screen is the item dropping to its own line, exactly as it does today.

   No rule above it: the band already opens with one, and a second a few hundred pixels down bracketed
   the bar into a strip of its own rather than letting it settle under the card. The top margin carries
   the separation on its own, so it is wider than the 16px this used against the hero caption. */
.mk-trustbar { display:flex; flex-wrap:wrap; justify-content:center; align-items:center;
  gap:12px clamp(14px, 4vw, 40px);
  max-width:1000px; margin:26px auto 0; padding:0; list-style:none; }
/* The flag is 15px tall against 20px line icons; without this the flag's row sits a pixel high. */
.mk-tb-item { display:flex; align-items:center; gap:8px; min-height:20px; }
.mk-tb-item span { font-family:var(--sans); font-weight:600; font-size:clamp(10.5px, 2.9vw, 13px);
  color:var(--body2); white-space:nowrap; }
.mk-tb-icon, .mk-tb-flag { flex:none; }
.mk-tb-flag { border-radius:2px; }

/* Reach figures: two block numbers side by side, sitting on the nude ground directly above the dark
   example strip. They are the last thing read before that strip, and they are meant to be read as one
   pair — hence the hairline between them rather than two separate cards, and hence no gap of their own
   below: they close the signup band's argument, they do not open a section.

   SIDE BY SIDE AT EVERY WIDTH, on purpose. `grid-template-columns:1fr 1fr` rather than flex-wrap, so
   the narrow one cannot drop under the wide one on a small phone — 92% of the traffic that sees this is
   mobile, and a stacked pair is a different design, not a degraded one. The number size is fluid instead:
   `161,609` is the widest string either column ever holds, and the clamp's floor is set so it fits a
   320px screen with both columns' padding on. If a figure ever grows a digit, re-check that floor.

   Tabular figures matter here more than anywhere else on the site: the count-up rewrites the text every
   frame, and proportional digits make the whole number jitter sideways as it climbs. */
.mk-stat-band { background:var(--nude); padding:8px 22px 24px; }
.mk-stats { display:grid; grid-template-columns:1fr 1fr; align-items:start;
  max-width:860px; margin:0 auto; padding:0; list-style:none; }
.mk-stat { text-align:center; padding:0 clamp(8px, 3vw, 28px); }
.mk-stat + .mk-stat { border-left:1px solid var(--line); }
.mk-stat-n { display:block; font-family:var(--serif); font-weight:600; color:var(--maroon);
  font-size:clamp(23px, 7.2vw, 42px); line-height:1.05; letter-spacing:-.01em;
  font-variant-numeric:tabular-nums; font-feature-settings:'tnum' 1; }
.mk-stat-l { display:block; margin-top:7px; font-family:var(--sans); font-weight:600;
  font-size:clamp(10.5px, 2.9vw, 13px); line-height:1.3; color:var(--body2); }

/* Rotating example texts: a full-bleed white strip below the signup band. All eight are in the DOM; one
   is visible at a time. They are absolutely positioned in a fixed-height box so a longer line can never
   resize the strip mid-fade — it is tall enough for the two rows the longest line takes on a phone, and
   that height never changes. (It was a white pill around each line until 2026-07-28; the pill resized
   with every sentence, which made the box the thing you watched.)

   Timing: every line runs the SAME keyframes for the WHOLE cycle and is offset by its own inline
   animation-delay (one --ex-step per position), so the percentages below are fractions of the cycle, not
   of a slot: within its 4.6s slot a line fades up over ~0.9s, holds ~2.8s, fades out over ~0.9s, and is
   invisible for the other seven slots. That ties them to the LIST LENGTH — eight items, 12.5% each — AND
   to the step: change --ex-step and the 2.45%/10.05% marks move with it, because they are a fraction of
   eight slots, not of one. A test pins the length; this comment is the only record of the rest. */
.mk-ex-band { background:var(--deep); padding:18px 22px; }
.mk-examples { --ex-step:4.6s; --ex-cycle:calc(var(--ex-step) * var(--ex-count));
  position:relative; min-height:46px; max-width:860px; margin:0 auto; padding:0; list-style:none;
  display:flex; align-items:center; justify-content:center; }
.mk-ex-line { position:absolute; left:0; right:0; text-align:center; opacity:0;
  animation:mk-ex-fade var(--ex-cycle) linear infinite; }
.mk-ex-line span { display:inline-block; max-width:94%; font:500 15px var(--sans); color:#F6E9DF;
  line-height:1.45; }
/* Hovering holds the line still, the same courtesy the hero carousel extends to anyone reading it. */
.mk-examples:hover .mk-ex-line { animation-play-state:paused; }
@keyframes mk-ex-fade { 0%, 12.5%, 100% { opacity:0; } 2.45%, 10.05% { opacity:1; } }
/* Reduced motion: no rotation at all. The first example stays up — an example that never changes is
   still an example, whereas a stack of eight would be a wall. */
@media (prefers-reduced-motion:reduce) {
  .mk-ex-line { animation:none; }
  .mk-ex-line:first-child { opacity:1; }
}

@media (min-width:900px) {
  .fk-thread .mk-hero-thread-view { height:468px; }
  .mk-signup-band { padding:24px 48px 18px; }
  .mk-stat-band { padding:12px 48px 32px; }
  /* One line fits at this width, so the strip only has to be one line tall. */
  .mk-ex-band { padding:20px 48px; }
  .mk-examples { min-height:26px; }
  .mk-ex-line span { font-size:16px; }
}
@media (max-width:380px) {
  .fk-thread .mk-hero-thread-view { height:300px; }
  .mk-signup-band { padding-left:16px; padding-right:16px; }
}

/* ---------------------------------------------------------------------------
   Welcome / consent gate (/welcome).

   The emptiest screen in the product on purpose: Mabel, one line of ask, the two consent strings, one
   button. Anything added here competes with the single tap the whole funnel depends on.
--------------------------------------------------------------------------- */
.mk-app-pill { margin-left:auto; }
.wg-hero { padding-top:6px; }
.wg-mabel { display:block; margin:0 auto; width:104px; height:134px; object-fit:contain; object-position:bottom; }
.wg-hero .mk-acc-h { margin-top:10px; font-size:30px; }
.wg-hero .mk-acc-sub { max-width:21em; margin-left:auto; margin-right:auto; }
/* The hook gets its own line and the number gets weight — for a 55+ visitor, "who is this texting
   me?" is the moment the welcome text either lands or gets reported as spam. */
.wg-hero .mk-acc-sub strong { display:block; color:var(--deep); font-weight:600; margin-bottom:2px; }
.wg-hero .mk-acc-sub b { color:var(--deep); font-weight:600; white-space:nowrap; }

@media (max-width:380px) {
  .wg-mabel { width:88px; height:113px; }
  .wg-hero .mk-acc-h { font-size:27px; }
}
