/* Inter — used only inside the dashboard mock-up (the product UI in Figma). */
@font-face {
  font-family: 'Inter';
  src: url('../Assets/Images/landing/dash/Font/Inter_Regular.ttf') format('truetype');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('../Assets/Images/landing/dash/Font/Inter_Medium.ttf') format('truetype');
  font-weight: 500; font-style: normal; font-display: swap;
}

/* ─── Landing page ──────────────────────────────────
   Builds on top of home.css. Variables / fonts / nav
   are inherited.
*/

/* ═══ Hero ════════════════════════════════════════════ */
/* Figma (node 18410:3796): title top y=280, 641 wide, no
   tracking, second line ink @ 64%; lede 24px below, 577 wide;
   button row 40px below the lede. Override home.css's .hero
   padding-bottom so the gap to .header-img is set explicitly
   (220px from the buttons). */
.hero { padding-bottom: 0; }
.hero__title {
  max-width: 641px;
  letter-spacing: 0;
}
.hero__title span {
  display: block;                     /* keep "for healthcare." on its own line at every width */
  color: rgba(10, 38, 51, 0.64);
}
.hero__lede { max-width: 577px; }

@media (min-width: 1101px) {
  .hero { padding-top: 280px; }
}
@media (min-width: 861px) {
  .hero__lede { margin-top: 24px; }
}

/* Button row — 165 × 48 filled + 151 × 48 outline (15px
   label, same size as the filled CTA), 16px gap.
   Visual styling comes from the shared .btn / .btn--lg /
   .btn--filled-dark / .btn--outline classes in home.css. */
.hero__actions {
  margin-top: 40px;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 16px;
}
.hero__cta { width: 165px; }
.hero__cta--waitlist {
  width: 151px;
  height: 48px;
  font-size: 15px;
}

/* ═══ Header image ════════════════════════════════════
   Figma node 18412:4876 (1728 design): photo 1648 × 860,
   32px radius, 40px side inset, 220px below the hero
   buttons. Two cards sit on the photo:
     • .voice-overlay  410 × 249 at (885, 69)   — shared component,
                       animated by [data-voice-overlay] in home.js
     • .triage         456 × 304, 88px from the right / 72px from
                       the bottom — static
   Card POSITIONS are percentages of the photo so they track it;
   card SIZES are fixed design px and step down via --card-scale
   (the photo itself scales fluidly). Below 720px both cards are
   hidden, like the clinics voice overlay.
*/
.header-img {
  --card-scale: 1;
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-top: 220px;              /* 600 (hero buttons bottom) → 820 (photo top) */
  padding: 0 40px;
}

.header-img__media {
  position: relative;
  width: 100%;
  max-width: 1648px;
  margin: 0 auto;
  aspect-ratio: 1648 / 860;
  border-radius: 32px;
  overflow: hidden;
  background: #eef2f4;
}
.header-img__photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  user-select: none;
}

/* ─── Voice card ─────────────────────────────────────
   Figma node 18412:5079: 463 × 249 at (880, 77) in the photo. Base
   glass / waveform styles live in home.css. Four lines (Jiva, John,
   Jiva, John) read out in turn, each with its speaker label in a
   right-aligned column (63px from the card's left edge) and the text
   starting at 75px. The handler in home.js walks the <p> lines and
   announces each finished line — the triage card below listens. */
.header-img__voice {
  top: 8.9535%;                   /* 77 / 860 */
  left: 53.3981%;                 /* 880 / 1648 */
  width: 463px;
  height: 249px;
  padding: 24px;
  transform: scale(var(--card-scale));
  transform-origin: 0 0;
  /* Figma adds a 1px angular-gradient rim at 18% */
  box-shadow: inset 0 0 0 1px rgba(204, 204, 204, 0.18);
}
.header-img__voice .voice-overlay__text {
  font-size: 17px;
  line-height: 21px;
  letter-spacing: 0.5px;
}
.header-img__voice .voice-overlay__line {
  display: flex;
  align-items: flex-start;
  white-space: nowrap;
}
.header-img__voice .voice-overlay__line + .voice-overlay__line { margin-top: 14px; }
.header-img__voice .voice-overlay__who {
  flex: 0 0 39px;                 /* 24 → 63 */
  margin-right: 12px;             /* text starts at 75 */
  text-align: right;
  font-weight: 450;               /* PP NM Regular */
  font-size: 16px;
  line-height: 20px;              /* Figma's label line box; centres it on the text's first line */
}

/* Figma: unread text is the solid #ABB0AC (171, 176, 172) and read text is
   white — not translucent white — so this card runs the engine in colour
   mode (data-voice-color): words stay opaque and js/home.js publishes a
   0..1 reading level in --vp that is blended here. */
.header-img__voice .voice-overlay__word {
  opacity: 1;
  color: color-mix(in srgb, #ffffff calc(var(--vp, 0) * 100%), #abb0ac);
  will-change: color;
  transition: none;
}

/* Figma ("voice dialog"): the waveform no longer has a "Jiva" label — 75 bars
   span x = 29 → 431 of the card, bottom-aligned 24.2px above its edge. */
.header-img__voice .voice-overlay__wave {
  left: 29px;
  right: auto;
  bottom: 24.2px;
}
.header-img__voice .voice-overlay__bars {
  flex: none;
  width: 402.17px;
  height: 26px;
  /* Figma puts the bars at y = 198.8; the browser snaps the box to a whole
     pixel, this hands the 0.2px back. */
  transform: translateY(-0.2px);
}

/* ─── Triage card ────────────────────────────────────
   Translucent 456 × 304 frame around a 436 × 284 white
   panel. Panel content is fixed design px:
     title   17 / 21 Medium, 22px from the panel top
     rows    24px tall, 14px apart, 24px below the title
             label 94 | bars 176 (30 × 2px @ 6px pitch) | 20 | badge 98
     footer  18px connector, 17px loader ring, status text */
.triage {
  position: absolute;
  right: 5.3398%;                 /* 88 / 1648 */
  bottom: 7.4419%;                /* 64 / 860 */
  z-index: 3;
  width: 456px;
  height: 304px;
  padding: 9px;                   /* + 1px border = 10px frame around the panel */
  background: rgba(228, 228, 228, 0.32);
  border: 1px solid rgba(255, 255, 255, 0.19);
  border-radius: 26px;
  transform: scale(var(--card-scale));
  transform-origin: 100% 100%;
  pointer-events: none;
}
.triage__panel {
  position: relative;
  width: 100%;
  height: 100%;
  padding: 21px 23px 0;           /* + 1px border → content at 22 / 24 */
  background: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.19);
  border-radius: 16px;
  box-shadow: 0 4px 4px rgba(0, 0, 0, 0.12);
}

.triage__title {
  font-weight: 500;               /* PP NM Medium */
  font-size: 17px;
  line-height: 21px;
  color: var(--color-ink);
}

.triage__rows {
  margin-top: 24px;
  display: grid;
  row-gap: 14px;
}
.triage__row {
  display: flex;
  align-items: center;
  height: 24px;
  transition: transform 0.55s cubic-bezier(0.32, 0.72, 0, 1);
}
/* State 2: SAH and Meningitis trade places (one row pitch = 24 + 14). */
.triage.is-swapped .triage__row--sah { transform: translateY(38px); }
.triage.is-swapped .triage__row--men { transform: translateY(-38px); }
.triage__label {
  flex: 0 0 94px;
  align-self: flex-start;
  margin-top: 2px;
  font-weight: 400;               /* PP NM Book */
  font-size: 15px;
  line-height: 19px;
  color: var(--color-ink);
  opacity: 0.6;
  white-space: nowrap;
}
.triage__bars {
  flex: none;
  width: 176px;
  height: 20px;
}
/* 30 bars per row. js/landing.js sets `.on` on the first N (N per state) and
   staggers each bar's transition-delay, so bars fill one by one. */
.triage__bars rect {
  fill: rgba(10, 38, 51, 0.15);
  transition: fill 0.22s ease;
}
.triage__bars rect.on { fill: #0b2e3e; }

.triage__badge {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 98px;
  height: 24px;
  margin-left: 20px;
  padding: 2px 10px;
  border-radius: 6px;
  font-weight: 500;
  font-size: 13px;
  line-height: 20px;
  white-space: nowrap;
}
.triage__badge--emergency  { background: #fdebea; color: rgba(180, 35, 24, 0.8); }
.triage__badge--non-urgent { background: #e8fff1; color: rgba(6, 118, 71, 0.87); }
.triage__badge--semi-urgent { background: #efefff; color: rgba(65, 89, 198, 0.88); }

/* Connector (exported SVG, 18 × 1, rotated to run vertically). */
.triage__connector {
  position: absolute;
  left: 27.5px;
  top: 221.5px;
  width: 18px;
  height: 1px;
  transform: rotate(90deg);
}
/* Loader (Figma "loader-6"): a soft gradient arc — strongest at 3 o'clock,
   fading to nothing on the left, sampled from the exported icon — that
   spins around a fixed centre dot. */
.triage__loader {
  position: absolute;
  left: 29px;
  top: 242px;
  width: 16px;                     /* 1px ring → centre-line radius 7.5px, as in the exported icon */
  height: 16px;
}
.triage__loader-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(
    rgba(139, 155, 168, 0.39) 0deg,
    rgba(139, 155, 168, 0.95) 60deg,
    rgba(139, 155, 168, 0.95) 120deg,
    rgba(139, 155, 168, 0.37) 180deg,
    rgba(139, 155, 168, 0.05) 240deg,
    rgba(139, 155, 168, 0.05) 320deg,
    rgba(139, 155, 168, 0.39) 360deg
  );
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 1px), #000 calc(100% - 1px));
          mask: radial-gradient(farthest-side, transparent calc(100% - 1px), #000 calc(100% - 1px));
  animation: triage-spin 0.9s linear infinite;
}
@keyframes triage-spin { to { transform: rotate(360deg); } }
.triage__loader::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 3px;
  height: 3px;
  margin: -1.5px 0 0 -1.5px;
  border-radius: 50%;
  background: #98a7af;
}
.triage__status {
  position: absolute;
  left: 53px;
  top: 240px;
  font-weight: 400;
  font-size: 15px;
  line-height: 19px;
  color: #8d9da5;
  white-space: nowrap;
}
/* "Analyzing differentials" + three dots that appear one by one, then
   start over (1.8s loop: dots at 0.45s / 0.9s / 1.35s). They keep their
   space, so the text never shifts. */
.triage__dots span {
  opacity: 0;
  animation: triage-dot 1.8s linear infinite;
}
.triage__dots span:nth-child(2) { animation-name: triage-dot-2; }
.triage__dots span:nth-child(3) { animation-name: triage-dot-3; }
@keyframes triage-dot   { 0%, 24.9% { opacity: 0; } 25%, 100% { opacity: 1; } }
@keyframes triage-dot-2 { 0%, 49.9% { opacity: 0; } 50%, 100% { opacity: 1; } }
@keyframes triage-dot-3 { 0%, 74.9% { opacity: 0; } 75%, 100% { opacity: 1; } }

/* ─── Staged reveal ──────────────────────────────────
   With scripts on (<html class="js">) the dialog and the triage card start
   hidden, slightly low. js/landing.js slides / fades the dialog up when the
   photo scrolls into view and starts its reading loop; a few seconds later
   the triage card follows, while the dialog keeps running. The individual
   `translate` property is used so it composes with the cards' own
   transform: scale(). */
.js .header-img__voice,
.js .triage {
  opacity: 0;
  translate: 0 36px;
  transition: opacity 0.9s cubic-bezier(0.22, 1, 0.36, 1),
              translate 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}
.js .header-img__voice.is-in,
.js .triage.is-in {
  opacity: 1;
  translate: 0 0;
}

/* Reduced motion: no spinning, dots shown, state changes are instant. */
@media (prefers-reduced-motion: reduce) {
  .triage__loader-ring { animation: none; }
  .triage__dots span { animation: none; opacity: 1; }
  .triage__row,
  .triage__bars rect { transition: none; }
  .js .header-img__voice,
  .js .triage { transition: none; translate: none; }
}

/* ─── Header image — responsive ──────────────────────
   --card-scale keeps the two cards from overlapping each
   other or the man's face as the photo narrows:
     > 1350   1     ≤ 1350   0.8     ≤ 1100   0.6     ≤ 860   0.5 */
@media (max-width: 1350px) {
  .header-img { --card-scale: 0.8; }
}
@media (max-width: 1100px) {
  .header-img {
    --card-scale: 0.6;
    margin-top: 140px;
    padding: 0 24px;
  }
  .header-img__media { border-radius: 24px; }
}
@media (max-width: 860px) {
  .header-img { --card-scale: 0.5; }
}
@media (max-width: 720px) {
  .header-img {
    margin-top: 96px;
    padding: 0 16px;
  }
  .header-img__media {
    aspect-ratio: 4 / 3;
    border-radius: 20px;
  }
  .header-img__photo { object-position: 25% center; }
  .header-img__voice,
  .triage { display: none; }
}

/* ═══ Intro copy ══════════════════════════════════════
   Figma node 18409:1258 (1728 design): 40 / 48 Regular, 0.6px
   tracking, centred in an 869px box (x=435, i.e. 5.5px right of
   centre), 240px below the header image and 240px above card 01.

   Scroll reveal — same mechanic as the manifesto on stivio.ai
   (see js/landing.js): once JS has split the text, every word
   starts #BCC5C8 and turns #0A2633 when lit, with their .35s
   colour transition. Without JS / with reduced motion the
   paragraph just stays #0A2633.
*/
.intro {
  width: 100%;
  max-width: var(--container);
  margin: 240px auto 0;               /* photo bottom → paragraph top */
  padding: 0 32px;                    /* same inset as .care */
}
.intro__text {
  max-width: 869px;
  margin: 0 auto;
  font-weight: 450;                   /* PP NM Regular */
  font-size: 40px;
  line-height: 48px;
  letter-spacing: 0.6px;
  text-align: center;
  word-break: break-word;
  color: var(--color-ink);            /* #0A2633 — active */
}

/* Figma places the text box at x=435, 5.5px right of true centre. */
@media (min-width: 1101px) {
  .intro__text { position: relative; left: 5.5px; }
}

.intro__text.is-reveal .reveal-word {
  color: #BCC5C8;                     /* default */
  transition: color 0.35s;
}
.intro__text.is-reveal .reveal-word.lit { color: var(--color-ink); }   /* active #0A2633 */

@media (max-width: 1100px) {
  .intro { margin-top: 120px; padding: 0 24px; }
  .intro__text { font-size: 32px; line-height: 40px; letter-spacing: 0.4px; }
}
@media (max-width: 720px) {
  .intro { margin-top: 80px; padding: 0 16px; }
  .intro__text { font-size: 26px; line-height: 34px; letter-spacing: 0.3px; }
}

/* ═══ Care cards — 01 Better care / 02 Clear recommendations ═══
   Figma node 18415:6620 (1728 design). Two white 1320 × 660 panels
   (24px radius, 40px apart) built on the shared .oh-card component
   (see "Card component" below), so the stacked / phone layouts
   below 1100px are the .oh-card ones.

   Card-relative geometry from Figma:
     index     (40, 56)   16 / 21 Light, 70% ink
     body      (40, 93)   540 wide, 18 / 28, SemiBold lead
     button    (40, 580)  202 × 40 outline, pinned to the bottom
     image     (680, 40)  600 × 580, 16px radius (the .oh-card default)
   .oh-card gives a 50 / 50 split (620px image) — the
   .oh-card--split modifier below swaps in the 680 / 640 split and
   the measurements above on desktop only.
*/
.care {
  position: relative;
  z-index: 1;                         /* cards sit above the wave that is pulled up behind them */
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 32px;                    
}
.care .oh-card:first-of-type { margin-top: 240px; }   /* photo → card 01 */

@media (min-width: 1101px) {
  .oh-card--split .oh-card__copy  { width: 51.5152%; padding-top: 56px; }   /* 680 / 1320 */
  .oh-card--split .oh-card__media { width: 48.4848%; }                      /* 640 / 1320 = 600 image + 40 inset */

  .oh-card--split .oh-card__index {
    font-size: 16px;
    line-height: 21px;
    color: var(--color-ink);
    opacity: 0.7;
  }
  .oh-card--split .oh-card__body { margin-top: 16px; max-width: 540px; }
  .oh-card--split .oh-card__cta  { width: 237px; }                          /* Figma: 'Experience a Jiva consultation' */
  .care .oh-card:nth-of-type(2) .oh-card__cta { width: 225px; }              /* 'Experience a clinical handoff' */
}
@media (max-width: 1100px) {
  .care { padding: 0 24px; }
  .care .oh-card:first-of-type { margin-top: 120px; }
}
@media (max-width: 720px) {
  .care { padding: 0 16px; }
  .care .oh-card:first-of-type { margin-top: 80px; }
}

/* ═══ Wave section ═══════════════════════════════════
   Sits directly below the header image: a full-bleed
   voive_wave_bg.png on the page bg (transitions
   white→teal) that hands off to the dark .features
   section. Decorative only — no copy.
*/
.stats {
  --u: calc(min(100vw, 1728px) / 1728);      /* one Figma px at the current width */
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  /* Figma node 18415:6620: the wave starts BEHIND card 02, and the
     "More time for the patient" title (.feat) sits 455px under that
     card's bottom edge (card 2986 → title 3441). The slab overlaps the
     wave's bottom by 160u (see .features), so this section is pulled up by
     455u + 160u − its own height. 1728px: 615 − 1180 = −565px. The cards
     (.care) are lifted above it with z-index. */
  margin-top: calc(615 * var(--u) - min(83.854vw, 1180px));
  background: var(--color-bg);               /* #F6F8F9 — page bg */
  isolation: isolate;
}

/* Wave illustration.
   In Figma the 5288×1449 PNG is rendered at the same scale as
   the 1728px design viewport — i.e. 5288 wide / 1449 tall.
   On viewports BELOW 1728px we scale it down proportionally
   (306.02 vw / 83.854 vw); at 1728px and above we LOCK to the
   design size so it never grows beyond the intended scale.
   Aspect ratio is preserved at every breakpoint. */
.stats__wave {
  position: relative;
  width: 100%;
  display: block;
  height: min(83.854vw, 1180px);
  overflow: hidden;
  z-index: 0;
}
.stats__wave-img {
  position: absolute;
  bottom: 0;                                 /* anchor dark crown to container bottom */
  left: 50%;
  transform: translateX(-50%);
  width: min(306.02vw, 5288px);
  max-width: none;
  /* On wide viewports the natural (auto) height of a Figma-scaled
     image is taller than the container, so the bottom dark crown
     sits flush against .features below — good. On narrow viewports
     the auto height becomes shorter than the container's mobile
     clamp height, exposing a strip of light page bg above the dark
     section — the white gap. Forcing min-height: 100% + cover keeps
     the image full-bleed at every viewport, and object-position
     keeps the dark crown pinned to the bottom edge so the join with
     .features stays seamless. */
  height: auto;
  min-height: 100%;
  object-fit: cover;
  object-position: 55% bottom;
  user-select: none;
  pointer-events: none;
}

/* ═══ Responsive — wave ════════════════════════════ */
@media (max-width: 720px) {
  .stats__wave { height: clamp(360px, 64vh, 700px); }
  /* On mobile, push the wave's focal point downward so more of
     the lighter (white) area shows at the top of the container. */
  .stats__wave-img { object-position: 55% 130%; }
}

/* ═══ Bottom wave — mirror of .stats__wave ════════════
   Closes out the dark .features section and fades down
   into the page bg. Figma displays the PNG at 5404×889
   anchored at x=-1802 inside a 1728 design viewport, so
   the image is rendered at 5404/1728 ≈ 312.73 vw wide
   × 889/1728 ≈ 51.45 vw tall, centered at +36 px right
   of viewport center (1802 - 5404/2 = -900; centered).
   Below 1728 px it scales down proportionally; at/above
   1728 px it locks to the Figma display size. */
.wave-bottom {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  height: min(51.447vw, 889px);
  background: var(--color-bg);               /* #F6F8F9 — page bg */
  overflow: hidden;
  isolation: isolate;
}
.wave-bottom__img {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: min(312.731vw, 5404px);
  /* Match Figma's 5404×889 display aspect (the source PNG is
     5400×1172; Figma crops the white-fade tail). Forcing the
     height + object-fit:cover with object-position:center top
     preserves the solid dark crown at the top of the image, so
     it butts cleanly against the dark .features section above
     instead of clipping the dark portion away. */
  height: min(51.447vw, 889px);
  object-fit: cover;
  object-position: center top;
  max-width: none;
  user-select: none;
  pointer-events: none;
}

/* ═══ Dark features section ══════════════════════════
   Continuous #0A2633 slab between the top wave (.stats) and
   the bottom wave (.wave-bottom), holding one feature block.

   Section height — Figma node 18414:5294. The two wave images
   carry long near-black "crowns" (≈195px at the bottom of
   .stats, ≈258px at the top of .wave-bottom at 1728), so with
   the slab simply butted against them the title / card sat
   ~160px further from the teal fades than in the design.
   Measured on the rasterised Figma frame vs this page (edge
   columns, fade level 17):
       title top  → top fade end       99px   (was 262px)
       card bottom → bottom fade start  178px  (was 334px)
   The slab therefore overlaps each wave crown (negative margins)
   and paints its dark fill with feathered top / bottom edges, so
   the join with the near-black crown stays invisible. --u is one
   Figma pixel at the current width; it stops at 1728 and scales
   down with the waves below that.
*/
.features {
  --u: calc(min(100vw, 1728px) / 1728);
  --features-pt: calc(60 * var(--u));           /* title sits 60u below the slab's top edge */
  --features-pb: calc(60 * var(--u));
  --features-overlap-top: calc(220 * var(--u));     /* 60u padding + 160u pull into the top crown */
  --features-overlap-bottom: calc(218 * var(--u));  /* 60u padding + 158u pull into the bottom crown */
  --features-feather: calc(100 * var(--u));

  position: relative;
  z-index: 1;                                   /* paint above the waves it overlaps */
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-top: calc(-1 * var(--features-overlap-top));
  margin-bottom: calc(-1 * var(--features-overlap-bottom));
  color: #ffffff;
  padding: var(--features-pt) 0 var(--features-pb);
  isolation: isolate;
}
.features::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    rgba(10, 38, 51, 0) 0,
    var(--color-ink) var(--features-feather),
    var(--color-ink) calc(100% - var(--features-feather)),
    rgba(10, 38, 51, 0) 100%
  );
}

/* Each feature article — centered title + lede + media. */
.feat {
  position: relative;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 32px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

/* Figma: 48 / 56 Regular, two lines — line 1 yellow, line 2 white. */
.feat__title {
  font-weight: 450;                   /* PP NM Regular */
  font-size: 48px;
  line-height: 56px;
  letter-spacing: 0;
  color: #ffffff;
  margin: 0;
}
.feat__title--w-634 { width: 634px; max-width: 100%; }
.feat__title-accent {
  color: var(--color-accent-yellow);
}

/* Figma: 18 / 28 Book, 0.8px tracking, 24px under the title. */
.feat__lede {
  margin-top: 24px;
  font-weight: 400;                   /* PP NM Book */
  font-size: 18px;
  line-height: 28px;
  letter-spacing: 0.8px;
  color: rgba(255, 255, 255, 0.8);
}
.feat__lede--w-633 { width: 633px; max-width: 100%; }

/* Media — outer container holds the illustration + pointer.
   The illustration PNG is the Figma card at 2× plus a shadow
   margin (6px left/right, 4px top, 8px bottom), so it sits
   76px under the lede (80px to the card itself). */
.feat__media {
  position: relative;
  margin-top: 76px;
}

/* ─── Pre-Visit Summary illustration (646 × 874) ─── */
.feat__media--summary {
  width: 646px;
  max-width: 100%;
  display: flex;
  justify-content: center;
}
.feat__summary-img {
  display: block;
  width: 646px;
  max-width: 100%;
  height: auto;
  user-select: none;
}

/* Dr. Anna pointer — the Figma pill group (178 × 105 PNG) sits at
   (568, 427) inside the illustration, resting beside the "Flagged
   for review" panel. Position and size are percentages of the
   illustration so the pointer stays on that row when it scales. */
.feat__dr-anna {
  position: absolute;
  left: 87.9257%;                     /* 568 / 646 */
  top: 48.8558%;                      /* 427 / 874 */
  width: 27.5542%;                    /* 178 / 646 */
  height: auto;
  z-index: 2;
  pointer-events: none;
  user-select: none;
  will-change: transform;
  animation: dr-anna-reading 12s cubic-bezier(0.45, 0, 0.2, 1) infinite;
}

/* Dr. Anna reads the pre-visit summary: the pointer stays on the
   right of the card and slides vertically to each section in turn —
   Chief complaint → History of present illness → Flagged for review
   → Working differentials → Jiva recommendation — pausing on each to
   "read", then moves down and into the card onto the Review & Sign
   button, presses (scale 0.94) to imitate a click, and loops back to
   the top. translate(0, 0) is the Figma rest pose (beside "Flagged
   for review"); the offsets are the distance from that row to each
   section's centre. Negative X moves it leftward INTO the card. */
@keyframes dr-anna-reading {
  0%     { transform: translate(0px, -232px)       scale(1); }   /* Chief complaint */
  11.67% { transform: translate(0px, -232px)       scale(1); }   /* read */
  15.83% { transform: translate(0px, -115px)       scale(1); }   /* slide to History of present illness */
  27.5%  { transform: translate(0px, -115px)       scale(1); }   /* read */
  31.67% { transform: translate(0px, 0px)          scale(1); }   /* slide to Flagged for review */
  43.33% { transform: translate(0px, 0px)          scale(1); }   /* read */
  47.5%  { transform: translate(0px, 115px)        scale(1); }   /* slide to Working differentials */
  59.17% { transform: translate(0px, 115px)        scale(1); }   /* read */
  63.33% { transform: translate(0px, 256px)        scale(1); }   /* slide to Jiva recommendation */
  75%    { transform: translate(0px, 256px)        scale(1); }   /* read */
  80.83% { transform: translate(-46px, 382px)      scale(1); }   /* hover Review & Sign */
  83.33% { transform: translate(-46px, 382px)      scale(1); }   /* settle */
  85.83% { transform: translate(-46px, 382px)      scale(0.94); }   /* press (click) */
  88.33% { transform: translate(-46px, 382px)      scale(1); }   /* release */
  91.67% { transform: translate(-46px, 382px)      scale(1); }   /* hold */
  100%   { transform: translate(0px, -232px)       scale(1); }   /* return to Chief complaint */
}

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

/* ═══ Responsive — features ═════════════════════════
   Tablet / phone keep the original (pre-redesign) behaviour:
   the same type sizes, gaps and pointer placement as before, and
   the slab goes back to a plain block — 200px (140px on phones)
   from its top edge to the title, nothing overlapping the waves.
   The wave-overlap "section height" above applies to desktop only.
*/
@media (max-width: 1100px) {
  .features {
    --features-pt: 200px;
    --features-pb: 0px;
    --features-overlap-top: 0px;
    --features-overlap-bottom: 0px;
    --features-feather: 0px;        /* solid fill, no feathered edges */
  }

  .feat { padding: 0 24px; }
  .feat__title { font-size: 32px; line-height: 36px; }
  .feat__title--w-634 { width: auto; max-width: 460px; }
  .feat__lede { margin-top: 32px; font-size: 16px; line-height: 24px; }
  .feat__lede--w-633 { width: auto; max-width: 460px; }

  .feat__media { margin-top: 80px; width: 100%; max-width: 560px; }

  .feat__media--summary { width: 100%; }

  .feat__summary-img { width: 100%; }

  .feat__dr-anna {
    width: 130px;
    left: auto;
    right: -36px;
    top: auto;
    bottom: 90px;
    animation: none;
    transform: none;
  }
}

@media (max-width: 720px) {
  .features { --features-pt: 140px; }

  .feat__title { font-size: 28px; line-height: 32px; }
  .feat__media { margin-top: 56px; }
  .feat__dr-anna { width: 100px; right: -8px; bottom: 48px; }
}

/* ═══ Experience section ═══════════════════════════════
   Light-bg section sitting after the bottom wave. Holds a
   centered header and three illustrated feature blocks:
   one full-width and two side-by-side.
*/
.exp {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 40px 32px 240px;
  background: var(--color-bg);
}

.exp__head {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.exp__title {
  font-weight: 450;                   /* PP NM Regular */
  font-size: 72px;
  line-height: 76px;
  letter-spacing: 0;
  color: var(--color-ink);
  max-width: 743px;
  margin: 0;
}
/* .exp__title-muted styling lives in the shared .title-muted utility (home.css). */

.exp__lede {
  margin-top: 24px;
  max-width: 599px;
  font-weight: 400;                   /* PP NM Book */
  font-size: 18px;
  line-height: 28px;
  letter-spacing: 0.6px;
  color: var(--color-ink);
}

/* ─── Block ─────────────────────────────────────────── */
.exp-block {
  display: flex;
  flex-direction: column;
  /* Allow grid items to shrink below their content's intrinsic
     width, so the two-up row collapses cleanly on mobile. */
  min-width: 0;
}
.exp-block--full {
  margin-top: 120px;
}

.exp-block__media {
  position: relative;
  width: 100%;
  border-radius: 24px;
  overflow: hidden;
  background: var(--color-bg);
}
.exp-block__media img {
  display: block;
  width: 100%;
  height: auto;
  user-select: none;
}

/* Full-width block keeps the 1320×668 ≈ 1.976 aspect. */
.exp-block__media--full {
  aspect-ratio: 1320 / 668;
}
.exp-block__media--full img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* Voice overlay — base styles live in home.css (.voice-overlay).
   Here we just position the card over the upper-right of the
   patient illustration and tune the body-text size for this
   block (the Priya quote needs slightly larger type). */
.exp-block__media--full .voice-overlay {
  top: 15%;
  left: 62%;
  transform: translateX(-50%);
  width: clamp(280px, 32%, 380px);
  height: clamp(160px, 19vw, 164px);
}
.exp-block__media--full .voice-overlay__text {
  font-size: 16px;
}

/* Two-up tiles use the 640×460 aspect. */
.exp-row .exp-block__media {
  aspect-ratio: 640 / 460;
}
.exp-row .exp-block__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.exp-block__copy {
  margin-top: 28px;                   /* y=1256 - y=1228 ≈ 28 */
  max-width: 640px;
  font-weight: 400;                   /* PP NM Book */
  font-size: 18px;
  line-height: 28px;
  letter-spacing: 0.6px;
  color: var(--color-ink);
}

.exp-block__lead {
  font-weight: 600;                   /* PP NM SemiBold */
}

/* ─── Two-up row ──────────────────────────────────────── */
.exp-row {
  margin-top: 80px;
  display: grid;
  /* minmax(0, 1fr) lets the cells shrink below their natural
     content width — without it, fixed-width children would force
     horizontal overflow on narrow viewports. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: 40px;                   /* 884 - 204 - 640 = 40 */
  row-gap: 0;
}

/* ═══ Responsive — exp ═════════════════════════════════ */
@media (max-width: 1100px) {
  .exp { padding: 96px 24px 140px; }
  .exp__title { font-size: 44px; line-height: 52px; }
  .exp__lede { font-size: 16px; line-height: 24px; }

  .exp-block--full { margin-top: 120px; }
  .exp-row {
    margin-top: 120px;
    grid-template-columns: minmax(0, 1fr);
    row-gap: 96px;
  }
}

@media (max-width: 720px) {
  .exp { padding: 80px 16px 120px; }
  .exp__title { font-size: 32px; line-height: 36px; }
  .exp__lede { margin-top: 20px; font-size: 16px; line-height: 24px; }

  .exp-block--full { margin-top: 80px; }
  .exp-block__copy { margin-top: 20px; font-size: 16px; line-height: 24px; }
  .exp-row { margin-top: 80px; row-gap: 64px; }
  .exp-block__media { border-radius: 20px; }

  /* Hide the voice overlay on mobile — the patient illustration
     reads better without the overlapping card on small screens. */
  .exp-block__media--full .voice-overlay { display: none; }
}

/* Clinics-page override of the shared `main { padding: 0 24px }`
   rule from home.css. Scoped automatically because clinics.css is
   only loaded on clinics.html. Full-bleed sections inside main
   (.header-img, .stats, .features, .wave-bottom) use
   `width: 100vw; margin-left: calc(50% - 50vw)` and remain viewport-
   aligned regardless of main's side padding. */
@media (max-width: 1100px) {
  main { padding: 0 8px; }
}

/* ═══ Dashboard — Better outcomes / Clinical capacity ═══
   Figma node 18425:8656 (1728 design): two 640 × 460 illustrations
   side by side (x=204 and x=884, 40px apart), each with its caption
   28px underneath, and the CTA banner 200px below the captions.
   The row is the shared .exp-row / .exp-block component, so the
   image radius (24px, 20px on phones), the 640 / 460 media aspect, the
   caption type and the stacked layout below 1100px all come from the
   experience section. Here it only gets the section container and a
   1320px row width (the Figma rail: 2 × 640 + 40). */
.dashboard {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 120px 32px 0;              /* top gap is not specified in the frame; bottom is the CTA's margin */
}
.dashboard .exp-row {
  max-width: 1320px;
  margin: 0 auto;                     /* overrides .exp-row's margin-top: 80 / 120 */
}

@media (max-width: 1100px) {
  .dashboard { padding: 96px 24px 0; }
}
@media (max-width: 720px) {
  .dashboard { padding: 80px 16px 0; }
}

/* Figma: captions end at y=782, the CTA banner starts at y=982 — 200px.
   The CTA follows </main>, so its margin is the whole gap. */
@media (min-width: 861px) {
  .cta { margin-top: 200px; }
}

/* ─── Logos marquee ──────────────────────────────────── */
.logos {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1320px;                  /* same rail as the dashboard row */
  margin: 80px auto 0;                /* under the dashboard captions */
  height: 80px;
  border-radius: 16px;
  background: #EAEEEF;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
  overflow: hidden;
  /* Edge fade — transparent at both ends so the marquee
     items appear to dissolve in/out. Authored as a mask
     so it blends with whatever bg sits behind. */
  -webkit-mask-image: linear-gradient(
    to right,
    rgba(0,0,0,0) 0%,
    rgba(0,0,0,1) 14%,
    rgba(0,0,0,1) 86%,
    rgba(0,0,0,0) 100%
  );
          mask-image: linear-gradient(
    to right,
    rgba(0,0,0,0) 0%,
    rgba(0,0,0,1) 14%,
    rgba(0,0,0,1) 86%,
    rgba(0,0,0,0) 100%
  );
}

.logos__track {
  display: flex;
  align-items: center;
  gap: 0;                              /* no seam between the duplicate rows */
  height: 100%;
  width: max-content;
  /* Track holds FOUR identical rows. Translating by -25%
     of the track equals exactly one row's width — the
     remaining three rows occupy the visible band, and
     the snap-back at -25% lands on a pixel-identical
     state, so the loop is endless with no empty space. */
  animation: logos-marquee 33.33s linear infinite;
  will-change: transform;
}
@keyframes logos-marquee {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-25%, 0, 0); }
}

.logos__row {
  display: flex;
  align-items: center;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  flex-shrink: 0;
}

.logos__item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 28px;                    /* spacing between items */
  font-weight: 450;                   /* PP NM Regular */
  font-size: 14px;
  line-height: 1;
  letter-spacing: 0;
  color: var(--color-ink);
  white-space: nowrap;
  flex-shrink: 0;
}
.logos__icon {
  width: auto;
  height: 18px;
  display: block;
  flex-shrink: 0;
}
/* SOC 2 icon's natural aspect renders smaller than the EHR/HIPAA
   shields at the same height, so bump it up a touch for visual
   parity with its neighbors. */
.logos__icon[src*="SOC2"] { height: 20px; }

/* Visually hidden list of the logos for screen readers
   (the marquee is aria-hidden so AT users get a clean
   itemized list instead of duplicated content). */
.logos__sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Pause animation for users who prefer reduced motion. */
@media (prefers-reduced-motion: reduce) {
  .logos__track { animation: none; }
}

/* ═══ Responsive — logos ══════════════════════════════ */
@media (max-width: 1100px) {
  .logos {
    margin-top: 64px;
    height: 72px;
  }
  .logos__item { padding: 0 20px; font-size: 13px; }
}

@media (max-width: 720px) {
  .logos { margin-top: 48px; height: 64px; border-radius: 12px; }
  .logos__item { padding: 0 16px; font-size: 12px; }
  .logos__icon { height: 16px; }
}

/* ═══ Card component (.oh-card) ══════════════════════
   White 1320 × 660 panel: copy column + illustration column.
   Used by the care cards above (.care). Stacks below 1100px.
*/
.oh-card {
  position: relative;
  width: 100%;
  max-width: 1320px;
  margin: 40px auto 0;
  /* Cards stack with a 40px gap. */
  height: 660px;
  background: #ffffff;
  border-radius: 24px;
  overflow: hidden;
  display: flex;
  align-items: stretch;
}

.oh-card__copy {
  position: relative;
  width: 50%;
  padding: 40px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.oh-card__index {
  font-weight: 300;                   /* PP NM Light */
  font-size: 18px;
  line-height: 1;
  letter-spacing: 0.6px;
  color: var(--color-ink-soft);       /* #6C7D85 */
}

.oh-card__body {
  margin-top: 24px;
  max-width: 512px;
  font-weight: 400;                   /* PP NM Book */
  font-size: 18px;
  line-height: 28px;
  letter-spacing: 0.6px;
  color: var(--color-ink);
}
.oh-card__lead {
  font-weight: 600;                   /* PP NM SemiBold */
}

/* Push the outline CTA to the bottom of the copy column.
   Visual styling comes from the shared .btn / .btn--outline. */
.oh-card__cta {
  margin-top: auto;
}

.oh-card__media {
  position: relative;
  width: 50%;
  /* Per Figma: illustration sits inside the white card with
     uniform padding, so the white card's edge frames the
     image — no padding on the LEFT (the image meets the
     copy column), and 40px padding on the other three
     sides so it stops short of the card's outer edges. */
  padding: 40px 40px 40px 0;
}
.oh-card__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  border-radius: 16px;
  user-select: none;
}

/* ═══ Responsive — card component ═════════════════════ */
@media (max-width: 1100px) {
  .oh-card {
    margin-top: 32px;
    height: auto;
    flex-direction: column;
  }

  .oh-card__copy,
  .oh-card__media { width: 100%; }
  .oh-card__copy {
    padding: 40px 32px 32px;
    gap: 32px;
  }
  .oh-card__body { margin-top: 24px; }
  .oh-card__cta { margin-top: 8px; }
  .oh-card__media {
    aspect-ratio: 16 / 10;
    padding: 0 32px 32px;             /* image inset on three sides on mobile */
  }
}

@media (max-width: 720px) {
  .oh-card {
    margin-top: 24px;
    border-radius: 20px;
  }
  .oh-card__copy { padding: 32px 24px 24px; }
  .oh-card__body { font-size: 16px; line-height: 24px; }
  .oh-card__media { aspect-ratio: 4 / 3; padding: 0 24px 24px; }
}

/* ═══ Fade-in on scroll (stivio.ai style) ═══════════════
   [data-fade] blocks rise 32px and fade in once as they scroll into view
   (js/landing.js adds .is-in). Elements sharing data-fade-group appear
   together; data-fade-delay staggers one after the group starts.
   Uses the individual `translate` property so it composes with any
   transform on the element. Without JS everything is simply visible. */
.js [data-fade] {
  opacity: 0;
  translate: 0 32px;
  transition: opacity 1s cubic-bezier(0.22, 1, 0.36, 1), translate 1s cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: var(--fade-delay, 0ms);
}
.js [data-fade].is-in {
  opacity: 1;
  translate: 0 0;
}
@media (prefers-reduced-motion: reduce) {
  .js [data-fade] { opacity: 1; translate: none; transition: none; }
}

/* ═══ Buttons — 0.2px tracking on every .btn (nav CTA: css/nav.css) ═══ */
.btn { letter-spacing: 0.2px; }

/* The Dr. Anna pointer waits at its first frame and starts reading only once
   the summary card is on screen (.is-reading, set by js/landing.js). */
.js .feat__dr-anna { animation-play-state: paused; }
.js .feat__media.is-reading .feat__dr-anna { animation-play-state: running; }

/* ═══ CTA banner copy (Figma 18425:8656) ═══════════════
   Title top 144px into the banner, 16px to the lede (16 / 24, 640 wide),
   40px to the button. Two-line title: white, then yellow. */
.cta__title-accent { color: var(--color-accent-yellow); }
@media (min-width: 861px) {
  .cta__inner { padding-top: 136px; }
  .cta__title { width: 465px; }
  .cta__copy {
    margin-top: 16px;
    width: 592px;
    font-size: 16px;
    line-height: 24px;
  }
  .cta__btn:not(.cta__btn--sticky) { margin-top: 48px; }
}

/* ═══ Shared 1320 rail — dashboard and CTA banner ═══
   The dashboard row is 1320 wide, centred (Figma x=204 … 1524 at 1728).
   The CTA copy sits on the same rail as the footer (css/footer.css):
   64px side inset (main 32 + dashboard 32), 32 below 1100px, 24 below
   720px, matching the dashboard's own insets at every width. */
.cta__inner {
  max-width: 1448px;
  padding-left: 64px;
  padding-right: 64px;
}
@media (max-width: 1100px) {
  .cta__inner { padding-left: 32px; padding-right: 32px; }
}
@media (max-width: 720px) {
  .cta__inner { padding-left: 24px; padding-right: 24px; }
}

/* ═══ Dashboard section — "See the next step. Follow the handoff." ═══
   Figma node 18436:11456 (1728 design; card 1495 × 864).
     title   72 / 76, centred, second line #607279   (y=130)
     lede    18 / 28, 523 wide, 24px under the title
     card    1495 × 864, 67px under the lede, bottom 71px above the logos
     logos   1496 × 80 running line, 88px above the two-up row
   The card is a real-markup mock-up. Every size inside it is written in
   design pixels and scaled by the card's width: .dash is a size container
   and --q is "one design pixel" (100cqw / 1348 — the wire the numbers were
   taken from; the 1495 card is this ×1.109), so the card keeps the
   Figma proportions at any viewport. Hooks for animation: [data-dash],
   [data-dash-banner], [data-dash-head], [data-dash-row] (--i = row index). */
.dash-head {
  text-align: center;
  color: #0a2633;
}
.dash-head__title {
  margin: 0 auto;
  font-weight: 450;                   /* PP NM Regular */
  font-size: 72px;
  line-height: 76px;
  letter-spacing: 0;
  color: #0a2633;
}
.dash-head__line { display: block; }
.dash-head__line--muted { color: #607279; }
.dash-head__copy {
  width: 725px;
  max-width: 100%;
  margin: 24px auto 0;
  font-weight: 400;                   /* PP NM Book */
  font-size: 18px;
  line-height: 28px;
  letter-spacing: 0.4px;
  color: #0a2633;
}

.dash {
  --q: calc(100cqw / 1348);           /* 1 design px of the 1348 wire; the card is 1495 wide at full size */
  --w: min(1495px, calc(100vw - 64px));
  container-type: inline-size;
  position: relative;
  width: var(--w);
  margin: 67px 0 0 calc(50% - var(--w) / 2);
  font-family: 'Inter', 'PP Neue Montreal', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  letter-spacing: 0;
  -webkit-font-smoothing: antialiased;
}
.dash-card {
  position: relative;
  height: calc(779 * var(--q));
  border-radius: calc(31.204 * var(--q));
  background: #ffffff;
  box-shadow: 0 calc(0.975 * var(--q)) calc(2.925 * var(--q)) rgba(10, 36, 66, 0.24);
}

/* Bottom of the card dissolves into the page (Figma "blur": 1393 × 256,
   transparent #F6F8F9 → #F6F8F9, 2px backdrop blur). */
.dash__fade {
  position: absolute;
  left: calc(-18 * var(--q));
  top: calc(547.3 * var(--q));
  width: calc(1384 * var(--q));
  height: calc(238 * var(--q));
  background: linear-gradient(to bottom, rgba(246, 248, 249, 0) 1.895%, #f6f8f9 100%);
  pointer-events: none;
}
/* the 2px backdrop blur only builds up towards the bottom (as in the
   Figma frame, where the first rows under the fade stay sharp) */
.dash__fade::before {
  content: "";
  position: absolute;
  inset: 0;
  -webkit-backdrop-filter: blur(2px);
          backdrop-filter: blur(2px);
  -webkit-mask-image: linear-gradient(to bottom, transparent 25%, #000 65%);
          mask-image: linear-gradient(to bottom, transparent 25%, #000 65%);
}

/* "Talking to 18 patients…" strip — the gradient video is cropped to a
   1313 × 48 rounded window (Figma masks a 1331 × 609 video). */
.dash-banner {
  position: absolute;
  left: calc(17 * var(--q));
  top: calc(16 * var(--q));
  width: calc(1313 * var(--q));
  height: calc(48 * var(--q));
  border-radius: calc(16 * var(--q));
  overflow: hidden;
  background: #0d5a72;
}
.dash-banner__video {
  position: absolute;
  left: calc(-7.516 * var(--q));
  top: calc(-60.406 * var(--q));
  width: calc(1330.869 * var(--q));
  height: calc(609.042 * var(--q));
  object-fit: cover;
  pointer-events: none;
}
.dash-banner__text {
  position: absolute;
  inset: 0;
  margin: 0;
  text-align: center;
  font-weight: 500;
  font-size: calc(11.401 * var(--q));
  line-height: calc(48 * var(--q));
  color: #ffffff;
  opacity: 0.9;
}

/* Table panel: white, 0.8px #E9ECEC rim, 16 radius. */
.dash-panel {
  position: absolute;
  left: calc(16 * var(--q));
  top: calc(78 * var(--q));
  width: calc(1316 * var(--q));
  height: calc(687 * var(--q));
  box-sizing: border-box;
  border: calc(0.814 * var(--q)) solid #e9ecec;
  border-radius: calc(16 * var(--q));
  background: #ffffff;
  overflow: hidden;
}
/* Everything inside is placed in panel coordinates: x = design x − 208.2,
   y = design y − 536.2 (the border is 0.8 wide). */
.dash-thead {
  position: absolute;
  left: calc(0.2 * var(--q));
  top: calc(0.2 * var(--q));
  width: calc(1314 * var(--q));
  height: calc(41 * var(--q));
  border-radius: calc(15 * var(--q)) calc(15 * var(--q)) 0 0;
  background: rgba(245, 248, 250, 0.5);
}
.dash-th {
  position: absolute;
  top: calc(10.14 * var(--q));
  height: calc(19.545 * var(--q));
  border-radius: calc(4.886 * var(--q));
  background: #e4eaee;
  display: flex;
  align-items: center;
  gap: calc(4.886 * var(--q));
  padding-left: calc(6.51 * var(--q));
  box-sizing: border-box;
  font-weight: 500;
  font-size: calc(9.77 * var(--q));
  line-height: normal;
  color: #849299;
  white-space: nowrap;
}
.dash-th__label { display: block; }
.dash-th__help { width: calc(13.03 * var(--q)); height: calc(13.03 * var(--q)); display: block; flex: none; }
.dash-th__sort {
  position: absolute;
  top: calc(7.33 * var(--q));
  width: calc(9.772 * var(--q));
  height: calc(4.886 * var(--q));
  object-fit: fill;
}
.dash-th--date        { left: calc(13.66 * var(--q));   width: calc(91.208 * var(--q)); }
.dash-th--date .dash-th__sort { left: calc(74.92 * var(--q)); top: calc(6.86 * var(--q)); }
.dash-th--patient     { left: calc(117.9 * var(--q));   width: calc(126.225 * var(--q)); }
.dash-th--patient .dash-th__sort { left: calc(109.12 * var(--q)); }
.dash-th--triaged     { left: calc(257.15 * var(--q));  width: calc(126.225 * var(--q)); }
.dash-th--triaged .dash-th__sort { left: calc(109.94 * var(--q)); }
.dash-th--diagnosis   { left: calc(396.41 * var(--q));  width: calc(205.218 * var(--q)); }
.dash-th--diagnosis .dash-th__sort { left: calc(188.93 * var(--q)); }
.dash-th--action      { left: calc(614.65 * var(--q));  width: calc(153.913 * var(--q)); }
.dash-th--action .dash-th__sort { left: calc(137.63 * var(--q)); }
.dash-th--assigned    { left: calc(781.6 * var(--q));   width: calc(144.955 * var(--q)); }
.dash-th--assigned .dash-th__sort { left: calc(128.66 * var(--q)); }
.dash-th--urgency     { left: calc(939.58 * var(--q));  width: calc(105.866 * var(--q)); }
.dash-th--urgency .dash-th__sort { left: calc(89.58 * var(--q)); }
.dash-th--institution { left: calc(1058.48 * var(--q)); width: calc(134.369 * var(--q)); }
.dash-th--institution .dash-th__sort { left: calc(118.08 * var(--q)); }
.dash-th--status      { left: calc(1205.88 * var(--q)); width: calc(94.465 * var(--q)); }
.dash-th--status .dash-th__sort { left: calc(78.17 * var(--q)); }

/* Patient list — rows are 58.63 apart with a #E9ECEC rule between them. */
.dash-rows {
  position: absolute;
  left: calc(0.2 * var(--q));
  top: calc(41.2 * var(--q));
  width: calc(1314 * var(--q));
  height: calc(642 * var(--q));
  overflow: hidden;
  box-shadow: inset 0 calc(0.982 * var(--q)) 0 #e9ecec;   /* rule under the header */
}
.dash-row {
  position: relative;
  box-sizing: border-box;
  height: calc(58.63 * var(--q));
  margin-top: 0;
  border-bottom: calc(0.982 * var(--q)) solid #e9ecec;
  font-size: calc(11.401 * var(--q));
  line-height: calc(13.03 * var(--q));
  color: #233c47;
  font-weight: 400;
  transition: opacity 0.75s cubic-bezier(0.22, 1, 0.36, 1);
}
.dash-row.is-new { opacity: 0; }
.dash-rows__track {
  margin-top: calc(-0.75 * var(--q));
  /* a row that slides in at the top pushes the rest down by one row */
  transition: transform 0.75s cubic-bezier(0.22, 1, 0.36, 1);
}
.dash-cell {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  white-space: nowrap;
}
.dash-cell--date        { left: calc(12.84 * var(--q)); }
.dash-cell--patient     { left: calc(118.7 * var(--q)); }
.dash-cell--triaged     { left: calc(257.15 * var(--q)); }
.dash-cell--diagnosis   { left: calc(400.48 * var(--q)); width: calc(201.146 * var(--q)); white-space: normal; }
.dash-cell--action      { left: calc(615.47 * var(--q)); }
.dash-cell--assigned    { left: calc(781.6 * var(--q)); }
.dash-cell--urgency     { left: calc(939.58 * var(--q)); }
.dash-cell--institution { left: calc(1058.48 * var(--q)); }
.dash-cell--status      { left: calc(1205.9 * var(--q)); }

.dash-main, .dash-sub { display: block; }
.dash-main { line-height: calc(13.03 * var(--q)); }
.dash-main--medium { font-weight: 500; }
.dash-sub {
  margin-top: calc(3.27 * var(--q));
  font-family: 'PP Neue Montreal', 'Inter', sans-serif;
  font-weight: 400;
  font-size: calc(10.74 * var(--q));
  line-height: calc(13 * var(--q));
  color: rgba(10, 38, 51, 0.6);
}
.dash-cell--date .dash-main, .dash-cell--patient .dash-main { margin-top: calc(0.49 * var(--q)); }

/* Badges — Untitled UI utility palette (bg / border / text). */
.dash-badge {
  display: inline-flex;
  align-items: center;
  box-sizing: border-box;
  height: calc(20.3 * var(--q));
  padding: 0 calc(8.144 * var(--q));
  border: calc(0.814 * var(--q)) solid var(--b);
  border-radius: 999px;
  background: var(--bg);
  color: var(--fg);
  font-weight: 500;
  font-size: calc(11.4 * var(--q));
  line-height: calc(16.287 * var(--q));
  white-space: nowrap;
}
.dash-badge--err   { --bg: #fef3f2; --b: #fecdca; --fg: #b42318; }
.dash-badge--warn  { --bg: #fffaeb; --b: #fedf89; --fg: #b54708; }
.dash-badge--brand { --bg: #f9f5ff; --b: #e9d7fe; --fg: #6941c6; }
.dash-badge--ok    { --bg: #ecfdf3; --b: #abefc6; --fg: #067647; }
.dash-badge--teal  { --bg: #e1f7f7; --b: #a1c8c8; --fg: #368894; }

/* Assignee: 27.7 round photo + name. */
.dash-doc { display: flex; align-items: center; gap: calc(7.1 * var(--q)); }
.dash-doc__img {
  width: calc(27.688 * var(--q));
  height: calc(27.688 * var(--q));
  border-radius: 50%;
  object-fit: cover;
  display: block;
  flex: none;
}

/* Status: 17.9 round icon chip + label. */
.dash-status {
  display: flex;
  align-items: center;
  gap: calc(6.5 * var(--q));
  height: calc(17.916 * var(--q));
}
.dash-status__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(17.916 * var(--q));
  height: calc(17.916 * var(--q));
  border-radius: 50%;
  flex: none;
}
.dash-status--resolved .dash-status__icon   { background: rgba(216, 245, 233, 0.6); }
.dash-status--undergoing .dash-status__icon { background: #ffebe3; }
.dash-status--resolved .dash-status__icon img   { width: calc(5.37 * var(--q)); height: calc(4.475 * var(--q)); }
.dash-status--undergoing .dash-status__icon img { width: calc(8.055 * var(--q)); height: calc(8.055 * var(--q)); }
.dash-status__icon img { display: block; }

/* Running logos — Figma "running logos": page-coloured 1496 × 80 band,
   14px PP NM Regular #0A2633 at 50%, icons at 50%, soft edge fade. */
.logos {
  background: transparent;
  box-shadow: none;
  border-radius: 16px;
  width: min(1496px, calc(100vw - 16px));
  max-width: none;
  margin: 71px 0 0 calc(50% - min(748px, 50vw - 8px));
}
.logos__item {
  gap: 12px;
  padding: 0 40px;                    /* 80px between items */
  font-weight: 450;
  color: #0a2633;
}
.logos__item > span { opacity: 0.5; }
.logos__icon { opacity: 0.5; }

/* Gap from the running line to the two-up row (Figma 1389 → 1477). */
.dashboard .exp-row { margin-top: 88px; }

@media (max-width: 1100px) {
  .dash-head__title { font-size: 56px; line-height: 60px; }
}
@media (max-width: 720px) {
  .dash-head__title { font-size: 40px; line-height: 44px; }
  .dash-head__copy { font-size: 16px; line-height: 24px; }
  .dash { --w: min(1495px, calc(100vw - 48px)); margin-top: 48px; }
  .logos { margin-top: 48px; margin-left: calc(50% - 50vw + 8px); width: calc(100vw - 16px); }
  .dashboard .exp-row { margin-top: 64px; }
}

/* single-line cells sit ~1px below the block centre in the Figma rows */
.dash-cell--one { transform: translateY(calc(-50% + 1.1 * var(--q))); }
.dash-doc > span { position: relative; top: calc(1.5 * var(--q)); }

/* "Talking to N patients…" — the three dots appear one after another, in a loop. */
.dash-dots span { opacity: 0; animation: dash-dot 1.8s linear infinite; }
.dash-dots span:nth-child(2) { animation-name: dash-dot-2; }
.dash-dots span:nth-child(3) { animation-name: dash-dot-3; }
@keyframes dash-dot   { 0%, 24.9% { opacity: 0; } 25%, 100% { opacity: 1; } }
@keyframes dash-dot-2 { 0%, 49.9% { opacity: 0; } 50%, 100% { opacity: 1; } }
@keyframes dash-dot-3 { 0%, 74.9% { opacity: 0; } 75%, 100% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .dash-dots span { animation: none; opacity: 1; }
  .dash-rows__track, .dash-row { transition: none; }
}

/* ═══ Features → dashboard spacing (Figma 18438:12703) ═══
   The summary illustration ends at y=2146 and the dashboard title starts at
   y=2746: 600px. From the illustration down the page runs 60u of features
   padding, then the bottom wave (889u tall) pulled 218u up into the
   features — and the illustration sits 32px above the article's bottom edge
   — so the dashboard is pulled up over the wave's faded tail by the rest
   (and loses its own 120px top padding). --u is one Figma pixel at the
   current width (stops at 1728, like the wave). Below 1100px the stacked
   layout keeps its own spacing. */
@media (min-width: 1101px) {
  .dashboard {
    position: relative;
    z-index: 2;                       /* paint above the wave it overlaps */
    padding-top: 0;
    margin-top: calc(-131 * min(100vw, 1728px) / 1728 + 32px);
  }
}
