/* ==========================================================================
   KeepPulsing — marketing site
   Tokens are the product's design system (see docs/context.md).
   Declared as HSL triplets without the hsl() wrapper so any consumer can add
   alpha: hsl(var(--primary) / 0.12)
   ========================================================================== */

/* --- Fonts ---------------------------------------------------------------- */
/* Figtree, self-hosted from the Google Fonts variable subsets (context.md
   forbids external font requests). Design file loaded these from gstatic. */
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url('../fonts/figtree-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url('../fonts/figtree-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --- Tokens: light (default) ---------------------------------------------- */
:root {
  --background: 40 100% 99%;
  --foreground: 34 11% 12%;
  --card: 40 100% 99%;
  --secondary: 55 28% 92%;
  --muted: 55 28% 92%;
  --muted-foreground: 34 8% 33%;
  --border: 38 24% 87%;

  --primary: 211 100% 50%;
  --primary-foreground: 0 0% 100%;
  --primary-strong: 211 100% 38%;
  --primary-light: 211 100% 62%;
  --primary-ink: 211 100% 50%;
  --primary-fill: 211 100% 50%;
  --brand: 211 100% 50%;
  /* Warm terracotta. Attention, not error: low stock, overdue follow-up, offline. */
  --accent: 30 62% 46%;
  --accent-foreground: 40 100% 99%;
  --navy: 36 27% 22%;

  --neutral-100: 44 35% 94%;
  --neutral-300: 38 24% 87%;
  --neutral-500: 34 8% 55%;
  --neutral-600: 34 8% 45%;
  --neutral-700: 34 8% 33%;
  --destructive: 8 55% 44%;

  /* One-off tints from the design file. */
  --tint-muted-soft: 34 8% 42%;
  --tint-muted-softer: 34 8% 50%;
  --tint-muted-strong: 34 9% 26%;
  --tint-border-soft: 38 24% 90%;
  --tint-border-softer: 38 24% 92%;
  --tint-border-firm: 38 24% 88%;
  --tint-border-85: 40 20% 83%;
  --tint-accent-strong: 30 62% 38%;
  --tint-accent-text: 30 62% 34%;
  --tint-navy-light: 36 27% 26%;
  --tint-success: 90 32% 34%;
  --tint-success-strong: 90 34% 26%;
  --tint-success-bg: 90 30% 36%;

  --gradient-primary: linear-gradient(135deg, hsl(211 100% 50%), hsl(205 100% 58%));
  --gradient-accent: linear-gradient(135deg, hsl(30 62% 46%), hsl(36 62% 52%));
  --gradient-navy: linear-gradient(135deg, hsl(36 27% 22%), hsl(36 27% 26%));
  --shadow-primary: 0 4px 20px -2px hsl(211 100% 50% / 0.3);
  --shadow-accent: 0 4px 20px -2px hsl(30 62% 46% / 0.3);
  --shadow-elegant: 0 10px 30px -10px hsl(36 27% 22% / 0.2);
  --shadow-mock: 0 30px 60px -30px hsl(36 27% 22% / 0.22);

  --radius: 0.75rem;
  --radius-md: calc(var(--radius) - 2px);
  --radius-sm: calc(var(--radius) - 4px);
  --radius-lg: 1.25rem;
  --radius-pill: 9999px;
  --ease-standard: ease-out;
  --duration-fast: 200ms;
  --duration-base: 300ms;

  --font-sans: 'Figtree', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --tracking-tight: -0.01em;
  --tracking-label: 0.04em;

  --gutter: 16px;
  --measure: 1200px;
  --section-pad: clamp(80px, 12vw, 128px);
}

/* --- Tokens: dark --------------------------------------------------------- */
html[data-theme='dark'] {
  color-scheme: dark;

  --background: 34 12% 9%;
  --foreground: 42 30% 94%;
  --card: 34 11% 12%;
  --secondary: 34 10% 16%;
  --muted: 34 10% 15%;
  --muted-foreground: 40 10% 68%;
  --border: 34 9% 22%;

  --primary: 211 95% 62%;
  --primary-foreground: 212 60% 10%;
  --primary-strong: 205 95% 74%;
  --primary-light: 211 90% 50%;
  --primary-ink: 211 95% 62%;
  --primary-fill: 211 95% 62%;
  --accent: 30 62% 56%;
  --accent-foreground: 34 12% 9%;
  --navy: 34 11% 14%;

  --neutral-100: 34 10% 15%;
  --neutral-300: 34 9% 22%;
  --neutral-500: 40 8% 58%;
  --neutral-600: 40 9% 66%;
  --neutral-700: 40 10% 74%;
  --destructive: 8 62% 60%;

  --tint-muted-soft: 40 10% 62%;
  --tint-muted-softer: 40 9% 56%;
  --tint-muted-strong: 42 20% 86%;
  --tint-border-soft: 34 9% 20%;
  --tint-border-softer: 34 9% 18%;
  --tint-border-firm: 34 9% 22%;
  --tint-border-85: 34 9% 27%;
  --tint-accent-strong: 30 62% 60%;
  --tint-accent-text: 30 62% 66%;
  --tint-navy-light: 34 11% 18%;
  --tint-success: 90 30% 58%;
  --tint-success-strong: 90 32% 66%;
  --tint-success-bg: 90 26% 44%;

  --gradient-primary: linear-gradient(135deg, hsl(211 90% 56%), hsl(205 85% 46%));
  --gradient-accent: linear-gradient(135deg, hsl(30 58% 46%), hsl(36 56% 40%));
  --gradient-navy: linear-gradient(135deg, hsl(34 11% 14%), hsl(34 11% 18%));
  --shadow-primary: 0 4px 20px -2px hsl(211 100% 50% / 0.35);
  --shadow-accent: 0 4px 20px -2px hsl(30 62% 46% / 0.3);
  --shadow-elegant: 0 10px 30px -10px hsl(0 0% 0% / 0.6);
  --shadow-mock: 0 30px 60px -30px hsl(0 0% 0% / 0.75);
}

/* --- Tokens: product colours ---------------------------------------------
   Blue is the master brand and General Clinic's colour. Each other vertical
   re-points the primary tokens inside a scope: <body> on its own page, and
   its own card/menu/footer entry elsewhere. Reserved, not yet built:
   Dental violet #7A51EC (ink #542FBC), Eye Care plum #C62F8F (ink #95236B).

   Homeopathy #0FB9A7 is light — 2.5:1 on the cream background. It is for
   fills, dots, bars and the logo tile; text and line icons use --primary-ink
   (#0A7B6F, 5.1:1). A fill that carries text (active tab, badge, chip) uses
   --primary-fill, which for homeopathy is the brand teal itself with white
   text — 2.5:1, below AA, accepted by Awais on 2026-09-24 for the look.
   A deeper #0B8478 (4.6:1) was tried first; it is the fallback. */
.theme-homeopathy {
  --brand: 173.6 85% 39.2%;
  --primary: 173.6 85% 39.2%;
  --primary-ink: 174 85% 26%;
  --primary-fill: 173.6 85% 39.2%;
  --primary-strong: 174 85% 26%;
  --primary-light: 174 70% 50%;
  --primary-foreground: 0 0% 100%;
  --gradient-primary: linear-gradient(135deg, hsl(173.6 85% 39.2%), hsl(170 75% 46%));
  --shadow-primary: 0 4px 20px -2px hsl(173.6 85% 39.2% / 0.3);
}
html[data-theme='dark'] .theme-homeopathy {
  --brand: 174 85% 28%;
  --primary: 173.6 85% 39.2%;
  --primary-ink: 173.6 85% 39.2%;
  --primary-fill: 174 85% 28%;
  --primary-strong: 172 65% 62%;
  --primary-light: 174 85% 32%;
  --primary-foreground: 0 0% 100%;
  --gradient-primary: linear-gradient(135deg, hsl(173.6 85% 39.2%), hsl(170 75% 34%));
  --shadow-primary: 0 4px 20px -2px hsl(173.6 85% 39.2% / 0.35);
}

/* --- Reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 88px;
}

body {
  margin: 0;
  /* isolate + z-index:0 gives the decorative backdrop a stacking context to
     sit behind (z-index:-1) without escaping under the page background. */
  position: relative;
  isolation: isolate;
  z-index: 0;
  background: hsl(var(--background));
  color: hsl(var(--foreground));
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, svg { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }

h1, h2, h3, h4 { margin: 0; font-weight: 600; text-wrap: balance; }
p { margin: 0; text-wrap: pretty; }
ul, ol { margin: 0; padding: 0; list-style: none; }

:focus-visible {
  outline: 2px solid hsl(var(--primary));
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: var(--gutter); top: 8px; z-index: 200;
  transform: translateY(-160%);
  background: hsl(var(--primary-fill)); color: hsl(var(--primary-foreground));
  padding: 10px 18px; border-radius: var(--radius-pill);
  font-size: 14px; font-weight: 500;
  transition: transform var(--duration-fast) var(--ease-standard);
}
.skip-link:focus-visible { transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* --- Decorative page backdrop --------------------------------------------- */
/* Three ECG traces behind the hero, faded out before the fold so nothing
   competes with the mockup. Decorative only: no layout role, no content. */
.page-glow {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 760px;
  overflow: hidden;
  z-index: -1;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgb(0 0 0 / 0.75) 42%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, rgb(0 0 0 / 0.75) 42%, transparent 100%);
}
.page-glow-lines { display: block; }
/* Soft primary wash centred over the headline. */
.page-glow-wash {
  position: absolute;
  top: -140px;
  left: 50%;
  width: min(1100px, 120%);
  height: 620px;
  transform: translateX(-50%);
  pointer-events: none;
  background: radial-gradient(60% 55% at 50% 30%, hsl(var(--primary) / 0.1), transparent 70%);
}

/* --- Layout primitives ---------------------------------------------------- */
.container { width: 100%; max-width: var(--measure); margin-inline: auto; }
.container--narrow { max-width: 900px; }

.section { padding: var(--section-pad) var(--gutter) 0; }
.section--first { padding-top: 56px; }
.section--last { padding-bottom: var(--section-pad); }

.section-head {
  max-width: 700px;
  margin-inline: auto;
  text-align: center;
}
/* The design centres every section head. --left is for the few places where a
   head sits directly above a two-column split and has to align with it. */
.section-head--left { margin-inline: 0; text-align: left; }
.section-head--center { margin-inline: auto; text-align: center; }

.eyebrow {
  display: block;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
  margin-bottom: 18px;
}

.h2 {
  font-size: clamp(32px, 4vw, 44px);
  line-height: 1.24;
  letter-spacing: -0.025em;
}

.h3 {
  font-size: 17px;
  line-height: 1.4;
  letter-spacing: var(--tracking-tight);
}

.lede {
  margin-top: 20px;
  max-width: 58ch;
  font-size: 17px;
  line-height: 1.75;
  color: hsl(var(--muted-foreground));
}
.section-head .lede { margin-inline: auto; }
.section-head--left .lede { margin-inline: 0; }

.note {
  font-size: 14px;
  line-height: 1.6;
  color: hsl(var(--muted-foreground));
}

/* --- Reveal on scroll ----------------------------------------------------- */
/* No initial opacity in CSS: without JS everything simply stays visible. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 600ms var(--ease-standard), transform 600ms var(--ease-standard);
}
.js [data-reveal].is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] { opacity: 1; transform: none; }
}

/* --- Buttons -------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 50px;
  padding: 0 28px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  font-size: 15px;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard),
              box-shadow var(--duration-fast) var(--ease-standard),
              transform var(--duration-fast) var(--ease-standard);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

/* Near-black pill, not blue. In the design, blue is reserved for state and
   accents inside the product mockups; the page's own buttons are ink on paper,
   which is what keeps the blue meaningful when it does appear. */
.btn--primary {
  background: hsl(var(--foreground));
  color: hsl(var(--background));
}
.btn--primary:hover { background: hsl(var(--tint-muted-strong)); }

.btn--outline {
  background: transparent;
  color: hsl(var(--foreground));
  border-color: hsl(var(--tint-border-85));
}
.btn--outline:hover { border-color: hsl(var(--foreground)); }

.btn--ghost {
  background: hsl(var(--secondary));
  color: hsl(var(--foreground));
}
.btn--ghost:hover { background: hsl(var(--neutral-300)); }

.btn--sm { height: 40px; padding: 0 20px; font-size: 14px; }

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 32px;
}
.cta-row--center { justify-content: center; }

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13.5px;
  font-weight: 500;
  color: hsl(var(--primary-ink));
}
.link-arrow:hover { gap: 10px; }
.link-arrow span { transition: transform var(--duration-fast) var(--ease-standard); }

/* --- Cards & badges ------------------------------------------------------- */
.card {
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-lg);
  background: hsl(var(--card));
  padding: 28px;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 10px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.6;
  white-space: nowrap;
}
/* Solid for the one you can buy; outlined for the ones you cannot. */
.badge--available {
  font-size: 12px;
  background: hsl(var(--primary-fill));
  color: hsl(var(--primary-foreground));
}
.badge--soon {
  background: transparent;
  color: hsl(var(--tint-muted-soft));
  border-color: hsl(var(--tint-border-firm));
}

/* --- Header --------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: hsl(var(--background) / 0.86);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid hsl(var(--border));
}
.header-inner {
  max-width: var(--measure);
  margin-inline: auto;
  padding: 0 var(--gutter);
  height: 64px;
  display: flex;
  align-items: center;
  gap: 32px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.02em;
  flex: 0 0 auto;
  color: hsl(var(--foreground));
}
/* Fixed brand blue, not --primary: the mark keeps its colour in dark mode
   the way a real logo asset would. */
.brand-mark { width: 26px; height: 26px; flex: 0 0 auto; }
.brand b { color: hsl(var(--brand)); font-weight: 600; }
.brand-mark rect { fill: hsl(var(--brand)); }

.nav {
  display: flex;
  align-items: center;
  gap: 26px;
  flex: 1 1 auto;
  min-width: 0;
}
.nav a {
  font-size: 14px;
  color: hsl(var(--muted-foreground));
  transition: color var(--duration-fast) var(--ease-standard);
}
.nav a:hover, .nav a[aria-current='page'] { color: hsl(var(--foreground)); }

/* --- Solutions menu ------------------------------------------------------- */
/* CSS only. The trigger is a real link to the Solutions section, so with a
   touch device, a keyboard, or JS blocked the nav still goes somewhere useful;
   the panel is an enhancement for pointer devices. */
.nav-group { position: relative; display: flex; align-items: center; }
.nav-group-trigger { display: inline-flex; align-items: center; gap: 5px; }
.nav-caret {
  width: 13px; height: 13px;
  transition: transform var(--duration-fast) var(--ease-standard);
}
.nav-menu {
  position: absolute;
  top: 100%;
  left: -12px;
  z-index: 40;
  width: 292px;
  margin-top: 11px;
  padding: 7px;
  border: 1px solid hsl(var(--border));
  border-radius: 16px;
  background: hsl(var(--card));
  box-shadow: var(--shadow-elegant);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity var(--duration-fast) var(--ease-standard),
              transform var(--duration-fast) var(--ease-standard),
              visibility var(--duration-fast);
}
/* Bridges the 11px gap under the trigger; without it the menu closes as the
   pointer crosses from the link to the panel. */
.nav-menu::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: -13px;
  height: 13px;
}
.nav-menu-item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 10px;
  border-radius: var(--radius-md);
}
.nav-menu-item:hover { background: hsl(var(--secondary)); }
.nav-menu-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; flex: 0 0 auto;
  border-radius: var(--radius-pill);
  background: hsl(var(--primary) / 0.1);
  color: hsl(var(--primary-ink));
}
.nav-menu-icon svg { width: 17px; height: 17px; }
.nav-menu-text b {
  display: block;
  font-size: 14px; font-weight: 600;
  color: hsl(var(--foreground));
  letter-spacing: var(--tracking-tight);
}
.nav-menu-text span { font-size: 12px; color: hsl(var(--muted-foreground)); }
/* Not yet shipped, so not a link and not dressed as one. */
.nav-menu-item.is-soon { cursor: default; }
.nav-menu-item.is-soon .nav-menu-icon {
  background: hsl(var(--secondary));
  color: hsl(var(--tint-muted-soft));
}
.nav-menu-item.is-soon .nav-menu-text b { color: hsl(var(--muted-foreground)); }

/* Hover only where hovering exists; a touch tap on the trigger should follow
   the link, not open a panel that then needs dismissing. Keyboard users get
   the same panel through :focus-within. */
@media (hover: hover) {
  .nav-group:hover .nav-menu {
    opacity: 1; visibility: visible; transform: none;
  }
  .nav-group:hover .nav-caret { transform: rotate(180deg); }
}
.nav-group:focus-within .nav-menu {
  opacity: 1; visibility: visible; transform: none;
}
.nav-group:focus-within .nav-caret { transform: rotate(180deg); }

.header-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
  margin-left: auto;
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: var(--radius-pill);
  border: 1px solid hsl(var(--border));
  background: transparent;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-standard);
}
.icon-btn:hover { background: hsl(var(--secondary)); }
.icon-btn svg { width: 18px; height: 18px; }

.theme-toggle .icon-moon { display: none; }
html[data-theme='dark'] .theme-toggle .icon-sun { display: none; }
html[data-theme='dark'] .theme-toggle .icon-moon { display: block; }

.nav-toggle { display: none; }

/* Mobile nav — the one place a media query earns its keep. */
@media (max-width: 900px) {
  .nav,
  .header-actions .btn,
  .header-actions .header-signin { display: none; }
  .nav-toggle { display: inline-flex; }

  .mobile-nav {
    display: none;
    border-top: 1px solid hsl(var(--border));
    background: hsl(var(--background));
    padding: 12px var(--gutter) 22px;
  }
  .mobile-nav.is-open { display: block; }
  .mobile-nav a {
    display: block;
    padding: 12px 2px;
    font-size: 16px;
    border-bottom: 1px solid hsl(var(--tint-border-soft));
  }
  .mobile-nav .mobile-sub {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 11px 2px 11px 16px;
    font-size: 15px;
    border-bottom: 1px solid hsl(var(--tint-border-soft));
  }
  .mobile-nav .mobile-sub em {
    font-style: normal;
    font-size: 12px;
    color: hsl(var(--muted-foreground));
  }
  .mobile-nav .mobile-sub.is-soon { color: hsl(var(--muted-foreground)); }
  .mobile-nav .btn { width: 100%; margin-top: 16px; }
}
@media (min-width: 901px) {
  .mobile-nav { display: none !important; }
}

/* --- Hero ----------------------------------------------------------------- */
.hero { padding: 104px var(--gutter) 0; text-align: center; }
.hero-inner { max-width: var(--measure); margin-inline: auto; }
/* The hero eyebrow is a pill, not the plain uppercase label the section heads
   use — it is the one place on the page that announces what this thing is. */
.hero .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px 5px 8px;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-pill);
  background: hsl(var(--muted));
  margin-bottom: 26px;
  font-size: 12.5px;
  font-weight: 400;
  letter-spacing: 0.01em;
  text-transform: none;
  color: hsl(var(--muted-foreground));
}
.hero .eyebrow::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: var(--radius-pill);
  background: hsl(var(--primary));
}
.hero h1 {
  margin-inline: auto;
  max-width: 17ch;
  font-size: clamp(40px, 6vw, 68px);
  line-height: 1.06;
  letter-spacing: -0.035em;
}
.hero .lede {
  margin-top: 26px;
  margin-inline: auto;
  max-width: 60ch;
  font-size: 19px;
  line-height: 1.7;
}
.hero-note { margin-top: 16px; font-size: 13px; color: hsl(var(--tint-muted-soft)); }

/* --- Trust strip ---------------------------------------------------------- */
/* Design treatment: two hairline rules, no card boxes, no fills. Our copy
   change (3 items with a description rather than 4 bare labels) keeps that
   treatment — the items just carry two lines instead of one. */
.trust-strip {
  display: grid;
  /* 3 items: explicit counts, never auto-fit, so there is no 2+1 orphan row. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px 28px;
  margin-top: 56px;
  padding: 22px 0;
  border-top: 1px solid hsl(var(--border));
  border-bottom: 1px solid hsl(var(--border));
  text-align: left;
}
.trust-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-width: 0;
}
.trust-item svg {
  width: 17px;
  height: 17px;
  color: hsl(var(--primary-ink));
  flex: 0 0 auto;
  margin-top: 3px;
}
.trust-text { min-width: 0; }
.trust-item b {
  display: block;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  color: hsl(var(--tint-muted-strong));
}
.trust-item .trust-text span {
  display: block;
  margin-top: 3px;
  font-size: 13px;
  line-height: 1.55;
  color: hsl(var(--muted-foreground));
}

@media (max-width: 680px) {
  .trust-strip { grid-template-columns: minmax(0, 1fr); gap: 16px; }
}

/* --- App mockup (shared chrome) ------------------------------------------- */
.mock {
  border: 1px solid hsl(var(--border));
  border-radius: 22px;
  background: hsl(var(--card));
  box-shadow: var(--shadow-mock);
  overflow: hidden;
}
.mock--hero { margin-top: 64px; text-align: left; }

/* Labels the mockup in the same voice as a section eyebrow ("THE PLATFORM"),
   not as a heading — it introduces the screenshot without competing with the
   h1 above it. Values kept in step with .eyebrow. */
.hero-figure { margin: 0; }
.hero-figure-label {
  margin-top: clamp(56px, 7vw, 80px);
  margin-bottom: 18px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
}
.hero-figure .mock--hero { margin-top: 0; }

/* --- Phone alongside the desktop frame ------------------------------------ */
/* The phone hangs off the lower-left and sits exactly over the 200px sidebar,
   so it covers a whole column rather than slicing nav labels in half. The
   stack's margin-bottom pays for the overhang, otherwise the phone lands on
   the trust strip. */
.mock-stack { position: relative; margin-bottom: 124px; }
.mock-phone {
  position: absolute;
  left: -32px;
  /* -88 rather than flush so the top edge clears the clinic name and the
     active Dashboard item: the two things in that sidebar carrying identity.
     The stack's 128px pays for the overhang and still leaves room before the
     trust strip. */
  bottom: -78px;
  /* 244 rather than 232: the right edge clears the sidebar's border by ~12px
     instead of landing exactly on it, which read as a seam rather than as one
     frame in front of another. The stack's margin-bottom pays for the overhang
     and keeps ~46px clear before the trust strip. */
  width: 244px;
  aspect-ratio: 390 / 845;
  padding: 8px;
  border-radius: 32px;
  background: hsl(var(--navy));
  /* In dark mode the bezel is nearly the page colour; the border is what
     separates the phone from the background. */
  border: 1px solid hsl(var(--border));
  box-shadow: 0 30px 60px -26px hsl(36 27% 22% / 0.5);
}
.phone-screen {
  height: 100%;
  border-radius: 25px;
  background: hsl(var(--card));
  overflow: hidden;
  display: flex;
  flex-direction: column;
  text-align: left;
}
.phone-topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px;
  border-bottom: 1px solid hsl(var(--border));
  font-size: 12.5px; font-weight: 600; letter-spacing: -0.01em;
  flex: 0 0 auto;
}
.phone-topbar svg { color: hsl(var(--muted-foreground)); }

/* The screen scrolls in the real app, so the last panel running under the tab
   bar is correct rather than a clipping accident. */
.phone-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  /* No bottom padding: the last panel should meet the tab bar mid-row, the way
     a scrolled screen does, rather than stopping short of it. */
  padding: 10px 10px 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.phone-greet b { display: block; font-size: 12.5px; font-weight: 600; letter-spacing: -0.015em; }
.phone-greet span { font-size: 9.5px; color: hsl(var(--primary-ink)); }
.phone-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px; }
.phone-stat {
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-sm);
  padding: 6px 8px;
  min-width: 0;
}
.phone-stat .k {
  display: block; font-size: 7.5px; letter-spacing: var(--tracking-label);
  text-transform: uppercase; color: hsl(var(--muted-foreground));
}
.phone-stat .v {
  display: block; margin-top: 2px;
  font-size: 16px; font-weight: 600; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.phone-stat .v small { font-size: 9px; font-weight: 400; color: hsl(var(--muted-foreground)); }
.phone-stat .m { display: block; font-size: 8px; color: hsl(var(--muted-foreground)); }
.phone-stat--attn {
  background: hsl(var(--accent) / 0.1);
  border-color: hsl(var(--accent) / 0.3);
}
.phone-stat--attn .v { color: hsl(var(--tint-accent-text)); }

.phone-panel {
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-sm);
  overflow: hidden;
  flex: 0 0 auto;
}
.phone-panel-head {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  padding: 7px 9px;
  background: hsl(var(--neutral-100));
  border-bottom: 1px solid hsl(var(--border));
  font-size: 10px; font-weight: 600;
}
.phone-panel-head .more { font-size: 8.5px; font-weight: 500; color: hsl(var(--primary-ink)); }
.phone-badge {
  min-width: 16px; padding: 1px 5px; border-radius: var(--radius-pill);
  background: hsl(var(--accent) / 0.14); color: hsl(var(--tint-accent-text));
  font-size: 8.5px; font-weight: 600; text-align: center;
}
.phone-appt, .phone-fu {
  display: flex; align-items: center; gap: 7px;
  padding: 8px 9px;
}
.phone-fu + .phone-fu { border-top: 1px solid hsl(var(--tint-border-soft)); }
.phone-appt .t {
  font-size: 9px; font-variant-numeric: tabular-nums;
  color: hsl(var(--muted-foreground)); flex: 0 0 auto;
}
.avatar--xs { width: 18px; height: 18px; font-size: 7.5px; }
.phone-appt .who, .phone-fu .who { flex: 1 1 auto; min-width: 0; }
.phone-appt .who b, .phone-fu .who b {
  display: block; font-size: 10px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.phone-appt .who span, .phone-fu .who span {
  display: block; font-size: 8.5px; color: hsl(var(--muted-foreground));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.phone-chip {
  padding: 3px 8px; border-radius: var(--radius-pill);
  background: hsl(var(--primary-fill)); color: hsl(var(--primary-foreground));
  font-size: 8.5px; font-weight: 600; flex: 0 0 auto;
}
.phone-fu .late {
  font-size: 8.5px; font-weight: 600; flex: 0 0 auto;
  color: hsl(var(--tint-accent-text));
}
.phone-fu .late--due { color: hsl(var(--muted-foreground)); }
.phone-panel-foot {
  padding: 6px 9px;
  border-top: 1px solid hsl(var(--tint-border-soft));
  font-size: 8px; color: hsl(var(--muted-foreground));
}

.phone-tabs {
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  border-top: 1px solid hsl(var(--border));
  background: hsl(var(--card));
  flex: 0 0 auto;
}
.phone-tabs span {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 7px 0 9px;
  font-size: 7.5px;
  color: hsl(var(--muted-foreground));
}
.phone-tabs .is-active { color: hsl(var(--primary-ink)); font-weight: 600; }

/* 760-900px: the desktop frame still has its sidebar and reads correctly, but
   it is now narrow enough that the phone would cover the screen it is meant to
   sit beside. The frame stands alone. */
@media (max-width: 900px) {
  .mock-phone { display: none; }
  .mock-stack { margin-bottom: 0; }
}

/* Below 760px the desktop frame loses its sidebar (see the narrow-screen block
   at the end of this file) and becomes browser chrome wrapped around a squeezed
   dashboard - it stops reading as our product. So the two swap: on a phone, the
   phone mockup is the honest one, shown on its own at something close to the
   size it would be on the device.

   zoom rather than transform: scale() because every dimension inside the phone
   is a px value tuned to a 244px frame, and zoom scales the layout box with the
   contents, so the mockup centres itself and reserves its own height. A
   transform would need a hand-computed margin to pay for the growth. */
@media (max-width: 760px) {
  .mock-stack > .mock--hero { display: none; }
  .mock-phone {
    display: block;
    position: static;
    margin-inline: auto;
    zoom: 1.2;
  }
}

.mock-chrome {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 42px;
  padding: 0 16px;
  border-bottom: 1px solid hsl(var(--border));
  background: hsl(var(--neutral-100));
}
.mock-dots { display: flex; gap: 6px; }
.mock-dots i {
  width: 10px; height: 10px; border-radius: 50%;
  background: hsl(var(--neutral-300));
}
.mock-url {
  flex: 1 1 auto;
  text-align: center;
  font-size: 12px;
  color: hsl(var(--muted-foreground));
  font-variant-numeric: tabular-nums;
}

.mock-body { display: grid; grid-template-columns: minmax(0, 200px) minmax(0, 1fr); }
.mock-sidebar {
  border-right: 1px solid hsl(var(--border));
  padding: 18px 14px;
  background: hsl(var(--neutral-100));
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.mock-clinic {
  padding: 10px 10px 14px;
  border-bottom: 1px solid hsl(var(--border));
  margin-bottom: 10px;
}
.mock-clinic b { display: block; font-size: 13px; font-weight: 600; }
.mock-clinic span { font-size: 11px; color: hsl(var(--muted-foreground)); }
.mock-navitem {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; border-radius: var(--radius-sm);
  font-size: 13px; color: hsl(var(--muted-foreground));
}
.mock-navitem.is-active {
  background: hsl(var(--primary) / 0.1);
  color: hsl(var(--primary-ink));
  font-weight: 500;
}
.mock-sync {
  margin-top: auto; padding: 10px;
  font-size: 11px; color: hsl(var(--tint-success));
  display: flex; align-items: center; gap: 6px;
}
.dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: hsl(var(--tint-success)); flex: 0 0 auto;
}
.dot--accent { background: hsl(var(--accent)); }
.dot--muted { background: hsl(var(--neutral-500)); }

.mock-main { padding: 20px; min-width: 0; }
.mock-topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 20px;
}
.mock-crumb { font-size: 12px; color: hsl(var(--muted-foreground)); }
.mock-greeting { font-size: 19px; font-weight: 600; letter-spacing: -0.02em; }
.mock-sub { font-size: 12px; color: hsl(var(--muted-foreground)); margin-top: 2px; }

.avatar {
  width: 30px; height: 30px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--gradient-primary);
  color: hsl(var(--primary-foreground));
  font-size: 11px; font-weight: 600; flex: 0 0 auto;
}
.avatar--sm { width: 26px; height: 26px; font-size: 10px; }

.mock-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
  gap: 10px;
  margin-bottom: 18px;
}
.mock-stat {
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-md);
  padding: 12px;
  background: hsl(var(--card));
  min-width: 0;
}
.mock-stat .k {
  font-size: 10.5px; letter-spacing: var(--tracking-label);
  text-transform: uppercase; color: hsl(var(--muted-foreground));
}
.mock-stat .v {
  font-size: 22px; font-weight: 600; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums; margin-top: 4px;
}
.mock-stat .v small { font-size: 12px; font-weight: 400; color: hsl(var(--muted-foreground)); }
.mock-stat .m { font-size: 11px; color: hsl(var(--muted-foreground)); margin-top: 2px; }
.mock-stat--accent .v { color: hsl(var(--tint-accent-text)); }

.mock-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 14px;
}
.mock-panel {
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-md);
  overflow: hidden;
  min-width: 0;
}
.mock-panel-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; padding: 10px 12px;
  border-bottom: 1px solid hsl(var(--border));
  background: hsl(var(--neutral-100));
  font-size: 12px; font-weight: 600;
}
.mock-panel-head a, .mock-panel-head span.more {
  font-size: 11px; font-weight: 500; color: hsl(var(--primary-ink));
}
.mock-row {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px;
  border-bottom: 1px solid hsl(var(--tint-border-soft));
  font-size: 12px;
  min-width: 0;
}
.mock-row:last-child { border-bottom: 0; }
.mock-row .t {
  font-variant-numeric: tabular-nums;
  color: hsl(var(--muted-foreground));
  flex: 0 0 auto;
}
.mock-row .main { flex: 1 1 auto; min-width: 0; }
.mock-row .main b { display: block; font-weight: 500; font-size: 12.5px; }
.mock-row .main span { font-size: 11px; color: hsl(var(--muted-foreground)); }
.mock-tag {
  font-size: 10.5px; padding: 3px 8px; border-radius: var(--radius-pill);
  background: hsl(var(--secondary)); color: hsl(var(--muted-foreground));
  white-space: nowrap; flex: 0 0 auto;
}
.mock-tag--ok { background: hsl(var(--tint-success-bg) / 0.12); color: hsl(var(--tint-success-strong)); }
.mock-tag--live { background: hsl(var(--primary) / 0.12); color: hsl(var(--primary-ink)); }
.mock-tag--warn { background: hsl(var(--accent) / 0.14); color: hsl(var(--tint-accent-text)); }

/* --- Platform / verticals ------------------------------------------------- */
/* One bordered container with 1px dividers showing the background through the
   gaps — not four separate cards. 4 items, so: 4 / 2 / 1 columns, never 3
   (which would leave 3+1). */
.vertical-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  margin-top: 52px;
  border: 1px solid hsl(var(--border));
  border-radius: 18px;
  background: hsl(var(--border));
  overflow: hidden;
  text-align: left;
}
.vertical-card {
  background: hsl(var(--card));
  padding: 26px 24px 28px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
  transition: background-color var(--duration-fast) var(--ease-standard);
}
/* Same tint as .faq-card and .offline-card, but mixed rather than layered.
   A translucent hsl(... / 0.03) would REPLACE the card's opaque background and
   let .vertical-grid's border-coloured background show through, washing the
   card grey instead of blue. color-mix gives the identical colour, opaque.
   No border shift here: these cards have no border of their own — the grid's
   1px gap over that background is what draws the separators. */
@media (hover: hover) {
  .vertical-card--live:hover {
    background: color-mix(in srgb, hsl(var(--primary)) 3%, hsl(var(--card)));
  }
}
.vertical-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.vertical-icon { display: inline-flex; color: hsl(var(--tint-muted-softer)); }
.vertical-icon svg { width: 22px; height: 22px; }
.vertical-card--live .vertical-icon { color: hsl(var(--primary-ink)); }
/* The live vertical is stated at full strength; the rest are dimmed a step so
   the grid reads as one product and three previews. */
.vertical-card h3 {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: hsl(var(--tint-muted-strong));
}
.vertical-card--live h3 { color: hsl(var(--foreground)); }
.vertical-card p {
  font-size: 14px;
  line-height: 1.55;
  color: hsl(var(--tint-muted-soft));
}
.vertical-card--live p { font-size: 16px; line-height: 1.7; color: hsl(var(--muted-foreground)); }
.vertical-card .link-arrow { margin-top: auto; padding-top: 10px; font-size: 13.5px; }

@media (max-width: 1000px) {
  .vertical-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .vertical-grid { grid-template-columns: minmax(0, 1fr); }
}

/* --- Problem -------------------------------------------------------------- */
.problem-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  max-width: 980px;
  margin: 56px auto 0;
  gap: 44px 56px;
  text-align: left;
}
/* Hairline rule, not a coloured bar: the design keeps these as quiet columns. */
.problem-card {
  border-top: 1px solid hsl(var(--border));
  padding-top: 22px;
}
.problem-num {
  display: block;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: normal;
  color: hsl(var(--tint-muted-softer));
  font-variant-numeric: tabular-nums;
  margin-bottom: 14px;
}
.problem-card h3 { font-size: 22px; letter-spacing: -0.02em; }
.problem-card p { margin-top: 10px; font-size: 16px; line-height: 1.7; color: hsl(var(--muted-foreground)); }

/* --- Modules -------------------------------------------------------------- */
.module-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 18px;
  margin-top: 44px;
}
.module-card {
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-lg);
  background: hsl(var(--card));
  padding: 22px;
}
.module-card .icon {
  width: 38px; height: 38px; border-radius: var(--radius-md);
  display: inline-flex; align-items: center; justify-content: center;
  background: hsl(var(--primary) / 0.1); color: hsl(var(--primary-ink));
  margin-bottom: 14px;
}
.module-card .icon svg { width: 19px; height: 19px; }
.module-card h3 { font-size: 16.5px; letter-spacing: -0.02em; }
.module-card p { margin-top: 6px; font-size: 14px; line-height: 1.6; color: hsl(var(--muted-foreground)); }

/* Homepage modules: heading held in a narrow left column, the six modules
   stacked 2x3 on the right. The heading stays put while the list reads down,
   which keeps the section from becoming another full-width row of boxes.
   (/homeopathy still uses the boxed .module-grid above.) */
.module-split {
  display: grid;
  /* Heading column floored at 400px: below that "Nothing you don't." cannot
     sit on one line at 44px, and text-wrap:balance breaks the heading into
     four lines with "needs. Nothing" straddling both sentences. The 430px
     floor leaves a margin over that measured minimum, since the exact width
     depends on the rendered font. */
  grid-template-columns: clamp(430px, 38%, 470px) minmax(0, 1fr);
  gap: clamp(40px, 6vw, 84px);
  align-items: start;
}
.module-intro .lede { margin-top: 18px; font-size: 16px; line-height: 1.7; }

.module-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 34px 40px;
}
.module-item { display: flex; align-items: flex-start; gap: 14px; min-width: 0; }
.module-icon {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: hsl(var(--primary) / 0.1);
  color: hsl(var(--primary-ink));
}
.module-icon svg { width: 18px; height: 18px; }
.module-body { min-width: 0; }
.module-item h3 { font-size: 16px; letter-spacing: var(--tracking-tight); }
.module-item p {
  margin-top: 4px;
  font-size: 14.5px;
  line-height: 1.6;
  color: hsl(var(--muted-foreground));
}

/* Stack while the heading column still clears its 400px floor, rather than
   letting it be squeezed below the width its longest line needs. */
@media (max-width: 1100px) {
  .module-split { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .module-intro .lede { max-width: 60ch; }
}
@media (max-width: 600px) {
  .module-list { grid-template-columns: minmax(0, 1fr); gap: 28px; }
}


/* --- Workflow ------------------------------------------------------------- */
.workflow { margin-top: 48px; }

/* Pills, not boxes: the design keeps the rail light so the panel below is the
   thing you look at. Wrapping flex row rather than a grid, so seven steps
   reflow onto two lines instead of each getting a wide equal track. */
.step-rail {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 24px;
}
.step-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-pill);
  background: hsl(var(--card));
  color: hsl(var(--tint-muted-strong));
  font-size: 13.5px;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-standard),
    border-color var(--duration-fast) var(--ease-standard),
    color var(--duration-fast) var(--ease-standard);
}
.step-btn .n {
  font-size: 11px;
  opacity: 0.72;
  color: inherit;
  font-variant-numeric: tabular-nums;
}
.step-btn .l { font-size: inherit; }
.step-btn:hover { border-color: hsl(var(--primary) / 0.5); }
.step-btn[aria-selected='true'] {
  background: hsl(var(--primary-fill));
  border-color: hsl(var(--primary-fill));
  color: #fff;
}

/* The panel is a warm tray holding a white card — that contrast is what makes
   the step read as a screen rather than more page. */
.step-panels {
  border: 1px solid hsl(var(--border));
  border-radius: 16px;
  background: hsl(var(--neutral-100));
  padding: clamp(18px, 3vw, 28px);
}
/* Any class that sets display beats the UA's [hidden] rule, so restore it once
   for everything rather than per component — this is what was showing both
   clinics' stat rows at the same time. */
[hidden] { display: none !important; }

.step-panel[hidden] { display: none; }
.step-panel {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 32px;
  align-items: center;
  text-align: left;
}
.step-copy .meta {
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
  font-weight: 400;
}
.step-copy h3 { margin-top: 10px; font-size: 26px; font-weight: 650; letter-spacing: -0.025em; }
.step-copy p { margin-top: 12px; font-size: 15.5px; line-height: 1.6; color: hsl(var(--muted-foreground)); }
.step-writes {
  margin-top: 20px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: hsl(var(--muted-foreground));
}
.step-writes::before {
  content: '';
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  border-radius: var(--radius-pill);
  background: hsl(var(--primary));
}
.step-writes b { color: hsl(var(--muted-foreground)); font-weight: 400; }

/* Step screen card */
.step-screen {
  border: 1px solid hsl(var(--border));
  border-radius: 12px;
  background: hsl(var(--card));
  overflow: hidden;
  min-height: 230px;
}
.step-screen-head {
  padding: 12px 14px;
  border-bottom: 1px solid hsl(var(--border));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.step-screen-head b { font-size: 13px; font-weight: 600; }
.step-screen-head span { font-size: 11px; color: hsl(var(--muted-foreground)); }
.step-screen .kv-list {
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  border-top: 0;
}
.step-screen .kv {
  padding: 9px 11px;
  border: 1px solid hsl(var(--tint-border-soft));
  border-radius: 9px;
  align-items: flex-start;
}
.step-screen .kv .k {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  padding-top: 2px;
}
.step-screen .kv .v { font-size: 13px; font-weight: 400; }

.kv-list { border-top: 1px solid hsl(var(--tint-border-soft)); }
.kv {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; padding: 10px 0;
  border-bottom: 1px solid hsl(var(--tint-border-soft));
  font-size: 13.5px;
}
.step-screen .kv { border-bottom: 1px solid hsl(var(--tint-border-soft)); }
.kv .k { color: hsl(var(--muted-foreground)); flex: 0 0 auto; }
.kv .v { text-align: right; font-weight: 500; }

/* --- Offline -------------------------------------------------------------- */
.offline-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
  margin-top: 44px;
}
.offline-card {
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-lg);
  background: hsl(var(--card));
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  transition: background-color var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard);
}
@media (hover: hover) {
  .offline-card:hover {
    background: hsl(var(--primary) / 0.03);
    border-color: hsl(var(--tint-border-85));
  }
}
.offline-state {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 12px; font-weight: 600;
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  color: hsl(var(--muted-foreground));
}
.offline-card h3 { font-size: 19px; letter-spacing: -0.02em; }
.offline-card p { font-size: 14.5px; line-height: 1.65; color: hsl(var(--muted-foreground)); }
.offline-meter {
  margin-top: auto; padding-top: 14px;
  border-top: 1px solid hsl(var(--tint-border-soft));
  display: flex; align-items: center; justify-content: space-between;
  font-size: 13px;
}
/* Fixed widths on the two ends so the bar between them keeps a steady length
   as the text swaps ("34%" -> "Just now", "Syncing" -> "Synced"). Without
   these the bar visibly jumps each time the label changes. */
.offline-meter b {
  font-variant-numeric: tabular-nums;
  min-width: 64px;
  text-align: right;
}
.offline-meter [data-meter-label] { min-width: 52px; }
/* Sits inline between the label and the value, so all three offline cards end
   in a single row of the same height. */
.meter {
  flex: 1 1 auto;
  min-width: 0;
  height: 6px;
  margin: 0 12px;
  border-radius: var(--radius-pill);
  background: hsl(var(--secondary));
  overflow: hidden;
}
.meter i {
  display: block; height: 100%; border-radius: inherit;
  background: var(--gradient-primary);
  width: 34%;
  transition: width 900ms linear;
}
.offline-foot {
  margin-top: 24px; padding: 16px 20px;
  border-radius: var(--radius-md);
  background: hsl(var(--secondary));
  font-size: 14.5px; color: hsl(var(--muted-foreground));
}

/* --- Split layout --------------------------------------------------------- */
.split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  gap: clamp(40px, 6vw, 72px);
  align-items: center;
  margin-top: 52px;
  text-align: left;
}
/* min(100%, 380px) rather than a bare 380px: below 380px viewport the bare
   value would overflow the track instead of collapsing to one column. */
.split .lede { margin-inline: 0; }

/* --- Audience ------------------------------------------------------------- */
/* Three labels, no boxes and no body copy. The trust strip near the top already
   uses icon + title + description, so this stays lighter to avoid reading as a
   second one. */
.audience-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 28px;
  margin-top: 48px;
}
.audience-row li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  min-width: 0;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: var(--tracking-tight);
  text-align: center;
  text-wrap: balance;
}
.audience-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: var(--radius-pill);
  background: hsl(var(--primary) / 0.1);
  color: hsl(var(--primary-ink));
}
.audience-icon svg { width: 20px; height: 20px; }

@media (max-width: 560px) {
  .audience-row { grid-template-columns: minmax(0, 1fr); gap: 24px; }
}

/* --- Comparison ----------------------------------------------------------- */
.compare {
  margin-top: 44px;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.compare-head, .compare-row {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr) minmax(0, 1fr);
}
.compare-head {
  background: hsl(var(--neutral-100));
  border-bottom: 1px solid hsl(var(--border));
}
/* From the design: only the first cell is an uppercase label. The two compared
   columns are sentence-case and dark, and the KeepPulsing side carries the
   brand lockup rather than a text label. */
.compare-head > div {
  padding: 14px 18px;
  font-size: 13px;
  font-weight: 600;
  color: hsl(var(--foreground));
}
.compare-head > div:first-child {
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
}
.compare-head > div + div { border-left: 1px solid hsl(var(--border)); }
.compare-head .kp { display: flex; align-items: center; gap: 8px; letter-spacing: -0.02em; }
.compare-mark { width: 16px; height: 16px; flex: 0 0 auto; }
.compare-head .kp b { color: hsl(var(--brand)); font-weight: 600; }
.compare-row { border-bottom: 1px solid hsl(var(--tint-border-soft)); }
.compare-row:last-child { border-bottom: 0; }
.compare-row > div { padding: 16px 18px; font-size: 13.5px; line-height: 1.5; }
.compare-row > div + div { border-left: 1px solid hsl(var(--tint-border-soft)); }
.compare-row .task { font-size: 14px; font-weight: 500; }
.compare-row .paper { color: hsl(var(--muted-foreground)); }
.compare-foot {
  margin-top: 24px;
  font-size: 17px;
  font-weight: 500;
  text-align: center;
}

/* --- Getting started ------------------------------------------------------ */
.steps-3 {
  display: grid;
  /* 3 items, so explicit counts: 3 or 1, never 2. auto-fit resolved to two
     tracks anywhere between ~576px and ~860px, leaving step 3 alone on a
     second row. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 28px;
  margin-top: 48px;
}
@media (max-width: 680px) {
  .steps-3 { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  /* One column: there is no next badge to the right to join. */
  .start-step:not(:last-child)::after { content: none; }
}
/* Centred like .audience-row, but read as a sequence rather than three facts:
   a hairline joins the badges, and the titles carry real weight so they are not
   mistaken for a second line of body copy. */
.start-step {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  text-align: center;
}
/* Badge centre (48 / 2) to badge centre, stopping 30px short of each so the
   line never runs under a number. Distance between centres is the track width
   plus the 28px gap, hence 100% + 28 - 60. */
.start-step:not(:last-child)::after {
  content: '';
  position: absolute;
  top: 24px;
  left: calc(50% + 30px);
  width: calc(100% - 32px);
  height: 1px;
  background: hsl(var(--border));
}
.start-step .n {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-pill);
  background: hsl(var(--primary) / 0.1);
  color: hsl(var(--primary-ink));
  font-size: 17px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.start-step h3 {
  margin-top: 18px;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}
.start-step p {
  margin-top: 8px;
  /* No character cap: the 381px track is already the measure, and a tighter
     one only forced two of the three to wrap while the third stayed on one
     line. text-wrap: balance handles the narrow breakpoints. */
  font-size: 14.5px;
  line-height: 1.65;
  color: hsl(var(--muted-foreground));
  text-wrap: balance;
}

/* --- Pricing -------------------------------------------------------------- */
.price-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
  margin-top: 44px;
  align-items: start;
}
.price-card {
  border: 1px solid hsl(var(--border));
  border-radius: 14px;
  background: hsl(var(--card));
  padding: 28px;
  text-align: left;
}
.price-top {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
/* Fixed height so swapping currency causes no layout shift. */
.price-value { min-height: 64px; display: flex; align-items: center; }
.price {
  font-size: 40px;
  font-weight: 600;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.price small {
  font-size: 15px; font-weight: 400;
  color: hsl(var(--muted-foreground));
}
/* The markup carries the global price, which is what crawlers and no-JS
   visitors see; site.js swaps the amount from #pricing-config and unhides
   the picker. */
.country-picker { display: flex; flex-direction: column; gap: 5px; padding-top: 6px; }
.country-picker label {
  font-size: 12px; font-weight: 500;
  color: hsl(var(--muted-foreground));
}
.country-picker .select { position: relative; display: block; }
.country-picker select {
  -webkit-appearance: none; appearance: none;
  width: 100%;
  min-width: 164px;
  padding: 6px 34px 6px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid hsl(var(--border));
  background: hsl(var(--card));
  color: hsl(var(--foreground));
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease-standard);
}
.country-picker select:hover { border-color: hsl(var(--primary-ink)); }
/* Chevron; the native arrow is removed by appearance: none. */
.country-picker .select::after {
  content: '';
  position: absolute; right: 15px; top: 50%;
  width: 7px; height: 7px;
  border-right: 1.5px solid hsl(var(--muted-foreground));
  border-bottom: 1.5px solid hsl(var(--muted-foreground));
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none;
}
/* iOS zooms the page when a control under 16px takes focus. */
@media (pointer: coarse) {
  .country-picker select { font-size: 16px; padding: 8px 36px 8px 16px; }
}
.price-per { font-size: 14px; color: hsl(var(--muted-foreground)); margin-top: 4px; }
.feature-list { margin-top: 22px; display: flex; flex-direction: column; gap: 12px; }
.feature-list li {
  display: flex; gap: 10px; align-items: flex-start;
  font-size: 15px; line-height: 1.55;
}
.feature-list svg {
  width: 18px; height: 18px; flex: 0 0 auto; margin-top: 2px;
  color: hsl(var(--primary-ink));
}
.price-cta { margin-top: 26px; display: flex; flex-direction: column; gap: 10px; }
.price-cta .btn { width: 100%; }
.price-notes { display: flex; flex-direction: column; gap: 20px; }
.price-note h3 { font-size: 16px; letter-spacing: -0.02em; }
.price-note p { margin-top: 6px; font-size: 14.5px; line-height: 1.65; color: hsl(var(--muted-foreground)); }

/* --- FAQ ------------------------------------------------------------------ */
.faq-list {
  margin-top: 44px;
  max-width: 820px;
  margin-inline: auto;
  border-top: 1px solid hsl(var(--border));
}
.faq-item { border-bottom: 1px solid hsl(var(--border)); }
.faq-q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 22px 4px;
  background: none;
  border: 0;
  text-align: left;
  font-size: 17px;
  font-weight: 500;
  cursor: pointer;
}
.faq-q .chev {
  flex: 0 0 auto; width: 18px; height: 18px;
  color: hsl(var(--muted-foreground));
  transition: transform var(--duration-fast) var(--ease-standard);
}
.faq-q[aria-expanded='true'] .chev { transform: rotate(180deg); }
.faq-a { padding: 0 4px 24px; max-width: 70ch; }
.faq-a p { font-size: 16px; line-height: 1.7; color: hsl(var(--muted-foreground)); }
.faq-a[hidden] { display: none; }

/* --- FAQ teaser cards (homepage) ------------------------------------------ */
/* The cards are the design's; its section head is not. That head ran at
   clamp(32px, 4.4vw, 52px) with a rule beneath it — the only h2 on the page at
   that size and the only decorative rule anywhere — so it reads as a different
   page. Standard .section-head, standard .h2. */
.faq-cards {
  display: grid;
  /* 4 cards, explicit counts. The design's own container is 1100px, where its
     auto-fit/380px resolves to 2 tracks; ours is 1200px, where the same rule
     would give 3 and strand the fourth card. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
  margin-top: 52px;
}
.faq-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  padding: clamp(28px, 4vw, 40px) clamp(22px, 3vw, 36px);
  border: 1px solid hsl(var(--border));
  border-radius: 18px;
  background: hsl(var(--card));
  text-align: center;
  transition: background-color var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard);
}
/* Tint and border only — no lift, no shadow. These cards are not clickable,
   and elevation is the strongest "press me" signal there is. Matches
   .vertical-card--live, which earns its hover by containing a link. */
@media (hover: hover) {
  .faq-card:hover {
    background: hsl(var(--primary) / 0.03);
    border-color: hsl(var(--tint-border-85));
  }
}
.faq-card-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 56px; height: 56px; flex: 0 0 auto;
  border-radius: 14px;
  background: hsl(var(--primary) / 0.1);
  color: hsl(var(--primary-strong));
}
.faq-card-icon svg { width: 24px; height: 24px; }
.faq-card h3 {
  font-size: clamp(18px, 1.8vw, 20px);
  font-weight: 600;
  letter-spacing: -0.015em;
}
.faq-card p {
  max-width: 420px;
  font-size: 15.5px;
  line-height: 1.7;
  color: hsl(var(--muted-foreground));
}
.faq-more { margin-top: 52px; display: flex; justify-content: center; }

/* --- /faq/ page ----------------------------------------------------------- */
.faq-group + .faq-group { margin-top: 56px; }
.faq-group > h2 {
  max-width: 820px;
  margin-inline: auto;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
}
.faq-group .faq-list { margin-top: 16px; }

/* Card accordion, /faq/ only. The open item drops its border and takes the
   warm tint; the + rotates into an ×.
   The open state keys off the panel, not aria-expanded, so it is still right
   with JS blocked — site.js sets [hidden], and without it every answer is
   open, which is exactly what the styling should then show. */
.faq-list--cards {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 820px;
  margin-inline: auto;
  border-top: 0;
}
.faq-list--cards .faq-item {
  border: 1px solid hsl(var(--border));
  border-radius: 16px;
  background: hsl(var(--card));
  transition: background-color var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard);
}
.faq-list--cards .faq-item:has(> .faq-a:not([hidden])) {
  background: hsl(var(--neutral-100));
  border-color: transparent;
}
.faq-list--cards .faq-q {
  align-items: center;
  gap: 16px;
  padding: 20px clamp(16px, 2.4vw, 24px);
  font-size: 16px;
}
.faq-list--cards .faq-a {
  padding: 0 clamp(16px, 2.4vw, 24px) 22px;
  max-width: 66ch;
}
.faq-list--cards .faq-a p { font-size: 15px; }
.faq-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border: 1px solid hsl(var(--border));
  border-radius: 50%;
  background: hsl(var(--card));
  color: hsl(var(--muted-foreground));
  transition: transform var(--duration-fast) var(--ease-standard);
}
.faq-icon svg { width: 13px; height: 13px; }
.faq-list--cards .faq-item:has(> .faq-a:not([hidden])) .faq-icon {
  transform: rotate(45deg);
}

@media (max-width: 820px) {
  .faq-cards { grid-template-columns: minmax(0, 1fr); }
}

/* --- Closing CTA ---------------------------------------------------------- */
/* A light tray, not a dark slab: the design ends the page on the same paper it
   started on, so the CTA reads as the next step rather than a banner ad. */
.closing {
  border: 1px solid hsl(var(--border));
  border-radius: 22px;
  background: hsl(var(--neutral-100));
  padding: clamp(32px, 5vw, 72px);
  margin-top: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 22px;
  text-align: left;
}
.closing h2 { max-width: 680px; font-size: clamp(32px, 4vw, 44px); line-height: 1.24; letter-spacing: -0.025em; }
.closing p { margin: 0; max-width: 560px; font-size: 17px; line-height: 1.6; color: hsl(var(--muted-foreground)); }
.closing .cta-row { margin-top: 0; }

/* --- Footer --------------------------------------------------------------- */
.site-footer {
  margin-top: 112px;
  border-top: 1px solid hsl(var(--border));
  padding: 56px var(--gutter) 48px;
}
.footer-inner { max-width: var(--measure); margin-inline: auto; }
.footer-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 40px;
}
/* No span: brand + 4 link columns is 5 tracks, and 5*190 + 4*40 = 1110 fits
   the 1200px measure. Spanning 2 needs 6 tracks (1340px) and wrapped the last
   column onto a second row. */
.footer-brand { min-width: 0; }
.footer-brand p { margin-top: 12px; max-width: 34ch; font-size: 14px; line-height: 1.6; color: hsl(var(--muted-foreground)); }
.footer-col h2 {
  font-size: 12px; font-weight: 600;
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  color: hsl(var(--muted-foreground)); margin-bottom: 14px;
}
.footer-col li { margin-bottom: 10px; }
.footer-col a { font-size: 14px; color: hsl(var(--foreground)); }
.footer-col a:hover { color: hsl(var(--primary-ink)); }
.footer-col span { font-size: 14px; color: hsl(var(--muted-foreground)); }
.footer-bottom {
  margin-top: 44px; padding-top: 24px;
  border-top: 1px solid hsl(var(--border));
  display: flex; flex-wrap: wrap; gap: 12px;
  align-items: center; justify-content: space-between;
  font-size: 13px; color: hsl(var(--muted-foreground));
}

/* --- Legal / prose pages -------------------------------------------------- */
.prose { max-width: 74ch; margin-inline: auto; }
.prose h1 { font-size: clamp(32px, 5vw, 46px); line-height: 1.15; letter-spacing: -0.03em; }
.prose .updated { margin-top: 12px; font-size: 14px; color: hsl(var(--muted-foreground)); }
.prose h2 {
  margin-top: 48px; font-size: 24px;
  letter-spacing: -0.02em; line-height: 1.3;
}
.prose h3 { margin-top: 28px; font-size: 18px; letter-spacing: -0.02em; }
.prose p { margin-top: 16px; font-size: 16.5px; line-height: 1.75; color: hsl(var(--muted-foreground)); }
.prose ul { margin-top: 16px; display: flex; flex-direction: column; gap: 10px; }
.prose ul li {
  position: relative; padding-left: 22px;
  font-size: 16.5px; line-height: 1.7; color: hsl(var(--muted-foreground));
}
.prose ul li::before {
  content: ''; position: absolute; left: 4px; top: 11px;
  width: 6px; height: 6px; border-radius: 50%;
  background: hsl(var(--primary));
}
.prose strong { color: hsl(var(--foreground)); font-weight: 600; }
.prose a { color: hsl(var(--primary-ink)); text-decoration: underline; text-underline-offset: 2px; }

/* Inline links inside running body copy. The base rule is
   `a { color: inherit; text-decoration: none }`, which is right for nav items,
   cards and buttons — they carry their own affordance. A link sitting inside a
   sentence has none, so it gets the .prose treatment or it reads as plain text
   and nobody clicks it. */
.lede a,
.faq-a a,
.closing p a,
.module-card p a,
.feature-wall p a,
.offline-foot a,
.compare-foot a,
.stock-foot a {
  color: hsl(var(--primary-ink));
  text-decoration: underline;
  text-underline-offset: 2px;
}
.prose .callout {
  margin-top: 24px; padding: 18px 22px;
  border-radius: var(--radius-md);
  background: hsl(var(--secondary));
  border-left: 3px solid hsl(var(--primary));
}
.prose .callout p { margin-top: 0; }

/* --- Contact -------------------------------------------------------------- */
.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
  margin-top: 44px;
}
.contact-card {
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-lg);
  background: hsl(var(--card));
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.contact-card--primary { border-color: hsl(var(--primary) / 0.45); box-shadow: var(--shadow-elegant); }
.contact-card h3 { font-size: 19px; letter-spacing: -0.02em; }
.contact-card p { font-size: 15px; line-height: 1.65; color: hsl(var(--muted-foreground)); }
.contact-card .btn { margin-top: auto; align-self: flex-start; }

/* ==========================================================================
   Narrow screens
   The layout is fluid by default; these are the two places where "collapse
   this" cannot be expressed with clamp() or auto-fit alone. Verified against
   360px, the narrowest width we design for.

   The desktop mockup used to collapse its sidebar here. It no longer needs to:
   below 760px the whole frame is swapped out for the phone instead - see the
   phone block near .mock-phone.
   ========================================================================== */

/* Three columns of prose at 360px leaves ~64px of text per cell. Stack them
   into labelled rows instead. */
@media (max-width: 720px) {
  .compare-head { display: none; }
  .compare-row { display: block; padding: 4px 0 14px; }
  .compare-row > div { border-left: 0 !important; padding: 8px 16px; }
  .compare-row .task {
    font-size: 15px;
    font-weight: 600;
    padding-top: 16px;
  }
  .compare-row .paper::before,
  .compare-row .kp-cell::before {
    display: block;
    margin-bottom: 4px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: hsl(var(--muted-foreground));
  }
  .compare-row .paper::before { content: 'The old way'; }
  .compare-row .kp-cell::before {
    content: 'KeepPulsing';
    color: hsl(var(--primary-ink));
  }
}

/* Section rhythm: 96–120px desktop, 64px mobile. */
@media (max-width: 640px) {
  :root { --section-pad: 64px; }
  .hero { padding-top: 72px; }
  .closing { border-radius: 18px; }
  .site-footer { padding-top: 48px; }
}

/* ==========================================================================
   Homeopathy (/homeopathy/)
   Ported from docs/design/KeepPulsing Homeopathy.html. Built first as
   /homeopathy-v2/ and promoted over the original page on 2026-09-23; the page
   it replaced is kept at docs/archive/homeopathy-v1.html. Everything below is
   used only by /homeopathy/ — no other page touches these classes.
   ========================================================================== */

/* Breadcrumb above the hero. The design uses it instead of the eyebrow pill,
   so the page announces where it sits rather than what it is. */
.crumb {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: hsl(var(--muted-foreground));
  margin-bottom: 26px;
}
.crumb a { color: inherit; }
.crumb a:hover { color: hsl(var(--foreground)); }
.crumb .sep { color: hsl(var(--tint-border-85)); }
.crumb b { color: hsl(var(--foreground)); font-weight: 500; }

/* The design's hero is left-aligned against the 1200px measure, not centred
   like the rest of the site. */
.hero--left { text-align: left; }
.hero--left .hero-inner > * { margin-inline: 0; }
.hero--left h1 { margin-inline: 0; max-width: 18ch; }
.hero--left .lede { margin-inline: 0; max-width: 58ch; }
.hero--left .cta-row { justify-content: flex-start; }

/* --- Case record (hero mockup) -------------------------------------------- */
/* Same idea as .mock, but the chrome is the case itself rather than a browser
   URL bar — the design shows the record, not the app around it. */
.caserec {
  margin-top: 56px;
  border: 1px solid hsl(var(--border));
  border-radius: 20px;
  background: hsl(var(--card));
  box-shadow: var(--shadow-mock);
  overflow: hidden;
  text-align: left;
}
.caserec-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 16px;
  height: 44px;
  border-bottom: 1px solid hsl(var(--border));
  background: hsl(var(--neutral-100));
}
.caserec-id { display: flex; align-items: center; gap: 9px; min-width: 0; }
.caserec-id svg { flex: none; width: 18px; height: 18px; }
.caserec-id svg rect { fill: hsl(var(--brand)); }
.caserec-id b { font-size: 13px; font-weight: 600; }
.caserec-id span,
.caserec-clinic { font-size: 11.5px; color: hsl(var(--muted-foreground)); }
.caserec-clinic { white-space: nowrap; }

/* Two panes of one record: this visit on the left, the case over time on the
   right. Two items, so 2 or 1 — never an odd count to strand. */
.caserec-body { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.caserec-body > * { padding: 20px; min-width: 0; }
.caserec-body > :first-child { border-right: 1px solid hsl(var(--border)); }
@media (max-width: 820px) {
  .caserec-body { grid-template-columns: minmax(0, 1fr); }
  .caserec-body > :first-child {
    border-right: 0;
    border-bottom: 1px solid hsl(var(--border));
  }
}

.caserec-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
}
.case-fields { margin-top: 14px; display: flex; flex-direction: column; gap: 10px; }
.case-field {
  border: 1px solid hsl(var(--tint-border-soft));
  border-radius: 10px;
  padding: 11px 13px;
}
.case-field .k {
  display: block;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: hsl(var(--muted-foreground));
}
.case-field .v { display: block; font-size: 13.5px; margin-top: 4px; }
.case-field .v--strong { font-weight: 500; }
.case-field .sub { display: block; font-size: 12px; margin-top: 3px; color: hsl(var(--muted-foreground)); }

/* Case history: date, what was given, how it moved. */
.case-history { margin-top: 14px; }
.case-line {
  display: grid;
  grid-template-columns: 76px minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid hsl(var(--tint-border-softer));
}
.case-line .d {
  font-size: 12px;
  color: hsl(var(--muted-foreground));
  font-variant-numeric: tabular-nums;
}
.case-line .r { font-size: 13px; min-width: 0; }

/* One badge shape, three meanings. Terracotta is attention, not error. */
.pill {
  font-size: 10.5px;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  text-align: center;
  background: hsl(var(--muted));
  color: hsl(var(--muted-foreground));
}
.pill--good { background: hsl(var(--tint-success-bg) / 0.12); color: hsl(var(--tint-success-strong)); }
.pill--info { background: hsl(var(--primary) / 0.12); color: hsl(var(--primary-strong)); }
.pill--warn { background: hsl(var(--accent) / 0.14); color: hsl(var(--tint-accent-text)); }

.case-next {
  margin-top: 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 13px;
  border: 1px solid hsl(var(--primary) / 0.35);
  border-radius: 10px;
  background: hsl(var(--primary) / 0.07);
}
.case-next b { font-size: 12.5px; font-weight: 500; color: hsl(var(--primary-strong)); }
.case-next span { font-size: 12px; color: hsl(var(--muted-foreground)); }

/* --- The visit (step flow) ------------------------------------------------- */
/* Heading left, step pills right on one baseline — the design puts the rail in
   the section head rather than above the panel. */
.flow-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 28px;
  flex-wrap: wrap;
  text-align: left;
}
.flow-head h2 { max-width: 20ch; }
.flow-head .step-rail { margin-bottom: 0; }

/* The tray holds a card with its own header bar, so the step reads as a screen
   inside the app rather than a slab of page. The card *is* the tab panel —
   the header changes with the step, so it cannot sit outside the thing
   site.js toggles. */
.flow-tray { margin-top: 32px; padding: clamp(16px, 3vw, 40px); }

.step-panel--flow {
  display: block;
  padding: 0;
  border: 1px solid hsl(var(--border));
  border-radius: 14px;
  background: hsl(var(--card));
  overflow: hidden;
  box-shadow: 0 26px 60px -34px hsl(var(--navy) / 0.32);
  text-align: left;
}
.flow-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid hsl(var(--border));
  background: hsl(var(--neutral-100));
}
.flow-card-head b { font-size: 13px; font-weight: 600; }
.flow-card-head span { font-size: 11.5px; color: hsl(var(--muted-foreground)); white-space: nowrap; }

.flow-body {
  padding: 20px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  min-height: 300px;
  align-items: start;
}
@media (max-width: 800px) { .flow-body { grid-template-columns: minmax(0, 1fr); } }
.flow-body > .copy { min-width: 0; }
.flow-body > .copy > p {
  font-size: 16px;
  line-height: 1.7;
  color: hsl(var(--muted-foreground));
}

.check-list { margin-top: 18px; display: flex; flex-direction: column; gap: 10px; }
.check-list li { display: flex; align-items: flex-start; gap: 10px; font-size: 14.5px; line-height: 1.55; }
.check-list svg {
  flex: none;
  width: 16px;
  height: 16px;
  margin-top: 3px;
  stroke: hsl(var(--primary));
}

/* Field readout beside the copy. Rows are label-left, value-right, and the
   panel sits at the top of its track so a short step does not stretch it. */
.readout {
  min-width: 0;
  border: 1px solid hsl(var(--border));
  border-radius: 12px;
  overflow: hidden;
  align-self: start;
}
.readout-head {
  padding: 11px 14px;
  border-bottom: 1px solid hsl(var(--border));
  font-size: 12.5px;
  font-weight: 600;
}
.readout-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  padding: 11px 14px;
  border-bottom: 1px solid hsl(var(--tint-border-softer));
}
.readout-row:last-child { border-bottom: 0; }
.readout-row .k {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: hsl(var(--muted-foreground));
  padding-top: 2px;
  flex: none;
}
.readout-row .v { font-size: 13px; text-align: right; }

/* --- Problem (v2 variant) -------------------------------------------------- */
/* /homeopathy/ and the v2 design both use the same bones here — a hairline
   rule, a number, a title, a paragraph — but the design tightens the type and
   states the number in primary blue rather than grey, which is what turns four
   quiet columns into a counted list. Kept as a modifier so the live page's
   larger, greyer treatment is untouched.
   Flush left against the full measure, because v2 aligns every section head to
   the container's left edge and a grid still centred at 980px under one reads
   as a mistake. 4 items, so 2 / 1 columns — both divide 4, no orphan row. */
.problem-grid--wide {
  max-width: none;
  margin: 44px 0 0;
  gap: clamp(24px, 3vw, 40px);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 860px) {
  .problem-grid--wide { grid-template-columns: minmax(0, 1fr); }
}
.problem-grid--wide .problem-num {
  margin-bottom: 12px;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: hsl(var(--primary-ink));
}
.problem-grid--wide .problem-card h3 { font-size: 19px; letter-spacing: -0.02em; }
.problem-grid--wide .problem-card p {
  max-width: 48ch;
  font-size: 15px;
  line-height: 1.65;
}

/* --- Feature wall --------------------------------------------------------- */
/* Same hairline-divider treatment as .vertical-grid. 6 items, so 3 / 2 / 1 —
   all of which divide 6 evenly and leave no orphan row. */
.feature-wall {
  margin-top: 44px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: hsl(var(--border));
  border: 1px solid hsl(var(--border));
  border-radius: 18px;
  overflow: hidden;
  text-align: left;
}
.feature-wall > article { background: hsl(var(--card)); padding: 26px 24px 30px; min-width: 0; }
.feature-wall h3 { font-size: 17px; font-weight: 600; letter-spacing: -0.015em; }
.feature-wall p {
  margin-top: 10px;
  font-size: 14.5px;
  line-height: 1.65;
  color: hsl(var(--muted-foreground));
}
@media (max-width: 1000px) { .feature-wall { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px) { .feature-wall { grid-template-columns: minmax(0, 1fr); } }

.feature-foot { margin-top: 16px; font-size: 13.5px; color: hsl(var(--tint-muted-soft)); }

/* --- Module grid (v2 variant) ---------------------------------------------- */
/* Bordered cards rather than the hairline .feature-wall above it: two
   identically-divided walls in a row would read as one long section. 8 items,
   so 4 / 2 / 1 — never 3, which strands two on the last row. */
.module-grid--4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 1060px) {
  .module-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .module-grid--4 { grid-template-columns: minmax(0, 1fr); }
}

/* --- Offline band --------------------------------------------------------- */
/* The homepage answers this worry with three full cards; a vertical page only
   needs the progression, so the three states collapse to three lines inside one
   card and the sync meter moves to the footer. Same [data-meter] hooks, so
   site.js drives it unchanged. */
.offline-band {
  margin-top: 44px;
  border: 1px solid hsl(var(--border));
  border-radius: 18px;
  overflow: hidden;
  background: hsl(var(--card));
  box-shadow: 0 30px 60px -36px hsl(var(--navy) / 0.22);
  text-align: left;
}
.offline-band-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 13px 16px;
  border-bottom: 1px solid hsl(var(--border));
  background: hsl(var(--neutral-100));
}
.offline-band-head b { font-size: 13px; font-weight: 600; }
.offline-band-head span { font-size: 11.5px; color: hsl(var(--muted-foreground)); }

/* Fixed first track so the three state labels align and the sentences start on
   one edge — the progression is the point, and a ragged left kills it. */
.offline-row {
  display: grid;
  grid-template-columns: 190px minmax(0, 1fr);
  gap: 16px;
  align-items: baseline;
  padding: 14px 16px;
  border-bottom: 1px solid hsl(var(--tint-border-softer));
}
.offline-row p { font-size: 14.5px; line-height: 1.6; color: hsl(var(--muted-foreground)); }
@media (max-width: 680px) {
  .offline-row { grid-template-columns: minmax(0, 1fr); gap: 6px; }
}

/* Reuses .offline-meter for the label/bar/value widths that stop the bar
   jumping as the text swaps; only the chrome changes. */
.offline-band .offline-meter {
  margin: 0;
  padding: 13px 16px;
  border-top: 0;
  background: hsl(var(--neutral-100));
}

/* --- Inventory card ------------------------------------------------------- */
.stock-card {
  border: 1px solid hsl(var(--border));
  border-radius: 18px;
  overflow: hidden;
  background: hsl(var(--card));
  box-shadow: 0 30px 60px -36px hsl(var(--navy) / 0.22);
}
.stock-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 13px 16px;
  border-bottom: 1px solid hsl(var(--border));
  background: hsl(var(--neutral-100));
}
.stock-head b { font-size: 13px; font-weight: 600; }
.stock-head span { font-size: 11.5px; color: hsl(var(--tint-accent-text)); }
.stock-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 84px 96px;
  gap: 12px;
  align-items: center;
  padding: 13px 16px;
  border-bottom: 1px solid hsl(var(--tint-border-softer));
}
.stock-row:last-child { border-bottom: 0; }
.stock-row .n { font-size: 13.5px; min-width: 0; }
.stock-row .q {
  font-size: 12.5px;
  color: hsl(var(--muted-foreground));
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.stock-foot {
  padding: 13px 16px;
  border-top: 1px solid hsl(var(--border));
  background: hsl(var(--neutral-100));
  font-size: 12.5px;
  line-height: 1.55;
  color: hsl(var(--muted-foreground));
}

/* ===========================================================================
   PRE-LAUNCH ONLY — one CTA left. Remove this block with the last span.

   app.keeppulsing.com went live on 2026-09-29 and all 64 of its CTAs are
   ordinary <a> links again. What remains is the single "Open WhatsApp" button
   on /contact/, still pointing at the wa.me/920000000000 placeholder, so it
   stays a <span class="btn btn--primary is-pending"> rather than a dead link.
   It renders exactly as designed and simply does not navigate — the same
   `is-soon` pattern the verticals use.

   The `@media (max-width: 900px)` rule that restored `.mobile-nav a` styling
   to a bare span was deleted on 2026-09-29: no bare `is-pending` spans survive
   the restore, so it matched nothing.

   When the real WhatsApp number lands: restore the <a href>, delete this whole
   block, and run tools/stamp-assets.py.
   =========================================================================== */
.btn.is-pending { cursor: default; }
.btn.is-pending:hover { transform: none; }
.btn--primary.is-pending:hover { background: hsl(var(--foreground)); }
