/* Lumen Labs — marketing site.
 *
 * The design language is stated once in the product, in src/styles/tokens.css,
 * and mirrored here because the site is a separate build with its own :root.
 * The values below are that file's values, not an approximation of them: a
 * dentist who reads this page and then signs in must not feel they have arrived
 * somewhere else.
 *
 * What the language is. The neutrals are slate rather than grey, because
 * --brand-700 — the navy the two circles of the mark make where they overlap —
 * is #020817, which is exactly the darkest step of the slate ramp. Cooling the
 * greys to match means every surface here is a tint of the brand instead of a
 * wash next to it. Corners are 10px by default rather than the 2px the product
 * inherited from its WPF ancestor. Shadows come in two layers and are tinted
 * with that same navy, because a neutral-black shadow on a slate surface reads
 * as dirt.
 *
 * Where the site departs from the app it is because this is a marketing page
 * and not a dense clinical tool; each departure is argued at the token.
 *
 * Light only, by decision.
 */

:root {
  color-scheme: light;

  /* ---- brand ----
     --brand-500 is the identity colour and stays on the mark and the wordmark,
     which are large enough to carry it. Every filled ask on the page sits on
     --brand-600 instead: white on #0088b0 measures 4.1:1 and this page leans on
     filled buttons for every ask it makes, where white on #0a6d8c is 5.87:1. */
  --brand-200:  #7cc3d9;
  --brand-500:  #0088b0;
  --brand-600:  #0a6d8c;
  --brand-700:  #020817;

  --accent-500: #d6006c;   /* Lumen magenta: focus rings, ticks, active underline */
  --accent-700: #ab0056;   /* the same magenta as a word — 7.3:1 on white */

  /* ---- surfaces ----
     The product's slate ramp, unchanged and stated whole: it is the language,
     and a step missing from the middle of it is a step somebody later invents.
     Each is a perceptible move from the one above, so a surface can sit on
     another without a border between them. --chip and --sunken are the arch's
     two tooth states, set from QuoteBuilder.tsx because framer-motion tweens a
     colour value and cannot read a custom property mid-tween. */
  --bg:      #ffffff;
  --paper:   #f8fafc;
  --paper-2: #f1f5f9;
  --chip:    #e9eef4;
  --sunken:  #dbe3ec;
  --edge:    #cbd5e1;

  /* ---- text ----
     Measured against every surface above: worst case 13.78 / 4.52 / 7.99. The
     old --ink-3 was a warm purple-grey from a palette this product no longer
     has, and it carried real selling copy; --text-2 replaces it everywhere. */
  --text:        #0f172a;
  --text-2:      #55667e;
  --text-header: #334155;

  /* Ink for the navy panels — the stat strip, the case viewer, the closing
     panel — each of which is its own small dark theme. */
  --on-dark:      rgba(255, 255, 255, 0.92);
  --on-dark-2:    rgba(255, 255, 255, 0.75);
  --on-dark-3:    rgba(255, 255, 255, 0.55);
  --on-dark-line: rgba(255, 255, 255, 0.14);

  /* ---- lines & washes ----
     --divider draws structure (section rules, table rows, card edges);
     --stroke draws the edge of something you can press. The split is what keeps
     a control looking like a control on a page made mostly of paper. */
  --divider: rgba(2, 8, 23, 0.09);
  --stroke:  rgba(2, 8, 23, 0.18);
  --brand-tint:  rgba(0, 136, 176, 0.08);

  /* A press darkens rather than dims, because dimming reads as disabled. */
  --brand-fill-hover:  color-mix(in srgb, var(--brand-600) 88%, black);
  --brand-fill-active: color-mix(in srgb, var(--brand-600) 78%, black);

  /* ---- type ----
     The product's filled ramp — 12 / 13 / 14 / 16 / 18 / 20 / 24 / 30 / 38 —
     stated in rem so a reader who has raised their browser's default text size
     keeps that choice. Nothing on the page goes below 12px.

     48 / 60 / 76 continue the same 1.26 ratio the top of the app's ramp already
     uses (24 → 30 → 38). They exist because a marketing headline has to carry a
     whole screen and the app's largest step is a dialog title; they are an
     extension of the scale rather than a second scale. */
  --fs-12: 0.75rem;
  --fs-13: 0.8125rem;
  --fs-14: 0.875rem;
  --fs-16: 1rem;
  --fs-18: 1.125rem;
  --fs-20: 1.25rem;
  --fs-24: 1.5rem;
  --fs-30: 1.875rem;
  --fs-38: 2.375rem;
  --fs-48: 3rem;
  --fs-60: 3.75rem;
  --fs-76: 4.75rem;

  --lh-tight: 1.25;
  --lh: 1.5;

  /* Fluid steps. Both ends of every clamp land on a step of the ramp; only the
     interpolation between them is off-grid, which is what a clamp is for. */
  --fs-hero: clamp(var(--fs-30), 4.6vw + 0.875rem, var(--fs-76));
  --fs-h2:   clamp(var(--fs-24), 1.7vw + 1rem, var(--fs-38));
  --fs-stat: clamp(var(--fs-38), 2.6vw + 1.5rem, var(--fs-60));
  --fs-lede: clamp(var(--fs-16), 0.4vw + 0.9rem, var(--fs-20));

  /* Prose here is 16px where the product's is 13. The ramp is shared; the size
     picked off it is not. The app is a dense clinical tool read at a desk all
     day and 13px is the right density for it. This page is argument, read once,
     often on a phone between patients. Every dense element on it — table cells,
     tiles, chips, captions — stays at the product's 13/14. */
  --font: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
          Roboto, "Helvetica Neue", Arial, sans-serif;

  /* ---- shape ----
     10px is not a new opinion; it is the one the product already had. */
  --radius-xs:   4px;
  --radius-sm:   8px;
  --radius:      10px;
  --radius-lg:   16px;
  --radius-pill: 999px;

  /* ---- elevation ----
     Two layers each: a tight contact shadow that anchors the edge and a wide
     soft one that lifts it, both tinted with the brand navy. --depth4 is the
     same recipe one step further, for the hero stage — the only object on any
     of the three surfaces that has a whole screen to lift off. */
  --depth1: 0 1px 2px rgba(2, 8, 23, 0.06), 0 1px 3px rgba(2, 8, 23, 0.08);
  --depth2: 0 2px 6px rgba(2, 8, 23, 0.06), 0 6px 14px rgba(2, 8, 23, 0.09);
  --depth3: 0 8px 20px rgba(2, 8, 23, 0.10), 0 18px 36px rgba(2, 8, 23, 0.12);
  --depth4: 0 12px 28px rgba(2, 8, 23, 0.12), 0 40px 80px rgba(2, 8, 23, 0.16);

  /* ---- motion ----
     --t for a state change, --t-slow for something arriving. */
  --t:      140ms cubic-bezier(0.2, 0, 0, 1);
  --t-slow: 240ms cubic-bezier(0.16, 1, 0.3, 1);

  /* ---- rhythm & layout ---- */
  --wrap: 1200px;
  --nav-h: 64px;
  --s1:  4px;
  --s2:  8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;
  --s7: 48px;
}

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

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 var(--fs-16)/var(--lh) var(--font);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Display sizes are set light and functional sizes semibold. One rule, and it
   is what keeps a 76px headline from shouting and a 14px label from whispering. */
h1, h2, h3 { margin: 0; line-height: var(--lh-tight); font-weight: 600; }
h1 { font-size: var(--fs-hero); font-weight: 300; letter-spacing: -0.032em; line-height: 1.04; }
h2 { font-size: var(--fs-h2); font-weight: 300; letter-spacing: -0.026em; color: var(--brand-700); text-wrap: balance; }
h3 { font-size: var(--fs-18); letter-spacing: -0.012em; color: var(--text-header); }
p { margin: 0 0 var(--s4); }
img { display: block; max-width: 100%; height: auto; }
em { font-style: normal; color: var(--accent-700); }
::selection { background: var(--accent-500); color: #fff; }

/* The nav is sticky, so an anchor that lands flush with the top of the viewport
   lands underneath it. Every jump target keeps a nav's worth of headroom. */
section[id], #main { scroll-margin-top: calc(var(--nav-h) + 20px); }
#main:focus, #main:focus-visible { outline: none; }

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: clamp(20px, 4vw, 40px); }
.wrap.narrow { max-width: 880px; }
.section { padding-block: clamp(64px, 8vw, 112px); }
/* Section separation is carried by the tint alternating and by the hairline
   every section head draws, so the band needs no border of its own. Two rules
   40px apart is fussiness, not rhythm. */
.band { background: var(--paper); }
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  padding: var(--s3) var(--s5); background: var(--brand-600); color: #fff;
  border-radius: 0 0 var(--radius) 0; font-weight: 600;
}
.skip:focus { left: 0; }

/* The no-JavaScript fallback in index.html. It is never seen with the app
   running, so it only needs to be readable. */
.noscript { max-width: 44rem; margin-inline: auto; padding: var(--s7) clamp(20px, 4vw, 40px); }
.noscript h1 { font-size: clamp(var(--fs-24), 1.4vw + 1.2rem, var(--fs-38)); color: var(--brand-700); margin-bottom: var(--s5); }
.noscript p { color: var(--text-2); }

/* One focus ring for the whole page. The magenta clears 3:1 on every light
   surface here; on the navy panels it would vanish, so those flip it to white
   where they are defined. */
a:focus-visible, button:focus-visible, summary:focus-visible,
input:focus-visible, [tabindex]:focus-visible {
  outline: 3px solid var(--accent-500);
  outline-offset: 2px;
}

/* ── motion ─────────────────────────────────────────────────────────────
   .anim is put on <html> by main.tsx, and only when the browser has an
   IntersectionObserver and the reader has not asked for less motion. Nothing
   below can strand content the observer never reports on: with no class on the
   root — no JavaScript, no observer, reduced motion — every .reveal is simply
   visible, and the hero never waits for an observer at all.

   The rise is 240ms rather than the 620ms it used to be. A long reveal was the
   fashion of an earlier page; at the language's entrance duration the content
   is simply there by the time the eye reaches it. */
html.anim .reveal { opacity: 0; transform: translateY(14px); }
html.anim .reveal.in {
  opacity: 1; transform: none;
  transition: opacity var(--t-slow), transform var(--t-slow);
}
html.anim .delay1.in { transition-delay: 60ms; }
html.anim .delay2.in { transition-delay: 120ms; }
html.anim .delay3.in { transition-delay: 180ms; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  html.anim .reveal { opacity: 1; transform: none; }
  *, *::before, *::after { transition-duration: 1ms !important; animation-duration: 1ms !important; }
}

/* ── nav ────────────────────────────────────────────────────────────── */
.nav {
  position: sticky; top: 0; z-index: 40;
  background: rgba(255, 255, 255, 0.72);
  backdrop-filter: saturate(1.7) blur(16px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--t), background var(--t), box-shadow var(--t);
}
.nav.scrolled {
  border-bottom-color: var(--divider);
  background: rgba(255, 255, 255, 0.94);
  box-shadow: var(--depth1);
}
.navInner {
  display: flex; align-items: center; gap: clamp(12px, 3vw, 40px);
  max-width: var(--wrap); margin-inline: auto;
  min-height: var(--nav-h);
  padding: var(--s3) clamp(20px, 4vw, 40px);
}
.brand {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: var(--fs-20); font-weight: 700; letter-spacing: -0.03em;
  color: var(--brand-500); text-decoration: none; white-space: nowrap;
}
.mark { position: relative; width: 25px; height: 21px; flex: 0 0 auto; }
.mark::before, .mark::after {
  content: ''; position: absolute; width: 16px; height: 16px; border-radius: 50%;
  mix-blend-mode: multiply;
}
.mark::before { left: 0; top: 0; background: var(--brand-500); }
.mark::after  { left: 9px; top: 5px; background: var(--accent-500); }
.navLinks { display: flex; gap: clamp(16px, 2vw, 28px); margin-left: auto; }
.navLinks a {
  position: relative; color: var(--text-2); text-decoration: none;
  font-size: var(--fs-14); font-weight: 500;
  padding-block: 4px; transition: color var(--t);
}
.navLinks a::after {
  content: ''; position: absolute; left: 0; right: 100%; bottom: 0; height: 2px;
  background: var(--accent-500); transition: right var(--t);
}
.navLinks a:hover { color: var(--brand-600); }
.navLinks a:hover::after { right: 0; }
.navCta { display: flex; gap: var(--s2); }

/* ── buttons ────────────────────────────────────────────────────────── */
.btn {
  --pad-y: 11px; --pad-x: 18px;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  padding: var(--pad-y) var(--pad-x);
  border: 1px solid transparent; border-radius: var(--radius);
  font-size: var(--fs-14); font-weight: 600; font-family: inherit; line-height: 1.2;
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: background var(--t), color var(--t), border-color var(--t),
              transform var(--t), box-shadow var(--t);
}
.btn.sm { --pad-y: 9px; --pad-x: 14px; font-size: var(--fs-13); }
.btn.lg { --pad-y: 15px; --pad-x: 26px; font-size: var(--fs-16); }
.btn.full { width: 100%; }
.btn:active { transform: translateY(1px); }

.primary { background: var(--brand-600); color: #fff; box-shadow: var(--depth1); }
.primary:hover { background: var(--brand-fill-hover); box-shadow: var(--depth2); }
.primary:active { background: var(--brand-fill-active); }
.ghost { background: var(--bg); border-color: var(--stroke); color: var(--text-header); }
.ghost:hover { border-color: var(--brand-200); color: var(--brand-600); background: var(--bg); }
.accent { background: var(--accent-500); color: #fff; box-shadow: var(--depth1); }
.accent:hover { background: var(--accent-700); box-shadow: var(--depth2); }
.arrow { transition: transform var(--t); }
.ghost:hover .arrow { transform: translateX(3px); }

/* ── hero ───────────────────────────────────────────────────────────── */
/* The headline runs the width of the page and the case sits under it at full
   width, rather than the two sharing a split. The product's whole claim is that
   you see the design first, so the design is the hero image and not a thumbnail
   beside the copy. */
.hero { position: relative; overflow: hidden; padding-block: clamp(36px, 5vw, 68px) clamp(56px, 7vw, 96px); }
.heroGlow {
  position: absolute; inset: -34% -10% auto -10%; height: 680px; pointer-events: none;
  background:
    radial-gradient(44% 58% at 26% 38%, rgba(0, 136, 176, 0.13), transparent 70%),
    radial-gradient(38% 52% at 76% 22%, rgba(214, 0, 108, 0.08), transparent 70%);
}
.heroInner { position: relative; display: grid; gap: clamp(32px, 4.5vw, 56px); }
.kicker {
  display: inline-flex; align-items: center; gap: var(--s2);
  margin: 0 0 var(--s5); padding: 6px 14px 6px 10px;
  border-radius: var(--radius-pill); background: var(--brand-tint);
  font-size: var(--fs-12); font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--brand-600);
}
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent-500); }
.hero h1 { color: var(--brand-700); max-width: 18ch; }
.heroFoot {
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(28px, 4vw, 64px); align-items: end; margin-top: clamp(24px, 3vw, 36px);
}
.lede { font-size: var(--fs-lede); color: var(--text-2); max-width: 44ch; text-wrap: pretty; }
.ctaRow { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: var(--s6); }

/* Three claims as ruled rows rather than a bulleted list. On a page with no
   testimonials to fill it, the second hero column has to earn its width with
   structure instead of decoration. */
.tickList { list-style: none; margin: 0; padding: 0; }
.tickList li {
  position: relative; padding: var(--s3) 0 var(--s3) 28px;
  border-top: 1px solid var(--divider);
  font-size: var(--fs-14); color: var(--text-2);
}
.tickList li::before {
  content: ''; position: absolute; left: 2px; top: 1.35em;
  width: 11px; height: 6px; border-left: 2px solid var(--accent-500);
  border-bottom: 2px solid var(--accent-500); transform: rotate(-45deg);
}
.tickList.light li { color: var(--on-dark); border-top-color: var(--on-dark-line); }
.tickList.light li::before { border-color: #fff; }

/* ── the case stage ─────────────────────────────────────────────────── */
/* Control bar, viewport, caption bar — one navy object rather than three
   stacked elements. The panel is the same #020817 the canvas clears to, so the
   mesh appears to float inside a device instead of on a rectangle. */
.stage {
  position: relative; overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--brand-700);
  box-shadow: var(--depth4);
}
.stage :is(a, button):focus-visible { outline-color: #fff; }
.stageBar {
  display: flex; align-items: center; justify-content: center;
  padding: var(--s3);
  border-bottom: 1px solid var(--on-dark-line);
}
.switchTabs {
  display: inline-flex; gap: 2px; padding: 3px;
  background: rgba(255, 255, 255, 0.07); border-radius: var(--radius-pill);
}
.switchTab {
  padding: 7px 16px; border: 0; border-radius: var(--radius-pill);
  background: transparent; color: var(--on-dark-2);
  font: inherit; font-size: var(--fs-13); font-weight: 600; line-height: 1.2;
  cursor: pointer; white-space: nowrap;
  transition: background var(--t), color var(--t);
}
.switchTab:hover { color: #fff; background: rgba(255, 255, 255, 0.08); }
.switchTab.on { background: var(--brand-600); color: #fff; }
.stageFoot {
  padding: var(--s3) var(--s5);
  border-top: 1px solid var(--on-dark-line);
  /* Two lines of room, reserved, so switching case files cannot shuffle the
     page under a reader who is mid-sentence. */
  min-height: calc(2 * var(--lh) * var(--fs-13) + 2 * var(--s3));
}
.stageCaption { margin: 0; font-size: var(--fs-13); line-height: var(--lh); color: var(--on-dark-2); }

/* The height is set here rather than inline so a phone is not handed a 460px
   slab of canvas, and it is viewport-derived rather than content-derived so the
   space is reserved before the mesh arrives and nothing below it moves. The
   frame's border, corner and shadow belong to .stage, which owns them once. */
.viewer {
  --viewer-h: 460px;
  position: relative; height: clamp(300px, 60vw, var(--viewer-h));
  background: var(--brand-700);
  /* Vertical drags stay with the page: a finger that lands on the viewer while
     scrolling must not trap the reader. Turning the case is a sideways drag. */
  touch-action: pan-y;
}
.viewer canvas { display: block; cursor: grab; }
.viewer canvas:active { cursor: grabbing; }
.viewerHint {
  position: absolute; left: 50%; translate: -50% 0; bottom: 16px; margin: 0;
  font-size: var(--fs-12); font-weight: 500; color: var(--on-dark);
  background: rgba(2, 8, 23, 0.55); padding: 7px 15px; border-radius: var(--radius-pill);
  border: 1px solid var(--on-dark-line);
  backdrop-filter: blur(8px); pointer-events: none;
}
.loader { display: grid; place-items: center; gap: var(--s2); color: var(--on-dark-2); font-size: var(--fs-13); }
.ring { width: 44px; height: 44px; transform: rotate(-90deg); }
.ringBg, .ringFg { fill: none; stroke-width: 3; }
.ringBg { stroke: rgba(255, 255, 255, 0.16); }
.ringFg { stroke: var(--accent-500); stroke-dasharray: 100; stroke-linecap: round; transition: stroke-dashoffset 0.2s; }
.viewerMsg {
  position: absolute; inset: 0; display: grid; place-content: center; justify-items: center;
  gap: var(--s2); padding: var(--s5); text-align: center;
  color: var(--on-dark-2); font-size: var(--fs-14); line-height: var(--lh);
}
.viewerMsg strong { font-weight: 600; color: #fff; }
.viewerMsg p { margin: 0; max-width: 32ch; }

/* ── the stat strip ─────────────────────────────────────────────────── */
/* Navy, immediately under the hero. It is the first dark thing on the page and
   it bookends with the closing panel, which is the other one. */
.metrics { background: var(--brand-700); color: #fff; padding-block: clamp(36px, 5vw, 56px); }
.metricGrid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(20px, 3vw, 32px); }
.metric { display: flex; flex-direction: column; gap: var(--s2); }
.metric:not(:last-child) { padding-right: clamp(16px, 2.4vw, 32px); border-right: 1px solid var(--on-dark-line); }
.mNum {
  font-size: var(--fs-stat); font-weight: 300; line-height: 1;
  letter-spacing: -0.04em; color: #fff; font-variant-numeric: tabular-nums;
}
.mLabel { font-size: var(--fs-13); line-height: 1.45; color: var(--on-dark-2); }

/* ── section heads ──────────────────────────────────────────────────── */
/* One editorial device, used by every section: a hairline, an eyebrow on it,
   the title left and the lede set against it on the right. It is what gives the
   page a rhythm you can feel while scrolling past at speed. */
.secHead {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  grid-template-areas: "eyebrow ." "title lede";
  column-gap: clamp(24px, 4vw, 72px);
  border-top: 1px solid var(--divider);
  padding-top: var(--s5);
  margin-bottom: clamp(32px, 4vw, 48px);
}
.eyebrow {
  grid-area: eyebrow;
  margin: 0 0 var(--s3); font-size: var(--fs-12); font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent-700);
}
.secHead h2 { grid-area: title; }
.sectionLede {
  grid-area: lede; align-self: end; margin: 0;
  font-size: var(--fs-16); line-height: var(--lh); color: var(--text-2); text-wrap: pretty;
}
.grid3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(272px, 1fr)); }
.gap { gap: clamp(18px, 2.4vw, 28px); }

.card {
  padding: clamp(20px, 2.4vw, 28px); border: 1px solid var(--divider); border-radius: var(--radius-lg);
  background: var(--bg); box-shadow: var(--depth1);
  transition: border-color var(--t), box-shadow var(--t), transform var(--t);
}
.card:hover { border-color: var(--brand-200); box-shadow: var(--depth2); transform: translateY(-2px); }
.probNo {
  display: block; font-size: var(--fs-30); font-weight: 300; line-height: 1;
  letter-spacing: -0.03em; color: var(--edge); margin-bottom: var(--s4);
  font-variant-numeric: tabular-nums;
}
.prob h3 { color: var(--brand-700); margin-bottom: var(--s2); font-size: var(--fs-18); }
.prob p { color: var(--text-2); font-size: var(--fs-14); line-height: var(--lh); margin: 0; }

.commit { padding-left: var(--s4); border-left: 2px solid var(--accent-500); }
.commit h3 { color: var(--brand-700); margin-bottom: 6px; font-size: var(--fs-16); }
.commit p { color: var(--text-2); font-size: var(--fs-14); line-height: var(--lh); margin: 0; }

/* ── steps ──────────────────────────────────────────────────────────── */
/* An index rather than a stack of cards: rule, number, title, body. The
   numbered circles this page used to have were the last piece of Material
   left on it. */
.steps { list-style: none; margin: 0; padding: 0; }
.steps li {
  display: grid;
  grid-template-columns: 44px minmax(0, 15rem) minmax(0, 1fr);
  gap: 0 clamp(16px, 2.4vw, 40px); align-items: start;
  padding: clamp(20px, 2.6vw, 30px) var(--s3);
  margin-inline: calc(var(--s3) * -1);
  border-top: 1px solid var(--divider);
  border-radius: var(--radius);
  transition: background var(--t);
}
.steps li:hover { background: var(--paper); }
.stepNo {
  font-size: var(--fs-13); font-weight: 700; letter-spacing: 0.08em;
  color: var(--brand-600); font-variant-numeric: tabular-nums; padding-top: 0.28em;
}
.steps h3 { font-size: var(--fs-20); font-weight: 600; color: var(--brand-700); letter-spacing: -0.018em; }
.stepBody p { color: var(--text-2); max-width: 62ch; margin: 0; }
.stepBody p + p { margin-top: var(--s3); }
.meta { font-size: var(--fs-13); color: var(--text-2); }
.meta.strong { color: var(--brand-600); font-weight: 600; }

/* An ask in the middle of the page, so a reader convinced by the four steps
   does not have to scroll past five more sections to find one. */
.inlineCta {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s4) var(--s5);
  margin-top: clamp(32px, 4vw, 44px); padding: clamp(20px, 2.6vw, 28px);
  border: 1px solid var(--divider); border-radius: var(--radius-lg); background: var(--paper);
}
.inlineCtaText { margin: 0; margin-right: auto; font-size: var(--fs-20); font-weight: 300; letter-spacing: -0.02em; color: var(--brand-700); }
.inlineCtaNote { flex-basis: 100%; margin: 0; font-size: var(--fs-13); color: var(--text-2); }

/* ── comparison ─────────────────────────────────────────────────────── */
.tableWrap {
  border: 1px solid var(--divider); border-radius: var(--radius-lg);
  background: var(--bg); box-shadow: var(--depth2); overflow: hidden;
}
.tableScroll { overflow-x: auto; }
.compare { width: 100%; border-collapse: collapse; min-width: 600px; }
.compare th, .compare td {
  padding: var(--s4) var(--s5); text-align: left;
  font-size: var(--fs-14); line-height: var(--lh); border-bottom: 1px solid var(--divider);
}
.compare thead th {
  padding-block: var(--s3);
  font-size: var(--fs-12); text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--text-2); font-weight: 700; background: var(--paper-2);
}
/* The column being argued for is tinted its whole height and capped with the
   brand, so a reader who scans one column knows which one they are in. */
.compare thead .usCol {
  color: var(--brand-600); background: var(--brand-tint);
  box-shadow: inset 0 2px 0 var(--brand-600);
}
.compare tbody th { font-weight: 600; color: var(--text-header); width: 26%; }
.compare td { color: var(--text-2); }
.compare .us { color: var(--text); font-weight: 500; background: var(--brand-tint); }
.compare tbody tr:last-child th, .compare tbody tr:last-child td { border-bottom: 0; }
.tableHint { display: none; margin: var(--s3) 2px 0; font-size: var(--fs-13); color: var(--text-2); }

/* ── work-type tiles ────────────────────────────────────────────────── */
/* Nine restorations in a three-by-three block: the catalogue reads as complete
   because it resolves into a rectangle rather than trailing off. The icon box
   is the product's own tile geometry — 52px box, 38px glyph — so a dentist who
   has seen the app recognises these before reading them. */
.typeGrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s3); }
.typeTile {
  display: flex; align-items: center; gap: var(--s4); padding: var(--s3) var(--s4);
  border: 1px solid var(--divider); border-radius: var(--radius); background: var(--bg);
  transition: border-color var(--t), transform var(--t), box-shadow var(--t);
}
.typeTile:hover { border-color: var(--brand-200); transform: translateY(-2px); box-shadow: var(--depth2); }
.typeIcon { display: grid; place-items: center; flex: 0 0 auto; width: 52px; height: 52px; border-radius: var(--radius); }
.typeIcon img { width: 38px; height: 38px; }
.typeText { flex: 1 1 auto; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px var(--s3); min-width: 0; }
.typeLabel { font-size: var(--fs-16); font-weight: 600; color: var(--text); line-height: var(--lh-tight); }
.typePrice { font-size: var(--fs-13); color: var(--text-2); font-variant-numeric: tabular-nums; margin-left: auto; white-space: nowrap; }
.matNote {
  margin-top: clamp(24px, 3vw, 32px); padding: var(--s5);
  border: 1px solid var(--divider); border-left: 3px solid var(--accent-500);
  background: var(--bg); border-radius: 0 var(--radius) var(--radius) 0;
}
.matNote p { margin: 0; color: var(--text-2); font-size: var(--fs-14); line-height: var(--lh); }
.matNote strong { color: var(--brand-700); }

/* ── quote builder ──────────────────────────────────────────────────── */
/* Two panels in one sheet: the arch you press on white, the quote it produces
   on paper. The tint is doing the work a heading would otherwise have to. */
.quote {
  display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  border: 1px solid var(--divider); border-radius: var(--radius-lg);
  background: var(--bg); box-shadow: var(--depth3); overflow: hidden;
}
.quotePicker { padding: clamp(20px, 2.8vw, 32px); }
.quotePanel {
  display: flex; flex-direction: column;
  padding: clamp(20px, 2.8vw, 32px);
  background: var(--paper); border-left: 1px solid var(--divider);
}
.quoteStep {
  display: flex; align-items: center; gap: var(--s3); margin: 0 0 var(--s4);
  font-size: var(--fs-12); font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-2);
}
.quoteStep span {
  display: grid; place-items: center; width: 20px; height: 20px; border-radius: var(--radius-xs);
  background: var(--brand-600); color: #fff; font-size: var(--fs-12); letter-spacing: 0;
}
.quoteStep + .quoteStep, .archWrap + .quoteStep { margin-top: var(--s6); }

.workRow { display: flex; flex-wrap: wrap; gap: 6px; }
.workChip {
  display: inline-flex; align-items: center; gap: var(--s2); padding: 6px 14px 6px 6px;
  border: 1px solid var(--stroke); border-radius: var(--radius-pill); background: var(--bg);
  font: inherit; font-size: var(--fs-13); font-weight: 600; color: var(--text-header); cursor: pointer;
  transition: border-color var(--t), color var(--t), background var(--t), transform var(--t);
}
.workChip:hover { border-color: var(--brand-200); transform: translateY(-1px); }
.workChip.on { color: #fff; }
.workChip.on.onLight { color: var(--text); }

/* The exocad glyphs are solid white, so they need their work-type colour behind
   them or they disappear on a white chip. */
.chipIcon {
  display: grid; place-items: center; flex: 0 0 auto;
  /* One step down the radius scale from the 52px tiles in the gallery, which is
     what keeps a 26px box and a 52px box looking like the same object. */
  width: 26px; height: 26px; border-radius: var(--radius-sm);
}
.chipIcon img { width: 19px; height: 19px; }
.workChip.on .chipIcon { background: rgba(255, 255, 255, 0.28) !important; }
.workChip.on.onLight .chipIcon { background: rgba(2, 8, 23, 0.16) !important; }

.archWrap { margin-top: var(--s1); display: grid; place-items: center; }
.arch { width: 100%; max-width: 400px; height: auto; }
.tooth { stroke: var(--edge); stroke-width: 2.5; cursor: pointer; }
.tooth:focus-visible { stroke: var(--accent-500); stroke-width: 5; outline: none; }
.toothNo { fill: var(--text-2); font-weight: 600; pointer-events: none; }
.toothNo.on { fill: #fff; }
.toothNo.onLight { fill: var(--text); }

.quoteEmpty { font-size: var(--fs-14); color: var(--text-2); line-height: var(--lh); margin: 0 0 auto; }
.quoteList {
  list-style: none; margin: 0 0 auto; padding: 0; display: flex; flex-direction: column;
  max-height: 250px; overflow-y: auto;
}
.quoteList li {
  display: grid; grid-template-columns: 8px 30px 1fr auto 24px; align-items: center; gap: var(--s2);
  padding: var(--s2) 0; border-bottom: 1px solid var(--divider); font-size: var(--fs-14);
}
.qDot { width: 8px; height: 8px; border-radius: 50%; }
.qTooth { font-weight: 700; color: var(--brand-600); font-variant-numeric: tabular-nums; }
.qWork { color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qPrice { color: var(--text); font-variant-numeric: tabular-nums; }
.qRemove {
  border: 0; background: none; color: var(--text-2); font-size: var(--fs-18);
  cursor: pointer; line-height: 1; border-radius: var(--radius-xs); transition: color var(--t);
}
.qRemove:hover { color: var(--accent-700); }

.speedRow { display: flex; gap: 6px; margin: var(--s5) 0 var(--s4); }
.speedChip {
  flex: 1; display: flex; flex-direction: column; gap: 2px; padding: var(--s3) var(--s3);
  border: 1px solid var(--stroke); border-radius: var(--radius); background: var(--bg);
  font: inherit; cursor: pointer; text-align: left;
  transition: border-color var(--t), background var(--t), box-shadow var(--t);
}
.speedChip:hover { border-color: var(--brand-200); }
.speedChip.on { border-color: var(--brand-600); background: var(--brand-tint); box-shadow: inset 0 0 0 1px var(--brand-600); }
.sLabel { font-size: var(--fs-13); font-weight: 700; color: var(--text); }
.sDays { font-size: var(--fs-12); color: var(--text-2); }
.sAdd { font-size: var(--fs-12); color: var(--accent-700); font-weight: 600; }

.quoteTotal {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--s3);
  padding-top: var(--s4); border-top: 1px solid var(--divider);
}
.quoteTotal span { font-size: var(--fs-13); color: var(--text-2); }
.quoteTotal strong {
  font-size: var(--fs-48); font-weight: 300; letter-spacing: -0.035em;
  color: var(--brand-700); font-variant-numeric: tabular-nums; line-height: 1.1;
}
.quoteNote { font-size: var(--fs-12); color: var(--text-2); margin: var(--s2) 0 var(--s4); line-height: 1.5; }
.quoteClear {
  margin-top: var(--s3); border: 0; background: none; color: var(--text-2);
  font: inherit; font-size: var(--fs-13); cursor: pointer; text-decoration: underline;
  border-radius: var(--radius-xs); transition: color var(--t);
}
.quoteClear:hover { color: var(--accent-700); }

/* Three notes under the builder: the same hairline the section heads use, so
   the terms read as footnotes to the quote rather than three more cards. */
.terms { margin-top: clamp(32px, 4vw, 48px); }
.term { border-top: 1px solid var(--divider); padding-top: var(--s4); }
.term h3 { color: var(--brand-700); margin-bottom: 6px; font-size: var(--fs-16); }
.term p { color: var(--text-2); font-size: var(--fs-14); line-height: var(--lh); margin: 0; }

/* ── faq ────────────────────────────────────────────────────────────── */
.faq { border: 1px solid var(--divider); border-radius: var(--radius-lg); background: var(--bg); box-shadow: var(--depth1); overflow: hidden; }
.faq details { border-bottom: 1px solid var(--divider); }
.faq details:last-child { border-bottom: 0; }
.faq summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  padding: var(--s5); cursor: pointer; list-style: none;
  font-size: var(--fs-16); font-weight: 600; color: var(--text); transition: background var(--t);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '+'; font-size: var(--fs-24); font-weight: 300; color: var(--accent-500);
  transition: transform var(--t); line-height: 1;
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq summary:hover { background: var(--paper); }
.faq p { margin: 0; padding: 0 var(--s5) var(--s5); color: var(--text-2); max-width: 68ch; }

/* ── final cta ──────────────────────────────────────────────────────── */
.cta { position: relative; overflow: hidden; background: var(--brand-700); color: #fff; padding-block: clamp(64px, 8vw, 104px); }
/* The same two brand hues as the hero glow, on the other end of the page and on
   the other ground — so the page closes where it opened. */
.cta::before {
  content: ''; position: absolute; inset: -40% -10% auto -10%; height: 640px; pointer-events: none;
  background:
    radial-gradient(42% 60% at 22% 30%, rgba(0, 136, 176, 0.30), transparent 70%),
    radial-gradient(36% 52% at 82% 18%, rgba(214, 0, 108, 0.18), transparent 70%);
}
.cta :is(a, button, input):focus-visible { outline-color: #fff; }
.ctaGrid { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 430px); gap: clamp(32px, 5vw, 72px); align-items: start; }
.cta h2 { color: #fff; margin-bottom: var(--s4); }
.ctaLede { font-size: var(--fs-lede); color: var(--on-dark); max-width: 40ch; margin-bottom: var(--s6); text-wrap: pretty; }

.contactForm {
  display: flex; flex-direction: column; gap: var(--s3);
  padding: clamp(20px, 3vw, 28px);
  background: rgba(255, 255, 255, 0.07); border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: var(--radius-lg); backdrop-filter: blur(8px);
}
.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-size: var(--fs-13); font-weight: 500; color: var(--on-dark); }
.field input {
  padding: 12px 14px; border: 1px solid rgba(255, 255, 255, 0.26); border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.10); color: #fff; font-size: var(--fs-16); font-family: inherit;
  transition: border-color var(--t), background var(--t);
}
.field input::placeholder { color: var(--on-dark-3); }
.field input:focus { border-color: #fff; background: rgba(255, 255, 255, 0.16); }
.formNote { font-size: var(--fs-13); color: var(--on-dark-2); margin: 2px 0 0; line-height: var(--lh); }
.formNote a { color: #fff; }
/* A mailto: hand-off is silent when it works and silent when it fails, so the
   form says out loud what it just did and leaves the address in reach. */
.formSent {
  margin: 0; padding: var(--s3) var(--s4); border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.12); border: 1px solid rgba(255, 255, 255, 0.26);
  font-size: var(--fs-13); color: #fff; line-height: var(--lh);
}
.formSent a { color: #fff; }

/* ── footer ─────────────────────────────────────────────────────────── */
.footer { padding-block: clamp(48px, 6vw, 72px) var(--s6); background: var(--bg); }
.footInner {
  display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1.1fr);
  gap: clamp(28px, 4vw, 56px);
}
.footBrand { margin: 0 0 var(--s1); font-size: var(--fs-18); }
.footHead {
  margin: 0 0 var(--s3); font-size: var(--fs-12); font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-2);
}
.small { font-size: var(--fs-13); color: var(--text-2); margin: 0; }
.footLinks { display: flex; flex-direction: column; gap: var(--s2); }
.footLinks a { color: var(--text-2); text-decoration: none; font-size: var(--fs-14); transition: color var(--t); }
.footLinks a:hover { color: var(--brand-600); }
.footContact { display: flex; flex-direction: column; gap: var(--s3); align-items: flex-start; }
.footMail { color: var(--brand-600); text-decoration: none; font-size: var(--fs-16); font-weight: 600; }
.footMail:hover { text-decoration: underline; }
.social { display: flex; gap: var(--s4); }
.social a { font-size: var(--fs-14); color: var(--text-2); text-decoration: none; transition: color var(--t); }
.social a:hover { color: var(--accent-700); }
.footBottom {
  display: flex; flex-wrap: wrap; gap: var(--s3) var(--s5); align-items: center; justify-content: space-between;
  margin-top: clamp(36px, 4vw, 52px); padding-top: var(--s5); border-top: 1px solid var(--divider);
}
.footLegal { display: flex; flex-wrap: wrap; gap: var(--s5); }
.footLegal a { font-size: var(--fs-13); color: var(--text-2); text-decoration: none; }
.footLegal a:hover { color: var(--brand-600); text-decoration: underline; }

/* ── narrow ─────────────────────────────────────────────────────────── */
@media (max-width: 1040px) {
  .typeGrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 940px) {
  .heroFoot, .ctaGrid, .secHead { grid-template-columns: 1fr; }
  .secHead { grid-template-areas: "eyebrow" "title" "lede"; }
  .sectionLede { margin-top: var(--s4); max-width: 52ch; }
  .navLinks { display: none; }
  .navCta { margin-left: auto; }
  .lede { max-width: none; }
  .footInner { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .steps li { grid-template-columns: 34px minmax(0, 1fr); }
  .stepBody { grid-column: 2; margin-top: var(--s2); }
}

@media (max-width: 860px) {
  .metricGrid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s5); }
  .metric:not(:last-child) { padding-right: 0; border-right: 0; }
  .quote { grid-template-columns: 1fr; }
  .quotePanel { border-left: 0; border-top: 1px solid var(--divider); }
  .quoteList { max-height: none; }
}

@media (max-width: 700px) {
  /* The table still scrolls sideways rather than being torn into cards, so it
     keeps its row and column semantics; it just says so. */
  .tableHint { display: block; }
  .compare th, .compare td { padding: var(--s3) var(--s4); font-size: var(--fs-13); }
}

/* Phone. The nav is the tightest row on the page: brand plus two buttons will
   not fit 360px, so sign-in steps back to the footer and the account button —
   the reason the page exists — keeps its place. */
@media (max-width: 600px) {
  .navCta .ghost { display: none; }
  .brand { font-size: var(--fs-18); }
  .btn.sm { --pad-x: 12px; }
  .btn.lg { --pad-y: 14px; --pad-x: 20px; font-size: var(--fs-14); }
  .ctaRow { gap: var(--s2); }
  .ctaRow .btn { flex: 1 1 100%; }
  .switchTabs { width: 100%; }
  .switchTab { flex: 1; padding: 8px 6px; }
  .stageBar { padding: var(--s2); }
  .stageFoot { padding: var(--s3) var(--s4); }
  .inlineCta .btn { width: 100%; }
  .faq summary { padding: var(--s4); }
  .faq p { padding: 0 var(--s4) var(--s4); }
  .footInner { grid-template-columns: 1fr; gap: var(--s6); }
  .footBottom { margin-top: var(--s6); }
}

@media (max-width: 480px) {
  /* Two columns of tiles leave about seventy pixels for "Primary telescopic
     crown". One column gives every restoration its name on one line. */
  .typeGrid { grid-template-columns: 1fr; }
  .speedRow { flex-direction: column; }
}
