/* Insurance Verified — public site.
   Palette, type, and spacing are taken from the approved Pen frames:
   "Landing — APPROVED" (1440x900), "Landing — 390", "Docs — Quickstart",
   and "Docs — POST /documents". */

:root {
  /* Motion tempo. Every entrance, reveal, cross-fade and travelling line is
     declared as a base duration times this factor, so the whole site can be
     made slower or quicker by changing one number. 1 is the original
     timing; 1.5 is what was asked for on 8/27. Interaction feedback under
     200ms (hover colour, button press) is deliberately left off the tempo. */
  --tempo: 1.5;
  --paper: #F6F5F1;
  --paper-pure: #FFFFFF;
  --ink: #0B0B0C;
  --ink-05: rgba(11, 11, 12, 0.05);
  --ink-70: #4B4B50;
  --ink-45: #8A8A90;
  --rule: #E2DFD7;
  --accent: #1E9E52;
  --accent-soft: #FFE7DC;
  --accent-12: #1E9E521F;
  --accent-32: #1E9E5252;
  --accent-55: #1E9E528C;
  --on-ink-12: #FFFFFF1F;
  --on-ink-40: #FFFFFF66;

  /* The docs grid and the header share one cap so their edges line up. */
  --docs-max: 105.5rem;
  --header-h: 4rem;

  --font-display: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo,
    Consolas, "Liberation Mono", monospace;
}

*, *::before, *::after { box-sizing: border-box; }

html {
  /* Fallback for browsers without clamp()/vw math; overridden below. */
  font-size: 16px;
  /* 16px at <=1440px viewport width, scaling linearly to 20px at 2560px. */
  font-size: clamp(16px, calc(16px + (100vw - 1440px) * (4 / 1120)), 20px);
  scrollbar-width: thin;
  scrollbar-color: var(--rule) transparent;
}
html::-webkit-scrollbar { width: 10px; height: 10px; }
html::-webkit-scrollbar-track { background: transparent; }
html::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 5px; }
html::-webkit-scrollbar-thumb:hover { background: var(--ink-45); }

html, body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-display);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }

/* Hover: a hairline drawn in from the left in the link's own colour. The
   selector list is explicit so the lockup, the primary button, and the mark
   button stay clean. Operation rows in the docs nav are left out on purpose:
   their labels clamp to two lines, and a rule under a wrapped label reads as
   a box edge rather than an underline. They keep the ink colour change and
   the follower rule instead. */
.landing-nav a,
.btn-text,
.docs-header-link,
.footer-line a,
.prose a,
.doc-note a,
.docs-nav .nav-item:not(.nav-item-op) > a .nav-text {
  position: relative;
}
.landing-nav a::after,
.btn-text::after,
.docs-header-link::after,
.footer-line a::after,
.prose a::after,
.doc-note a::after,
.docs-nav .nav-item:not(.nav-item-op) > a .nav-text::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 180ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.landing-nav a:hover::after,
.landing-nav a:focus-visible::after,
.btn-text:hover::after,
.btn-text:focus-visible::after,
.docs-header-link:hover::after,
.docs-header-link:focus-visible::after,
.footer-line a:hover::after,
.footer-line a:focus-visible::after,
.prose a:hover::after,
.prose a:focus-visible::after,
.doc-note a:hover::after,
.doc-note a:focus-visible::after,
.docs-nav .nav-item:not(.nav-item-op) > a:hover .nav-text::after,
.docs-nav .nav-item:not(.nav-item-op) > a:focus-visible .nav-text::after {
  transform: scaleX(1);
}
.docs-nav .nav-item:not(.nav-item-op) > a .nav-text::after { bottom: -2px; }

/* ---------------------------------------------------------------- the mark */

.mark { display: block; overflow: visible; }
.mark-halo-outer { fill: var(--accent-12); }
.mark-halo-mid { fill: var(--accent-32); }
.mark-core { fill: var(--accent-55); }
.mark-line path, .mark-line circle {
  stroke: var(--ink);
  fill: none;
  vector-effect: non-scaling-stroke;
}

.mark-148 .mark-line path, .mark-148 .mark-line circle { stroke-width: 2.31px; }
.mark-96  .mark-line path, .mark-96  .mark-line circle { stroke-width: 1.5px; }
.mark-24  .mark-line path, .mark-24  .mark-line circle { stroke-width: 0.8px; }
.mark-20  .mark-line path, .mark-20  .mark-line circle { stroke-width: 1.52px; }

/* The landing mark is sized in rem (over the SVG's width/height attributes)
   so it scales with the root type on larger screens. */
.mark-148 { width: 9.25rem; height: 9.25rem; }
.mark-24 { width: 1.5rem; height: 1.5rem; }

/* The micro cut drops the outer halo. */
.mark-20 .mark-halo-outer { display: none; }

/* Motion: the pulse is the only moving part on the page, and all of it is
   CSS.

   The breathe is one @keyframes on .mark-pulse. Script never touches that
   element — not its style, not its class — so from first paint to the last
   frame of the session the animation cannot be restarted, re-phased, or
   cancelled. The earlier rAF loop, which drove the same values from
   JavaScript and bent the period toward the pointer, is gone: writing
   opacity and transform from script every frame, on top of a compositor
   animation that was also running, is what made the mark stutter on a
   Retina display. Pointer proximity is withdrawn with it.

   Each of the three groups owns exactly one animation, so none of them ever
   contends for the `animation` property: .mark-pulse breathes, .mark-beat
   beats, .mark-rise fades in on the entrance. transform-box: fill-box makes
   each group scale about its own centre rather than the viewBox origin. */
.mark-rise, .mark-beat, .mark-pulse {
  transform-box: fill-box;
  transform-origin: center;
}

.mark-148 .mark-pulse, .mark-96 .mark-pulse {
  animation: mark-breathe calc(2.4s * var(--tempo)) ease-in-out infinite;
  will-change: transform, opacity;
}
.mark-148 .mark-core, .mark-96 .mark-core {
  animation: mark-core-breathe calc(2.4s * var(--tempo)) ease-in-out infinite;
  will-change: opacity;
}

@keyframes mark-breathe {
  0%, 100% { transform: scale(1);    opacity: 0.35; }
  50%      { transform: scale(1.08); opacity: 0.75; }
}

/* The centre deepens in step with the halo. */
@keyframes mark-core-breathe {
  0%, 100% { opacity: 0.7; }
  50%      { opacity: 1; }
}

/* Transform only: opacity belongs to the breathe underneath. */
@keyframes mark-beat {
  0%   { transform: scale(1); }
  22%  { transform: scale(1.16); }
  60%  { transform: scale(0.97); }
  100% { transform: scale(1); }
}

/* ------------------------------------------------------- landing entrance

   First visit of a session: the outline draws itself as one continuous
   stroke, the axis follows once the outline is closed, the ring fades in and
   the mark takes one beat, then the words rise. A later visit in the same
   session gets the same shape, shortened.

   The whole sequence is CSS. site.js does exactly one thing to it: at load
   it measures each stroke, writes the dash inline, and adds .is-drawing.
   Everything after that belongs to the compositor, and the animation is no
   longer a WAAPI one racing the stylesheet for the same properties.

   The measurement is not optional, and it is not a plain getTotalLength():
   these strokes carry vector-effect: non-scaling-stroke, so the dash is
   drawn in screen pixels while getTotalLength() answers in viewBox units.
   See site.js for what that discrepancy looked like on screen.

   The 1000 below is longer than any stroke in the mark measured in either
   space, so nothing shows between first paint and the measured values
   landing.

   The classes come off on the last animation's own end event, never on a
   timer racing the animations it is supposed to follow. */

@keyframes mark-draw { to { stroke-dashoffset: 0; } }

.enter-full  .mark-148 { --draw-ms: calc(900ms * var(--tempo)); --axis-ms: calc(150ms * var(--tempo)); --fade-ms: calc(350ms * var(--tempo)); }
.enter-short .mark-148 { --draw-ms: calc(420ms * var(--tempo)); --axis-ms: calc(85ms * var(--tempo)); --fade-ms: calc(200ms * var(--tempo)); }

.enter-full .mark-148 .mark-line path,
.enter-short .mark-148 .mark-line path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
}
.enter-full .mark-148 .mark-ring,
.enter-short .mark-148 .mark-ring { opacity: 0; }
.enter-full .mark-148 .mark-rise,
.enter-short .mark-148 .mark-rise { opacity: 0; }

/* The outline draws first, as one continuous closed stroke. The two axis
   segments follow in document order, so the axis reads as a single line
   descending through the ring; they are paths 2 and 3 of .mark-line, the
   outline being path 1. Then the ring lands and the mark takes one beat. */
.mark-148.is-drawing .mark-outline {
  animation: mark-draw var(--draw-ms) ease-out both;
}
.mark-148.is-drawing .mark-axis:nth-of-type(2) {
  animation: mark-draw var(--axis-ms) linear var(--draw-ms) both;
}
.mark-148.is-drawing .mark-axis:nth-of-type(3) {
  animation: mark-draw var(--axis-ms) linear
             calc(var(--draw-ms) + var(--axis-ms)) both;
}
.mark-148.is-drawing .mark-ring {
  animation: fade-in var(--fade-ms) cubic-bezier(0.22, 1, 0.36, 1)
             calc(var(--draw-ms) + var(--axis-ms)) both;
}
.mark-148.is-drawing .mark-rise {
  animation: fade-in var(--fade-ms) cubic-bezier(0.22, 1, 0.36, 1)
             calc(var(--draw-ms) + var(--axis-ms) * 2) both;
}
.mark-148.is-drawing .mark-beat {
  animation: mark-beat calc(800ms * var(--tempo)) cubic-bezier(0.2, 0.8, 0.2, 1)
             calc(var(--draw-ms) + var(--axis-ms) * 2) 1 both;
}

/* A click, or the pointer crossing into the shield, beats on top of whatever
   the entrance is doing. Listed last and at equal weight so it wins. */
.mark-148 .mark-beat.is-beating, .mark-96 .mark-beat.is-beating {
  animation: mark-beat calc(800ms * var(--tempo)) cubic-bezier(0.2, 0.8, 0.2, 1) 1;
}

/* ------------------------------------------------------------- the lockup */

.lockup { display: inline-flex; align-items: center; gap: 0.6875rem; }
.lockup:hover { text-decoration: none; }
.wordmark {
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.03125rem;
  line-height: 1;
  color: var(--ink);
}

/* --------------------------------------------------------- landing (1440) */

.page-landing { overflow: hidden; }

.landing {
  height: 100dvh;
  /* In rem, like the type inside it: at 1440px this is the 1440 frame, and
     on a wide display it grows with the root size instead of leaving the
     headline to wrap inside a fixed 1440px box. */
  max-width: 90rem;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  padding: 2.125rem 3rem;
  background: var(--paper);
}

.landing-header {
  flex: none;
  height: 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.landing-nav {
  display: flex;
  align-items: center;
  gap: 1.75rem;
  font-size: 0.875rem;
  line-height: 0.9375rem;
  color: var(--ink-70);
}

.landing-centre {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.mark-button {
  appearance: none;
  border: 0;
  padding: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  line-height: 0;
}
.mark-button:focus-visible { outline: 1px solid var(--ink); outline-offset: 6px; }

/* The words rise 8px on a 60ms stagger once the mark has finished drawing
   and taken its beat; the footer comes last. `both` puts each element in its
   start state at first paint, so nothing flashes, and only opacity and
   transform move, so nothing shifts. Without the entrance class - no script,
   or reduced motion - every one of these is simply already in place. */
@keyframes rise-in {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}

/* At tempo 1: outline 0-900, axis 900-1200, ring 1100-1450, one beat at
   1200, then the words. Every figure below scales with --tempo.
   Compositor-only: opacity and transform, nothing else. */
.enter-full .landing-headline { animation: rise-in calc(520ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) calc(1450ms * var(--tempo)) both; }
.enter-full .landing-sub      { animation: rise-in calc(520ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) calc(1520ms * var(--tempo)) both; }
.enter-full .landing-actions  { animation: rise-in calc(520ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) calc(1590ms * var(--tempo)) both; }
.enter-full .landing-footer   { animation: rise-in calc(520ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) calc(1660ms * var(--tempo)) both; }

.enter-short .landing-headline { animation: rise-in calc(340ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) calc(420ms * var(--tempo)) both; }
.enter-short .landing-sub      { animation: rise-in calc(340ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) calc(470ms * var(--tempo)) both; }
.enter-short .landing-actions  { animation: rise-in calc(340ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) calc(520ms * var(--tempo)) both; }
.enter-short .landing-footer   { animation: rise-in calc(340ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) calc(570ms * var(--tempo)) both; }

.landing-headline {
  margin: 2.75rem 0 0;
  max-width: 62.5rem;
  text-wrap: balance;
  font-size: 2.875rem;
  font-weight: 600;
  letter-spacing: -0.1125rem;
  line-height: 1.12;
  text-align: center;
  color: var(--ink);
}

.landing-sub {
  margin: 1.25rem 0 0;
  max-width: 44rem;
  text-wrap: balance;
  font-size: 1.0625rem;
  font-weight: 400;
  line-height: 1.5;
  text-align: center;
  color: var(--ink-70);
}

/* The headline is one line on anything desktop-sized; below that it wraps,
   balanced. Both the measure and the type are in rem, so the line holds at
   every root size rather than only at 1440. */
@media (min-width: 1100px) {
  .landing-headline { max-width: none; white-space: nowrap; }
  .landing-sub { white-space: nowrap; max-width: none; }
}

.landing-actions {
  margin-top: 2.375rem;
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.btn-primary {
  display: inline-flex;
  align-items: center;
  padding: 0.8125rem 1.25rem;
  border-radius: 3px;
  background: var(--ink);
  color: var(--paper);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 0.9375rem;
}
.btn-primary {
  transition: background-color 120ms ease, transform 80ms ease;
}
.btn-primary:hover { text-decoration: none; background: #000; }
.btn-primary:active { transform: scale(0.98); }

.btn-text {
  font-size: 0.875rem;
  line-height: 0.9375rem;
  color: var(--ink-70);
}

.landing-footer {
  flex: none;
  height: 0.8125rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 0.625rem;
  line-height: 0.8125rem;
  letter-spacing: 0.0625rem;
  color: var(--ink-45);
}

/* ---------------------------------------------------------- landing (390) */

@media (max-width: 600px) {
  .landing { padding: 1.625rem 1.5rem; }
  .landing-header { height: 1.25rem; }
  .lockup { gap: 0.5625rem; }
  .wordmark { font-size: 0.875rem; letter-spacing: -0.028125rem; }
  .landing-nav { gap: 1.25rem; font-size: 0.84375rem; }
  .landing-nav .nav-secondary { display: none; }

  .mark-148 { width: 6rem; height: 6rem; }
  .mark-148 .mark-line path, .mark-148 .mark-line circle { stroke-width: 1.5px; }

  .landing-headline {
    margin-top: 2rem;
    max-width: 330px;
    font-size: 1.8125rem;
    letter-spacing: -0.06875rem;
    line-height: 1.15;
  }
  .landing-sub { margin-top: 1rem; max-width: 320px; font-size: 0.90625rem; }
  .landing-actions { margin-top: 1.875rem; flex-direction: column; gap: 1.125rem; }
  .landing-footer { height: 0.6875rem; font-size: 0.53125rem; line-height: 0.6875rem; letter-spacing: 0.03125rem; }
}

/* ------------------------------------------------------------------- docs */

.docs {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
}

.docs-header {
  position: sticky;
  top: 0;
  z-index: 10;
  flex: none;
  height: var(--header-h);
  background: var(--paper-pure);
  border-bottom: 1px solid var(--rule);
}

.docs-header-inner {
  height: 100%;
  max-width: var(--docs-max);
  margin: 0 auto;
  padding: 0 2rem;
  display: flex;
  align-items: center;
}
.docs-header .wordmark { font-size: 0.875rem; letter-spacing: -0.028125rem; }
.docs-header .lockup { gap: 10px; }

.docs-header-link {
  margin-left: 26px;
  font-size: 0.84375rem;
  line-height: 0.9375rem;
  color: var(--ink);
}
.docs-header-link.muted { margin-left: 24px; color: var(--ink-70); }
.docs-header-spacer { flex: 1 1 auto; }

.docs-search {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: 280px;
  height: 30px;
  padding: 0 10px;
  border: 1px solid var(--rule);
  border-radius: 3px;
  color: var(--ink-45);
  background: var(--paper-pure);
}
.docs-search input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline: 0;
  background: none;
  font-family: var(--font-display);
  font-size: 0.78125rem;
  color: var(--ink);
}
.docs-search input::placeholder { color: var(--ink-45); }

/* Three fluid tracks inside one cap. The percentages hold the 1440 frame
   exactly (248 / 672 / 520) and the clamps stop the nav and the code panel
   from running away on a wide display; the reading column takes the rest. */
.docs-body {
  flex: 1 1 auto;
  width: 100%;
  max-width: var(--docs-max);
  margin: 0 auto;
  display: grid;
  grid-template-columns:
    clamp(15rem, 17.2%, 17.5rem)
    minmax(0, 1fr)
    clamp(23.75rem, 36.1%, 35rem);
  grid-template-areas: "nav content panel";
  align-items: stretch;
}

/* nav */

.docs-nav {
  grid-area: nav;
  min-width: 0;
  border-right: 1px solid var(--rule);
}

/* The nav pins under the header and scrolls its own overflow on a hairline,
   exactly as the code panel does. No overscroll-behavior: once the column
   reaches its end the wheel chains back to the page, so a reader who lands
   the pointer here never finds the page refusing to move. */
.docs-nav-inner {
  position: sticky;
  top: var(--header-h);
  max-height: calc(100dvh - var(--header-h));
  padding: 1.875rem 0.75rem 1.875rem 1.75rem;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--rule) transparent;
}
.docs-nav-inner::-webkit-scrollbar { width: 6px; }
.docs-nav-inner::-webkit-scrollbar-track { background: transparent; }
.docs-nav-inner::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 3px; }
.docs-nav-inner::-webkit-scrollbar-thumb:hover { background: var(--ink-45); }

.nav-group-label {
  margin: 0 0 14px;
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  line-height: 0.8125rem;
  letter-spacing: 0.08125rem;
  color: var(--ink-45);
}
.nav-group-label-second { margin-top: 26px; }

.nav-list { margin: 0; padding: 0; list-style: none; }
.nav-list-ops { margin-bottom: 10px; }

.nav-item { margin: 0; }
.nav-item > a, .nav-section-head {
  display: flex;
  align-items: center;
  height: 30px;
  margin: 0;
  font-size: 0.78125rem;
  line-height: 0.875rem;
  color: var(--ink-70);
}
.nav-item > a:hover { text-decoration: none; color: var(--ink); }

.nav-bar {
  flex: none;
  width: 2px;
  height: 16px;
  margin-right: 12px;
  background: transparent;
}
.nav-item.is-current > a .nav-bar { background: var(--ink); }

/* A second, lighter rule tracks the hovered row. The current page's ink bar
   is a different element and never moves. site.js parks this one on the
   hovered anchor's bar and fades it out when the pointer leaves the nav. */
.nav-hover-rule {
  position: absolute;
  top: 0;
  left: 0;
  width: 2px;
  height: 16px;
  background: var(--ink-45);
  opacity: 0;
  pointer-events: none;
  transition: transform 160ms cubic-bezier(0.2, 0.8, 0.2, 1),
              height 160ms cubic-bezier(0.2, 0.8, 0.2, 1),
              opacity 160ms ease;
}
.docs-nav-inner.rule-on .nav-hover-rule { opacity: 1; }
.nav-item.is-current > a .nav-text { color: var(--ink); font-weight: 600; }

.nav-section-head { color: var(--ink); font-weight: 600; }
.nav-section-head > a { flex: 1 1 auto; color: var(--ink); font-weight: 600; }
.nav-section-head > a:hover { text-decoration: none; }
.nav-section-head .nav-bar { background: transparent; }

/* An operation shows its summary in the sans face with the method as a mono
   tag. The full path stays on the reference page's own title. */
.nav-item-op > a {
  height: auto;
  min-height: 24px;
  align-items: flex-start;
  padding: 5px 0 5px 14px;
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--ink-45);
}
.nav-item-op .nav-bar { margin-top: 2px; height: 12px; }
.nav-method {
  flex: none;
  width: 30px;
  margin-right: 8px;
  font-family: var(--font-mono);
  font-size: 0.53125rem;
  line-height: 1rem;
  letter-spacing: 0.05625rem;
  color: var(--ink-45);
}
.nav-item-op .nav-text {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: break-word;
}
.nav-item-op.is-current > a { color: var(--ink); }
.nav-item-op.is-current > a .nav-method { color: var(--ink); }
.nav-item-op.is-current > a .nav-text { color: var(--ink); font-weight: 500; }

.nav-empty {
  margin: 8px 0 0;
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  letter-spacing: 0.08125rem;
  color: var(--ink-45);
}

/* content column */

.docs-content {
  grid-area: content;
  min-width: 0;
  /* 760px of reading measure plus the two 44px gutters. */
  max-width: 848px;
  padding: 2.5rem 2.75rem;
}

.eyebrow {
  margin: 0 0 10px;
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  line-height: 0.8125rem;
  letter-spacing: 0.08125rem;
  color: var(--ink-45);
}

/* Operations and guides that ship at launch rather than today. Mono caption
   scale, outlined, ink on paper: informative, never a warning colour. */
.status-pill {
  display: inline-block;
  margin: -2px 0 14px;
  padding: 3px 8px;
  border: 1px solid var(--rule);
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  line-height: 0.8125rem;
  letter-spacing: 0.08125rem;
  color: var(--ink-70);
}

.doc-h1 {
  margin: 0 0 14px;
  font-size: 1.875rem;
  font-weight: 600;
  letter-spacing: -0.0625rem;
  line-height: 1.1;
  color: var(--ink);
}
.doc-h1-mono {
  font-family: var(--font-mono);
  font-size: 1.375rem;
  font-weight: 400;
  letter-spacing: -0.0125rem;
  word-break: break-word;
}

.doc-intro {
  margin: 0 0 30px;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--ink-70);
}

.doc-note {
  margin: 18px 0 0;
  font-size: 0.78125rem;
  line-height: 1.45;
  color: var(--ink-70);
}
.doc-note code { font-family: var(--font-mono); font-size: 0.6875rem; color: var(--ink); }

/* section heads: label + hairline */

.section-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 30px 0 12px;
}
.section-head-spaced { margin-top: 28px; }
.section-label {
  flex: none;
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  line-height: 0.8125rem;
  letter-spacing: 0.08125rem;
  color: var(--ink-45);
}
.section-rule { flex: 1 1 auto; height: 1px; background: var(--rule); }

/* reference tables */

.spec-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}
.spec-table th {
  padding: 0 0.75rem 0.5625rem 0;
  text-align: left;
  font-family: var(--font-mono);
  font-size: 0.5625rem;
  font-weight: 400;
  line-height: 0.75rem;
  letter-spacing: 0.075rem;
  color: var(--ink-45);
  border-bottom: 1px solid var(--ink);
}
.spec-table td {
  padding: 1rem 0.75rem 1rem 0;
  vertical-align: top;
  border-bottom: 1px solid var(--rule);
}
.spec-table tbody tr:last-child td { border-bottom: 0; }
.spec-table .col-name { width: 150px; }
.spec-table .col-type { width: 84px; }
.spec-table .col-req { width: 76px; }

.cell-name {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  line-height: 1.45;
  color: var(--ink);
  word-break: break-word;
}
.cell-type {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  line-height: 1.45;
  color: var(--ink-45);
  word-break: break-word;
}
.cell-desc {
  font-size: 0.78125rem;
  line-height: 1.45;
  color: var(--ink-70);
}

/* content footer */

.docs-content-footer { margin-top: 49px; }
.rule { height: 1px; border: 0; margin: 0 0 14px; background: var(--rule); }
.footer-line {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  line-height: 0.8125rem;
  letter-spacing: 0.0625rem;
  color: var(--ink-45);
}
.footer-line a { color: inherit; }

/* prose (rendered guide markdown) */

.prose { color: var(--ink-70); }
.prose > p {
  margin: 0 0 18px;
  font-size: 0.84375rem;
  line-height: 1.6;
}
.prose > p:first-child {
  margin-bottom: 30px;
  font-size: 0.875rem;
  line-height: 1.6;
}

.prose h2 {
  margin: 30px 0 12px;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.021875rem;
  line-height: 1.1;
  color: var(--ink);
}
.prose h3 {
  margin: 24px 0 9px;
  font-size: 0.84375rem;
  font-weight: 600;
  color: var(--ink);
}

.prose ol {
  margin: 0 0 24px;
  padding: 0;
  list-style: none;
  counter-reset: step;
}
.prose ol > li {
  position: relative;
  padding-left: 36px;
  margin-bottom: 24px;
}
.prose ol > li::before {
  counter-increment: step;
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0;
  width: 20px;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  line-height: 1rem;
  letter-spacing: 0.025rem;
  color: var(--ink-45);
}
.prose ol > li > p { margin: 0 0 9px; font-size: 0.84375rem; line-height: 1.6; }
.prose ol > li > p:first-child { margin-bottom: 9px; }
.prose ol > li > p:first-child strong {
  display: block;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.021875rem;
  line-height: 1.05;
  color: var(--ink);
}
.prose ol > li > p:last-child { margin-bottom: 0; }

/* The step the reader is on, when the guide maps its steps to samples: the
   number goes to ink and an ink rule draws down the number gutter, matching
   the docs nav's current-page bar. Transform and opacity only. Added by
   site.js. */
.prose ol > li::after {
  content: "";
  position: absolute;
  left: 0;
  /* From the top of the body copy (the title's line box plus its 9px
     margin) to the bottom of the caption, so the rule brackets the words
     under the title at every step and every type size. */
  top: calc(1.05rem + 9px);
  bottom: 0;
  width: 1px;
  background: var(--ink);
  opacity: 0;
  transform: scaleY(0);
  transform-origin: top center;
  transition: opacity calc(240ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1),
              transform calc(240ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1);
}
.prose ol > li.is-current-step::before { color: var(--ink); }
.prose ol > li.is-current-step::after { opacity: 1; transform: scaleY(1); }

.prose ul { margin: 0 0 18px; padding-left: 18px; }
.prose ul > li { margin-bottom: 8px; font-size: 0.84375rem; line-height: 1.6; }

/* mono captions, marked in the markdown with {: .caption } */
.prose p.caption,
.prose ol > li > p.caption {
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  line-height: 1.5;
  letter-spacing: 0.05625rem;
  color: var(--ink-45);
  text-transform: uppercase;
}
.prose p.caption code { font-size: 0.59375rem; color: inherit; }

/* Inline identifiers read as tokens: a touch larger than before, on a faint
   tint with a hair of padding, so a sentence with several of them still
   scans. Blocks (pre) and the reference tables keep their own sizes. */
.prose code {
  font-family: var(--font-mono);
  font-size: 0.78125rem;
  padding: 0.0625rem 0.3125rem;
  border-radius: 3px;
  background: var(--ink-05);
  color: var(--ink);
}
.prose pre code { font-size: inherit; padding: 0; background: none; border-radius: 0; }
/* Next: two destinations at the foot of a guide, as outlined link cards.
   The card is the whole target. Hairline border, title, one line, and the
   border darkens on hover; no arrows, no colour. */
.prose .next-links {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin: 0 0 8px;
}
.prose a.next-link {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px 18px 18px;
  border: 1px solid var(--rule);
  border-radius: 4px;
  text-decoration: none;
  color: var(--ink);
  transition: border-color 160ms ease, background-color 160ms ease;
}
.prose a.next-link::after { content: none; }
.prose a.next-link:hover,
.prose a.next-link:focus-visible { border-color: var(--ink); background: var(--paper-pure); }
.prose a.next-link:focus-visible { outline: 1px solid var(--ink); outline-offset: 2px; }
.next-title { font-size: 0.9375rem; font-weight: 600; letter-spacing: -0.015rem; line-height: 1.2; }
.next-desc { font-size: 0.78125rem; line-height: 1.5; color: var(--ink-70); }
.prose .next-links:has(> .next-link:nth-child(3)) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 1100px) { .prose .next-links:has(> .next-link:nth-child(3)) { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px) { .prose .next-links, .prose .next-links:has(> .next-link:nth-child(3)) { grid-template-columns: minmax(0, 1fr); } }

/* Captions are already mono; a token inside one needs no tint. */
.prose p.caption code { font-size: inherit; padding: 0; background: none; border-radius: 0; }

/* An endpoint token that has a reference page. The token keeps its look; the
   link shows only as a hairline under it that darkens on hover, so a linked
   token and a plain one sit on the same baseline. */
.prose a.code-link { text-decoration: none; }
.prose a.code-link::after { content: none; }
.prose a.code-link code {
  border-bottom: 1px solid var(--ink-45);
  border-radius: 3px 3px 0 0;
  transition: border-bottom-color 120ms ease, background-color 120ms ease;
}
.prose a.code-link:hover code,
.prose a.code-link:focus-visible code { border-bottom-color: var(--ink); background: var(--ink-10, var(--ink-05)); }

.prose pre {
  margin: 0 0 18px;
  padding: 1.125rem;
  background: var(--ink);
  overflow-x: auto;
  /* Chrome's fixed-width generic-font default is 13px; before the root
     font-size rule below existed, this bare <pre> (no font-size of its own)
     fell through to that default rather than truly inheriting 16px. Pin it
     explicitly so introducing the root rule doesn't shift this element. */
  font-size: 0.8125rem;
}
.prose pre code {
  font-size: 0.65625rem;
  line-height: 1.7;
  color: var(--paper);
}

.prose blockquote {
  margin: 28px 0 0;
  padding: 16px 18px;
  border: 1px solid var(--rule);
}
.prose blockquote p {
  margin: 0;
  font-size: 0.84375rem;
  line-height: 1.55;
  color: var(--ink);
}

.prose table {
  width: 100%;
  margin: 0 0 18px;
  border-collapse: collapse;
  table-layout: fixed;
}
.prose th {
  padding: 0 0.75rem 0.5625rem 0;
  text-align: left;
  font-family: var(--font-mono);
  font-size: 0.5625rem;
  font-weight: 400;
  letter-spacing: 0.075rem;
  text-transform: uppercase;
  color: var(--ink-45);
  border-bottom: 1px solid var(--ink);
}
.prose td {
  padding: 0.875rem 0.75rem 0.875rem 0;
  vertical-align: top;
  font-size: 0.78125rem;
  line-height: 1.45;
  color: var(--ink-70);
  border-bottom: 1px solid var(--rule);
}
.prose td code { font-size: 0.75rem; }

/* Three-column guide tables hold a step, an endpoint, and a reason. The mono
   endpoint gets a third of the row and wraps inside it. */
.prose table.cols-3 th:nth-child(1),
.prose table.cols-3 td:nth-child(1) { width: 30%; }
.prose table.cols-3 th:nth-child(2),
.prose table.cols-3 td:nth-child(2) { width: 35%; }
.prose table.cols-3 th:nth-child(3),
.prose table.cols-3 td:nth-child(3) { width: 35%; }
.prose td code { overflow-wrap: anywhere; }

/* code panel */

/* The column hairline lives on the reading column's right edge, not on the
   panel's left edge. The panel is `align-self: start` beside the wide
   viewports so that it can pin, which means it is only as tall as its own
   content; a border on it would stop short of the footer. .docs-content
   still stretches, so its edge draws the full-height line in exactly the
   same place. */
.code-panel {
  grid-area: panel;
  min-width: 0;
  padding: 2.5rem 1.75rem;
}

.panel-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}
.panel-head-spaced { margin-top: 26px; }
.panel-label {
  flex: none;
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  line-height: 0.8125rem;
  letter-spacing: 0.08125rem;
  color: var(--ink-45);
}
.panel-rule { flex: 1 1 auto; height: 1px; background: var(--rule); }

/* Copy sits on the REQUEST rule, top right of the request block. Success is
   a confirmation, so it is allowed the green: tick plus "Copied" for 1.2s. */
.copy-btn {
  flex: none;
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  /* The button is taller than the label it sits beside. The negative block
     margins keep it out of the row's height calculation, so adding Copy did
     not push the panel down; it overhangs into the 12px gap below. */
  margin: -0.21875rem 0;
  padding: 2px 7px;
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: none;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 0.5625rem;
  line-height: 0.875rem;
  letter-spacing: 0.05rem;
  text-transform: uppercase;
  color: var(--ink-45);
  transition: color 120ms ease, border-color 120ms ease;
}
.copy-btn:hover { color: var(--ink); border-color: var(--ink-45); }
.copy-btn:focus-visible { outline: 1px solid var(--ink); outline-offset: 2px; }
.copy-tick { display: none; line-height: 0; }
.copy-btn.is-copied { color: var(--accent); border-color: var(--accent-55); }
.copy-btn.is-copied .copy-tick { display: inline-flex; }

.langs { display: flex; align-items: center; gap: 18px; margin-bottom: 12px; }
.lang {
  appearance: none;
  border: 0;
  padding: 0;
  background: none;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  line-height: 0.9375rem;
  letter-spacing: 0.0375rem;
  color: var(--ink-45);
}
.lang .lang-underline { display: block; width: 100%; height: 1px; background: transparent; }
.lang.is-active { color: var(--ink); }
.lang.is-active .lang-underline { background: var(--ink); }

/* Language switch. The panes sit in normal flow and only the chosen one is
   in the document (`hidden` on the rest), so the panel is always exactly as
   tall as the sample showing: a short curl never leaves a band of paper
   under it before the response. A switch resizes at once and the incoming
   pane fades in over the new height; opacity only, nothing else moves.
   Without script the first pane shows, exactly as before. */
.lang-panes { position: relative; }
.lang-pane.is-entering {
  animation: fade-in calc(240ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Quickstart's per-step panels: the step in view is in flow, the rest are
   stacked behind it, faded out and dropped 6px. A step change is a
   cross-fade with a short rise on the incoming panel; the outgoing one
   keeps its fade, and visibility is only withdrawn once that fade has
   ended, so it never blinks off. Opacity and transform only; the sticky
   box is the parent .code-panel, which carries no transform. Without JS
   the first step shows and nothing else does. */
.panel-step {
  transition: opacity calc(240ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1),
              transform calc(240ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1),
              visibility 0s;
}
.panel-step:not(.is-active) {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  opacity: 0;
  transform: translateY(6px);
  visibility: hidden;
  pointer-events: none;
  transition: opacity calc(240ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1),
              transform calc(240ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1),
              visibility 0s linear calc(240ms * var(--tempo));
}
.panel-steps { position: relative; }

.code-block, .prose pre {
  scrollbar-width: thin;
  scrollbar-color: var(--on-ink-40) transparent;
}
.code-block::-webkit-scrollbar, .prose pre::-webkit-scrollbar { height: 6px; width: 6px; }
.code-block::-webkit-scrollbar-track,
.prose pre::-webkit-scrollbar-track { background: transparent; }
.code-block::-webkit-scrollbar-thumb,
.prose pre::-webkit-scrollbar-thumb { background: var(--on-ink-40); border-radius: 3px; }

.code-block {
  margin: 0 0 0;
  padding: 1.125rem;
  background: var(--ink);
  overflow-x: auto;
}
/* Same fixed-width generic-font default as .prose pre above: the bare
   <pre class="code-block"> tabs have no font-size of their own, so pin them
   to what they resolved to before the root font-size rule existed. The
   <div class="code-block code-block-framed"> panes aren't a monospace
   generic-family element and were never affected, so this stays pre-only. */
pre.code-block { font-size: 0.8125rem; }
.code-block code,
.code-block pre {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.65625rem;
  line-height: 1.7;
  color: var(--paper);
  white-space: pre;
}
.code-block-framed { padding: 1.125rem; }

.code-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-family: var(--font-mono);
  font-size: 0.65625rem;
  line-height: 0.875rem;
  letter-spacing: 0.025rem;
}
.status-ok { color: var(--accent); }
.status-event { color: var(--paper); }
.status-aside {
  font-size: 0.5625rem;
  letter-spacing: 0.05rem;
  color: var(--on-ink-40);
}
.code-hairline {
  height: 1px;
  border: 0;
  margin: 12px 0;
  background: var(--on-ink-12);
}

.panel-note {
  margin: 14px 0 0;
  font-family: var(--font-mono);
  font-size: 0.5625rem;
  line-height: 1.6;
  letter-spacing: 0.05rem;
  color: var(--ink-45);
}

/* ------------------------------------------------- page-load line (header) */

/* A hairline that runs the width of the header while a same-site navigation
   is in flight: 0 to ~70% on the click, 70% to 100% on the next page's load,
   then it fades. Ink, never green — nothing here is verified. */
/* .docs-header is NOT listed here. It is `position: sticky` further up, and
   `position: sticky` is already a positioned value, so it anchors .page-line
   on its own. Naming it here at equal weight but later in the file quietly
   reset it to `relative` and unpinned the docs header: the header scrolled
   out of view with the page, and the panel column was left looking like the
   only thing that stayed. Nothing may set `position` on .docs-header except
   the rule that makes it sticky. */
.landing-header { position: relative; }
.page-line {
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: left center;
  opacity: 0;
  pointer-events: none;
  z-index: 1;
}
.docs-header .page-line { bottom: -1px; }
.landing-header .page-line { bottom: -0.5rem; }
.page-line.is-running {
  opacity: 1;
  transform: scaleX(0.7);
  transition: transform calc(600ms * var(--tempo)) cubic-bezier(0.16, 0.72, 0.28, 1);
}
.page-line.is-arriving { opacity: 1; transform: scaleX(0.7); }
.page-line.is-done {
  opacity: 1;
  transform: scaleX(1);
  transition: transform calc(180ms * var(--tempo)) ease-out;
}
.page-line.is-fading {
  opacity: 0;
  transform: scaleX(1);
  transition: opacity calc(200ms * var(--tempo)) ease calc(60ms * var(--tempo));
}

/* F3: the header's hairline darkens once the page has moved. */
.docs-header { transition: border-bottom-color calc(200ms * var(--tempo)) ease; }
.docs-header.is-scrolled { border-bottom-color: var(--ink-45); }

/* ---------------------------------------------------------- docs entrance

   First visit of a session only. The header's own hairline draws itself
   left to right on the same take as the landing mark's outline (900ms at
   tempo 1), on the same soft ease the reveals use, starting at first paint,
   so the two entrances read as one gesture. The opening block arrives on
   the same 70ms stagger (times the tempo), so the entrance and the scroll
   reveals read as one behaviour.
   Later navigations inside the session get nothing but the progress line,
   which is a different element and a different colour. */
@keyframes rule-draw { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.enter-full .docs-header { border-bottom-color: transparent; }
.enter-full .docs-header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: var(--rule);
  transform-origin: left center;
  animation: rule-draw calc(900ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) both;
  transition: background-color 200ms ease;
}
.enter-full .docs-header.is-scrolled::after { background: var(--ink-45); }

.enter-full .docs-content > .eyebrow { animation: rise-in calc(520ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) calc(300ms * var(--tempo)) both; }
.enter-full .docs-content > .doc-h1  { animation: rise-in calc(520ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) calc(370ms * var(--tempo)) both; }
.enter-full .docs-content > .doc-intro,
.enter-full .docs-content > .prose   { animation: rise-in calc(520ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) calc(440ms * var(--tempo)) both; }
.enter-full .docs-content > .section-head,
.enter-full .docs-content > .spec-table { animation: rise-in calc(520ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) calc(510ms * var(--tempo)) both; }
/* Opacity only, never transform. .code-panel is now the sticky box itself,
   and a transform on a sticky element takes it out of sticky positioning
   entirely: the panel would scroll away with the column instead of pinning,
   then snap back the moment the entrance class came off. That snap is the
   flashing. Opacity is safe — it makes a stacking context, not a containing
   block — but nothing on this element may carry a transform, a filter, or
   will-change: transform. */
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
.enter-full .code-panel { animation: fade-in calc(520ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) calc(580ms * var(--tempo)) both; }

/* ------------------------------------------------------ loading indicator */

/* The mark's ring on its own, pulsing green. Shown only when something is
   genuinely slow; see the `loading` macro in _mark.html. */
.iv-loading { flex: none; line-height: 0; }
.iv-loading:not([hidden]) { display: inline-flex; }
.iv-loading-ring { transform-origin: 50% 50%; overflow: visible; }
.iv-loading-ring circle {
  stroke: var(--accent);
  stroke-width: 1.2px;
  vector-effect: non-scaling-stroke;
}
.iv-loading:not([hidden]) .iv-loading-ring {
  animation: iv-loading-pulse 1.2s ease-in-out infinite;
}
@keyframes iv-loading-pulse {
  0%, 100% { opacity: 0.35; transform: scale(0.86); }
  50%      { opacity: 1;    transform: scale(1); }
}

/* --------------------------------------------------------- docs reveal-in */

/* Sections arrive rather than appear: 16px over 520ms on a soft ease, 70ms
   apart within a batch, so a reader moving at normal speed sees each one
   land. Applied by site.js only to elements below the fold at load, so
   anything already on screen renders finished and never flashes.

   Opacity and transform only, and will-change is set when an element is
   observed and dropped the moment its animation ends, so nothing holds a
   compositor layer it is not using. */
@keyframes reveal-rise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}
.reveal { opacity: 0; transform: translateY(16px); }
.reveal.is-animating { will-change: opacity, transform; }
.reveal.reveal-in {
  animation: reveal-rise calc(520ms * var(--tempo)) cubic-bezier(0.22, 1, 0.36, 1) var(--reveal-delay, 0ms) both;
}

/* docs on narrow viewports */

/* Beside the reading column, the whole panel column pins under the header,
   so the sample for the step in view stays in view. At rest (scroll 0) it
   renders exactly where a static panel would.

   The sticky box is .code-panel itself, and it is the only element in this
   column that may scroll. Previously .panel-steps was sticky and capped
   *inside* a full-height .code-panel, which made a second scroll container
   nested in the page: a wheel with the pointer over the panel scrolled that
   box instead of the document, so the panel came to rest showing the
   WEBHOOK block at its top while the rest of the page had not moved. There
   is now one scroll container on the page, the document, plus this panel and
   the nav column for their own overflow only — and no `overscroll-behavior`
   on either, so once a column reaches its end the wheel chains back to the
   page instead of dead-ending.

   align-self: start is what lets it pin: a stretched grid item is as tall as
   the row and has nowhere to stick. The cap keeps a panel taller than the
   screen from riding the page up, and means a step change resizes nothing
   outside this box. */
@media (min-width: 1101px) {
  .docs-content { border-right: 1px solid var(--rule); }

  .code-panel {
    position: sticky;
    top: var(--header-h);
    align-self: start;
    max-height: calc(100dvh - var(--header-h));
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--rule) transparent;
  }
  .code-panel::-webkit-scrollbar { width: 6px; }
  .code-panel::-webkit-scrollbar-track { background: transparent; }
  .code-panel::-webkit-scrollbar-thumb {
    background: var(--rule);
    border-radius: 3px;
  }
  .code-panel::-webkit-scrollbar-thumb:hover { background: var(--ink-45); }
}

/* Under 1100 the code panel drops beneath the reading column; the nav keeps
   its own track and runs the full height of both. */
@media (max-width: 1100px) {
  .docs-body {
    grid-template-columns: clamp(13.75rem, 24%, 17.5rem) minmax(0, 1fr);
    grid-template-areas:
      "nav content"
      "nav panel";
  }
  .docs-content { max-width: none; }
  .code-panel { border-top: 1px solid var(--rule); }
}

/* Under 700 the nav becomes a top row of links. */
@media (max-width: 700px) {
  .docs-header { position: static; height: auto; }
  .docs-header-inner { flex-wrap: wrap; height: auto; padding: 0.75rem 1.25rem; gap: 10px 16px; }
  .docs-header-link, .docs-header-link.muted { margin-left: 0; }
  .docs-header-spacer { display: none; }
  .docs-search { width: 100%; }

  .docs-body {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "nav"
      "content"
      "panel";
  }
  .docs-nav { border-right: 0; border-bottom: 1px solid var(--rule); }
  .docs-nav-inner {
    position: static;
    max-height: none;
    overflow: visible;
    padding: 0.75rem 1.25rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0 18px;
  }
  .docs-nav-inner .nav-group-label,
  .docs-nav-inner .nav-group-label-second { margin: 0; }
  .docs-nav-inner .nav-section { display: contents; }
  .docs-nav-inner .nav-list { display: flex; flex-wrap: wrap; gap: 0 18px; margin: 0; }
  .docs-nav-inner .nav-list-ops { display: none; }
  .docs-nav-inner .nav-item { display: flex; }
  .docs-nav .nav-bar { display: none; }
  .nav-hover-rule { display: none; }

  .docs-content { padding: 1.75rem 1.25rem; }
  .code-panel { padding: 1.75rem 1.25rem; }
}

/* --------------------------------------------------------- reduced motion */

/* One block, and it is the whole story: every animation and transition on
   this site is switched off here, and each element is left in the state it
   would have finished in. Nothing is left mid-way and nothing is hidden.
   site.js checks the same query and never starts the breathe loop, the
   entrance, the reveals, or the progress line, so there is nothing running
   for this block to have to catch. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
  }

  /* A: the breathe, the beat, and the entrance all land finished. The mark
     is drawn, the ring is there, the halo sits at full strength, and every
     word is already in place. */
  .mark-rise,
  .mark-pulse,
  .mark-beat,
  .mark-core,
  .mark-148 .mark-pulse,
  .mark-96 .mark-pulse,
  .mark-148 .mark-core,
  .mark-96 .mark-core,
  .mark-148 .mark-rise,
  .mark-148 .mark-beat,
  .mark-148.is-drawing .mark-rise,
  .mark-148.is-drawing .mark-beat,
  .mark-148 .mark-beat.is-beating,
  .mark-96 .mark-beat.is-beating {
    animation: none !important;
    transform: none !important;
    opacity: 1 !important;
    will-change: auto !important;
  }
  .mark-line path,
  .mark-148 .mark-line path,
  .mark-148.is-drawing .mark-outline,
  .mark-148.is-drawing .mark-axis {
    stroke-dasharray: none !important;
    stroke-dashoffset: 0 !important;
    animation: none !important;
  }
  .mark-148 .mark-ring,
  .mark-148.is-drawing .mark-ring { animation: none !important; opacity: 1 !important; }
  .landing-headline,
  .landing-sub,
  .landing-actions,
  .landing-footer,
  .docs-content > * { animation: none !important; opacity: 1; transform: none; }
  /* No transform here, ever: it would break the sticky panel inside. */
  .code-panel { animation: none !important; opacity: 1; }
  .docs-header { border-bottom-color: var(--rule); }
  .docs-header::after { display: none !important; }

  /* B: hover rules and the button press hold their resting state. */
  .landing-nav a::after,
  .btn-text::after,
  .docs-header-link::after,
  .footer-line a::after,
  .prose a::after,
  .doc-note a::after,
  .docs-nav .nav-item > a .nav-text::after { transition: none !important; }
  .btn-primary:active { transform: none; }
  .nav-hover-rule { transition: none !important; }

  /* C and F1: panes and step panels swap outright. */
  .lang-pane.is-entering { animation: none !important; }
  .panel-step { transition: none !important; }

  /* D: no travelling line. It never shows at all. */
  .page-line { display: none !important; }

  /* E: the ring is still a ring, just a still one. */
  .iv-loading:not([hidden]) .iv-loading-ring {
    animation: none !important;
    opacity: 1;
    transform: none;
  }

  /* F1: the step rule is simply there. */
  .prose ol > li::after { transition: none !important; }
  .prose ol > li.is-current-step::after { opacity: 1; transform: scaleY(1); }

  /* F2 and F3: content is present on arrival, the hairline does not travel. */
  .reveal, .reveal.reveal-in {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
    will-change: auto !important;
  }
  .docs-header { transition: none !important; }
}


/* ------------------------------------------------------------ account pages

   Sign in, request access, and their result states share the landing's
   centred composition: the 96px mark, a mono eyebrow, a heading, then one
   360px column. Fields are hairline boxes; the only fill is the primary
   button. */
.page-auth .landing-centre { gap: 0; }
.auth-mark { line-height: 0; margin-bottom: 2.25rem; }
.auth-eyebrow { margin: 0 0 0.625rem; text-align: center; }
.auth-heading {
  margin: 0 0 2rem;
  font-size: 1.875rem;
  font-weight: 600;
  letter-spacing: -0.0625rem;
  line-height: 1.1;
  text-align: center;
  color: var(--ink);
}
.auth-form { width: 22.5rem; max-width: calc(100vw - 3rem); }
.auth-fields { display: flex; flex-direction: column; gap: 1rem; }
.field { display: flex; flex-direction: column; gap: 0.4375rem; }
.field-label {
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  line-height: 0.8125rem;
  letter-spacing: 0.08125rem;
  color: var(--ink-45);
}
.field input {
  appearance: none;
  width: 100%;
  height: 2.5rem;
  padding: 0 0.75rem;
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: var(--paper-pure);
  font: inherit;
  font-size: 0.875rem;
  color: var(--ink);
  transition: border-color 120ms ease;
}
.field input::placeholder { color: var(--ink-45); font-family: var(--font-mono); font-size: 0.75rem; }
.field input:focus { outline: none; border-color: var(--ink); }
.btn-block { display: flex; width: 100%; justify-content: center; margin-top: 0.25rem; cursor: pointer; font: inherit; border: 0; }
.auth-caption {
  margin: 0.25rem 0 0;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  line-height: 1.5;
  letter-spacing: 0.08125rem;
  color: var(--ink-45);
}
.auth-error {
  margin: 0;
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--ink);
  border-radius: 3px;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--ink);
}
.auth-hairline { margin: 1.75rem 0 1.25rem; border: 0; border-top: 1px solid var(--rule); }
.auth-alt { margin: 0; text-align: center; font-size: 0.875rem; color: var(--ink-70); }
.auth-alt a { color: var(--ink); font-weight: 600; }
.auth-lead { margin: 0 0 1.5rem; font-size: 0.9375rem; line-height: 1.6; color: var(--ink-70); text-align: center; }
.auth-mono { font-family: var(--font-mono); font-size: 0.8125rem; color: var(--ink); }
.auth-back { display: inline-block; margin: 0 auto; }
.page-auth .auth-form .btn-text { display: block; text-align: center; }


/* ------------------------------------------------------- signed-in header

   Mode chip, account name, and an initials avatar as one summary; the menu
   is a <details> panel so it works without script. */
.account-menu { position: relative; margin-left: 12px; }
.account-summary {
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  color: var(--ink);
}
.account-summary::-webkit-details-marker { display: none; }
.account-summary:focus-visible { outline: 1px solid var(--ink); outline-offset: 4px; border-radius: 3px; }
.mode-form { margin: 0 0 0 24px; }
.mode-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: none;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  line-height: 0.8125rem;
  letter-spacing: 0.08125rem;
  color: var(--ink-70);
  transition: border-color 120ms ease, color 120ms ease;
}
.mode-chip:hover, .mode-chip:focus-visible { border-color: var(--ink-45); color: var(--ink); outline: none; }
.mode-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ink-45); }
.mode-chip.mode-live .mode-dot { background: var(--accent); }
.account-name { font-size: 0.84375rem; line-height: 0.9375rem; color: var(--ink); }
.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--rule);
  border-radius: 50%;
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  letter-spacing: 0.05rem;
  color: var(--ink);
  background: var(--paper);
}
.account-panel {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  width: 240px;
  padding: 8px 0;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--paper-pure);
  z-index: 20;
}
.account-panel-eyebrow {
  margin: 4px 16px 6px;
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  letter-spacing: 0.08125rem;
  color: var(--ink-45);
}
.account-panel form { margin: 0; }
.account-panel-item {
  display: block;
  width: 100%;
  padding: 8px 16px;
  border: 0;
  background: none;
  text-align: left;
  font: inherit;
  font-size: 0.84375rem;
  line-height: 1.2;
  color: var(--ink);
  cursor: pointer;
  text-decoration: none;
}
.account-panel-item:hover { background: var(--paper); text-decoration: none; }
.account-panel-rule { margin: 6px 0; border: 0; border-top: 1px solid var(--rule); }

/* ---- account pages: keys and team ---- */

/* Secondary button: same metrics as .btn-primary, hairline instead of fill. */
.btn-secondary {
  display: inline-flex;
  align-items: center;
  padding: 0.8125rem 1.25rem;
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: none;
  color: var(--ink);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 0.9375rem;
  transition: border-color 120ms ease, background-color 120ms ease;
}
.btn-secondary:hover { text-decoration: none; border-color: var(--ink-45); background: var(--paper); }
.btn-secondary:active { transform: scale(0.98); }

/* Row actions (Rotate, Revoke, Remove): bold ink text, not the muted
   .btn-text used for auth-form Cancel links. */
.table-action {
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  font-size: 0.84375rem;
  font-weight: 600;
  line-height: 0.9375rem;
  color: var(--ink);
  cursor: pointer;
  text-decoration: none;
}
.table-action { display: inline; line-height: 1.45; vertical-align: baseline; margin: 0; appearance: none; }
.table-action:hover { text-decoration: underline; }
.cell-actions { display: flex; align-items: baseline; gap: 14px; line-height: 1.45; }
.inline-form { margin: 0; display: inline; line-height: inherit; }
.spec-table td { vertical-align: top; }
.spec-table .cell-body, .spec-table .cell-desc, .spec-table .cell-name { line-height: 1.45; }

/* NAME column of the keys/team tables holds plain body text, unlike
   .cell-name (mono) used for reference-table parameter names. */
.cell-body { font-size: 0.84375rem; line-height: 1.45; color: var(--ink); }
.cell-empty { color: var(--ink-45); font-size: 0.78125rem; }

/* Column widths beyond the generic .col-name/.col-type/.col-req already
   defined for reference tables. In the keys table the KEY column is fixed
   so the nowrap prefix never runs into CREATED; NAME is the column that
   flexes and wraps. */
.col-key { width: 128px; }
.col-created { width: 110px; }
.col-lastused { width: 110px; }
.col-actions { width: 120px; }
.col-role { width: 100px; }
.col-added { width: 110px; }
.col-status { width: 180px; }
.cell-muted { color: var(--ink-45); }

/* Team table (2026-09-15): a long address in the EMAIL column ran into
   ROLE. The address is one unbreakable token, so let it break anywhere
   and keep the column from collapsing under the fixed layout. */
.col-email { width: 190px; } /* fixed layout: explicit widths, they must fit the column */
.spec-table td code.cell-name { display: inline-block; max-width: 100%; white-space: normal; overflow-wrap: anywhere; word-break: break-all; }

/* Left-aligned mono caption, used under a field, a key, or a table/button
   block. The tight variant sits directly under the element it annotates. */
.account-caption {
  margin: 14px 0 0;
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  line-height: 1.5;
  letter-spacing: 0.08125rem;
  color: var(--ink-45);
}
.account-caption-tight { margin: 4px 0 0; }

.account-actions { margin-top: 24px; }

/* Plain body paragraph outside .prose, sized like .doc-intro but without
   its large bottom margin (used for the Notices copy). */
.section-text { margin: 0; font-size: 0.875rem; line-height: 1.6; color: var(--ink-70); }

/* The create/rotate/created sheets: a centered card over a dimmed scrim of
   the docs content. Clicking outside is not wired up. */
.account-scrim {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(246, 245, 241, 0.6);
}
.account-sheet {
  width: 480px;
  max-width: 100%;
  padding: 28px;
  background: var(--paper-pure);
  border: 1px solid var(--rule);
  border-radius: 4px;
}
.sheet-heading {
  margin: 14px 0 10px;
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.02rem;
  line-height: 1.25;
  color: var(--ink);
}
.sheet-text { margin: 0 0 20px; font-size: 0.875rem; line-height: 1.6; color: var(--ink-70); }
.sheet-actions { display: flex; align-items: center; gap: 20px; margin-top: 4px; }
.sheet-copy { margin: 12px 0 20px; }

/* The new-key block wraps instead of scrolling, unlike the request/response
   .code-block panes, which stay single-line with horizontal overflow. */
.code-block-wrap { padding: 0.875rem; }
.code-block-wrap code { white-space: pre-wrap; overflow-wrap: anywhere; }

/* Segmented mono radio choice (MODE, OVERLAP, ROLE): visually identical to
   the .lang sample-language tabs, but backed by a real radio input instead
   of JS-toggled state, so a submit works with no script at all. */
.lang-radio { position: relative; cursor: pointer; }
.lang-radio input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
}
.lang-radio input:checked + .lang { color: var(--ink); }
.lang-radio input:checked + .lang .lang-underline { background: var(--ink); }
.lang-radio input:focus-visible + .lang { outline: 1px solid var(--ink); outline-offset: 2px; }

/* Identifiers in account tables stay on one line; the description column
   takes the squeeze. */
.spec-table td code, .spec-table .cell-name { white-space: nowrap; }

/* Team table: six columns in a ~580px content column. Automatic layout
   sizes to content; the email breaks anywhere; dates never wrap. */
.team-table { table-layout: auto; }
.team-table .col-name, .team-table .col-email, .team-table .col-role,
.team-table .col-status, .team-table .col-added, .team-table .col-actions { width: auto; min-width: 0; }
.team-table th { white-space: nowrap; }
.team-table td { vertical-align: top; }
.team-table .cell-nowrap { white-space: nowrap; }
.team-table td code.cell-name { font-size: 0.78rem; }

/* Account pages: no request/response panel, so the content takes that room. */
.docs-body.is-wide {
  grid-template-columns: clamp(15rem, 17.2%, 17.5rem) minmax(0, 1fr);
  grid-template-areas: "nav content";
}
.docs-body.is-wide .docs-content { max-width: 1120px; }

/* ---------------------------------------------------------- verifications
   /account/verifications (G45): a toolbar (two filter pills + search), a
   status-tab row with mono counts, a wide results table, and a footer
   pager. No existing table/tab/chip classes fit a status list, so this is
   a parallel set (.verif-*) rather than a reuse of .spec-table/.status-pill. */

.verif-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}
.verif-head .doc-h1 { margin-bottom: 0; }
.verif-updated {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  letter-spacing: 0.08125rem;
  color: var(--ink-45);
  white-space: nowrap;
}

.verif-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin: 26px 0 20px;
}
.verif-toolbar-filters { display: flex; gap: 10px; flex-wrap: wrap; }

.verif-filter {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 2.25rem;
  padding: 0 1.75rem 0 0.75rem;
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: var(--paper-pure);
  cursor: pointer;
}
.verif-filter-label {
  font-family: var(--font-mono);
  font-size: 0.59375rem;
  letter-spacing: 0.08125rem;
  color: var(--ink-45);
  white-space: nowrap;
}
.verif-filter select {
  appearance: none;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.8125rem;
  color: var(--ink);
  cursor: pointer;
  padding: 0;
  max-width: 11rem;
  text-overflow: ellipsis;
}
.verif-filter select:focus { outline: none; }
.verif-filter-chevron {
  position: absolute;
  right: 0.75rem;
  top: 50%;
  transform: translateY(-52%);
  font-size: 0.75rem;
  color: var(--ink-45);
  pointer-events: none;
}

.verif-search {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: 280px;
  height: 2.25rem;
  padding: 0 0.75rem;
  border: 1px solid var(--rule);
  border-radius: 3px;
  color: var(--ink-45);
  background: var(--paper-pure);
}
.verif-search input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline: 0;
  background: none;
  font: inherit;
  font-size: 0.8125rem;
  color: var(--ink);
}
.verif-search input::placeholder { color: var(--ink-45); }

/* Visually hidden but reachable — the toolbar's selects auto-submit on
   change (script in the template); this is the no-JS fallback. */
.verif-apply {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.verif-tabs {
  display: flex;
  align-items: baseline;
  gap: 26px;
  margin: 0 0 18px;
  border-bottom: 1px solid var(--rule);
}
.verif-tab {
  position: relative;
  padding: 0 0 12px;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--ink-45);
}
.verif-tab.is-active {
  color: var(--ink);
  font-weight: 600;
}
.verif-tab.is-active::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: var(--ink);
}
.verif-tab-count {
  margin-left: 4px;
  font-family: var(--font-mono);
  font-size: 0.71875rem;
  color: var(--ink-45);
}

.verif-table-wrap { overflow-x: auto; }
.verif-table {
  width: 100%;
  min-width: 860px;
  border-collapse: collapse;
  table-layout: auto;
}
.verif-table th {
  padding: 0 0.75rem 0.625rem 0;
  text-align: left;
  font-family: var(--font-mono);
  font-size: 0.5625rem;
  font-weight: 400;
  letter-spacing: 0.075rem;
  color: var(--ink-45);
  border-bottom: 1px solid var(--ink);
  white-space: nowrap;
}
.verif-table td {
  padding: 1.125rem 0.75rem 1.125rem 0;
  vertical-align: top;
  border-bottom: 1px solid var(--rule);
}
.verif-table tbody tr:last-child td { border-bottom: 0; }
.verif-row { transition: background-color 120ms ease; }
.verif-row:hover { background: var(--paper); }
.verif-table th.col-insured, .verif-table td.col-insured { padding-left: 12px; }
.verif-table td.col-insured { position: relative; min-width: 190px; }
.verif-row-bar {
  position: absolute;
  left: 0;
  top: 0; bottom: 0;
  width: 3px;
  background: transparent;
}
.verif-row:hover .verif-row-bar { background: var(--ink); }
.verif-table .col-updated { text-align: right; white-space: nowrap; }
.verif-table td.col-updated { text-align: right; }
.verif-detail {
  margin: 4px 0 0;
  font-size: 0.75rem;
  line-height: 1.4;
  color: var(--ink-45);
}
.verif-empty-row td { text-align: center; padding: 2.5rem 0; }

/* Status chips: small mono uppercase pills, one look per verdict/surface
   status, reused for both the SURFACE CHECK and VERDICT columns. */
.chip {
  display: inline-block;
  padding: 3px 8px;
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.05rem;
  line-height: 1.1;
  white-space: nowrap;
}
.chip-compliant { border: 1px solid var(--accent); color: var(--accent); background: none; }
.chip-non-compliant { border: 1px solid var(--ink); color: var(--paper-pure); background: var(--ink); }
.chip-pending, .chip-grace { border: 1px solid var(--rule); color: var(--ink-45); background: none; }
.chip-insufficient { border: 1px solid var(--ink); color: var(--ink); background: var(--paper); }

/* Partners (2026-09-24): the KIND chip on a requirement-set rule row —
   outlined green for a plain required rule, outlined grey for one that
   only applies conditionally (an any_of alternative or a `where`
   condition), same outlined shape as .chip-compliant / .chip-pending. */
.chip-required { border: 1px solid var(--accent); color: var(--accent); background: none; }
.chip-conditional { border: 1px solid var(--rule); color: var(--ink-45); background: none; }

.verif-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 20px;
}
.verif-footer-count {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.05rem;
  color: var(--ink-45);
}
.verif-pager { display: flex; gap: 8px; }
.verif-pager-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  border: 1px solid var(--rule);
  border-radius: 3px;
  color: var(--ink);
  font-size: 0.875rem;
}
.verif-pager-btn:hover { border-color: var(--ink-45); background: var(--paper); }
.verif-pager-btn.is-disabled { color: var(--ink-45); opacity: 0.5; pointer-events: none; }

@media (max-width: 1024px) {
  .verif-toolbar { align-items: stretch; }
  .verif-search { width: 100%; }
}

.verif-row-link { color: var(--ink); text-decoration: none; }
.verif-row-link:hover { text-decoration: underline; }
.verif-head-right { display: flex; align-items: center; gap: 20px; }
.verif-upload { padding: 10px 18px; font-size: 0.9375rem; }

/* list UPDATED column: mono, like the frame */
.verif-table td.col-updated { font-family: "JetBrains Mono", monospace; font-size: 0.6875rem; letter-spacing: 0.1em; color: var(--ink-45); text-align: right; }

/* verifications list rhythm */
.page-portal .verif-head { margin-bottom: 16px; align-items: center; }
.page-portal .verif-toolbar { margin-bottom: 14px; }
.page-portal .verif-tabs { margin-bottom: 14px; }
.page-portal .verif-table td { padding-top: 14px; padding-bottom: 14px; }
.page-portal .verif-table th { padding-top: 16px; padding-bottom: 14px; }
.page-portal .verif-table td { padding-top: 18px; padding-bottom: 18px; }
.page-portal .verif-tabs { margin-bottom: 8px; }

/* list v2 (frame dl7UE): tokens per line, status dot, clock */
.verif-cell-line { display: flex; align-items: center; gap: 5px; margin-bottom: 6px; }
.verif-cell-text { display: block; padding-left: 17px; font-size: 0.75rem; color: var(--ink-70); }
.verif-word { font-weight: 500; color: var(--ink); }
.verif-sep { margin: 0 5px; color: var(--ink-45); }
.sdot { width: 12px; display: inline-flex; justify-content: flex-start; }
.sdot::before { content: ""; width: 7px; height: 7px; border-radius: 50%; box-sizing: border-box; }
.sdot-compliant::before { background: var(--accent); }
.sdot-non_compliant::before { background: var(--ink); }
.sdot-pending::before { background: var(--ink-45); }
.sdot-insufficient_evidence::before { border: 1.5px solid var(--ink); }
.sdot-grace::before { border: 1.5px solid var(--accent); }
.verif-table th.col-clock, .verif-table td.col-clock { padding-left: 12px; white-space: nowrap; }
.verif-clock { font-family: var(--font-mono); font-size: 0.625rem; letter-spacing: 0.05em; color: var(--ink-70); }
.verif-clock.is-out { color: var(--ink); }
.verif-clock.is-none { color: var(--ink-45); }
.tok { display: inline-flex; align-items: center; justify-content: center; min-width: 22px; padding: 3px 5px; border-radius: 2px; position: relative;
  font-family: var(--font-mono); font-size: 0.59375rem; letter-spacing: 0.7px; line-height: 1; border: 1px solid var(--rule); color: var(--ink-45); box-sizing: border-box; }
.tok-pass { border-color: var(--accent); background: var(--accent); color: #fff; }          /* verified: filled, like fails */
.tok-open { border-color: var(--ink-45); color: var(--ink-70); }                           /* on file, not confirmed */
.tok-missing { border-style: dashed; border-color: var(--ink-45); color: var(--ink-45); }  /* nothing on file */
.tok-attention { border-color: var(--ink); color: var(--ink); }                           /* needs attention: dark border, no fill */
.tok-fail, .tok-contradicted { border-color: var(--fail, #9E2F27); background: var(--fail, #9E2F27); color: #fff; } /* fails the rule */
.tok-expired { border-color: var(--ink-45); color: var(--ink-45); text-decoration: line-through; }

/* token key: collapsed by default */
.tok-legend { margin: 10px 0 4px; font-size: 0.75rem; color: var(--ink-70); }
.tok-legend summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: 0.625rem; letter-spacing: 0.12em; color: var(--ink-45); }
.tok-legend summary::-webkit-details-marker { display: none; }
.tok-legend summary::after { content: ""; width: 7px; height: 7px; margin-left: 2px; border-right: 1px solid currentColor; border-bottom: 1px solid currentColor;
  transform: translateY(-2px) rotate(45deg); transition: transform 150ms ease; }
.tok-legend[open] summary::after { transform: translateY(2px) rotate(225deg); }
.tok-legend-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 18px; margin-top: 10px; }
.tok-legend-item { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.tok-legend-gap { width: 8px; }
.tok-legend .sdot { width: auto; }
/* breathing room: toolbar → tabs → table */
.page-portal .verif-toolbar { margin-bottom: 22px; }
.page-portal .verif-tabs { margin-bottom: 12px; }
.page-portal .verif-table th { padding-top: 18px; padding-bottom: 14px; }

.verif-cell-single { margin-bottom: 0; font-size: 0.75rem; color: var(--ink-70); }
.verif-cell-single .sdot { margin-right: 0; }
.verif-cell-detail { color: var(--ink-70); }

/* alignment: cells top-aligned so dots and tokens share one baseline; key sits with the count */
.page-portal .verif-table td { vertical-align: middle; }
.verif-cell-line, .verif-cell-single { min-height: 18px; align-items: center; }
.verif-cell-single { line-height: 18px; }
.verif-footer { align-items: flex-start; }
.verif-footer-left { display: flex; align-items: baseline; gap: 22px; }
.verif-footer-left .tok-legend { margin: 0; }
.tok-legend summary { line-height: 1; }
.tok-legend-row { padding-left: 0; }
/* every cell centres on the row; token cells centre as a two-line block */
.verif-cell-single { margin-top: 0; }

/* A page written for one account has no code panel; keep a guide's measure. */
.partner-doc { max-width: 860px; }
.partner-doc pre { overflow-x: auto; }

/* Every clickable control shows a hand (Daniel 2026-09-29). */
button, [role="button"], summary, input[type="submit"], input[type="file"], label[for],
.btn-primary, .btn-secondary, .btn-text, .copy-btn, .mode-chip, .portal-account, .account-panel-item,
.ops-log-btn, .ops-btn-primary, .ops-call, .ops-pick-btn, .ops-upload-btn, .ops-text-btn, .ops-step,
.ops-row-link, .ops-token, .ops-tab, .ops-coverage-row, .ops-close, .staff-banner-btn, .settings-tab { cursor: pointer; }
button:disabled, .ops-log-btn:disabled, .ops-call.is-disabled { cursor: not-allowed; }
