/* ══════════════════════════════════════════════════════════════════════════════
   Docodile — landing page (docodile.app)
   Static, no build step. nginx serves this directory from /var/www/landing.

   Tokens below MIRROR the product design system:
     frontend/src/styles/theme.ts      → colours, radii, shadows, spacing, motion
     frontend/src/styles/globals.css   → type ramp, motion vars, reduced-motion
   Keep them in sync by hand — this file is intentionally dependency-free
   (no Tailwind CDN, no PostCSS) so the marketing site can never break the app
   or drag a 400 KB runtime compiler in front of first paint.

   NOTE ON VIEWPORTS: the *app* is desktop-only (min 1200, browser never
   scrolls). This page is the opposite — a public marketing site that must work
   at 360px. So it does NOT inherit the app's viewport contract, only its brand.
   ══════════════════════════════════════════════════════════════════════════════ */

:root {
  /* ─── Primary: warm cream → burnt orange (theme.ts colors.primary*) ─── */
  --p100: #F9F9ED;  --p200: #F3F3DC;  --p300: #EDDFBA;  --p400: #EDCA99;
  --p500: #ECA66D;  --p600: #E48647;  --p700: #CF6F2F;  --p800: #AE561A;

  /* ─── Secondary: sage → deep green (theme.ts colors.secondary*) ─── */
  --s50:  #F1F6E7;  --s100: #E3EAD7;  --s200: #C8D4B0;  --s300: #ACBF88;
  --s400: #98B06C;  --s500: #849D54;  --s600: #6C8145;  --s700: #556536;
  --s800: #3D4927;

  /* ─── Neutrals (theme.ts colors.neutral*) ─── */
  --n100: #FFFFFF;  --n150: #F5F5F5;  --n200: #E3E3E3;  --n300: #C7C7C7;
  --n400: #ABABAB;  --n500: #8F8F8F;  --n600: #747474;  --n700: #585858;
  --n800: #3C3C3C;  --n900: #202020;  --n1000:#040404;

  /* ─── Semantic aliases ─── */
  --paper: #FFFDF7;          /* warm off-white card surface */
  --ink:   var(--n900);
  --line:  var(--p300);
  --muted: var(--n700);

  /* ─── Radii (theme.ts radii) ─── */
  --r-xs: 4px;  --r-s: 6px;  --r-m: 8px;  --r-l: 10px;
  --r-xl: 12px; --r-2xl: 16px; --r-pill: 999px;

  /* ─── Shadows (theme.ts shadows) ─── */
  --sh-card:  0 4px 20px rgba(0, 0, 0, .04);
  --sh-menu:  0 4px 16px rgba(0, 0, 0, .08);
  --sh-modal: 0 12px 40px rgba(0, 0, 0, .12);
  /* Marketing-only: a warm lift the app doesn't need */
  --sh-lift:  0 1px 0 rgba(0,0,0,.02), 0 18px 50px -22px rgba(174, 86, 26, .22);

  /* ─── Spacing (theme.ts spacing) ─── */
  --sp-2xs: 4px; --sp-xs: 8px;  --sp-s: 12px; --sp-m: 16px; --sp-l: 20px;
  --sp-xl: 24px; --sp-2xl: 32px; --sp-3xl: 40px; --sp-4xl: 48px; --sp-5xl: 56px;

  /* Hero frost strength. CSS blur(<length>) sets the Gaussian standard
     deviation directly, so this is the same scale as the SVG's stdDeviation and
     as Figma's own blur field, where the design sets 3.3px. */
  --hero-blur: 5px;

  /* ─── Motion (globals.css --motion-* / --ease-*) ─── */
  --motion-fast: 120ms;
  --motion-base: 180ms;
  --motion-slow: 240ms;
  --ease-standard: cubic-bezier(0.2, 0, 0, 1);
  --ease-entrance: cubic-bezier(0.05, 0.7, 0.1, 1);
  --ease-spring:   cubic-bezier(0.34, 1.56, 0.64, 1);

  /* ─── Type ───────────────────────────────────────────────────────────────
     The app ramp is a two-tier step (1440 baseline / 1200 compact). A landing
     page spans 360→2560, so the same rungs are expressed as clamp() instead —
     the 1440 value is the clamp's upper bound, so desktop matches the product.  */
  --fs-display: clamp(2.5rem, 1.55rem + 4.24vw, 5.25rem); /* 40 → 84  display */
  --fs-hero:    clamp(2.5rem, 1.55rem + 3.10vw, 4.5rem);  /* 40 → 72  hero h1 */
  --fs-h1:      clamp(2rem,  1.36rem + 2.86vw, 3.75rem);  /* 32 → 60  section */
  --fs-h2:      clamp(1.75rem, 1.32rem + 1.90vw, 3rem);   /* 28 → 48  */
  --fs-h3:      clamp(1.5rem, 1.21rem + 1.29vw, 2.5rem);  /* 24 → 40  */
  --fs-h4:      clamp(1.25rem, 1.07rem + 0.80vw, 2rem);   /* 20 → 32  */
  --fs-h5:      clamp(1.125rem, 1.04rem + 0.36vw, 1.5rem);/* 18 → 24  */
  --fs-l:       clamp(1.0625rem, 1.02rem + 0.19vw, 1.25rem); /* 17 → 20 */
  --fs-m:       1rem;      /* 16 — body, holds (accessibility floor) */
  --fs-s:       0.875rem;  /* 14 */
  --fs-xs:      0.75rem;   /* 12 */
  --fs-caption: 0.6875rem; /* 11 */

  --lh-tight: 1.06;
  --lh-snug:  1.25;
  --lh-body:  1.6;

  /* ─── Layout ─── */
  /* 1440, not 1160: at a 1440 viewport the old cap left 140px of dead gutter
     PER SIDE before padding even applied, which is what read as "too much
     left/right padding". At this cap the content runs near edge-to-edge on a
     laptop and only starts centring on genuinely wide screens, where some
     gutter is what keeps long lines readable. Headings stay comfortable
     regardless via .section-head's own 46rem measure. */
  --content-max: 1440px;
  --gutter: clamp(1.25rem, 0.90rem + 1.56vw, 2.5rem);  /* 20 → 40  outer margin */
  --grid-gap: clamp(1rem, 0.86rem + 0.7vw, 1.5rem);    /* 16 → 24  inter-column gutter */
  --section-y: clamp(3.5rem, 2.36rem + 5.09vw, 7rem);  /* 56 → 112 */
  --nav-h: 58px;          /* capsule height (was a full-width 68px bar) */
  --nav-float: 12px;      /* inset of the floating nav capsule from the viewport top */
}

@media (prefers-reduced-motion: reduce) {
  .mods__panel { transition: none; transform: none; }
  :root {
    --motion-fast: 0.01ms;
    --motion-base: 0.01ms;
    --motion-slow: 0.01ms;
  }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   BASE
   ══════════════════════════════════════════════════════════════════════════ */

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

html {
  scroll-behavior: smooth;
  /* Anchor targets clear the sticky header instead of hiding behind it. */
  scroll-padding-top: calc(var(--nav-h) + var(--nav-float) * 2 + 12px);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--p100);
  color: var(--ink);
  font-family: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: var(--fs-m);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  /* Belt-and-braces: nothing on a marketing page may cause sideways scroll. */
  overflow-x: hidden;
}

h1, h2, h3, h4, h5, p, figure, blockquote { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img, svg { max-width: 100%; }
a { color: inherit; text-decoration: none; }

/* One visible focus treatment for every interactive element. The app relies on
   component-level focus rings; a static page needs a global one. */
:focus-visible {
  outline: 2px solid var(--p700);
  outline-offset: 3px;
  border-radius: var(--r-xs);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--n900);
  color: var(--n100);
  padding: var(--sp-s) var(--sp-m);
  border-radius: 0 0 var(--r-m) 0;
  font-size: var(--fs-s);
}
.skip-link:focus { left: 0; }

.wrap {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.serif {
  font-family: 'Libertinus Serif', 'Source Serif Pro', Georgia, 'Times New Roman', serif;
}

/* Every heading on the site: hero h1, section titles, the CTA heading and the
   legal-page titles. Instrument Serif has a smaller x-height and a tighter
   default fit than Libertinus, so it needs far less negative tracking (-0.5%
   rather than -1.5%). Loaded on index/privacy/terms alike. */
.display {
  font-family: 'Instrument Serif', Georgia, serif;
  font-weight: 400;
  letter-spacing: -0.005em;
  line-height: var(--lh-tight);
}

.section { padding-block: var(--section-y); }

.section-head { max-width: 46rem; }
.section-head--center { margin-inline: auto; text-align: center; }

.section-title {
  font-size: var(--fs-h2);
  margin-top: var(--sp-m);
}

.section-sub {
  margin-top: var(--sp-m);
  color: var(--muted);
  font-size: var(--fs-l);
}

.lede { color: var(--muted); font-size: var(--fs-l); }

/* ══════════════════════════════════════════════════════════════════════════
   PRIMITIVES — mirror the product's Button / Card / Badge canon
   ══════════════════════════════════════════════════════════════════════════ */

/* Eyebrow label. Product equivalent: Badge (tone-tinted pill). */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-xs);
  border-radius: var(--r-pill);
  padding: 6px 14px;
  background: var(--p200);
  color: var(--p800);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.eyebrow::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: var(--r-pill);
  background: var(--p700);
  flex-shrink: 0;
}
.eyebrow--sage { background: var(--s100); color: var(--s800); }
.eyebrow--sage::before { background: var(--s600); }

/* Button — Button.styles.ts canon: pill radius, 1.5px border, static height,
   motion-token transition, never wraps. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-xs);
  border-radius: var(--r-pill);
  border: 1.5px solid transparent;
  padding: 0 var(--sp-xl);
  height: 46px;
  font-family: inherit;
  font-size: var(--fs-m);
  font-weight: 500;
  white-space: nowrap;
  flex-shrink: 0;
  cursor: pointer;
  transition:
    background-color var(--motion-base) var(--ease-standard),
    border-color var(--motion-base) var(--ease-standard),
    color var(--motion-base) var(--ease-standard),
    transform var(--motion-fast) var(--ease-standard),
    box-shadow var(--motion-base) var(--ease-standard);
}
.btn:active { transform: scale(.98); }   /* product's key-press microinteraction */

/* Fill/hover match Button.styles.ts `primary`: active.shade700 → shade800.
   (The old page used p600, which was both off-system and the lowest-contrast
   pairing on the site.) */
.btn--primary {
  background: var(--p700);
  border-color: var(--p700);
  color: var(--n100);
  font-weight: 600;
}
.btn--primary:hover {
  background: var(--p800);
  border-color: var(--p800);
  box-shadow: var(--sh-menu);
}

/* Always-green CTA — the product's `secondary` variant, which deliberately
   does not theme-swap. Used for the one true conversion action. */
.btn--sage {
  background: var(--s500);
  border-color: var(--s500);
  color: var(--n100);
  font-weight: 600;
}
.btn--sage:hover {
  background: var(--s600);
  border-color: var(--s600);
  box-shadow: var(--sh-menu);
}

.btn--ghost {
  background: var(--paper);
  border-color: var(--line);
  color: var(--ink);
}
.btn--ghost:hover { border-color: var(--p500); background: var(--n100); }

.btn--sm { height: 40px; padding: 0 var(--sp-m); font-size: var(--fs-s); }

/* Card — one radius (2xl/16), warm paper surface, hairline warm border. */
.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-2xl);
  padding: var(--sp-xl);
}
.card--lift { box-shadow: var(--sh-lift); }
.card--sage { background: var(--s50); border-color: var(--s200); }
.card--plain { background: var(--n100); }

/* Icon — 24px box, currentColor, matches the product <Icon> contract. */
.icon { width: 24px; height: 24px; display: block; flex-shrink: 0; }
.icon--sm { width: 20px; height: 20px; }

/* Tinted icon chip that fronts each card. */
.icon-chip {
  width: 46px; height: 46px;
  border-radius: var(--r-xl);
  display: grid;
  place-items: center;
  background: var(--p200);
  color: var(--p800);
  flex-shrink: 0;
}
.icon-chip--sage { background: var(--s100); color: var(--s700); }
.icon-chip--plain { background: var(--n150); color: var(--n800); }

/* ══════════════════════════════════════════════════════════════════════════
   GRID SYSTEM — 12 columns desktop, 8 tablet, 4 mobile (Material Design's
   standard column tiers; tiers snap to the page's existing 900/620 content
   breakpoints so the grid and every other responsive rule agree on where
   "tablet" and "mobile" start).

   Two tools, two jobs:
   - `.grid-12` + `.col-*`  — literal column spans, for a layout that is
     genuinely asymmetric (the hero's 5/7 copy-vs-art split). Spans are
     re-declared per tier rather than scaled, because 12→8→4 isn't an integer
     ratio (5/12 has no equivalent whole span at 8 or 4 columns).
   - `.cards` + `.cards-N`  — even N-up card grids (3-up features, 2-up
     email/security). 3 and 6-item rows don't factor into 8 or 4 columns
     either, so these size directly by "cards per row" rather than by
     spanning a track count — same --grid-gap gutter, same tier breakpoints,
     simpler math for the common case.
   ══════════════════════════════════════════════════════════════════════════ */

.grid-12 {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--grid-gap);
}
.col-3  { grid-column: span 3; }
.col-4  { grid-column: span 4; }
.col-5  { grid-column: span 5; }
.col-6  { grid-column: span 6; }
.col-7  { grid-column: span 7; }
.col-8  { grid-column: span 8; }
.col-9  { grid-column: span 9; }
.col-12 { grid-column: span 12; }

.cards { display: grid; gap: var(--sp-l) var(--grid-gap); }
.cards-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cards-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.card-title {
  font-size: var(--fs-h5);
  font-weight: 600;
  letter-spacing: -0.01em;
}
.card-body {
  margin-top: var(--sp-xs);
  color: var(--muted);
  font-size: var(--fs-s);
  line-height: 1.55;
}

/* ══════════════════════════════════════════════════════════════════════════
   ANNOUNCE BAR + NAV
   ══════════════════════════════════════════════════════════════════════════ */


/* Floating glass capsule. The <header> itself is just a transparent sticky
   rail; the glass lives on .nav__inner so it can be a detached pill. The rail
   spans the full width but must not eat clicks on the hero behind it, hence
   pointer-events off on the rail and back on for the capsule. */
.nav {
  position: sticky;
  top: var(--nav-float);
  z-index: 50;
  margin-top: var(--nav-float);
  /* The capsule overrides .wrap's own gutter padding (it needs its own tighter
     internal padding), so the rail has to supply the inset from the viewport
     edges — otherwise the pill runs edge to edge and stops reading as floating. */
  padding-inline: var(--gutter);
  background: transparent;
  border-bottom: 0;
  pointer-events: none;
}
.nav__inner {
  pointer-events: auto;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-m);
  /* Roomier on the left so the logo sits inside the pill rather than against
     its edge; tighter on the right so the CTA nests rather than drifting. */
  padding-inline: var(--sp-2xl) var(--sp-xs);
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0);
  backdrop-filter: blur(0px) saturate(100%);
  -webkit-backdrop-filter: blur(0px) saturate(100%);
  border: 1px solid rgba(255, 255, 255, 0);
  box-shadow: 0 3px 14px -8px rgba(174, 86, 26, 0);
  transition: background var(--motion-slow) var(--ease-standard),
              border-color var(--motion-slow) var(--ease-standard),
              box-shadow var(--motion-slow) var(--ease-standard),
              backdrop-filter var(--motion-slow) var(--ease-standard),
              -webkit-backdrop-filter var(--motion-slow) var(--ease-standard);
}
.nav--scrolled .nav__inner {
  background: rgba(255, 255, 255, .42);
  backdrop-filter: blur(24px) saturate(180%);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  border-color: rgba(255, 255, 255, .55);
  box-shadow: 0 3px 14px -8px rgba(174, 86, 26, .16);
}
.nav__logo { display: flex; align-items: center; flex-shrink: 0; }
.nav__logo img { height: 34px; width: auto; display: block; }

.nav__links {
  display: flex;
  align-items: center;
  gap: var(--sp-2xl);
  font-size: var(--fs-s);
  color: var(--n800);
}
.nav__links a { position: relative; padding-block: 4px; }
/* Underline grows from the centre — the product's sliding-indicator idiom. */
.nav__links a::after {
  content: "";
  position: absolute;
  left: 50%; bottom: 0;
  width: 0; height: 1.5px;
  background: var(--p700);
  transform: translateX(-50%);
  transition: width var(--motion-base) var(--ease-standard);
}
.nav__links a:hover { color: var(--ink); }
.nav__links a:hover::after { width: 100%; }

.nav__actions { display: flex; align-items: center; gap: var(--sp-s); }
.nav__login { font-size: var(--fs-s); color: var(--n800); }
.nav__login:hover { color: var(--ink); }

/* Mobile menu button — hidden on desktop, the ONLY nav affordance below 900px.
   (The previous page hid its links at <768px with no fallback at all.) */
.nav__toggle {
  display: none;
  width: 44px; height: 44px;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1.5px solid var(--line);
  border-radius: var(--r-pill);
  color: var(--ink);
  cursor: pointer;
}

/* Matches the capsule: a detached glass sheet under it, not a full-width drop
   panel. Needs pointer-events back on, since the .nav rail disables them. */
.nav__mobile {
  display: none;
  pointer-events: auto;
  /* No horizontal margin: the .nav rail's padding-inline already insets this,
     and adding the gutter again double-indents it relative to the capsule. */
  margin: var(--sp-s) 0 0;
  padding: var(--sp-xs) var(--sp-l) var(--sp-l);
  border-radius: var(--r-2xl);
  background: rgba(255, 255, 255, .62);
  backdrop-filter: blur(24px) saturate(180%);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, .55);
  box-shadow: 0 3px 14px -8px rgba(174, 86, 26, .16);
}
.nav__mobile.is-open { display: block; }
.nav__mobile a {
  display: block;
  padding: var(--sp-s) 0;
  font-size: var(--fs-l);
  border-bottom: 1px solid rgba(237, 223, 186, .6);
}
/* `display:block` above would otherwise beat .btn's inline-flex and strand the
   label on the left edge of the pill. */
.nav__mobile .btn {
  display: flex;
  width: 100%;
  margin-top: var(--sp-m);
  border-bottom: 0;
}

/* ══════════════════════════════════════════════════════════════════════════
   HERO
   ══════════════════════════════════════════════════════════════════════════ */

.hero {
  position: relative;
  display: flex;
  align-items: center;
  /* Near-full-page: the viewport minus the sticky nav. svh (not vh) so mobile
     browser chrome doesn't push the CTAs below the fold. */
  min-height: calc(100vh - var(--nav-h) - var(--nav-float) * 2);
  min-height: calc(100svh - var(--nav-h) - var(--nav-float) * 2);
  padding-block: clamp(2.5rem, 1.30rem + 5.1vw, 5rem);
  text-align: left;
  /* Flat --p100, no radial glow. The hero PNG ships an OPAQUE #F9F9ED plate
     (Figma exported it without transparency), and its palette entry is pinned
     to this exact colour so the image edge is invisible. A gradient here would
     be occluded by that plate and turn the image into a visible rectangle.
     The artwork carries its own glow internally, so nothing is lost. */
  background: var(--p100);
}

/* Copy left, artwork right, inside the same centred container as every other
   section. */
.hero__inner {
  /* Gap is INHERITED from .grid-12, deliberately. A hero-sized 64px gap was
     fine when this was a 2-column grid (one gap); across 12 columns it becomes
     11 gaps and swallowed 704px of a 1425px row, crushing every track to 54px.
     In a column system the breathing room between copy and art comes from the
     column split (5/7) and the copy's own trailing padding, never from
     inflating a gap that repeats 11 times. */
  align-items: center;
}
.hero__copy {
  /* Keeps the copy off the artwork without touching the shared gap token. */
  padding-right: clamp(0rem, 1.5vw, 2rem);
}

/* Sans headline with a single word set in italic serif (the "The New Standard"
   masthead idiom). The contrast does the work, so the serif word stays the
   same colour as the rest — tinting it as well would be two accents fighting. */
.hero h1 {
  font-size: var(--fs-hero);
  line-height: 1.02;
  margin-top: 0;
  text-wrap: balance;
}

.hero p {
  margin-top: var(--sp-l);
  max-width: 34rem;
  color: var(--muted);
  font-size: var(--fs-l);
}
.hero__cta {
  margin-top: var(--sp-2xl);
  display: flex;
  gap: var(--sp-s);
  justify-content: flex-start;
  flex-wrap: wrap;
}

/* ── Hero artwork ─────────────────────────────────────────────────────────
   Vector export of the design-system hero frame (node 3257:7397), cropped to
   the artwork's own bounds with the baked glow removed. */
.hero__art {
  margin: 0;
  min-width: 0;
  /* Must stay stretched: `justify-self: start` sizes a grid item to its content,
     which makes the image's `width: 100%` circular and collapses it to the SVG's
     intrinsic size. No max-width needed now that the col-8 track bounds it. */
  justify-self: stretch;
}
/* WHY THERE IS NO CSS GLASS ON THE CARDS: a backdrop-filter only blurs what
   sits *behind* the element. The cards' own text and icons are baked into this
   same flat SVG, so any blur layer placed over the image from CSS would blur
   that content too, not just the artwork behind it. Real frosted glass needs
   the blur sandwiched between the background art and the card contents, which
   only exists inside the SVG. Splitting the export into background and card
   layers would allow it; see the note in the handover. */
.hero__art { position: relative; }
.hero-frost { filter: blur(var(--hero-blur)); }

.hero__art > svg {
  display: block;
  width: 100%;
  height: auto;
}

/* ── Hero card motion ────────────────────────────────────────────────────
   Two animations on one element rather than nested wrapper groups. The
   entrance uses fill-mode both so it holds before it starts; the float is
   delayed past the entrance and, being later in the list, takes over the
   transform the moment it begins. Both end and begin at translateY(0), so the
   handover is invisible.

   transform-box: fill-box is required: an SVG element's default transform
   origin is the user-space origin, so a scale without it would throw the card
   across the canvas instead of easing it in place. */
.hcard {
  transform-box: fill-box;
  transform-origin: center;
  animation:
    hcard-in    900ms var(--ease-entrance) both,
    hcard-float 9s    var(--ease-standard) 900ms infinite;
}
.hcard--patient { animation-delay: 0ms,   900ms;  }
.hcard--med     { animation-delay: 120ms, 3100ms; }
.hcard--bill    { animation-delay: 240ms, 5300ms; }
.hcard--rx      { animation-delay: 360ms, 7500ms; }

@keyframes hcard-in {
  from { opacity: 0; transform: translateY(14px) scale(.985); }
  to   { opacity: 1; transform: none; }
}
/* Deliberately transform-only. Animating the blur or the filter would force the
   frost to re-composite every frame, which is where a hero starts dropping
   frames; translating the finished result is nearly free. */
@keyframes hcard-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}

@media (prefers-reduced-motion: reduce) {
  .hcard { animation: none; }
}



/* Below two columns the hero stacks and re-centres — there is no left/right to
   preserve, and a centred short hero reads better on a phone. It also stops
   being full-height, since stacked content sets its own. */
@media (max-width: 940px) {
  .hero {
    display: block;
    min-height: 0;
    text-align: center;
  }
  .hero__inner {
    max-width: var(--content-max);
    margin-inline: auto;
    padding-inline: var(--gutter);
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-2xl);
  }
  .hero h1 { max-width: 18ch; margin-inline: auto; }
  .hero p  { margin-inline: auto; }
  .hero__cta { justify-content: center; }
  .hero__art { max-width: 720px; margin-inline: auto; justify-self: stretch; }
}

@media (max-width: 620px) {
  /* The composition is detail-dense, so on phones it bleeds to the viewport
     edges rather than shrinking the cards into illegibility. Cancelling the
     gutter (rather than an eyeballed %) is what keeps it exactly viewport-wide
     — a percentage overshoots on one side and reintroduces sideways scroll. */
  .hero__art {
    max-width: none;
    margin-inline: calc(-1 * var(--gutter));
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   PROBLEM / TRUST
   ══════════════════════════════════════════════════════════════════════════ */

/* Bands are tints, not lids. They stay translucent so the ambient field below
   shows through: an opaque band would seal the page and leave every
   backdrop-filter on it with nothing to blur. */
.band { background: rgba(255, 253, 247, .72); border-block: 1px solid var(--line); }
.band--sage { background: rgba(241, 246, 231, .72); border-block: 1px solid var(--s200); }
.band--cream { background: rgba(249, 249, 237, .72); border-block: 1px solid var(--line); }

/* ══════════════════════════════════════════════════════════════════════════
   AUDIENCES — two doors under one headline: clinics still on paper, and
   clinics on software that slows them down. Each card is drawn as the thing
   that visitor uses today, so they can find their own door before reading a
   word: a register page (punched holes, ruled field) and an app window (title
   bar dots, clean pane). The two chrome strips share a height so the headings
   line up across the pair.
   ══════════════════════════════════════════════════════════════════════════ */
#audiences .section-title { text-wrap: balance; }
.aud { margin-top: var(--sp-3xl); align-items: stretch; }
.aud__card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: var(--r-2xl);
  overflow: hidden;
  box-shadow: var(--sh-lift);
}
.aud__chrome {
  display: flex;
  align-items: center;
  gap: var(--sp-xs);
  height: 40px;
  padding: 0 var(--sp-xl);
  flex-shrink: 0;
}
.aud__chrome i { width: 8px; height: 8px; border-radius: 50%; }
.aud__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: var(--sp-xl) var(--sp-2xl) var(--sp-2xl);
}

/* Paper: holes punched along the top, a double header rule, a faint ruled field. */
.aud__card--paper { background: var(--p100); }
.aud__card--paper .aud__chrome {
  justify-content: space-evenly;
  border-bottom: 3px double rgba(207, 111, 47, .32);
}
.aud__card--paper .aud__chrome i {
  width: 10px; height: 10px;
  background: var(--p200);
  box-shadow: inset 0 1px 2px rgba(174, 86, 26, .22);
}
.aud__card--paper .aud__body {
  background: repeating-linear-gradient(to bottom, transparent 0 31px, rgba(237, 223, 186, .5) 31px 32px);
}

/* App: a window, with neutral title-bar dots and a clean white pane. */
.aud__card--app { background: var(--n100); border-color: var(--n200); }
.aud__card--app .aud__chrome { background: var(--n150); border-bottom: 1px solid var(--n200); }
.aud__card--app .aud__chrome i { background: var(--n300); }

.aud__head { display: flex; align-items: center; gap: var(--sp-s); }
/* Tag colours clear 4.5:1 on their own card (p800 on p100 4.8:1, s700 on white 6.4:1). */
.aud__tag {
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--p800);
}
.aud__card--app .aud__tag { color: var(--s700); }
/* One hook line per card. It carries the card, so it steps up to h3 now that
   there's no paragraph beneath it. */
.aud__title { margin-top: var(--sp-l); font-size: var(--fs-h3); text-wrap: balance; }
/* The wins sit under a dashed rule. The titles are written to the same length,
   so the two lists start level. */
.aud__list {
  list-style: none;
  margin: var(--sp-xl) 0 0;
  padding: var(--sp-xl) 0 0;
  border-top: 1px dashed var(--line);
  display: grid;
  gap: var(--sp-s);
}
.aud__list li {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  gap: var(--sp-s);
  align-items: start;
  font-size: var(--fs-m);
}
.aud__list .icon { color: var(--s600); margin-top: 2px; }

/* ══════════════════════════════════════════════════════════════════════════
   MODULES  (replaces the old Features / Insights / Communication sections)
   ══════════════════════════════════════════════════════════════════════════ */

.mods { align-items: start; margin-top: var(--sp-3xl); }

.mods__list { display: flex; flex-direction: column; gap: 2px; }
.mods__btn {
  display: grid;
  grid-template-columns: 1.25rem minmax(0, 1fr);
  align-items: center;
  gap: var(--sp-m);
  width: 100%;
  text-align: left;
  padding: var(--sp-m) var(--sp-l);
  border: 0;
  border-radius: var(--r-l);
  background: transparent;
  cursor: pointer;
  font: inherit;
  color: var(--muted);
  transition: background var(--motion-base) var(--ease-standard),
              color var(--motion-base) var(--ease-standard);
}
.mods__btn:hover { background: rgba(255, 255, 255, .55); color: var(--ink); }
.mods__btn[aria-selected="true"] {
  background: rgba(255, 255, 255, .55);
  backdrop-filter: blur(16px) saturate(160%);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, .6);
  color: var(--ink);
  box-shadow: var(--sh-lift);
}
/* The border only appears on the selected row, so every row reserves its width
   up front and the rail does not shift by 2px as you move down it. */
.mods__btn { border: 1px solid transparent; }
.mods__name { font-weight: 600; font-size: var(--fs-m); }
/* Only the open row explains itself, so the rail stays a scannable list. */
.mods__desc {
  grid-column: 2;
  display: none;
  margin: var(--sp-xs) 0 0;
  font-size: var(--fs-s);
  color: var(--muted);
}
.mods__btn[aria-selected="true"] .mods__desc { display: block; }

/* Panels are stacked in one grid cell rather than toggled with display:none,
   so the tallest screen sets the height once and the stage never jumps as you
   move down the rail. */
.mods__stage { display: grid; }
.mods__panel {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity var(--motion-base) var(--ease-standard),
              transform var(--motion-base) var(--ease-standard),
              visibility 0s linear var(--motion-base);
}
.mods__panel[data-active] {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}
.mods__note { margin-top: var(--sp-m); font-size: var(--fs-xs); color: var(--muted); }

/* Stand-in chrome for a product screenshot: a window bar plus a few rows. */
.shot {
  background: rgba(255, 253, 247, .58);
  backdrop-filter: blur(20px) saturate(170%);
  -webkit-backdrop-filter: blur(20px) saturate(170%);
  border: 1px solid rgba(255, 255, 255, .62);
  border-radius: var(--r-2xl);
  box-shadow: var(--sh-lift);
  overflow: hidden;
}
.shot__bar {
  display: flex;
  align-items: center;
  gap: var(--sp-xs);
  padding: var(--sp-m) var(--sp-l);
  border-bottom: 1px solid rgba(255, 255, 255, .5);
  background: rgba(255, 255, 255, .38);
}
.shot__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--line); }
.shot__title {
  margin-left: var(--sp-s);
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--muted);
}
.shot__body { padding: var(--sp-l); display: grid; gap: var(--sp-s); }
.shot__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-m);
  padding: var(--sp-m);
  border-radius: var(--r-l);
  background: rgba(255, 255, 255, .42);
  font-size: var(--fs-s);
}
.shot__ph {
  display: grid;
  place-items: center;
  min-height: 200px;
  border: 1px dashed var(--line);
  border-radius: var(--r-l);
  color: var(--muted);
  font-size: var(--fs-xs);
}

/* ══════════════════════════════════════════════════════════════════════════
   MODULE SCENES — illustrated panels exported from Figma (design file
   rPjDXi9Av2vXMqyaDu42nb) as PNG, not rebuilt in CSS: the frosted-glass chips
   and the blurred card tray only survive as a flattened render. 2x + 1x files
   via srcset; corners are baked transparent, so no radius or clip here.
   So far: Appointments (node 289:1749), Patient records (node 289:1695).
   ══════════════════════════════════════════════════════════════════════════ */
.scene-img { display: block; width: 100%; height: auto; }

/* ══════════════════════════════════════════════════════════════════════════
   AMBIENT FIELD
   The enabling layer for everything glassy on this page. Frosted glass is not a
   texture you can apply to a flat surface: backdrop-filter blurs whatever sits
   behind an element, so on a uniform cream page it resolves to cream and the
   effect is invisible. This fixed field gives every blur on the page something
   to actually bite on, and it is what makes the nav and the module panels read
   as glass rather than as slightly tinted rectangles.
   ══════════════════════════════════════════════════════════════════════════ */

body { position: relative; }
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(42rem 32rem at 10% 4%,   rgba(236, 166, 109, .20), transparent 64%),
    radial-gradient(38rem 30rem at 92% 26%,  rgba(152, 176, 108, .18), transparent 64%),
    radial-gradient(44rem 34rem at 30% 70%,  rgba(237, 202, 153, .16), transparent 66%),
    radial-gradient(36rem 28rem at 84% 96%,  rgba(172, 191, 136, .16), transparent 64%);
}

/* The product showcase sits on the same dark sage as the closing CTA
   (.cta__box: s700→s800 at 160deg), full-bleed, so the page gets one deep band
   between its cream sections. Everything inside is re-toned for it below. */
#modules {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: linear-gradient(160deg, var(--s700) 0%, var(--s800) 100%);
}
/* A faint in-family lift, so the glass rail still has some variation to
   refract without the band reading as anything but flat dark green. */
#modules::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(34rem 26rem at 78% 30%, rgba(152, 176, 108, .22), transparent 64%),
    radial-gradient(28rem 22rem at 12% 88%, rgba(249, 249, 237, .06), transparent 62%);
}
/* White is scoped to the header, not set on #modules: the envelope and stat
   cards inherit their ink, and would go white-on-white. */
#modules .section-head { color: var(--n100); }
#modules .eyebrow { background: rgba(255, 255, 255, .1); color: var(--p100); }
#modules .eyebrow::before { background: var(--p500); }
#modules .section-sub { color: rgba(255, 255, 255, .88); }

/* Rail, white on sage. Resting labels and the note at .82 clear 4.5:1 on the
   lighter s700 end (4.8:1). */
#modules .mods__btn { color: rgba(255, 255, 255, .82); }
#modules .mods__btn:hover {
  background: rgba(255, 255, 255, .05);
  border-color: rgba(255, 255, 255, .08);
  color: var(--n100);
}
/* The open row is a subtle pane of frosted glass: a white sheen that fades
   across it, an edge that is brighter along the top where the light catches,
   and a soft drop. Saturation stays near 1. The base rule's 160% pumps the
   sage behind it into a flat olive block, which is the opposite of glass. The
   sheen peaks at .12, so the .94 description still clears 4.5:1 at its brightest. */
#modules .mods__btn[aria-selected="true"] {
  background: linear-gradient(135deg, rgba(255, 255, 255, .12) 0%, rgba(255, 255, 255, .04) 100%);
  backdrop-filter: blur(14px) saturate(115%);
  -webkit-backdrop-filter: blur(14px) saturate(115%);
  border-color: rgba(255, 255, 255, .14);
  border-top-color: rgba(255, 255, 255, .26);
  color: var(--n100);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .10),
    0 12px 32px -20px rgba(0, 0, 0, .55);
}
#modules .mods__desc { color: rgba(255, 255, 255, .94); }
#modules .mods__note { color: rgba(255, 255, 255, .82); }

/* The stand-in .shot panels are 58% glass, which turns a muddy green-grey over
   dark sage. Here they go opaque cream, like the envelope and the stat cards. */
#modules .shot { background: var(--p100); border-color: var(--line); }

/* ══════════════════════════════════════════════════════════════════════════
   SCROLL REVEAL
   Cheap, and it stops a long page from arriving all at once. The hidden state
   is scoped to .js-reveal, which the head script sets before first paint, so a
   visitor without JS gets the fully visible page rather than a blank one.
   ══════════════════════════════════════════════════════════════════════════ */

.js-reveal [data-reveal] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 620ms var(--ease-entrance),
              transform 620ms var(--ease-entrance);
}
.js-reveal [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .js-reveal [data-reveal] { opacity: 1; transform: none; transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   SPECIALTY
   ══════════════════════════════════════════════════════════════════════════ */

.spec { align-items: start; }
.spec .section-sub { margin-inline: 0; text-align: left; }

.spec__list { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--sp-s); }
.spec__item {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-m);
  padding: var(--sp-m) 0;
  border-bottom: 1px solid rgba(203, 217, 190, .8);
}
.spec__item:last-child { border-bottom: 0; }
.spec__item b { font-weight: 600; font-size: var(--fs-m); }
.spec__item span { display: block; margin-top: 2px; color: var(--muted); font-size: var(--fs-s); }

/* The roadmap sits apart from the Derma pitch: a visitor from another specialty
   needs to find their answer without reading the Derma list first. */
.spec__next {
  margin-top: var(--sp-4xl);
  padding-top: var(--sp-xl);
  border-top: 1px solid rgba(203, 217, 190, .8);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-m);
}
.spec__next-label {
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--s700);
}
.spec__chips { display: flex; flex-wrap: wrap; gap: var(--sp-s); margin: 0; padding: 0; list-style: none; }
.spec__chip {
  padding: var(--sp-xs) var(--sp-m);
  border-radius: var(--r-pill);
  border: 1px dashed var(--s400);
  color: var(--s700);
  font-size: var(--fs-s);
}
.spec__next-note { flex: 1 1 22rem; margin: 0; color: var(--muted); font-size: var(--fs-s); }

/* ══════════════════════════════════════════════════════════════════════════
   MODULE SCREEN INTERNALS  (stats and the email preview, kept from the
   sections they used to headline)
   ══════════════════════════════════════════════════════════════════════════ */

.stat__label {
  display: flex;
  align-items: center;
  gap: var(--sp-xs);
  font-size: var(--fs-s);
  color: var(--muted);
}
.stat__value {
  margin-top: var(--sp-s);
  font-family: 'Libertinus Serif', Georgia, serif;
  font-size: var(--fs-h3);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.stat__delta { margin-top: var(--sp-xs); font-size: var(--fs-xs); }
.stat__delta--up { color: var(--s700); }
.stat__delta--flat { color: var(--n700); }

/* Sparkline bars — CSS only, no chart library. */
.spark {
  margin-top: var(--sp-m);
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 34px;
}
.spark i {
  flex: 1;
  background: var(--p300);
  border-radius: 2px 2px 0 0;
  display: block;
}
.spark i:last-child { background: var(--p600); }
.spark--sage i { background: var(--s200); }
.spark--sage i:last-child { background: var(--s500); }

/* The envelope preview */
.envelope {
  border: 1px solid var(--line);
  border-radius: var(--r-2xl);
  background: var(--n100);
  box-shadow: var(--sh-lift);
  overflow: hidden;
}
.envelope__bar {
  padding: var(--sp-s) var(--sp-m);
  border-bottom: 1px solid var(--n200);
  font-size: var(--fs-xs);
  color: var(--n700);
  background: var(--n150);
}
.envelope__body { padding: var(--sp-xl); }
.envelope__brand {
  font-family: 'Libertinus Serif', Georgia, serif;
  font-size: var(--fs-h5);
}
.envelope__rule { height: 1px; background: var(--n200); margin-block: var(--sp-m); }
.envelope__line {
  height: 9px;
  border-radius: var(--r-pill);
  background: var(--n150);
  margin-bottom: var(--sp-xs);
}
.envelope__receipt {
  margin-top: var(--sp-m);
  border: 1px dashed var(--line);
  border-radius: var(--r-l);
  padding: var(--sp-m);
  background: var(--paper);
  font-size: var(--fs-s);
}
.envelope__kv {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-m);
  padding-block: 3px;
}
.envelope__kv span { color: var(--muted); }
.envelope__kv b { font-variant-numeric: tabular-nums; font-weight: 600; }

/* ══════════════════════════════════════════════════════════════════════════
   PRICING
   ══════════════════════════════════════════════════════════════════════════ */

/* Two plans: capped so each card stays a readable column, not half the page. */
.price__grid { margin: var(--sp-3xl) auto 0; max-width: 56rem; align-items: start; }
.price {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: var(--sp-2xl) var(--sp-xl);
}
.price--feature {
  background: linear-gradient(180deg, var(--p100) 0%, var(--p200) 100%);
  border-color: var(--p500);
  position: relative;
}
.price__flag {
  position: absolute;
  top: calc(-1 * var(--sp-s));
  left: var(--sp-xl);
  background: var(--p800);
  color: var(--n100);
  font-size: var(--fs-caption);
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  font-weight: 600;
}
.price__tier { font-size: var(--fs-s); font-weight: 600; color: var(--p800); }
.price__amt {
  margin-top: var(--sp-xs);
  font-family: 'Libertinus Serif', Georgia, serif;
  font-size: var(--fs-h3);
  line-height: 1.1;
}
.price__amt small { font-family: 'Inter', sans-serif; font-size: var(--fs-m); color: var(--n600); }
.price__for { margin-top: var(--sp-xs); color: var(--muted); font-size: var(--fs-s); }
.price__list { margin-top: var(--sp-l); display: grid; gap: var(--sp-xs); font-size: var(--fs-s); }
.price__list li { display: flex; align-items: flex-start; gap: var(--sp-xs); }
.price__list .icon { width: 18px; height: 18px; color: var(--s600); margin-top: 2px; }
.price .btn { margin-top: var(--sp-xl); width: 100%; }
.price__spacer { flex: 1; }
/* The licence unit (doctor) and what's free (staff) — the line clinics ask about first. */
.price__seat {
  margin-top: var(--sp-m);
  padding: var(--sp-xs) var(--sp-s);
  border-radius: var(--r-m);
  background: var(--p100);
  color: var(--muted);
  font-size: var(--fs-s);
}
.price--feature .price__seat { background: var(--paper); }
.price__list-head { font-weight: 600; color: var(--ink); }
.price__list .price__ai { color: var(--p700); }
.price__note {
  margin: var(--sp-xl) auto 0;
  max-width: 40rem;
  text-align: center;
  color: var(--muted);
  font-size: var(--fs-s);
}

/* ══════════════════════════════════════════════════════════════════════════
   FAQ
   ══════════════════════════════════════════════════════════════════════════ */

.faq { margin-top: var(--sp-3xl); border: 1px solid var(--line); border-radius: var(--r-2xl); overflow: hidden; background: var(--paper); }
.faq details { border-bottom: 1px solid var(--line); }
.faq details:last-child { border-bottom: 0; }
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-m);
  padding: var(--sp-l) var(--sp-xl);
  cursor: pointer;
  font-weight: 500;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "";
  width: 10px; height: 10px;
  border-right: 1.5px solid var(--p700);
  border-bottom: 1.5px solid var(--p700);
  transform: rotate(45deg);
  flex-shrink: 0;
  transition: transform var(--motion-base) var(--ease-standard);
}
.faq details[open] summary::after { transform: rotate(-135deg); }
.faq p { padding: 0 var(--sp-xl) var(--sp-l); color: var(--muted); font-size: var(--fs-s); }

/* ══════════════════════════════════════════════════════════════════════════
   CTA + FOOTER
   ══════════════════════════════════════════════════════════════════════════ */

.cta__box {
  border-radius: var(--r-2xl);
  /* s700→s800, not s600→s800: white text over the s600 stop is only 4.19:1,
     so the lighter start failed AA before a single character was placed. */
  background: linear-gradient(160deg, var(--s700) 0%, var(--s800) 100%);
  color: var(--n100);
  padding: clamp(2.5rem, 1.5rem + 4vw, 4.5rem) var(--gutter);
  text-align: center;
  box-shadow: var(--sh-modal);
}
.cta__box h2 { font-size: var(--fs-h2); }
.cta__box p {
  margin-top: var(--sp-m);
  margin-inline: auto;
  max-width: 42rem;
  color: rgba(255, 255, 255, .88);
  font-size: var(--fs-l);
}
.cta__box .btn {
  margin-top: var(--sp-2xl);
  background: var(--p100);
  border-color: var(--p100);
  color: var(--s800);
  font-weight: 600;
}
.cta__box .btn:hover { background: var(--n100); border-color: var(--n100); }

.footer {
  background: var(--paper);
  border-top: 1px solid var(--line);
  padding-block: var(--sp-4xl) var(--sp-xl);
}
.footer__top {
  /* Grid tracks come from .grid-12 (see HTML): brand col-6, link cols col-3
     each. Rounds the previous 1.4:1:1 ad-hoc ratio to clean 12-col fractions
     (50:25:25) — close to the original balance, exact on the grid. */
  column-gap: var(--sp-2xl);
  row-gap: var(--sp-2xl);
}
.footer__logo img { height: 28px; width: auto; display: block; }
.footer__tag { margin-top: var(--sp-m); color: var(--muted); font-size: var(--fs-s); max-width: 26ch; }
.footer__h {
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--n600);
}
.footer__list { margin-top: var(--sp-m); display: grid; gap: var(--sp-xs); font-size: var(--fs-s); }
.footer__list a { color: var(--n700); }
.footer__list a:hover { color: var(--p700); }
.footer__bottom {
  margin-top: var(--sp-3xl);
  padding-top: var(--sp-l);
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-m);
  flex-wrap: wrap;
  font-size: var(--fs-xs);
  color: var(--n600);
}
/* Big tonal wordmark closing the page, as the emails end (EmailFooterWordmark).
   The SVG clips its own letters at the baseline, so sitting it flush on the
   footer's bottom edge (no bottom padding) reads as cropped by the page. Its
   letters are p300 (#EDDFBA) on the paper footer: a texture, not a second logo. */
.footer:has(.footer__wordmark) { padding-bottom: 0; }
.footer__wordmark { margin-top: var(--sp-3xl); }
.footer__wordmark img { display: block; width: 100%; height: auto; }

/* ══════════════════════════════════════════════════════════════════════════
   RESPONSIVE — mobile-up overrides.
   Breakpoints are content-driven, not device-driven: each one is where a
   specific grid stops fitting.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Grid system: tablet tier (899px down to 620px) — 12 → 8 columns.
   Spans are re-declared, not scaled: 12→8 isn't an integer ratio (5/12 has
   no equivalent whole span at 8), so each tier states its own layout intent
   rather than deriving one from the other. Nav collapses to the hamburger
   here too, and the module rail folds onto the shared tier instead of its own
   1000px breakpoint. */
@media (max-width: 900px) {
  .nav__links, .nav__login { display: none; }
  .nav__toggle { display: inline-flex; }

  .grid-12 { grid-template-columns: repeat(8, minmax(0, 1fr)); }
  .col-3, .col-4      { grid-column: span 4; }  /* quarters/thirds -> half */
  .col-5, .col-6, .col-7 { grid-column: span 8; }  /* asymmetric splits -> stack */
  .col-8, .col-9, .col-12 { grid-column: span 8; }

  .cards-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* No hover on touch, so the rail becomes a scrollable row of chips. */
  .mods__list {
    flex-direction: row;
    overflow-x: auto;
    gap: var(--sp-xs);
    padding-bottom: var(--sp-s);
    margin-bottom: var(--sp-l);
  }
  .mods__btn { width: auto; flex: 0 0 auto; grid-template-columns: auto; }
  .mods__btn .icon, .mods__desc,
  .mods__btn[aria-selected="true"] .mods__desc { display: none; }

  .footer__top { grid-template-columns: 1fr 1fr; }
}

/* ── Grid system: mobile tier (<620px) — 8 → 4 columns, everything stacks. */
@media (max-width: 620px) {
  .grid-12 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-12 { grid-column: span 4; }

  .cards-3, .cards-2 { grid-template-columns: minmax(0, 1fr); }
  .footer__top { grid-template-columns: 1fr; gap: var(--sp-xl); }
  .hero__cta .btn { width: 100%; }
  .footer__bottom { justify-content: flex-start; }
}

/* Print: the page is occasionally saved as PDF for pitch decks. */
@media print {
  .nav, .nav__mobile, .hero__cta { display: none; }
  body { background: #fff; }
  .card { box-shadow: none; }
}

/* ── Section heads without an eyebrow: the title leads, so no top gap. ── */
.section-head > .section-title:first-child { margin-top: 0; }

/* ══════════════════════════════════════════════════════════════════════════
   FOOTER — just the links and the copyright line: no logo, tagline, column
   headings or dividers (the cropped wordmark at the foot carries the brand).
   All eleven links flow down three equal columns (4 · 4 · 3); the two lists
   stay in the markup but dissolve into the one grid. Copyright sits under it.
   ══════════════════════════════════════════════════════════════════════════ */
.footer { border-top: 0; }
.footer__top {
  display: grid;
  grid-template-columns: repeat(3, max-content);
  grid-template-rows: repeat(4, auto);
  grid-auto-flow: column;
  justify-content: center;   /* the block is centred; each column stays left-aligned */
  column-gap: clamp(2.5rem, 1rem + 6vw, 7rem);
  row-gap: var(--sp-xs);
}
.footer__top > .col-3, .footer__top .footer__list { display: contents; }
.footer__list li { font-size: var(--fs-s); }
.footer__bottom { border-top: 0; padding-top: 0; margin-top: var(--sp-2xl); justify-content: center; text-align: center; }
@media (max-width: 620px) {
  .footer__top { grid-template-columns: repeat(2, max-content); grid-template-rows: repeat(6, auto); }
}

/* FAQ band: no rules across the page above or below it. */
#faq { border-block: 0; }

/* ══════════════════════════════════════════════════════════════════════════
   PHONES (≤620)
   - Header: centred logo + hamburger only ("Book a Demo" moves into the menu).
   - Hero: a single "Book a Demo" under the paragraph ("See the product" goes).
   - Product and FAQ titles take the hero h1 size.
   - The module showcase becomes a TICKER: all seven scenes in one strip that
     crawls left forever. The script at the foot of index-full.html clones the
     seven (aria-hidden) so the strip is two identical halves; the animation
     slides exactly one half, so the loop seam is invisible. Each scene wears its
     module name as the same frosted-glass pill as the desktop rail's open row.
     Touch pauses it; reduced motion turns it into a plain swipeable row.
   ══════════════════════════════════════════════════════════════════════════ */
.mods__panel--clone { display: none; }
@keyframes mods-ticker { to { transform: translateX(-50%); } }
@media (max-width: 620px) {
  /* Header: the logo alone, centred; the demo button lives in the hamburger menu. */
  .nav__inner { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; padding-inline: var(--sp-xs); }  /* even padding so the logo is truly centred */
  .nav__logo { grid-column: 2; }
  .nav__actions { grid-column: 3; justify-self: end; }
  .nav__actions > .btn { display: none; }

  /* Hero: one CTA, Book a Demo, right under the paragraph. */
  .hero__cta .btn--ghost { display: none; }

  /* Section titles match the hero's h1 on a phone. */
  #modules .section-title, #faq .section-title { font-size: var(--fs-hero); }

  #modules .mods__list { display: none; }
  #modules .mods { overflow: hidden; margin-inline: calc(-1 * var(--gutter)); padding-left: var(--gutter); }
  #modules .mods__stage {
    display: flex;
    width: max-content;   /* no padding here: the loop slides exactly half this width */
    animation: mods-ticker 48s linear infinite;
  }
  #modules .mods__stage.is-held { animation-play-state: paused; }
  #modules .mods__panel,
  #modules .mods__panel--clone {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 78vw;
    margin-right: var(--sp-s);   /* margin, not gap: keeps both halves equal */
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: none;
  }
  #modules .mods__panel::after {
    content: attr(data-name);
    margin-top: var(--sp-s);
    padding: 6px 14px;
    border-radius: var(--r-pill);
    font-size: var(--fs-s);
    font-weight: 600;
    color: var(--n100);
    background: linear-gradient(135deg, rgba(255, 255, 255, .12) 0%, rgba(255, 255, 255, .04) 100%);
    backdrop-filter: blur(14px) saturate(115%);
    -webkit-backdrop-filter: blur(14px) saturate(115%);
    border: 1px solid rgba(255, 255, 255, .14);
    border-top-color: rgba(255, 255, 255, .26);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .10), 0 12px 32px -20px rgba(0, 0, 0, .55);
  }
}
@media (max-width: 620px) and (prefers-reduced-motion: reduce) {
  #modules .mods { overflow-x: auto; }
  #modules .mods__stage { animation: none; }
  #modules .mods__panel--clone { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   BREATHING ROOM — a calmer, roomier rhythm. Phones were running at the floor
   of every clamp (20px margins, 56px between sections); these lift them.
   ══════════════════════════════════════════════════════════════════════════ */
.footer { padding-top: var(--sp-5xl); }
.footer__wordmark { margin-top: var(--sp-4xl); }

@media (max-width: 620px) {
  :root {
    --gutter: 1.75rem;       /* 28px side margins, was 20 */
    --section-y: 5.5rem;     /* 88px between sections, was 56 */
  }
  /* Hero: more air above the headline, between its parts, and below the art. */
  .hero { padding-block: var(--sp-4xl) var(--sp-5xl); }
  .hero p { margin-top: var(--sp-xl); line-height: 1.6; }
  .hero__cta { margin-top: var(--sp-3xl); justify-content: center; }
  .hero__cta .btn { width: auto; padding-inline: var(--sp-2xl); }   /* a shorter pill, not full width */
  .hero__art, .hero figure { margin-top: var(--sp-l); }   /* the art carries its own top air */

  /* Titles sit further from what they introduce. */
  #modules .mods, .faq { margin-top: var(--sp-4xl); }

  /* FAQ rows breathe. */
  .faq summary { padding: var(--sp-xl); }
  .faq p { padding: 0 var(--sp-xl) var(--sp-xl); line-height: 1.6; }

  /* Footer: roomier link rows and space before the copyright and wordmark. */
  .footer { padding-top: var(--sp-5xl); }
  .footer__top { row-gap: var(--sp-s); column-gap: var(--sp-3xl); }
  .footer__bottom { margin-top: var(--sp-3xl); }
}


/* Footer social links (landing) — icon row above the copyright. */
.footer__social { display: flex; justify-content: center; gap: 16px; align-items: center; margin: 24px 0 16px; }
.footer__social a { display: inline-flex; color: var(--n700); transition: color .15s ease; }
.footer__social a:hover { color: var(--ink); }

/* Desktop: pin the module showcase and drive it by scroll (JS adds .mods--sticky). */
@media (min-width: 901px) {
  #modules.mods--sticky { height: 480vh; overflow: visible; }
  #modules.mods--sticky > .wrap {
    position: sticky;
    top: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-block: var(--section-y);
    box-sizing: border-box;
  }
}
