/* ============================================================================
   PORCELAIN MARKETING — a small "Porcelain-family" component set for the
   signed-out Jinja pages (marketing/legal, the top navbar, footer, error
   pages). These pages cannot import the Porcelain React bundle's CSS Modules
   (see scripts/build_porcelain_shell_css.py's own header for why), so this is
   a hand-authored sheet in the same spirit as porcelain-shell.css: it reads
   the SAME --cls-* custom properties porcelain-tokens.css already declares
   (loaded earlier in base.html — see that file), and adds nothing of its own
   except layout/typography rules and five NEW component classes the base
   system has no equivalent for (a marketing hero, a stat strip, a pull-quote,
   a comparison ledger, an FAQ disclosure). Every rule here follows DESIGN.md:
   warm neutral ramp, Lexend, hairline structure, one raised tier, the two
   named eases, no bounce, no gradient text, no glass.

   Class prefix: `mkt-` for anything new, so it can never collide with a
   Tailwind utility or an existing hand-authored class. Nav/footer/error/form
   fixes below reuse the DOM's EXISTING class and id/data-attribute names —
   see each section's own comment for why touching only the CSS was safe
   there (nav.js and the FAQ/contact-modal scripts read those names).
   ============================================================================ */

/* ---------------------------------------------------------------------------
   0. Shared primitives
--------------------------------------------------------------------------- */
.mkt-shell{max-width:1180px;margin-inline:auto;padding-inline:1rem;}
@media (min-width:640px){.mkt-shell{padding-inline:1.5rem;}}
@media (min-width:1024px){.mkt-shell{padding-inline:2rem;}}
.mkt-shell-narrow{max-width:800px;margin-inline:auto;padding-inline:1rem;}
@media (min-width:640px){.mkt-shell-narrow{padding-inline:1.5rem;}}

/* DESIGN.md's `caps` token verbatim: 10.5/700/.09em/uppercase — "the section
   label," and the type table's own words for the job an eyebrow does.
   BUDGET (DESIGN.md §8 house rule 2): at most TWO caps labels per page —
   "two is a structure; five is a warning label." This is a chapter marker
   for a genuine new section, never a card/demo micro-caption — use .mkt-tag
   below for that job instead (audited 2026-09-04: several live pages had
   drifted into using .mkt-eyebrow for both jobs). */
.mkt-eyebrow{
  display:inline-flex;align-items:center;gap:.5rem;
  font-size:10.5px;line-height:1.3;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--cls-blue-ink,#14599f);
}
.dark .mkt-eyebrow{color:var(--cls-blue-ink,#7cbbf7);}
.mkt-eyebrow-dot{width:6px;height:6px;border-radius:var(--cls-pill,999px);background:var(--cls-blue,#2b8cee);flex:none;}
/* index.html's two fixed-dark sections again (see .mkt-h2--inverse above). */
.mkt-eyebrow--inverse,.dark .mkt-eyebrow--inverse{color:var(--cls-blue-ink,#7cbbf7);}
/* A lighter sibling for a card/demo-internal micro-caption ("15 minutes out",
   "Weekly digest — from Tutix") — same job as an eyebrow's label role, but
   NOT a section marker, so no uppercase/wide-tracking chapter-heading voice. */
.mkt-tag{display:inline-flex;align-items:center;gap:.4rem;font-size:11.5px;line-height:1.45;font-weight:600;letter-spacing:-.005em;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-tag{color:var(--cls-ink-3,#b0a795);}

/* A marketing headline needs bigger type than Porcelain's product ramp tops
   out at (--figure is 30px) — these two sizes are a deliberate, SEPARATE
   marketing-only scale, not a violation of "no tenth size": that rule scopes
   product chrome, and a hero headline is not product chrome. Both are still
   Lexend, still ink-solid, still respect the same tracking direction as the
   rest of the ramp (tighter at larger sizes). */
.mkt-h1{
  font-family:'Lexend','Helvetica Neue',Helvetica,system-ui,sans-serif;
  font-weight:700;letter-spacing:-.02em;line-height:1.08;
  font-size:clamp(2.1rem,1.55rem + 2.4vw,3.4rem);
  color:var(--cls-ink,#1c1a17);
  overflow-wrap:anywhere;min-width:0;
}
.dark .mkt-h1{color:var(--cls-ink,#f4efe6);}
/* .mkt-h2 is PageHeader.module.css's `.title` VERBATIM (25/700/-.02em/1.25) —
   not a marketing-scale invention like .mkt-h1. A section head on a
   marketing page and a page title in the signed-in product are the same
   job (the biggest thing on the view, naming what follows), so this is the
   one place "match the React build" means "use its exact number." */
.mkt-h2{
  font-family:'Lexend','Helvetica Neue',Helvetica,system-ui,sans-serif;
  font-weight:700;letter-spacing:-.02em;line-height:1.25;
  font-size:25px;
  color:var(--cls-ink,#1c1a17);
  overflow-wrap:anywhere;min-width:0;
}
.dark .mkt-h2{color:var(--cls-ink,#f4efe6);}
/* index.html's two dark-panel sections (a fixed #0f1724, independent of the
   site's own light/dark toggle) need white regardless of mode — the same
   reason --cls-on-lead exists: a fixed dark surface needs a fixed ink. */
.mkt-h2--inverse,.dark .mkt-h2--inverse{color:var(--cls-on-lead,#fff);}
/* .mkt-h3 is EmptyState.module.css's `.title` verbatim (15.5/600/-.005em) —
   the same "series-name size" DESIGN.md's own type table calls `name`. */
.mkt-h3{font-size:15.5px;line-height:1.3;font-weight:600;letter-spacing:-.005em;color:var(--cls-ink,#1c1a17);overflow-wrap:anywhere;min-width:0;}
.dark .mkt-h3{color:var(--cls-ink,#f4efe6);}
/* .mkt-lede is DESIGN.md's own `lede` token verbatim (19/600/-.015em) —
   "wordmark, page lede." A hero's supporting paragraph is exactly that job. */
.mkt-lede{font-size:19px;font-weight:600;letter-spacing:-.015em;line-height:1.4;color:var(--cls-ink-2,#443f38);overflow-wrap:anywhere;min-width:0;}
.dark .mkt-lede{color:var(--cls-ink-2,#cec6b8);}
/* .mkt-body is the `body` token verbatim (14/1.55) — the reading size. */
.mkt-body{font-size:14px;line-height:1.55;color:var(--cls-ink-2,#443f38);}
.dark .mkt-body{color:var(--cls-ink-2,#cec6b8);}
/* .mkt-meta is PageHeader's `.description` verbatim (12.5/500/1.5). */
.mkt-meta{font-size:12.5px;font-weight:500;line-height:1.5;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-meta{color:var(--cls-ink-3,#b0a795);}

/* Accent text — replaces the animated/clip-text gradient runs that used to
   sit inline in a headline. Solid ink, per DESIGN.md §4. */
.mkt-accent{color:var(--cls-blue-ink,#14599f);}
.dark .mkt-accent{color:var(--cls-blue-ink,#7cbbf7);}

/* ---------------------------------------------------------------------------
   1. Section rhythm — replaces the radial-gradient hero glow + blurred
   floating blobs every page opened with. Flat surfaces, a single hairline
   between bands where one is needed instead of a colour change plus a glow.
--------------------------------------------------------------------------- */
.mkt-section{padding-block:4.5rem;}
.mkt-section-tight{padding-block:3.25rem;}
@media (max-width:640px){
  .mkt-section{padding-block:3rem;}
  .mkt-section-tight{padding-block:2.25rem;}
}
.mkt-band{background:var(--cls-tray,#f4f2ee);}
.dark .mkt-band{background:var(--cls-tray,#211d15);}
.mkt-band-ruled{border-block:1px solid var(--cls-line,#e6e1da);}
.dark .mkt-band-ruled{border-color:var(--cls-line,#332d24);}

.mkt-hero{padding-block:4rem 3.25rem;}
@media (min-width:1024px){.mkt-hero{padding-block:5.5rem 4rem;}}

/* ---------------------------------------------------------------------------
   2. Cards / tiles — matched to Tile.module.css exactly: --cls-r radius,
   --cls-panel ground, --cls-line hairline, and the ONE thing the earlier
   pass was missing — Tile ships `box-shadow: var(--cls-lit)` AT REST (the
   family-signature inset top edge), not only on hover. `.card-hover` is a
   GLOBAL override, not `.mkt-`-scoped: it is used only by the pages this
   pass touches plus four already-orphaned pre-Porcelain templates (verified
   via `grep -rl card-hover templates/` — about/classes-for-parents/
   help-and-faq/index/tutor-classes/tutors/why-tutix, marketing_fx.html
   itself, and cog-plus.html + login.html, neither reachable from any live
   route), so redirecting it sitewide carries none of the blast-radius risk
   a generic Tailwind class name like `.rounded-2xl` would.
--------------------------------------------------------------------------- */
.mkt-tile,.card-hover,.faq-item{
  border-radius:var(--cls-r,14px)!important;
  border:1px solid var(--cls-line,#e6e1da)!important;
  background:var(--cls-panel,#fdfcfa)!important;
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95))!important;
}
/* :where() keeps this default at zero specificity, so a co-applied Tailwind
   padding utility (p-4, px-6, py-3, etc.) on the same element wins instead
   of silently losing to this rule (both are otherwise equal-specificity, and
   this file loads after Tailwind's compiled utilities) — verified live: 25+
   elements across the site pair .mkt-tile with an explicit padding utility
   expecting it to apply. Elements using bare .mkt-tile with no padding
   utility keep 24px. CAUTION: this comment must never contain the literal
   two-character sequence that closes a CSS comment — it silently truncates
   everything after it in some parsers and is very hard to notice. */
:where(.mkt-tile){padding:1.5rem;}
.mkt-tile{transition:border-color var(--cls-dur,180ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));}
.dark .mkt-tile,.dark .card-hover,.dark .faq-item{
  border-color:var(--cls-line,#332d24)!important;
  background:var(--cls-panel,#2a251d)!important;
}
.mkt-tile:hover{border-color:var(--cls-line-hover,#c8c1b5);}
.dark .mkt-tile:hover{border-color:var(--cls-line-hover,#5b5145);}
@media (prefers-reduced-motion: reduce){.mkt-tile{transition:none;}}

/* .sq-ic (Icon.module.css) is 28px / --cls-r-sm / --cls-leaf / --cls-line-2 /
   --cls-lit for PRODUCT chrome; a marketing feature grid draws attention
   rather than labelling a row, so this is deliberately the larger, tinted
   "one accent tone over leaf" treatment Pill's own .blue/.green tones use —
   same radius token and elevation model, a marketing-scale variant on top,
   which is what "add customized components to the system" means in
   practice: extend the vocabulary, don't invent a new one. */
.mkt-icon-well{
  width:44px;height:44px;border-radius:var(--cls-r-sm,9px);
  display:flex;align-items:center;justify-content:center;flex:none;
  background:color-mix(in srgb,var(--cls-blue,#2b8cee) 10%,var(--cls-leaf,#fff));
  border:1px solid color-mix(in srgb,var(--cls-blue-ink,#14599f) 20%,transparent);
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95));
  color:var(--cls-blue-ink,#14599f);
  margin-bottom:1rem;
}
.dark .mkt-icon-well{background:color-mix(in srgb,var(--cls-blue,#2b8cee) 14%,var(--cls-leaf,#2d2820));color:var(--cls-blue-ink,#7cbbf7);}
.mkt-icon-well.mkt-icon-well--green{background:color-mix(in srgb,var(--cls-green,#16a34a) 10%,var(--cls-leaf,#fff));border-color:color-mix(in srgb,var(--cls-green-ink,#10682f) 20%,transparent);color:var(--cls-green-ink,#10682f);}
.dark .mkt-icon-well.mkt-icon-well--green{background:color-mix(in srgb,var(--cls-green,#16a34a) 14%,var(--cls-leaf,#2d2820));color:var(--cls-green-ink,#5cc684);}
/* The comment above recommends .mkt-icon-well used INLINE beside a heading
   as the go-forward pattern (see tutor-classes.html) — but the well's own
   default margin-bottom:1rem is only correct for its ORIGINAL stacked
   usage. Every live inline call site had to patch that around with its own
   `style="margin-bottom:0"` (audited 2026-09-05); this modifier moves that
   fix into the class itself instead of leaving every caller to rediscover it. */
.mkt-icon-well.mkt-icon-well--inline{margin-bottom:0;}
/* .icon-container (about/why-tutix/tutors/tutor-classes/classes-for-parents/
   help-and-faq/index) — same global-safety argument as .card-hover; radius
   and shadow only, size stays whatever Tailwind width/height utility the
   markup already sets, since that varies 40-48px per page by design intent,
   not drift. */
.icon-container{border-radius:var(--cls-r-sm,9px)!important;box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95))!important;}
/* Escape hatch (audited 2026-09-04): .icon-container/.card-hover's boxed-
   square-above-heading shape is legacy-compat only — repeated at scale it's
   the textbook "icon-tile feature card in a 3-column grid" tell. New/updated
   sections should prefer .mkt-icon-well used INLINE beside a heading (see
   tutor-classes.html's own pattern) over a boxed icon above one; when
   .icon-container's boxed square must stay (existing markup), this modifier
   strips it back to a bare icon with no square/border/shadow of its own. */
.icon-container--bare{background:transparent!important;border:none!important;box-shadow:none!important;width:auto!important;height:auto!important;}
/* Circular avatar well (index.html's 7-tutor grid) — TutorAvatar.module.css's
   --cls-pill radius, NOT .icon-container's --cls-r-sm square-well radius
   (the two must never share a class or the square radius wins and the frame
   stops being a circle). */
.mkt-avatar-well{border-radius:var(--cls-pill,999px);background:var(--cls-leaf,#fff);box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95));}

.mkt-feature-grid{display:grid;gap:1.25rem;grid-template-columns:1fr;}
@media (min-width:640px){.mkt-feature-grid{grid-template-columns:repeat(2,minmax(0,1fr));}}
@media (min-width:1024px){.mkt-feature-grid--4{grid-template-columns:repeat(4,minmax(0,1fr));}
  .mkt-feature-grid--3{grid-template-columns:repeat(3,minmax(0,1fr));}
  /* An asymmetric escape hatch from "N equal columns" — a lead item spans
     4/6, the rest share the remaining 2/6 each. Same content, one deliberate
     size break instead of a uniform grid every LLM defaults to. */
  .mkt-feature-grid--asym{grid-template-columns:repeat(6,minmax(0,1fr));}
  .mkt-feature-grid--asym>:first-child{grid-column:span 4;}
  .mkt-feature-grid--asym>:not(:first-child){grid-column:span 2;}
}

/* ---------------------------------------------------------------------------
   3. Buttons — matched to Button.module.css's REAL anatomy: 44px min-height,
   0 16px padding, --cls-r radius, ctl type (13/600/-.005em/1.35),
   --cls-line-2 border, --cls-lit shadow, focus-visible outline, active =
   --cls-recess (never a transform). This is a GLOBAL override of
   `.btn-primary`/`.btn-secondary` (see the scope note on .card-hover above —
   same file list) rather than markup edits: every instance still carries the
   OLD Tailwind sizing (h-12/h-14, px-7/px-8, rounded-lg, font-semibold/bold,
   text-lg) in the same class="" attribute, and rewriting that across ~40
   button instances in 9 files would be far riskier than winning the cascade
   on each conflicting property. `!important` is load-bearing here: Tailwind's
   `h-12` sets `height` (a fixed value `min-height` alone cannot shrink below),
   so `height:auto` has to be forced too before `min-height:44px` can act as
   the real height. Result: every marketing CTA is now the SAME control the
   signed-in build renders, not a bigger look-alike — no exception for the
   "hero" buttons some pages sized to h-14/text-lg. Hierarchy still reads
   through colour and position, exactly like every Porcelain screen. */
/* .mkt-btn-primary/.mkt-btn-secondary ride the same selector list as the
   legacy names — for markup written fresh (nothing to out-rank) the
   `!important`s below are simply inert, not load-bearing; behaviour is
   identical either way. */
.btn-primary,.btn-secondary,.mkt-btn-primary,.mkt-btn-secondary{
  display:inline-flex!important;align-items:center!important;justify-content:center!important;
  gap:8px!important;
  height:auto!important;min-height:44px!important;
  padding:0 16px!important;
  border-radius:var(--cls-r,14px)!important;
  font-size:13px!important;line-height:1.35!important;font-weight:600!important;letter-spacing:-.005em!important;
  white-space:nowrap;
  text-decoration:none!important;
}
.btn-primary,.mkt-btn-primary{
  background:var(--cls-blue,#2b8cee)!important;
  border:1px solid var(--cls-blue-deep,#1a6bbd)!important;
  color:var(--cls-on-accent,#1c1a17)!important;
  box-shadow:var(--cls-lit-on,inset 0 1px 0 rgba(255,255,255,.42)),0 2px 6px color-mix(in srgb,var(--cls-shadow-ink,#4a3e2c) 20%,transparent)!important;
  transition:background-color var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1))!important;
}
.btn-primary:hover,.mkt-btn-primary:hover{background:var(--cls-blue-hover,#3f97f0)!important;}
.btn-primary:active,.mkt-btn-primary:active{background:var(--cls-blue,#2b8cee)!important;box-shadow:var(--cls-recess,inset 0 2px 5px rgba(74,62,44,.10),inset 0 0 0 1px rgba(74,62,44,.05))!important;}
.btn-primary:focus-visible,.mkt-btn-primary:focus-visible{outline:2px solid var(--cls-blue-deep,#1a6bbd);outline-offset:1px;transition:none!important;}

.btn-secondary,.mkt-btn-secondary{
  background:var(--cls-leaf,#fff)!important;
  border:1px solid var(--cls-line-2,#d6d0c6)!important;
  color:var(--cls-ink-2,#443f38)!important;
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95))!important;
  transition:border-color var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1)),color var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1))!important;
}
.dark .btn-secondary,.dark .mkt-btn-secondary{background:var(--cls-leaf,#2d2820)!important;color:var(--cls-ink-2,#cec6b8)!important;}
.btn-secondary:hover,.mkt-btn-secondary:hover{border-color:var(--cls-line-hover,#c8c1b5)!important;color:var(--cls-ink,#1c1a17)!important;}
.dark .btn-secondary:hover,.dark .mkt-btn-secondary:hover{color:var(--cls-ink,#f4efe6)!important;}
.btn-secondary:active,.mkt-btn-secondary:active{background:var(--cls-well,#e3dfd8)!important;color:var(--cls-ink,#1c1a17)!important;box-shadow:var(--cls-recess,inset 0 2px 5px rgba(74,62,44,.10),inset 0 0 0 1px rgba(74,62,44,.05))!important;}
.dark .btn-secondary:active,.dark .mkt-btn-secondary:active{background:var(--cls-well,#12100a)!important;color:var(--cls-ink,#f4efe6)!important;}
.btn-secondary:focus-visible,.mkt-btn-secondary:focus-visible{outline:2px solid var(--cls-blue-deep,#1a6bbd);outline-offset:1px;transition:none!important;}
@media (prefers-reduced-motion: reduce){.btn-primary,.btn-secondary,.mkt-btn-primary,.mkt-btn-secondary{transition:none!important;}}
/* Button.module.css's real `.sm`: 36px min-height, 56px min-width, 0 12px
   padding, 12.5px text — for nav.html's compact bar, where every other
   control (the account-menu trigger, the theme toggle) sits at h-9/36px.
   Nav CTAs currently reach this at h-9 with raw bg-primary/text-white
   (the forbidden white-on-blue pair) instead of this variant. */
.mkt-btn-primary--sm,.mkt-btn-secondary--sm{min-height:36px!important;min-width:56px!important;padding:0 12px!important;font-size:12.5px!important;}

/* ---------------------------------------------------------------------------
   4. Pills / badges — matched to Pill.module.css: 22px tall, 0 8px padding,
   10.5/700/uppercase/.075em (note: NOT the `caps` token's .09em — the
   component sheet tightens it specifically for a pill). `.badge-pill` is
   the global override (same scope argument as .card-hover — it appears only
   in this pass's files, marketing_fx.html, and the two orphaned templates
   already named above), replacing the old rounded chip with the real
   control; `.mkt-pill` is the equivalent for markup written fresh.
--------------------------------------------------------------------------- */
.mkt-pill,.badge-pill{
  display:inline-flex!important;align-items:center!important;gap:4px!important;
  height:22px!important;padding:0 8px!important;
  border-radius:var(--cls-pill,999px)!important;
  font-size:10.5px!important;line-height:1.3!important;font-weight:700!important;letter-spacing:.075em!important;text-transform:uppercase!important;
  white-space:nowrap;
  border:1px solid var(--cls-line-2,#d6d0c6);
  background:var(--cls-sunk,#eeebe5);
  color:var(--cls-ink-2,#443f38);
}
.dark .mkt-pill,.dark .badge-pill{border-color:var(--cls-line-2,#4a4236);background:var(--cls-sunk,#1b1710);color:var(--cls-ink-2,#cec6b8);}
.mkt-pill--accent{border-color:color-mix(in srgb,var(--cls-blue-ink,#14599f) 26%,transparent)!important;background:color-mix(in srgb,var(--cls-blue,#2b8cee) 12%,var(--cls-leaf,#fff))!important;color:var(--cls-blue-ink,#14599f)!important;}
.dark .mkt-pill--accent{background:color-mix(in srgb,var(--cls-blue,#2b8cee) 16%,var(--cls-leaf,#2d2820))!important;color:var(--cls-blue-ink,#7cbbf7)!important;}
.mkt-pill--green{border-color:color-mix(in srgb,var(--cls-green-ink,#10682f) 22%,transparent)!important;background:color-mix(in srgb,var(--cls-green,#16a34a) 12%,transparent)!important;color:var(--cls-green-ink,#10682f)!important;}
.dark .mkt-pill--green{color:var(--cls-green-ink,#5cc684)!important;}
.mkt-pill--amber{border-color:color-mix(in srgb,var(--cls-amber-ink,#8f4c04) 22%,transparent)!important;background:color-mix(in srgb,var(--cls-amber,#f59e0b) 13%,transparent)!important;color:var(--cls-amber-ink,#8f4c04)!important;}
.dark .mkt-pill--amber{color:var(--cls-amber-ink,#ecb160)!important;}
.mkt-pill--red{border-color:color-mix(in srgb,var(--cls-red-ink,#b31d1d) 24%,transparent)!important;background:color-mix(in srgb,var(--cls-red,#dc2626) 11%,transparent)!important;color:var(--cls-red-ink,#b31d1d)!important;}
.dark .mkt-pill--red{color:var(--cls-red-ink,#f18d88)!important;}

/* ---------------------------------------------------------------------------
   4b. Inline feedback banner — Banner.module.css's .strip, for the raw
   green-50/red-50 success/error messages contact.html and help-and-faq.html
   build in JS (className = '...') and links.html's access-error notice.
   Deliberately NOT a card (audited 2026-09-04): every live consumer nests
   this inside a .mkt-tile/.card-hover or .mkt-dialog, so the original
   border+--cls-lit+--cls-r recipe duplicated its own container's "card"
   signature one level down — a strip, not a second bordered/shadowed box.
--------------------------------------------------------------------------- */
.mkt-banner{
  border-radius:var(--cls-r-sm,9px);
  background:var(--cls-tray,#f4f2ee);
  padding:11px 14px;
  font-size:14px;font-weight:500;line-height:1.35;
  color:var(--cls-ink-2,#443f38);
}
.dark .mkt-banner{background:var(--cls-tray,#211d15);color:var(--cls-ink-2,#cec6b8);}
.mkt-banner--success{background:color-mix(in srgb,var(--cls-green,#16a34a) 8.5%,var(--cls-leaf,#fff));}
.dark .mkt-banner--success{background:color-mix(in srgb,var(--cls-green,#16a34a) 12%,var(--cls-leaf,#2d2820));}
.mkt-banner--error{background:color-mix(in srgb,var(--cls-red,#dc2626) 7.5%,var(--cls-leaf,#fff));}
.dark .mkt-banner--error{background:color-mix(in srgb,var(--cls-red,#dc2626) 11%,var(--cls-leaf,#2d2820));}

/* ---------------------------------------------------------------------------
   5. Stat strip / pull-quote — two genuinely new components, built for the
   comparison + founder-quote moments that used to lean on a drop-shadow
   "glow" card.
--------------------------------------------------------------------------- */
.mkt-stat-card{
  border-radius:var(--cls-r,14px);
  border:1px solid var(--cls-line,#e6e1da);
  background:var(--cls-panel,#fdfcfa);
  padding:2rem;
  box-shadow:var(--cls-raise,0 1px 2px rgba(74,62,44,.06),0 6px 16px -6px rgba(74,62,44,.16));
}
.dark .mkt-stat-card{border-color:var(--cls-line,#332d24);background:var(--cls-panel,#2a251d);}
.mkt-stat-figure{font-size:52px;line-height:1;font-weight:700;letter-spacing:-.03em;color:var(--cls-blue-ink,#14599f);font-variant-numeric:tabular-nums;}
.dark .mkt-stat-figure{color:var(--cls-blue-ink,#7cbbf7);}
/* Documented modifier, not an inline style override — why-tutix.html's cost-
   anchor card is the one figure on the site that needs the bigger size. */
.mkt-stat-figure--lg{font-size:64px;}
.mkt-stat-was{font-size:30px;line-height:1;font-weight:700;letter-spacing:-.03em;color:var(--cls-ink-3,#5b554c);text-decoration:line-through;text-decoration-color:var(--cls-red,#dc2626);text-decoration-thickness:2px;font-variant-numeric:tabular-nums;}
.dark .mkt-stat-was{color:var(--cls-ink-3,#b0a795);}

.mkt-quote{
  border-left:2px solid var(--cls-blue,#2b8cee);
  padding-left:1.1rem;
  /* Georgia, not the ambient Lexend body font (audited 2026-09-05): Lexend
     loads weight only, no italic cut, so font-style:italic here used to
     synthesize a mechanical shear instead of drawing a real italic. Georgia
     ships a genuine italic on every OS, and it's already the one outlier
     face this file spends on §19's decorative quotation mark — reusing it
     here keeps the "quote" family to that same single outlier slot. */
  font-family:Georgia,'Times New Roman',serif;
  font-size:15.5px;line-height:1.5;font-style:italic;
  color:var(--cls-ink,#1c1a17);
}
.dark .mkt-quote{color:var(--cls-ink,#f4efe6);}
.mkt-quote footer{margin-top:.6rem;font-style:normal;font-size:11.5px;font-weight:600;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-quote footer{color:var(--cls-ink-3,#b0a795);}

/* ---------------------------------------------------------------------------
   6. Comparison ledger — replaces the ad hoc CSS-grid-with-1px-gaps
   comparison tables (why-tutix.html, tutor-classes.html, index.html) with
   one real table, hairline-ruled, sharing --cls-seam's identity/status
   reading rhythm.
--------------------------------------------------------------------------- */
.mkt-compare{width:100%;border-collapse:collapse;border:1px solid var(--cls-line,#e6e1da);border-radius:var(--cls-r,14px);overflow:hidden;}
.dark .mkt-compare{border-color:var(--cls-line,#332d24);}
.mkt-compare thead th{
  background:var(--cls-tray,#f4f2ee);
  font-size:12.5px;font-weight:700;text-align:left;padding:.85rem 1.1rem;
  color:var(--cls-ink-2,#443f38);
  border-bottom:1px solid var(--cls-line,#e6e1da);
}
.dark .mkt-compare thead th{background:var(--cls-tray,#211d15);color:var(--cls-ink-2,#cec6b8);border-color:var(--cls-line,#332d24);}
.mkt-compare thead th.mkt-compare-lead{background:var(--cls-blue,#2b8cee);color:var(--cls-on-accent,#1c1a17);}
.mkt-compare tbody td{padding:.85rem 1.1rem;font-size:13.5px;border-top:1px solid var(--cls-line,#e6e1da);color:var(--cls-ink-2,#443f38);}
.dark .mkt-compare tbody td{border-color:var(--cls-line,#332d24);color:var(--cls-ink-2,#cec6b8);}
.mkt-compare tbody td:first-child{font-weight:600;color:var(--cls-ink,#1c1a17);}
.dark .mkt-compare tbody td:first-child{color:var(--cls-ink,#f4efe6);}
.mkt-compare tbody td.mkt-compare-win{font-weight:600;color:var(--cls-blue-ink,#14599f);background:color-mix(in srgb,var(--cls-blue,#2b8cee) 5%,transparent);}
.dark .mkt-compare tbody td.mkt-compare-win{color:var(--cls-blue-ink,#7cbbf7);}
.mkt-compare tbody tr{transition:background-color var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));}
.mkt-compare tbody tr:hover{background:var(--cls-tray,#f4f2ee);}
.dark .mkt-compare tbody tr:hover{background:var(--cls-tray,#211d15);}
@media (prefers-reduced-motion: reduce){.mkt-compare tbody tr{transition:none;}}
@media (max-width:640px){.mkt-compare thead th,.mkt-compare tbody td{padding:.65rem .75rem;font-size:12.5px;}}
/* A wide ledger scrolls inside its own box on a small screen rather than
   forcing the whole page to scroll sideways. */
.mkt-compare-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;}

/* Legacy demo-frame / showcase-card — index.html + tutor-classes.html.
   Same names, Flat-Until-Engaged treatment instead of a 3D tilt / lift. */
.demo-frame,.showcase-card{transition:border-color var(--cls-dur,180ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));}
.demo-frame:hover,.showcase-card:hover{border-color:var(--cls-line-hover,#c8c1b5);}
@media (prefers-reduced-motion: reduce){.demo-frame,.showcase-card{transition:none;}}

/* ---------------------------------------------------------------------------
   7. FAQ disclosure (help-and-faq.html). Same #ids/classes toggleFaq()
   already reads (.faq-item / .faq-answer / .faq-icon) — only the paint
   changes, so the search filter and open/close script needed no edit.
--------------------------------------------------------------------------- */
/* radius/border/background/shadow now come from §2's shared .mkt-tile,.card-hover,.faq-item
   rule (with !important, since this page also fights Tailwind classes elsewhere);
   this rule only adds what that shared one doesn't know about — clipping the
   inner toggle button's own independent rounded-2xl corner/hover-fill to the
   tile's radius, exactly Tile.module.css's documented .clip pattern
   ("the unfold clips its body to the tile radius"). */
.faq-item{overflow:hidden;}
/* The toggle button sits edge-flush against .faq-item on all sides, so a
   default browser focus ring (drawn at offset 0) would be clipped by the
   overflow:hidden above — an INSET ring (same fix already used for
   .mkt-toggle-btn:focus-visible) draws inside the button's own box instead,
   so it can never be clipped regardless of how flush the button sits. */
.faq-item>button:focus-visible{outline:2px solid var(--cls-blue-deep,#1a6bbd);outline-offset:-2px;border-radius:var(--cls-r,14px);transition:none;}
.faq-icon{transition:transform var(--cls-dur,180ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));color:var(--cls-ink-3,#5b554c);}
.dark .faq-icon{color:var(--cls-ink-3,#b0a795);}
@media (prefers-reduced-motion: reduce){.faq-icon{transition:none;}}

/* ---------------------------------------------------------------------------
   8. Legal prose (privacy.html, terms.html) — replaces the Tailwind
   Typography `.prose` plugin styling (raw slate palette) with Porcelain
   tokens at the same ~70ch measure DESIGN.md's Appendix says was kept.
--------------------------------------------------------------------------- */
.mkt-legal{max-width:70ch;}
/* Deliberately NOT .mkt-h2/title (25px) — a numbered legal section is a
   document-internal break, not the page's own title (the H1 already is
   that); DESIGN.md's `lede` (19/600/-.015em/1.25) is the nearer real token,
   and it also wins the cascade over a bare .mkt-h2 by specificity (a
   descendant selector beats a single class), so this is stated, not
   accidental. Higher specificity than the generic §0 .mkt-h2 rule on
   purpose — see the comment there. */
.mkt-legal h2{font-size:19px;line-height:1.25;font-weight:600;letter-spacing:-.015em;color:var(--cls-ink,#1c1a17);margin-block:0 .9rem;}
.dark .mkt-legal h2{color:var(--cls-ink,#f4efe6);}
.mkt-legal h3{font-size:15.5px;line-height:1.3;font-weight:600;letter-spacing:-.005em;color:var(--cls-ink,#1c1a17);margin-block:1.25rem .6rem;}
.dark .mkt-legal h3{color:var(--cls-ink,#f4efe6);}
.mkt-legal p{font-size:14px;line-height:1.65;color:var(--cls-ink-2,#443f38);margin-block:0 .85rem;}
.dark .mkt-legal p{color:var(--cls-ink-2,#cec6b8);}
.mkt-legal ul,.mkt-legal ol{font-size:14px;line-height:1.65;color:var(--cls-ink-2,#443f38);padding-left:1.4rem;margin-block:0 .85rem;}
.dark .mkt-legal ul,.dark .mkt-legal ol{color:var(--cls-ink-2,#cec6b8);}
.mkt-legal ul{list-style:disc;}
.mkt-legal li{margin-block:.35rem;}
.mkt-legal li>strong{color:var(--cls-ink,#1c1a17);}
.dark .mkt-legal li>strong{color:var(--cls-ink,#f4efe6);}
.mkt-legal section{margin-bottom:2rem;}
.mkt-legal a{color:var(--cls-blue-ink,#14599f);text-decoration:underline;text-decoration-color:transparent;text-underline-offset:3px;transition:text-decoration-color var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));}
.dark .mkt-legal a{color:var(--cls-blue-ink,#7cbbf7);}
.mkt-legal a:hover{text-decoration-color:currentColor;}
.mkt-legal a:focus-visible{outline:2px solid var(--cls-blue-deep,#1a6bbd);outline-offset:2px;border-radius:var(--cls-r-sm,9px);}
@media (prefers-reduced-motion:reduce){.mkt-legal a{transition:none;}}
/* Flat --cls-tray fill, no border/shadow (fixed 2026-09-05): this used to
   carry the same border+--cls-lit "card" recipe as .mkt-legal's own
   .mkt-tile wrapper, so the summary read as a card nested inside a card —
   the audit-flagged case round 3 deliberately deferred. Now matches §24's
   .mkt-callout discipline: distinguished by fill/radius alone. */
.mkt-legal-summary{
  border-radius:var(--cls-r-sm,9px);
  background:var(--cls-tray,#f4f2ee);
  padding:1.25rem 1.5rem;margin-bottom:2rem;
}
.dark .mkt-legal-summary{background:var(--cls-tray,#211d15);}
.mkt-legal-summary h2,.mkt-legal-summary h3{margin-top:0;}
.mkt-legal-summary ul{margin-bottom:0;}
/* Specificity fix: .mkt-legal h2/h3/ul (0,1,1, inside the wrapping .mkt-legal
   doc) otherwise beats a bare .mkt-accent/text-[var(--cls-blue-ink)] (0,1,0)
   on this callout's own heading/list, silently killing its accent color.
   Covers BOTH h2 and h3 — privacy.html's Summary heading is an h2 (fixed to
   that level for correct heading hierarchy; the a11y fix that changed its
   tag from h3 to h2 previously broke this rule when it only listed h3). */
.mkt-legal-summary h2,.mkt-legal-summary h3,.mkt-legal-summary ul{color:var(--cls-blue-ink,#14599f);}
.dark .mkt-legal-summary h2,.dark .mkt-legal-summary h3,.dark .mkt-legal-summary ul{color:var(--cls-blue-ink,#7cbbf7);}

/* ---------------------------------------------------------------------------
   9. Field / form — used by contact.html, the help-and-faq contact modal,
   and links.html's password gate. Pairs with .input-glow's focus fix in
   styles-custom.css (kept there — it's a cross-cutting utility class, not
   marketing-only).
--------------------------------------------------------------------------- */
/* Field.tsx's real `.lbl`: 10.5/700/.09em/uppercase on --cls-ink-3 — the
   `caps` token, not an invented smaller label size. Corrected after reading
   Field.module.css directly (the first version was written without it). */
.mkt-field-label{display:block;font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--cls-ink-3,#5b554c);margin-bottom:.5rem;}
.dark .mkt-field-label{color:var(--cls-ink-3,#b0a795);}
/* Control.module.css's `.base`: --cls-leaf ground (not panel — a form field
   is the one raised layer on a form page), --cls-lit at rest like every
   other control ships, 0 12px padding + 44px min-height (the touch-target
   floor every Porcelain control clears), 500-weight body text. */
.mkt-field{
  width:100%;min-height:44px;padding:0 12px;border-radius:var(--cls-r-sm,9px);
  border:1px solid var(--cls-line-2,#d6d0c6);
  background:var(--cls-leaf,#fff);
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95));
  color:var(--cls-ink,#1c1a17);
  font-size:14px;font-weight:500;line-height:1.5;
}
textarea.mkt-field{min-height:0;padding-block:.6rem;resize:vertical;}
.mkt-field::placeholder{color:var(--cls-ink-4,#6f6759);}
.dark .mkt-field{border-color:var(--cls-line-2,#4a4236);background:var(--cls-leaf,#2d2820);color:var(--cls-ink,#f4efe6);}
.dark .mkt-field::placeholder{color:var(--cls-ink-4,#9a9180);}
/* :hover/:disabled/--error were missing (audited 2026-09-04) despite three
   real forms (contact.html, the help-and-faq contact modal, links.html's
   password gate) that can hit both a locked-while-sending state and a
   validation failure. Focus itself is handled separately by .input-glow
   (styles-custom.css) — every live .mkt-field pairs that class already. */
.mkt-field:hover:not(:focus):not(:disabled){background:var(--cls-tray,#f4f2ee);}
.dark .mkt-field:hover:not(:focus):not(:disabled){background:var(--cls-tray,#211d15);}
.mkt-field:disabled{opacity:.55;cursor:not-allowed;background:var(--cls-well,#e3dfd8);box-shadow:none;}
.dark .mkt-field:disabled{background:var(--cls-well,#12100a);}
.mkt-field:disabled::placeholder{color:var(--cls-line-2,#d6d0c6);}
.dark .mkt-field:disabled::placeholder{color:var(--cls-line-2,#4a4236);}
.mkt-field--error{border-color:var(--cls-red-ink,#b31d1d);}
.mkt-field--error:focus-visible{outline:2px solid var(--cls-red-ink,#b31d1d);outline-offset:1px;transition:none;}
.dark .mkt-field--error{border-color:var(--cls-red-ink,#f18d88);}

/* ---------------------------------------------------------------------------
   9b. Dialog (help-and-faq.html's #contact-modal) — matched to
   Dialog.module.css's real .scrim/.dialog/.title anatomy. The dialog is
   deliberately NOT a deeper elevation — same --cls-leaf as everything else,
   raised only by sitting on the scrim (--cls-lit + --cls-raise together).
   Title is 14/600 prose weight, explicitly NOT the 19px lede scale.
--------------------------------------------------------------------------- */
.mkt-dialog-scrim{
  position:fixed;inset:0;z-index:50;
  background:var(--cls-scrim,rgb(74 62 44 / .34));
  padding:14px 12px;
  overflow-y:auto;overscroll-behavior:contain;
}
/* :not(.hidden), not a bare `display:flex` — this stylesheet loads after
   Tailwind's compiled utilities, so a plain display:flex here (same 0,1,0
   specificity as .hidden{display:none}) would always win and the dialog
   could never actually be hidden via the .hidden toggle both #contact-modal
   and #full-page-error use. :not() lifts this rule's specificity so it only
   applies — and only wins — when .hidden isn't present. */
.mkt-dialog-scrim:not(.hidden){display:flex;align-items:center;justify-content:center;}
@media (min-width:768px){.mkt-dialog-scrim{padding:26px 22px;}}
/* base.html's fatal-error overlay must sit above every other scrim (it was
   z-[100] before this rewrite) — id-scoped so the shared .mkt-dialog-scrim
   z-index:50 stays correct for every other dialog on the site. */
#full-page-error.mkt-dialog-scrim{z-index:100;}
.mkt-dialog{
  width:100%;max-width:28rem;max-height:100%;
  background:var(--cls-leaf,#fff);
  border:1px solid var(--cls-line-2,#d6d0c6);
  border-radius:var(--cls-r,14px);
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95)),var(--cls-raise,0 1px 2px rgba(74,62,44,.06),0 6px 16px -6px rgba(74,62,44,.16));
  overflow:hidden;padding:18px 18px 16px;
}
.dark .mkt-dialog{background:var(--cls-leaf,#2d2820);border-color:var(--cls-line-2,#4a4236);}
.mkt-dialog-title{margin:0;font-size:14px;font-weight:600;letter-spacing:-.005em;line-height:1.32;color:var(--cls-ink,#1c1a17);}
.dark .mkt-dialog-title{color:var(--cls-ink,#f4efe6);}

/* ---------------------------------------------------------------------------
   10. Error state (404/403/500) — modelled directly on EmptyState.module.css's
   `.glyph`: a square well at --cls-r-sm (not a circle — Porcelain has no
   999px icon well anywhere in the system), --cls-leaf ground, --cls-line-2
   hairline, --cls-lit shadow. EmptyState's own square is 34px for an inline
   empty list; a full-page status reads as a bigger moment, so this scales
   the SAME shape up rather than reaching for a different one.
--------------------------------------------------------------------------- */
.mkt-error-icon{
  width:56px;height:56px;border-radius:var(--cls-r-sm,9px);
  display:flex;align-items:center;justify-content:center;margin:0 auto 1.5rem;
  background:var(--cls-leaf,#fff);
  border:1px solid var(--cls-line-2,#d6d0c6);
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95));
  color:var(--cls-blue-ink,#14599f);
}
.dark .mkt-error-icon{background:var(--cls-leaf,#2d2820);border-color:var(--cls-line-2,#4a4236);color:var(--cls-blue-ink,#7cbbf7);}
.mkt-error-icon--amber{color:var(--cls-amber-ink,#8f4c04);}
.dark .mkt-error-icon--amber{color:var(--cls-amber-ink,#ecb160);}
.mkt-error-icon--red{color:var(--cls-red-ink,#b31d1d);}
.dark .mkt-error-icon--red{color:var(--cls-red-ink,#f18d88);}
.mkt-error-code{font-size:52px;line-height:1;font-weight:700;letter-spacing:-.03em;color:var(--cls-blue-ink,#14599f);margin-bottom:.75rem;font-variant-numeric:tabular-nums;}
.dark .mkt-error-code{color:var(--cls-blue-ink,#7cbbf7);}
.mkt-error-code--amber{color:var(--cls-amber-ink,#8f4c04);}
.dark .mkt-error-code--amber{color:var(--cls-amber-ink,#ecb160);}
.mkt-error-code--red{color:var(--cls-red-ink,#b31d1d);}
.dark .mkt-error-code--red{color:var(--cls-red-ink,#f18d88);}

/* ---------------------------------------------------------------------------
   11. Nav / footer chrome — same ids/data-attrs nav.js and the drawer/dropdown
   logic already read (see templates/partials/nav.html + static/js/nav.js);
   only paint changes below, never a hook name.
--------------------------------------------------------------------------- */
#main-navbar{
  background:color-mix(in srgb, var(--cls-ground,#f9f8f5) 92%, transparent);
  border-bottom:1px solid var(--cls-line,#e6e1da);
  -webkit-backdrop-filter:none;backdrop-filter:none; /* DESIGN.md §6: no glass */
}
.dark #main-navbar{background:color-mix(in srgb, var(--cls-ground,#26211a) 92%, transparent);border-color:var(--cls-line,#332d24);}
.nav-dropdown-panel{
  border-radius:var(--cls-r,14px)!important;
  border:1px solid var(--cls-line,#e6e1da)!important;
  background:var(--cls-panel,#fdfcfa)!important;
  box-shadow:var(--cls-raise,0 1px 2px rgba(74,62,44,.06),0 6px 16px -6px rgba(74,62,44,.16))!important;
}
.dark .nav-dropdown-panel{border-color:var(--cls-line,#332d24)!important;background:var(--cls-panel,#2a251d)!important;}
/* Dropdown-panel & drawer row internals — scoped to .nav-dropdown-panel /
   .nav-drawer-link specifically (NOT a bare global override): the raw
   hover:bg-slate-100/border-slate-200/text-slate-500 pairs these rows use are
   also reused, unrelated, across a dozen other already-migrated authenticated
   pages (flashcards-hub, quiz-hub, admin, modals) — repainting those globally
   would be out of this pass's scope. LedgerRow's warm wash, not cool slate. */
.nav-dropdown-panel a:hover,.nav-dropdown-panel button:hover,.nav-drawer-link:hover{background:var(--cls-tray,#f4f2ee)!important;}
.dark .nav-dropdown-panel a:hover,.dark .nav-dropdown-panel button:hover,.dark .nav-drawer-link:hover{background:var(--cls-tray,#211d15)!important;}
.nav-dropdown-panel .border-b,.nav-dropdown-panel .border-t{border-color:var(--cls-line-2,#d6d0c6)!important;}
.dark .nav-dropdown-panel .border-b,.dark .nav-dropdown-panel .border-t{border-color:var(--cls-line-2,#4a4236)!important;}
.nav-dropdown-panel .text-slate-500,.nav-drawer-panel .text-slate-500{color:var(--cls-ink-3,#5b554c)!important;}
.dark .nav-dropdown-panel .text-slate-400,.dark .nav-drawer-panel .text-slate-400{color:var(--cls-ink-3,#b0a795)!important;}
/* Ties on specificity with §12's `.bg-background-light` fix (the drawer panel
   carries both classes) — element+class, same reasoning as footer.site-footer
   above, so this survives regardless of the two rules' order in the file.
   Both currently resolve to --cls-ground anyway, so this is a robustness fix,
   not a visible one. */
div.nav-drawer-panel{background:var(--cls-ground,#f9f8f5)!important;border-color:var(--cls-line,#e6e1da)!important;}
.dark div.nav-drawer-panel{background:var(--cls-ground,#26211a)!important;border-color:var(--cls-line,#332d24)!important;}

/* footer.html also carries `bg-background-light dark:bg-background-dark` (the
   retired-palette fix in §12 below), which ties on specificity with a bare
   `.site-footer` class selector — both `!important`, so it would come down
   to declaration order. `footer.site-footer` (element + class) is a point
   more specific, so the footer's OWN band colour always wins regardless of
   where §12's blanket fix lands in this file. */
footer.site-footer{background:var(--cls-tray,#f4f2ee)!important;border-color:var(--cls-line,#e6e1da)!important;}
.dark footer.site-footer{background:var(--cls-tray,#211d15)!important;border-color:var(--cls-line,#332d24)!important;}

/* SiteFooter.module.css's ACTUAL structure, not just its colour: the real
   component is a contained --cls-tray box at --cls-r-sm with a --cls-line-2
   hairline, `300px 1fr` brand/columns grid at 28px gap, .t-ctl (13/600, NOT
   caps — four caps heads would spend the whole page's caps budget on a
   footer, DESIGN.md house rule 2) group heads on --cls-ink-2, .t-meta
   (12.5/500) links on --cls-ink-3, and a legal bar recessed one further
   step to --cls-sunk behind its own --cls-line rule. footer.html's own
   `.site-footer` keeps the outer full-bleed band (unchanged since it also
   carries the page's own top padding); this box sits inside it. */
.mkt-footer-box{
  background:var(--cls-tray,#f4f2ee);
  border:1px solid var(--cls-line-2,#d6d0c6);
  border-radius:var(--cls-r-sm,9px);
  overflow:hidden;
}
.dark .mkt-footer-box{background:var(--cls-tray,#211d15);border-color:var(--cls-line-2,#4a4236);}
.mkt-footer-body{display:grid;grid-template-columns:300px minmax(0,1fr);gap:28px;padding:24px 26px 22px;}
@media (max-width:1199.98px){.mkt-footer-body{grid-template-columns:1fr;}}
@media (max-width:767.98px){.mkt-footer-body{padding:24px 16px 22px;}}

.mkt-footer-brand{display:flex;flex-direction:column;align-items:flex-start;gap:10px;min-width:0;}
.mkt-footer-tagline{margin:0;max-width:260px;font-size:12.5px;font-weight:500;line-height:1.5;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-footer-tagline{color:var(--cls-ink-3,#b0a795);}
.mkt-footer-social{
  display:inline-flex;align-items:center;justify-content:center;
  width:24px;height:24px;border-radius:var(--cls-r-sm,9px);
  color:var(--cls-ink-3,#5b554c);
  transition:color var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));
}
.dark .mkt-footer-social{color:var(--cls-ink-3,#b0a795);}
.mkt-footer-social:hover{color:var(--cls-ink-2,#443f38);}
.dark .mkt-footer-social:hover{color:var(--cls-ink-2,#cec6b8);}
.mkt-footer-social:focus-visible{outline:2px solid var(--cls-blue-deep,#1a6bbd);outline-offset:2px;transition:none;}
@media (max-width:767.98px){.mkt-footer-social{width:44px;height:44px;}}
@media (prefers-reduced-motion: reduce){.mkt-footer-social{transition:none;}}

.mkt-footer-columns{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:28px;}
@media (max-width:1199.98px){.mkt-footer-columns{grid-template-columns:repeat(2,minmax(0,1fr));}}
@media (max-width:639.98px){.mkt-footer-columns{grid-template-columns:1fr;}}
.mkt-footer-head{margin:0 0 5px;font-size:13px;font-weight:600;letter-spacing:-.005em;line-height:1.3;color:var(--cls-ink-2,#443f38);}
.dark .mkt-footer-head{color:var(--cls-ink-2,#cec6b8);}
.mkt-footer-links{margin:0;padding:0;list-style:none;}
.mkt-footer-link{display:block;padding:4px 0;text-decoration:none;font-size:12.5px;font-weight:500;line-height:1.4;color:var(--cls-ink-3,#5b554c);transition:color var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));}
.dark .mkt-footer-link{color:var(--cls-ink-3,#b0a795);}
.mkt-footer-link:hover{color:var(--cls-ink-2,#443f38);}
.dark .mkt-footer-link:hover{color:var(--cls-ink-2,#cec6b8);}
.mkt-footer-link:focus-visible{outline:2px solid var(--cls-blue-deep,#1a6bbd);outline-offset:2px;border-radius:var(--cls-r-sm,9px);transition:none;}
@media (max-width:767.98px){.mkt-footer-link{min-height:44px;display:flex;align-items:center;}}
@media (prefers-reduced-motion: reduce){.mkt-footer-link{transition:none;}}

.mkt-footer-legal{
  display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;
  column-gap:18px;row-gap:8px;
  min-height:52px;padding:14px 26px;
  background:var(--cls-sunk,#eeebe5);
  border-top:1px solid var(--cls-line,#e6e1da);
}
.dark .mkt-footer-legal{background:var(--cls-sunk,#1b1710);border-color:var(--cls-line,#332d24);}
@media (max-width:767.98px){.mkt-footer-legal{padding:14px 16px;}}
.mkt-footer-copy{margin:0;font-size:11.5px;font-weight:500;line-height:1.4;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-footer-copy{color:var(--cls-ink-3,#b0a795);}
.mkt-footer-legal-list{display:flex;align-items:center;flex-wrap:wrap;column-gap:18px;row-gap:8px;margin:0;padding:0;list-style:none;}
.mkt-footer-legal-link{font-size:11.5px;font-weight:500;line-height:1.4;color:var(--cls-ink-3,#5b554c);text-decoration:none;transition:color var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));}
.dark .mkt-footer-legal-link{color:var(--cls-ink-3,#b0a795);}
.mkt-footer-legal-link:hover{color:var(--cls-ink-2,#443f38);}
.dark .mkt-footer-legal-link:hover{color:var(--cls-ink-2,#cec6b8);}
.mkt-footer-legal-link:focus-visible{outline:2px solid var(--cls-blue-deep,#1a6bbd);outline-offset:2px;border-radius:var(--cls-r-sm,9px);transition:none;}
@media (prefers-reduced-motion: reduce){.mkt-footer-legal-link{transition:none;}}

/* ---------------------------------------------------------------------------
   12. Retiring the pre-Porcelain "cool" base palette on the pages that never
   got migrated. `text-main`/`text-muted`/`background-light`/`background-dark`/
   `border-light` are this project's OWN theme.extend.colors names (see
   native/packages/design/tailwind-preset.cjs) — never touched since the
   Porcelain restyle, so `bg-background-light`/`text-text-main` etc. still
   compiled to the retired cool blue-grey ramp DESIGN.md's Appendix documents
   as replaced (#f6f7f8 canvas, #0d141b ink). These four are safe to redirect
   sitewide: they are project-specific names, not a generic Tailwind palette
   colour, so this cannot collide with an unrelated use elsewhere the way
   overriding `.text-slate-900` globally would. templates/base.html's own
   default body_class is exactly this pair, which is why the fix reaches
   every base.html page that never overrode it (marketing, legal, error,
   admin) — not scope creep, the same retired ramp everywhere it appears.

   `border-border-light` pairs with a GENERIC dark:border-slate-700/800 on
   these pages, which IS reused for unrelated borders elsewhere in the app —
   so that half is a compound selector (both classes required on the same
   element) rather than a bare .dark .border-slate-700 override, which would
   have repainted borders on pages this pass never touched. Same reasoning
   for text-text-muted's dark:text-slate-400/500 pair. */
.text-text-main{color:var(--cls-ink,#1c1a17)!important;}
.dark .text-text-main{color:var(--cls-ink,#f4efe6)!important;}
/* nav.html's active-page links carry text-text-main IN ADDITION to nav-active
   (e.g. class="text-text-main ... nav-active") — since this stylesheet loads
   after styles.css, the !important above silently beat nav-active's blue-ink
   color at equal (0,1,0) specificity, at rest AND on hover, everywhere. A
   currently-active nav link read as identical to every inactive one except
   for font-weight. Re-declared here, after text-text-main, so it wins back. */
.nav-active{color:var(--cls-blue-ink,#14599f)!important;}
.dark .nav-active{color:var(--cls-blue-ink,#7cbbf7)!important;}
.nav-active:hover{color:var(--cls-blue-ink,#14599f)!important;}
.dark .nav-active:hover{color:var(--cls-blue-ink,#7cbbf7)!important;}
.text-text-muted{color:var(--cls-ink-3,#5b554c)!important;}
.dark .text-text-muted{color:var(--cls-ink-3,#b0a795)!important;}
.dark .text-text-muted.dark\:text-slate-400,.dark .text-text-muted.dark\:text-slate-500{color:var(--cls-ink-3,#b0a795)!important;}
.bg-background-light{background-color:var(--cls-ground,#f9f8f5)!important;}
.dark\:bg-background-dark{background-color:var(--cls-ground,#26211a)!important;}
.border-border-light{border-color:var(--cls-line,#e6e1da)!important;}
.dark .border-border-light.dark\:border-slate-700,.dark .border-border-light.dark\:border-slate-800{border-color:var(--cls-line,#332d24)!important;}

/* ============================================================================
   MARKETING COMPONENT LIBRARY — ROUND 2 (2026-09-04). Sections 13-23 below are
   NEW component families, added for the pages this pass explicitly targets:
   pricing (card/toggle), any page with a conversion moment (CTA band), a
   walkthrough moment ("how it works" steps), a social-proof moment (avatar
   group / testimonial / logo row — the latter two ship unwired, see their own
   comments), an announcement moment, a video/screenshot moment, and the two
   long-form legal docs (table of contents). Every rule below follows the same
   discipline as §0-12 above: real --cls-* tokens (values matched against the
   actual React component when a Porcelain equivalent exists — SegmentedControl
   for §14, Pill for the ribbon, EmptyState's glyph-well for the step marker),
   light+dark pairs, --cls-dur-fast/--cls-dur transitions with a
   prefers-reduced-motion:reduce escape hatch, and 44px control heights on
   mobile. Class prefix stays `mkt-` throughout — nothing here reaches for a
   bare Tailwind utility class name that could collide sitewide.

   HONEST STATUS (audited 2026-09-04): §13/14/16/17/21/22's only live
   consumer is templates/pages/pricing.html, which is DEAD CODE — the real
   `/pricing` route renders the React account-app shell, not this Jinja
   template (confirmed via blueprints/web/routes.py's `_render_account_app`).
   So today, only §15 (CTA band, live on why-tutix.html) and §23 (table of
   contents, live on privacy.html/terms.html) actually reach a user; the
   other seven families are exactly as "styled, ready, unwired" as §19/20
   already say they are — they just didn't say so. Each is still real,
   finished, --cls-token-correct CSS a future Jinja page can drop in
   without touching this file; treat pricing.html's markup as a working
   usage reference, not a live page.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   13. Pricing card — Tile.module.css's anatomy (radius/border/panel/--cls-lit)
   plus a taller pad and a flex-column body so a feature list can push the CTA
   to the bottom of an equal-height row. `--featured` is the ONE-raised-object
   budget item for a pricing grid (DESIGN.md house rule 3) — use it on at most
   one card per page. The ribbon is a centred pill straddling the top edge
   (Pill.module.css's own accent-tone recipe, not a corner flag — a flag reads
   as a sticker; a pill reads as a status, which is what "Popular" actually is
   on this system's own vocabulary).
--------------------------------------------------------------------------- */
.mkt-price-card{
  position:relative;
  display:flex;flex-direction:column;
  height:100%;
  border-radius:var(--cls-r,14px);
  border:1px solid var(--cls-line,#e6e1da);
  background:var(--cls-panel,#fdfcfa);
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95));
  padding:1.75rem;
  transition:border-color var(--cls-dur,180ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));
}
.dark .mkt-price-card{border-color:var(--cls-line,#332d24);background:var(--cls-panel,#2a251d);}
.mkt-price-card:hover{border-color:var(--cls-line-hover,#c8c1b5);}
.dark .mkt-price-card:hover{border-color:var(--cls-line-hover,#5b5145);}
@media (prefers-reduced-motion:reduce){.mkt-price-card{transition:none;}}
.mkt-price-card--featured{
  border-color:var(--cls-blue,#2b8cee);
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95)),var(--cls-raise,0 1px 2px rgba(74,62,44,.06),0 6px 16px -6px rgba(74,62,44,.16));
}
.dark .mkt-price-card--featured{border-color:var(--cls-blue,#2b8cee);}
.mkt-price-ribbon{
  position:absolute;top:0;left:50%;transform:translate(-50%,-50%);
  display:inline-flex;align-items:center;gap:4px;
  height:22px;padding:0 10px;
  border-radius:var(--cls-pill,999px);
  font-size:10.5px;font-weight:700;letter-spacing:.075em;text-transform:uppercase;
  white-space:nowrap;
  border:1px solid var(--cls-blue-deep,#1a6bbd);
  background:var(--cls-blue,#2b8cee);
  color:var(--cls-on-accent,#1c1a17);
  box-shadow:0 2px 6px color-mix(in srgb,var(--cls-shadow-ink,#4a3e2c) 20%,transparent);
}
.mkt-price-name{margin:0 0 2px;font-size:15.5px;line-height:1.3;font-weight:600;letter-spacing:-.005em;color:var(--cls-ink,#1c1a17);}
.dark .mkt-price-name{color:var(--cls-ink,#f4efe6);}
.mkt-price-tagline{margin:0 0 1.1rem;font-size:12.5px;line-height:1.5;font-weight:500;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-price-tagline{color:var(--cls-ink-3,#b0a795);}
.mkt-price-figure{display:flex;align-items:baseline;gap:5px;margin-bottom:1.25rem;}
.mkt-price-amount{font-size:30px;line-height:1;font-weight:700;letter-spacing:-.03em;color:var(--cls-ink,#1c1a17);font-variant-numeric:tabular-nums;}
.dark .mkt-price-amount{color:var(--cls-ink,#f4efe6);}
.mkt-price-period{font-size:12.5px;font-weight:500;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-price-period{color:var(--cls-ink-3,#b0a795);}
.mkt-price-note{margin:.35rem 0 0;font-size:11.5px;font-weight:500;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-price-note{color:var(--cls-ink-3,#b0a795);}
.mkt-price-card .mkt-check-list{flex:1 1 auto;margin-bottom:1.5rem;}
.mkt-price-fine{margin:.6rem 0 0;font-size:11.5px;line-height:1.5;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-price-fine{color:var(--cls-ink-3,#b0a795);}

/* ---------------------------------------------------------------------------
   14. Segmented toggle — SegmentedControl.module.css's REAL anatomy, matched
   value for value (not a freelanced pill switch): a recessed --cls-sunk tray
   at --cls-r-sm holding --cls-r-xs stops, a 6px dot marking the checked stop
   (colour is never the only signal), --cls-lit+--cls-raise on the checked
   stop (the tray's one raised object). The dot is a ::before, not a markup
   child — existing plain-text `<button>` markup (e.g. pricing.html's
   long-lived monthly/yearly toggle) gets it for free from CSS alone.
   `.pricing-toggle-active` rides the same rule as the fresh `.is-active` name
   so pricing-page.js's existing classList.toggle(...) needs no JS change —
   same dual-class pattern as §3's .btn-primary/.mkt-btn-primary.
--------------------------------------------------------------------------- */
.mkt-toggle{
  display:inline-flex;gap:3px;padding:3px;
  background:var(--cls-sunk,#eeebe5);
  border:1px solid var(--cls-line-2,#d6d0c6);
  border-radius:var(--cls-r-sm,9px);
  box-shadow:var(--cls-recess,inset 0 2px 5px rgba(74,62,44,.10),inset 0 0 0 1px rgba(74,62,44,.05));
}
.dark .mkt-toggle{background:var(--cls-sunk,#1b1710);border-color:var(--cls-line-2,#4a4236);}
.mkt-toggle-btn{
  font-family:inherit;
  font-size:13px;font-weight:600;letter-spacing:-.005em;
  color:var(--cls-ink-3,#5b554c);
  min-height:40px;padding:0 15px;
  border-radius:var(--cls-r-xs,7px);
  border:1px solid transparent;
  background:transparent;
  cursor:pointer;white-space:nowrap;
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  transition:color var(--cls-dur-fast,120ms) var(--cls-ease,cubic-bezier(.4,0,.2,1)),background-color var(--cls-dur-fast,120ms) var(--cls-ease,cubic-bezier(.4,0,.2,1)),border-color var(--cls-dur-fast,120ms) var(--cls-ease,cubic-bezier(.4,0,.2,1));
}
.dark .mkt-toggle-btn{color:var(--cls-ink-3,#b0a795);}
.mkt-toggle-btn::before{content:'';width:6px;height:6px;flex:none;border-radius:var(--cls-pill,999px);background:transparent;}
.mkt-toggle-btn:hover:not(:disabled){color:var(--cls-ink,#1c1a17);border-color:var(--cls-line-hover,#c8c1b5);}
.dark .mkt-toggle-btn:hover:not(:disabled){color:var(--cls-ink,#f4efe6);}
.mkt-toggle-btn:active:not(:disabled){background:var(--cls-well,#e3dfd8);}
.dark .mkt-toggle-btn:active:not(:disabled){background:var(--cls-well,#12100a);}
.mkt-toggle-btn:focus-visible{outline:2px solid var(--cls-blue-deep,#1a6bbd);outline-offset:-1px;transition:none;}
.mkt-toggle-btn:disabled{color:var(--cls-ink-3,#5b554c);border-color:var(--cls-line-2,#d6d0c6);border-style:dashed;cursor:not-allowed;}
.dark .mkt-toggle-btn:disabled{color:var(--cls-ink-3,#b0a795);border-color:var(--cls-line-2,#4a4236);}
.mkt-toggle-btn.is-active,.mkt-toggle-btn.pricing-toggle-active{
  background:var(--cls-leaf,#fff);
  border-color:var(--cls-line-2,#d6d0c6);
  color:var(--cls-ink,#1c1a17);
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95)),var(--cls-raise,0 1px 2px rgba(74,62,44,.06),0 6px 16px -6px rgba(74,62,44,.16));
}
.dark .mkt-toggle-btn.is-active,.dark .mkt-toggle-btn.pricing-toggle-active{background:var(--cls-leaf,#2d2820);border-color:var(--cls-line-2,#4a4236);color:var(--cls-ink,#f4efe6);box-shadow:var(--cls-lit),var(--cls-raise,0 1px 2px rgba(74,62,44,.06),0 6px 16px -6px rgba(74,62,44,.16));}
.mkt-toggle-btn.is-active::before,.mkt-toggle-btn.pricing-toggle-active::before{background:var(--cls-blue-deep,#1a6bbd);}
@media (max-width:767px),(pointer:coarse){.mkt-toggle-btn{min-height:44px;}}
@media (prefers-reduced-motion:reduce){.mkt-toggle-btn{transition:none;}}

/* ---------------------------------------------------------------------------
   15. CTA band — a full-width conversion moment. `--accent` is the loud
   variant (--cls-blue ground, --cls-on-accent text — the same pair
   .btn-primary already uses) for the one place per page that should earn the
   loudest treatment; the default is the same --cls-tray band §1 already uses
   for section rhythm, quieter and reusable more than once per page.
--------------------------------------------------------------------------- */
.mkt-cta-band{
  border-radius:var(--cls-r,14px);
  background:var(--cls-tray,#f4f2ee);
  border:1px solid var(--cls-line,#e6e1da);
  padding:2.75rem 2rem;
  text-align:center;
}
.dark .mkt-cta-band{background:var(--cls-tray,#211d15);border-color:var(--cls-line,#332d24);}
.mkt-cta-band--accent,.dark .mkt-cta-band--accent{
  background:var(--cls-blue,#2b8cee);
  border-color:var(--cls-blue-deep,#1a6bbd);
  box-shadow:var(--cls-lit-on,inset 0 1px 0 rgba(255,255,255,.42));
}
.mkt-cta-band--accent .mkt-h2,.mkt-cta-band--accent .mkt-lede,.mkt-cta-band--accent .mkt-body{color:var(--cls-on-accent,#1c1a17)!important;}
/* A button's usual blue-deep focus ring sits close in hue to this band's own
   solid blue fill (~1.6:1 contrast, fails the WCAG 1.4.11 3:1 floor for a
   ring against its surrounding surface) — swap to the on-accent ink already
   used for this band's own text, the same fix .mkt-announce-dismiss uses for
   the identical solid-blue-fill situation. */
.mkt-cta-band--accent .btn-primary:focus-visible,.mkt-cta-band--accent .mkt-btn-primary:focus-visible,.mkt-cta-band--accent .btn-secondary:focus-visible,.mkt-cta-band--accent .mkt-btn-secondary:focus-visible{outline-color:var(--cls-on-accent,#1c1a17);}
.mkt-cta-band-copy{max-width:44ch;margin-inline:auto;}
.mkt-cta-band-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:.75rem;margin-top:1.5rem;}
@media (max-width:640px){.mkt-cta-band{padding:2.25rem 1.25rem;}}

/* ---------------------------------------------------------------------------
   16. Process steps — a numbered walkthrough ("how it works"). The marker
   reuses EmptyState.module.css's square-well glyph recipe (--cls-r-sm,
   --cls-leaf, --cls-line-2, --cls-lit) scaled down, matching §10's error-icon
   and §2's icon-well — the THIRD place this exact well recipe appears, which
   is the point: one motif, reused, not three different affordances.
   The connector line needs the step count as --n (inline `style="--n:4"` on
   .mkt-steps when it isn't 3) — exact math for N equal grid columns, no
   overshoot/clip hack: a line from the first marker's centre to the last
   marker's centre is calc(50%/N) in from each edge.
--------------------------------------------------------------------------- */
.mkt-steps{--n:3;position:relative;display:grid;grid-template-columns:1fr;gap:1.75rem;}
@media (min-width:768px){
  .mkt-steps{grid-template-columns:repeat(var(--n),minmax(0,1fr));gap:0 1.75rem;}
  .mkt-steps::before{
    content:'';position:absolute;top:18px;
    left:calc(50% / var(--n));right:calc(50% / var(--n));
    height:1px;background:var(--cls-line,#e6e1da);z-index:0;
  }
  .dark .mkt-steps::before{background:var(--cls-line,#332d24);}
}
.mkt-step{position:relative;z-index:1;display:flex;flex-direction:column;gap:.65rem;min-width:0;}
.mkt-step-marker{
  display:flex;align-items:center;justify-content:center;flex:none;
  width:36px;height:36px;
  border-radius:var(--cls-r-sm,9px);
  background:var(--cls-leaf,#fff);
  border:1px solid var(--cls-line-2,#d6d0c6);
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95));
  font-size:14px;font-weight:700;color:var(--cls-blue-ink,#14599f);
}
.dark .mkt-step-marker{background:var(--cls-leaf,#2d2820);border-color:var(--cls-line-2,#4a4236);color:var(--cls-blue-ink,#7cbbf7);}
.mkt-step-title{margin:0;font-size:15.5px;line-height:1.3;font-weight:600;letter-spacing:-.005em;color:var(--cls-ink,#1c1a17);}
.dark .mkt-step-title{color:var(--cls-ink,#f4efe6);}
.mkt-step-body{margin:0;font-size:13.5px;line-height:1.55;color:var(--cls-ink-2,#443f38);}
.dark .mkt-step-body{color:var(--cls-ink-2,#cec6b8);}

/* ---------------------------------------------------------------------------
   17. Checklist rows — generalises pricing.html's existing check_circle/info
   list markup (kept as Material Symbols; Porcelain's own icon set is a React
   sprite unavailable to a plain-CSS page) into a reusable row with two tones:
   default = included (--cls-green-ink), `--info` = metered/conditional
   (--cls-amber-ink) — the exact distinction pricing.html already draws by
   hand with raw Tailwind color utilities, now token-driven and reusable
   anywhere a feature/benefit list appears.
--------------------------------------------------------------------------- */
.mkt-check-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.55rem;}
.mkt-check-item{display:flex;align-items:flex-start;gap:.6rem;font-size:13.5px;line-height:1.5;color:var(--cls-ink-2,#443f38);}
.dark .mkt-check-item{color:var(--cls-ink-2,#cec6b8);}
.mkt-check-icon{flex:none;margin-top:1px;font-size:18px;line-height:1;color:var(--cls-green-ink,#10682f);}
.dark .mkt-check-icon{color:var(--cls-green-ink,#5cc684);}
.mkt-check-item--info .mkt-check-icon{color:var(--cls-amber-ink,#8f4c04);}
.dark .mkt-check-item--info .mkt-check-icon{color:var(--cls-amber-ink,#ecb160);}

/* ---------------------------------------------------------------------------
   18. Avatar group — stacked initials for a social-proof line ("join N
   learners already on Tutix"). --mkt-avatar-ring lets a caller match the ring
   colour to whatever surface the group sits on (defaults to --cls-ground,
   the page's own base — override inline when nesting inside a --cls-tray
   band: style="--mkt-avatar-ring: var(--cls-tray)"). No photo slot: initials
   only, so this never needs placeholder headshots.
--------------------------------------------------------------------------- */
.mkt-avatar-group{display:inline-flex;align-items:center;}
.mkt-avatar-group-item{
  width:32px;height:32px;flex:none;margin-left:-8px;
  display:flex;align-items:center;justify-content:center;
  border-radius:var(--cls-pill,999px);
  border:2px solid var(--mkt-avatar-ring,var(--cls-ground,#f9f8f5));
  background:color-mix(in srgb,var(--cls-blue,#2b8cee) 12%,var(--cls-leaf,#fff));
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95));
  font-size:11.5px;font-weight:700;letter-spacing:-.01em;color:var(--cls-blue-ink,#14599f);
}
.dark .mkt-avatar-group-item{background:color-mix(in srgb,var(--cls-blue,#2b8cee) 16%,var(--cls-leaf,#2d2820));color:var(--cls-blue-ink,#7cbbf7);}
.mkt-avatar-group-item:first-child{margin-left:0;}
.mkt-avatar-group-more{
  width:32px;height:32px;flex:none;margin-left:-8px;
  display:flex;align-items:center;justify-content:center;
  border-radius:var(--cls-pill,999px);
  border:2px solid var(--mkt-avatar-ring,var(--cls-ground,#f9f8f5));
  background:var(--cls-sunk,#eeebe5);
  font-size:10.5px;font-weight:700;color:var(--cls-ink-3,#5b554c);
}
.dark .mkt-avatar-group-more{background:var(--cls-sunk,#1b1710);color:var(--cls-ink-3,#b0a795);}

/* ---------------------------------------------------------------------------
   19. Testimonial card — styled and ready, DELIBERATELY NOT wired into any
   live page in this pass: the site has no real customer quotes yet (grepped
   every marketing template — none), and Hallmark's own honest-copy rule
   (never fabricate a metric, quote, or attributed name) applies here exactly
   as it would to an invented statistic. Wire real content in once it exists;
   the CSS contract below is final.
--------------------------------------------------------------------------- */
.mkt-testimonial{
  display:flex;flex-direction:column;gap:1.1rem;height:100%;
  border-radius:var(--cls-r,14px);
  border:1px solid var(--cls-line,#e6e1da);
  background:var(--cls-panel,#fdfcfa);
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95));
  padding:1.5rem;
}
.dark .mkt-testimonial{border-color:var(--cls-line,#332d24);background:var(--cls-panel,#2a251d);}
.mkt-testimonial-quote{margin:0;font-family:Georgia,'Times New Roman',serif;font-style:italic;font-size:15.5px;line-height:1.6;color:var(--cls-ink,#1c1a17);}
.dark .mkt-testimonial-quote{color:var(--cls-ink,#f4efe6);}
.mkt-testimonial-byline{display:flex;align-items:center;gap:.65rem;margin-top:auto;}
.mkt-testimonial-avatar{
  width:36px;height:36px;flex:none;
  display:flex;align-items:center;justify-content:center;
  border-radius:var(--cls-pill,999px);
  background:color-mix(in srgb,var(--cls-blue,#2b8cee) 12%,var(--cls-leaf,#fff));
  font-size:13px;font-weight:700;color:var(--cls-blue-ink,#14599f);
}
.dark .mkt-testimonial-avatar{background:color-mix(in srgb,var(--cls-blue,#2b8cee) 16%,var(--cls-leaf,#2d2820));color:var(--cls-blue-ink,#7cbbf7);}
.mkt-testimonial-name{font-size:13px;font-weight:600;letter-spacing:-.005em;line-height:1.3;color:var(--cls-ink,#1c1a17);}
.dark .mkt-testimonial-name{color:var(--cls-ink,#f4efe6);}
.mkt-testimonial-role{font-size:11.5px;font-weight:500;line-height:1.4;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-testimonial-role{color:var(--cls-ink-3,#b0a795);}

/* ---------------------------------------------------------------------------
   20. Logo cloud — same "styled, unwired" status as §19 and for the same
   reason: no real partner/press logos exist yet to grep for. Desaturated at
   rest (a logo row reads as texture, not a call to action) and restored to
   full colour on hover/focus so it stays legible, never fully invisible.
   If a logo links out, wrap it `<a class="mkt-logo-link"><img.../></a>` —
   a bare `<img>`/`<svg>` is never keyboard-focusable on its own, so the
   opacity-only hover/focus pair below is a POINTER affordance only; the
   `a:focus-visible` outline is the real keyboard indicator and is required
   on any linked logo (an unlinked, purely decorative logo needs neither).
--------------------------------------------------------------------------- */
.mkt-logo-row{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:2.5rem 3rem;}
.mkt-logo-row img,.mkt-logo-row svg{
  height:24px;width:auto;display:block;
  opacity:.5;filter:grayscale(1);
  transition:opacity var(--cls-dur,180ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));
}
.mkt-logo-row img:hover,.mkt-logo-row svg:hover{opacity:.9;}
.mkt-logo-row a.mkt-logo-link{display:block;border-radius:var(--cls-r-xs,7px);}
.mkt-logo-row a.mkt-logo-link:hover img,.mkt-logo-row a.mkt-logo-link:hover svg{opacity:.9;}
.mkt-logo-row a.mkt-logo-link:focus-visible{outline:2px solid var(--cls-blue-deep,#1a6bbd);outline-offset:3px;}
.mkt-logo-row a.mkt-logo-link:focus-visible img,.mkt-logo-row a.mkt-logo-link:focus-visible svg{opacity:.9;}
.dark .mkt-logo-row img,.dark .mkt-logo-row svg{opacity:.65;filter:grayscale(1) brightness(1.7);}
.dark .mkt-logo-row img:hover,.dark .mkt-logo-row svg:hover,.dark .mkt-logo-row a.mkt-logo-link:hover img,.dark .mkt-logo-row a.mkt-logo-link:hover svg{opacity:1;}
@media (prefers-reduced-motion:reduce){.mkt-logo-row img,.mkt-logo-row svg{transition:none;}}

/* ---------------------------------------------------------------------------
   21. Announcement bar — a thin, dismissible top-of-page strip. Solid
   --cls-blue like .btn-primary/.mkt-cta-band--accent (the one place a strip
   this loud is earned — a site-wide notice, shown once). JS contract: any
   script wiring the dismiss button only needs to hide the bar's own root on
   click; no state is baked into this stylesheet.
--------------------------------------------------------------------------- */
.mkt-announce-bar{
  position:relative;
  display:flex;align-items:center;justify-content:center;gap:.75rem;flex-wrap:wrap;
  min-height:40px;padding:.55rem 2.75rem .55rem 1rem;
  background:var(--cls-blue,#2b8cee);
  color:var(--cls-on-accent,#1c1a17);
  font-size:12.5px;font-weight:600;line-height:1.4;text-align:center;
}
.mkt-announce-bar a{color:inherit;text-decoration:underline;text-decoration-color:color-mix(in srgb,var(--cls-on-accent,#1c1a17) 45%,transparent);text-underline-offset:2px;}
.mkt-announce-bar a:hover{text-decoration-color:currentColor;}
.mkt-announce-bar a:focus-visible{outline:2px solid var(--cls-on-accent,#1c1a17);outline-offset:2px;text-decoration-color:currentColor;}
.mkt-announce-dismiss{
  position:absolute;right:8px;top:50%;transform:translateY(-50%);
  display:flex;align-items:center;justify-content:center;
  width:28px;height:28px;
  border-radius:var(--cls-r-sm,9px);
  background:transparent;border:none;color:inherit;cursor:pointer;opacity:.75;
  transition:opacity var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1)),background-color var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));
}
.mkt-announce-dismiss:hover{opacity:1;background:color-mix(in srgb,var(--cls-on-accent,#1c1a17) 14%,transparent);}
.mkt-announce-dismiss:focus-visible{outline:2px solid var(--cls-on-accent,#1c1a17);outline-offset:1px;opacity:1;transition:none;}
/* The bar's own 40px min-height leaves no room to grow the visible 28px
   chip to the 44px touch floor without overflowing it — an invisible
   expanded hit area does the same job without changing the bar's density. */
.mkt-announce-dismiss::before{content:'';position:absolute;inset:-8px;}
@media (prefers-reduced-motion:reduce){.mkt-announce-dismiss{transition:none;}}

/* ---------------------------------------------------------------------------
   22. Media frame — an aspect-locked frame for a screenshot or video poster,
   with an optional play-button overlay. Same --cls-raise elevation budget as
   §5's stat-card (use at most one raised element per page); the play button
   is a translucent --cls-leaf disc so it reads on top of ANY poster image
   without needing to know the image's own contrast ahead of time.
--------------------------------------------------------------------------- */
.mkt-media-frame{
  position:relative;
  border-radius:var(--cls-r,14px);
  border:1px solid var(--cls-line,#e6e1da);
  background:var(--cls-tray,#f4f2ee);
  overflow:hidden;
  box-shadow:var(--cls-raise,0 1px 2px rgba(74,62,44,.06),0 6px 16px -6px rgba(74,62,44,.16));
  aspect-ratio:16/9;
}
.dark .mkt-media-frame{border-color:var(--cls-line,#332d24);background:var(--cls-tray,#211d15);}
.mkt-media-frame img,.mkt-media-frame video{width:100%;height:100%;object-fit:cover;display:block;}
.mkt-media-play{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:60px;height:60px;
  display:flex;align-items:center;justify-content:center;
  border-radius:var(--cls-pill,999px);
  background:color-mix(in srgb,var(--cls-leaf,#fff) 92%,transparent);
  border:1px solid var(--cls-line-2,#d6d0c6);
  /* --cls-lit, not --cls-raise (fixed 2026-09-04): the frame already carries
     the one raised tier this composition is budgeted for — a second
     independent ambient shadow on the disc sitting on top of it doubles the
     elevation the token system is built to keep at exactly one. */
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95));
  color:var(--cls-blue-ink,#14599f);
  cursor:pointer;
  transition:transform var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1)),background-color var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));
}
.mkt-media-play:hover{transform:translate(-50%,-50%) scale(1.06);background:var(--cls-leaf,#fff);}
.dark .mkt-media-play{background:color-mix(in srgb,var(--cls-leaf,#2d2820) 92%,transparent);border-color:var(--cls-line-2,#4a4236);color:var(--cls-blue-ink,#7cbbf7);}
.dark .mkt-media-play:hover{background:var(--cls-leaf,#2d2820);}
.mkt-media-play:focus-visible{outline:2px solid var(--cls-blue-deep,#1a6bbd);outline-offset:2px;transition:none;}
@media (prefers-reduced-motion:reduce){.mkt-media-play{transition:none;}.mkt-media-play:hover{transform:translate(-50%,-50%);}}

/* ---------------------------------------------------------------------------
   23. Table of contents — a companion to §8's .mkt-legal for privacy.html /
   terms.html, both already numbered-h2 documents with no anchors. `.is-active`
   is optional (a scroll-spy script may add it; the list works with none set).
--------------------------------------------------------------------------- */
.mkt-toc{
  border-radius:var(--cls-r,14px);
  border:1px solid var(--cls-line,#e6e1da);
  background:var(--cls-tray,#f4f2ee);
  padding:1.1rem 1.25rem;
}
.dark .mkt-toc{border-color:var(--cls-line,#332d24);background:var(--cls-tray,#211d15);}
.mkt-toc-label{margin:0 0 .6rem;font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-toc-label{color:var(--cls-ink-3,#b0a795);}
.mkt-toc-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:1px;}
.mkt-toc-link{
  display:block;padding:6px 8px;margin:0 -8px;
  border-radius:var(--cls-r-sm,9px);
  font-size:12.5px;font-weight:500;line-height:1.5;
  color:var(--cls-ink-3,#5b554c);text-decoration:none;
  transition:color var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1)),background-color var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));
}
.dark .mkt-toc-link{color:var(--cls-ink-3,#b0a795);}
.mkt-toc-link:hover{color:var(--cls-ink,#1c1a17);background:var(--cls-sunk,#eeebe5);}
.dark .mkt-toc-link:hover{color:var(--cls-ink,#f4efe6);background:var(--cls-sunk,#1b1710);}
.mkt-toc-link.is-active{color:var(--cls-blue-ink,#14599f);font-weight:600;}
.dark .mkt-toc-link.is-active{color:var(--cls-blue-ink,#7cbbf7);}
.mkt-toc-link:focus-visible{outline:2px solid var(--cls-blue-deep,#1a6bbd);outline-offset:1px;transition:none;}
@media (prefers-reduced-motion:reduce){.mkt-toc-link{transition:none;}}
.mkt-toc-link{position:relative;}
.mkt-toc-link.is-active{padding-left:14px;}
.mkt-toc-link.is-active::before{content:'';position:absolute;left:2px;top:50%;transform:translateY(-50%);width:2px;height:14px;border-radius:2px;background:var(--cls-blue-ink,#14599f);}
.dark .mkt-toc-link.is-active::before{background:var(--cls-blue-ink,#7cbbf7);}
/* privacy.html/terms.html render this full-width, not as a sidebar — at
   320-375px several real section titles ("4. Subscription Plans, Payments,
   and Billing") wrap to two lines. min-height+flex/align-items:center keeps
   a wrapped row centred and clears the 44px touch floor; the wider list gap
   gives a wrapped two-line row room to breathe next to single-line ones. */
@media (max-width:767.98px){
  .mkt-toc-link{min-height:44px;display:flex;align-items:center;padding-block:8px;}
  .mkt-toc-list{gap:2px;}
}

/* ============================================================================
   ROUND 2 REFINEMENT PASS (same day) — a second look at §13-23 for the detail
   a "finished" component carries: a featured tier that reads as chosen even
   with the ribbon covered, a testimonial with an editorial mark instead of a
   bare box, an optional rating row, an icon accent for a CTA band and an
   announcement bar, a "reached" state for a step marker, a caption bar for a
   media frame. Every value below is still a real --cls-* token — nothing here
   introduces gradients, blur, or a colour outside the ramp; DESIGN.md's "no
   glass, no bounce, no gradient" line is unchanged by any of this.
   ============================================================================ */

/* §13 — the featured tier now carries its own faint tint, not just a border
   and a ribbon: color-mix keeps it a Porcelain surface (still --cls-panel
   underneath) rather than a new colour, at a low enough percentage that body
   text contrast is untouched (verified: WCAG AA holds at 4%/8%). */
.mkt-price-card--featured{
  background:color-mix(in srgb,var(--cls-blue,#2b8cee) 4%,var(--cls-panel,#fdfcfa));
}
.dark .mkt-price-card--featured{
  background:color-mix(in srgb,var(--cls-blue,#2b8cee) 8%,var(--cls-panel,#2a251d));
}

/* §16 — a marker that represents a step already completed (e.g. an onboarding
   checklist reusing the same component), plus a small lift on hover so the
   row reads as reachable, not printed. */
.mkt-step-marker{transition:transform var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));}
.mkt-step:hover .mkt-step-marker{transform:translateY(-2px);}
@media (prefers-reduced-motion:reduce){.mkt-step-marker{transition:none;}.mkt-step:hover .mkt-step-marker{transform:none;}}
.mkt-step-marker--done{
  background:var(--cls-blue,#2b8cee);
  border-color:var(--cls-blue-deep,#1a6bbd);
  color:var(--cls-on-accent,#1c1a17);
}

/* §18 — a touch more depth between overlapping avatars: a real drop shadow
   alongside the family's --cls-lit inset, not just the ring border. */
.mkt-avatar-group-item{box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95)),0 1px 3px color-mix(in srgb,var(--cls-shadow-ink,#4a3e2c) 18%,transparent);}
.dark .mkt-avatar-group-item{box-shadow:var(--cls-lit),0 1px 3px color-mix(in srgb,var(--cls-shadow-ink,#060403) 45%,transparent);}

/* §19 — an editorial pull-quote mark (a literal serif quotation glyph, not an
   icon-font dependency) sitting low-contrast behind the quote text; a
   caller-built star row for a real rating (never a baked-in number — see
   §19's own no-fabrication note, which applies exactly the same way to a
   star count as to a quote). `.mkt-star--empty` is the unfilled tone; the
   caller renders N filled + (5-N) empty, both real SVGs so print/zoom stay
   crisp (no icon-font dependency here either). */
.mkt-testimonial{position:relative;overflow:hidden;}
.mkt-testimonial-mark{
  position:absolute;top:.1rem;right:.85rem;
  font-family:Georgia,'Times New Roman',serif;
  font-size:56px;line-height:1;font-weight:700;
  color:var(--cls-line-2,#d6d0c6);
  pointer-events:none;user-select:none;
}
.dark .mkt-testimonial-mark{color:var(--cls-line-2,#4a4236);}
.mkt-testimonial-quote{position:relative;z-index:1;}
.mkt-star-row{display:inline-flex;align-items:center;gap:2px;color:var(--cls-amber,#f59e0b);}
.mkt-star-row svg{width:14px;height:14px;fill:currentColor;flex:none;}
.mkt-star-row .mkt-star--empty{color:var(--cls-line-2,#d6d0c6);}
.dark .mkt-star-row .mkt-star--empty{color:var(--cls-line-2,#4a4236);}

/* §15/§21 — a small square icon badge for a CTA band's heading, and a fixed
   flex slot so an icon glyph placed before an announcement bar's text never
   gets squeezed by flex-wrap. The badge inherits on-accent tones automatically
   inside `--accent` via color-mix on the fixed on-accent ink, so it never
   needs its own dark-mode rule (on-accent is not theme-dependent — see §14's
   note on why --cls-on-accent is never redeclared under .dark). */
.mkt-cta-band-icon{
  display:flex;align-items:center;justify-content:center;
  width:44px;height:44px;margin:0 auto 1.1rem;
  border-radius:var(--cls-r-sm,9px);
  background:var(--cls-leaf,#fff);
  border:1px solid var(--cls-line-2,#d6d0c6);
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95));
  color:var(--cls-blue-ink,#14599f);
}
.dark .mkt-cta-band-icon{background:var(--cls-leaf,#2d2820);border-color:var(--cls-line-2,#4a4236);color:var(--cls-blue-ink,#7cbbf7);}
.mkt-cta-band--accent .mkt-cta-band-icon{
  background:color-mix(in srgb,var(--cls-on-accent,#1c1a17) 12%,transparent);
  border-color:color-mix(in srgb,var(--cls-on-accent,#1c1a17) 24%,transparent);
  color:var(--cls-on-accent,#1c1a17);
}
.mkt-announce-bar-icon{display:inline-flex;flex:none;font-size:16px;line-height:1;}

/* §22 — an optional solid caption bar over a poster image. Deliberately NOT
   `var(--cls-ink)`: ink is TEXT, so it flips from near-black to near-cream in
   dark mode (right for text, wrong for a fill that has to stay dark under a
   white caption regardless of theme, since the photo behind it doesn't
   invert with the page). `--cls-shadow-ink` stays dark-toned in both modes
   (brown in light, near-black in dark — tokens.css's own note: "a wash must
   use a higher alpha" than a drop-shadow does), mixed at a fixed high
   opacity so white text stays legible over an arbitrary bright photo in
   either theme — a flat colour, never a gradient. */
.mkt-media-frame{--mkt-caption-ink:#fff;}
.mkt-media-caption{
  position:absolute;left:0;right:0;bottom:0;z-index:1;
  padding:10px 14px;
  background:color-mix(in srgb,var(--cls-shadow-ink,#4a3e2c) 78%,transparent);
  color:var(--mkt-caption-ink);
  font-size:12.5px;font-weight:600;line-height:1.4;
}

/* ============================================================================
   MARKETING COMPONENT LIBRARY — ROUND 3 (2026-09-05). Eight more families,
   picked to do two jobs at once: round out real gaps in what the site can
   express (a tabbed switcher, a dated sequence, a wayfinding trail, a team
   roster, a genuine "nothing found" state) AND give the library structural
   variety it was missing — §25's icon row and this pass's escape hatches are
   direct answers to round 2's audit finding that the icon-tile-in-a-grid
   shape repeats site-wide with no alternative. Every rule below holds the
   same line every prior section has: real --cls-* tokens only, light+dark
   pairs, explicit :focus-visible rings, prefers-reduced-motion fallbacks,
   44px control heights, no gradient/glass/bounce, no card nested in a card.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   24. Callout — a flat, non-card "important note" block for body content
   (originally built to finally fix §8's .mkt-legal-summary, which had been
   sitting as a card nested inside .mkt-tile since before this round's audit
   — that fix now lives with the rest of §8, in place, not duplicated here).
   No border, no shadow: distinguished by
   --cls-tray fill and radius alone, the same discipline §4b's .mkt-banner
   already uses, so it can sit inside ANY existing card without becoming a
   second one. The icon well is small enough (32px) to read as an inline
   glyph, not a competing container — same reasoning §15/§21's badge-sized
   icons already rely on inside their own bordered bands.
--------------------------------------------------------------------------- */
.mkt-callout{
  display:flex;gap:.85rem;
  border-radius:var(--cls-r-sm,9px);
  background:var(--cls-tray,#f4f2ee);
  padding:1.1rem 1.25rem;
}
.dark .mkt-callout{background:var(--cls-tray,#211d15);}
.mkt-callout-icon{
  flex:none;width:32px;height:32px;
  display:flex;align-items:center;justify-content:center;
  border-radius:var(--cls-r-xs,7px);
  background:var(--cls-leaf,#fff);
  border:1px solid var(--cls-line-2,#d6d0c6);
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95));
  color:var(--cls-blue-ink,#14599f);
  font-size:18px;
}
.dark .mkt-callout-icon{background:var(--cls-leaf,#2d2820);border-color:var(--cls-line-2,#4a4236);color:var(--cls-blue-ink,#7cbbf7);}
.mkt-callout-body{min-width:0;}
.mkt-callout-title{margin:0 0 .3rem;font-size:13px;font-weight:600;letter-spacing:-.005em;line-height:1.3;color:var(--cls-blue-ink,#14599f);}
.dark .mkt-callout-title{color:var(--cls-blue-ink,#7cbbf7);}
.mkt-callout-body p,.mkt-callout-body ul{margin:0;font-size:13.5px;line-height:1.55;color:var(--cls-ink-2,#443f38);}
.dark .mkt-callout-body p,.dark .mkt-callout-body ul{color:var(--cls-ink-2,#cec6b8);}
.mkt-callout-body ul{padding-left:1.1rem;}
.mkt-callout-body li{margin-block:.2rem;}
/* Tone variants — same amber/red vocabulary §4/§10 already use, background
   only (never a border, or this becomes the side-stripe-card tell). */
.mkt-callout--amber{background:color-mix(in srgb,var(--cls-amber,#f59e0b) 10%,var(--cls-leaf,#fff));}
.dark .mkt-callout--amber{background:color-mix(in srgb,var(--cls-amber,#f59e0b) 14%,var(--cls-leaf,#2d2820));}
.mkt-callout--amber .mkt-callout-icon{color:var(--cls-amber-ink,#8f4c04);}
.dark .mkt-callout--amber .mkt-callout-icon{color:var(--cls-amber-ink,#ecb160);}
.mkt-callout--amber .mkt-callout-title{color:var(--cls-amber-ink,#8f4c04);}
.dark .mkt-callout--amber .mkt-callout-title{color:var(--cls-amber-ink,#ecb160);}

/* ---------------------------------------------------------------------------
   25. Icon row — an inline alternative to §2's icon-tile grid card, for a
   feature list that shouldn't read as N identical boxes (the exact tell
   named above; see also §2's .icon-container--bare and
   .mkt-feature-grid--asym, the other two escape hatches from that finding).
   Reuses .mkt-icon-well's own 44px glyph unchanged — one motif, positioned
   beside the heading instead of above it, not a second icon treatment.
--------------------------------------------------------------------------- */
.mkt-icon-row{display:flex;flex-direction:column;gap:1.5rem;}
.mkt-icon-row-item{display:flex;gap:1rem;align-items:flex-start;}
.mkt-icon-row-item>.mkt-icon-well{margin-bottom:0;}
.mkt-icon-row-body{min-width:0;}
.mkt-icon-row-title{margin:0 0 .3rem;font-size:15.5px;line-height:1.3;font-weight:600;letter-spacing:-.005em;color:var(--cls-ink,#1c1a17);}
.dark .mkt-icon-row-title{color:var(--cls-ink,#f4efe6);}
.mkt-icon-row-body p{margin:0;font-size:13.5px;line-height:1.55;color:var(--cls-ink-2,#443f38);}
.dark .mkt-icon-row-body p{color:var(--cls-ink-2,#cec6b8);}

/* ---------------------------------------------------------------------------
   26. Tabs — a content-switcher, deliberately NOT another SegmentedControl:
   §14's toggle is a two/three-way VALUE picker living in a recessed tray;
   this switches between genuinely different content panels, so it earns its
   own, different visual language — an underline indicator on plain text,
   the pattern editorial/docs sites use for "destination" tabs. JS contract:
   toggle `.is-active` on the clicked .mkt-tab and toggle `hidden` on the
   matching .mkt-tab-panel; nothing here assumes a specific framework.
--------------------------------------------------------------------------- */
.mkt-tabs{display:flex;gap:1.75rem;border-bottom:1px solid var(--cls-line,#e6e1da);overflow-x:auto;}
.dark .mkt-tabs{border-color:var(--cls-line,#332d24);}
.mkt-tab{
  position:relative;flex:none;
  display:inline-flex;align-items:center;min-height:44px;
  font-family:inherit;background:transparent;border:none;padding:0;margin-bottom:-1px;
  cursor:pointer;white-space:nowrap;
  font-size:13.5px;font-weight:600;letter-spacing:-.005em;
  color:var(--cls-ink-3,#5b554c);
  transition:color var(--cls-dur-fast,120ms) var(--cls-ease,cubic-bezier(.4,0,.2,1));
}
.dark .mkt-tab{color:var(--cls-ink-3,#b0a795);}
.mkt-tab:hover{color:var(--cls-ink,#1c1a17);}
.dark .mkt-tab:hover{color:var(--cls-ink,#f4efe6);}
.mkt-tab:focus-visible{outline:2px solid var(--cls-blue-deep,#1a6bbd);outline-offset:2px;border-radius:var(--cls-r-xs,7px);transition:none;}
.mkt-tab.is-active{color:var(--cls-ink,#1c1a17);}
.dark .mkt-tab.is-active{color:var(--cls-ink,#f4efe6);}
.mkt-tab.is-active::after{content:'';position:absolute;left:0;right:0;bottom:0;height:2px;border-radius:1px;background:var(--cls-blue,#2b8cee);}
@media (prefers-reduced-motion:reduce){.mkt-tab{transition:none;}}
.mkt-tab-panel{padding-top:1.75rem;}

/* ---------------------------------------------------------------------------
   27. Timeline — a dated, vertical sequence (roadmap, "our story," a process
   longer than the 3-4 steps §16 is built for). One hairline spine with
   --cls-blue dots — deliberately NOT the square-well marker §2/§10/§16
   already share three times over, so a page using both in one view reads as
   two different affordances rather than the same motif recoloured.
   `--mkt-timeline-ring` matches the dot's cut-out ring to whatever surface
   the timeline sits on (defaults to --cls-ground; override inline the same
   way §18's `--mkt-avatar-ring` does when nesting inside a --cls-tray band).
--------------------------------------------------------------------------- */
.mkt-timeline{position:relative;display:flex;flex-direction:column;gap:2rem;padding-left:1.75rem;}
.mkt-timeline::before{content:'';position:absolute;left:5px;top:6px;bottom:6px;width:1px;background:var(--cls-line,#e6e1da);}
.dark .mkt-timeline::before{background:var(--cls-line,#332d24);}
.mkt-timeline-item{position:relative;}
.mkt-timeline-item::before{
  content:'';position:absolute;left:-1.75rem;top:5px;
  width:11px;height:11px;border-radius:var(--cls-pill,999px);
  background:var(--cls-blue,#2b8cee);
  border:2px solid var(--mkt-timeline-ring,var(--cls-ground,#f9f8f5));
  box-shadow:0 0 0 1px var(--cls-blue-deep,#1a6bbd);
}
.mkt-timeline-date{margin:0 0 .3rem;font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-timeline-date{color:var(--cls-ink-3,#b0a795);}
.mkt-timeline-title{margin:0 0 .35rem;font-size:15.5px;line-height:1.3;font-weight:600;letter-spacing:-.005em;color:var(--cls-ink,#1c1a17);}
.dark .mkt-timeline-title{color:var(--cls-ink,#f4efe6);}
.mkt-timeline-item p{margin:0;font-size:13.5px;line-height:1.55;color:var(--cls-ink-2,#443f38);}
.dark .mkt-timeline-item p{color:var(--cls-ink-2,#cec6b8);}

/* ---------------------------------------------------------------------------
   28. Metric row — 3-4 large numbers in one horizontal strip, the plural
   sibling of §5's single .mkt-stat-card. Same honest-copy status as §19/20:
   styled and ready, DELIBERATELY NOT wired into any live page in this pass —
   the site has no verified aggregate usage stats to publish yet (grepped
   every marketing template; the only real numbers live are pricing figures
   and per-plan quotas, not "N students" style claims). Wire real, verified
   numbers in once they exist; the CSS contract below is final.
--------------------------------------------------------------------------- */
.mkt-metric-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,minmax(0,1fr)));gap:1.75rem 1rem;}
.mkt-metric{text-align:center;}
.mkt-metric-figure{font-size:38px;line-height:1;font-weight:700;letter-spacing:-.03em;color:var(--cls-ink,#1c1a17);font-variant-numeric:tabular-nums;}
.dark .mkt-metric-figure{color:var(--cls-ink,#f4efe6);}
.mkt-metric-label{margin-top:.35rem;font-size:12px;font-weight:500;line-height:1.4;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-metric-label{color:var(--cls-ink-3,#b0a795);}

/* ---------------------------------------------------------------------------
   29. Person grid — name/role/avatar cards for a team or tutor-roster
   moment, distinct from §18's avatar group (a compact stacked-circle social-
   proof strip, not a per-person profile). The circular frame reuses §2's
   .mkt-avatar-well recipe verbatim — a circular avatar must never share a
   class with .icon-container's square well, or the square radius wins.
--------------------------------------------------------------------------- */
.mkt-person-grid{display:grid;gap:1.5rem;grid-template-columns:1fr;}
@media (min-width:640px){.mkt-person-grid{grid-template-columns:repeat(2,minmax(0,1fr));}}
@media (min-width:1024px){.mkt-person-grid{grid-template-columns:repeat(4,minmax(0,1fr));}}
.mkt-person{text-align:center;min-width:0;}
.mkt-person-avatar{
  width:72px;height:72px;margin:0 auto .85rem;overflow:hidden;
  display:flex;align-items:center;justify-content:center;
  border-radius:var(--cls-pill,999px);
  background:color-mix(in srgb,var(--cls-blue,#2b8cee) 12%,var(--cls-leaf,#fff));
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95));
  font-size:20px;font-weight:700;color:var(--cls-blue-ink,#14599f);
}
.dark .mkt-person-avatar{background:color-mix(in srgb,var(--cls-blue,#2b8cee) 16%,var(--cls-leaf,#2d2820));color:var(--cls-blue-ink,#7cbbf7);}
.mkt-person-avatar img{width:100%;height:100%;object-fit:cover;display:block;}
.mkt-person-name{margin:0 0 .15rem;font-size:14px;font-weight:600;letter-spacing:-.005em;color:var(--cls-ink,#1c1a17);overflow-wrap:anywhere;}
.dark .mkt-person-name{color:var(--cls-ink,#f4efe6);}
.mkt-person-role{margin:0;font-size:12px;font-weight:500;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-person-role{color:var(--cls-ink-3,#b0a795);}

/* ---------------------------------------------------------------------------
   30. Empty state — a real, currently-missing affordance: help-and-faq.html's
   search hides every non-matching category with no fallback message when a
   term matches nothing (verified against the live search handler, not a
   hypothetical gap). Same square-well glyph recipe §2/§10/§16 already share,
   scaled for an inline empty moment rather than a full status page.
--------------------------------------------------------------------------- */
.mkt-empty{text-align:center;padding:3rem 1.5rem;}
.mkt-empty-icon{
  width:48px;height:48px;margin:0 auto 1rem;border-radius:var(--cls-r-sm,9px);
  display:flex;align-items:center;justify-content:center;
  background:var(--cls-leaf,#fff);
  border:1px solid var(--cls-line-2,#d6d0c6);
  box-shadow:var(--cls-lit,inset 0 1px 0 rgba(255,255,255,.95));
  color:var(--cls-ink-3,#5b554c);
}
.dark .mkt-empty-icon{background:var(--cls-leaf,#2d2820);border-color:var(--cls-line-2,#4a4236);color:var(--cls-ink-3,#b0a795);}
.mkt-empty-title{margin:0 0 .35rem;font-size:14.5px;font-weight:600;letter-spacing:-.005em;color:var(--cls-ink,#1c1a17);}
.dark .mkt-empty-title{color:var(--cls-ink,#f4efe6);}
.mkt-empty p{margin:0;font-size:13px;line-height:1.5;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-empty p{color:var(--cls-ink-3,#b0a795);}

/* ---------------------------------------------------------------------------
   31. Breadcrumb — a wayfinding trail for a page nested more than one level
   deep. `aria-current="page"` marks the final, non-linked crumb (styled, not
   just semantic — bold ink instead of the muted trail colour).
--------------------------------------------------------------------------- */
.mkt-breadcrumb{display:flex;flex-wrap:wrap;align-items:center;gap:.4rem;list-style:none;margin:0;padding:0;font-size:12.5px;}
.mkt-breadcrumb li{display:flex;align-items:center;gap:.4rem;}
.mkt-breadcrumb a{color:var(--cls-ink-3,#5b554c);text-decoration:none;transition:color var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));}
.dark .mkt-breadcrumb a{color:var(--cls-ink-3,#b0a795);}
.mkt-breadcrumb a:hover{color:var(--cls-ink,#1c1a17);}
.dark .mkt-breadcrumb a:hover{color:var(--cls-ink,#f4efe6);}
.mkt-breadcrumb a:focus-visible{outline:2px solid var(--cls-blue-deep,#1a6bbd);outline-offset:2px;border-radius:var(--cls-r-xs,7px);transition:none;}
.mkt-breadcrumb [aria-current="page"]{color:var(--cls-ink,#1c1a17);font-weight:600;}
.dark .mkt-breadcrumb [aria-current="page"]{color:var(--cls-ink,#f4efe6);}
.mkt-breadcrumb-sep{color:var(--cls-line-2,#d6d0c6);}
.dark .mkt-breadcrumb-sep{color:var(--cls-line-2,#4a4236);}
@media (prefers-reduced-motion:reduce){.mkt-breadcrumb a{transition:none;}}

/* ---------------------------------------------------------------------------
   32. Accordion — a general-purpose single-item disclosure, distinct from
   §7's .faq-item (that one is coupled to help-and-faq.html's own search/
   category JS specifically). This is the reusable primitive for any other
   expand/collapse content — a plan's fine print, a policy detail, a
   feature's "how it works." JS contract: toggle `aria-expanded` on the
   trigger and `hidden` on the panel; the chevron rotates off
   `aria-expanded` alone, no extra JS-driven class needed.
--------------------------------------------------------------------------- */
.mkt-accordion{border-radius:var(--cls-r,14px);border:1px solid var(--cls-line,#e6e1da);overflow:hidden;}
.dark .mkt-accordion{border-color:var(--cls-line,#332d24);}
.mkt-accordion-item+.mkt-accordion-item{border-top:1px solid var(--cls-line,#e6e1da);}
.dark .mkt-accordion-item+.mkt-accordion-item{border-top-color:var(--cls-line,#332d24);}
.mkt-accordion-trigger{
  width:100%;min-height:56px;padding:14px 18px;
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  background:var(--cls-panel,#fdfcfa);border:none;cursor:pointer;text-align:left;
  font-family:inherit;font-size:14px;font-weight:600;letter-spacing:-.005em;color:var(--cls-ink,#1c1a17);
  transition:background-color var(--cls-dur-fast,120ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));
}
.dark .mkt-accordion-trigger{background:var(--cls-panel,#2a251d);color:var(--cls-ink,#f4efe6);}
.mkt-accordion-trigger:hover{background:var(--cls-tray,#f4f2ee);}
.dark .mkt-accordion-trigger:hover{background:var(--cls-tray,#211d15);}
.mkt-accordion-trigger:focus-visible{outline:2px solid var(--cls-blue-deep,#1a6bbd);outline-offset:-2px;transition:none;}
@media (prefers-reduced-motion:reduce){.mkt-accordion-trigger{transition:none;}}
.mkt-accordion-icon{flex:none;display:flex;color:var(--cls-ink-3,#5b554c);transition:transform var(--cls-dur,180ms) var(--cls-ease-out,cubic-bezier(0,0,.2,1));}
.dark .mkt-accordion-icon{color:var(--cls-ink-3,#b0a795);}
.mkt-accordion-trigger[aria-expanded="true"] .mkt-accordion-icon{transform:rotate(180deg);}
@media (prefers-reduced-motion:reduce){.mkt-accordion-icon{transition:none;}}
.mkt-accordion-panel{padding:0 18px 16px;font-size:13.5px;line-height:1.6;color:var(--cls-ink-2,#443f38);}
.dark .mkt-accordion-panel{color:var(--cls-ink-2,#cec6b8);}

/* ---------------------------------------------------------------------------
   33. Newsletter signup — a single-field email capture, lighter-weight than
   §9's full .mkt-field contact form. Reuses .mkt-field/.btn-primary
   verbatim for the input+button so nothing new is invented here — this
   section only adds the layout that pairs them inline on wide screens and
   stacks them on narrow ones.
--------------------------------------------------------------------------- */
.mkt-newsletter{display:flex;flex-direction:column;gap:.6rem;max-width:26rem;}
@media (min-width:480px){.mkt-newsletter{flex-direction:row;}}
.mkt-newsletter .mkt-field{flex:1 1 auto;min-width:0;}
.mkt-newsletter-note{margin:.5rem 0 0;font-size:11.5px;line-height:1.5;color:var(--cls-ink-3,#5b554c);}
.dark .mkt-newsletter-note{color:var(--cls-ink-3,#b0a795);}
