/* Pulsive - design tokens mirrored from the Figma file (Pulsive Tokens collection) */
:root {
  --ink: #1a1517;
  --ink-soft: #6e6460;
  --paper: #faf7f4;
  --surface: #ffffff;
  --crimson: #be123c;
  --crimson-deep: #8c0e2e;
  --crimson-tint: #fbe7eb;
  --green: #0b7a4b;
  --sand: #efe9e2;
  --sand-deep: #ddd5cc;
  --placeholder: #a39a96;

  /* Crimson is used two ways: as accent TEXT on a neutral surface, and as a
     saturated panel behind white text. Dark mode needs those to move in
     opposite directions, so the panel colour is its own constant. */
  --crimson-solid: #be123c;
  --success-tint: #e6f4ec;
  --success-ink: #085c39;
  --warn-tint: #fdf3e3;
  --warn-ink: #7a4c0d;
  --warn-edge: #e0a33c;
  /* Translucent paper for the sticky mobile nav; the dark theme needs its own
     or a cream bar sits over dark content. */
  --glass: rgba(250, 247, 244, 0.92);

  /* The stats band and the hospital path card sit on a near-black panel in
     both themes, so they cannot borrow --ink: that flips with the text. */
  --contrast-bg: #1a1517;
  --contrast-ink: #ffffff;
  --contrast-muted: #c9bfc2;

  --muted: #6e6460;

  --radius-card: 16px;
  --radius-input: 12px;
  --radius-pill: 999px;

  --display: "Sora", "Segoe UI", system-ui, sans-serif;
  --body: "Instrument Sans", "Segoe UI", system-ui, sans-serif;

  --shadow-card: 0 16px 48px rgba(26, 21, 23, 0.1);
  --shadow-chip: 0 10px 32px rgba(26, 21, 23, 0.1);
}

/* Dark theme. Applied as an attribute on <html> so the head script can set it
   before first paint and avoid a flash of the light theme. */
[data-theme="dark"] {
  --ink: #f5f0ec;
  --ink-soft: #b0a5a0;
  --paper: #14100f;
  --surface: #1e1918;
  --sand: #2a2322;
  --sand-deep: #3a3130;
  --placeholder: #8b7f7a;

  --crimson: #f87d99;
  --crimson-deep: #9c0f30;
  --crimson-tint: #3d1622;
  --green: #4ade9b;
  --success-tint: #123526;
  --success-ink: #6ee7a8;
  --warn-tint: #3a2a12;
  --warn-ink: #f0c274;
  --warn-edge: #a97c2a;

  --crimson-solid: #be123c;

  --glass: rgba(20, 16, 15, 0.92);

  --contrast-bg: #0a0708;
  --contrast-ink: #ffffff;
  --contrast-muted: #a89ea1;

  --muted: #b0a5a0;

  --shadow-card: 0 16px 48px rgba(0, 0, 0, 0.5);
  --shadow-chip: 0 10px 32px rgba(0, 0, 0, 0.45);
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.5;
}

h1, h2, h3, .display { font-family: var(--display); }

a { color: var(--crimson); }

:focus-visible {
  outline: 3px solid var(--crimson);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Keyboard users otherwise tab through the whole nav on every page. */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--crimson-solid); color: #fff;
  padding: 13px 20px; border-radius: 0 0 var(--radius-input) 0;
  font-weight: 600; font-size: 15px; text-decoration: none;
}
.skip-link:focus { left: 0; }

.wrap { max-width: 1200px; margin: 0 auto; padding: 0 24px; }

/* ------------------------------------------------------------- nav --- */
.nav {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 72px;
  border-bottom: 1px solid var(--sand);
  background: var(--paper);
}
.nav .links { display: flex; gap: 28px; margin-left: 24px; }
.nav .links a { color: var(--ink); text-decoration: none; font-weight: 500; }
.nav .links a:hover { color: var(--crimson); }
.nav .spacer { flex: 1; }
.nav .nav-toggle { display: none; }

/* Theme toggle. The icon shows the theme you would switch TO, so a moon in
   light mode and a sun in dark mode. */
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; padding: 0; border-radius: 50%;
  background: transparent; border: 1px solid var(--sand-deep);
  color: var(--ink); cursor: pointer; flex: none;
}
.theme-toggle:hover { border-color: var(--crimson); color: var(--crimson); }
.theme-toggle svg { width: 18px; height: 18px; }
.theme-toggle .icon-sun { display: none; }
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }
[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--ink); font-family: var(--display); font-weight: 700; font-size: 22px; }
.mark {
  width: 38px; height: 38px; border-radius: 11px; background: var(--crimson-solid);
  display: grid; place-items: center;
}
.mark svg { width: 15px; height: 18px; fill: #fff; }

/* ---------------------------------------------------------- buttons --- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 14px 22px; border-radius: var(--radius-pill);
  font-weight: 600; font-size: 15px; font-family: var(--body);
  border: 1.5px solid transparent; cursor: pointer; text-decoration: none;
  transition: transform 0.12s ease, background 0.2s ease, border-color 0.2s ease;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--crimson-solid); color: #fff; }
.btn-primary:hover { background: var(--crimson-deep); }
.btn-ghost { background: var(--paper); color: var(--ink); border-color: var(--ink); }
.btn-ghost:hover { background: var(--sand); }
.btn-white { background: var(--surface); color: var(--crimson); }
.btn-white:hover { background: var(--crimson-tint); }
.btn-white-ink { background: var(--surface); color: var(--ink); }
.btn-block { width: 100%; }
.btn[disabled] { opacity: 0.55; cursor: not-allowed; }

/* ------------------------------------------------------------- hero --- */
.hero { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 48px; align-items: center; padding: 64px 0 80px; }
.eyebrow { font-family: var(--display); font-size: 12px; font-weight: 600; letter-spacing: 0.14em; color: var(--crimson); margin: 0 0 24px; }
.hero h1 { font-size: clamp(40px, 5vw, 60px); line-height: 1.08; letter-spacing: -0.02em; margin: 0 0 20px; }
.hero p.lede { font-size: 19px; color: var(--ink-soft); max-width: 34ch; margin: 0 0 32px; }
.hero .ctas { display: flex; gap: 14px; flex-wrap: wrap; }

.hero-visual { position: relative; min-height: 480px; }
.blob { position: absolute; width: 420px; height: 420px; border-radius: 50%; background: var(--crimson-tint); top: 10px; right: 40px; }
.droplet { position: absolute; width: 130px; top: 0; right: 0; fill: var(--crimson); }

.request-card {
  position: absolute; top: 110px; left: 0; width: 420px;
  background: var(--surface); border: 1px solid var(--sand); border-radius: 20px;
  padding: 28px; box-shadow: var(--shadow-card);
}
/* Not a heading: the whole hero visual is aria-hidden decorative, and an
   empty <h3> before the fetch resolves was an h1->h3 skip in the outline. */
.request-card-title {
  font-family: var(--display); font-size: 22px; font-weight: 700;
  color: var(--ink); margin: 14px 0 8px; line-height: 1.25;
}
.request-card p { color: var(--ink-soft); margin: 0 0 14px; font-size: 15px; }
.meta { display: flex; gap: 16px; font-size: 14px; margin-bottom: 20px; }
.meta strong { font-weight: 600; }
.meta span { color: var(--ink-soft); }

.donor-chip {
  position: absolute; bottom: 0; left: 30px;
  display: flex; align-items: center; gap: 12px;
  background: var(--surface); border: 1px solid var(--sand); border-radius: 16px;
  padding: 14px 18px; box-shadow: var(--shadow-chip);
}
.avatar { width: 40px; height: 40px; border-radius: 50%; background: var(--crimson-tint); color: var(--crimson); display: grid; place-items: center; font-family: var(--display); font-weight: 600; font-size: 14px; }
.donor-chip .name { font-weight: 600; font-size: 14px; }
.donor-chip .meta-line { font-size: 12px; color: var(--green); }

.badge {
  display: inline-block; padding: 6px 12px; border-radius: var(--radius-pill);
  background: var(--crimson-tint); color: var(--crimson);
  font-family: var(--display); font-size: 11px; font-weight: 600; letter-spacing: 0.08em;
}
.badge.green { background: var(--success-tint); color: var(--green); }
.badge.neutral { background: var(--sand); color: var(--ink-soft); letter-spacing: 0; }

/* ------------------------------------------------------------ stats --- */
.stats { background: var(--contrast-bg); color: var(--contrast-ink); padding: 40px 0; }
.stats .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; text-align: center; }
.stats .num { font-family: var(--display); font-size: 44px; font-weight: 700; line-height: 1.1; }
.stats .lbl { color: var(--contrast-muted); font-size: 15px; }

/* -------------------------------------------------------- sections --- */
.section { padding: 88px 0; }
.section h2 { font-size: 40px; letter-spacing: -0.01em; margin: 0 0 40px; }
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; }
.step { background: var(--surface); border: 1px solid var(--sand); border-radius: 20px; padding: 30px; }
.step .n { width: 44px; height: 44px; border-radius: 50%; background: var(--crimson-tint); color: var(--crimson); display: grid; place-items: center; font-family: var(--display); font-weight: 700; margin-bottom: 16px; }
.step h3 { font-size: 21px; margin: 0 0 10px; }
.step p { color: var(--ink-soft); font-size: 15px; margin: 0; }

.paths { display: grid; grid-template-columns: 1fr 1fr; gap: 32px; padding-bottom: 88px; }
.path { border-radius: 28px; padding: 46px 42px; }
.path.donor { background: var(--crimson-solid); color: #fff; }
.path.hospital { background: var(--contrast-bg); color: var(--contrast-ink); }
.path h3 { font-size: 30px; margin: 0 0 14px; }
.path p { margin: 0 0 26px; max-width: 44ch; }
.path.donor p { color: #f6d7de; }
.path.hospital p { color: var(--contrast-muted); }

/* ------------------------------------------------------------ forms --- */
.form-page { padding: 48px 0 96px; display: grid; place-items: start center; }
.form-card { width: 100%; max-width: 560px; background: var(--surface); border: 1px solid var(--sand); border-radius: 24px; padding: 40px 36px; }
.form-card h1 { font-size: 30px; margin: 0 0 8px; }
.form-card .sub { color: var(--ink-soft); font-size: 15px; margin: 0 0 28px; }
.field { margin-bottom: 18px; }
.field label { display: block; font-weight: 600; font-size: 14px; margin-bottom: 8px; }
.field input, .field select, .field textarea {
  width: 100%; padding: 14px 16px; font-size: 15px; font-family: var(--body);
  border: 1.5px solid var(--sand); border-radius: var(--radius-input);
  background: var(--surface); color: var(--ink);
}
.field input::placeholder, .field textarea::placeholder { color: var(--placeholder); }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--crimson); outline: none; }
.field .hint { font-size: 12px; color: var(--ink-soft); margin-top: 8px; }
.field .error { font-size: 13px; color: var(--crimson); margin-top: 8px; font-weight: 500; }
.field.invalid input, .field.invalid select { border-color: var(--crimson); }
.row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

/* Date of birth: three selects in one control, no native date picker chrome. */
.dob { display: grid; grid-template-columns: 1fr 1.9fr 1.3fr; gap: 8px; }
.dob select {
  width: 100%; padding: 14px 12px; font-size: 15px; font-family: var(--body);
  border: 1.5px solid var(--sand); border-radius: var(--radius-input);
  background: var(--surface); color: var(--ink); cursor: pointer;
  appearance: none; -webkit-appearance: none; text-align: center;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
                    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 16px) calc(50% + 2px), calc(100% - 11px) calc(50% + 2px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 30px;
}
.dob select:hover { border-color: var(--sand-deep); }
.dob select:focus { border-color: var(--crimson); outline: none; }
.dob select:invalid, .dob select option[disabled] { color: var(--placeholder); }
select:disabled, .field select:disabled { background-color: var(--sand); color: var(--placeholder); cursor: not-allowed; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  padding: 9px 16px; border-radius: var(--radius-pill); border: 1.5px solid var(--sand);
  background: var(--surface); font-weight: 600; font-size: 14px; cursor: pointer; font-family: var(--body); color: var(--ink);
}
.chip[aria-pressed="true"] { background: var(--crimson-solid); border-color: var(--crimson-solid); color: #fff; }

.checkbox { display: flex; gap: 12px; align-items: flex-start; font-size: 14px; color: var(--ink-soft); margin-bottom: 20px; }
.checkbox input { width: 18px; height: 18px; margin-top: 2px; accent-color: var(--crimson); }

.notice { border-radius: 12px; padding: 14px 16px; font-size: 14px; margin-bottom: 20px; }
.notice.ok { background: var(--success-tint); color: var(--green); }
.notice.err { background: var(--crimson-tint); color: var(--crimson); }
.notice[hidden] { display: none; }

/* ---------------------------------------------------------- request --- */
.board { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 24px; }
.req {
  background: var(--surface); border: 1px solid var(--sand); border-radius: 20px; padding: 24px;
  display: flex; flex-direction: column; gap: 12px;
}
.req h3 { font-size: 19px; margin: 0; }
.req .badge { align-self: flex-start; }
.req .where { color: var(--ink-soft); font-size: 14px; margin: 0; }
.req .notes { font-size: 14px; color: var(--ink-soft); margin: 0; }
.req .foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: auto; padding-top: 8px; }
.units { font-family: var(--display); font-weight: 700; font-size: 18px; }
.units small { display: block; font-family: var(--body); font-weight: 400; font-size: 12px; color: var(--ink-soft); }

.toolbar { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; margin-bottom: 32px; }
.toolbar .field { margin: 0; min-width: 180px; }
.empty { text-align: center; padding: 64px 24px; color: var(--ink-soft); }
.skeleton { background: linear-gradient(90deg, var(--sand), var(--surface), var(--sand)); background-size: 200% 100%; animation: shimmer 1.4s linear infinite; border-radius: 20px; height: 220px; }
@keyframes shimmer { to { background-position: -200% 0; } }

.pill-count { display: inline-block; background: var(--crimson-tint); color: var(--crimson); border-radius: var(--radius-pill); padding: 4px 12px; font-size: 13px; font-weight: 600; }

/* ----------------------------------------------------------- table --- */
.table { width: 100%; border-collapse: collapse; background: var(--surface); border: 1px solid var(--sand); border-radius: 16px; overflow: hidden; }
.table th, .table td { text-align: left; padding: 14px 18px; font-size: 14px; border-top: 1px solid var(--sand); }
.table th { font-weight: 600; background: var(--sand); border-top: 0; }

/* ---------------------------------------------------------- footer --- */

/* ------------------------------------------------------- verification --- */
.tabs { display: flex; gap: 6px; margin-bottom: 16px; background: var(--sand); padding: 4px; border-radius: var(--radius-pill); }
.tab {
  flex: 1; padding: 10px 14px; border: 0; border-radius: var(--radius-pill); cursor: pointer;
  background: transparent; font-family: var(--body); font-size: 14px; font-weight: 600; color: var(--ink-soft);
  transition: background 0.2s ease, color 0.2s ease;
}
.tab[aria-pressed="true"] { background: var(--surface); color: var(--ink); box-shadow: 0 1px 3px rgba(26, 21, 23, 0.12); }
.tab:focus-visible { outline: 3px solid var(--crimson); outline-offset: 1px; }

.verify-block { margin-bottom: 8px; }
.optional { font-weight: 400; color: var(--placeholder); font-size: 13px; }

.verify-panel { margin-top: 14px; padding: 16px; border-radius: var(--radius-input); font-size: 14px; }
.verify-panel[hidden] { display: none; }
.verify-panel.ok { background: var(--success-tint); color: var(--success-ink); }
.verify-panel.warn { background: var(--warn-tint); color: var(--warn-ink); }
.verify-panel.err { background: var(--crimson-tint); color: var(--crimson); }
.verify-title { font-family: var(--display); font-weight: 600; margin: 0 0 10px; }
.verify-note { margin: 10px 0 0; font-size: 12px; opacity: 0.85; }
.verify-panel p { margin: 0; }

.checks { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.check { display: flex; align-items: baseline; gap: 8px; font-size: 13px; }
.check-label { font-weight: 600; }
.check-detail { opacity: 0.8; margin-left: auto; text-align: right; }
.mark-sm { font-weight: 700; width: 16px; text-align: center; }
.check.ok .mark-sm { color: var(--green); }
.check.bad .mark-sm { color: var(--crimson); }
.check.skip { opacity: 0.6; }

/* Pulsive is a coordination layer, never a clinical one. The research on the
   National Blood Service Commission Act made this the single most effective
   risk mitigation available, so it is stated plainly rather than buried.

   It leads the footer because on this product it is the trust signal, not
   fine print. Icon and lead give it a reading position the old wall of 13px
   text never had. */
.clinical-boundary {
  border-top: 1px solid var(--sand);
  background: var(--sand);
  padding: 36px 0;
}
.boundary-inner { display: flex; align-items: flex-start; gap: 18px; }
.boundary-mark {
  flex: none; width: 40px; height: 40px; border-radius: 12px;
  display: grid; place-items: center;
  background: var(--surface); color: var(--crimson);
  border: 1px solid var(--sand-deep);
}
.boundary-mark svg { width: 21px; height: 21px; }
.boundary-copy { max-width: 78ch; }
.boundary-lead {
  font-family: var(--display); font-size: 17px; font-weight: 600;
  color: var(--ink); margin: 0 0 8px; line-height: 1.35;
}
.boundary-body { font-size: 14px; line-height: 1.65; color: var(--ink-soft); margin: 0; }
/* Per-page reassurance: hashed NINs, hashed licence IDs, request visibility. */
.boundary-note {
  font-size: 13px; color: var(--crimson); margin: 10px 0 0;
  display: inline-flex; align-items: center; gap: 7px;
}
.boundary-note::before {
  content: ""; width: 5px; height: 5px; border-radius: 50%;
  background: currentColor; flex: none;
}

/* ------------------------------------------------------------- footer --- */
/* Three tiers with deliberate rhythm: brand and navigation, then a quiet meta
   rail. The old single row gave all four items equal weight and no path. */
.footer { border-top: 1px solid var(--sand); background: var(--paper); padding: 56px 0 28px; }
.footer-top {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 40px; align-items: start;
  padding-bottom: 36px;
}
.footer-brand .brand { margin-bottom: 12px; }
.footer-tagline { font-size: 15px; color: var(--ink-soft); margin: 0; max-width: 30ch; }

.footer-nav { display: flex; gap: 64px; }
.footer-col { display: flex; flex-direction: column; gap: 10px; }
.footer-col-title {
  font-family: var(--body); font-size: 11px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-soft); margin: 0 0 4px;
}
.footer-col a {
  color: var(--ink); text-decoration: none; font-size: 15px; font-weight: 500;
  transition: color 0.18s ease;
}
.footer-col a:hover { color: var(--crimson); }

.footer-meta {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 12px 24px; padding-top: 22px;
  border-top: 1px solid var(--sand);
  font-size: 13px; color: var(--ink-soft);
}
.footer-meta-links { margin-left: auto; }

.mono { font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; }
.page-title { font-family: var(--display); font-size: 40px; letter-spacing: -0.01em; margin: 0 0 8px; }

/* ------------------------------------------------------------ motion --- */
/* Every animation below is gated behind .js + prefers-reduced-motion: no-preference,
   so no-JS and reduced-motion users get the full static page. */
@media (prefers-reduced-motion: no-preference) {
  :root { --ease-out: cubic-bezier(0.16, 1, 0.3, 1); }

  /* 1. Hero entrance: one orchestrated load moment, in reading order.
        No base `opacity: 0` here. With fill-mode `backwards` the hidden state
        lives in the `from` keyframe, which applies during the delay and then
        releases; a base opacity of 0 would re-apply on release and leave the
        headline permanently invisible. */
  .js .hero .eyebrow,
  .js .hero h1,
  .js .hero .lede,
  .js .hero .ctas > * {
    animation: rise 0.75s var(--ease-out) backwards;
  }
  .js .hero .eyebrow { animation-delay: 0.05s; }
  .js .hero h1 { animation-delay: 0.15s; }
  .js .hero .lede { animation-delay: 0.28s; }
  .js .hero .ctas > *:nth-child(1) { animation-delay: 0.4s; }
  .js .hero .ctas > *:nth-child(2) { animation-delay: 0.48s; }

  /* 2. Hero visual: fades and drifts in after the copy, then settles into a
        slow ambient loop.

        Entrances use fill-mode `backwards` rather than `both` on purpose. `both`
        keeps applying the final keyframe forever, which locks the element's
        transform and silently kills every hover transform inside it — including
        the hero CTA buttons. `backwards` hides the element during its delay,
        then releases it once the entrance ends, so :hover works again.

        Each ambient loop is delayed to start the instant its entrance releases
        (cardIn ends at 1.35s, dropIn at 1.2s, blobIn at 1.3s), so the two
        animations never claim `transform` at the same time. All loops are
        alternate + infinite: they return to rest and read as a slow sway rather
        than a loop with a visible seam. */
  .js .request-card { animation: cardIn 0.9s var(--ease-out) 0.45s backwards, float 6s ease-in-out 1.35s infinite alternate; }
  .js .donor-chip { animation: cardIn 0.8s var(--ease-out) 0.75s backwards; }
  .js .droplet { animation: dropIn 0.9s var(--ease-out) 0.3s backwards, bob 4s ease-in-out 1.2s infinite alternate; transform-origin: 50% 0%; }
  .js .blob { animation: blobIn 1.1s var(--ease-out) 0.2s backwards, drift 9s ease-in-out 1.3s infinite alternate; }

  /* 2c. The urgent badge is the one thing on screen saying "act now", so it gets
        the fastest pulse. box-shadow only — no transform, so it never contends
        with the card's float. */
  .js .request-card .badge { animation: breathe 2.4s ease-in-out 2s infinite; }

  /* 2d. The matched-donor chip deliberately does not loop. It is the payoff of
        the card above it, and a floating payoff competes with it. It lifts on
        hover instead. */
  .donor-chip { transition: transform 0.3s var(--ease-out, ease), box-shadow 0.3s var(--ease-out, ease); }
  .donor-chip:hover { transform: translateY(-3px); box-shadow: 0 16px 40px rgba(26, 21, 23, 0.14); }

  /* 3. Scroll reveal. app.js observes these elements and adds .is-in when they
        scroll into view; the selectors MUST match REVEAL_SELECTOR there.

        These were previously styled only as `.reveal`, a class nothing but the
        request board ever adds — so the observer was marking elements that were
        never hidden, and every section appeared instantly with no motion.

        The hidden state is applied via `.js .will-reveal`, a class app.js adds
        only to elements it has just handed to a live IntersectionObserver.
        Hiding the bare selectors instead would mean anything the observer fails
        to reach stays invisible forever. Content must fail open. */
  .js .will-reveal {
    opacity: 0;
    transform: translateY(26px);
    /* 400ms, not 700ms: a section arriving while the previous one is still
       settling reads as lag rather than as a cascade. */
    transition: opacity 0.4s var(--ease-out), transform 0.4s var(--ease-out);
    transition-delay: var(--reveal-delay, 0s);
  }
  .js .will-reveal.is-in { opacity: 1; transform: none; }

  /* 4. Feedback: cards lift, buttons press, chips confirm a choice. */
  /* Card hover is seen tens of times a session, so it runs at UI speed
     rather than the 0.35s it used to take. */
  .req { transition: transform 0.18s var(--ease-out), box-shadow 0.18s var(--ease-out), border-color 0.18s ease; }
  .req:hover { transform: translateY(-4px); box-shadow: var(--shadow-card); border-color: var(--sand-deep); }
  .btn { transition: transform 0.14s var(--ease-out), background 0.2s ease, border-color 0.2s ease; }
  .btn:hover { transform: translateY(-2px); }
  /* One press state for every motion setting. 0.99 was too small to feel. */
  .btn:active { transform: scale(0.97); }
  .chip { transform: scale(1); transition: transform 0.18s var(--ease-out), background 0.2s ease, border-color 0.2s ease, color 0.2s ease; }
  .chip:hover { transform: translateY(-2px); }
  /* A transition, not a keyframe: picking one chip then another retargets
     smoothly instead of restarting a pop from zero. */
  .chip[aria-pressed="true"] { transform: scale(1.04); }
  .notice:not([hidden]) { animation: rise 0.4s var(--ease-out) both; }
  .nav a, .links a { transition: color 0.2s ease; }

  /* 5. Live state only: an open request is a real, changing fact, so its
     urgency badge breathes. Nothing else loops.
     The ring is a static box-shadow on a pseudo-element and only its opacity
     is animated, so the loop stays on the compositor instead of repainting. */
  .req .badge:not(.neutral) { position: relative; }
  .req .badge:not(.neutral)::after {
    content: ""; position: absolute; inset: 0; border-radius: inherit;
    box-shadow: 0 0 0 5px rgba(190, 18, 60, 0.14);
    opacity: 0; pointer-events: none;
  }
  .req .badge:not(.neutral) { animation: breathe 3.2s ease-in-out 1.2s infinite; }
}

@keyframes rise { from { opacity: 0; transform: translateY(22px); } to { opacity: 1; transform: none; } }
@keyframes cardIn { from { opacity: 0; transform: translateY(28px) scale(0.98); } to { opacity: 1; transform: none; } }
@keyframes dropIn { from { opacity: 0; transform: translateY(-24px) scale(0.9); } to { opacity: 1; transform: none; } }
@keyframes blobIn { from { opacity: 0; transform: scale(0.86); } to { opacity: 1; transform: none; } }


/* Ambient loops. Each is a small, alternating displacement that starts and
   ends at rest, so `alternate` produces a continuous sway with no seam. The
   card moves against the droplet's phase (4s vs 6s, coprime-ish) so the two
   never fall into a shared beat and read as one rigid object. */
@keyframes bob { from { transform: translateY(0); } to { transform: translateY(-9px); } }
@keyframes float { from { transform: translateY(0); } to { transform: translateY(-6px); } }
@keyframes drift {
  from { transform: translate(0, 0) scale(1); }
  to { transform: translate(-14px, 10px) scale(1.045); }
}
/* Toast: a transition rather than a keyframe. Toasts arrive in bursts and a
   second one must retarget mid-flight, not restart from zero. */
#toast {
  transition: transform 200ms var(--ease-out, ease), opacity 200ms var(--ease-out, ease);
}
#toast[hidden] { opacity: 0; transform: translateY(16px); }
#toast:not([hidden]) { opacity: 1; transform: none; }
@keyframes breathe {
  0%, 100% { opacity: 0; }
  50% { opacity: 1; }
}

/* --------------------------------------------------------- responsive --- */
@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; gap: 40px; padding: 40px 0 56px; }
  .hero h1 { font-size: clamp(34px, 8vw, 48px); }
  .hero p.lede { font-size: 17px; max-width: 40ch; }
  .hero-visual { min-height: 0; }
  .request-card { position: static; width: auto; }
  .donor-chip { position: static; margin-top: 16px; display: inline-flex; }
  .blob, .droplet { display: none; }
  .steps, .paths { grid-template-columns: 1fr; }
  .section { padding: 56px 0; }
  .section h2 { font-size: 30px; }
  .row { grid-template-columns: 1fr; }
  /* Nav collapses to a toggle; the panel is the same markup, just stacked. */
  .nav { flex-wrap: wrap; height: auto; }
  .nav .links { display: none; }
  .nav .links.is-open {
    display: flex; flex-direction: column; gap: 0;
    width: 100%; margin-left: 0;
    border-top: 1px solid var(--sand);
  }
  .nav .links.is-open a { padding: 14px 0; border-bottom: 1px solid var(--sand); }
  .nav .nav-toggle { display: inline-flex; }
  .board { grid-template-columns: 1fr; }
  /* Footer: navigation stops competing with the brand for the first row. */
  .footer-top { grid-template-columns: 1fr; gap: 32px; }
  .footer-nav { gap: 48px; }
}

@media (max-width: 720px) {
  .wrap { padding: 0 20px; }

  /* Nav: sticky, and one primary action instead of two competing ones. */
  .nav {
    position: sticky; top: 0; z-index: 20; min-height: 64px; height: auto;
    padding-top: 10px; padding-bottom: 10px;
    background: var(--glass);
    -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  }
  .nav .mark { width: 34px; height: 34px; border-radius: 10px; }
  .nav .brand { font-size: 20px; }
  .nav .btn { padding: 12px 18px; }

  /* Touch targets: 44px minimum on anything tappable. */
  .btn, .chip, .mark, .theme-toggle { min-height: 44px; }
  .theme-toggle { width: 44px; }
  .chip { padding: 12px 18px; }
  .hero .ctas { flex-direction: column; align-items: stretch; }
  .hero .ctas .btn { width: 100%; }
  .page-title { font-size: 30px; }

  /* Forms: full-bleed cards, roomier controls, no truncation. */
  .form-page { padding: 24px 0 64px; }
  .form-card { padding: 28px 20px; border-radius: 20px; }
  .form-card h1 { font-size: 26px; }
  .field input, .field select, .field textarea { padding: 15px 14px; min-height: 48px; }
  .dob { grid-template-columns: 1fr 1.5fr 1.1fr; }
  .dob select { padding: 15px 26px 15px 10px; text-align: left; }
  .toolbar { flex-direction: column; align-items: stretch; }
  .toolbar .field { min-width: 0; }

  /* Sections: tighter rhythm, readable on a phone. */
  .section { padding: 44px 0; }
  .section h2 { font-size: 26px; margin-bottom: 28px; }
  .step, .path { padding: 24px 20px; border-radius: 20px; }
  .path h3 { font-size: 24px; }
  .stats .num { font-size: 32px; }
  .stats .lbl { font-size: 13px; }
  .stats .grid { gap: 12px; }
  .footer { padding: 40px 0 24px; }
  .footer-top { gap: 28px; padding-bottom: 28px; }
  .footer-nav { gap: 36px; }
  .footer-col a { min-height: 44px; display: inline-flex; align-items: center; }
  .footer-meta { flex-direction: column; align-items: flex-start; gap: 10px; }
  .footer-meta-links { margin-left: 0; }
  .boundary-inner { gap: 14px; }
  .boundary-mark { width: 34px; height: 34px; border-radius: 10px; }
  .boundary-mark svg { width: 18px; height: 18px; }
  .boundary-lead { font-size: 16px; }
  .req .foot { flex-direction: column; align-items: stretch; gap: 12px; }
  .req .foot .btn { width: 100%; }
}

@media (max-width: 420px) {
  .wrap { padding: 0 16px; }
  .hero h1 { font-size: 32px; }
  .hero .ctas { gap: 12px; }
  .form-card { padding: 24px 16px; }
  .chips { gap: 6px; }
  .chip { padding: 10px 14px; font-size: 13px; }
  .stats .grid { grid-template-columns: 1fr; gap: 20px; }
  .dob { grid-template-columns: 1fr; }
  .board { gap: 16px; }
  #toast { left: 16px; right: 16px; transform: none; max-width: none; }
}

@media (hover: none) {
  /* No hover on touch: lift only on the states that still exist. */
  .req:hover { transform: none; box-shadow: none; }
  .btn:hover, .chip:hover { transform: none; }
}

/* Reduced motion: stop the decorative movement, but keep the transitions that
   carry state (a chip confirming, a panel opening, a toast arriving). A blanket
   0.001ms kill on * removes that feedback along with the ambience. */
@media (prefers-reduced-motion: reduce) {
  .blob, .droplet, .request-card, .donor-chip, .js .request-card .badge,
  .req .badge:not(.neutral), .skeleton {
    animation: none !important;
  }
  .js .will-reveal { transition: none !important; transform: none !important; }
  html { scroll-behavior: auto; }
}

/* Demo mode: make it impossible to mistake a sample lookup for a real check. */
.demo-banner {
  border: 1.5px solid var(--warn-edge);
  background: var(--warn-tint);
  color: var(--warn-ink);
  border-radius: var(--radius-input);
  padding: 14px 16px;
  font-size: 14px;
  margin-bottom: 20px;
}
.demo-banner[hidden] { display: none; }
.demo-banner strong { font-family: var(--display); }

/* ------------------------------------------------------------- legal --- */
.legal { max-width: 760px; }
.legal h1 { font-size: clamp(34px, 6vw, 46px); letter-spacing: -0.02em; margin: 0 0 16px; }
.legal .lede { font-size: 19px; color: var(--ink-soft); max-width: 56ch; margin: 0 0 32px; }
.legal h2 { font-size: 22px; margin: 40px 0 12px; letter-spacing: -0.01em; }
.legal p { margin: 0 0 14px; }
.legal ul { margin: 0 0 18px; padding-left: 20px; }
.legal li { margin-bottom: 8px; }
.legal strong { font-weight: 600; }
.legal-alert {
  border: 1.5px solid var(--warn-edge);
  background: var(--warn-tint);
  color: var(--warn-ink);
  border-radius: var(--radius-input);
  padding: 18px 20px;
  font-size: 14px;
  margin-bottom: 8px;
}
.legal-alert strong { display: block; margin-bottom: 4px; font-family: var(--display); }

/* ------------------------------------------------------------- print --- */
/* Scroll-reveal hides sections until they enter the viewport, so anything the
   observer never reached would print blank. Print what the reader cannot see. */
@media print {
  .js .will-reveal { opacity: 1 !important; transform: none !important; }
  .nav { position: static; }
  .nav .links { display: flex !important; }
  .nav-toggle { display: none !important; }
}

/* --------------------------------- dashboard & simulation enhancements --- */

.dash-header {
  margin-bottom: 32px;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
}

.profile-card {
  background: var(--surface);
  border: 1px solid var(--sand-deep);
  border-radius: var(--radius-card);
  padding: 24px;
  box-shadow: var(--shadow-card);
  margin-bottom: 32px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.profile-main {
  display: flex;
  align-items: center;
  gap: 18px;
}

.blood-avatar {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--crimson-solid);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--display);
  font-size: 24px;
  font-weight: 700;
  flex-shrink: 0;
  box-shadow: 0 4px 16px rgba(190, 18, 60, 0.35);
}

.profile-info h2 {
  margin: 0 0 6px;
  font-size: 22px;
}

.profile-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

.profile-actions {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

/* Toggle switch */
.switch-wrap {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
}

.switch {
  position: relative;
  display: inline-block;
  width: 48px;
  height: 26px;
}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0; left: 0; right: 0; bottom: 0;
  background-color: var(--sand-deep);
  transition: .3s;
  border-radius: 34px;
}

.slider:before {
  position: absolute;
  content: "";
  height: 20px;
  width: 20px;
  left: 3px;
  bottom: 3px;
  background-color: white;
  transition: .3s;
  border-radius: 50%;
  box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}

input:checked + .slider {
  background-color: var(--green);
}

input:checked + .slider:before {
  transform: translateX(22px);
}

/* Metric stat grid */
.metric-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  margin-bottom: 32px;
}

.metric-card {
  background: var(--surface);
  border: 1px solid var(--sand-deep);
  border-radius: var(--radius-card);
  padding: 20px;
  box-shadow: var(--shadow-card);
}

.metric-card .val {
  font-size: 32px;
  font-family: var(--display);
  font-weight: 700;
  color: var(--ink);
  line-height: 1.1;
  margin-bottom: 4px;
}

.metric-card .lbl {
  font-size: 13px;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
}

/* Tabs */
.tabs-nav {
  display: flex;
  gap: 8px;
  border-bottom: 1.5px solid var(--sand-deep);
  margin-bottom: 24px;
  overflow-x: auto;
  padding-bottom: 2px;
}

.tab-btn {
  background: transparent;
  border: none;
  font-family: var(--body);
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-soft);
  padding: 10px 18px;
  cursor: pointer;
  border-radius: var(--radius-input) var(--radius-input) 0 0;
  position: relative;
  transition: color 0.2s, background 0.2s;
  white-space: nowrap;
}

.tab-btn:hover {
  color: var(--ink);
}

.tab-btn.is-active {
  color: var(--crimson);
  border-bottom: 3px solid var(--crimson);
  margin-bottom: -2px;
}

.tab-badge {
  background: var(--sand);
  color: var(--ink);
  padding: 2px 7px;
  border-radius: var(--radius-pill);
  font-size: 12px;
  margin-left: 6px;
}

.tab-btn.is-active .tab-badge {
  background: var(--crimson-tint);
  color: var(--crimson);
}

/* Progress bar */
.progress-wrap {
  margin: 12px 0 8px;
}

.progress-bar {
  height: 8px;
  background: var(--sand);
  border-radius: var(--radius-pill);
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: var(--crimson);
  border-radius: var(--radius-pill);
  transition: width 0.4s ease;
}

.progress-fill.full {
  background: var(--green);
}

.progress-meta {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  color: var(--ink-soft);
  margin-top: 4px;
}

/* Responses list */
.donor-response-box {
  background: var(--sand);
  border-radius: var(--radius-input);
  padding: 14px 16px;
  margin-top: 16px;
  font-size: 14px;
}

.donor-response-box h4 {
  margin: 0 0 10px;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
}

.pledge-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--sand-deep);
}

.pledge-row:last-child {
  border-bottom: none;
}

.pledge-phone {
  font-family: monospace;
  font-size: 13px;
  color: var(--ink);
  background: var(--surface);
  padding: 2px 8px;
  border-radius: 4px;
  border: 1px solid var(--sand-deep);
}

/* Matrix & Simulation Styles */
.matrix-container {
  overflow-x: auto;
  margin: 24px 0;
  background: var(--surface);
  border: 1px solid var(--sand-deep);
  border-radius: var(--radius-card);
  padding: 20px;
  box-shadow: var(--shadow-card);
}

.matrix-table {
  width: 100%;
  border-collapse: collapse;
  text-align: center;
  font-size: 14px;
}

.matrix-table th, .matrix-table td {
  padding: 10px;
  border: 1px solid var(--sand-deep);
}

.matrix-table th {
  background: var(--sand);
  font-family: var(--display);
  font-weight: 600;
}

.matrix-cell {
  transition: all 0.2s;
  cursor: pointer;
}

.matrix-cell.exact {
  background: var(--crimson-tint);
  color: var(--crimson);
  font-weight: 700;
}

.matrix-cell.compat {
  background: var(--success-tint);
  color: var(--success-ink);
  font-weight: 600;
}

.matrix-cell.incompat {
  background: transparent;
  color: var(--placeholder);
}

.matrix-cell.highlight {
  outline: 2px solid var(--crimson);
  transform: scale(1.05);
}

/* Simulation Pipeline */
.sim-pipeline {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin: 24px 0;
}

.sim-stage {
  background: var(--surface);
  border: 1px solid var(--sand-deep);
  border-radius: var(--radius-card);
  padding: 18px 22px;
  transition: border-color 0.3s, box-shadow 0.3s;
}

.sim-stage.active {
  border-color: var(--crimson);
  box-shadow: 0 0 0 1px var(--crimson), var(--shadow-card);
}

.sim-stage-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.sim-stage-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--display);
  font-size: 16px;
  font-weight: 600;
}

.sim-num {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--sand);
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
}

.sim-stage.active .sim-num {
  background: var(--crimson);
  color: #fff;
}

/* Log stream */
.log-stream {
  background: var(--contrast-bg);
  color: var(--contrast-ink);
  font-family: monospace;
  font-size: 13px;
  border-radius: var(--radius-input);
  padding: 16px;
  max-height: 320px;
  overflow-y: auto;
  line-height: 1.6;
}

.log-entry {
  margin-bottom: 6px;
  display: flex;
  gap: 8px;
}

.log-tag {
  color: #f87d99;
  font-weight: bold;
}

.log-tag.INGESTION { color: #60a5fa; }
.log-tag.COMPATIBILITY_ANALYSIS { color: #34d399; }
.log-tag.RANKING { color: #fbbf24; }
.log-tag.DISPATCH { color: #f472b6; }
.log-tag.PLEDGE_RECEIVED { color: #4ade80; }
.log-tag.STATUS_UPDATE { color: #38bdf8; }

.scenario-picker {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}

.scenario-card {
  background: var(--surface);
  border: 2px solid var(--sand-deep);
  border-radius: var(--radius-card);
  padding: 18px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.scenario-card:hover {
  border-color: var(--crimson);
  transform: translateY(-2px);
}

.scenario-card.selected {
  border-color: var(--crimson);
  background: var(--crimson-tint);
}

.scenario-card h3 {
  font-size: 17px;
  margin: 0 0 6px;
}

.scenario-card p {
  font-size: 13px;
  color: var(--ink-soft);
  margin: 0 0 10px;
}

/* Modal Drawer */
.modal-backdrop {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(0,0,0,0.6);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  backdrop-filter: blur(4px);
}

.modal-backdrop[hidden] {
  display: none;
}

.modal-box {
  background: var(--surface);
  border-radius: var(--radius-card);
  max-width: 600px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  padding: 28px;
  box-shadow: 0 24px 64px rgba(0,0,0,0.3);
  position: relative;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.modal-close {
  background: transparent;
  border: none;
  font-size: 24px;
  cursor: pointer;
  color: var(--ink-soft);
}

/* Auth & Privacy Access Gates */
.auth-gate {
  max-width: 580px;
  margin: 32px auto 60px;
  background: var(--surface);
  border: 1px solid var(--sand-deep);
  border-radius: var(--radius-card);
  padding: 36px 32px;
  box-shadow: 0 12px 36px rgba(0,0,0,0.06);
}

.auth-gate h2 {
  font-size: 22px;
  margin: 0 0 8px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.auth-privacy-notice {
  font-size: 13px;
  color: var(--ink-soft);
  background: var(--surface-muted);
  border-left: 3px solid var(--crimson);
  padding: 10px 14px;
  border-radius: 4px;
  margin: 16px 0 24px;
  line-height: 1.5;
}

.demo-chip-group {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px dashed var(--sand-deep);
}

.demo-chip-group p {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 8px;
}

.demo-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.demo-chip {
  font-size: 12px;
  padding: 6px 12px;
  border-radius: 20px;
  background: var(--surface-muted);
  border: 1px solid var(--sand-deep);
  cursor: pointer;
  transition: all 0.15s ease;
  font-family: inherit;
  color: var(--ink);
}

.demo-chip:hover {
  border-color: var(--crimson);
  color: var(--crimson);
  background: rgba(190, 18, 60, 0.05);
}

.auth-status-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--surface-muted);
  border: 1px solid var(--sand-deep);
  border-radius: var(--radius-card);
  padding: 12px 18px;
  margin-bottom: 24px;
}

.auth-badge-role {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 3px 8px;
  border-radius: 4px;
  background: var(--crimson);
  color: #fff;
}

/* Global Development Status Banner */
.global-dev-banner,
.global-sandbox-banner {
  background: var(--sand);
  color: var(--ink);
  border-bottom: 1px solid var(--sand-deep);
  font-size: 13px;
  line-height: 1.5;
  padding: 8px 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 12px;
  position: relative;
  z-index: 9999;
  text-align: center;
  font-family: var(--body);
}

[data-theme="dark"] .global-dev-banner,
[data-theme="dark"] .global-sandbox-banner {
  background: var(--surface);
  border-bottom-color: var(--sand-deep);
}

.global-dev-badge,
.global-sandbox-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(190, 18, 60, 0.1);
  color: var(--crimson);
  border: 1px solid rgba(190, 18, 60, 0.25);
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  flex-shrink: 0;
}

[data-theme="dark"] .global-dev-badge,
[data-theme="dark"] .global-sandbox-badge {
  background: rgba(248, 125, 153, 0.15);
  color: var(--crimson);
  border-color: rgba(248, 125, 153, 0.3);
}

.dev-pulse-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--crimson);
  display: inline-block;
  box-shadow: 0 0 0 0 rgba(190, 18, 60, 0.4);
  animation: pulse-dot 2s infinite;
}

@keyframes pulse-dot {
  0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(190, 18, 60, 0.6); }
  70% { transform: scale(1); box-shadow: 0 0 0 5px rgba(190, 18, 60, 0); }
  100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(190, 18, 60, 0); }
}

.global-dev-text {
  font-size: 13px;
  color: var(--ink-soft);
}

.global-dev-text strong {
  color: var(--ink);
}

.global-dev-banner a,
.global-sandbox-banner a {
  color: var(--crimson);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.global-dev-banner a:hover,
.global-sandbox-banner a:hover {
  color: var(--crimson-deep);
}



