:root {
  color-scheme: dark;
  --ink: #eeeeee;
  --muted: #999999;
  --line: #343d46;
  --paper: #1a1f23;
  --surface: #1e2327;
  --group: #23292f;
  --row-open: #1f2a22;
  --drill: #1c2226;
  --accent: #89df00;
  --accent-strong: #24ae1d;
  /* liatrio.ai's nav sits at white/80 over the header; #c5c8c9 is that mix, flattened. */
  --nav-ink: #c5c8c9;
  /* The six responsibility cells: title close to white at 14.9:1, body lifted from --muted's
     5.56:1 to 8.65:1 on --surface, both measured. */
  --owns-title: #f7f8f8;
  --owns-body: #bcc0c2;
  --brand-green: #89df00;
  --focus-ring: var(--accent);
  --lime: #c6f135;
  --lagoon: #00c1db;
  /* Links take the brand green rather than a pale cyan that appears nowhere else in
     the palette. #89df00 is 10:1 on --paper and 9.5:1 on --surface. */
  --link: #89df00;
  /* Hero banner. Measured off the supplied cut so the drawing keeps the art's own values
     rather than borrowing --line and --accent, which are tuned for type and controls. */
  --banner-line: #353b3d;
  --banner-band-fill: #31501c;
  --banner-band-stroke: #7cc02f;
  --banner-mark: #89df00;
  --banner-dot-dim: #7f888b;
  --banner-dot-lime: #d9ef3b;
  --banner-dot-violet: #b668f3;
  --banner-dot-green: #8ade10;
  --radius: 0.75rem;
  --tip-bg: #f8f9fa;
  --tip-fg: #111111;
  --yes: #89df00;
  --yes-bg: #143a12;
  --paid: #f77f00;
  --paid-bg: #3a2408;
  --paid-ink: var(--paid);
  --no: #e63946;
  --no-bg: #3a1418;
  /* Hot Red #e63946 is 3.80:1 on graphite; small labels need this lifted mix. */
  --no-ink: #ff8088;
  --unk: #cccccc;
  --unk-bg: #2a3036;
  --na: #999999;
}

:root[data-theme="light"] {
  color-scheme: light;
  --ink: #111111;
  /* #666666 is 4.29:1 on the splash-stat tile; #555555 holds ≥4.5:1 there. */
  --muted: #555555;
  --line: #dddddd;
  --paper: #f8f9fa;
  --surface: #ffffff;
  --group: #eeeeee;
  --row-open: #eef8e8;
  --drill: #f8f9fa;
  --accent: #24ae1d;
  --accent-strong: #24ae1d;
  --nav-ink: #404040;
  /* Light mode's equivalent of the same move is downward: #4a4a4a is 8.86:1 on white,
     against --muted's 7.46:1. Lightening here would cost contrast, not gain it. */
  --owns-title: #111111;
  --owns-body: #4a4a4a;
  --brand-green: #187a14;
  --focus-ring: #0e6414;
  --lime: #6b9a00;
  --lagoon: #006989;
  /* Light's brand green, the same hex --brand-green uses here: 5.5:1 on white,
     where Bright Green is 1.9:1 and Primary Green 3.4:1. */
  --link: #187a14;
  --banner-line: #a5acad;
  --banner-band-fill: #ffffff;
  --banner-band-stroke: #97d04b;
  --banner-mark: #4e9e1f;
  --banner-dot-dim: #98a0a1;
  --banner-dot-lime: #a8bf14;
  --banner-dot-violet: #a25fcf;
  --banner-dot-green: #6fb500;
  --tip-bg: #1a1f23;
  --tip-fg: #eeeeee;
  --yes: #187a14;
  --yes-bg: #e8f8e6;
  /* Meter/fill stays orange; #c45f00 as text is 3.79:1 on --paid-bg. */
  --paid: #c45f00;
  --paid-bg: #fff1e0;
  /* #a14d00 reaches 5.2:1 at 8pt bold on --paid-bg. */
  --paid-ink: #a14d00;
  --no: #c1121f;
  --no-bg: #fde8ea;
  --no-ink: var(--no);
  --unk: #666666;
  --unk-bg: #eeeeee;
  --na: #999999;
}

* {
  box-sizing: border-box;
}

html {
  scroll-padding-top: var(--masthead-h, 5.5rem);
}

body {
  margin: 0;
  font-family: "Space Grotesk", "Segoe UI", sans-serif;
  color: var(--ink);
  background: var(--paper);
  line-height: 1.5;
}

.shell {
  max-width: 1200px;
  margin: 0 auto;
  padding: 1.5rem 1.25rem 4rem;
}

.masthead {
  position: sticky;
  top: 0;
  z-index: 20;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}

.masthead::before {
  content: "";
  display: block;
  height: 2px;
  background: linear-gradient(90deg, var(--accent-strong) 0 4rem, var(--line) 4rem);
}

.masthead .shell {
  padding-bottom: 1.25rem;
}

.masthead-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.masthead-identity {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  min-width: 0;
}

.brand-lockup {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  text-decoration: none;
}

.brand-lockup .logomark {
  display: none;
  height: 1.7rem;
  width: auto;
}

.brand-lockup .wordmark {
  height: 1.55rem;
  width: auto;
}

.brand-lockup .wordmark-dark,
.site-foot-brand .wordmark-dark {
  display: block;
}

.brand-divider {
  width: 2px;
  height: 2.35rem;
  background: var(--line);
  flex-shrink: 0;
}

.site-nav-toggle,
.site-nav-scrim {
  display: none;
}

.masthead-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.35rem;
  flex-shrink: 0;
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.35rem;
}

.site-nav-link,
.site-map-btn {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 0.375rem;
  background: var(--paper);
  color: var(--ink);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-decoration: none;
}

/* liatrio.ai's main nav is text, not buttons: each item sits at 80% of the body colour and
   turns Bright Green on hover and while it is the current page. Matching that means undoing
   the button treatment above rather than tuning it — a bordered pill with a green ring on
   hover and a separate underline for the current page was three affordances where the
   reference has one colour change. The site-map button keeps the pill; it is a control. */
.site-nav-link {
  flex-direction: column;
  text-align: center;
  min-height: 2.55rem;
  padding: 0.28rem 0.65rem;
  border: 0;
  border-radius: 0.25rem;
  background: none;
  color: var(--nav-ink);
  font-weight: 500;
  line-height: 1.15;
  transition: color 120ms ease;
}

.site-nav-line {
  display: block;
}

.site-map-btn:hover,
.site-map-btn:focus-visible {
  border-color: var(--focus-ring);
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.site-nav-link:hover {
  color: var(--brand-green);
}

/* The current page is the same green, held rather than hovered, with the weight carrying the
   rest — aria-current is on the link, so this is not the only signal. */
.site-nav-link.is-current {
  color: var(--brand-green);
  font-weight: 700;
}

@media (min-width: 961px) {
  /* #363 asks for the CTA in the nav, not below it. .masthead-actions stacks by default —
     the drawer on one row, anything after it on the next — so on desktop the container
     becomes a row and the CTA lands at the end of the nav line. */
  .masthead-actions {
    flex-direction: row;
    align-items: center;
    gap: 0.6rem;
  }

  .site-nav-drawer {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-end;
    gap: 0.35rem;
  }
}

@media (max-width: 960px) {
  .masthead-identity {
    flex-wrap: nowrap;
    gap: 0.55rem;
    min-width: 0;
    flex: 1;
  }

  .brand-divider {
    display: none;
  }

  .brand-lockup {
    width: auto;
  }

  .masthead-title {
    min-width: 0;
  }

  .masthead h1 {
    font-size: 1rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 52vw;
  }

  .masthead-actions {
    flex-direction: row;
    align-items: center;
    gap: 0.4rem;
    width: 2.55rem;
    height: 2.55rem;
  }

  .site-nav-toggle {
    display: inline-flex;
    position: relative;
    z-index: 50;
    align-items: center;
    justify-content: center;
    width: 2.55rem;
    height: 2.55rem;
    margin: 0;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: 0.375rem;
    background: var(--paper);
    color: var(--ink);
    cursor: pointer;
  }

  .site-nav-toggle:hover,
  .site-nav-toggle:focus-visible {
    border-color: var(--focus-ring);
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
  }

  .site-nav-toggle-bars,
  .site-nav-toggle-bars::before,
  .site-nav-toggle-bars::after {
    display: block;
    width: 1.05rem;
    height: 2px;
    background: currentColor;
    border-radius: 1px;
  }

  .site-nav-toggle-bars {
    position: relative;
  }

  .site-nav-toggle-bars::before,
  .site-nav-toggle-bars::after {
    content: "";
    position: absolute;
    left: 0;
  }

  .site-nav-toggle-bars::before {
    top: -5px;
  }

  .site-nav-toggle-bars::after {
    top: 5px;
  }

  body.nav-open .site-nav-toggle-bars {
    background: transparent;
  }

  body.nav-open .site-nav-toggle-bars::before {
    top: 0;
    transform: rotate(45deg);
  }

  body.nav-open .site-nav-toggle-bars::after {
    top: 0;
    transform: rotate(-45deg);
  }

  .site-nav-drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.65rem;
    width: 80vw;
    max-width: 80vw;
    padding: 4.5rem 1.1rem 1.35rem;
    background: var(--surface);
    border-left: 1px solid var(--line);
    box-shadow: -12px 0 32px rgb(0 0 0 / 0.28);
    transform: translateX(100%);
    visibility: hidden;
    /* visibility is stepped: delay its flip to hidden until the slide-out
       transform finishes so the drawer stays interactable during close, but
       flip to visible immediately on open so bindNavDrawer can move focus
       into the drawer for the WCAG 2.4.3 focus trap. */
    transition: transform 0.2s ease, visibility 0s linear 0.2s;
    overflow: auto;
  }

  body.nav-open .site-nav-drawer {
    transform: none;
    visibility: visible;
    transition: transform 0.2s ease, visibility 0s linear 0s;
  }

  .site-nav {
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0.45rem;
  }

  .site-nav-link {
    flex-direction: row;
    justify-content: flex-start;
    gap: 0.3em;
    width: 100%;
    min-height: 2.75rem;
    padding: 0.55rem 0.75rem;
    text-align: left;
  }

  .site-nav-line {
    display: inline;
  }

  .site-nav-line + .site-nav-line::before {
    content: " ";
  }

  /* The drawer has room for words, so the icon keeps its label there. */
  .site-nav-drawer .theme-toggle {
    width: 100%;
    height: 2.75rem;
    justify-content: flex-start;
    padding: 0.55rem 0.75rem;
    margin-top: auto;
  }

  .site-nav-drawer .theme-toggle-text {
    display: inline;
  }

  .site-nav-drawer .copy-btn-share {
    width: 100%;
    min-width: 0;
    min-height: 2.75rem;
    height: 2.75rem;
    justify-content: flex-start;
    gap: 0.5rem;
    padding: 0.55rem 0.75rem;
    margin: 0;
    opacity: 1;
  }

  .site-nav-drawer .copy-btn-share .copy-btn-text {
    display: inline;
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip: auto;
  }

  .site-nav-scrim {
    display: block;
    position: fixed;
    inset: 0 80vw 0 0;
    z-index: 35;
    margin: 0;
    padding: 0;
    border: 0;
    background: rgb(0 0 0 / 0.45);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
  }

  body.nav-open .site-nav-scrim {
    opacity: 1;
    pointer-events: auto;
  }

  body.nav-open {
    overflow: hidden;
  }
}

.site-foot {
  border-top: 1px solid var(--line);
  background: var(--surface);
}

.site-foot .shell {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.25rem;
  padding-top: 1.25rem;
  padding-bottom: 1.5rem;
}

.site-foot-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  text-decoration: none;
}

.site-foot-brand .wordmark {
  height: 1.35rem;
  width: auto;
}

.brand-lockup .wordmark-light,
.site-foot-brand .wordmark-light,
:root[data-theme="light"] .brand-lockup .wordmark-dark,
:root[data-theme="light"] .site-foot-brand .wordmark-dark {
  display: none;
}

:root[data-theme="light"] .brand-lockup .wordmark-light,
:root[data-theme="light"] .site-foot-brand .wordmark-light {
  display: block;
}

@media (max-width: 960px) {
  .brand-lockup .wordmark,
  .brand-lockup .wordmark-dark,
  .brand-lockup .wordmark-light,
  :root[data-theme="light"] .brand-lockup .wordmark-dark,
  :root[data-theme="light"] .brand-lockup .wordmark-light {
    display: none;
  }

  .brand-lockup .logomark,
  :root[data-theme="light"] .brand-lockup .logomark {
    display: block;
  }
}

.site-foot-kicker {
  color: var(--muted);
  font-size: 0.78rem;
  letter-spacing: 0.02em;
}

/* The icon names the theme the click switches to: a sun while dark, a moon
   while light. It is drawn as a mask so it takes the button's text colour. */
:root {
  --theme-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='4.25'/%3E%3Cpath d='M12 2.6v2.4M12 19v2.4M2.6 12H5M19 12h2.4M5.3 5.3L7 7M17 17l1.7 1.7M18.7 5.3L17 7M7 17l-1.7 1.7'/%3E%3C/svg%3E");
}

:root[data-theme="light"] {
  --theme-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M20.4 14.8A8.6 8.6 0 0 1 9.2 3.6 8.6 8.6 0 1 0 20.4 14.8Z'/%3E%3C/svg%3E");
}

.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  flex-shrink: 0;
  width: 2.55rem;
  height: 2.55rem;
  margin: 0;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 0.375rem;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
}

.theme-toggle::before {
  content: "";
  flex-shrink: 0;
  width: 1.15rem;
  height: 1.15rem;
  background: currentColor;
  -webkit-mask: var(--theme-icon) center / contain no-repeat;
  mask: var(--theme-icon) center / contain no-repeat;
}

.theme-toggle:hover,
.theme-toggle:focus-visible {
  border-color: var(--focus-ring);
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.theme-toggle-text {
  display: none;
}

.theme-label-light {
  display: none;
}

.theme-label-dark {
  display: inline;
}

:root[data-theme="light"] .theme-label-light {
  display: inline;
}

:root[data-theme="light"] .theme-label-dark {
  display: none;
}

h1 {
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0 0 0.35rem;
  text-wrap: balance;
}

.masthead h1 {
  font-size: 1.35rem;
  margin: 0;
}

@media (max-width: 960px) {
  .masthead h1 {
    font-size: 1rem;
  }
}

.masthead p {
  margin: 0;
  color: var(--muted);
  max-width: 42rem;
}

a {
  color: var(--link);
  text-decoration-color: color-mix(in srgb, var(--link) 45%, transparent);
  text-underline-offset: 0.15em;
}

a:hover {
  text-decoration-color: currentColor;
}

button:focus-visible,
a:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.masthead h1,
.fit-card h3,
.headline h3 {
  color: var(--ink);
}

/* Nav links and the nav CTA carry their own colour, and .masthead a is specific enough
   (0,1,1) to outrank .site-nav-link or .site-cta (0,1,0) — which is how the nav ended up
   painting body ink over the values set for it, and how the CTA ended up at #eeeeee on
   Bright Green, 1.43:1. Exclude them here rather than escalating every rule to match. */
.masthead a:not(.site-nav-link):not(.site-cta) {
  color: var(--ink);
}

.err {
  color: var(--no-ink);
}

.hint,
.tag {
  color: var(--muted);
  font-size: 0.78rem;
}

.tag {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 0.75rem;
}

.wrap {
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

/* The /matrix/ page is the grid on its own, with no nested scroller: the
   document scrolls on both axes. Column min-widths set the floor; the table
   fills available width when there is room and pans horizontally when not. */
.matrix-full table {
  min-width: 0;
  border: 1px solid var(--line);
  background: var(--surface);
}

/* Sticky cells now pin against the viewport, so they need the masthead's real
   height as an offset instead of sitting behind it. */
.matrix-full thead th {
  top: var(--masthead-h, 5.5rem);
}

/* Unlike the masthead, cells can slide: the table is their containing block and
   it is the thing overflowing, so pinning the first column keeps the
   requirement labels readable while the page pans right. /matrix/ is the only
   grid, and it pins against the viewport, so the rules hang off #matrix. */
#matrix tbody tr:not(.group-row, .area-row) th {
  position: sticky;
  left: 0;
  z-index: 1;
  /* tbody th is already var(--surface); without it the pills would slide through
     the pinned column instead of under it. border-collapse: collapse drops the
     borders off a pinned cell, so the right-hand rule is drawn as a shadow that
     travels with the column. */
  box-shadow: inset -1px 0 0 var(--line);
  white-space: normal;
  max-width: 10.5rem;
  min-width: 7.5rem;
}

#matrix th,
#matrix td {
  padding: 0.45rem 0.45rem;
}

#matrix thead th.gateway-head {
  padding-left: 0.7rem;
  padding-right: 0.7rem;
}

/* The corner cell pins on both axes, so it has to sit above both sticky edges,
   and it carries both the header's bottom rule and the column's right one. */
#matrix thead th:first-child {
  left: 0;
  z-index: 3;
  min-width: 7.5rem;
  max-width: 10.5rem;
  box-shadow: inset -1px -1px 0 var(--line);
}

/* A tier heading spans the whole table, so pinning the cell would drag the band
   along with the scroll. Pinning the text inside it keeps the heading readable
   over the pills while the band stays put. The offset matches the cell padding,
   so nothing moves until the label would otherwise leave the scroll box. */
#matrix .group-row th {
  background-image: none;
  padding-left: 0.7rem;
}

#matrix .group-row .group-label {
  position: sticky;
  left: 0.7rem;
  display: inline-block;
  padding-left: 1.35rem;
  background: url("logomark_Liatrio.svg?v=2dae709") no-repeat 0 center;
  background-size: auto 0.85rem;
}

#matrix .area-row th {
  padding: 0.45rem 0.7rem;
  background: color-mix(in srgb, var(--group) 62%, var(--surface));
  color: var(--ink);
  font-size: 0.76rem;
  font-weight: 700;
}

#matrix .area-row .area-label {
  position: sticky;
  left: 0.7rem;
  display: inline-block;
}

.area-kind {
  display: inline-block;
  margin-right: 0.55rem;
  color: var(--muted);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* A sticky masthead drifts left once the document scrolls horizontally: its
   containing block is only as wide as the viewport, so there is nothing to
   slide against. Fixing it anchors the bar on both axes; main then reserves the
   height the bar no longer occupies in flow. */
body[data-page="matrix"] .masthead {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}

body[data-page="matrix"] main.shell {
  max-width: none;
  padding-top: calc(var(--masthead-h, 5.5rem) + 1.5rem);
}

#summaries,
#adoption,
#matrix {
  scroll-margin-top: calc(var(--masthead-h, 5.5rem) + 0.5rem);
}

table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.85rem;
}

th,
td {
  border-bottom: 1px solid var(--line);
  padding: 0.55rem 0.7rem;
  text-align: left;
  vertical-align: top;
}

thead th {
  background: var(--surface);
  position: sticky;
  top: 0;
  z-index: 2;
  font-weight: 600;
  /* border-collapse: collapse drops borders off sticky cells while they are
     pinned, so draw the rule with a shadow that travels with the header. */
  box-shadow: inset 0 -1px 0 var(--line);
}

/* Gateway columns share leftover width. Extra horizontal padding keeps the
   score bars from reading as one continuous strip across the row. */
thead th.gateway-head {
  min-width: 6.75rem;
  width: 6.75rem;
  padding-left: 0.65rem;
  padding-right: 0.65rem;
}

/* A fixed two-line box: names that wrap fill it, names that do not (LiteLLM,
   Bifrost) leave the second line empty and their meter still lines up. */
.gateway-head-name {
  display: block;
  min-height: 2.6em;
  max-height: 2.6em;
  line-height: 1.3;
  font-size: 0.72rem;
  overflow: hidden;
  overflow-wrap: break-word;
  hyphens: auto;
}

thead th.gateway-head a {
  color: var(--ink);
  text-decoration: none;
}

thead th.gateway-head a:hover,
thead th.gateway-head a:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.col-meter {
  display: flex;
  height: 0.35rem;
  margin: 0.45rem auto 0.25rem;
  overflow: hidden;
  border-radius: 999px;
  background: var(--unk-bg);
  max-width: 4.75rem;
  width: 100%;
}

.col-meter-seg {
  min-width: 0;
}

.col-meter-seg.yes {
  background: var(--yes);
}

.col-meter-seg.paid {
  background: var(--paid);
}

.col-meter-seg.no {
  background: var(--no);
}

.col-meter-seg.unknown {
  background: var(--unk);
}

.col-meter-seg.na {
  background: var(--na);
}

.col-watch {
  display: block;
  color: var(--muted);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.col-watch.is-gap {
  color: var(--no-ink);
}

/* Same meter on a gateway page, between the scores note and the requirement
   table. There is room here for the counts the matrix heading has to hover. */
.gateway-meter {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.3rem 0.6rem;
  margin: 0.75rem 0 0;
}

.gateway-meter .col-meter {
  flex: 0 0 12rem;
  max-width: none;
  margin: 0;
}

.gateway-meter-counts {
  color: var(--muted);
  font-size: 0.75rem;
}

.matrix-read {
  max-width: 46rem;
  margin: 0 0 0.85rem;
  color: var(--ink);
  font-size: 0.92rem;
  line-height: 1.45;
}

tbody th {
  font-weight: 500;
  white-space: nowrap;
  background: var(--surface);
}

.sub {
  display: block;
  color: var(--muted);
  font-weight: 400;
  font-size: 0.75rem;
}

.cell-link {
  display: inline-block;
  text-decoration: none;
}

/* Every hover note on the site is one of these. The cursor is the whole point: it
   is the only feedback a reader gets before the note appears, and the native `title`
   attribute this replaced changed no cursor at all. */
.mark-tip {
  cursor: help;
}

/* A matrix cell carries the note and the link inside it is what you click. Without
   this the browser's own pointer cursor for links would win over the inherited help
   cursor, so the feedback would change halfway across a single cell. */
.mark-tip .cell-link {
  cursor: help;
}

.mark-tip:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

#tooltip-float {
  position: fixed;
  z-index: 20;
  width: max-content;
  max-width: 22rem;
  padding: 0.45rem 0.55rem;
  border-radius: 0.5rem;
  background: var(--tip-bg);
  color: var(--tip-fg);
  font-size: 0.72rem;
  font-weight: 400;
  line-height: 1.35;
  /* Matrix headings and cells hand over multi-line hover text, one line per field. */
  white-space: pre-line;
}

tbody tr.row-open th,
tbody tr.row-open td {
  background: var(--row-open);
}

tbody tr.row-open th {
  box-shadow: inset 3px 0 0 var(--accent);
}

.group-row th {
  background: var(--group) url("logomark_Liatrio.svg?v=2dae709") no-repeat 0.75rem center;
  background-size: auto 0.85rem;
  border-bottom: 1px solid var(--line);
  box-shadow: inset 0 2px 0 var(--accent-strong);
  padding: 0.65rem 0.7rem 0.65rem 2.05rem;
  color: var(--ink);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.035em;
  text-transform: uppercase;
}

.row-pillar {
  display: block;
  margin-bottom: 0.15rem;
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 500;
}

.hard-stop {
  display: inline-block;
  margin-left: 0.5rem;
  color: var(--no-ink);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.source {
  color: var(--muted);
  font-size: 0.75rem;
  max-width: 22rem;
}

.drill-toggle {
  display: inline;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  white-space: normal;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: var(--line);
  text-underline-offset: 0.15em;
}

.drill-toggle:hover,
.drill-toggle:focus-visible {
  text-decoration-color: currentColor;
}

.drill-toggle[aria-expanded="true"] {
  font-weight: 650;
}

.drill-toggle::after {
  content: "▸";
  margin-left: 0.35rem;
  color: var(--muted);
  font-size: 0.7rem;
  text-decoration: none;
}

.drill-toggle[aria-expanded="true"]::after {
  content: "▾";
}

.drill-row > td {
  background: var(--surface);
  padding: 0;
}

.drill {
  padding: 0.9rem 1rem 1rem;
  border-left: 3px solid var(--accent);
  background: var(--drill);
}

.drill h3 {
  margin: 0;
  font-size: 0.95rem;
}

.drill-head {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}

.drill-head .copy-btn {
  flex-shrink: 0;
  margin: 0;
}

.drill-meta {
  margin: 0.15rem 0 0.75rem;
  color: var(--muted);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.drill dl {
  display: grid;
  grid-template-columns: 9rem minmax(0, 1fr);
  gap: 0.4rem 1rem;
  margin: 0;
}

.drill dt {
  color: var(--muted);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.drill dd {
  margin: 0;
  max-width: 52rem;
}

.drill .source-list {
  padding-left: 1.1rem;
}

.drill-links {
  margin: 0.85rem 0 0;
  font-size: 0.78rem;
  color: var(--muted);
}

.local-copy,
.source-third-party {
  font-size: 0.72rem;
  color: var(--muted);
}

.source-more {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.7rem;
  color: var(--muted);
}

@media (max-width: 780px) {
  .drill dl {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.15rem;
  }

  .drill dt {
    margin-top: 0.5rem;
  }
}

.sources p {
  max-width: 46rem;
  color: var(--muted);
  font-size: 0.9rem;
}

.source-list {
  margin: 0;
  padding-left: 1.2rem;
}

.source-list a {
  word-break: break-all;
}

.pill {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  padding: 0.15rem 0.45rem;
  border-radius: 999px;
}

.yes {
  color: var(--yes);
  background: var(--yes-bg);
}

.paid {
  color: var(--paid-ink);
  background: var(--paid-bg);
}

.no {
  color: var(--no-ink);
  background: var(--no-bg);
}

.unknown {
  color: var(--unk);
  background: var(--unk-bg);
}

.fact {
  color: var(--ink);
  background: var(--unk-bg);
  text-transform: none;
  letter-spacing: 0;
}

.na {
  color: var(--na);
  background: var(--unk-bg);
}

/* Status icons for the matrix grid. Lucide glyphs, which is the Liatrio icon set, in a
   tinted chip that reuses the same status tokens as the word pills above, so a cell and
   its legend entry cannot drift apart. The token values are already the published brand
   hexes (Bright Green, Flame Orange, Hot Red, Grey 300, Grey 400), so nothing new is
   introduced here and the light theme keeps its darkened, AA-passing variants.

   Shape carries the status and colour repeats it. Greyscale printing, a screenshot in a
   deck, and any colour vision deficiency all still resolve the grid. */
.mark {
  --mark-fg: var(--unk);
  --mark-bg: var(--unk-bg);
  display: inline-flex;
  align-items: flex-start;
  gap: 0.03rem;
  line-height: 1;
  vertical-align: middle;
}

.mark-yes {
  --mark-fg: var(--yes);
  --mark-bg: var(--yes-bg);
}

.mark-paid {
  --mark-fg: var(--paid-ink);
  --mark-bg: var(--paid-bg);
}

.mark-no {
  --mark-fg: var(--no-ink);
  --mark-bg: var(--no-bg);
}

.mark-unknown {
  --mark-fg: var(--unk);
  --mark-bg: var(--unk-bg);
}

.mark-na {
  --mark-fg: var(--na);
  --mark-bg: var(--unk-bg);
}

.mark-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--mark-fg) 42%, transparent);
  background: var(--mark-bg);
  color: var(--mark-fg);
}

.mark-glyph {
  width: 0.82rem;
  height: 0.82rem;
}

/* `~` (integration-backed yes) and `†` (native no with a workaround) are the notation the
   rest of the site already explains, so a modified cell keeps its status glyph and takes
   a small mark rather than a colour or shape of its own. */
.mark-mod {
  margin-top: -0.1em;
  color: var(--mark-fg);
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1;
}

/* Icon-only cells scan far better centred under their column name. Only gateway cells are
   `td`; the requirement label and the tier bands are `th` and keep their left edge. */
#matrix tbody td {
  text-align: center;
}

/* The glyph is what a reader compares down a column, so it holds the centre line alone and
   the denotation hangs off its right edge. In flow, a `~` or a `†` adds width to the
   cell's centred content and pulls the glyph left, so a column steps in and out wherever a
   score carries one. The eye reads that step as a difference in score, which is the one
   thing the modifier is not. Zero width settles every glyph on the same line while the
   mark still paints and still follows the glyph in reading order. */
#matrix tbody td .mark {
  gap: 0;
}

#matrix tbody td .mark-mod {
  flex: 0 0 0;
  width: 0;
  min-width: 0;
  transform: translateX(0.06rem);
}

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  margin: 0 0 1rem;
  font-size: 0.8rem;
  color: var(--muted);
}

/* The capability filter sits between the legend and the grid on both pages. It is a
   details box because thirty checkboxes printed above the matrix would push the grid
   off screen, and the reader who wants all eight tools never has to open it. */
.matrix-filter {
  margin: 0 0 1rem;
}

.matrix-filter-panel {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.matrix-filter-panel > summary {
  padding: 0.6rem 0.8rem;
  border-radius: var(--radius);
  color: var(--ink);
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}

.matrix-filter-panel[open] > summary {
  border-bottom: 1px solid var(--line);
  border-radius: var(--radius) var(--radius) 0 0;
}

.matrix-filter-panel > .hint {
  max-width: 52rem;
  margin: 0.7rem 0.8rem;
}

.matrix-filter-groups {
  display: grid;
  gap: 0.7rem;
  padding: 0 0.8rem 0.8rem;
}

.matrix-filter-group {
  margin: 0;
  padding: 0.4rem 0.7rem 0.65rem;
  border: 1px solid var(--line);
  border-radius: 0.5rem;
}

.matrix-filter-group legend {
  padding: 0 0.35rem;
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.matrix-filter-area + .matrix-filter-area {
  margin-top: 0.65rem;
}

.matrix-filter-area-label {
  margin: 0 0 0.3rem;
  color: var(--ink);
  font-size: 0.7rem;
  font-weight: 700;
}

.matrix-filter-checks {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

/* Label-only chips: the full requirement sentence is hover text, the way the matrix row
   header already carries it, so the whole control stays short enough to sit above the
   grid without burying it. */
.matrix-filter-check {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  font-size: 0.78rem;
  line-height: 1.3;
  cursor: pointer;
}

.matrix-filter-check:hover {
  border-color: var(--accent);
}

.matrix-filter-check:has(input:checked) {
  border-color: var(--accent);
  background: var(--row-open);
}

.matrix-filter-check:has(input:focus-visible) {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.matrix-filter-check input {
  margin: 0;
  accent-color: var(--accent);
}

.matrix-filter-check .hard-stop {
  margin-left: 0.15rem;
}

.matrix-filter-status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin: 0.6rem 0 0;
  color: var(--muted);
  font-size: 0.8rem;
}

.matrix-filter-clear {
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
}

.matrix-filter-clear:hover:not(:disabled) {
  border-color: var(--accent);
}

.matrix-filter-clear:disabled {
  opacity: 0.45;
  cursor: default;
}

/* Filters which columns are in play (by product family), same pill vocabulary as
   Clear filter next to it. A pressed button reuses the checked-chip treatment from
   .matrix-filter-check so "gateway vs MaaS" and "capability required" read as the
   same kind of control. */
.matrix-family-toggle {
  display: inline-flex;
  gap: 0.3rem;
}

.matrix-family-btn {
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--muted);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
}

.matrix-family-btn:hover {
  border-color: var(--accent);
  color: var(--ink);
}

.matrix-family-btn[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--row-open);
  color: var(--ink);
}

/* Filtering to a set nothing satisfies is a real answer, so it says so and names the
   requirements that collided rather than leaving an empty grid on screen. */
.matrix-empty {
  padding: 1rem 1.1rem;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: 0.88rem;
}

.matrix-empty p {
  max-width: 46rem;
  margin: 0 0 0.6rem;
}

.matrix-empty p:last-child {
  margin-bottom: 0;
}

.matrix-empty ul {
  margin: 0 0 0.6rem;
  padding-left: 1.1rem;
  color: var(--muted);
}

section {
  margin-top: 2.5rem;
}

section h2 {
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0 0 0.75rem;
}

article.prose {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 0.85rem 1rem;
}

.saas-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(21rem, 100%), 1fr));
  gap: 1rem;
  align-items: start;
}

.saas-card {
  scroll-margin-top: calc(var(--masthead-h, 5rem) + 1rem);
  padding: 1.1rem 1.2rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.saas-card.is-linked {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}

.saas-card-head {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 0.8rem;
  border-bottom: 1px solid var(--line);
}

.saas-card-head .tag {
  margin-bottom: 0.25rem;
}

.saas-card-head h2 {
  margin: 0;
  font-size: 1.15rem;
}

.saas-card-head .sub {
  margin: 0.2rem 0 0;
  color: var(--muted);
  font-size: 0.82rem;
}

.saas-card-link {
  color: var(--muted);
  text-decoration: none;
}

.saas-card-link:hover,
.saas-card-link:focus-visible {
  color: var(--link);
}

.saas-card-summary {
  margin: 0.9rem 0;
  font-size: 0.88rem;
  font-weight: 650;
}

.saas-card-notes {
  color: var(--muted);
  font-size: 0.86rem;
}

.saas-card-notes p {
  margin: 0.65rem 0 0;
}

.crumbs {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.8rem;
  color: var(--muted);
  margin-bottom: 1rem;
}

.page-head {
  margin-bottom: 1.5rem;
}

.page-head .sub {
  margin: 0 0 0.5rem;
  font-size: 0.9rem;
}

.conclusion {
  margin: 0 0 0.75rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  border-left: 3px solid var(--accent);
  background: var(--surface);
  font-size: 0.92rem;
  max-width: 52rem;
}

.conclusion-label {
  display: block;
  margin-bottom: 0.2rem;
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.tool-lede {
  margin: 0 0 1.25rem;
  max-width: 40rem;
  color: var(--muted);
  font-size: 1.02rem;
}

/* Home combines the request-path view engineers need with the role-based
   questions leaders ask. Copy renders without JavaScript; home.js only fills
   the research counts. */
.splash-hero {
  display: grid;
  gap: 0.75rem;
  align-items: center;
  /* section's 2.5rem top margin would hold the card off the band it is meant to overlap. */
  margin-top: 0;
  padding: clamp(1.25rem, 3vw, 1.75rem) clamp(1.25rem, 3vw, 2.5rem) clamp(2rem, 5vw, 3.5rem);
  border: 1px solid var(--line);
  border-radius: calc(var(--radius) * 1.3);
  background: var(--paper);
}

/* The lede is the widest thing in the column now that nothing sits beside it, so
   the measure is capped here rather than by the old two-column grid. */
.splash-hero-copy {
  max-width: 46rem;
}

/* The art sits beside the copy once there is room for both; below 860px it is dropped
   rather than stacked, so the first screen stays copy and buttons. */
@media (min-width: 861px) {
  .splash-hero {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: clamp(1.5rem, 4vw, 3rem);
  }
}

.splash-hero-art {
  justify-self: center;
  width: 100%;
  max-width: 30rem;
  height: auto;
}

@media (max-width: 860px) {
  .splash-hero-art {
    display: none;
  }
}

/* Home is the only page that asks a reader to make contact, so the button lives in
   index.html rather than the shared masthead in theme.js. liatrio.ai's own nav CTA is solid
   Bright Green, uppercase and tracked, with the hover a slightly softer green; #111111 text
   on #89df00 is 9.4:1, and the light theme keeps the same pair. */
.site-cta {
  display: inline-flex;
  align-items: center;
  min-height: 2.1rem;
  padding: 0.4rem 0.9rem;
  border: 1px solid var(--accent);
  border-radius: 0.375rem;
  background: var(--accent);
  color: #111111;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  transition: background 120ms ease, border-color 120ms ease;
}

.site-cta:hover {
  background: color-mix(in srgb, var(--accent) 88%, #000000);
  border-color: color-mix(in srgb, var(--accent) 88%, #000000);
}

/* The drawer carries its own Contact CTA below 961px, and a second one in the masthead row
   widened it past the viewport — which pushed the off-canvas drawer further right and put a
   sideways scroll on the page. This block has to sit after the base rule, not up in the
   drawer's media block: same specificity, so file order decides. */
@media (max-width: 960px) {
  .site-cta {
    display: none;
  }
}

.splash-eyebrow {
  margin: 0 0 0.8rem;
  color: var(--yes);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.splash-title {
  max-width: 22ch;
  margin: 0 0 0.45rem;
  font-size: clamp(1.85rem, 4vw, 3rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
}


.splash-lede {
  max-width: 42rem;
  margin: 0;
  color: var(--muted);
  font-size: clamp(1.05rem, 2vw, 1.35rem);
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.45;
}

/* The lede runs as two paragraphs — what the library is, then what a gateway is — and
   .splash-lede zeroes its own margins, so the break needs its own gap. */
.splash-lede + .splash-lede {
  margin-top: 0.85rem;
}

.splash-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.6rem;
}

.splash-action {
  display: inline-flex;
  align-items: center;
  min-height: 2.8rem;
  padding: 0.7rem 1.25rem;
  border: 1px solid transparent;
  color: var(--ink);
  font-size: 0.86rem;
  font-weight: 600;
  text-decoration: none;
  transition: border-color 120ms ease, transform 120ms ease;
}

.splash-action:hover {
  transform: translateY(-1px);
}

.splash-action-primary {
  background: var(--accent);
  color: #111111;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.splash-action-secondary {
  border-color: var(--line);
}

.splash-action-secondary:hover {
  border-color: var(--muted);
}

/* The banner band spans the viewport, above and behind the shell. The still holds the box and
   the video is laid over it rather than swapped in, so revealing the motion cannot reflow the
   page under a reader who has already started scrolling. aspect-ratio keeps the art's own
   3.2:1 shape at narrow widths, where a fixed height would crop it to a sliver; max-height
   stops a wide viewport from turning it into a 600px wall. */
.splash-top {
  position: relative;
  /* Height, not aspect-ratio: with a max-height to stop a wide viewport turning the band
     into a 600px wall, aspect-ratio narrows the *width* to match the capped height, and the
     band stops spanning the viewport. Set the height directly and let object-fit crop — the
     art is centred, so cropping is symmetric and loses only empty track. */
  width: 100%;
  height: clamp(10rem, 26vw, 22rem);
  /* Pulled up under the masthead so the band sits tighter to the nav. */
  margin-top: -50px;
  margin-bottom: calc(-1 * clamp(3.5rem, 7vw, 8rem));
  overflow: hidden;
  background: var(--paper);
}

/* slice on the viewBox is what object-fit: cover was doing for the video: the art is
   centred, so a narrow viewport crops symmetrically and loses only empty track. */
.splash-top-art {
  display: block;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.banner-lines path {
  fill: none;
  stroke: var(--banner-line);
  stroke-width: 2;
}

.banner-band {
  fill: var(--banner-band-fill);
  stroke: var(--banner-band-stroke);
  stroke-width: 2.5;
}

.banner-mark {
  fill: none;
  stroke: var(--banner-mark);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* A request arrives unresolved and leaves the gateway served: every dot is grey on the
   approach and carries its own colour on the way out. The swap sits at 50% of the path,
   which is where the band covers it, so the change itself is never seen — and the dots are
   drawn before the band for exactly that reason. */
.banner-dot {
  fill: var(--banner-dot-dim);
  offset-rotate: 0deg;
  animation: banner-travel 5.3s linear infinite, banner-serve 5.3s step-end infinite;
}

@keyframes banner-travel {
  from {
    offset-distance: 0%;
  }

  to {
    offset-distance: 100%;
  }
}

@keyframes banner-serve {
  0% {
    fill: var(--banner-dot-dim);
  }

  50% {
    fill: var(--banner-dot);
  }
}

/* One rule per dot: which line it rides, where in the 5.3s loop it starts, and the colour it
   leaves with. The delays are negative so the loop opens mid-flight rather than with every
   dot stacked on the left edge. */
.banner-dot-0 {
  offset-path: path("M 0 176 C 520 220.8, 1060 338.96, 1600 345.5 L 2560 345.5");
  animation-delay: -3.29s;
  --banner-dot: var(--banner-dot-lime);
}

.banner-dot-0b {
  offset-path: path("M 0 176 C 520 220.8, 1060 338.96, 1600 345.5 L 2560 345.5");
  animation-delay: -0.64s;
  --banner-dot: var(--banner-dot-green);
}

.banner-dot-1 {
  offset-path: path("M 0 288 C 520 310.4, 1060 369.48, 1600 372.75 L 2560 372.75");
  animation-delay: -1.43s;
  --banner-dot: var(--banner-dot-violet);
}

.banner-dot-2 {
  offset-path: path("M 0 400 C 520 400, 1060 400, 1600 400 L 2560 400");
  animation-delay: -4.24s;
  --banner-dot: var(--banner-dot-green);
}

.banner-dot-3 {
  offset-path: path("M 0 512 C 520 489.6, 1060 430.52, 1600 427.25 L 2560 427.25");
  animation-delay: -2.33s;
  --banner-dot: var(--banner-dot-lime);
}

.banner-dot-4 {
  offset-path: path("M 0 624 C 520 579.2, 1060 461.04, 1600 454.5 L 2560 454.5");
  animation-delay: -0.42s;
  --banner-dot: var(--banner-dot-violet);
}

.banner-dot-4b {
  offset-path: path("M 0 624 C 520 579.2, 1060 461.04, 1600 454.5 L 2560 454.5");
  animation-delay: -3.07s;
  --banner-dot: var(--banner-dot-lime);
}

@media (prefers-reduced-motion: reduce) {
  /* Parked past the band, where a dot carries its colour. */
  .banner-dot {
    animation: none;
    offset-distance: 66%;
    fill: var(--banner-dot);
  }
}

/* The shell rides over the band's lower edge. z-index rather than source order alone: the
   band is positioned, so the hero would otherwise paint under it. */
.splash-top + .shell {
  position: relative;
  z-index: 1;
}

/* Where to start used the generic link colour, a pale blue that appears nowhere else in the
   brand. Card titles read as ink and turn brand green with the card; the two inline links at
   the foot of the section keep their underline and take the same green. #89df00 is Bright
   Green as the brand guide has it; light mode swaps to #187a14, because Bright Green is
   1.9:1 on white and Primary Green #24ae1d is 3.4:1 — both under AA for body text. */
.splash-start .fit-card h3 {
  display: flex;
  align-items: center;
  gap: 0.45rem;
}

.splash-start .fit-card {
  position: relative;
}

.splash-start .fit-card h3 a {
  color: var(--ink);
  text-decoration: none;
}

/* The whole card is the target, not just the title. A stretched pseudo-element rather than
   wrapping the card in an <a>: the link keeps its accessible name from the heading, the
   heading stays a heading, and there is still exactly one link per card for a screen reader
   to announce. Everything the reader sees is unchanged. */
.splash-start .fit-card h3 a::after {
  position: absolute;
  inset: 0;
  border-radius: var(--radius);
  content: "";
}

/* Focus lands on the link inside, so the card has to show it: same border as hover, with the
   link's own focus ring left in place as the precise indicator. */
.splash-start .fit-card:focus-within {
  border-color: var(--brand-green);
}

.splash-start .fit-card:hover h3 a,
.splash-start .fit-card h3 a:hover,
.splash-start .fit-card h3 a:focus-visible {
  color: var(--brand-green);
}

.splash-start .hint a {
  color: var(--brand-green);
  text-decoration-color: color-mix(in srgb, var(--brand-green) 45%, transparent);
}

.splash-start .fit-card:hover {
  border-color: color-mix(in srgb, var(--brand-green) 55%, var(--line));
}

/* Both icon sets: line art on currentColor, sized to the text beside them, and never the
   only carrier of meaning — each sits next to the label it illustrates. */
.card-icon,
.row-icon {
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  fill: none;
  stroke: var(--brand-green);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.splash-definition,
.splash-problem,
.splash-purpose,
.splash-start {
  padding: clamp(3rem, 7vw, 5.5rem) 0;
  border-top: 1px solid var(--line);
}

/* The hero is already a bordered card, so a rule directly beneath it reads as a second
   edge. The later sections keep their divider. */
.splash-definition {
  border-top: 0;
}

.splash-definition > h2,
.splash-problem > h2,
.splash-purpose > h2,
.splash-start > h2 {
  max-width: 20ch;
  margin: 0 0 1rem;
  font-size: clamp(1.65rem, 3vw, 2.35rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.splash-definition > p:not(.splash-eyebrow),
.splash-problem > p:not(.splash-eyebrow),
.splash-purpose > p:not(.splash-eyebrow) {
  max-width: 46rem;
  margin: 0 0 1.2rem;
  color: var(--muted);
}

.splash-definition-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(21rem, 1fr);
  gap: clamp(2rem, 6vw, 4rem);
  align-items: start;
  margin-top: 2rem;
}

.splash-definition-grid p {
  max-width: 42rem;
  margin: 0 0 1rem;
  color: var(--muted);
}

.splash-code {
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}

.splash-code-bar {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.6rem 0.75rem;
  border-bottom: 1px solid var(--line);
  background: var(--group);
}

.splash-code-bar span {
  width: 0.42rem;
  height: 0.42rem;
  border-radius: 50%;
  background: var(--muted);
  opacity: 0.45;
}

.splash-code-bar b {
  margin-left: 0.35rem;
  color: var(--muted);
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 0.62rem;
  font-weight: 400;
}

.splash-code pre {
  margin: 0;
  padding: clamp(1rem, 3vw, 1.5rem);
  overflow-x: auto;
  color: var(--ink);
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: clamp(0.66rem, 1.3vw, 0.78rem);
  line-height: 1.85;
}

.code-comment {
  color: var(--muted);
}

.code-key {
  color: var(--lagoon);
}

.code-value {
  color: var(--yes);
}

.splash-owns {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-top: clamp(2.5rem, 6vw, 4rem);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.splash-owns div {
  min-width: 0;
  padding: 1.75rem 1.25rem;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: var(--surface);
  text-align: center;
}

.splash-owns div:nth-child(3n) {
  border-right: 0;
}

.splash-owns div:nth-last-child(-n + 3) {
  border-bottom: 0;
}

/* Bigger than the card and row icons elsewhere on the page: these six sit above their label
   rather than beside it, so they read as the cell's mark and carry the section visually. */
.owns-icon {
  display: block;
  /* Glyph plus padding makes the ring: box-sizing stays content-box so the two
     scale together and the circle keeps its 1:1 ratio. */
  box-sizing: content-box;
  width: 2.6rem;
  height: 2.6rem;
  padding: 0.85rem;
  margin: 0 auto 1rem;
  border: 2px solid color-mix(in srgb, var(--accent-strong) 80%, transparent);
  border-radius: 50%;
  fill: none;
  /* Primary Green rather than Bright Green: the six marks sit together as a set and
     the brighter green reads as a call to action next to the buttons. */
  stroke: var(--accent-strong);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.splash-owns strong,
.splash-owns span {
  display: block;
}

.splash-owns strong {
  margin-bottom: 0.4rem;
  color: var(--owns-title);
  font-size: 1.02rem;
}

.splash-owns span {
  color: var(--owns-body);
  font-size: 0.9rem;
  line-height: 1.5;
}

.splash-ledger {
  margin: 2rem 0 1.5rem;
  border-top: 1px solid var(--line);
}

.splash-ledger-head,
.splash-ledger-row {
  display: grid;
  grid-template-columns: minmax(10rem, 0.7fr) minmax(0, 1.15fr) minmax(0, 1.15fr);
  gap: clamp(1rem, 4vw, 3rem);
}

.splash-ledger-head {
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 0.64rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.splash-ledger-row {
  align-items: start;
  padding: 1.35rem 0;
  border-bottom: 1px solid var(--line);
}

.splash-ledger-who strong,
.splash-ledger-who span {
  display: block;
}

.splash-ledger-who strong {
  /* flex, not the block above, so the role icon sits on the label's baseline row. */
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.92rem;
}

.splash-ledger-who span {
  margin-top: 0.15rem;
  color: var(--muted);
  font-size: 0.74rem;
}

.splash-ledger-row p {
  margin: 0;
  color: var(--muted);
  font-size: 0.86rem;
}

.splash-ledger-row p:last-child {
  color: var(--ink);
}

.splash-problem-note {
  margin-top: 2rem !important;
  padding-left: 1rem;
  border-left: 3px solid var(--lagoon);
}

.splash-limits {
  padding: 0.9rem 1rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: 0.9rem;
}

/* Counts come from the research files, so home cannot claim a gateway,
   requirement, or adoption date the data does not contain. */
/* Columns follow the tile count rather than a fixed number, so the strip stays
   full width whether or not the Tier 1 count is present. */
.splash-stats {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  margin-top: 2rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.splash-stat {
  display: block;
  min-width: 0;
  padding: 1.1rem;
  border-right: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  transition: background 120ms ease;
}

.splash-stat:last-child {
  border-right: 0;
}

.splash-stat:hover {
  background: var(--group);
}

.splash-stat-value {
  display: block;
  color: var(--yes);
  font-size: 1.55rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.splash-stat-label {
  display: block;
  margin-top: 0.25rem;
  color: var(--muted);
  font-size: 0.74rem;
}

.splash-start .fit-cards {
  grid-template-columns: repeat(auto-fit, minmax(min(21rem, 100%), 1fr));
}

.splash-card p {
  font-size: 0.84rem;
}

@media (max-width: 860px) {
  .splash-definition-grid {
    grid-template-columns: 1fr;
  }

  .splash-owns {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .splash-owns div {
    border-right: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
  }

  .splash-owns div:nth-child(2n) {
    border-right: 0;
  }

  .splash-owns div:nth-last-child(-n + 2) {
    border-bottom: 0;
  }

  .splash-stats {
    grid-auto-flow: row;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* An odd tile count would otherwise leave a gap in the last row. */
  .splash-stat:last-child:nth-child(odd) {
    grid-column: 1 / -1;
  }

  .splash-stat:nth-child(2) {
    border-right: 0;
  }

  .splash-stat:nth-child(-n + 2) {
    border-bottom: 1px solid var(--line);
  }

  .splash-ledger-head {
    display: none;
  }

  .splash-ledger-row {
    grid-template-columns: minmax(9rem, 0.65fr) minmax(0, 1.35fr);
    gap: 0.6rem 1.5rem;
  }

  .splash-ledger-row p:last-child {
    grid-column: 2;
  }
}

@media (max-width: 520px) {
  .splash-action {
    justify-content: center;
    width: 100%;
  }

  .splash-owns,
  .splash-stats {
    grid-auto-flow: row;
    grid-template-columns: 1fr;
  }

  .splash-owns div,
  .splash-stat,
  .splash-stat:nth-child(2) {
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }

  .splash-owns div:last-child,
  .splash-stat:last-child {
    border-bottom: 0;
  }

  .splash-ledger-row {
    grid-template-columns: 1fr;
    gap: 0.45rem;
    padding: 1.15rem 0;
  }

  .splash-ledger-row p:last-child {
    grid-column: 1;
    margin-top: 0.3rem;
  }
}

.headlines h2 {
  font-size: 1rem;
  margin: 0 0 0.2rem;
}

.fit-cards {
  display: grid;
  gap: 0.6rem;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  margin-top: 0.75rem;
}

.fit-card {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 0.65rem 0.8rem 0.75rem;
  transition: border-color 120ms ease, transform 120ms ease;
}

.fit-card:hover {
  border-color: var(--muted);
  transform: translateY(-1px);
}

.fit-card h3 {
  margin: 0 0 0.3rem;
  font-size: 0.88rem;
}

.fit-card p {
  margin: 0;
  font-size: 0.8rem;
  color: var(--muted);
}

.headline-table-wrap {
  margin-top: 0.75rem;
}

.headline-table {
  font-size: 0.8rem;
}

.headline-table th,
.headline-table td {
  padding: 0.4rem 0.55rem;
}

.headline-table tbody th {
  white-space: nowrap;
}

/* Market adoption (research/adoption.json): maturity stage, usage counts, stated share.
   `missing` is styled as a value in its own right so an unpublished figure reads as a
   deliberate blank rather than a rendering slip. */
.maturity {
  display: inline-block;
  padding: 0.05rem 0.4rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 0.67rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.maturity-ga {
  color: var(--yes);
  border-color: color-mix(in srgb, var(--yes) 55%, transparent);
  background: var(--yes-bg);
}

.maturity-preview {
  color: var(--paid-ink);
  border-color: color-mix(in srgb, var(--paid) 55%, transparent);
  background: var(--paid-bg);
}

.maturity-beta {
  color: var(--lagoon);
  border-color: color-mix(in srgb, var(--lagoon) 55%, transparent);
  background: color-mix(in srgb, var(--lagoon) 12%, transparent);
}

.adopt-since {
  white-space: nowrap;
}

.adopt-missing {
  color: var(--muted);
  font-weight: 500;
}

.summary-table-wrap {
  margin-top: 0.75rem;
}

/* Fit copy and market adoption share one row, so the table carries eight columns.
   Each gets a readable floor and .wrap pans sideways, rather than squeezing a
   sentence into a two-word column and making the row twenty lines tall. */
.summary-table th,
.summary-table td {
  min-width: 11rem;
}

.summary-table .adopt-maturity,
.summary-table .adopt-usage {
  min-width: 13rem;
}

.summary-table .adopt-share {
  min-width: 17rem;
}

.summary-table .adopt-note,
.summary-table .adopt-figures p {
  max-width: 17rem;
}

/* The matrix meter needs the name to stop reserving a nowrap line for itself.
   Eight columns pan a long way right, so the name and its bar pin to the left
   edge the way the matrix pins its requirement labels. */
.summary-table tbody th.summary-gateway {
  min-width: 12rem;
  white-space: normal;
  position: sticky;
  left: 0;
  z-index: 1;
}

.summary-table thead th:first-child {
  left: 0;
  z-index: 3;
}

/* A rule on the pinned edge, so the half-scrolled column beside it reads as
   another column rather than as text spilling out of the gateway cell. */
.summary-table thead th:first-child,
.summary-table tbody th.summary-gateway {
  border-right: 1px solid var(--line);
}

.summary-gateway-name {
  display: block;
  line-height: 1.3;
}

/* The matrix caps the meter at 4.75rem and centres it under a narrow heading.
   This cell is a left-aligned row label, so the same cap leaves a centred stub;
   drop it and let the bar track the column's width at any viewport. */
.summary-table tbody th.summary-gateway .col-meter {
  max-width: none;
  margin-inline: 0;
}

.experience-summary {
  margin-top: 1.4rem;
}

.experience-summary h2 {
  font-size: 1rem;
  margin: 0 0 0.2rem;
}

.experience-table th,
.experience-table td {
  min-width: 12rem;
  vertical-align: top;
}

.experience-table tbody th {
  white-space: normal;
}

/* One section answers two links: /summaries/#summaries and the market-adoption
   links written before the two tables merged. */
.anchor-alias {
  display: block;
  height: 0;
}

.adoption-table {
  font-size: 0.8rem;
}

.adoption-table th,
.adoption-table td {
  padding: 0.55rem 0.6rem;
  vertical-align: top;
}

.adoption-table tbody th {
  white-space: nowrap;
}

.adoption-table td > .maturity {
  margin-bottom: 0.25rem;
}

.adopt-sub,
.adopt-since {
  display: block;
  color: var(--muted);
  font-size: 0.72rem;
}

.adoption-table .adopt-since {
  margin-top: 0.15rem;
}

.adopt-note {
  margin: 0.35rem 0 0;
  color: var(--muted);
  font-size: 0.72rem;
  max-width: 24rem;
}

.adopt-asof-line {
  margin: 0.3rem 0 0;
  color: var(--muted);
  font-size: 0.7rem;
}

.adopt-counts,
.adopt-figures,
.adopt-src {
  margin: 0;
  padding: 0;
  list-style: none;
}

.adopt-counts li {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  flex-wrap: wrap;
  white-space: nowrap;
}

.adopt-counts .adopt-k {
  min-width: 6.5rem;
  color: var(--muted);
  font-size: 0.72rem;
}

.adopt-counts .adopt-sub {
  flex-basis: 100%;
  white-space: normal;
}

.adopt-figures li {
  margin-bottom: 0.4rem;
}

.adopt-figures p {
  margin: 0;
  max-width: 26rem;
}

.adopt-src {
  margin-top: 0.3rem;
  font-size: 0.7rem;
  color: var(--muted);
}

.adopt-src li {
  margin-bottom: 0.1rem;
}

.headline {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 0.85rem 1rem 0.95rem;
}

.headline h3 {
  margin: 0 0 0.65rem;
  font-size: 0.95rem;
}

.headline-item {
  margin: 0 0 0.55rem;
}

.headline-item:last-child {
  margin-bottom: 0;
}

.headline-label {
  display: block;
  margin-bottom: 0.12rem;
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.headline-item p {
  margin: 0;
  font-size: 0.85rem;
}

.headline-tldr {
  margin-top: 0.65rem;
  padding-top: 0.55rem;
  border-top: 1px solid var(--line);
}

.headline-tldr p {
  font-size: 0.9rem;
}

.page-head .headline {
  margin: 0.65rem 0 0.75rem;
  max-width: 52rem;
  border-left: 3px solid var(--accent);
}

.adopters {
  margin: 1.5rem 0 0;
}

.adopters h2 {
  font-size: 1rem;
  margin: 0 0 0.2rem;
}

.adopter-scan-table td {
  vertical-align: top;
}

.adopter-scan-count {
  display: inline-block;
  min-width: 1.1rem;
  margin-right: 0.2rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  font-weight: 650;
}

.adopter-scan-empty {
  white-space: nowrap;
}

.adopter-gateway {
  margin: 0.85rem 0 0;
}

.adopter-gateway h3 {
  margin: 0 0 0.35rem;
  font-size: 0.88rem;
}

.adopter-list {
  margin: 0;
  padding-left: 1.2rem;
}

.adopter-list li {
  margin: 0 0 0.75rem;
}

.adopter-list li:last-child {
  margin-bottom: 0;
}

.adopter-who,
.adopter-what,
.adopter-note,
.adopter-source {
  margin: 0;
}

.adopter-who {
  font-weight: 650;
}

.adopter-what {
  margin-top: 0.15rem;
  font-size: 0.9rem;
}

.adopter-note,
.adopter-source {
  margin-top: 0.2rem;
  font-size: 0.8rem;
  color: var(--muted);
}

.layout {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: minmax(0, 1fr) 220px;
  align-items: start;
}

@media (max-width: 780px) {
  .layout {
    grid-template-columns: minmax(0, 1fr);
  }
}

aside h2 {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin: 0 0 0.5rem;
}

.sidenav {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  font-size: 0.85rem;
}

.sidenav li {
  padding: 0.2rem 0;
}

.sidenav .current {
  font-weight: 650;
}

article.prose {
  margin-top: 1.5rem;
  padding: 1rem 1.25rem;
}

.prose h1,
.prose h2,
.prose h3 {
  font-size: 1rem;
  margin: 1.25rem 0 0.5rem;
}

.prose h1:first-child,
.prose h2:first-child {
  margin-top: 0;
}

.prose p,
.prose ul,
.prose ol {
  font-size: 0.9rem;
}

.prose pre {
  background: var(--unk-bg);
  padding: 0.75rem;
  overflow-x: auto;
  font-size: 0.8rem;
}

.prose code {
  background: var(--unk-bg);
  padding: 0.05rem 0.25rem;
  font-size: 0.85em;
}

.prose pre code {
  background: none;
  padding: 0;
}

.prose blockquote {
  margin: 0.75rem 0;
  padding-left: 0.9rem;
  border-left: 3px solid var(--accent);
  color: var(--muted);
}

.prose table {
  margin: 0.75rem 0;
}

.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;
}

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

.guide-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.5rem;
  margin: 0 0 1.25rem;
  padding: 0;
  list-style: none;
  counter-reset: guide-step;
  font-size: 0.78rem;
  color: var(--muted);
}

.guide-steps li {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.28rem 0.7rem 0.28rem 0.35rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  counter-increment: guide-step;
}

.guide-steps li::before {
  content: counter(guide-step);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.15rem;
  height: 1.15rem;
  border-radius: 999px;
  background: var(--paper);
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 700;
}

.guide-steps li.current {
  border-color: var(--accent-strong);
  background: var(--accent-strong);
  color: #111111;
  font-weight: 650;
}

.guide-steps li.current::before {
  background: #111111;
  color: var(--accent);
}

.guide-steps li.done {
  color: var(--ink);
  border-color: color-mix(in srgb, var(--lime) 55%, var(--line));
}

.guide-steps li.done::before {
  content: "✓";
  background: color-mix(in srgb, var(--lime) 22%, var(--surface));
  color: var(--lime);
}

.guide-panel {
  max-width: 46rem;
}

.guide-panel h2 {
  font-size: 1.1rem;
  margin: 0 0 0.5rem;
}

.guide-panel > p {
  color: var(--muted);
  font-size: 0.92rem;
  max-width: 42rem;
}

.guide-list {
  margin: 0.75rem 0 1rem;
  padding-left: 1.2rem;
  font-size: 0.9rem;
}

.guide-fieldset {
  margin: 1rem 0;
  padding: 0;
  border: 0;
}

.guide-fieldset legend {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.45rem;
}

.guide-option,
.guide-check {
  display: flex;
  gap: 0.65rem;
  align-items: flex-start;
  margin: 0 0 0.55rem;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  cursor: pointer;
}

.guide-option:has(input:checked),
.guide-check:has(input:checked) {
  border-color: var(--accent-strong);
  box-shadow: inset 3px 0 0 var(--accent);
  background: color-mix(in srgb, var(--accent-strong) 8%, var(--surface));
}

.guide-option input,
.guide-check input {
  margin-top: 0.2rem;
  flex-shrink: 0;
}

.guide-option-body,
.guide-check-body {
  display: block;
}

.guide-option-label,
.guide-check-label {
  display: block;
  font-weight: 600;
  font-size: 0.92rem;
}

.guide-option-detail,
.guide-check-detail {
  display: block;
  margin-top: 0.15rem;
  color: var(--muted);
  font-size: 0.85rem;
}

.guide-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.25rem;
}

.guide-actions button,
.guide-req-actions button {
  margin: 0;
  padding: 0.45rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}

.guide-next {
  border-color: var(--accent-strong);
  background: var(--accent-strong);
  color: #ffffff;
}

.guide-next:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.guide-actions button:hover,
.guide-actions button:focus-visible,
.guide-req-actions button:hover,
.guide-req-actions button:focus-visible {
  border-color: var(--focus-ring);
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.guide-req-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin: 0.75rem 0 0.35rem;
}

.guide-recap {
  display: grid;
  grid-template-columns: 10rem minmax(0, 1fr);
  gap: 0.35rem 1rem;
  margin: 0 0 1rem;
  font-size: 0.88rem;
}

.guide-recap dt {
  color: var(--muted);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.guide-recap dd {
  margin: 0;
}

.guide-results {
  display: grid;
  gap: 0.75rem;
  margin: 1rem 0;
}

.guide-result {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 0.85rem 1rem 0.95rem;
}

.guide-result-lead {
  border-top: 3px solid var(--lime);
  box-shadow: inset 3px 0 0 var(--accent);
}

.guide-result-blocked {
  opacity: 0.85;
}

.guide-result-head h3 {
  margin: 0;
  font-size: 0.98rem;
}

.guide-result p {
  margin: 0.45rem 0 0;
  font-size: 0.88rem;
}

.guide-score {
  font-weight: 650;
}

.guide-blocked {
  color: var(--no-ink);
  font-weight: 600;
}

.guide-result details {
  margin-top: 0.65rem;
  font-size: 0.85rem;
}

.guide-gap-list {
  margin: 0.35rem 0 0;
  padding-left: 1.1rem;
}

.guide-gap-list li {
  margin: 0.35rem 0;
}

.guide-workaround {
  display: block;
  margin-top: 0.1rem;
  color: var(--muted);
  font-size: 0.8rem;
}

.guide-links,
.guide-footer-links {
  margin-top: 0.65rem;
  font-size: 0.82rem;
  color: var(--muted);
}

.guide-subsection {
  margin-top: 1.75rem;
}

.guide-subsection h3 {
  font-size: 0.95rem;
  margin: 0 0 0.5rem;
}

.guide-ruled-out {
  margin: 0;
  padding-left: 1.1rem;
  font-size: 0.88rem;
}

.guide-empty {
  padding: 0.85rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: 0.9rem;
}

@media (max-width: 780px) {
  .guide-recap {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.15rem;
  }

  .guide-recap dt {
    margin-top: 0.45rem;
  }
}

.implementation-questions h3 {
  margin: 0 0 0.45rem;
  font-size: 0.92rem;
}

.considerations {
  margin: 0 0 2.5rem;
}

.consideration-list {
  display: grid;
  gap: 0.5rem;
}

.consideration-list details {
  padding: 0.75rem 1rem;
  border: 1px solid var(--line);
  border-radius: 0.55rem;
  background: var(--surface);
}

.consideration-list summary {
  cursor: pointer;
  font-size: 0.92rem;
  font-weight: 600;
}

.consideration-list p {
  margin: 0.6rem 0 0;
  max-width: 62rem;
  font-size: 0.86rem;
}

.consideration-sources {
  color: var(--muted);
  font-size: 0.78rem;
}

.guidance-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.8rem;
}

.guidance-grid > section {
  padding: 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.guidance-grid h3 {
  margin: 0 0 0.6rem;
  font-size: 0.82rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--muted);
}

.guidance-grid ul {
  display: grid;
  gap: 0.7rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.guidance-grid li {
  display: grid;
  gap: 0.15rem;
  font-size: 0.82rem;
}

.guidance-grid li > a {
  font-weight: 600;
}

.guidance-grid li > span:last-child {
  color: var(--muted);
}

.evidence-link-note {
  margin: 0 0 0.6rem;
  padding-top: 0.5rem;
  border-top: 1px dashed var(--line);
  color: var(--muted);
  font-size: 0.78rem;
}

.evidence-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.8rem;
}

.evidence-grid article {
  padding: 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.evidence-grid h3 {
  margin: 0.2rem 0 0.4rem;
  font-size: 1rem;
}

.evidence-body {
  min-height: 7.5rem;
  margin: 0 0 0.55rem;
  color: var(--muted);
  font-size: 0.84rem;
}

.evidence-grid a {
  font-size: 0.82rem;
  font-weight: 600;
}

.implementation-questions {
  margin-top: 0.8rem;
  padding: 1rem 1.15rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--group);
}

.implementation-questions ol {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.4rem 2rem;
  margin: 0;
  padding-left: 1.3rem;
  font-size: 0.82rem;
}

@media (max-width: 780px) {
  .evidence-grid,
  .guidance-grid,
  .implementation-questions ol {
    grid-template-columns: minmax(0, 1fr);
  }

  .evidence-body {
    min-height: 0;
  }
}

.setup-story {
  max-width: 46rem;
}

.setup-story + section,
.setup-patterns {
  margin-top: 1.75rem;
}

.setup-industry {
  max-width: 46rem;
  margin: 1.75rem 0;
}

.setup-industry > p,

.setup-cost {
  margin-top: 0.45rem;
}

.setup-card .sub {
  margin: 0 0 0.35rem;
}

.setup-patterns h2,
.setup-story h2,
.setup-industry h2 {
  font-size: 1.1rem;
  margin: 0 0 0.45rem;
}

@media (max-width: 900px) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 620px) {
    display: block;
  }

    margin-top: 0.45rem;
  }

    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 780px) {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 900px) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 620px) {
    display: block;
  }

    margin-top: 0.45rem;
  }

    grid-template-columns: minmax(0, 1fr);
  }
}

.guide-back-link,
.text-btn {
  display: inline-block;
  margin: 0;
  padding: 0.45rem 0.85rem;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

@media (max-width: 780px) {
    grid-template-columns: minmax(0, 1fr);
  }

    align-items: flex-start;
    flex-direction: column;
  }
}

/* ================================================================
 * /combinations/ POC (see AGENTS.md and #290). Uses .pill and
 * .mark-tip from the shared toolkit — combinations-specific classes
 * are the picker, the synthesized grid, and the M/G attribution
 * badge.
 * ============================================================== */

.combinations-lede {
  margin: 0 0 1.75rem;
  padding: 1rem 1.25rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}
.combinations-lede p { margin: 0.5rem 0; color: var(--ink); }
.combinations-lede code { font-size: 0.85em; }
.combinations-lede .lede-eyebrow {
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 0.35rem;
}
.combinations-lede .hint { color: var(--muted); font-size: 0.9rem; }

.combinations-picker { margin: 0 0 1.5rem; }
.combinations-picker h2 { margin: 0; font-size: 1.05rem; color: var(--ink); }
.combinations-picker-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 0 0 0.75rem;
}
.combo-presets { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.combo-preset {
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  border-radius: 0.35rem;
  padding: 0.35rem 0.7rem;
  font: inherit;
  font-size: 0.8rem;
  cursor: pointer;
}
.combo-preset:hover, .combo-preset:focus {
  border-color: var(--accent);
  color: var(--link);
}
.combo-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 0.75rem;
  align-items: stretch;
}
.combo-card {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.combo-card-row {
  display: flex;
  align-items: end;
  gap: 0.4rem;
}
.combo-field { display: flex; flex-direction: column; gap: 0.15rem; flex: 1 1 0; }
.combo-field-label {
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.combo-field select {
  width: 100%;
  padding: 0.35rem 0.4rem;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 0.35rem;
  font: inherit;
  font-size: 0.85rem;
}
.combo-plus {
  color: var(--muted);
  font-size: 1.1rem;
  padding-bottom: 0.35rem;
  align-self: center;
}
.combo-remove {
  border: 1px solid var(--line);
  background: transparent;
  color: var(--muted);
  border-radius: 0.35rem;
  padding: 0.15rem 0.45rem;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  height: 2rem;
  align-self: end;
}
.combo-remove:hover, .combo-remove:focus { color: var(--no-ink); border-color: var(--no); }
.combo-card-label { margin: 0; font-size: 0.8rem; color: var(--muted); }
.combo-add {
  border: 1px dashed var(--line);
  background: transparent;
  color: var(--ink);
  border-radius: var(--radius);
  padding: 0.75rem;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  font: inherit;
  font-size: 0.9rem;
  min-height: 90px;
}
.combo-add:hover, .combo-add:focus {
  border-color: var(--accent);
  color: var(--link);
}
.combo-add > :first-child { font-size: 1.5rem; line-height: 1; }

.combinations-grid { overflow-x: auto; }
.combinations-table {
  width: 100%;
  border-collapse: collapse;
  min-width: 720px;
}
.combinations-table th, .combinations-table td {
  text-align: left;
  padding: 0.5rem 0.7rem;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
  font-size: 0.87rem;
}
.combinations-table thead th {
  position: sticky;
  top: 0;
  background: var(--paper);
  z-index: 1;
}
.combinations-table .requirement-head { min-width: 15rem; }
.combinations-table .combo-column-head {
  min-width: 7rem;
  white-space: nowrap;
  color: var(--ink);
  font-weight: 600;
  cursor: help;
}
.combinations-table .area-head th {
  background: var(--group);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  padding-top: 0.75rem;
}
.combinations-table .requirement { color: var(--ink); font-weight: 500; }
.combinations-table .capability-tip {
  display: inline-flex;
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 50%;
  border: 1px solid var(--line);
  color: var(--muted);
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  cursor: help;
}
.combinations-table .combo-cell {
  white-space: nowrap;
  vertical-align: middle;
}
.combinations-table .combo-cell.mark-tip { cursor: help; }
.combo-attribution {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0 0.35rem;
  border: 1px solid var(--line);
  border-radius: 0.35rem;
  font-size: 0.7rem;
  color: var(--muted);
  font-weight: 600;
  cursor: help;
}
.combinations-grid .empty {
  color: var(--muted);
  padding: 1rem;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  text-align: center;
}

/* ==========================================================================
   Loading, error, and skeleton states
   Every JS-mounted `#app` starts with "Loading…" text. The spinner and error
   card replace that placeholder without a layout jump when a fetch is in
   flight or fails, and aria-busy stays on until the render lands so a
   screen reader announces the state change.
   ========================================================================== */
.is-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.85rem;
  min-height: 8rem;
  padding: 2rem 1rem;
  color: var(--muted);
}

.load-spinner {
  width: 2rem;
  height: 2rem;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: load-spin 720ms linear infinite;
}

@keyframes load-spin {
  to { transform: rotate(360deg); }
}

.load-error {
  margin: 1.25rem auto;
  max-width: 40rem;
  padding: 1.25rem 1.5rem;
  border: 1px solid var(--no);
  border-radius: var(--radius);
  background: var(--no-bg);
  color: var(--ink);
}

.load-error h2 {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
}

.load-error p {
  margin: 0 0 0.75rem;
  color: var(--muted);
}

.load-error .retry {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.45rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: 0.35rem;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.load-error .retry:hover,
.load-error .retry:focus-visible {
  border-color: var(--focus-ring);
  color: var(--link);
}

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

/* ==========================================================================
   404 page
   Uses the site chrome; the card grid mirrors the six primary surfaces so
   a misrouted reader gets one keystroke to every important page.
   ========================================================================== */
.notfound {
  max-width: 60rem;
  margin: 2rem auto;
  text-align: center;
}

.notfound-code {
  margin: 0;
  font-size: 5.5rem;
  font-weight: 700;
  color: var(--link);
  line-height: 1;
  letter-spacing: -0.02em;
}

.notfound h2 {
  margin: 0.75rem 0 0.5rem;
  font-size: 1.6rem;
}

.notfound-lede {
  margin: 0 auto 2rem;
  max-width: 34rem;
  color: var(--muted);
}

.notfound-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 0.85rem;
  text-align: left;
}

.notfound-card {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 1rem 1.1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  transition: border-color 120ms ease, transform 120ms ease;
}

.notfound-card:hover,
.notfound-card:focus-visible {
  border-color: var(--focus-ring);
  transform: translateY(-1px);
}

.notfound-card strong { font-size: 1rem; }
.notfound-card span { color: var(--muted); font-size: 0.9rem; }

/* ==========================================================================
   Privacy / terms pages
   Standalone prose; kept narrow so paragraphs stay readable.
   ========================================================================== */
.legal-page {
  max-width: 44rem;
}

.legal-page section {
  margin-top: 1.75rem;
}

.legal-page h2 {
  margin: 0 0 0.5rem;
  font-size: 1.2rem;
}

.legal-page p,
.legal-page li { line-height: 1.65; }

.legal-page ul {
  padding-left: 1.2rem;
}

.legal-page li { margin-bottom: 0.4rem; }

.legal-updated {
  margin: 0 0 1.25rem;
  color: var(--muted);
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.legal-page code {
  padding: 0.1rem 0.35rem;
  border: 1px solid var(--line);
  border-radius: 0.25rem;
  background: var(--surface);
  font-size: 0.85em;
}

/* ==========================================================================
   Expanded footer
   The existing .site-foot rules keep the brand row. .site-foot-top and
   .site-foot-bottom split the two rows so the legal + address block sits
   underneath the brand + site-map row on desktop and stacks cleanly on
   mobile.
   ========================================================================== */
.site-foot .site-foot-top {
  padding-bottom: 0.75rem;
}

.site-foot .site-foot-bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding-top: 0.5rem;
  padding-bottom: 1.75rem;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.82rem;
}

.site-foot-address {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  font-style: normal;
  color: var(--muted);
}

.site-foot-address strong {
  color: var(--ink);
  font-weight: 600;
}

.site-foot-address a {
  color: var(--muted);
  text-decoration: none;
}

.site-foot-address a:hover,
.site-foot-address a:focus-visible {
  color: var(--link);
  text-decoration: underline;
}

.site-foot-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  align-items: center;
}

.site-foot-legal a {
  color: var(--muted);
  text-decoration: none;
}

.site-foot-legal a:hover,
.site-foot-legal a:focus-visible {
  color: var(--link);
  text-decoration: underline;
}


.site-foot-consent-reset {
  appearance: none;
  border: 0;
  background: transparent;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.15em;
  cursor: pointer;
}

.site-foot-consent-reset:hover,
.site-foot-consent-reset:focus-visible {
  color: var(--accent);
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.site-foot-revision {
  margin: 0.4rem 0 0;
  color: var(--muted);
  font-size: 0.72rem;
  letter-spacing: 0.02em;
}

.site-foot-copy {
  flex-basis: 100%;
  margin: 0;
  color: var(--muted);
  font-size: 0.78rem;
}

.site-foot-copy a {
  color: inherit;
  text-decoration: underline;
}

@media (max-width: 780px) {
  .site-foot .site-foot-bottom {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
  }
}

/* ==========================================================================
   Analytics / storage consent banner
   Explains localStorage keys, cookieless Plausible, and consent-gated GA4.
   Accept analytics loads gtag; Essential only keeps theme + Plausible only.
   ========================================================================== */
/* ==========================================================================
   Skip-to-content link — visually hidden until keyboard focus lands on it.
   A keyboard user hits Tab once on any page and can jump straight over the
   masthead + nav straight to the primary content. Sighted mouse users never
   see it.
   ========================================================================== */
.skip-link {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 200;
  padding: 0.6rem 1rem;
  background: var(--accent);
  color: #14170f;
  font-weight: 600;
  text-decoration: none;
  border-radius: 0 0 0.5rem 0;
  transform: translateY(-120%);
  transition: transform 0.15s ease-out;
}

.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
}

.storage-notice {
  position: fixed;
  left: 1rem;
  right: 1rem;
  bottom: 1rem;
  z-index: 15;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem 1.25rem;
  max-width: 60rem;
  margin: 0 auto;
  padding: 0.75rem 1rem;
  border: 1px solid var(--line);
  border-radius: 0.5rem;
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.25);
  font-size: 0.85rem;
}

.storage-notice[hidden] { display: none; }

/* When the mobile drawer opens (theme toggle lives inside it), get the
   notice and the sticky CTA out of the way. The nav drawer sits above at
   z-index ~25; both hide entirely rather than compete for click-through
   or remain tabbable under the scrim. */
body.nav-open .storage-notice,
body.nav-open .mobile-cta { display: none; }

.storage-notice p {
  margin: 0;
  flex: 1 1 20rem;
}

.storage-notice a { color: var(--link); }

.storage-notice-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  flex: 0 0 auto;
}

.storage-notice-reject,
.storage-notice-accept {
  padding: 0.4rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: 0.35rem;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.storage-notice-accept {
  border-color: var(--accent);
  background: var(--accent);
  color: #14170f;
}

.storage-notice-reject:hover,
.storage-notice-reject:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
}

.storage-notice-accept:hover,
.storage-notice-accept:focus-visible {
  filter: brightness(1.05);
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/* ==========================================================================
   Sticky mobile CTA
   Home-only. The hero contact button scrolls out of view on phones, so the
   sticky bar keeps "Talk to us" reachable with one thumb. Desktop hides it
   because the masthead + hero CTAs are already visible.
   ========================================================================== */
.mobile-cta {
  display: none;
}

@media (max-width: 780px) {
  body[data-page="home"] .mobile-cta {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 30;
    display: flex;
    gap: 0.5rem;
    padding: 0.65rem 0.75rem calc(0.65rem + env(safe-area-inset-bottom, 0px));
    background: var(--surface);
    border-top: 1px solid var(--line);
    box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.2);
  }

  body[data-page="home"] .mobile-cta a {
    flex: 1;
    padding: 0.7rem 0.9rem;
    border-radius: 0.35rem;
    text-align: center;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.92rem;
  }

  body[data-page="home"] .mobile-cta .mobile-cta-primary {
    background: var(--accent);
    color: #111111;
  }

  body[data-page="home"] .mobile-cta .mobile-cta-secondary {
    border: 1px solid var(--line);
    color: var(--ink);
  }

  /* Must beat the display:flex rule above (same specificity otherwise). */
  body[data-page="home"].nav-open .mobile-cta {
    display: none;
  }

  /* Clearance on the body (not just main) so the footer legal row —
     Privacy / Terms / © — sits above the sticky bar instead of under it. */
  body[data-page="home"] {
    padding-bottom: 6.5rem;
  }

  body[data-page="home"] .storage-notice {
    bottom: 5rem;
  }
}

/* == Research breadcrumbs ==
   The trail sits above the article's page-head on every research half so a
   reader who deep-links or lands from search can see where the page fits in
   the library. `Home / Research / Gateway / <name>` on the hierarchy; a
   trailing `Paired half` link only appears when the loaded half has a
   `pairsWithMaas` / `pairsWithGateway` sibling. That last item is a lateral
   reference, not part of the parent chain, so aria-current stays on the
   half the reader is on. Hidden on narrow phones because a full four- or
   five-item trail wraps to two lines and shoves the h1 down further than
   the space it costs to keep it. */
.research-breadcrumbs {
  margin: 0.25rem 0 0.75rem;
  font-size: 0.82rem;
  color: var(--muted);
}

.research-breadcrumbs ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.5rem;
  align-items: baseline;
}

.research-breadcrumbs li {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}

.research-breadcrumbs li + li::before {
  content: "/";
  color: var(--line);
  font-weight: 400;
}

.research-breadcrumbs a {
  color: var(--link);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 120ms ease, color 120ms ease;
}

.research-breadcrumbs a:hover,
.research-breadcrumbs a:focus-visible {
  border-bottom-color: currentColor;
  color: var(--ink);
}

.research-breadcrumbs [aria-current="page"] {
  color: var(--ink);
  font-weight: 600;
}

@media (max-width: 480px) {
  .research-breadcrumbs {
    display: none;
  }
}

/* == Freshness signal ==
   "Last verified <date>" chip in the article's page-head (research half),
   on `/matrix/`, and on `/sources/`. It's a `<time datetime="…">` so a
   crawler or reader-mode extraction picks up the ISO stamp without the
   humanized label. Kept quiet — same weight and color as a subtitle — so
   the h1 stays the entry point. */
.freshness {
  margin: 0.15rem 0 0.75rem;
  font-size: 0.8rem;
  color: var(--muted);
  letter-spacing: 0.01em;
}

.freshness time {
  display: inline-block;
  padding: 0.1rem 0.5rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--muted);
  white-space: nowrap;
}

.page-head .freshness {
  margin-top: 0;
}

/* ==========================================================================
   Load-error retry
   Auto-retry with a 1s → 2s → 4s backoff wraps around the manual Reload
   card so a transient network hiccup self-heals without a keystroke. The
   status line uses tabular numerals so the ticking countdown does not
   nudge the surrounding copy sideways on every tick, and the offline
   variant swaps the red border for the neutral surface: "waiting for a
   connection" is not the same failure state as "the server said no".
   ========================================================================== */
.load-error .load-error-status {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.load-error .load-error-countdown {
  font-weight: 600;
  color: var(--ink);
}

.load-error-offline {
  border-color: var(--line);
  background: var(--surface);
}

.privacy-consent-reset {
  appearance: none;
  margin-top: 0.5rem;
  padding: 0.45rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: 0.35rem;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.privacy-consent-reset:hover,
.privacy-consent-reset:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/* == Print media == */
@media print {
  @page {
    size: A4;
    margin: 0.75in;
  }

  /* Named page + nested @page: Chromium honors `page` more reliably than
     a nested at-rule alone when Save as PDF reads page size. */
  @page matrix {
    size: A4 landscape;
    margin: 0.5in;
  }

  body[data-page="matrix"] {
    page: matrix;

    @page {
      size: A4 landscape;
      margin: 0.5in;
    }
  }

  :root,
  :root[data-theme="light"] {
    color-scheme: light;
    --ink: #000000;
    --muted: #444444;
    --line: #bbbbbb;
    --paper: #ffffff;
    --surface: #ffffff;
    --group: #ffffff;
    --row-open: #ffffff;
    --drill: #ffffff;
    /* Light-theme hexes: default dark PDFs otherwise paint ~1.9:1
       Bright Green links (`--link: #89df00`) and lime accents. */
    --accent: #24ae1d;
    --lime: #6b9a00;
    --lagoon: #006989;
    --link: #187a14;
    --radius: 0.25rem;
    --tip-bg: #ffffff;
    --tip-fg: #000000;
    --yes: #187a14;
    --yes-bg: #e8f8e6;
    --paid: #c45f00;
    --paid-bg: #fff1e0;
    --no: #c1121f;
    --no-bg: #fde8ea;
    --unk: #555555;
    --unk-bg: #eeeeee;
    --na: #666666;
  }

  /* Beats theme.js's inline `html { color-scheme }` (root.style.colorScheme). */
  html {
    color-scheme: light !important;
  }

  html,
  body {
    background: #fff;
    color: #000;
    font-size: 11pt;
    line-height: 1.4;
    height: auto;
    overflow: visible;
  }

  * {
    box-shadow: none !important;
  }

  :where(.wrap, .card, article, .guide-result, .signpost, .splash-hero, .splash-code, .splash-stats) {
    border-radius: 0.25rem;
    background: #fff;
  }

  /* Keep the masthead (brand + page H1) so a printed PDF still has a
     document title. Hide only the interactive chrome inside it. */
  .masthead {
    position: static;
    background: #fff;
  }

  .masthead-actions,
  .site-nav-drawer,
  .site-nav-toggle,
  .site-nav-scrim,
  .site-foot,
  .mobile-cta,
  body[data-page="home"] .mobile-cta,
  .storage-notice,
  .skip-link,
  .theme-toggle,
  [data-theme-toggle],
  [data-print-hide] {
    display: none !important;
  }

  details,
  details > summary {
    display: block;
  }

  /* `display: revert` restores the UA box but does not force a closed
     <details> open — its children stay `display: none`. Override that
     for Guide disclosures; leave `.matrix-filter-panel` collapsed so
     thirty filter checkboxes do not dump onto the matrix PDF. */
  details:not(.matrix-filter-panel) > *:not(summary) {
    display: block !important;
  }

  .matrix-filter-panel {
    display: none !important;
  }

  /* UA `[hidden] { display: none !important }` otherwise keeps closed
     drill-downs out of the PDF. Procurement prints want the answers. */
  .drill-row[hidden] {
    display: table-row !important;
  }

  .wrap,
  .gateway-head-name,
  .matrix-full,
  main,
  .shell {
    max-height: none !important;
    overflow: visible !important;
    height: auto;
  }

  /* Long-form research/answers only. Legal pages (.legal-page) and other
     short surfaces must not get a page-per-H2. Skip the first H2 so the
     article title and opening section stay on page one.
     /doc/ also uses .prose, so printing an answers.md there is a page
     per heading — a lot of paper, by design, rather than one wall of
     text. Narrowing that would mean tagging /doc/ with data-page. */
  .prose h2:not(:first-of-type) {
    break-before: page;
    page-break-before: always;
  }

  h1,
  h2,
  h3 {
    break-after: avoid-page;
  }

  tr,
  li {
    break-inside: avoid;
  }

  a[href^="http"]:not([href*="ai-gateway.liatr.io"])::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    color: #444;
  }

  .pill,
  .pill-yes,
  .pill-no,
  .pill-paid,
  .pill-unknown,
  .pill-na,
  .pill.yes,
  .pill.no,
  .pill.paid,
  .pill.unknown,
  .pill.na,
  .mark,
  .mark-chip,
  .mark-yes,
  .mark-paid,
  .mark-no,
  .mark-unknown,
  .mark-na,
  .col-meter,
  .col-meter-seg {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .brand-lockup .wordmark-dark,
  .site-foot-brand .wordmark-dark,
  :root[data-theme="light"] .brand-lockup .wordmark-dark,
  :root[data-theme="light"] .site-foot-brand .wordmark-dark,
  .brand-lockup .logomark,
  :root[data-theme="light"] .brand-lockup .logomark {
    display: none !important;
  }

  .brand-lockup .wordmark-light,
  .site-foot-brand .wordmark-light,
  :root[data-theme="light"] .brand-lockup .wordmark-light,
  :root[data-theme="light"] .site-foot-brand .wordmark-light {
    display: block !important;
  }
}
/* ==========================================================================
   Focus-visible audit
   One consistent focus indicator across every interactive element so a
   keyboard user reads the site the way a mouse user does. outline covers
   modern browsers; the box-shadow halo covers older Safari where
   outline-offset renders quirkily. --focus-ring tracks --accent in dark
   theme and a darker green in light theme so the ring meets WCAG 2.2
   SC 1.4.11 (3:1) against paper in both themes.
   ========================================================================== */
.site-nav-link:focus-visible,
.site-nav-toggle:focus-visible,
.site-nav-scrim:focus-visible,
.site-map-btn:focus-visible,
.site-foot-brand:focus-visible,
.site-foot-legal a:focus-visible,
.site-foot-address a:focus-visible,
.theme-toggle:focus-visible,
[data-theme-toggle]:focus-visible,
.mobile-cta-primary:focus-visible,
.mobile-cta-secondary:focus-visible,
.storage-notice-accept:focus-visible,
.storage-notice-reject:focus-visible,
.privacy-consent-reset:focus-visible,
.site-foot-consent-reset:focus-visible,
.notfound-card:focus-visible,
.legal-page a:focus-visible,
.prose a:focus-visible,
.source-list a:focus-visible,
.sidenav a:focus-visible,
#matrix thead th a:focus-visible,
#matrix tbody th .drill-toggle:focus-visible,
#matrix tbody td .cell-link:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--focus-ring) 30%, transparent);
  border-radius: 0.25rem;
}

/* The skip-link is the only interactive element whose own background is
   --accent. A 2px outline-offset sits the ring against --paper, and
   --focus-ring is the same token as the rest of the audit: lime on dark
   paper, dark green on light paper, both above WCAG 2.2 SC 1.4.11 (3:1).
   currentColor (#14170f) failed that floor against dark --paper (1.09:1).
   The halo still picks up --ink so the pattern reads as one system. */
.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--ink) 30%, transparent);
}

/* ==========================================================================
   Reduced motion
   The `*, *::before, *::after` reset earlier in this file already zeroes
   CSS animations and transitions site-wide; this section pins the specific
   elements the a11y review called out so a parallel change that adds an
   `!important` transition to one of them still respects the preference.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }

  .site-nav-drawer,
  .site-nav-scrim {
    transition: none !important;
  }

  .skip-link {
    transition: none !important;
  }

  .storage-notice {
    animation: none !important;
    transition: none !important;
  }
}

/* == Share affordance ==
   Small copy buttons sit next to matrix row labels and drill-down headings
   so a researcher can grab a shareable markdown citation for any row or
   answer. A matching button in the masthead copies the current URL,
   canonicalized to the published host, so links pasted from a preview
   deploy still land on ai-gateway.liatr.io.

   The control is a DOM sibling of the heading text (`.copy-head` on matrix
   rows, `.drill-head` around the drill `<h3>`), not nested inside the
   heading node, so the row/section accname stays the capability label.
   Hit target is at least 24px (WCAG 2.5.8). Resting opacity stays high
   enough that `--muted` on `--paper` meets 3:1 (1.4.11). Clipboard
   failure is not silent — `showCopyToast("Copy failed")` uses an
   assertive live-region sibling; the visible toast is CSS-only
   (visibility + opacity) and `aria-hidden`. */
.copy-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  vertical-align: middle;
  min-width: 24px;
  min-height: 24px;
  width: 24px;
  height: 24px;
  margin: 0 0 0 0.2rem;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 0.25rem;
  background: transparent;
  color: currentColor;
  font: inherit;
  cursor: pointer;
  line-height: 0;
  opacity: 0.78;
  transition: opacity 120ms ease, background-color 120ms ease, border-color 120ms ease;
}

.copy-btn:hover {
  opacity: 1;
  background: color-mix(in srgb, currentColor 14%, transparent);
}

.copy-btn:focus-visible {
  opacity: 1;
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.copy-btn .copy-glyph {
  width: 0.85rem;
  height: 0.85rem;
}

.copy-btn-row,
.copy-btn-drill,
.copy-btn-share {
  color: var(--muted);
}

.copy-btn-share {
  margin: 0;
}

.copy-btn-text {
  display: none;
}

.copy-head {
  display: flex;
  align-items: flex-start;
  gap: 0.2rem;
}

.copy-head .copy-cluster {
  flex: 1;
  min-width: 0;
}

.copy-head .copy-btn {
  flex-shrink: 0;
  margin: 0;
}

.copy-toast {
  position: fixed;
  left: 50%;
  bottom: 2rem;
  z-index: 100;
  transform: translateX(-50%);
  padding: 0.5rem 1rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font-size: 0.85rem;
  font-weight: 600;
  box-shadow: 0 4px 20px rgb(0 0 0 / 0.25);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 180ms ease, visibility 180ms ease;
}

.copy-toast.is-visible {
  opacity: 1;
  visibility: visible;
}

@media (prefers-reduced-motion: reduce) {
  .copy-toast {
    transition: none;
  }
}
