/* ==========================================================================
   Cubie Health — Shared Theme
   Loaded on every page: tokens, reset, nav, hero scaffold, section headers,
   forms, footer, motion utilities.

   COLOUR RULE — read before changing anything here:
   --brand-violet (#8565FB) measures 4.00:1 on white. It FAILS WCAG AA for
   body text and small links. It is permitted ONLY on the logomark, large
   display type (>=24px bold, which needs 3:1), and solid fills.
   For links, buttons and any body-size text use --primary (5.57:1).
   ========================================================================== */

:root {
  /* grounds */
  --ground:        #FFFFFF;
  --bg-soft:       #F8F8FC;
  --tint:          #F2F0FC;
  --border:        #E6E3F5;

  /* ink — from the Cubie logomark navy */
  --ink:           #0D1C32;  /* 17.08:1 on white */
  --ink-soft:      #4C5468;  /*  7.57:1 */
  --ink-faint:     #616A7E;  /*  5.42:1 on white, 4.82:1 on --tint, 4.55:1 under the
                                 cube field over --tint. The previous #6B7488 measured
                                 4.69:1 on white but only 4.43:1 on --bg-soft and 4.16:1
                                 on --tint, where this token is actually used. */

  /* interactive */
  --primary:       #6E4CE0;  /*  5.57:1 — links, buttons, body-size accents */
  --primary-deep:  #5A3BC4;  /*  7.35:1 — hover, pressed */

  /* The brand accent, defined once. .rule-accent draws it at 90deg and
     .mock-foot::before at 180deg — one device, two axes. */
  --accent-stops:  var(--brand-violet), var(--primary) 70%, var(--primary-deep);

  /* brand — display and fills only, never body text */
  --brand-violet:  #8565FB;  /*  4.00:1 — see COLOUR RULE above */

  /* on navy grounds */
  --on-navy:       #A594FF;  /*  6.74:1 on --ink */
  --navy-soft:     #C9D0DC;  /* 11.01:1 on --ink */

  --shadow-soft: 0 20px 60px -20px rgba(110, 76, 224, 0.22);
  --shadow-card: 0 10px 30px -12px rgba(13, 28, 50, 0.12);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  --font-display: 'Manrope', 'Helvetica Neue', Arial, sans-serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  --wrap: 1180px;

  /* ---- type scale ----
     Explicit rem stops rather than clamp(): the spec fixes three sizes per
     element, and clamp interpolates between them at widths where it shouldn't.
     Overridden on :root in the RESPONSIVE block at the foot of this file. */
  --fs-h1:      3.5rem;     /* 56 */
  --fs-h2:      2.375rem;   /* 38 */
  --fs-h3:      1.5rem;     /* 24 */
  --fs-lede:    1.1875rem;  /* 19 */
  --fs-body:    1.0625rem;  /* 17 */
  --fs-meta:    0.875rem;   /* 14 — the floor for diagram and supporting copy */
  --fs-eyebrow: 0.8125rem;  /* 13 */
  --fs-btn:     1rem;       /* 16 */

  /* ---- spacing ---- */
  --gutter:      32px;
  --section-y:   88px;
  --hero-top:   144px;
  --hero-bot:    80px;
  --gap-intro:   40px;   /* section introduction -> its content */
  --gap-grid:    32px;
  --panel-pad:   32px;   /* information panels */
  --mock-pad:    28px;   /* product panels */
  --banner-pad:  48px;
  --form-pad:    32px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }

body {
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--ground);
  font-size: var(--fs-body);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

/* Display face carries headings and pull quotes. Inter takes over below h3. */
h1, h2, h3, .display {
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.12;
  text-wrap: balance;
}
/* Anchored sections must clear the fixed header when jumped to. Scoped to the
   elements that are actually link targets — a bare [id] would also match <body>
   and <main>. */
section[id], article[id], h2[id], h3[id] { scroll-margin-top: 96px; }

/* Reflow at enlarged text. Two separate causes, both needed:
   1. A grid or flex track defaults to a min-content floor, so a column will not
      shrink below its longest unbreakable word and pushes the whole page wide.
   2. At 200% text "Cardiovascular" sets at 72px, which is wider than a phone's
      text column no matter how the track is sized — so it has to be allowed to
      break rather than force the page to scroll sideways.
   Without these the homepage measured 530px of content in a 375px viewport. */
.hero .wrap > *, .wrap > * { min-width: 0; }
/* Nested grids need it too — the floor is per-track, so every grid container on
   the site has to release its children, not just the outermost one. */
.contact-grid > *, .banner > *, .wf-pair > *, .panel-grid > *, .icards > *,
.timeline > *, .steps > *, .stages > *, .msteps > *, .resp-grid > *,
.covers-grid > *, .form-row > *, .footer-grid > *, .opp-row > *,
.wf-row > *, .wf-final > *, .step > * { min-width: 0; }
h1, h2, h3, h4, p, li, dd, dt, figcaption, .lede { overflow-wrap: break-word; }
h4, h5, h6 { font-family: var(--font-body); font-weight: 600; }

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gutter); }

/* ---------- ACCESSIBILITY ---------- */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--ink); color: #fff; padding: 12px 20px;
  border-radius: 0 0 8px 0; font-size: 0.9rem; font-weight: 600;
}
.skip-link:focus { left: 0; }

:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 3px;
  border-radius: 4px;
}
/* --primary is 5.57:1 on white but only 1.86:1 on --ink, so the ring would all
   but vanish on the navy banner and footer. --on-navy carries 6.74:1 there. */
.site-footer :focus-visible, .banner :focus-visible { outline-color: var(--on-navy); }

/* Inline links in running text are underlined; navigation, buttons and card
   action labels are deliberately exempt. */
main p a:not(.btn), main li a:not(.btn), main dd a:not(.btn) {
  text-decoration: underline; text-underline-offset: 3px;
}

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

/* ---------- NAV ---------- */
header.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  background: rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}
header.nav.scrolled { border-bottom-color: var(--border); background: rgba(255, 255, 255, 0.92); }

/* Without JS the toggle can never open the panel, so the links must not be
   hidden behind it. The .no-js class is on <html> and is stripped inline in
   <head>, so this applies only when scripting is genuinely off: the header
   leaves the fixed layer, the toggle disappears, and the links wrap under the
   logo where they are always reachable. */
.no-js header.nav { position: static; background: var(--ground); }
.no-js .nav-inner { flex-wrap: wrap; }
.no-js .nav-toggle { display: none !important; }
.no-js .nav-links { display: flex !important; flex-wrap: wrap; }
.no-js .nav-cta { display: inline-flex !important; }

.nav-inner {
  max-width: var(--wrap); margin: 0 auto; padding: 14px var(--gutter);
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  min-height: 72px;
}

/* ---------- BRAND LOCKUP ----------
   The mark is inline SVG rather than an <img> so it stays vector-sharp and can
   inherit colours. The original asset used a luminance mask, which browsers
   rasterize at rendered size — that is what made it look soft at 34px. Here the
   halo is simply painted in the ground colour, so nothing rasterizes.
   The wordmark is live Manrope at -6% tracking, matching the logotype. */
.brand { display: flex; align-items: center; gap: 3px; }
.brand .mark { height: 34px; width: 34px; flex: none; overflow: visible; }
.brand .m-cube  { stroke: var(--mark-ink, var(--ink)); }
.brand .m-halo  { fill: var(--mark-ground, var(--ground)); stroke: var(--mark-ground, var(--ground)); }
.brand .m-heart { fill: var(--mark-accent, var(--brand-violet)); }
/* Wordmark weights and spacing are measured from cubie-fulllogo.svg, not eyeballed.
   Normalising stem width by cap height (36 units in both words) gives Cubie .1898
   and Health .1025; rasterising Manrope at each weight puts those at 800 and 400.
   The optical drop exists because the heart spikes above the cube, pulling the
   mark's ink centre upward — the logotype sits 3.80px lower to compensate, which
   align-items:center cannot know about. */
.brand .wordmark {
  font-family: var(--font-display); font-size: 1.28rem;
  /* Pinned, not inherited. patients.css sets body { line-height: 1.7 }, which
     resolved against this element's own 20.48px made the wordmark's line box
     taller than the 34px mark — so the wordmark set the flex line height and
     align-items:center pushed the mark 0.69px down on that page alone.
     1.6 is exactly what the other seven pages already computed. */
  line-height: 1.6;
  letter-spacing: -0.06em; color: var(--ink); white-space: nowrap;
  position: relative; top: 0.143em;      /* 2.93px at 20.48px */
  word-spacing: 0.118em;                 /* ink gap 6.2px, matching the lockup's 14.85/36 cap ratio */
}
.brand .wordmark b { font-weight: 800; }
.brand .wordmark i { font-weight: 400; font-style: normal; }

/* ---------- MOBILE MENU ---------- */
.nav-toggle {
  display: none; width: 44px; height: 44px; border: 1px solid var(--border);
  border-radius: 11px; background: var(--ground); cursor: pointer;
  align-items: center; justify-content: center; padding: 0;
}
.nav-toggle .bars { display: block; width: 18px; height: 12px; position: relative; }
.nav-toggle .bars i {
  position: absolute; left: 0; right: 0; height: 2px; border-radius: 2px;
  background: var(--ink); transition: transform 0.25s var(--ease), opacity 0.2s var(--ease);
}
.nav-toggle .bars i:nth-child(1) { top: 0; }
.nav-toggle .bars i:nth-child(2) { top: 5px; }
.nav-toggle .bars i:nth-child(3) { top: 10px; }
.nav-toggle[aria-expanded="true"] .bars i:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .bars i:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .bars i:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

[hidden] { display: none !important; }

.nav-panel {
  display: none;                       /* never shown on desktop */
  border-top: 1px solid var(--border); background: rgba(255,255,255,0.97);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  padding: 10px 20px 18px; flex-direction: column;
}
.nav-panel a {
  display: flex; align-items: center; min-height: 48px;
  padding: 12px 4px; font-size: 1.02rem; font-weight: 500; color: var(--ink);
  border-bottom: 1px solid var(--border);
}
.nav-panel a:last-child { border-bottom: 0; color: var(--primary); font-weight: 600; }

/* ---------- CUBE AMBIENT FIELD ----------
   Built from the logomark's rounded square rather than a generic dot grid. */
.cube-field { position: relative; overflow: hidden; }
.cube-field::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='104' height='104'%3E%3Crect x='26' y='26' width='52' height='52' rx='14' fill='none' stroke='%236E4CE0' stroke-width='1'/%3E%3C/svg%3E");
  opacity: 0.5;
  mask-image: radial-gradient(120% 90% at 78% 8%, rgba(0,0,0,0.09) 0%, rgba(0,0,0,0.05) 38%, transparent 72%);
  -webkit-mask-image: radial-gradient(120% 90% at 78% 8%, rgba(0,0,0,0.09) 0%, rgba(0,0,0,0.05) 38%, transparent 72%);
}
.cube-field > * { position: relative; z-index: 1; }
/* On a narrow viewport the tile is a large fraction of the width, so the field
   stops reading as ambient and starts reading as content. Shrink and fade it. */
@media (max-width: 700px) {
  .cube-field::before {
    background-size: 58px 58px;
    mask-image: radial-gradient(140% 60% at 88% 2%, rgba(0,0,0,0.05) 0%, transparent 62%);
    -webkit-mask-image: radial-gradient(140% 60% at 88% 2%, rgba(0,0,0,0.05) 0%, transparent 62%);
  }
}

/* Chrome pins the typography it depends on rather than inheriting it. patients.css
   sets body { line-height: 1.7 }; inherited, that made the nav's button taller,
   which made the bar taller, which pushed the centred logo down on that page
   alone. 1.6 is what every other page already computes, so nothing else moves. */
.nav-links {
  display: flex; align-items: center; gap: 30px;
  font-size: 0.93rem; font-weight: 500; line-height: 1.6; color: var(--ink-soft);
}
.nav-links a { transition: color 0.2s var(--ease); }
.nav-links a:hover { color: var(--primary); }
/* Colour and weight alone were far too quiet to answer "where am I". The rule
   underneath is the part that actually reads at a glance. */
.nav-links a { position: relative; padding-bottom: 4px; }
.nav-links a[aria-current="page"] { color: var(--ink); font-weight: 600; }
.nav-links a[aria-current="page"]::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px;
  height: 2px; border-radius: 2px; background: var(--primary);
}
.nav-panel a[aria-current="page"] { color: var(--primary); font-weight: 600; }

.nav-right { display: flex; align-items: center; gap: 20px; }

/* ---------- BUTTONS ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px 22px; border-radius: 100px; min-height: 48px;
  font-family: var(--font-body); font-weight: 600; font-size: var(--fs-btn);
  line-height: 1.6;                     /* pinned: see the note on .nav-links */
  text-align: center; white-space: normal;
  cursor: pointer; border: 1px solid transparent;
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease),
              background 0.25s var(--ease), border-color 0.25s var(--ease), color 0.25s var(--ease);
}
.btn-primary {
  background: var(--primary); color: #fff;
  box-shadow: 0 8px 20px -6px rgba(110, 76, 224, 0.5);
}
.btn-primary:hover {
  background: var(--primary-deep);
  transform: translateY(-2px);
  box-shadow: 0 12px 26px -6px rgba(110, 76, 224, 0.55);
}
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--border); }
.btn-ghost:hover { border-color: var(--primary); color: var(--primary); }
/* Only the padding shrinks. The label stays at --fs-btn so every button on the
   site is the same 16px, and the 48px floor still holds. */
.btn-sm { padding: 12px 20px; }

/* ---------- EYEBROW ---------- */
.eyebrow {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: var(--fs-eyebrow); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--primary); background: var(--tint);
  border: 1px solid var(--border); padding: 8px 16px; border-radius: 100px;
  margin-bottom: 22px;
}

/* ---------- HERO SCAFFOLD ---------- */
.hero { padding: var(--hero-top) 0 var(--hero-bot); }
.hero .wrap { display: grid; grid-template-columns: 1.05fr 0.95fr; align-items: center; gap: 48px; }

h1 { font-size: var(--fs-h1); line-height: 1.12; margin-bottom: 16px; }

/* Gradient lives on a rule beneath the headline, never on the letterforms.
   Filling display text with --brand-violet would drop it to 4.00:1. */
.rule-accent {
  width: 88px; height: 4px; border-radius: 4px; margin-bottom: 26px;
  background: linear-gradient(90deg, var(--accent-stops));
}

.lede { font-size: var(--fs-lede); color: var(--ink-soft); max-width: 64ch; margin-bottom: 34px; line-height: 1.6; }
.hero-ctas { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

/* ---------- SECTION HEADERS ---------- */
.section { padding: var(--section-y) 0; }
.section-soft { background: var(--bg-soft); }

/* Left-aligned is now the default: the business pages all lead from the left,
   and a centred introduction column reads as a landing page rather than a
   document. .left is retained as a no-op while existing markup still sets it. */
.section-head { max-width: 680px; margin: 0 0 var(--gap-intro); text-align: left; }
.section-head.left { text-align: left; }
h2 { font-size: var(--fs-h2); line-height: 1.18; margin-bottom: 16px; }
.section-head p { color: var(--ink-soft); font-size: var(--fs-body); line-height: 1.65; max-width: 64ch; }

h3 { font-size: var(--fs-h3); line-height: 1.25; font-weight: 700; margin-bottom: 10px; letter-spacing: -0.015em; }

/* ---------- FOOTER (navy ground) ---------- */
footer.site-footer { background: var(--ink); color: var(--navy-soft); padding: 56px 0 32px; font-size: 0.9375rem; line-height: 1.6; }
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 40px; margin-bottom: 44px; }
.footer-brand .footer-lockup { margin-bottom: 16px; --mark-ink: #EEF1F6; --mark-ground: var(--ink); }
.footer-brand .footer-lockup .wordmark { color: #fff; }
.footer-brand p { font-size: 0.9375rem; max-width: 340px; line-height: 1.6; }
.footer-col h4 {
  font-size: 0.76rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: #fff; margin-bottom: 16px; font-weight: 600;
}
.footer-col ul { list-style: none; display: flex; flex-direction: column; gap: 11px; font-size: 0.9375rem; }
.footer-col a:hover { color: var(--on-navy); }
.footer-bottom {
  border-top: 1px solid rgba(255,255,255,0.12); padding-top: 26px;
  display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap;
  font-size: var(--fs-meta); color: var(--navy-soft);
}

/* ---------- MOTION ----------
   Scroll-reveal hiding was removed here: nothing meant to be read may start at
   opacity 0 waiting on an observer, which is what a thumbnail, a paused tab and
   a printed page all get. The .reveal class is inert and is being stripped from
   the markup as each page is rebuilt. The hero motif's own keyframes are
   untouched and live in components.css. */

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

/* ---------- RESPONSIVE ----------
   Three ranges: phone below 600, tablet 600-1099, desktop 1100 and up. The nav
   collapses on its own boundary at 1024, because what decides that is whether
   five links plus the CTA still fit, not which type scale is in play. */

@media (max-width: 1099px) {
  :root {
    --fs-h1: 2.75rem;   /* 44 */
    --fs-h2: 2rem;      /* 32 */
    --fs-h3: 1.375rem;  /* 22 */
    --fs-lede: 1.125rem;/* 18 */
    --fs-body: 1rem;    /* 16 */
    --section-y: 72px; --hero-top: 116px; --hero-bot: 64px;
    --gap-intro: 36px; --gap-grid: 24px;
    --panel-pad: 28px; --mock-pad: 24px; --banner-pad: 36px; --form-pad: 28px;
  }
  .hero .wrap { grid-template-columns: 1fr; gap: 40px; }
  footer.site-footer { padding: 40px 0 28px; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .footer-brand { grid-column: 1 / -1; }   /* brand takes the first row alone */
}

@media (max-width: 1023px) {
  .nav-links { display: none; }
  .nav-toggle { display: flex; }
  .nav-cta { display: none; }
  .nav-panel:not([hidden]) { display: flex; }
  .nav-inner { min-height: 68px; }
}

@media (max-width: 599px) {
  :root {
    --fs-h1: 2.25rem;    /* 36 */
    --fs-h2: 1.75rem;    /* 28 */
    --fs-h3: 1.3125rem;  /* 21 */
    --gutter: 20px;
    --section-y: 56px; --hero-top: 104px; --hero-bot: 48px;
    --gap-intro: 32px; --gap-grid: 20px;
    --panel-pad: 24px; --mock-pad: 20px; --banner-pad: 28px; --form-pad: 20px;
  }
  .nav-inner { padding: 12px var(--gutter); }
  .hero-ctas { flex-direction: column; align-items: stretch; gap: 12px; }
  .hero-ctas .btn { width: 100%; }
  .footer-grid { grid-template-columns: 1fr; gap: 32px; }
}

/* ---------- PRINT ----------
   The fixed header, decorative layers and animation controls carry nothing on
   paper; everything meant to be read must survive. */
@media print {
  header.nav, .nav-panel, .skip-link { display: none !important; }
  .cube-field::before, .panel-tr::after, .panel-br::after,
  .banner::before, .banner::after { display: none !important; }
  /* Decorative layers carry nothing on paper: the tinted interval, every
     dashed connector, the responsibility markers and the circle halo. The
     ordered lists, their labels and the source text all survive. */
  .timeline::before, .resp-col::before,
  .tl-step::after, .step::before, .step::after, .mstep::after,
  .stage::after, .wf-caps li::after { display: none !important; }
  /* The step divider is a background layer now, and paper drops backgrounds. */
  .step:not(:last-child) { border-bottom: 1pt solid #999; }
  .mock, .facts li, .resp-grid { box-shadow: none !important; border: 1pt solid #999; }
  .mstep-n, .step-n, .stage-n, .wf-num, .tl-marker { box-shadow: none !important; }
  .mock-foot, .mock-status, .wf-final { background: #fff !important; }
  body { font-size: 11pt; line-height: 1.5; color: #000; background: #fff; }
  .section, .hero { padding: 18pt 0; }
  h1, h2, h3 { break-after: avoid-page; }
  .banner, .callout, .qa-emergency { border: 1pt solid #999; background: #fff !important; color: #000 !important; }
  .banner *, .site-footer * { color: #000 !important; }
  .site-footer { background: #fff !important; border-top: 1pt solid #999; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; }
}

/* Forced colors (Windows high contrast). The system replaces every colour, so
   anything that carried meaning through a tint alone loses it. Those cues get
   a border instead, and the purely decorative fills and shadows come off so
   they cannot sit on top of system-painted text. */
@media (forced-colors: active) {
  .timeline::before, .resp-col::before { display: none; }
  .mock, .facts li, .resp-grid, .panel { box-shadow: none; border: 1px solid CanvasText; }
  .mstep-n, .step-n, .stage-n, .wf-num { box-shadow: none; }
  /* Same reason as print: the divider's background is repainted away. */
  .step:not(:last-child) { border-bottom: 1px solid CanvasText; }
  /* Selection and status read through shape, not fill. */
  .mock-foot, .mock-status, .callout, .wf-final {
    border: 1px solid CanvasText;
  }
  .callout, .wf-final { border-left-width: 3px; }
  /* A gradient paints nothing here. */
  .mock-patient::before { background: CanvasText; }
}
