  :root {
    color-scheme: light;
    --ink: #0B1220;
    --ink-dim: #59616E;
    --muted: #8A929E;
    --bg: #ffffff;
    --bg-alt: #F7F9FC;
    --accent: #2F7BFF;
    --accent-dark: #1E63E6;
    --border: #E6E9EE;
    --border-soft: #ECEEF2;
    --good: #0B7C6F;
    --good-bg: #E7F8EF;
    --good-dot: #12B76A;
    --soon: #B4610C;
    --soon-bg: #FFF3E3;
    --bad-dot: #E5484D;
    --hero-glow: #EAF2FF;
  }
  * { box-sizing: border-box; }
  html { scroll-behavior: smooth; }
  body {
    margin: 0;
    font-family: 'Onest', -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
    color: var(--ink);
    background: var(--bg);
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
  }
  button { font: inherit; cursor: pointer; border: none; background: none; padding: 0; }
  input, textarea { font: inherit; color: inherit; }
  ::placeholder { color: #9AA3B2; }
  .wrap { max-width: 1080px; margin: 0 auto; padding: 0 24px; }

  /* Intro reveal: the logo draws itself in, then the whole veil fades away.
     Founder hotfix (2026-07-30): this used to auto-play via animation-name
     applied at parse time, which raced real page readiness -- on a slow
     load or a throttled CPU, the browser could still be laying out/painting
     while the 2.4s clock was already ticking, so by the time anything was
     actually visible the intro had already flashed past or finished. Fixed
     by gating every animation-name behind an `.intro-play` class that a
     tiny script below only adds once document.fonts is ready and a couple
     of animation frames have actually painted -- the intro's visible start
     is now synced to real readiness, not to style-parse time. Before that
     class lands, everything sits in its own explicit first-frame state
     (opacity/transform/stroke-dashoffset set directly, not implied by a
     keyframe's 0%) so there is nothing to flash. */
  @keyframes introVeil { 0%, 60% { opacity: 1; visibility: visible; } 100% { opacity: 0; visibility: hidden; } }
  @keyframes introLogo { 0% { opacity: 0; transform: scale(.94); } 45% { opacity: 1; transform: scale(1); } 100% { opacity: 1; transform: scale(1.04); } }
  /* The name means "to flow efficiently" -- the mark performs that rather
     than decorating it. wmGlowUp: FLOXIENT rises from dim to a brief bright
     peak (with a soft blue glow) then settles to normal reading brightness --
     once, on load, never a bounce/pulse. ribbonShimmer: a slow diagonal
     light sweep confined to the ribbon's own silhouette via a mask-image of
     the ribbon PNG's alpha channel, so the "light" only ever travels along
     the ribbon lines, never as a generic glow box. */
  @keyframes wmGlowUp {
    0% { opacity: .14; filter: brightness(.55) drop-shadow(0 0 0 rgba(47,123,255,0)); }
    70% { opacity: 1; filter: brightness(1.18) drop-shadow(0 0 16px rgba(47,123,255,.5)); }
    100% { opacity: 1; filter: brightness(1) drop-shadow(0 0 0 rgba(47,123,255,0)); }
  }
  @keyframes ribbonShimmer { 0% { background-position: 0% 0%; } 100% { background-position: 100% 100%; } }
  .intro-veil {
    position: fixed;
    inset: 0;
    z-index: 100;
    background: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    opacity: 1;
    visibility: visible;
  }
  .intro-veil.intro-play { animation: introVeil 2.7s cubic-bezier(.4, 0, .2, 1) forwards; }
  /* prefers-reduced-motion (and the sessionStorage repeat-visit skip, same
     mechanism): an instant, elegant fade instead of the multi-second draw. */
  .intro-veil.intro-reduced { transition: opacity .3s ease; opacity: 0; visibility: hidden; }
  .intro-logo { opacity: 0; transform: scale(.94); }
  .intro-veil.intro-play .intro-logo { animation: introLogo 2.2s cubic-bezier(.2, .8, .25, 1) forwards; }
  .intro-veil.intro-reduced .intro-logo { opacity: 1; transform: none; }
  .intro-logo .wordmark { display: inline-flex; align-items: center; font-family: 'Roboto Slab', Georgia, serif; font-weight: 800; text-transform: uppercase; letter-spacing: .01em; color: #101828; font-size: 48px; line-height: 1; }
  .intro-logo .wm-text { display: inline-block; opacity: .14; filter: brightness(.55); }
  .intro-veil.intro-play .intro-logo .wm-text { animation: wmGlowUp 2.3s cubic-bezier(.3, .6, .25, 1) forwards; animation-delay: .25s; }
  .intro-veil.intro-reduced .intro-logo .wm-text { opacity: 1; filter: none; }
  /* Reusable wordmark X: an <img> of the isolated ribbon cutout plus a
     shimmer overlay masked to its exact silhouette. em-sized, so header,
     footer, mini-chrome, and the intro veil each get a proportional mark
     just by inheriting a different font-size -- no per-context pixel values. */
  .wm-x { position: relative; display: inline-block; height: 1.32em; margin: 0 -.12em; vertical-align: middle; }
  .wm-x .wm-ribbon { display: block; height: 100%; width: auto; }
  .wm-x .wm-shimmer {
    position: absolute;
    inset: 0;
    background: linear-gradient(115deg, transparent 35%, rgba(255,255,255,.85) 50%, transparent 65%);
    background-size: 280% 280%;
    -webkit-mask: url('/assets/ribbon-x.png') center / 100% 100% no-repeat;
    mask: url('/assets/ribbon-x.png') center / 100% 100% no-repeat;
    mix-blend-mode: screen;
    opacity: .5;
    animation: ribbonShimmer 6s linear infinite;
    pointer-events: none;
  }
  @media (prefers-reduced-motion: reduce) { .wm-x .wm-shimmer { animation: none; background-position: 50% 50%; } }

  header.site {
    position: sticky;
    top: 0;
    z-index: 20;
    background: rgba(255, 255, 255, .85);
    backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--border-soft);
  }
  header.site .wrap { height: 64px; display: flex; align-items: center; justify-content: space-between; }
  /* text-decoration:none is load-bearing: .brand is an <a> in the header and
     footer (it links home from the topic pages), and without this the
     browser's default anchor underline draws straight through the
     wordmark, ribbon and all. */
  .brand { text-decoration: none; display: inline-flex; align-items: center; font-family: 'Roboto Slab', Georgia, serif; font-weight: 800; text-transform: uppercase; letter-spacing: .01em; color: #101828; font-size: 21px; line-height: 1; }
  nav.site { display: flex; align-items: center; gap: 26px; }
  nav.site a { color: var(--ink-dim); text-decoration: none; font-size: 14px; font-weight: 500; }
  nav.site a:hover { color: var(--accent-dark); }
  nav.site a.nav-cta {
    display: inline-flex;
    align-items: center;
    height: 36px;
    padding: 0 15px;
    border-radius: 9px;
    background: var(--accent);
    color: #fff;
    font-size: 13.5px;
    font-weight: 600;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .16), 0 2px 8px rgba(47, 123, 255, .26);
  }
  nav.site a.nav-cta:hover { background: var(--accent-dark); }

  .hero {
    position: relative;
    overflow: hidden;
    background: radial-gradient(1200px 500px at 50% -10%, var(--hero-glow) 0%, rgba(234, 242, 255, 0) 60%), var(--bg);
  }
  .hero .wrap { max-width: 840px; padding: 88px 24px 64px; text-align: center; }
  /* Founder hotfix (2026-07-30): this used to be a fixed height:30px pill,
     which is fine for one line but has nowhere for a second line to go --
     at phone widths the copy wraps and the wrapped line just overflows the
     pill's box (and its rounded background), leaving the dot looking
     stranded next to text that no longer visually belongs to it. Padding
     instead of a fixed height lets the pill grow to fit 1 or 2 lines;
     align-items:flex-start (rather than center) keeps the dot pinned to
     the *first* line instead of drifting to the vertical middle of a now-
     taller two-line block; the small margin-top on .dot nudges it back
     down to that first line's optical center. text-align:center is
     inherited by .kicker-text so a wrapped second line centers under the
     first rather than wrapping ragged-left. */
  .kicker {
    display: inline-flex;
    align-items: flex-start;
    gap: 8px;
    padding: 7px 16px;
    border-radius: 999px;
    background: var(--hero-glow);
    color: var(--accent-dark);
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.4;
    text-align: center;
    margin-bottom: 22px;
  }
  .kicker .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); flex: none; margin-top: 6px; }
  .hero h1 { margin: 0; font-size: 56px; line-height: 1.04; letter-spacing: -.035em; font-weight: 800; color: var(--ink); }
  .hero p.sub { margin: 22px auto 0; max-width: 600px; font-size: 18px; color: var(--ink-dim); }
  .cta-row { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-top: 32px; }
  .btn {
    display: inline-flex;
    align-items: center;
    height: 48px;
    padding: 0 26px;
    border-radius: 11px;
    font-weight: 600;
    text-decoration: none;
    font-size: 15px;
    cursor: pointer;
    border: 1px solid transparent;
  }
  .btn-primary { background: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(16, 24, 40, .18), 0 6px 18px rgba(47, 123, 255, .3); }
  .btn-primary:hover { background: var(--accent-dark); }
  .btn-ghost { background: #fff; color: #344054; border-color: var(--border); padding: 0 24px; }
  .btn-ghost:hover { border-color: var(--accent); color: var(--accent-dark); }
  .trust-row { margin-top: 40px; display: flex; justify-content: center; gap: 28px; flex-wrap: wrap; color: var(--muted); font-size: 13px; font-weight: 500; }
  .trust-row span { display: inline-flex; align-items: center; gap: 7px; }

  section { padding: 72px 0; }
  section.alt { background: var(--bg-alt); border-top: 1px solid var(--border-soft); border-bottom: 1px solid var(--border-soft); }
  h2 { margin: 0; font-size: 32px; font-weight: 800; letter-spacing: -.02em; text-align: center; color: var(--ink); }
  p.section-lead { max-width: 680px; margin: 14px auto 40px; text-align: center; font-size: 16px; color: var(--ink-dim); }

  .problem-answer { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
  .pa-card { background: var(--bg); border: 1px solid var(--border); border-radius: 16px; padding: 26px; box-shadow: 0 1px 2px rgba(16, 24, 40, .04); }
  .pa-card.answer { background: linear-gradient(180deg, #F5F9FF, #fff); border-color: #D3E2FF; }
  .pa-card .tag { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; margin-bottom: 14px; }
  .pa-card.problem .tag { color: #B42318; }
  .pa-card.answer .tag { color: var(--good); }
  .pa-card .tag .dot { width: 8px; height: 8px; border-radius: 50%; }
  .pa-card.problem .tag .dot { background: var(--bad-dot); }
  .pa-card.answer .tag .dot { background: var(--good-dot); }
  .pa-card ul { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 10px; font-size: 14.5px; }
  .pa-card.problem ul { color: #475467; }
  .pa-card.answer ul { color: #344054; }

  .table-scroll { overflow-x: auto; background: var(--bg); border: 1px solid var(--border); border-radius: 16px; box-shadow: 0 1px 3px rgba(16, 24, 40, .05); }
  table.compare { border-collapse: collapse; width: 100%; min-width: 820px; font-size: 13px; }
  table.compare th, table.compare td { padding: 11px 16px; text-align: left; vertical-align: top; }
  table.compare thead th { background: #FAFBFC; font-size: 11px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
  table.compare thead th.us { color: var(--accent-dark); }
  table.compare tbody tr { border-top: 1px solid var(--border-soft); }
  table.compare td.feature { color: #101828; font-weight: 500; }
  table.compare td.alt { color: #98A2B3; white-space: nowrap; }
  table.compare td.us { white-space: nowrap; }
  .pill { display: inline-flex; align-items: center; height: 22px; padding: 0 10px; border-radius: 7px; font-size: 12px; font-weight: 700; }
  .pill.built { background: var(--good-bg); color: var(--good); }
  .pill.soon { background: var(--soon-bg); color: var(--soon); }
  .pill-detail { display: block; font-size: 11px; color: #98A2B3; margin-top: 2px; }
  p.table-note { max-width: 760px; margin: 20px auto 0; text-align: center; font-size: 13.5px; color: var(--muted); }

  /* Desktop table sub-header rows: one per role group (clinician/front
     desk/biller/owner/coming-next), so a long table scans as five short
     ones instead of one wall of 28 rows. */
  table.compare tr.group-header td { background: #F5F7FA; font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); padding-top: 10px; padding-bottom: 10px; border-top: none; }
  table.compare tr.group-header:first-child td { padding-top: 11px; }

  /* Mobile card layout (<=720px, see media query below): the desktop table
     is hidden entirely rather than horizontally scrolled -- a 5-column
     table has no readable narrow form, so this is a genuinely different
     layout, not a squeeze of the same one. Each role group is a native
     <details> (no JS needed to expand/collapse), each feature a stacked
     card. */
  #feature-cards { display: none; }
  .feature-group { border: 1px solid var(--border); border-radius: 12px; margin-bottom: 10px; background: var(--bg); overflow: hidden; }
  .feature-group summary { padding: 13px 16px; font-size: 13px; font-weight: 700; color: #101828; cursor: pointer; list-style: none; display: flex; align-items: center; justify-content: space-between; }
  .feature-group summary::-webkit-details-marker { display: none; }
  .feature-group summary::after { content: '+'; font-size: 16px; color: var(--muted); font-weight: 400; }
  .feature-group[open] summary::after { content: '\2212'; }
  .feature-group summary .count { font-weight: 500; color: var(--muted); font-size: 12px; margin-left: 6px; }
  .feature-card { padding: 12px 16px; border-top: 1px solid var(--border-soft); }
  .feature-card .feature-card-name { font-size: 13.5px; font-weight: 600; color: #101828; margin-bottom: 6px; }
  .feature-card .feature-card-compare { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: 12px; color: #98A2B3; margin-top: 6px; }

  .pillar-strip { display: flex; justify-content: center; flex-wrap: wrap; gap: 10px; margin: 0 auto 40px; }
  .pillar-chip { display: inline-flex; align-items: center; height: 34px; padding: 0 16px; border-radius: 999px; background: var(--bg-alt); border: 1px solid var(--border); color: var(--ink-dim); font-size: 13.5px; font-weight: 600; }
  .roles-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
  .role-card { background: var(--bg); border: 1px solid var(--border); border-radius: 16px; padding: 20px; box-shadow: 0 1px 2px rgba(16, 24, 40, .04); }
  .role-badge { display: inline-flex; align-items: center; height: 24px; padding: 0 11px; border-radius: 7px; background: var(--hero-glow); color: var(--accent-dark); font-size: 12.5px; font-weight: 700; margin-bottom: 14px; }
  .role-widget { border: 1px solid var(--border-soft); border-radius: 12px; padding: 12px 14px; margin-bottom: 10px; }
  .role-widget:last-child { margin-bottom: 0; }
  .role-widget-title { font-size: 13.5px; font-weight: 700; color: #101828; display: flex; align-items: center; gap: 7px; }
  .role-widget-body { font-size: 13px; color: var(--ink-dim); margin-top: 3px; }
  .role-widget.doc-flag { background: #FFF8F7; border-color: #FBD9D6; }
  .red-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--bad-dot); flex: none; }

  .moat-grid { display: grid; grid-template-columns: 1.2fr 1fr; gap: 40px; align-items: start; }
  .moat-list { display: flex; flex-direction: column; gap: 18px; }
  .moat-item { display: flex; gap: 14px; }
  .moat-item .n { flex: none; width: 30px; height: 30px; border-radius: 9px; background: var(--hero-glow); color: var(--accent-dark); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 14px; }
  .moat-item .title { font-size: 15px; font-weight: 700; color: #101828; margin-bottom: 2px; }
  .moat-item .body { font-size: 14px; color: var(--ink-dim); }
  .credibility { background: #0B1220; border-radius: 16px; padding: 26px; color: #C7D0DE; }
  .credibility h3 { margin: 0 0 12px; font-size: 14px; font-weight: 700; color: #fff; }
  .credibility p { margin: 0; font-size: 14px; line-height: 1.6; }


  .program-card {
    background: linear-gradient(160deg, #F5F9FF, #fff 60%);
    border: 1px solid #D3E2FF;
    border-radius: 20px;
    padding: 40px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 40px;
    align-items: start;
    box-shadow: 0 2px 20px rgba(47, 123, 255, .08);
  }
  .program-card h2 { text-align: left; color: #0B1220; }
  .spots-badge { display: inline-flex; align-items: center; height: 26px; padding: 0 11px; border-radius: 999px; background: var(--accent); color: #fff; font-size: 12px; font-weight: 700; margin-bottom: 14px; }
  .program-card > div:first-child p { margin: 12px 0 18px; font-size: 15px; color: #59616E; }
  .perks { display: flex; flex-direction: column; gap: 11px; }
  .perks .perk { display: flex; gap: 10px; align-items: flex-start; font-size: 14.5px; color: #344054; }
  .perks .perk svg { flex: none; margin-top: 1px; }

  .signup-panel { background: var(--bg); border: 1px solid var(--border); border-radius: 16px; padding: 26px; box-shadow: 0 1px 3px rgba(16, 24, 40, .05); }
  .signup-panel h3 { margin: 0 0 4px; font-size: 16px; font-weight: 700; color: #101828; }
  .signup-panel .hint { font-size: 13px; color: var(--muted); margin-bottom: 16px; }
  form.signup { display: flex; flex-direction: column; gap: 11px; }
  form.signup label { display: flex; flex-direction: column; gap: 5px; font-size: 12.5px; font-weight: 600; color: #667085; }
  form.signup label .req { color: var(--bad-dot); }
  form.signup input, form.signup textarea {
    padding: 0 12px;
    height: 40px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: #fff;
    font-size: 14px;
    outline: none;
  }
  form.signup textarea { height: auto; min-height: 64px; padding: 10px 12px; resize: vertical; }
  form.signup input:focus, form.signup textarea:focus { border-color: #9CC4FF; box-shadow: 0 0 0 3px rgba(47, 123, 255, .12); }
  form.signup .btn-primary { justify-content: center; height: 44px; margin-top: 4px; }
  #signup-status { font-size: 12.5px; font-weight: 500; color: #B42318; }
  .signup-success { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 26px 8px; gap: 12px; }
  .signup-success .check {
    width: 52px; height: 52px; border-radius: 14px; background: var(--good-bg); color: var(--good-dot);
    display: flex; align-items: center; justify-content: center;
  }
  .signup-success .title { font-size: 17px; font-weight: 700; color: #101828; }
  .signup-success .body { font-size: 14px; color: #667085; }
  .hidden { display: none !important; }

  footer.site { border-top: 1px solid var(--border-soft); }
  footer.site .wrap { padding: 36px 24px; display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
  footer.site .note { font-size: 13px; color: #98A2B3; }

  @media (max-width: 720px) {
    .hero h1 { font-size: 38px; }
    .problem-answer, .program-card, .moat-grid, .roles-grid { grid-template-columns: 1fr; }
    nav.site { gap: 14px; }
    nav.site a:not(.nav-cta) { display: none; }
    /* The 5-column comparison table has no readable narrow form -- below
       this width it's replaced entirely by stacked, collapsible cards
       (#feature-cards) rather than left to horizontally scroll. */
    #feature-table-wrap { display: none; }
    #feature-cards { display: block; }
  }

  /* Product tour: one 45s CSS animation cycle, 9 scenes x 5s, shared by every
     animated element via animation-delay. See design-handoffs/handoff-tour
     README for the full engine explanation. Do not shorten sceneFade's tail
     (12.3%) -- a strictly sequential version flashes the white stage between
     scenes. */
  @keyframes sceneFade{0%{opacity:0}0.5%{opacity:1}11.1%{opacity:1}12.3%{opacity:0}100%{opacity:0}}
  @keyframes dotOn{0%{width:7px;background:#DDE3EA}0.9%{width:22px;background:#2F7BFF}10.2%{width:22px;background:#2F7BFF}11.1%{width:7px;background:#DDE3EA}100%{width:7px;background:#DDE3EA}}
  @keyframes revealIn{0%{opacity:0;transform:translateY(7px)}1.4%{opacity:1;transform:none}100%{opacity:1;transform:none}}
  @keyframes revealPop{0%{opacity:0;transform:scale(.9)}1%{opacity:1;transform:scale(1.03)}1.8%{transform:scale(1)}100%{opacity:1;transform:none}}
  @keyframes revealShake{0%{opacity:0;transform:translateX(0)}0.3%{opacity:1;transform:translateX(-5px)}0.7%{transform:translateX(5px)}1.1%{transform:translateX(-3px)}1.5%{transform:translateX(0)}100%{opacity:1;transform:none}}
  @keyframes revealType{0%{opacity:0;max-width:0}0.25%{opacity:1}1.5%{max-width:100%}100%{opacity:1;max-width:100%}}
  @keyframes revealPulse{0%{opacity:0}0.4%{opacity:1;box-shadow:0 0 0 0 rgba(47,123,255,.45)}2%{box-shadow:0 0 0 13px rgba(47,123,255,0)}2.6%{box-shadow:0 0 0 0 rgba(47,123,255,0)}100%{opacity:1}}

  /* Pause on tap (all devices, via data-tour-paused set by JS) or hover
     (real-mouse desktop only). !important is load-bearing: every
     [data-tour-anim] element sets its animation via the inline
     `style="animation:... infinite both"` shorthand, which implicitly
     declares animation-play-state:running -- and an inline style beats a
     non-important external rule for the same property no matter how
     specific the selector. Without !important this pause never actually
     takes effect (confirmed: computed animation-play-state stayed
     "running" the whole time it was tested). */
  [data-tour-player][data-tour-paused="true"] [data-tour-anim]{animation-play-state:paused !important}
  [data-tour-player] [data-when="paused"]{display:none}
  [data-tour-player][data-tour-paused="true"] [data-when="paused"]{display:inline}
  [data-tour-player][data-tour-paused="true"] [data-when="playing"]{display:none}

  /* The :hover pause is scoped to (hover:hover) and (pointer:fine) -- real
     mouse devices only. Touchscreens report a synthetic, "sticky" :hover
     after a tap (it never gets a mouseleave to clear it), so without this
     guard the tour would silently pause itself on the very first tap and
     never resume via hover alone -- exactly the "hover must never pause it
     on phones" rule this is here to enforce. */
  /* data-tour-hoverlock (added 2026-08-25 with click-to-play): the play button
     sits in the middle of the player, so the cursor that just pressed it is
     still hovering when playback starts -- and this hover rule would pause the
     tour on the very frame it began, which reads as a dead play button. The
     lock suspends hover-pause until the pointer leaves the player once, after
     which hovering behaves exactly as it always did. */
  @media (hover: hover) and (pointer: fine) {
    [data-tour-player]:not([data-tour-hoverlock="true"]):hover [data-tour-anim]{animation-play-state:paused !important}
    [data-tour-player]:not([data-tour-hoverlock="true"]):hover [data-when="paused"]{display:inline}
    [data-tour-player]:not([data-tour-hoverlock="true"]):hover [data-when="playing"]{display:none}
  }

  [data-tour-dot]{width:7px;height:7px;border-radius:4px;background:#DDE3EA;animation:dotOn 45s linear infinite both}
  [data-tour-dot]:focus-visible{outline:2px solid #2F7BFF;outline-offset:3px}

  @media (prefers-reduced-motion: reduce){
    [data-tour-anim]{animation:none !important}
    [data-tour-stage] > *:not(:first-child){display:none}
  }

  /* [data-tour-stage] always clips: without this, any scene whose stacked
     mobile content runs taller than the stage's box (the absolutely
     positioned .tour-scene children don't grow the stage, they just
     overflow its bottom edge) bleeds visually into the caption bar below,
     overlapping the "SCENE N OF 9" label with the previous scene's own
     text. Confirmed happening on scenes 3, 4, and 7 at 375px width before
     this was added. */
  [data-tour-stage]{overflow:hidden}

  /* Below 768px: scene 4's note column switches from typewriter (revealType,
     which relies on overflow:hidden + white-space:nowrap) to a plain fade,
     because a nowrap line has nowhere to go in a narrow column except get
     clipped. The scene also stacks to one column so the note gets full
     width instead of half. Scene 7's phone mockup + copy stack too, and the
     stat grids in scenes 1 and 8 drop from 4 to 2 columns so numbers do not
     get squeezed into unreadably narrow tiles. */
  @media (max-width: 767px){
    [data-tour-typewriter]{animation-name:revealIn !important;white-space:normal !important;max-width:none !important;overflow:visible !important}
    /* !important is load-bearing here: [data-tour-stage]'s own inline
       style sets min-height:330px, and an inline style beats an external
       rule of any specificity (media query or not) for the same property.
       Without !important this override silently never applied -- measured
       scene content at 375px needs up to 441px (scene 4), so the stage
       stayed clamped at 330px and every tall scene bled into the caption
       bar below it. 480px leaves headroom above the tallest measured
       scene for font-rendering variance across real devices. */
    [data-tour-stage]{min-height:480px !important}
    .tour-scene{padding:14px !important}
    .tour-scene-4{grid-template-columns:1fr !important;gap:8px !important}
    .tour-scene-4 .tour-note-col{border-left:none !important;padding-left:0 !important;border-top:1px solid #EEF1F5;padding-top:10px !important;margin-top:2px}
    .tour-scene-7{flex-direction:column !important;gap:16px !important}
    .tour-stat-grid{grid-template-columns:repeat(2,1fr) !important}
  }

  /* Patient app phone tour: a second, independent tour instance -- separate
     data-ptour-* attributes and floxientPatientTour* function names so
     seeking/pausing this one never touches the desktop tour's [data-tour-anim]
     elements (and vice versa). 4 scenes x 5s = 20s cycle, vs. the desktop
     tour's 9 x 5s = 45s -- same per-scene length, fewer scenes. */
  @keyframes ptourFade{0%{opacity:0}1%{opacity:1}25%{opacity:1}27%{opacity:0}100%{opacity:0}}
  @keyframes ptourDotOn{0%{width:7px;background:#DDE3EA}1%{width:22px;background:#1f52c4}24%{width:22px;background:#1f52c4}25%{width:7px;background:#DDE3EA}100%{width:7px;background:#DDE3EA}}

  [data-ptour-player][data-ptour-paused="true"] [data-ptour-anim]{animation-play-state:paused !important}
  [data-ptour-player] [data-when="paused"]{display:none}
  [data-ptour-player][data-ptour-paused="true"] [data-when="paused"]{display:inline}
  [data-ptour-player][data-ptour-paused="true"] [data-when="playing"]{display:none}
  /* data-ptour-hoverlock: see the data-tour-hoverlock note above -- the play
     button sits in the middle of the phone, so the cursor that pressed it is
     still hovering when playback starts. */
  @media (hover: hover) and (pointer: fine) {
    [data-ptour-player]:not([data-ptour-hoverlock="true"]):hover [data-ptour-anim]{animation-play-state:paused !important}
    [data-ptour-player]:not([data-ptour-hoverlock="true"]):hover [data-when="paused"]{display:inline}
    [data-ptour-player]:not([data-ptour-hoverlock="true"]):hover [data-when="playing"]{display:none}
  }
  /* Click to play, same shape as the desktop tour's idle state above. The
     phone tour is simpler: its scenes carry only ptourFade with no inner
     reveal animations, so any moment between 1% (200ms, fully faded in) and
     25% (5000ms, when scene 1 starts leaving) is a clean still frame. */
  [data-ptour-player][data-ptour-idle="true"] [data-ptour-anim]{animation-play-state:paused !important}
  [data-ptour-player] [data-when="idle"]{display:none}
  [data-ptour-player][data-ptour-idle="true"] [data-when="idle"]{display:inline}
  [data-ptour-player][data-ptour-idle="true"] [data-when="playing"],
  [data-ptour-player][data-ptour-idle="true"] [data-when="paused"]{display:none}

  .pt-poster{
    position:absolute;
    inset:0;
    z-index:5;
    display:flex;
    flex-direction:column;
    align-items:center;
    justify-content:center;
    gap:11px;
    padding:18px;
    width:100%;
    text-align:center;
    background:rgba(255,255,255,.58);
    -webkit-backdrop-filter:saturate(.9) blur(.5px);
    backdrop-filter:saturate(.9) blur(.5px);
    cursor:pointer;
  }
  [data-ptour-player]:not([data-ptour-idle="true"]) .pt-poster{display:none}
  .pt-poster .play{
    width:54px;height:54px;border-radius:50%;
    background:#1f52c4;color:#fff;flex:none;
    display:flex;align-items:center;justify-content:center;
    box-shadow:0 2px 6px rgba(16,24,40,.2), 0 10px 26px rgba(31,82,196,.42);
  }
  .pt-poster:hover .play{background:#1b47ab}
  .pt-poster:focus-visible{outline:3px solid #1f52c4;outline-offset:-3px}
  /* The phone screen is dense -- the caption sits directly on top of the
     appointment and balance cards, and plain text over a translucent veil is
     unreadable there (the desktop tour's poster does not need this: its
     caption lands in the empty lower half of a much wider stage). A solid
     chip gives the words their own ground. */
  .pt-poster .cap{
    display:flex;
    flex-direction:column;
    gap:3px;
    background:#fff;
    border:1px solid #E6EAF1;
    border-radius:13px;
    padding:10px 13px;
    box-shadow:0 8px 22px rgba(16,24,40,.16);
  }
  .pt-poster .label{font-size:13.5px;font-weight:700;color:#101828;line-height:1.35;max-width:190px}
  .pt-poster .sub{font-size:11.5px;font-weight:600;color:#667085}
  @media (prefers-reduced-motion: reduce){ .pt-poster{display:none !important} }

  [data-ptour-dot]{width:7px;height:7px;border-radius:4px;background:#DDE3EA;animation:ptourDotOn 20s linear infinite both}
  [data-ptour-dot]:focus-visible{outline:2px solid #1f52c4;outline-offset:3px}
  @media (prefers-reduced-motion: reduce){
    [data-ptour-anim]{animation:none !important}
    [data-ptour-stage] > *:not(:first-child){display:none}
  }

  .pt-frame{width:100%;background:#0B1220;border-radius:44px;padding:12px 9px;box-shadow:0 24px 60px rgba(16,24,40,.22)}
  [data-ptour-stage]{position:relative;width:100%;aspect-ratio:402/874;background:#F7F9FC;border-radius:32px;overflow:hidden}
  .pt-scene{position:absolute;inset:0;display:flex;flex-direction:column;font-family:'Onest',-apple-system,system-ui,sans-serif}
  .pt-island{position:absolute;top:9px;left:50%;transform:translateX(-50%);width:80px;height:21px;background:#0B1220;border-radius:11px}
  .pt-home-bar{position:absolute;bottom:7px;left:50%;transform:translateX(-50%);width:96px;height:4px;border-radius:3px;background:rgba(11,18,32,.28)}

  /* ---- Split-page chrome (2026-08-25) -------------------------------------
     The site was one long page; it is now a short home page plus /compare,
     /trust, /patient-app and /tour. These are the only rules that page split
     needed: everything above is the original single-page stylesheet, now
     shared by every page from one file so the two can never drift. */

  /* Page-top strip on the four topic pages: says where you are and how to
     get back, without a second navigation pattern to learn. */
  .page-intro { padding: 56px 0 0; }
  .page-intro .back { display: inline-flex; align-items: center; gap: 7px; font-size: 13.5px; font-weight: 600; color: var(--ink-dim); text-decoration: none; }
  .page-intro .back:hover { color: var(--accent-dark); }
  .page-intro h1 { margin: 16px 0 0; font-size: 40px; line-height: 1.08; letter-spacing: -.03em; font-weight: 800; text-align: center; }
  .page-intro p.lead { max-width: 680px; margin: 14px auto 0; text-align: center; font-size: 16px; color: var(--ink-dim); }

  /* Closing band on every topic page -- one route back to the one thing the
     site asks for, so a visitor who arrives on /trust from a link is never a
     dead end. */
  .page-cta { border-top: 1px solid var(--border-soft); background: var(--bg-alt); }
  .page-cta .wrap { padding: 48px 24px; text-align: center; }
  .page-cta h2 { font-size: 26px; }
  .page-cta p { max-width: 560px; margin: 12px auto 22px; font-size: 15px; color: var(--ink-dim); }

  /* Home's "read more" links under a section that now continues elsewhere. */
  .more-link { display: inline-flex; align-items: center; gap: 7px; font-size: 14.5px; font-weight: 600; color: var(--accent-dark); text-decoration: none; }
  .more-link:hover { text-decoration: underline; }
  .more-row { text-align: center; margin-top: 30px; }

  footer.site nav { display: flex; gap: 18px; flex-wrap: wrap; }
  footer.site nav a { font-size: 13px; color: var(--ink-dim); text-decoration: none; font-weight: 500; }
  footer.site nav a:hover { color: var(--accent-dark); }

  /* Why-it-is-different on home lost its right-hand column (the "Built like
     medical software" panel moved to /trust), so the two-column grid becomes
     a single full-width list rather than a column of empty space. */
  .moat-grid.solo { grid-template-columns: 1fr; }
  .moat-grid.solo .moat-list { display: grid; grid-template-columns: 1fr 1fr; gap: 22px 40px; }
  @media (max-width: 720px) { .moat-grid.solo .moat-list { grid-template-columns: 1fr; } }

  /* The nine scenes written out on /tour, for anyone who would rather read
     the day than watch it. */
  .scene-list { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; max-width: 860px; margin: 0 auto; }
  .scene-list .scene { display: flex; gap: 13px; align-items: flex-start; background: var(--bg); border: 1px solid var(--border); border-radius: 14px; padding: 15px 17px; }
  .scene-list .scene .n { flex: none; width: 28px; height: 28px; border-radius: 8px; background: var(--hero-glow); color: var(--accent-dark); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 13px; }
  .scene-list .scene .t { font-size: 14.5px; font-weight: 700; color: #101828; line-height: 1.35; }
  @media (max-width: 720px) { .scene-list { grid-template-columns: 1fr; } }

  /* ---- Click to play (2026-08-25) ----------------------------------------
     The tour used to start itself the moment the page parsed. It now holds on
     a still frame of scene 1 until the visitor presses play. Mechanically the
     idle state is the same CSS pause the tap-to-pause state already used
     (animation-play-state, !important because every [data-tour-anim] element
     declares its animation via an inline shorthand -- see the note above the
     tap-to-pause rules); what makes it a *still frame* rather than a blank
     stage is the engine seeking currentTime to a moment inside scene 1 where
     every one of that scene's own reveal animations has finished. Doing that
     from the parser-blocking script at the end of <body> means it lands
     before the first paint, so there is nothing to flash. */
  [data-tour-player][data-tour-idle="true"] [data-tour-anim] { animation-play-state: paused !important; }
  [data-tour-player] [data-when="idle"] { display: none; }
  [data-tour-player][data-tour-idle="true"] [data-when="idle"] { display: inline; }
  [data-tour-player][data-tour-idle="true"] [data-when="playing"],
  [data-tour-player][data-tour-idle="true"] [data-when="paused"] { display: none; }

  .tour-poster {
    position: absolute;
    inset: 0;
    z-index: 5;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 13px;
    padding: 20px;
    width: 100%;
    text-align: center;
    background: rgba(255, 255, 255, .58);
    -webkit-backdrop-filter: saturate(.9) blur(.5px);
    backdrop-filter: saturate(.9) blur(.5px);
    cursor: pointer;
  }
  [data-tour-player]:not([data-tour-idle="true"]) .tour-poster { display: none; }
  .tour-poster .play {
    width: 62px; height: 62px; border-radius: 50%;
    background: var(--accent); color: #fff; flex: none;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 2px 6px rgba(16, 24, 40, .2), 0 10px 28px rgba(47, 123, 255, .42);
  }
  .tour-poster:hover .play { background: var(--accent-dark); }
  .tour-poster:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
  .tour-poster .label { font-size: 15.5px; font-weight: 700; color: #101828; max-width: 340px; line-height: 1.35; }
  .tour-poster .sub { font-size: 12.5px; font-weight: 600; color: #667085; }
  /* Reduced motion already replaces the tour with a static scene 1 (see the
     prefers-reduced-motion block above), so there is nothing to press play
     on -- the poster would only cover the one frame that is being shown. */
  @media (prefers-reduced-motion: reduce) { .tour-poster { display: none !important; } }
