
@font-face {
  font-family: "Instrument Sans";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("/app/assets/fonts/instrument-sans-upright-b4cf60bf4e3b.woff2") format("woff2");
}

@font-face {
  font-family: "Instrument Sans";
  font-style: italic;
  font-weight: 400 600;
  font-display: swap;
  src: url("/app/assets/fonts/instrument-sans-italic-acabf784a5e7.woff2") format("woff2");
}

:root {
  /* Redesign foundation (#2953, #2955). Public documents and signed-in
     routes share one dark slate frame. Semantic aliases stay separate even
     when the approved palette gives them the same value: interaction,
     success, P&L, and navigation must not silently become one meaning. */
  --bg: #0e161b;
  --surface: #172229;
  --surface-2: #24343d;
  --border: #344750;
  --border-strong: #78909b;
  --text: #edf3f1;
  --text-dim: #a5b7bb;
  --accent: #93d8c4;
  --on-accent: #0e161b;
  --nav-active: #edf3f1;
  --data-neutral: #91a8ba;
  --success: #b5cf9a;
  --warn: #e6c27a;
  --danger: #f1a4a8;
  --info: #9cc9e0;
  --pnl-up: #b5cf9a;
  --pnl-down: #e8a3ab;
  /* Legal print-only paper adaptation; never a browser theme. */
  --print-paper: #ffffff;
  --print-ink: #000000;

  /* Accent washes are reserved for interactive emphasis on the canvas or
     working surface. Semantic fills use the same reviewed 12% recipe but
     retain their own hue and meaning. */
  --accent-wash: rgba(147, 216, 196, 0.10);
  --accent-wash-strong: rgba(147, 216, 196, 0.16);
  --accent-bg: var(--accent-wash-strong);
  --success-bg: rgba(181, 207, 154, 0.12);
  --warn-bg: rgba(230, 194, 122, 0.12);
  --danger-border: var(--danger);
  --danger-bg: rgba(241, 164, 168, 0.12);
  --info-bg: rgba(156, 201, 224, 0.12);

  /* Geometry has three jobs: chips, controls, and bounded task surfaces.
     Ordinary rows and sections remain flat; elevation tokens below are only
     for overlays, menus, dialogs, tooltips, and the mobile drawer. */
  --radius-sm: 4px;
  --radius: 8px;
  --radius-lg: 12px;
  --font-sans: "Instrument Sans", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
               Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas,
               "Liberation Mono", monospace;
  --fs-micro: 0.75rem;
  /* #986 removed the 0.8125rem (13px) --fs-sm step: it packed a third
     size into the 12-14px band and was used interchangeably with its
     neighbors, earning no distinct role. Every consumer was repointed
     up to --fs-base-sm (14px), a uniform +1px move that shrinks
     nothing. */
  --fs-base-sm: 0.875rem;
  --fs-base: 1rem;
  --fs-md: 1.125rem;
  --fs-lg: 1.25rem;
  --fs-xl: 1.5rem;
  --fs-2xl: 2rem;
  /* Mobile rescales for the page/ticker display size. Kept as
     explicit tokens (rather than rolling clamp() into --fs-xl /
     --fs-2xl) because the codebase isn't using clamp() anywhere
     else yet; the token surface stays consistent across breakpoints. */
  --fs-h1-mobile: 1.625rem;
  --fs-hero-mobile: 1.625rem;
  /* Marketing display step. The public marketing pages set
     ``body.layout-marketing`` and consume the approved 56/36px pair. */
  --fs-3xl: 3.5rem;
  --fs-3xl-mobile: 2.25rem;
  /* Spacing scale — 4px-based, used by every gap/margin/padding
     declaration in the branded web surface. Twenty-six off-scale
     rem values had been intuited per-component before issue #523;
     this token series snaps them to a single rhythm so cards,
     rows, and tiles share consistent breathing room. Steps follow
     a 4px progression (--space-1 = 4px, --space-2 = 8px, …), with
     gaps in the numbering (skipping 7, 9-11) reserved for future
     additions. */
  --space-1: 0.25rem;  /*  4px */
  --space-2: 0.5rem;   /*  8px */
  --space-3: 0.75rem;  /* 12px */
  --space-4: 1rem;     /* 16px */
  --space-5: 1.25rem;  /* 20px */
  --space-6: 1.5rem;   /* 24px */
  --space-8: 2rem;     /* 32px */
  --space-12: 3rem;    /* 48px */
  /* Font weights — three steps cover the surface. Five distinct
     weights had been used inconsistently before issue #527 (400 /
     500 / 600 / 700 / inherited). Headings sit at --fw-bold so the
     UA default 700 doesn't slam light-on-dark display type; --fw-
     medium picks out labels and tile values that want a small step
     up from body without going semi-bold. The bare literal ``700``
     survives only on the tier-features ✓ icon, a deliberate
     typographic exception documented at that site rather than a fourth
     token. */
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-bold: 600;
  /* Elevation is reserved for true overlays: the tooltip and mobile drawer.
     Ordinary cards and highlighted rows remain flat. */
  --shadow-md: 0 6px 18px rgba(0, 0, 0, 0.45);
  --shadow-lg: 2px 0 16px rgba(0, 0, 0, 0.4);
  /* Layout measures (#2573 D02, the design system's foundation slice).
     The --space-* scale above covers every gap/margin/padding
     relationship, and Stylelint enforces it. It does not cover
     ``width``, ``max-width``, ``min-height`` or ``line-height``, which
     sit outside the literal ban in both frontend/stylelint.config.mjs
     and scripts/check_spacing_tokens.py. Those four properties had
     therefore drifted uncaught: 65ch appeared 8 times, 2.75rem 10
     times, and 40rem twice, with no declared authority anywhere.
     docs/frontend-design-system.md is the design decision; these
     tokens make it executable. SPA stylesheets cannot declare a custom
     property at all, so a shared token is the only available home. */

  /* Comfortable reading measure for prose, ledes, help and supporting
     notes. A genuinely tabular comparison is not prose and is not
     capped here. */
  --measure-prose: 65ch;
  --measure-support: 72ch;

  /* Slatemark's minimum interaction target for single-line controls,
     buttons and inline actions. This is a product choice, not an
     accessibility floor: WCAG 2.2 AA's target-size minimum is 24 CSS
     px with specified exceptions. Do not describe this token as the
     AA minimum. */
  --control-target: 2.75rem;

  /* Purposeful control widths. Every one is a maximum applied as
     min(100%, maximum), so a control still fits a narrow column; none
     of them is a value constraint. A 10rem quantity field does not
     imply a numeric limit. --control-long doubles as the fallback cap
     for a control that has not been classified yet. */
  --control-numeric: 10rem;
  --control-symbol: 12rem;
  --control-compact: 20rem;
  --control-text: 32rem;
  --control-long: 40rem;

  /* Line heights. Body and controls read at --lh-body, long prose at
     --lh-prose, and headings at --lh-heading, which is the loose end
     of the 1.2 to 1.35 heading band. */
  --lh-body: 1.5;
  --lh-prose: 1.65;
  --lh-heading: 1.35;
}
* { box-sizing: border-box; }
/* Native choice controls share the interaction accent (#1562 D19).
   The browser keeps its platform-native shape and forced-colors behavior. */
input[type="checkbox"],
input[type="radio"] { accent-color: var(--accent); }
/* Themed scrollbars (design pass). The OS default scrollbar renders as
   a chunky light bar that clashes with the dark theme — most visible on
   the fixed sidebar's overflow-y track at viewport heights where the
   nav + footer exceed the fold (1080p and below), and on any long
   dashboard. Thin + dark across Firefox (scrollbar-*) and WebKit/Blink
   (::-webkit-scrollbar) so every scroll container (sidebar, main, code
   blocks, tooltips) recedes into the surface instead of punching a
   bright rectangle through the page. Track stays transparent; the thumb
   is the hairline --border at rest and lifts to --text-dim on hover so
   it reads as grabbable without ever shouting. */
html { scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 999px;
  /* Transparent border + padding-box clip insets the thumb so it reads
     as a slim pill with breathing room, not a full-width slab. */
  border: 2px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--text-dim); }
/* WCAG 2.1 SC 2.4.7 — keyboard focus indicator. Chrome's default
   focus ring dims to near-invisible against the dark theme, so we
   draw our own. Scoped to :focus-visible so a mouse click into an
   input or button doesn't paint a ring. Elements that need a
   different offset (overflow-clipped containers, dense nav rows)
   override per-class below. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius);
}
.btn:focus-visible { outline-offset: 3px; }
.nav-item:focus-visible { outline-offset: -2px; }
html {
  /* Lock the rem base to 16px regardless of UA quirks. Every rem
     value below is sized against this. */
  font-size: 16px;
  min-height: 100%;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: 1.5;
  /* Antialiasing for the unified dark public and signed-in surface, where
     subpixel rendering thickens light-on-dark text. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: "kern", "liga";
  /* Sticky footer. Body is a column flex container that fills the
     viewport, main grows to absorb any leftover space, footer stays
     non-shrinking at the bottom. Works for both the public topbar
     layout and the signed-in sidebar layout — the sidebar is
     position:fixed and the hidden nav-toggle checkbox is
     position:absolute, so neither participates in the flex flow. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  color-scheme: dark;
}
main { flex: 1 0 auto; }
.footer { flex-shrink: 0; }
/* Semantic emphasis follows the same three-step weight system as the
   headings and components instead of falling back to UA-specific boldness.
   Keep italic explicit too, so prose emphasis has one shared primitive even
   though the current platform stacks already provide a native italic face. */
strong, b { font-weight: var(--fw-bold); }
em, i { font-style: italic; }
/* Authored underlines use the same font-relative geometry as prose links.
   ``skip-ink`` keeps descenders legible instead of drawing through them. */
u, ins {
  text-decoration: underline;
  text-decoration-thickness: 0.08em;
  text-underline-offset: 0.16em;
  text-decoration-skip-ink: auto;
}
/* Inline links need a non-color resting affordance (#1570 / WCAG
   1.4.1). Accent green is intentionally close to the surrounding
   light body text, so color alone cannot identify a prose link.
   Navigation and whole-component links opt out at their component
   rules below; ordinary prose, help, and legal links stay underlined. */
a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 0.08em;
  text-underline-offset: 0.16em;
  text-decoration-skip-ink: auto;
}
a:hover { text-decoration-thickness: 0.12em; }
/* Long support addresses must reflow without changing their destination. */
a[href^="mailto:"] { overflow-wrap: anywhere; }
/* Honor the ``hidden`` attribute even on elements whose own rule
   sets a ``display`` (e.g. ``.tile`` is flex, ``.hero-card-link``
   is block) — the UA ``[hidden]`` rule loses to any author display.
   Used by the client-side tool filter (#766) to show/hide cards. */
[hidden] { display: none !important; }
/* Screen-reader-only label: removed from view but kept in the
   accessibility tree (e.g. the tool-search input's label, #766). */
.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;
}
code, .mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum", "zero";
}
/* Skip-to-content link (#1300 P2, WCAG 2.4.1). First focusable
   element in the public topbar shell; parked offscreen until a
   keyboard user tabs onto it, then pinned over the header so Tab ->
   Enter jumps past the nav to <main id="main">. */
.skip-link {
  position: absolute;
  left: -9999px;
  z-index: 100;
}
.skip-link:focus {
  left: var(--space-4);
  top: var(--space-4);
  background: var(--surface-2);
  color: var(--text);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  text-decoration: none;
}
.shell { max-width: 56rem; margin: 0 auto; padding: 0 var(--space-6); }

/* Sidebar layout — opt-in via <body class="layout-sidebar"> on the
   frontend-owned signed-in document shell. Public pages keep the topbar.

   Mobile drawer trick: a hidden checkbox sibling of the sidebar +
   scrim drives the slide-in via :checked, so the whole thing is
   CSS-only. Order matters: the checkbox must appear in the DOM
   before .sidebar and .scrim for the `~` sibling selectors below
   to fire. */
.nav-toggle { position: absolute; left: -9999px; }
.sidebar {
  container: navigation-rail / inline-size;
  position: fixed;
  left: 0;
  top: 0;
  bottom: 0;
  width: 13rem;
  background: var(--bg);
  border-right: 1px solid var(--border);
  /* env(safe-area-inset-*) keeps the brand off the iOS notch /
     status bar and the Sign out button clear of the home
     indicator. The viewport meta carries ``viewport-fit=cover``
     so the env values resolve to actual insets on iPhone; on
     Android / desktop they're 0 and the fallback padding wins. */
  padding:
    max(var(--space-4), calc(var(--space-3) + env(safe-area-inset-top)))
    var(--space-3)
    max(var(--space-4), calc(var(--space-2) + env(safe-area-inset-bottom)));
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  overflow-y: auto;
  z-index: 20;
}
.sidebar .brand {
  display: inline-flex;
  align-items: center;
  gap: 0;
  padding: var(--space-2);
  font-size: var(--fs-lg);
}
/* Keep the wordmark and its dot together. At large text the decorative
   mark yields first, so the native drawer keeps the same readable name
   as the text-only SPA rail. */
.sidebar .brand-mark { margin-inline-end: var(--space-2); }
@container navigation-rail (max-width: 12rem) {
  .sidebar .brand-mark { display: none; }
}
.brand-mark {
  display: block;
  width: var(--space-6);
  height: var(--space-6);
  flex: 0 0 auto;
}
.side-nav { display: flex; flex-direction: column; gap: var(--space-4); flex: 1; }
.nav-group { display: flex; flex-direction: column; gap: var(--space-1); }
.job-context {
  margin-bottom: var(--space-4);
}
.context-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  width: fit-content;
  max-width: 100%;
  min-height: 2.75rem;
  border-bottom: 1px solid var(--border);
}
.context-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding: var(--space-2) var(--space-3);
  border-bottom: 2px solid transparent;
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
  text-decoration: none;
}
.context-nav a:hover {
  background: var(--surface-2);
  color: var(--text);
  text-decoration: none;
}
.context-nav a[aria-current] { color: var(--text); }
/* Exact pages carry the stronger fill plus underline treatment; a containing
   location keeps only its underline. Weight and shape preserve page versus
   section without depending on color alone (#1659). */
.context-nav a[aria-current="page"] {
  border-bottom-color: var(--nav-active);
  background: var(--surface-2);
  font-weight: var(--fw-medium);
}
.context-nav a[aria-current="location"] {
  border-bottom-color: var(--border-strong);
}
.nav-item {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: var(--space-2);
  /* 44px min touch target (issue #626 a11y) — the rows were
     tightly stacked at space-2 padding. min-height + centered
     flex keeps the visual rhythm while meeting the target. */
  min-height: 2.75rem;
  padding: var(--space-2);
  border-radius: var(--radius);
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
  border-left: 2px solid transparent;
  text-decoration: none;
  line-height: 1.3;
}
.nav-icon {
  display: block;
  width: 1.125rem;
  height: 1.125rem;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.nav-label { flex: 1 1 auto; }
.nav-item:hover {
  background: var(--surface-2);
  color: var(--text);
  text-decoration: none;
}
.nav-item.active {
  background: var(--surface-2);
  color: var(--text);
  border-left-color: var(--nav-active);
  font-weight: var(--fw-medium);
}
.sidebar-foot {
  border-top: 1px solid var(--border);
  padding-top: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.account-disclosure > summary {
  min-height: 2.75rem;
  padding: var(--space-2);
  border-radius: var(--radius);
  color: var(--text-dim);
  cursor: pointer;
}
.account-disclosure > summary:hover,
.account-disclosure[open] > summary {
  background: var(--surface-2);
  color: var(--text);
}
.account-disclosure > summary::marker { color: var(--accent); }
.sidebar-foot .who {
  display: inline-block;
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
  font-family: var(--font-mono);
  max-width: calc(100% - var(--space-4));
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: middle;
  white-space: nowrap;
}
.sidebar-foot form { padding: var(--space-2) var(--space-1) 0; }
.sidebar-foot .btn { width: 100%; text-align: center; padding: var(--space-2) var(--space-3); font-size: var(--fs-base-sm); }

/* Navigation experience (2026-09-26): the rail.

   The product owner asked for the navigation tabs to be a visually
   exciting experience. The exception and its guardrails are recorded under
   "Navigation experience" in docs/frontend-design-system.md. This block
   dresses the rail's five destinations, on the SPA chrome and on the
   signed-in browser documents' rail alike, so it stays in the shared
   stylesheet. The contextual row renders only in the SPA, so its half of
   the experience lives in src/spa.css.

   - A switchboard, not a status board. Each destination sits beside a
     recessed key; the current one is the key that is switched on, a face
     in the navigation marker's own role with a jade halo, and a filament
     in the same role burns along its leading edge. Nothing here reflects
     the reader's data or a live signal.
   - Decoration never hides text from the contrast check. The key is an
     in-flow flex item beside the label, never behind it, and the filament
     is a 2px line. The raised plate paints no tint of its own: its light is
     a thin inset rim and a halo outside its box. The key's halo and the
     filament's glow do reach the plate beside the label, the one place
     jade composites over the raised surface, and a browser case measures
     the label there.
   - Light moves, content does not. Under no-preference only, the
     destination that becomes current ignites once: its key flares and its
     filament draws itself in, animating only box-shadow on the key and
     opacity and transform on the filament, all finished within 900ms.
     Hover gains 160ms colour and opacity feedback.
   - Tokens only: existing roles and color-mix() of a role with another role
     or transparent. A browser without :has() draws no key and keeps each
     outline in its link's colour. Forced colours drop the keys, filaments
     and lit edge, and keep the words, borders and the current-destination
     outline. */
.sidebar {
  border-image: linear-gradient(to bottom, color-mix(in srgb, var(--accent) 53%, var(--border)), color-mix(in srgb, var(--accent) 18%, var(--border)) 30%, var(--border) 60%, color-mix(in srgb, var(--info) 25%, var(--border))) 1;
  box-shadow:
    inset 0 200px 150px -150px color-mix(in srgb, var(--accent) 8%, transparent),
    inset 0 -180px 150px -150px color-mix(in srgb, var(--info) 4%, transparent);
}
/* The leading padding sets each key 8px inside its plate, level with the
   wordmark above and the account summary below, and close to the 7px the
   44px row leaves above and below it. */
.nav-item {
  gap: var(--space-3);
  padding-inline-start: var(--space-3);
  position: relative;
  transition: background-color 160ms ease, color 160ms ease;
}
/* The key: a recessed well centred under the 18px outline. It is an in-flow
   flex item that starts 0.375rem before the icon and pulls the icon back
   over itself, and its block margins shrink its outer size to the icon's,
   so the row keeps its 44px height, the key never sits behind the label
   and the icon keeps its reviewed box. A destination without an icon draws
   no key. */
.nav-item:has(> .nav-icon)::before {
  background: linear-gradient(165deg, color-mix(in srgb, var(--surface-2) 78%, var(--text)), var(--surface) 55%, var(--bg));
  block-size: 1.875rem;
  border: 1px solid color-mix(in srgb, var(--border-strong) 45%, var(--border));
  border-radius: var(--radius);
  box-shadow:
    0 0 0 0 transparent,
    inset 0 1px 0 color-mix(in srgb, var(--text) 12%, transparent),
    inset 0 -4px 6px color-mix(in srgb, var(--bg) 30%, transparent);
  box-sizing: border-box;
  content: "";
  flex: none;
  inline-size: 1.875rem;
  margin-block: calc((1.125rem - 1.875rem) / 2);
  margin-inline: -0.375rem calc(0.375rem - 1.875rem - var(--space-3));
  transition: border-color 160ms ease;
}
/* The filament: every destination has one along its leading edge. It warms
   on hover and burns on the current destination, in the navigation
   marker's own role, where it replaces the flat marker. */
.nav-item::after {
  background: var(--nav-active);
  border-radius: var(--radius-sm);
  content: "";
  inline-size: 2px;
  inset-block: var(--space-3);
  inset-inline-start: -2px;
  opacity: 0;
  pointer-events: none;
  position: absolute;
  transition: opacity 160ms ease;
}
.nav-item:hover::before {
  border-color: color-mix(in srgb, var(--accent) 42%, var(--border));
}
.nav-item:hover::after { opacity: 0.45; }
.nav-item.active {
  border-left-color: transparent;
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 17%, transparent),
    inset 0 1px 0 color-mix(in srgb, var(--text) 10%, transparent),
    0 0 26px -8px color-mix(in srgb, var(--accent) 30%, transparent),
    0 16px 30px -20px color-mix(in srgb, var(--accent) 38%, transparent);
}
.nav-item.active::before {
  background: radial-gradient(circle at 50% 30%, var(--nav-active), color-mix(in srgb, var(--nav-active) 82%, var(--surface-2)) 75%);
  border-color: color-mix(in srgb, var(--nav-active) 70%, var(--border-strong));
  box-shadow:
    0 0 18px 2px color-mix(in srgb, var(--accent) 35%, transparent),
    inset 0 1px 0 var(--nav-active),
    inset 0 -4px 6px color-mix(in srgb, var(--bg) 20%, transparent);
}
/* The switched-on key is a pale face, so its outline takes the dark
   text-on-accent role and still draws in currentColor. The rule shares the
   key's :has() condition, so a browser that draws no key keeps the outline
   in its link's colour on the raised plate. */
.nav-item.active:has(> .nav-icon) > .nav-icon { color: var(--on-accent); }
.nav-item.active::after {
  box-shadow:
    0 0 6px 1px color-mix(in srgb, var(--accent) 45%, transparent),
    0 0 20px 2px color-mix(in srgb, var(--accent) 25%, transparent);
  inset-block: var(--space-2);
  opacity: 1;
}
@media (forced-colors: active) {
  .sidebar { border-image: none; }
  .nav-item::before,
  .nav-item::after { display: none; }
}
@media (prefers-reduced-motion: no-preference) {
  .nav-item.active::before { animation: nav-ignite 900ms ease-out 1 backwards; }
  .nav-item.active::after { animation: nav-filament 520ms cubic-bezier(0.2, 0.8, 0.2, 1) 1 backwards; }
}
/* The key flares as it switches on, then settles to its lit glow. */
@keyframes nav-ignite {
  from {
    box-shadow:
      0 0 0 0 transparent,
      inset 0 1px 0 transparent,
      inset 0 0 0 transparent;
  }
  40% {
    box-shadow:
      0 0 34px 8px color-mix(in srgb, var(--accent) 45%, transparent),
      inset 0 1px 0 var(--nav-active),
      inset 0 0 0 transparent;
  }
}
@keyframes nav-filament {
  from { opacity: 0; transform: scaleY(0.1); }
}

/* Mobile top strip on sidebar pages — slim bar with hamburger +
   brand. Hidden on desktop; the sidebar carries everything there. */
.topbar.mobile-only { display: none; }
/* The drawer toggle is a `span.hamburger` wrapped in a role-free
   `label[for="nav-toggle"]`: the label is the no-JavaScript activation
   path, the span is where `role="button"` is actually valid (#2604).
   `display: contents` drops the wrapper's box so the span stays the
   topbar flex item and every `.hamburger` rule below still applies. */
.hamburger-slot { display: contents; }
.hamburger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  color: var(--text);
  background: transparent;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  cursor: pointer;
  /* Reset font metrics so the SVG icon below isn't shifted by
     an inherited line-height (system fonts vary on Mac vs.
     iOS Safari and the old &#9776; glyph centered differently
     on each). */
  line-height: 1;
}
.hamburger:hover { background: var(--surface-2); }
.hamburger svg {
  width: 1.25rem;
  height: 1.25rem;
  display: block;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
}
.scrim { display: none; }

/* 13rem on the main + foot margin-left is the wide sidebar offset
   (matches the .sidebar width above) — a layout constraint, not a
   spacing-rhythm value, so it stays a literal rather than riding on
   the --space-* scale. */
body.layout-sidebar main { margin-left: 13rem; padding: var(--space-12) 0 4rem; /* 4rem bottom = generous page-bottom breathing; --space-12 (3rem) would crowd the foot on long dashboards */ }
body.layout-sidebar .shell { max-width: 78rem; margin: 0 auto; padding: 0 var(--space-8); }
body.layout-sidebar > .topbar:not(.mobile-only) { display: none; }
body.layout-sidebar .footer {
  margin-left: 13rem; /* sidebar offset, see above */
  background: var(--surface);
}

/* The immutable SPA document reaches first paint before the authenticated
   React chrome can exist. Keep its footer out of that pending frame so it
   cannot flash at the top of an otherwise empty workspace. Limit the rule to
   the empty mount and sole session-loading status so complete, error and
   reviewed synthetic shell content reveal the footer normally. */
body.layout-sidebar:has(#slatemark-spa-root:empty) > .footer,
body.layout-sidebar:has(#slatemark-spa-root > p[role="status"]:only-child) > .footer {
  visibility: hidden;
}
@media (scripting: none) {
  body.layout-sidebar:has(#slatemark-spa-root:empty) > .footer {
    visibility: visible;
  }
}

/* Intermediate desktop keeps the same jobs in a compact 184px rail with the
   contract's 24px task gutter. */
@media (min-width: 900px) and (max-width: 1199px) {
  body.layout-sidebar .sidebar { width: 11.5rem; }
  body.layout-sidebar main,
  body.layout-sidebar .footer { margin-left: 11.5rem; }
  body.layout-sidebar .shell { padding: 0 var(--space-6); }
}

/* Below 900px the task column takes the viewport and the existing rail becomes
   the accessible overlay drawer (#2741, #2956). */
@media (max-width: 899px) {
  body.layout-sidebar > .topbar.mobile-only,
  body.layout-sidebar > #slatemark-browser-document-root > .topbar.mobile-only {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: max(var(--space-3), calc(var(--space-1) + env(safe-area-inset-top))) var(--space-5) var(--space-3);
    flex-direction: row;
    flex-wrap: wrap;
    container: mobile-topbar / inline-size;
  }
  /* Large text on a narrow phone (#2744). The menu control, the mark and
     the wordmark need about 12.5rem in one row, and 200% text on a 320px
     phone leaves 8rem inside the topbar's padding. The control keeps its
     full target instead of shrinking, the row wraps so the wordmark takes
     a line of its own, and the decorative mark drops first, once that
     row is 13.5rem or narrower (the 12.5rem plus a rem of slack), so the
     wordmark stays whole. The query is in rem, which follows the text
     size. A break inside the wordmark is the last resort, for text larger
     still. The SPA shell and the signed-in browser documents both render
     this topbar. */
  .topbar.mobile-only .hamburger { flex: none; }
  .topbar.mobile-only .brand { min-width: 0; overflow-wrap: anywhere; }
  @container mobile-topbar (max-width: 13.5rem) {
    .topbar.mobile-only .brand-mark { display: none; }
  }
  body.layout-sidebar main { margin-left: 0; padding: var(--space-6) 0 var(--space-12); }
  body.layout-sidebar .shell { padding: 0 var(--space-5); }
  body.layout-sidebar .footer { margin-left: 0; }
  body.layout-sidebar .sidebar {
    transform: translateX(-100%);
    /* The closed drawer is removed from pointer AND keyboard/AT reach
       (WCAG 2.4.3 / #1395 WS7) — an off-screen transform alone leaves
       ~30 nav links in the tab order behind the page. The transform is
       intentionally instant; the redesign motion contract permits only
       brief colour or opacity feedback. */
    visibility: hidden;
    width: min(16rem, 100%);
    /* The drawer keeps the rail's inner light (the Navigation experience's
       two inset pools) beneath its overlay shadow. */
    box-shadow:
      inset 0 200px 150px -150px color-mix(in srgb, var(--accent) 13%, transparent),
      inset 0 -180px 150px -150px color-mix(in srgb, var(--info) 7%, transparent),
      var(--shadow-lg);
  }
  body.layout-sidebar .nav-toggle:checked ~ .sidebar {
    transform: translateX(0);
    visibility: visible;
  }
  body.layout-sidebar .scrim {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    z-index: 15;
    opacity: 0;
    pointer-events: none;
    transition: opacity 160ms ease;
  }
  body.layout-sidebar .nav-toggle:checked ~ .scrim {
    opacity: 1;
    pointer-events: auto;
  }
}

@media (max-width: 375px) {
  body.layout-sidebar > .topbar.mobile-only,
  body.layout-sidebar > #slatemark-browser-document-root > .topbar.mobile-only {
    padding-inline: var(--space-4);
  }
  body.layout-sidebar .shell { padding-inline: var(--space-4); }
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-6);
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.brand {
  font-family: var(--font-mono);
  font-weight: var(--fw-bold);
  font-size: var(--fs-md);
  letter-spacing: 0.02em;
  color: var(--text);
  text-decoration: none;
}
/* Keep the wordmark and its dot together, as the rail does: the decorative
   mark carries the space after it, not a flex gap (#2744). min-width and
   overflow-wrap let the wordmark wrap rather than overflow, as a last
   resort; each header drops its mark before that point at up to 200%
   text. */
.topbar .brand {
  display: inline-flex;
  align-items: center;
  gap: 0;
  min-width: 0;
  max-width: 100%;
  overflow-wrap: anywhere;
}
.topbar .brand-mark { margin-inline-end: var(--space-2); }
.brand .dot { color: var(--accent); }
.topbar-right { display: flex; align-items: center; gap: var(--space-4); }
.topbar nav a:not(.btn) {
  margin-left: var(--space-5);
  color: var(--text-dim);
  text-decoration: none;
}
.topbar nav a:first-child { margin-left: 0; }
.topbar nav a:not(.btn):hover { color: var(--text); text-decoration: none; }
/* Active-page state on the public nav (#1300 P0). The shell marks the
   current page's nav link with ``aria-current="page"`` (derived from
   the request's canonical path), and the style keys off that
   attribute so the semantic and visual state can't drift apart. Kept
   deliberately neutral — full text color plus a quiet underline; the
   accent green stays reserved for the CTA (#627 "one green, one
   meaning"). */
.topbar nav a[aria-current="page"] {
  color: var(--text);
  text-decoration: underline;
  text-decoration-color: var(--text-dim);
  text-underline-offset: 0.45em;
}
/* Compact header CTA (#1300 P0), sized down from the body .btn so it
   sits inside the header type, not on top of it. "Sign in" stays a text
   link; one filled control per header. It is the public nav's last
   item, so a narrow header folds it into the menu with the links rather
   than crowding the brand row above a hero that repeats it. */
.btn.nav-cta {
  padding: var(--space-1) var(--space-3);
  font-size: var(--fs-base-sm);
  white-space: nowrap;
}
.public-menu > summary { list-style: none; }
.public-menu > summary::-webkit-details-marker { display: none; }
main { padding: var(--space-8) 0 4rem; /* 4rem bottom = generous page-bottom breathing on the public layout; --space-12 (3rem) would crowd the foot under long pages */ }
/* Headings: explicit 600 so we don't inherit the UA's 700 — too
   heavy for light-on-dark display text. Slight negative tracking
   on h1 tightens the larger size optically. */
h1 {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-bold);
  letter-spacing: -0.01em;
  line-height: 1.2;
  margin: 0 0 0.5rem;
}
body.layout-sidebar main h1 {
  font-size: var(--fs-2xl);
  line-height: 1.2;
  letter-spacing: -0.015em;
}
@media (max-width: 640px) {
  body.layout-sidebar main h1 { font-size: var(--fs-hero-mobile); }
}
/* Hero size step — opt-in via ``.card.hero`` on a landing-style card.
   Product and account pages share the approved 32/26px page-title pair. */
.card.hero h1 {
  font-size: var(--fs-2xl);
  line-height: 1.2;
  letter-spacing: -0.015em;
}
@media (max-width: 640px) {
  .card.hero h1 { font-size: var(--fs-hero-mobile); }
}
/* Marketing pages opt into the approved 56/36px hero pair; the public Home's
   two-column hero scales between the two (see the Home experience below).
   Section headings stay at the shared 20/18px scale. Element-level selectors
   are intentional: copy pins assert the literal heading markup. */
body.layout-marketing .card.hero h1 {
  font-size: var(--fs-3xl);
  font-weight: var(--fw-medium);
  line-height: 1.1;
}
body.layout-marketing h2 { font-size: var(--fs-lg); }
@media (max-width: 640px) {
  body.layout-marketing .card.hero h1 { font-size: var(--fs-3xl-mobile); }
  body.layout-marketing h2 { font-size: var(--fs-md); }
}
h2 {
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  line-height: var(--lh-heading);
  margin: 0 0 0.75rem;
  color: var(--text);
}
p.kicker {
  /* Dim, not accent (design-critique pass): the eyebrow kicker used to
     paint --accent green, putting a second green attention magnet right
     above the hero's green CTA so first fixation split between the two.
     This completes the "one green, one meaning" accent discipline the
     rest of the marketing surface already follows: green is reserved for
     the CTA button and the proof column (#627), and for the analyst turn
     label + CTA on /examples (#817). The kicker now shares the signed-in
     sentence-case eyebrow role, letting the <h1> and the CTA own the hero.
     --text-dim on the dark surface is ~7:1, well past AA at this size. */
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-medium);
  margin: 0 0 0.5rem;
}
p.lede {
  color: var(--text-dim);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  margin: 0 0 var(--space-8);
}
/* Opt-in measure cap (issue #760) — a dashboard ``.lede`` runs the full
   60rem shell width by default, which is too wide for comfortable
   reading. Pages where the lede is body copy (not a hero line) add
   ``measure`` to cap it near the ~65ch readable line length, matching
   the ``.dim-blurb`` (60ch) treatment. Opt-in for dashboard surfaces;
   the marketing pages carry a blanket ~70ch cap below (#1300 P2 —
   uncapped ledes ran 85-90ch across the 56rem shell). */
p.lede.measure { max-width: var(--measure-prose); }
/* Marketing prose measure (#1300 P2). Scoped to the public marketing
   shell: ledes cap near 70ch so
   paragraphs stop running the full 56rem card width. Ledes that opt
   into the tighter 65ch .measure are excluded here (the :not()) so
   the opt-in keeps winning — without it this later, higher-specificity
   rule would silently widen them to 70ch. */
body.layout-marketing p.lede:not(.measure) { max-width: var(--measure-support); }
/* "How this works" expander — demotes pipeline/drift mechanics under
   a plain-English lede (e.g. /dashboard/rules) so the value promise
   reads first and the internals are one click away. Tighten the gap
   to the lede above it so the two read as one unit. */
p.lede:has(+ details.how-it-works) { margin-bottom: var(--space-3); }
details.how-it-works {
  margin: 0 0 var(--space-8);
  font-size: var(--fs-base-sm);
  color: var(--text-dim);
}
details.how-it-works > summary {
  cursor: pointer;
  list-style: none;
  color: var(--text-dim);
  font-weight: var(--fw-medium);
}
details.how-it-works > summary::-webkit-details-marker { display: none; }
details.how-it-works > summary::before {
  content: "▸" / "";
  display: inline-block;
  flex: 0 0 auto;
  margin-right: var(--space-2);
}
details.how-it-works[open] > summary::before { transform: rotate(90deg); }
details.how-it-works > summary:hover { color: var(--accent); }
details.how-it-works > p {
  margin: var(--space-2) 0 0;
  line-height: 1.55;
}
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-5) var(--space-6);
  margin-bottom: var(--space-4);
}
.card.hero { border-radius: var(--radius-lg); }
body.layout-sidebar .card { padding: var(--space-6) var(--space-8); }
@media (max-width: 640px) {
  body.layout-sidebar .card { padding: var(--space-5); }
}
.card.danger { border-color: var(--danger-border); }
/* Section-rhythm floor (#1308). Top-level page sections self-space
   via a bottom margin on their own class (.card above;
   .feature-pillar, .tier-grid below), but a
   section class that never joined the system rendered flush against
   its neighbor: /demo's bare `section.tile-grid` sat 0px above the
   setup-help card. This floor guarantees the standard gap between
   adjacent top-level sections. :where() keeps it at zero
   specificity, so any class that declares its own margin-top
   (.mt-*) still wins outright, and sibling margin
   collapsing makes the floor a no-op wherever the preceding section
   already carries a bottom margin of --space-4 or more (every
   existing page). Pinned by tests/web/test_section_rhythm.py; a new
   top-level section class must also join RHYTHM_AUDITED_CLASSES
   there. */
:where(.shell > section + section) { margin-top: var(--space-4); }
.tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
  gap: var(--space-4);
}
/* /features capability grid (issue #816). The shared auto-fit
   .tile-grid uses a smaller content floor here to keep reading measures
   useful at intermediate widths. The floor is bounded by available width
   so enlarged text still gets one complete column. */
.tile-grid.feature-grid {
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
}
.tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-5) var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
/* Flex gap owns generic tile rhythm. Zero specificity lets a component
   with an intentional paragraph margin override this without a fight. */
:where(.tile > p) { margin: 0; }
.tile .row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
  /* Wrap so a long pill drops below its label rather than
     squeezing the label into a two-line stub when the row
     can't hold both on one line. */
  flex-wrap: wrap;
}
/* Long unbreakable code tokens (SLATEMARK_* env names, row ids) are
   the classic 320px page-overflow source (#1395 WS7): let them break
   anywhere rather than widen the page. */
code { overflow-wrap: anywhere; }
/* Focal accent-left rule, the single point of truth for the
   "this is the focal one" framing on tile-grid heroes
   (``.tile.hero``, issue #422).
   ``.tier.featured`` intentionally uses a different treatment
   (full accent border + ``--accent-wash`` bg, see below) —
   it sits in a grid of peers on /pricing and carries heavier
   emphasis than a single focal card. */
.tile.hero {
  border-left: 3px solid var(--accent);
}
/* A faint accent wash and complete accent edge make the promoted next step
   distinct without elevation. */
.tile.hero {
  background: var(--accent-wash);
  border-color: var(--accent);
  border-left-color: var(--accent);
}
/* Features pairs a short promise with its evidence in each of six anchored
   pillars. Headings remain in the document's reading order, and the layout
   below gives the same lead/detail relationship at every width. */
.feature-lead > h2 { margin-bottom: var(--space-2); }
.feature-lead > .pillar-lede {
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
  line-height: 1.55;
  margin: 0;
  max-width: var(--measure-prose);
}
/* Marketing-tile heading — the scannable title on a /features tile.
   Deliberately NOT .tile-title (that's a mono identifier for the
   tools catalog): full --text color, sentence case, and a step above
   the 16px body so the title is the most prominent element on the
   tile, not the dimmest (issue #816 inverted-hierarchy fix). Promoted
   from a dim <span class="label"> to a real <h3> so heading
   navigation and SEO get one stop per feature. */
.tile > h3.tile-heading {
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  line-height: var(--lh-heading);
  color: var(--text);
  margin: 0;
}
/* Linked tile titles (#1298): a heading is no place to spend the
   accent (one green, one meaning). Keep the title in --text and carry
   the link affordance as a quiet underline that sharpens on hover. */
.tile > h3.tile-heading a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--border);
  text-underline-offset: 3px;
}
.tile > h3.tile-heading a:hover { text-decoration-color: var(--text-dim); }
.tile .value {
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum", "zero";
}
.tile .actions { margin-top: auto; padding-top: var(--space-2); display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; }
.muted-note {
  color: var(--text-dim);
  /* Roman, not italic (issue #626): long italic runs hurt
     readability and these are the lowest-contrast text on the
     tile face. Contrast of --text-dim on --surface is ~7:1, well
     past the 4.5:1 AA floor. */
  font-size: var(--fs-base-sm);
}
.tile .muted-note { padding: var(--space-3) 0; }
/* Setup-stepper "skill install" sub-card. Groups the per-AI-client
   download picker, the install-path hint, and the attestation
   checkbox into one visually-cohesive block on step 2's done state.
   Without the frame the three pieces read as three competing
   affordances on a flat surface; with it they read as one
   "install your skill" workflow. */
.card > .muted-note:first-of-type {
  margin-top: 0;
  margin-bottom: var(--space-4);
  max-width: 48rem;
}
.section-stack > * + * { margin-top: var(--space-6); }
/* Returning-user recent-record panel on Home / the dashboard (#1578).
   Rides .card for its section rhythm; these rules only shape the
   inner list and rows. ``Open <symbol>`` is an explicit compact action,
   not prose, so it uses weight + hover feedback instead of carrying the
   global resting underline into every ticker row. */
.activity-recent {
  list-style: none;
  margin: 0 0 var(--space-3);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.activity-recent-link {
  display: inline-block;
  font-weight: var(--fw-medium);
  text-decoration: none;
}
.activity-recent-link:hover {
  text-decoration: underline;
  text-decoration-thickness: 0.1em;
}
.activity-attention {
  margin: 0 0 var(--space-2);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.activity-scorecard { margin: 0; }
.connection-row { margin: 0; }
/* The card's vertical rhythm rides the .tile flex `gap` (--space-2), not
   the UA <p> margins (which never collapse in a flex column and stacked
   on the gap) nor the shared `.tile .muted-note` padding — both zeroed
   here so related content stays tight. Group boundaries add an explicit
   token margin on top of the base gap so unrelated groups breathe, and
   the biggest void inside the card no longer exceeds the page's own
   section rhythm (#1375). */
.connection-row p { margin: 0; }
.connection-row .muted-note { padding: 0; }
.connection-row .account-list-head {
  margin-top: var(--space-2);  /* + the .tile gap ~= a group boundary */
  padding: 0;
}
.connection-row .account-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--border);
}
/* Account rows read as a border-separated table, name + institution
   inline ("Roth IRA · Fidelity") rather than
   flung to opposite card edges with no separator (#1375). */
.connection-row .account-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  flex-wrap: wrap;
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--border);
}
.connection-row .account-row:last-child { border-bottom: none; }
.connection-row .account-broker { color: var(--text-dim); }
.connection-row .account-broker::before {
  content: "·";
  padding-right: var(--space-2);
}
/* Rename: a real disclosure affordance, not inert dim text. The prior
   `display: inline-block` suppressed the UA marker, leaving "Rename"
   looking static; draw our own caret and
   underline on hover, grouped just under the action row (#1375). */
.connection-row .rename { margin-top: 0; }
.connection-row .rename > summary {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  width: max-content;
  padding: var(--space-1) 0;
  list-style: none;
}
.connection-row .rename > summary::-webkit-details-marker { display: none; }
.connection-row .rename > summary::before {
  content: "";
  width: 0.4rem;
  height: 0.4rem;
  border-right: 2px solid var(--text-dim);
  border-bottom: 2px solid var(--text-dim);
  transform: rotate(-45deg);
}
.connection-row .rename[open] > summary::before {
  transform: rotate(45deg);
}
.connection-row .rename > summary:hover {
  color: var(--text);
  text-decoration: underline;
}
.connection-row .rename > summary:hover::before { border-color: var(--accent); }
.coming-soon { margin-top: var(--space-4); }
.credentials {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--border);
  margin-top: var(--space-1);
}
p.callout {
  margin: 0 0 var(--space-4) 0;
  padding: var(--space-3) var(--space-4);
  background: var(--surface-2);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  font-size: var(--fs-base-sm);
  color: var(--text);
}
p.callout code {
  font-family: var(--font-mono);
  /* em-relative shrink (not a token): monospace inline <code> renders
     visually larger than the surrounding sans, so it scales relative to
     its parent rather than to a rem-based size. */
  font-size: 0.88em;
  color: var(--text-dim);
}
.tool-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  margin: var(--space-3) 0 var(--space-1) 0;
}
/* Shared input skin (#985, extended #1206). One base, the .input class,
   owns the surface + border + radius + padding + text color + accent
   focus-border that each form system used to redeclare identically.
   Per-system deltas (width / max-width / font-family / font-size / flex
   / resize) stay on the individual rules below. The selector list folds
   in each system's existing matched set (descendant
   input/select/textarea) alongside .input, so no element needs
   class="input" added and specificity is unchanged, while a future form
   can just use class="input". The keyboard :focus-visible ring lives at
   the top of this file and is untouched; the focus selectors below only
   restate the accent border + non-keyboard outline-reset. A single
   ::placeholder treatment (dim + italic) is hoisted alongside the skin
   (#1206) so placeholder tone no longer varies page to page; a system's
   own font-family on the placeholder stays local. The systems whose
   last consumer retired were removed from these lists (#2591 D20).
   color-scheme: dark
   is part of the skin (#1207): it themes the native control chrome (the
   <select> arrow, the date-picker glyph) that the UA otherwise draws
   dark-on-dark against these controls' dark background. */
.input,
.form-stack input[type="text"],
.form-stack input[type="datetime-local"],
.form-stack input[type="number"],
.form-stack input[type="email"],
.form-stack input[type="password"],
.form-stack input[type="url"],
.form-stack select,
.form-stack textarea,
.reconcile-tag-form select,
.reconcile-tag-form input[type="text"],
.reconcile-tag-form textarea,
.chat-form textarea {
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  padding: var(--space-2) var(--space-3);
  color: var(--text);
  color-scheme: dark;
}
/* The shared skin keeps native arrows and picker glyphs on the same dark
   chrome across public, auth, and signed-in surfaces. */
.input:focus,
.form-stack input:focus,
.form-stack select:focus,
.form-stack textarea:focus,
.reconcile-tag-form select:focus,
.reconcile-tag-form input[type="text"]:focus,
.reconcile-tag-form textarea:focus,
.chat-form textarea:focus { border-color: var(--accent); }
.input:focus:not(:focus-visible),
.form-stack input:focus:not(:focus-visible),
.form-stack select:focus:not(:focus-visible),
.form-stack textarea:focus:not(:focus-visible),
.reconcile-tag-form select:focus:not(:focus-visible),
.reconcile-tag-form input[type="text"]:focus:not(:focus-visible),
.reconcile-tag-form textarea:focus:not(:focus-visible),
.chat-form textarea:focus:not(:focus-visible) { outline: none; }
/* Shared placeholder treatment (#1206). One dim, italic tone for every
   skinned control, so placeholder text reads the same on every form
   (.form-stack, .reconcile-tag-form, and .chat-form fell back to the
   browser default). Only color + slant are shared:
   font-family stays per system, so the mono controls keep a mono
   placeholder. Selects carry no placeholder and are absent from the
   list. */
.input::placeholder,
.form-stack input::placeholder,
.form-stack textarea::placeholder,
.reconcile-tag-form input[type="text"]::placeholder,
.reconcile-tag-form textarea::placeholder,
.chat-form textarea::placeholder {
  color: var(--text-dim);
  font-style: italic;
}
/* Keep Chromium's saved-value paint inside the same dark control contract.
   Native picker glyphs and select arrows inherit the body/control dark
   color-scheme; the text/caret declarations prevent a bright autofill state
   from erasing the value against that ground. */
.input:-webkit-autofill,
.form-stack input:-webkit-autofill,
.reconcile-tag-form input:-webkit-autofill {
  -webkit-text-fill-color: var(--text);
  caret-color: var(--text);
}
.input:disabled,
.form-stack :is(input, select, textarea):disabled,
.reconcile-tag-form :is(input, select, textarea):disabled,
.chat-form textarea:disabled {
  background: var(--surface-2);
  color: var(--text-dim);
  cursor: not-allowed;
}
.input[readonly],
.form-stack :is(input, textarea)[readonly],
.reconcile-tag-form :is(input, textarea)[readonly],
.chat-form textarea[readonly] {
  background: var(--surface-2);
  border-style: dashed;
}
/* Inline validation error state (#977, #2744). A control is invalid only
   when its projection names that control: the message is the field's
   .field-error line, joined to the control's aria-describedby. A
   form-level error is a role="alert" banner and marks no control. Every
   .field-row sits in a form.form-stack. These element-qualified
   selectors tie the skin's focus rule and sit later in source, so the
   danger edge survives focus. */
.form-stack input[aria-invalid="true"],
.form-stack select[aria-invalid="true"],
.form-stack textarea[aria-invalid="true"] { border-color: var(--danger); }
.btn {
  display: inline-block;
  /* Grid items stretch across their track by default even when their
     display is inline-block. Buttons should hug their label unless a
     component deliberately owns a full-width CTA (for example the
     sidebar and narrow-screen action stacks), so make that default
     shared across every grid-backed action row. */
  justify-self: start;
  max-width: 100%;
  padding: var(--space-2) var(--space-4);
  background: var(--accent);
  color: var(--on-accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  font-weight: var(--fw-bold);
  font-size: var(--fs-base);
  cursor: pointer;
  text-decoration: none;
  font-family: inherit;
  /* Background and text switch together so disabled-to-enabled changes never
     pass through an unreadable interpolated pair. The edge keeps the brief
     interaction feedback allowed by the motion contract. */
  transition: border-color 160ms ease;
}
.btn:hover { background: var(--accent); color: var(--on-accent); border-color: var(--text); text-decoration: none; }
.btn.small {
  padding: var(--space-1) var(--space-3);
  font-size: var(--fs-base-sm);
}
.hero-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-4);
  margin: 0 0 var(--space-4) 0;
}
.btn.secondary {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border-strong);
}
.btn.secondary:hover { background: var(--surface-2); border-color: var(--text-dim); color: var(--text); }
.btn.danger {
  background: transparent;
  color: var(--danger);
  border: 1px solid var(--border-strong);
}
.btn.danger:hover { background: var(--danger-bg); border-color: var(--danger); }
.btn:disabled,
.btn:disabled:hover,
.btn[aria-disabled="true"],
.btn[aria-disabled="true"]:hover {
  background: var(--surface-2);
  color: var(--text-dim);
  border-color: var(--border-strong);
  cursor: not-allowed;
  /* Belt + suspenders (issue #426). The anchor-as-button render
     pattern uses ``<a class="btn" aria-disabled="true" tabindex="-1">``
     with no ``href`` so it can't be clicked or focused. ``pointer-
     events: none`` is a final guard: if a future caller adds an
     ``href`` to "fix" linting, the disabled visual still doesn't
     navigate. */
  pointer-events: none;
}
.pill {
  display: inline-block;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-bold);
  font-family: var(--font-sans);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  /* Long pill text (e.g. "1 active · 1 revoked", "Swing /
     individual-stock trader") used to wrap inside the pill on
     narrow viewports, which made the pill look like a two-line
     bubble and pushed the sibling label onto two lines too.
     Keep pill content atomic; the surrounding ``.tile .row``
     flex-wraps it onto its own line when the row can't fit
     both items. */
  white-space: nowrap;
}
.pill.ok { background: var(--success-bg); color: var(--success); }
.pill.warn { background: var(--warn-bg); color: var(--warn); }
.pill.dim { background: var(--surface-2); color: var(--text-dim); }
/* Meaning-specific, non-status pills (#1569). Trade side, plan identity,
   and a product recommendation are labels, not success or warning
   states, so they deliberately carry no ok/warn glyph. */
.pill.side {
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border-strong);
  padding: calc(var(--space-1) - 1px) calc(var(--space-2) - 1px);
}
.pill.plan { background: var(--surface-2); color: var(--text-dim); }
.pill.recommended { background: var(--info-bg); color: var(--info); }
/* ``.pill.danger`` (issue #635) — muted-danger status tone so a
   terminal/revoked state reads as *status*, distinct from the
   neutral grey ``.pill.dim`` used for provenance tags (e.g.
   "Auto-connected") that sit beside it. Same 0.12-alpha-fill +
   token-color recipe as ``.ok`` / ``.warn``, which clears WCAG AA on
   both frames: the tokens resolve to --danger over --surface on the
   public pages and the same dark signed-in canvas (#2955). */
.pill.danger { background: var(--danger-bg); color: var(--danger); }
/* ``.pill.info`` (issue #419) — half-state tone for "started, not
   done" rows. Distinct from ``.pill.warn`` ("needs your attention")
   and ``.pill.ok`` ("done"), so a user scanning the setup stepper
   can tell PINNED apart from PENDING at a glance. Cool blue keeps
   the system at three colors plus dim and clears WCAG AA on both
   frames, resolving to --info over --surface on the public pages and
   to --info over the unified signed-in canvas (#2955). */
.pill.info { background: var(--info-bg); color: var(--info); }
/* ``.pill.outline`` (issue #432) — credential row "Not set" status,
   distinct from ``.pill.dim`` ("Disabled" — stored but paused). The
   solid border + no fill reads as "no key here" so a user scanning
   the credentials page can tell stored-paused from nothing-stored
   apart without reading the masked value. */
.pill.outline {
  background: transparent;
  color: var(--text-dim);
  border: 1px solid var(--border-strong);
  /* solid border eats ~2px vs filled background; trim padding to
     keep pill height visually consistent with .ok/.warn/.dim. */
  padding: calc(var(--space-1) - 1px) calc(var(--space-2) - 1px);
}
/* The check-email resend form (#981). Sign-in and sign-up compose a
   form.form-stack field since #2744. */
form.signin { display: flex; flex-direction: column; gap: var(--space-3); max-width: 22rem; }
/* Share the first-paint and resolved form footprint. Longer signup details
   and validation messages remain free to grow without clipping at zoom. */
.auth-card { min-block-size: 20rem; }
.auth-pending {
  min-block-size: 10rem;
  display: grid;
  align-content: center;
  color: var(--text-dim);
}
.auth-pending p {
  align-items: center;
  display: grid;
  gap: var(--space-4);
  grid-template-columns: var(--space-12) minmax(0, 1fr);
  margin: 0;
}
/* The decorative ledger mark resolves like a compact journal coming into
   focus without implying measurable progress. Its bars grow only inside the
   mark's reserved footprint; status text and surrounding layout stay fixed.
   The shared auth and React loading states remain still when the user requests
   reduced motion. */
.loading-mark {
  border-inline-start: 1px solid var(--border-strong);
  display: grid;
  gap: var(--space-2);
  inline-size: var(--space-12);
  padding-inline-start: var(--space-3);
}
.loading-mark > span {
  background: var(--info);
  block-size: calc(var(--space-1) / 2);
  border-radius: var(--radius-sm);
  display: block;
  transform-origin: left center;
}
.loading-mark-long { inline-size: 100%; }
.loading-mark-medium { inline-size: 75%; }
.loading-mark-short { inline-size: 50%; }
@media (prefers-reduced-motion: no-preference) {
  .loading-mark > span {
    animation: loading-mark-resolve 1.4s ease-in-out infinite;
  }
  /* These selectors deliberately outrank the animation shorthand above. */
  .loading-mark > .loading-mark-medium { animation-delay: -0.35s; }
  .loading-mark > .loading-mark-short { animation-delay: -0.7s; }
}
@keyframes loading-mark-resolve {
  0%, 100% {
    opacity: 0.35;
    transform: scaleX(0.55);
  }
  50% {
    opacity: 1;
    transform: scaleX(1);
  }
}
.signup-assurance {
  max-width: 34rem;
  margin: var(--space-5) 0 0;
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
  line-height: 1.5;
}
.signup-assurance li + li { margin-top: var(--space-2); }
.signup-assurance strong {
  color: var(--text);
  font-weight: var(--fw-medium);
}
/* Resend affordance on the check-your-email page (#981). The button
   group lays the inbox deep-link and the resend button in one wrapping
   row; the status line below carries the live cooldown countdown. */
form.signin.resend { gap: var(--space-2); }
.resend-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}
.resend-status {
  margin: var(--space-1) 0 0;
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
  min-height: 1.25em;
}
.banner {
  border-left: 3px solid var(--accent);
  background: var(--accent-wash);
  padding: var(--space-3) var(--space-4);
  border-radius: 0 var(--radius) var(--radius) 0;
  margin-bottom: var(--space-6);
  color: var(--text-dim);
}
.banner.warn { background: var(--warn-bg); border-left-color: var(--warn); }
.banner.danger { background: var(--danger-bg); border-left-color: var(--danger); }
/* A form directly inside a banner (the past-due "Update payment"
   button, #177) sits under the message with a small gap. Inline-block
   rather than inline: a vertical margin needs a block-level box to take
   effect. */
.banner > form {
  display: inline-block;
  margin-top: var(--space-2);
}
.banner-progress {
  display: block;
  margin-top: var(--space-2);
  height: 0.35rem;
  background: var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.banner-progress > span {
  display: block;
  height: 100%;
  background: var(--warn);
  border-radius: inherit;
}
.banner.warn .banner-progress > span { background: var(--warn); }
.footer {
  border-top: 1px solid var(--border);
  margin-top: 4rem; /* 4rem footer top margin = clear separation from page content; --space-12 (3rem) would crowd the disclaimer band */
  padding: var(--space-5) 0;
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
}
.footer .shell { display: flex; justify-content: space-between; align-items: center; gap: var(--space-4); }
.footer-nav { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.footer-nav a { color: var(--text-dim); text-decoration: none; }
.footer-nav a:hover { color: var(--text); text-decoration: none; }
/* The fineprint deliberately does NOT use ``.shell``. The sidebar
   layout's ``body.layout-sidebar .shell { margin: 0 auto; padding: 0 var(--space-8) }``
   has higher specificity than this rule, so reusing ``.shell`` here
   collapses the fineprint's margin-top and padding-top to zero on
   dashboard pages — the disclaimer ends up jammed against the row
   above with no separator. Give the fineprint its own sizing and
   centering so the spacing survives. */
.footer-fineprint {
  display: block;
  max-width: 56rem;
  margin: var(--space-4) auto 0;
  padding: var(--space-4) var(--space-6) 0;
  border-top: 1px solid var(--border);
  font-size: var(--fs-base-sm);
  line-height: 1.5;
  color: var(--text-dim);
}
body.layout-sidebar .footer-fineprint {
  max-width: 72rem;
  padding-left: var(--space-8);
  padding-right: var(--space-8);
}
.disclosure-list { margin: var(--space-6) 0; padding: var(--space-4) var(--space-4) var(--space-4) var(--space-8); background: var(--surface-2); border-left: 3px solid var(--border); border-radius: var(--radius); font-size: var(--fs-base-sm); line-height: 1.55; color: var(--text-dim); }
.disclosure-list li { margin: var(--space-1) 0; }
.disclosure-list strong { color: var(--text); font-weight: var(--fw-bold); }
.hero-disclaimer {
  margin: 0;
  font-size: var(--fs-base-sm);
  line-height: 1.5;
  color: var(--text-dim);
}
.hero-disclaimer a { color: var(--text-dim); text-decoration: underline; }
.hero-disclaimer a:hover { color: var(--text); }
/* Tertiary text-link CTA (e.g. paused-signup "Sign in") sitting in the
   .hero-cta flex row beside the .btn pair (#627). Reads as a link, not
   a button, so the single primary stays unambiguous. Padded so the tap
   target clears 44px on touch even though it isn't a .btn. */
.hero-cta-text {
  color: var(--text-dim);
  font-weight: var(--fw-medium);
  text-decoration: underline;
  padding: var(--space-2) 0;
}
.hero-cta-text:hover { color: var(--text); }
/* Hero proof teaser (#818 P1) — lifts one cite chip above the fold so a
   product whose pitch is "sourced, timestamped numbers" shows a sourced
   number in the hero, not only in the third card down the page. Reuses
   the .cite typographic mark from the after-vignette; line-height runs
   loose so the inline chips don't crowd. */
.hero-proof {
  margin: 0 0 var(--space-5);
  font-size: var(--fs-base);
  line-height: 1.7;
  color: var(--text-dim);
}
/* Launch-wedge audience line (#855) — names the swing trader as the
   first audience right under the lede, so a cold visitor knows who the
   product is built for before the proof chip. Same quiet treatment as
   .hero-clients: secondary color, the audience noun promoted to
   --text. */
.hero-audience {
  margin: 0 0 var(--space-4);
  font-size: var(--fs-base-sm);
  line-height: 1.5;
  color: var(--text-dim);
}
.hero-audience strong { color: var(--text); font-weight: var(--fw-medium); }
/* BYO-AI-client line (#818 P2) — states the bring-your-own-client model
   next to the hero CTA so a cold visitor knows Slatemark plugs into the
   AI client they already use, not a chatbot we host. */
.hero-clients {
  margin: 0 0 var(--space-4);
  font-size: var(--fs-base-sm);
  line-height: 1.5;
  color: var(--text-dim);
}
.hero-clients strong { color: var(--text); font-weight: var(--fw-medium); }
.kv {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-2) var(--space-4);
  font-size: var(--fs-base-sm);
  font-variant-numeric: tabular-nums;
}
.kv dt { color: var(--text-dim); }
.kv dd { margin: 0; }
/* FAQ list — question/answer pairs. Desktop: two columns with a
   fixed-width question gutter so the answers wrap on a consistent
   left edge. Mobile: questions stack above answers (see the 640px
   breakpoint) since long questions otherwise crush the answer
   column on a phone. */
.faq { display: grid; grid-template-columns: minmax(0, 16rem) minmax(0, 1fr); gap: var(--space-4) var(--space-6); font-size: var(--fs-base); align-items: baseline; }
.faq dt { color: var(--text); font-weight: var(--fw-bold); line-height: 1.4; }
.faq dd { margin: 0; color: var(--text-dim); line-height: 1.6; }
/* Pricing keeps lower-frequency FAQ answers in one native disclosure.
   .disclosure-summary uses flex layout, which can hide the browser marker,
   so restore an explicit chevron and rotate it with the native open state. */
.pricing-faq-more > summary { list-style: none; }
.pricing-faq-more > summary::-webkit-details-marker { display: none; }
.pricing-faq-more > summary::before {
  content: "▸";
  display: inline-block;
  margin-right: var(--space-2);
}
.pricing-faq-more[open] > summary::before { transform: rotate(90deg); }
.center { text-align: center; }

/* L4 — design-system audit cleanup. The utilities and three
   component classes below replace the bulk of the inline
   ``style=""`` declarations that had accumulated across the
   branded web modules before the H1/H2/M4 token series landed
   (issues #522 / #523 / #527). Per the class-naming guidance at
   the top of this file, a utility earns its keep when it's used
   in two+ unrelated components AND is purely presentational. */
.mt-2 { margin-top: var(--space-2); }
.mt-3 { margin-top: var(--space-3); }
.mt-4 { margin-top: var(--space-4); }
.mt-5 { margin-top: var(--space-5); }
.mt-6 { margin-top: var(--space-6); }
.ml-2 { margin-left: var(--space-2); }

/* Document forms (#1211, #2744): the browser documents' statement of the
   field anatomy in docs/frontend-design-system.md ("Field", "Field
   widths"). One order, always: the label, the control, then an optional
   .field-notes block holding the help and then the field error. The label
   names the control through <label for>, and the help and error join its
   aria-describedby, so its accessible name is the label alone. The
   signed-in .sm-field in frontend/src/spa.css is the same anatomy in the
   route bundle; site.css declares no .sm-field rule and spa.css no
   .field-row rule, so the two never meet.

   Each gap has one owner, and no child adds a margin in the same axis. A
   form.form-stack spaces its fields from its action row (24px),
   .field-group spaces fields (16px), .field-row spaces the label, control
   and notes (8px), and .field-notes spaces the help from the error (4px).
   A bare div.form-stack, the reviewed first-workflow copy box, keeps its
   20px step. */
.form-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
form.form-stack { gap: var(--space-6); }
.form-stack > .btn { align-self: flex-start; }
.field-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
/* The single minmax(0, 1fr) track and min-width: 0 let a control shrink
   below its intrinsic width on the 320px floor at 200% text. */
.field-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  gap: var(--space-2);
  min-width: 0;
}
.field-row > .field-label {
  color: var(--text);
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-bold);
  line-height: var(--lh-body);
}
.field-notes {
  display: grid;
  gap: var(--space-1);
}
/* The notes block owns both of its steps, so its lines keep no user-agent
   paragraph margin. */
.field-notes > * { margin: 0; }
.field-help {
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
  line-height: var(--lh-body);
}
.field-error {
  color: var(--danger);
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-medium);
  line-height: var(--lh-body);
}
.form-stack input[type="text"],
.form-stack input[type="datetime-local"],
.form-stack input[type="number"],
.form-stack input[type="email"],
.form-stack input[type="password"],
.form-stack input[type="url"],
.form-stack select {
  width: 100%;
  /* The unclassified fallback, the route bundle's cap. */
  max-width: var(--control-long);
  min-block-size: var(--control-target);
  margin: 0;
  font-family: inherit;
  font-size: var(--fs-base);
  line-height: var(--lh-body);
}
.form-stack textarea {
  width: 100%;
  font-family: var(--font-mono);
  font-size: var(--fs-base-sm);
  line-height: 1.5;
  resize: vertical;
}
/* A classified control width. Only the control takes the maximum; the
   label and notes keep the field's column. This ties the control rule
   above at (0,2,1) and wins on source order alone, so it stays after it. */
.field-row.field-text > :is(input, select, textarea) {
  max-width: var(--control-text);
}
/* A read-only input reads as neither editable nor disabled, as in the
   route bundle: the subdued ground and a dashed edge, with the skin's live
   text color. It ties the skin at (0,2,1) and wins on source order. */
.field-row > input[readonly] {
  background: var(--surface-2);
  border-style: dashed;
}

/* Broker link + Account-Data consent interstitials (#1208). The
   SnapTrade link, consent, and result pages use the clean neutral React
   shell, with no distracting nav on a trust-sensitive consent step. They
   inherit ``.card`` / ``.btn`` /
   ``.form-stack`` / ``.banner`` / ``.muted-note``; these two rules are
   the only markup unique to them: the consent bullet list and the
   affirmative-consent checkbox row. */
.consent-points { margin: 0 0 var(--space-4); padding-left: var(--space-5); }
.consent-points li { margin: var(--space-1) 0; line-height: 1.5; }
.consent-agree {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
  margin: var(--space-4) 0;
  line-height: 1.5;
}
.consent-agree input[type="checkbox"] { flex: none; margin: var(--space-1) 0 0; }

/* Data table. Only signed-in route bodies render one today (Scorecard,
   the symbol page, a record's booked reductions and Settings' starter
   packs). Cells stay left-aligned unless numeric. Wrap a table that must
   scroll on a narrow viewport in a labeled, focusable ``.scroll-x``
   region. */
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-base);
}
.data-table thead tr {
  text-align: left;
  color: var(--text-dim);
  /* Headings sit at --fs-base-sm (14px), below the 16px body they head
     (#986), in sentence case with normal tracking like every other label
     (#2744). */
  font-size: var(--fs-base-sm);
  border-bottom: 1px solid var(--border);
}
.data-table th { padding: var(--space-2); font-weight: var(--fw-medium); }
.data-table td { padding: var(--space-3) var(--space-2); vertical-align: top; }
.data-table th:first-child,
.data-table td:first-child { padding-left: 0; }
.data-table tbody tr { border-bottom: 1px solid var(--border); }
.data-table tbody tr:last-child { border-bottom: none; }

/* Strategy Scorecard (/dashboard/scorecard) — page-specific styling
   for the date/account filter row, the sortable + numeric ``.data-table``
   modifiers, the sample-size badges (P0-7), the "Favorite vs Best"
   insight card (P0-6), and the free-tier teaser (P0-9). These extend
   the shared ``.data-table`` base above; they live here rather than
   inline in ``web/scorecard.py`` so all page CSS stays in this one
   string (see module docstring). */
.data-table th.sortable a {
  color: inherit;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  text-decoration: none;
}
.data-table th.sortable a:hover { color: var(--accent); text-decoration: none; }
.data-table td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.data-table th.num { text-align: right; }
/* P&L cells read from the semantic --pnl-* tokens, not the brand
   --accent / --danger, so gain/loss *meaning* is decoupled from CTA
   and destructive intent (#982). */
.data-table td .pnl-pos { color: var(--pnl-up); }
.data-table td .pnl-neg { color: var(--pnl-down); }
.win-ci { display: block; color: var(--text-dim); font-size: var(--fs-micro); }
/* Facet rollup (#828): the default scorecard view, one expandable
   disclosure per PRIMARY facet. The summary carries the facet name and
   its distribution headline; expanding reveals the per-leaf table. */
.facet-rollup {
  border-top: 1px solid var(--border);
  padding: var(--space-2) 0;
}
.facet-rollup:first-of-type { border-top: none; }
.facet-rollup > summary {
  cursor: pointer;
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  list-style: none;
}
.facet-rollup > summary::-webkit-details-marker { display: none; }
.facet-rollup > summary::before {
  content: "▸";
  color: var(--text-dim);
}
.facet-rollup[open] > summary::before { content: "▾"; }
.facet-rollup .facet-name { font-weight: 600; }
.facet-rollup .facet-dist { color: var(--text-dim); font-size: 0.9em; }
.facet-rollup .data-table { margin-top: var(--space-2); }
/* Per-trade capture foundation (#731 / #1409). The journal symbol page's
   capture forms use these controls; the reconcile inbox moved to the
   shared field layer (#2585 D14). */
.reconcile-tag-form {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.reconcile-tag-form label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--fs-base-sm);
  color: var(--text-dim);
}
/* Reconcile tag form controls (trades-needing-attention inbox, #731):
   the shared .input skin (#985) supplies the surface / border / focus;
   these are just the reconcile-only deltas (select min-width, font
   sizing). The skin resolves its semantic tokens against whichever
   frame the page sets. The native control chrome stays dark on every route
   under the unified #2955 palette. */
.reconcile-tag-form select,
.reconcile-tag-form input[type="text"],
.reconcile-tag-form textarea {
  font-family: inherit;
  font-size: var(--fs-base);
}
.reconcile-tag-form select { min-width: 12rem; }
/* The why box on a merged attention row (#1412). Tag-first means the
   facet picker leads and this follows, so it takes the full remaining
   width and wraps to its own line on a narrow viewport rather than
   squeezing the picker. Surface / border / focus come from the shared
   .input skin above; these are the reconcile-only deltas. */
.reconcile-ask { flex: 1 1 22rem; }
.reconcile-ask textarea {
  width: 100%;
  resize: vertical;
}
/* The reconcile inbox is a progressive review queue: every trade is a
   compact disclosure row and only the first unresolved item opens on
   render. Its field and action composition lives with the route in the
   SPA stylesheet (#2585 D14). */
.reconcile-task-list {
  border-top: 1px solid var(--border);
  margin-top: var(--space-4);
}
.reconcile-task {
  border-bottom: 1px solid var(--border);
}
.reconcile-task:last-child { border-bottom: none; }
.reconcile-task-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 3rem;
  padding: var(--space-3) var(--space-6) var(--space-3) 0;
  cursor: pointer;
  list-style: none;
  position: relative;
}
.reconcile-task-head::-webkit-details-marker { display: none; }
.reconcile-task-head::after {
  content: "";
  position: absolute;
  right: var(--space-1);
  top: 50%;
  width: var(--space-2);
  height: var(--space-2);
  margin-top: calc(-1 * var(--space-2));
  border-right: 2px solid var(--text-dim);
  border-bottom: 2px solid var(--text-dim);
  transform: rotate(-45deg);
}
.reconcile-task[open] > .reconcile-task-head::after {
  margin-top: calc(-1 * var(--space-1));
  transform: rotate(45deg);
}
.reconcile-task-head:hover::after { border-color: var(--accent); }
.reconcile-task-trade { min-width: 0; }
.reconcile-task-needs {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-left: auto;
}
.reconcile-task-needs-label {
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
}
@media (max-width: 640px) {
  .reconcile-task-head {
    align-items: flex-start;
    flex-direction: column;
  }
  .reconcile-task-needs {
    justify-content: flex-start;
    margin-left: 0;
  }
  .reconcile-dismiss {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}
.capture-panel {
  box-sizing: border-box;
  width: 100cqw;
  padding: var(--space-4);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.capture-form {
  display: grid;
  grid-template-columns:
    minmax(14rem, 18rem) minmax(min(20rem, 100%), 1fr);
  align-items: start;
  gap: var(--space-3);
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}
.capture-form legend {
  grid-column: 1 / -1;
  width: 100%;
  margin-bottom: var(--space-3);
  padding: 0 0 var(--space-2);
  border-bottom: 1px solid var(--border);
  color: var(--text);
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-medium);
}
.capture-form label { width: 100%; min-width: 0; }
.capture-form.capture-form-reason-only label { grid-column: 1 / -1; }
.capture-form select,
.capture-form textarea {
  width: 100%;
  min-width: 0;
  max-width: 100%;
}
.capture-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-top: var(--space-3);
}
.helper-prompt-disclosure > summary {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 44px;
  cursor: pointer;
  list-style: none;
}
.helper-prompt-disclosure > summary::-webkit-details-marker { display: none; }
.helper-prompt-disclosure > summary::after {
  content: "▸";
  flex: 0 0 auto;
  margin-left: auto;
  color: var(--text-dim);
}
.helper-prompt-disclosure[open] > summary::after { transform: rotate(90deg); }
.helper-prompt-summary-title {
  color: var(--text);
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
}
.helper-prompt-summary-hint {
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
}
.helper-prompt-body {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
}
.helper-prompt-body .muted-note { margin: 0; }
.helper-prompt-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: var(--space-3);
}
.helper-prompt-preview {
  display: block;
  margin-top: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius);
  background: var(--surface-2);
  white-space: normal;
  overflow-wrap: break-word;
}
.capture-batch-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
}
.capture-batch-footer .muted-note { margin: 0; }
@media (max-width: 640px) {
  .capture-panel { padding: var(--space-3); }
  .capture-form { grid-template-columns: minmax(0, 1fr); }
  .capture-batch-footer {
    align-items: stretch;
    flex-direction: column;
  }
  .helper-prompt-summary-hint { display: none; }
  .helper-prompt-actions .btn { width: 100%; }
  .capture-batch-footer .btn { min-height: 44px; }
}
/* The prompt heading the thesis cell, sitting above its own form row.
   Reads as a label, not a link: the affordance is the form below. */
.capture-prompt {
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
}
/* "No read on this one" (#1410). A quiet text-link affordance, not a
   button: dismissing is the secondary path out of the row and must not
   compete with Save. Matches .reconcile-note-toggle > summary. */
.reconcile-dismiss {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font-family: inherit;
  font-size: var(--fs-base-sm);
  color: var(--text-dim);
}
.reconcile-dismiss:hover { color: var(--accent); }
/* Close-note disclosure inside each untagged row (#731): the optional
   close note is hidden behind a quiet text-link summary so the default
   row reads as one tidy line; the field reveals on demand. */
.reconcile-note-toggle > summary {
  cursor: pointer;
  list-style: none;
  font-size: var(--fs-base-sm);
  color: var(--text-dim);
}
.reconcile-note-toggle > summary::-webkit-details-marker { display: none; }
.reconcile-note-toggle > summary:hover { color: var(--accent); }
.reconcile-note-toggle[open] > summary { margin-bottom: var(--space-2); }
.reconcile-note-toggle > *:not(summary) { margin-top: var(--space-2); }
/* Linked-trades history disclosure (#600): the whole "Linked trades"
   section collapses by default so the inbox leads with the actionable
   worklists. The summary carries the section heading and reads like the
   card's other <h2> headings, with a disclosure affordance. Sits in a
   .card. The unlinked-closes disclosure (#1406) shares the shape: an
   informational section that must not compete with the action queues. */
.reconcile-linked-disclosure > summary,
.reconcile-unlinked-disclosure > summary {
  cursor: pointer;
  list-style: none;
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  line-height: var(--lh-heading);
  color: var(--text);
  padding-right: var(--space-5);
  position: relative;
}
.reconcile-linked-disclosure > summary::-webkit-details-marker,
.reconcile-unlinked-disclosure > summary::-webkit-details-marker { display: none; }
.reconcile-linked-disclosure > summary::after,
.reconcile-unlinked-disclosure > summary::after {
  content: "";
  position: absolute;
  right: 0.25rem;
  top: 50%;
  width: 0.5rem;
  height: 0.5rem;
  margin-top: -0.35rem;
  border-right: 2px solid var(--text-dim);
  border-bottom: 2px solid var(--text-dim);
  transform: rotate(-45deg);
}
.reconcile-linked-disclosure[open] > summary::after,
.reconcile-unlinked-disclosure[open] > summary::after {
  margin-top: -0.15rem;
  transform: rotate(45deg);
}
.reconcile-linked-disclosure > summary:hover::after,
.reconcile-unlinked-disclosure > summary:hover::after { border-color: var(--accent); }
.reconcile-linked-disclosure[open] > summary,
.reconcile-unlinked-disclosure[open] > summary { margin-bottom: var(--space-4); }
/* Shared Journal page identity and symbol links, also used by the React
   route bodies. Keep these base styles alongside the shared shell. */
.journal-page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4) var(--space-6);
  margin-bottom: var(--space-4);
}
.journal-page-header .lede { margin-bottom: 0; }
.journal-symbol-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  text-decoration: none;
}
@media (max-width: 640px) {
  .journal-page-header {
    flex-direction: column;
    align-items: stretch;
  }
  .journal-symbol-link { min-height: 2.75rem; }
}
/* Filter disclosure (#625): filters sit below the headline numbers and
   stay collapsed until reached for. Open by default when a non-default
   filter is active so the applied scope stays visible. */
.scorecard-filters-disclosure { margin-bottom: var(--space-4); }
.insight-card {
  border: 1px solid var(--accent);
  /* Inset/recessed callout: the insight card uses the canvas inside a
     working panel and an accent edge instead of elevation. */
  border-radius: var(--radius);
  background: var(--bg);
  padding: var(--space-5) var(--space-5);
}
/* Page-level scorecard disclaimer (#388 / #840): a muted past-performance
   + not-advice note under the real card, free or Pro. */
.scorecard-disclaimer {
  margin-top: var(--space-4);
  font-size: var(--fs-micro);
}

/* Read-only code / JSON snapshot block. Pre + monospace +
   scrollable surface for verbatim text the analyst recorded
   (notes appended to a journal entry; intent-params / rule_refs
   captured at fill time; rendered skill Markdown). The
   ``.snapshot-note`` helper renders the explanatory caption
   above a ``.code-block`` (e.g. "Snapshot at record time"). */
.code-block {
  background: var(--surface-2);
  padding: var(--space-3);
  border-radius: var(--radius);
  max-height: 24rem;
  overflow: auto;
  white-space: pre-wrap;
  font-size: var(--fs-base-sm);
  font-family: var(--font-mono);
  line-height: 1.5;
  margin: 0;
}
.snapshot-note {
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
  margin: 0 0 0.5rem 0;
}
.record-snapshot {
  margin-top: var(--space-3);
}
.record-snapshot > summary {
  cursor: pointer;
  list-style: none;
  font-weight: var(--fw-medium);
  color: var(--text-dim);
}
.record-snapshot > summary::-webkit-details-marker { display: none; }
.record-snapshot > summary::before {
  content: "▸";
  display: inline-block;
  margin-right: var(--space-2);
}
.record-snapshot[open] > summary::before { transform: rotate(90deg); }
.record-snapshot > summary:hover { color: var(--accent); }
.record-snapshot > *:not(summary) { margin-top: var(--space-2); }
/* Disclosure-summary styling for the recurring "open the
   advanced editor" pattern used by connected-apps, credentials,
   setup, and onboarding. ``-aside`` is the parenthetical hint
   after the summary text. */
.disclosure-summary {
  display: flex;
  align-items: center;
  min-height: 44px;
  cursor: pointer;
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  color: var(--text);
}
.disclosure-summary-aside {
  font-weight: var(--fw-regular);
  margin-left: var(--space-2);
  font-size: var(--fs-base-sm);
}
/* "Label + copyable value + copy button" row pattern used by the
   credentials-shown-once success page in connected-apps. The
   value span flexes to 18rem so the copy button sits beside it
   on desktop and wraps below it on phones. */
.copy-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  word-break: break-all;
}
.copy-row > .value { flex: 1 1 18rem; }
/* Last-resort copy target. The shared handler reveals this read-only
   textarea only after both clipboard writes fail and a copy button has
   no visible .copy-row value to select. It spans its container so long
   commands and multi-line snippets remain readable and selectable. */
.copy-fallback-value {
  flex: 1 1 100%;
  width: 100%;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  line-height: 1.5;
  resize: vertical;
}
/* A copy-row carrying a sentence rather than an identifier (#1462:
   the first question the setup funnel and the connect walkthroughs
   hand over). ``break-all`` above is right for a URL or a CLI command
   and wrong for prose, which it snaps mid-word ("how does the chart
   read int / o it today?"). */
.copy-row.prose { word-break: normal; overflow-wrap: break-word; }
.copy-row.tinted {
  background: var(--surface-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
}
/* Unstyled list inside a ``<dl><dd>`` — kills the default
   margin / list-style so a short bullet list of redirect URLs
   sits flush against the term. */
.flush-list { margin: 0; padding-left: var(--space-4); }

/* Sit a paragraph or heading flush — the wrapping ``.copy-row``
   already supplies its own spacing, so the inner element should
   not add a default block margin. */
.flush { margin: 0; }
/* Tinted code snippet pre — onboarding's "paste this into your
   AI client's config" block. Same surface tint as
   ``.endpoint-display`` but pre-wraps preserved verbatim
   (whitespace:pre) and a horizontal scrollbar for long lines. */
.snippet-block {
  background: var(--surface-2);
  padding: var(--space-3);
  border-radius: var(--radius);
  overflow-x: auto;
  margin: var(--space-3) 0 0;
  white-space: pre;
}
.install-hint { font-size: var(--fs-base); }
/* The waitlist form on the landing-notify document and the reviewed
   campaign home variants (#2744): a form.form-stack, like the sign-in and
   reviewer forms, with one text-width email field. Only its distance from
   the lede above it is local. */
.notify-me-form { margin-top: var(--space-4); }

.disclosure-summary.plain {
  cursor: pointer;
  font-size: inherit;
  color: inherit;
  font-weight: var(--fw-bold);
}
/* The paid first-workflow renderer is scoped under .setup-page. The Free
   first-value journey reuses the generic setup-stepper classes and keeps its
   separate compact milestone treatment. */
.setup-page { min-width: 0; }

/* Detail-page reference key: the raw kebab-case slug shown mono
   directly under the humanized <h1>, mirroring the catalog row so a
   power user can still cite the id (#1349). */
.rule-slug {
  margin: var(--space-1) 0 var(--space-3) 0;
  font-size: var(--fs-base-sm);
  color: var(--text-dim);
}

/* ===========================================================
   Landing-interstitial (per-AI-client "not wired up yet" page)
   =========================================================== */
.interstitial-aside-base {
  margin-top: var(--space-2);
  font-size: var(--fs-base);
}

/* ===========================================================
   OAuth consent screen (/oauth/authorize)
   =========================================================== */
.oauth-client-logo {
  width: 48px;
  height: 48px;
  border-radius: 8px;
  background: var(--surface-2);
  object-fit: contain;
}
.oauth-client-header {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.oauth-client-header > div { min-width: 0; overflow-wrap: anywhere; }
.oauth-client-subhead { font-size: var(--fs-base-sm); }
.oauth-scopes-heading {
  font-size: var(--fs-base);
  margin-top: var(--space-6);
}
.oauth-scopes-list {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-6);
}
.oauth-scopes-note { font-size: var(--fs-base-sm); }
.oauth-decision-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-4);
}
.oauth-scope-desc { font-size: var(--fs-base-sm); }
.oauth-scope-row {
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--border);
}

/* PS6: one bounded task per first-party form, decision, or result. These
   widths are reading columns, not additional themes or route capabilities. */
.card.document-task {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  gap: var(--space-6);
  max-width: 36rem;
  margin-inline: auto;
  padding: var(--space-8);
  border: 0;
  border-radius: var(--radius-lg);
  overflow-wrap: anywhere;
}
.card.document-task > *,
.card.document-task > .muted-note { margin-block: 0; }
.card.document-task > :is(p, ul) { line-height: var(--lh-prose); }
.document-task .btn { min-block-size: var(--control-target); }
.card.auth-card,
.card.notify-card { max-width: 28rem; }
.card.oauth-card { max-width: 42rem; }
.card.consent-card { max-width: 46rem; }
body.layout-sidebar .document-task { margin-inline: 0; }
/* A pending or refused OAuth projection has no verified sidebar. Its neutral
   frame must not reserve the rail gutter from the static document body. */
body.layout-sidebar .document-frame main,
body.layout-sidebar .document-frame .footer { margin-left: 0; }
body.layout-sidebar .document-frame .shell { max-width: 56rem; }
body.layout-sidebar .document-frame .document-task { margin-inline: auto; }
.document-task .signup-assurance {
  background: transparent;
  border: 0;
  border-top: 1px solid var(--border);
  border-radius: 0;
  padding: var(--space-4) 0 0 var(--space-5);
}
.document-task .oauth-scopes-list { margin-top: calc(-1 * var(--space-3)); }
.document-task .oauth-client-header { align-items: flex-start; }
.document-task .oauth-client-logo { flex: none; }
.document-task .oauth-scope-row {
  display: grid;
  gap: var(--space-1);
  padding-block: var(--space-3);
}
.document-task .consent-points {
  display: grid;
  gap: var(--space-4);
  padding-left: var(--space-6);
  border-left: 1px solid var(--border);
}
.document-task .consent-points li {
  margin: 0;
  line-height: var(--lh-prose);
}
.document-consent-form {
  display: grid;
  gap: var(--space-4);
  justify-items: start;
}
.document-consent-form .consent-agree {
  margin: 0;
  min-height: var(--control-target);
  line-height: var(--lh-prose);
}
.document-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}
.document-status-code {
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
  font-variant-numeric: tabular-nums;
}
@media (max-width: 640px) {
  .card.document-task,
  body.layout-sidebar .card.document-task { padding: var(--space-6); }
  .document-task h1 { font-size: var(--fs-h1-mobile); }
}

/* Sign-in and sign-up experience (docs/frontend-design-system.md). The two
   auth documents set their card beside one aria-hidden scene: a glass
   envelope and link, a dashed arc into a standing slate, and a lit floor.
   The scene holds no text and never sits behind text, so every line keeps
   its measured ground. It has one box in the data-free first paint and in
   every projected state, so the heading never moves when the form arrives.
   Its arrival plays once, when a loaded state mounts; the pending pose is
   that arrival's first frame, so a slow projection never replays it. Only
   the scene's own parts move, and every animation ends within 2.6s. */
.shell:has(> .auth-stage) {
  max-width: 64rem;
  container: auth-shell / inline-size;
}
.auth-stage {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  gap: var(--space-6);
}
.auth-stage > .auth-card {
  grid-row: 2;
  width: 100%;
  border: 1px solid color-mix(in srgb, var(--accent) 15%, var(--border));
  border-top-color: color-mix(in srgb, var(--accent) 45%, var(--border));
  filter: drop-shadow(0 0 var(--space-6) color-mix(in srgb, var(--accent) 6%, transparent));
}
.auth-stage .signup-assurance {
  list-style: none;
  padding-inline-start: 0;
}
.auth-stage .signup-assurance li {
  position: relative;
  padding-inline-start: var(--space-6);
}
.auth-stage .signup-assurance li::before {
  content: "";
  position: absolute;
  inset-inline-start: var(--space-1);
  top: 0.55em;
  width: 7px;
  height: 7px;
  rotate: 45deg;
  background: var(--accent);
}
.auth-scene {
  grid-row: 1;
  position: relative;
  width: 100%;
  max-width: 28rem;
  height: clamp(128px, 36vw, 208px);
  container-type: size;
  /* Not clip: axe clips an element's box only by a hidden overflow, and
     would otherwise read the floor's wide plane as lying over the card. */
  overflow: hidden;
  pointer-events: none;
  -webkit-mask-image: radial-gradient(closest-side, var(--bg) 72%, transparent);
  mask-image: radial-gradient(closest-side, var(--bg) 72%, transparent);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}
@container auth-shell (min-width: 56rem) {
  .auth-stage {
    grid-template-columns: 28rem minmax(0, 1fr);
    align-items: start;
    justify-items: stretch;
    column-gap: var(--space-12);
  }
  .auth-stage > .auth-card { grid-row: 1; grid-column: 1; }
  .auth-scene {
    grid-row: 1;
    grid-column: 2;
    max-width: none;
    height: 30rem;
    position: sticky;
    top: var(--space-8);
  }
}
.auth-scene::before,
.auth-scene::after {
  content: "";
  position: absolute;
  inset: 0;
}
/* Jade light behind the slate, information haze above the envelope, the
   rings of light under the slate's foot, and a faint pin lattice. */
.auth-scene::before {
  background:
    radial-gradient(22cqh 6cqh at calc(50% + 17cqh) 78cqh, color-mix(in srgb, var(--accent) 23%, transparent) 0 22%, color-mix(in srgb, var(--accent) 6%, transparent) 36%, transparent 40% 52%, color-mix(in srgb, var(--accent) 19%, transparent) 54% 57%, transparent 60% 74%, color-mix(in srgb, var(--accent) 11%, transparent) 76% 78.5%, transparent 81%),
    radial-gradient(40cqh 11cqh at calc(50% + 17cqh) 78cqh, transparent 86%, color-mix(in srgb, var(--accent) 7%, transparent) 88% 90%, transparent 93%),
    radial-gradient(64cqh 50cqh at calc(50% + 14cqh) 48cqh, color-mix(in srgb, var(--accent) 14%, transparent), transparent 72%),
    radial-gradient(70cqh 46cqh at calc(50% - 30cqh) 22cqh, color-mix(in srgb, var(--info) 7%, transparent), transparent 72%);
}
.auth-scene::after {
  background: radial-gradient(color-mix(in srgb, var(--border-strong) 55%, transparent) 0.16cqh, transparent 0.26cqh) 0 0 / 4.5cqh 4.5cqh;
  -webkit-mask-image: radial-gradient(60cqh 40cqh at 50% 34cqh, var(--bg), transparent);
  mask-image: radial-gradient(60cqh 40cqh at 50% 34cqh, var(--bg), transparent);
}
.auth-scene > span { position: absolute; display: block; }
/* The floor recedes to a horizon behind the slate. */
.auth-scene-floor {
  left: 50%;
  bottom: 0;
  width: 240cqh;
  height: 600cqh;
  margin-inline-start: -120cqh;
  transform-origin: 50% 100%;
  transform: perspective(110cqh) rotateX(64deg);
  background:
    linear-gradient(90deg, color-mix(in srgb, var(--accent) 18%, transparent) 0.35cqh, transparent 0.35cqh) calc(50% + 4cqh) 0 / 12cqh 12cqh,
    linear-gradient(color-mix(in srgb, var(--accent) 18%, transparent) 0.35cqh, transparent 0.35cqh) 0 100% / 12cqh 12cqh;
  -webkit-mask-image: radial-gradient(70% 16% at 56% 100%, var(--bg), transparent);
  mask-image: radial-gradient(70% 16% at 56% 100%, var(--bg), transparent);
}
/* A standing glass slate with a lit rim, and an older one behind it.
   Sign-in's slate carries abstract writing; sign-up's is blank. */
.auth-scene-slate {
  left: calc(50% + 2cqh);
  top: 32cqh;
  width: 30cqh;
  height: 46cqh;
  box-sizing: border-box;
  border: 0.32cqh solid color-mix(in srgb, var(--accent) 41%, var(--border));
  border-radius: 2.4cqh;
  transform-origin: 50% 100%;
  transform: perspective(150cqh) rotateY(-28deg) rotateX(3deg);
  background:
    linear-gradient(color-mix(in srgb, var(--text-dim) 55%, transparent), color-mix(in srgb, var(--text-dim) 55%, transparent)) 18% 31% / 64% 1cqh no-repeat,
    linear-gradient(color-mix(in srgb, var(--text-dim) 45%, transparent), color-mix(in srgb, var(--text-dim) 45%, transparent)) 18% 40% / 56% 1cqh no-repeat,
    linear-gradient(color-mix(in srgb, var(--text-dim) 35%, transparent), color-mix(in srgb, var(--text-dim) 35%, transparent)) 18% 49% / 38% 1cqh no-repeat,
    linear-gradient(160deg, color-mix(in srgb, var(--surface-2) 91%, var(--accent)), color-mix(in srgb, var(--surface) 82%, transparent));
  filter: drop-shadow(0 2cqh 3cqh var(--bg));
}
.auth-stage-signup .auth-scene-slate-front {
  background:
    repeating-linear-gradient(90deg, color-mix(in srgb, var(--text-dim) 45%, transparent) 0 3cqh, transparent 3cqh 4.6cqh) 18% 38% / 64% 0.8cqh no-repeat,
    repeating-linear-gradient(90deg, color-mix(in srgb, var(--text-dim) 35%, transparent) 0 3cqh, transparent 3cqh 4.6cqh) 18% 52% / 64% 0.8cqh no-repeat,
    repeating-linear-gradient(90deg, color-mix(in srgb, var(--text-dim) 25%, transparent) 0 3cqh, transparent 3cqh 4.6cqh) 18% 66% / 64% 0.8cqh no-repeat,
    linear-gradient(160deg, color-mix(in srgb, var(--surface-2) 91%, var(--accent)), color-mix(in srgb, var(--surface) 82%, transparent));
}
.auth-scene-slate-back {
  left: calc(50% + 12cqh);
  top: 23cqh;
  border-color: var(--border);
  background: linear-gradient(160deg, color-mix(in srgb, var(--surface-2) 70%, transparent), color-mix(in srgb, var(--surface) 50%, transparent));
}
.auth-scene-slate-front::before,
.auth-scene-slate-front::after {
  content: "";
  position: absolute;
}
/* The slate's lit first line writes itself in when the link lands. */
.auth-scene-slate-front::before {
  left: 9.5%;
  top: 16%;
  width: 46%;
  height: 1.5cqh;
  background: var(--accent);
  box-shadow: 0 0 1.4cqh color-mix(in srgb, var(--accent) 25%, transparent);
  transform-origin: 0 50%;
}
.auth-scene-slate-front::after {
  inset: -0.32cqh;
  border-radius: inherit;
  box-shadow:
    0 0 4cqh color-mix(in srgb, var(--accent) 19%, transparent),
    inset 0 0 3cqh color-mix(in srgb, var(--accent) 10%, transparent);
}
/* The link rides a dashed arc from the envelope into the slate and lands
   with one ring on the floor. */
.auth-scene-pulse {
  left: calc(50% + 17cqh);
  top: 78cqh;
  width: 40cqh;
  height: 11cqh;
  margin: -5.5cqh 0 0 -20cqh;
  box-sizing: border-box;
  border: 0.35cqh solid color-mix(in srgb, var(--accent) 49%, transparent);
  border-radius: 50%;
  opacity: 0;
  transform: scale(1.25);
}
.auth-scene-arc {
  left: calc(50% - 22cqh);
  top: 38cqh;
  width: 34cqh;
  height: 34cqh;
  box-sizing: border-box;
  border: 0.4cqh dashed transparent;
  border-top-color: color-mix(in srgb, var(--accent) 49%, transparent);
  border-right-color: color-mix(in srgb, var(--accent) 49%, transparent);
  border-radius: 50%;
  transform: rotate(-45deg);
  opacity: 0.5;
  transition: opacity 160ms ease;
}
.auth-scene-spark {
  left: calc(50% - 5cqh);
  top: 55cqh;
  width: 0;
  height: 0;
  transform: rotate(180deg);
}
.auth-scene-spark::before {
  content: "";
  position: absolute;
  left: -18.1cqh;
  top: -1.1cqh;
  width: 2.2cqh;
  height: 2.2cqh;
  border-radius: 50%;
  background: radial-gradient(var(--text), var(--accent) 45%, transparent 72%);
  box-shadow: 0 0 2.4cqh 0.6cqh color-mix(in srgb, var(--accent) 28%, transparent);
  opacity: 0;
}
.auth-scene-envelope {
  left: calc(50% - 35cqh);
  top: 55.5cqh;
  width: 26cqh;
  height: 17cqh;
  box-sizing: border-box;
  border: 0.32cqh solid color-mix(in srgb, var(--accent) 31%, var(--border));
  border-radius: 1.6cqh;
  background: linear-gradient(170deg, color-mix(in srgb, var(--surface-2) 89%, var(--accent)), color-mix(in srgb, var(--surface) 92%, transparent));
  transform: perspective(120cqh) translateY(0) rotateY(24deg) rotateX(14deg) rotateZ(-8deg);
  filter: drop-shadow(0 1.6cqh 2.4cqh var(--bg));
}
.auth-scene-envelope::before,
.auth-scene-envelope::after {
  content: "";
  position: absolute;
}
.auth-scene-envelope::before {
  inset: 0 0 38%;
  background:
    linear-gradient(to top right, transparent calc(50% - 0.25cqh), color-mix(in srgb, var(--accent) 49%, transparent) 50%, transparent calc(50% + 0.25cqh)) 0 0 / 50% 100% no-repeat,
    linear-gradient(to top left, transparent calc(50% - 0.25cqh), color-mix(in srgb, var(--accent) 49%, transparent) 50%, transparent calc(50% + 0.25cqh)) 100% 0 / 50% 100% no-repeat;
}
/* A seal shows only once the link is sent. */
.auth-scene-envelope::after {
  left: 50%;
  top: 62%;
  width: 3.6cqh;
  height: 3.6cqh;
  margin: -1.8cqh 0 0 -1.8cqh;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 2cqh color-mix(in srgb, var(--accent) 30%, transparent);
  opacity: 0;
}
.auth-stage-sent .auth-scene-envelope::after { opacity: 1; }
.auth-scene-link {
  left: calc(50% - 30cqh);
  top: 39cqh;
  width: 16cqh;
  height: 7cqh;
  transform: translateY(0) rotate(-24deg) scale(1);
  filter: drop-shadow(0 0 1.4cqh color-mix(in srgb, var(--accent) 28%, transparent));
  opacity: 0.85;
  transition: opacity 160ms ease;
}
.auth-scene-link::before,
.auth-scene-link::after {
  content: "";
  position: absolute;
  top: 0;
  width: 9.5cqh;
  height: 7cqh;
  box-sizing: border-box;
  border: 1.1cqh solid var(--accent);
  border-radius: 3.5cqh;
}
.auth-scene-link::before { left: 0; }
.auth-scene-link::after { right: 0; }
.auth-stage-sent .auth-scene-link {
  opacity: 0;
  transform: translateY(9cqh) rotate(-8deg) scale(0.45);
}
.auth-scene-mote {
  width: 1.3cqh;
  height: 1.3cqh;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 1.6cqh color-mix(in srgb, var(--accent) 35%, transparent);
  transform: translateY(0);
}
.auth-scene-mote:nth-last-child(1) { left: calc(50% + 36cqh); top: 24cqh; background: var(--info); }
.auth-scene-mote:nth-last-child(2) { left: calc(50% + 4cqh); top: 17cqh; }
.auth-scene-mote:nth-last-child(3) { left: calc(50% - 40cqh); top: 30cqh; width: 0.9cqh; height: 0.9cqh; }
/* Typing an address lights the arc and the link. */
.auth-stage-form:has(#signin-email:not(:placeholder-shown)) .auth-scene-arc,
.auth-stage-form:has(#signin-email:not(:placeholder-shown)) .auth-scene-link { opacity: 1; }
.auth-stage-paused .auth-scene-arc,
.auth-stage-paused .auth-scene-link { opacity: 0.3; }
@media (prefers-reduced-motion: no-preference) {
  .auth-stage-pending .auth-scene-envelope {
    opacity: 0;
    transform: perspective(120cqh) translateY(9cqh) rotateY(24deg) rotateX(14deg) rotateZ(-18deg);
  }
  .auth-stage-pending .auth-scene-link {
    opacity: 0;
    transform: translateY(-7cqh) rotate(-64deg) scale(0.7);
  }
  .auth-stage-pending .auth-scene-arc,
  .auth-stage-pending .auth-scene-mote { opacity: 0; }
  .auth-stage-pending .auth-scene-slate-front::before { transform: scaleX(0); }
  .auth-stage-pending .auth-scene-slate-front::after { opacity: 0.35; }
  .auth-stage-form .auth-scene-envelope {
    animation: auth-rise 800ms cubic-bezier(0.2, 0.8, 0.2, 1) 50ms backwards;
  }
  .auth-stage-form .auth-scene-link {
    animation: auth-drop 700ms cubic-bezier(0.2, 0.8, 0.2, 1) 300ms backwards;
  }
  .auth-stage-form .auth-scene-arc {
    animation: auth-fade 500ms ease-out 600ms backwards;
  }
  .auth-stage-form .auth-scene-spark {
    animation: auth-travel 1000ms cubic-bezier(0.45, 0, 0.3, 1) 800ms backwards;
  }
  .auth-stage-form .auth-scene-spark::before {
    animation: auth-flash 1000ms linear 800ms backwards;
  }
  .auth-stage-form .auth-scene-pulse {
    animation: auth-pulse 800ms ease-out 1600ms backwards;
  }
  .auth-stage-form .auth-scene-slate-front::before {
    animation: auth-write 800ms cubic-bezier(0.6, 0, 0.2, 1) 1600ms backwards;
  }
  .auth-stage-form .auth-scene-slate-front::after {
    animation: auth-ignite 800ms ease-out 1600ms backwards;
  }
  .auth-stage-form .auth-scene-mote {
    animation: auth-float 700ms ease-out 1000ms backwards;
  }
  .auth-stage-form .auth-scene-mote:nth-last-child(2) { animation-delay: 1200ms; }
  .auth-stage-form .auth-scene-mote:nth-last-child(1) { animation-delay: 1400ms; }
  .auth-stage-sent .auth-scene-envelope {
    animation: auth-rise 800ms cubic-bezier(0.2, 0.8, 0.2, 1) 50ms backwards;
  }
  .auth-stage-sent .auth-scene-envelope::after {
    animation: auth-seal 400ms ease-out 1100ms backwards;
  }
  .auth-stage-sent .auth-scene-link {
    animation:
      auth-tuck 450ms ease-in 900ms backwards,
      auth-drop 600ms cubic-bezier(0.2, 0.8, 0.2, 1) 300ms backwards;
  }
  .auth-stage-sent .auth-scene-arc {
    animation: auth-fade 500ms ease-out 600ms backwards;
  }
  .auth-stage-sent .auth-scene-spark {
    animation: auth-travel 1000ms cubic-bezier(0.45, 0, 0.3, 1) 1000ms backwards;
  }
  .auth-stage-sent .auth-scene-spark::before {
    animation: auth-flash 1000ms linear 1000ms backwards;
  }
  .auth-stage-sent .auth-scene-pulse {
    animation: auth-pulse 800ms ease-out 1600ms backwards;
  }
  .auth-stage-sent .auth-scene-slate-front::before {
    animation: auth-write 800ms cubic-bezier(0.6, 0, 0.2, 1) 1600ms backwards;
  }
  .auth-stage-sent .auth-scene-slate-front::after {
    animation: auth-ignite 800ms ease-out 1600ms backwards;
  }
  .auth-stage-sent .auth-scene-mote {
    animation: auth-float 700ms ease-out 1200ms backwards;
  }
  .auth-stage-paused .auth-scene-slate-front::before,
  .auth-stage-paused .auth-scene-envelope,
  .auth-stage-paused .auth-scene-arc,
  .auth-stage-paused .auth-scene-link,
  .auth-stage-paused .auth-scene-mote {
    animation: auth-fade 600ms ease-out backwards;
  }
}
@keyframes auth-rise {
  from {
    opacity: 0;
    transform: perspective(120cqh) translateY(9cqh) rotateY(24deg) rotateX(14deg) rotateZ(-18deg);
  }
}
@keyframes auth-drop {
  from {
    opacity: 0;
    transform: translateY(-7cqh) rotate(-64deg) scale(0.7);
  }
  to {
    opacity: 1;
    transform: translateY(0) rotate(-24deg) scale(1);
  }
}
@keyframes auth-tuck {
  from {
    opacity: 1;
    transform: translateY(0) rotate(-24deg) scale(1);
  }
  to {
    opacity: 0;
    transform: translateY(9cqh) rotate(-8deg) scale(0.45);
  }
}
@keyframes auth-fade {
  from { opacity: 0; }
}
@keyframes auth-travel {
  from { transform: rotate(0deg); }
  to { transform: rotate(180deg); }
}
@keyframes auth-flash {
  0% { opacity: 0; }
  12%, 86% { opacity: 1; }
  100% { opacity: 0; }
}
@keyframes auth-pulse {
  0% {
    opacity: 0;
    transform: scale(0.3);
  }
  15% { opacity: 0.9; }
  100% {
    opacity: 0;
    transform: scale(1.25);
  }
}
@keyframes auth-write {
  from { transform: scaleX(0); }
}
@keyframes auth-ignite {
  from { opacity: 0.35; }
}
@keyframes auth-seal {
  from {
    opacity: 0;
    transform: scale(0.2);
  }
}
@keyframes auth-float {
  from {
    opacity: 0;
    transform: translateY(3cqh);
  }
}
@media (forced-colors: active) {
  .auth-scene { display: none; }
  .auth-stage > .auth-card { filter: none; }
}
@media print {
  .auth-scene { display: none; }
}

/* Status banner used by dashboard POST-redirect-GET surfaces (e.g. the
   reconcile inbox) — a bordered card-ish strip reporting the result of
   the last POST. The ``.flash-ok`` color above tints the success
   variant; the error variant borrows the danger accent. */
.flash {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-2) var(--space-3);
  margin: 0 0 var(--space-4);
  font-size: var(--fs-base-sm);
}
.flash.flash-error { color: var(--danger); border-color: var(--danger); }
.data-table em.col-empty { opacity: 0.7; }

/* Account-profile editor — full-width section under the tile grid.
   The briefing and per-account forms are stacks of labelled inputs /
   textareas, mirroring the credentials row styling but with multiline
   support. Each per-account form sits in its own native disclosure so the
   account list stays scannable without hiding controls from no-JS users. */
.profile { display: flex; flex-direction: column; gap: var(--space-5); }
.profile .blurb {
  margin: 0;
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
}

/* Before/after vignette — the contrast block on the landing page.
   Two side-by-side panels (vanilla AI vs. AI + Slatemark) with the
   "after" panel accent-tinted so the reader's eye lands there. The
   `.vignette-question` row above the grid carries the prompt being
   compared. Falls back to a single column under the .tile-grid
   breakpoint so phones stack cleanly. */
.vignette-question {
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  color: var(--text);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-2);
  border-left: 3px solid var(--text-dim);
  border-radius: 0 var(--radius) var(--radius) 0;
  margin: 0 0 var(--space-4);
}
.vignette-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
  gap: var(--space-4);
}
/* Retained vignette component. PS4 and PS5 own their public compositions;
   examples use a flat reading sequence rather than this panel. */
.vignette {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
/* Before panel: neutral left border + dim label (intentionally
   NOT --danger). Coloring vanilla AI as "danger" framed it as a
   competitor failure rather than a typical baseline; neutral
   reads as "this is what an AI without Slatemark says" without the
   comparative loaded coding. Also dodges the red/green a11y
   trap — deuteranopia / protanopia compress red/green contrast,
   so the text labels carry the meaning instead. */
.vignette.before {
  border-left: 3px solid var(--border);
}
.vignette.after {
  border-left: 3px solid var(--accent);
  background: var(--accent-wash);
}
.vignette-label {
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-bold);
  color: var(--text-dim);
}
.vignette.after .vignette-label { color: var(--accent); }
.vignette-quote {
  margin: 0;
  font-size: var(--fs-base);
  line-height: 1.55;
  color: var(--text);
}
.vignette-meta {
  margin: 0;
  font-size: var(--fs-base-sm);
  color: var(--text-dim);
  border-top: 1px solid var(--border);
  padding-top: var(--space-3);
}
/* Citation chips inside the after-vignette quote. Each chip pairs a
   value (tabular-nums monospace, accent left bar) with a small
   source label so the analyst output reads as sourced, not
   invented. That contrast is the visual punchline opposite the
   prose-only "before" panel. No background fill: the chip is a
   *typographic* mark, not a pill, so the surrounding prose still
   reads as prose. Value and source may wrap inside a narrow column; keeping
   them in one element preserves their association at enlarged text sizes. */
.cite {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-1);
  padding-left: var(--space-1);
  border-left: 2px solid var(--accent);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--text);
  white-space: normal;
  overflow-wrap: anywhere;
  max-width: 100%;
  flex-wrap: wrap;
}
.cite .cite-src { white-space: normal; }
.cite-src {
  font-family: var(--font-sans);
  font-size: var(--fs-micro);
  color: var(--text-dim);
  font-weight: var(--fw-medium);
  letter-spacing: 0;
}
/* In the segmented after-vignette the chip value carries the punchline
   ("every number is sourced"), so bold the value while the source label
   stays medium (#818 P2). Scoped to .vignette.after so the inline chips
   elsewhere keep their lighter typographic-mark weight. */
.vignette.after .cite { font-weight: var(--fw-bold); }
.vignette.after .cite-src { font-weight: var(--fw-medium); }

/* Compact numbered paths shared by the homepage's record loop and the
   setup value preview. The accent is reserved for the step index only,
   keeping the single-green discipline intact. */
.step-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-4);
  align-items: stretch;
}
.step {
  flex: 1 1 14rem;
  min-width: 0;
  max-width: 100%;
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-4) var(--space-5);
}
.step-num {
  flex: none;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: var(--fw-bold);
  font-size: var(--fs-md);
  line-height: 1.2;
  color: var(--accent);
}
.step-body { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; overflow-wrap: anywhere; }
.step-title { font-weight: var(--fw-bold); color: var(--text); }
.step-detail {
  margin: 0;
  font-size: var(--fs-base-sm);
  line-height: 1.5;
  color: var(--text-dim);
}
/* Four setup beats read as a deliberate 2 × 2 sequence. The generic
   flex strip lets a fourth item stretch across the whole second row,
   which overstates that beat and makes the sequence look accidental. */
@media (max-width: 640px) {
}

/* A one-sentence deployment caveat should not consume a full card
   (#1562 D15). Keep the canonical Availability copy in its established
   pre-close position, but render it as a compact labelled note. */
.availability-note {
  margin: 0 0 var(--space-4);
  padding-left: var(--space-3);
  border-left: 2px solid var(--border-strong);
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
}
.availability-note strong { color: var(--text); }

.hero-proof .cite,
.vignette-quote .cite { margin: 0 0.15em; }

/* Pricing tiers — same shape as .tile but with a price line and a
   feature list inside. The "featured" tier (Plus) is the page's focal
   point: it carries a multi-signal treatment (a "Recommended" badge,
   accent border, raised wash, and a soft shadow lift) so the eye lands
   there first. Color alone never carries the featured state — issue
   #819 found the old hue-only differentiation was invisible on the
   dark surface and undetectable to low-vision / colorblind users; the
   text badge fixes the design and the a11y gap at once. Tier cards
   stack on mobile. */
.tier-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-6);
  /* Vertical room for the badge that overhangs the featured card's
     top edge (it's translated up by half its own height). */
  padding-top: var(--space-3);
}
/* Shared-baseline tier rows (#1300 P0). The two asks must sit on one
   eyeline, so each card is a row subgrid over the parent grid: six
   rows — name / price / tagline / CTA / risk reversal / features — each
   sized to the tallest card, which pins the Free and Plus CTAs to the
   exact same y. Free leaves the risk-reversal row empty so both feature
   lists begin below the Plus cancellation/retention note.
   The card order puts the CTA *above* the feature list (price ->
   ask -> evidence), so the ~250px void that #819 hit (bottom-anchored
   CTA under Free's much shorter bullet list, via stretch +
   margin-top:auto) can't reopen: the only slack row is the trailing
   feature list, where extra space reads as list whitespace, not a
   detached button. Browsers without subgrid drop the
   grid-template-rows declaration and fall back to a per-card grid —
   same visual order, CTAs a few px apart at worst. The codebase
   already leans on subgrid (.catalog-row). */
.tier {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-6) var(--space-6) var(--space-5);
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 6;
  align-content: start;
  gap: var(--space-3);
}
.tier.featured {
  position: relative;
  border: 1px solid var(--accent);
  background: var(--accent-wash-strong);
}
/* Featured-tier "Recommended" pill — solid accent with the same dark
   --on-accent text the filled .btn uses (AA-passing on accent green).
   Overhangs the card's top edge so it reads as a ribbon, not a list
   item. */
.tier-badge {
  position: absolute;
  top: 0;
  right: var(--space-5);
  transform: translateY(-50%);
  background: var(--accent);
  color: var(--on-accent);
  font-size: var(--fs-micro);
  font-weight: var(--fw-bold);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
.tier-name {
  /* Plan names keep their authored title case and use the marketing
     subheading step instead of the compact label role. */
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  color: var(--text);
}
.tier.featured .tier-name { color: var(--accent); }
.tier-price {
  font-family: var(--font-mono);
  font-size: var(--fs-2xl);
  font-weight: var(--fw-bold);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum", "zero";
  color: var(--text);
  line-height: 1.1;
  letter-spacing: -0.01em;
  margin: 0;
}
.tier-price .per { font-size: var(--fs-base-sm); color: var(--text-dim); font-weight: var(--fw-regular); }
.tier-tagline {
  font-size: var(--fs-base);
  color: var(--text-dim);
  margin: 0;
}
.tier > .muted-note {
  grid-row: 5;
  margin: 0;
}
.tier-features {
  grid-row: 6;
  list-style: none;
  padding: 0;
  margin: var(--space-2) 0 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  font-size: var(--fs-base-sm);
}
.tier-features li {
  display: flex;
  gap: var(--space-2);
  color: var(--text);
}
.tier-features li::before {
  content: "✓";
  color: var(--accent);
  font-weight: 700;
  flex-shrink: 0;
}
.tier-features li.muted { color: var(--text-dim); }
.tier-features li.muted::before { color: var(--text-dim); content: "·"; }
/* The CTA is row 4 of the tier subgrid (see .tier above), directly
   under the tagline — no bottom-anchoring auto margin, which is what
   opened the #819 void when the rows were a flex column. */
.tier-cta { padding-top: var(--space-2); }
/* The pricing CTA is the page's primary conversion target, so give it
   a roomier touch target than the default .btn (#819): taller vertical
   padding and full card width so it's an easy tap on mobile. */
.tier-cta .btn {
  display: block;
  text-align: center;
  padding-top: var(--space-3);
  padding-bottom: var(--space-3);
}

/* Horizontal-scroll wrapper for wide tables that can't shrink to a
   phone viewport without losing meaning (catalogs of credentials,
   skills, etc.). Pair with a `min-width` on the inner table so the
   columns keep usable width when the wrapper scrolls. */
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.scroll-x > table { min-width: 32rem; }

/* A documentary excerpt, using the journal's label/value grammar. The
   example carries no live data, interactive controls or model conclusion. */
.journal-preview-title { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.journal-preview-facts { display: grid; grid-template-columns: minmax(0, 9rem) minmax(0, 1fr); gap: var(--space-3) var(--space-4); }
.journal-preview-facts dt { color: var(--text-dim); }
.journal-preview-facts dd { margin: 0; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.journal-preview { container: journal-preview / inline-size; }
@container journal-preview (max-width: 28rem) {
  .journal-preview-facts { grid-template-columns: minmax(0, 1fr); gap: var(--space-1); }
  .journal-preview-facts dt { margin-top: var(--space-3); }
}

/* Mobile breakpoint. Phones land here (~iPhone 13/14 logical width
   is 390px; the small Plus/Mini sizes are 320–375). The desktop
   layout assumes ~700px+ before the public topbar fits its brand,
   navigation, and account action on one row, so anything narrower
   needs to stack. */
@media (max-width: 640px) {
  .topbar {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
  }
  .topbar-right {
    width: 100%;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-3);
    justify-content: flex-start;
  }
  .topbar nav { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3); }
  /* Touch-target bump (#627, WCAG 2.5.5 / Apple HIG ≥44px): the public
     top-nav links (Features / Pricing / Sign in)
     are bare text on desktop; on phones they need vertical padding so
     the tap target clears 44px. 14px text × 1.5 line-height + 12px × 2
     padding ≈ 45px. */
  .topbar nav a:not(.btn) { margin-left: 0; font-size: var(--fs-base-sm); display: inline-block; padding: var(--space-3) 0; }
  .shell { padding: 0 var(--space-4); }
  main { padding: var(--space-6) 0 var(--space-12); }
  /* Mobile rescales: h1 stays distinctly larger than body, h2 stays
     larger than body, lede stays heavier than body via line-height
     even when sizes converge. Don't drop h2 to 1rem — collapses
     against body and the hierarchy disappears. */
  h1 { font-size: var(--fs-h1-mobile); }
  h2 { font-size: var(--fs-md); }
  p.lede { font-size: var(--fs-base); margin-bottom: var(--space-5); }
  .card { padding: var(--space-4); }
  .tile { padding: var(--space-4); }
  .tile-grid { gap: var(--space-3); }
  /* Touch-target bumps (issue #426). Apple HIG / WCAG 2.5.5 both
     ask for ≥44px on touchable targets. Desktop padding is fine
     for pointer; on phones the same controls need to be thumb-sized.
     ``.nav-item`` and ``.btn`` are the two surfaces the dashboard
     leans on most heavily. */
  .nav-item { padding: var(--space-3); }
  .btn { padding: var(--space-3) var(--space-4); }
  .btn.secondary { padding: var(--space-3) var(--space-4); }
  /* ``.btn.small`` (e.g. the reconcile inbox tag/link/unlink actions,
     #731/#600) stays compact on desktop but needs the same ≥44px tap
     target on touch — bump min-height + padding inside the media query
     only so desktop is untouched. */
  .btn.small {
    min-height: 44px;
    padding: var(--space-2) var(--space-4);
  }
  /* Hamburger nudge: 2rem (32px) on desktop is fine for pointer
     but undersized for touch — bump to 2.75rem (44px) on mobile. */
  .hamburger { width: 2.75rem; height: 2.75rem; }
  .footer .shell { flex-wrap: wrap; }
  /* The footer links run beyond one phone-width row — the lone
     horizontal-overflow source at phone widths (pre-existing;
     spotted during the #1300 mobile pass). Let the row wrap. */
  .faq { grid-template-columns: 1fr; gap: var(--space-1) 0; }
  .faq dt { font-size: var(--fs-base); margin-top: var(--space-3); }
  .faq dt:first-of-type { margin-top: 0; }
  .faq dd { padding-bottom: var(--space-1); border-bottom: 1px solid var(--border); }
  .faq dd:last-of-type { border-bottom: 0; padding-bottom: 0; }
}

/* A signed-in marketing page loses 14rem to the sidebar and 2rem more to shell/card
   padding. Stack its FAQs until they have the same room as the public 640px
   breakpoint; otherwise the fixed question gutter crushes the answer column. */
@media (min-width: 641px) and (max-width: 896px) {
  body.layout-sidebar.layout-marketing .faq { grid-template-columns: 1fr; gap: var(--space-1) 0; }
  body.layout-sidebar.layout-marketing .faq dt { font-size: var(--fs-base); margin-top: var(--space-3); }
  body.layout-sidebar.layout-marketing .faq dt:first-of-type { margin-top: 0; }
  body.layout-sidebar.layout-marketing .faq dd { padding-bottom: var(--space-1); border-bottom: 1px solid var(--border); }
  body.layout-sidebar.layout-marketing .faq dd:last-of-type { border-bottom: 0; padding-bottom: 0; }
}

/* The header itself supplies the available inline size. Container-query rem
   units follow enlarged text, unlike viewport media-query rem units. The same
   native disclosure becomes an inline navigation row only when its text fits. */
.topbar.collapsible {
  container: public-header / inline-size;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: var(--space-2) var(--space-3);
}
.topbar.collapsible .brand { margin-right: auto; }
.topbar.collapsible .topbar-right,
.topbar.collapsible .public-menu,
.topbar.collapsible .public-menu::details-content { display: contents; }
.topbar.collapsible .hamburger {
  display: inline-flex;
  order: 2;
  width: 2.75rem;
  height: 2.75rem;
  flex: none;
}
.topbar.collapsible nav { display: none; }
.topbar.collapsible .public-menu[open] > nav {
  display: flex;
  flex-direction: column;
  gap: 0;
  order: 10;
  flex-basis: 100%;
}
.topbar.collapsible nav a:not(.btn) {
  margin-left: 0;
  padding: var(--space-3) 0;
}
/* The open menu ends on the CTA at the body button's touch size. */
.topbar.collapsible nav .nav-cta {
  align-self: flex-start;
  margin-block: var(--space-2);
  padding: var(--space-3) var(--space-4);
  font-size: var(--fs-base);
  white-space: normal;
}
/* Large text on a narrow phone (#2744). The mark and the wordmark need
   about 9rem in one line, and 200% text on a 320px phone leaves 8rem
   inside the header's padding. The decorative mark drops once that row is
   9.5rem or narrower (the 9rem plus slack), so the wordmark stays whole;
   the mark is alt="" and aria-hidden, so no accessible name changes. The
   neutral header is a query container for this alone. The signed-in
   mobile topbar keeps its own threshold above, because its row also holds
   the menu control. */
.topbar:not(.collapsible):not(.mobile-only) { container: neutral-header / inline-size; }
@container neutral-header (max-width: 9.5rem) {
  .topbar:not(.collapsible):not(.mobile-only) .brand-mark { display: none; }
}
@container public-header (max-width: 9.5rem) {
  .topbar.collapsible .brand-mark { display: none; }
}
@container public-header (min-width: 43.75rem) {
  @supports selector(::details-content) {
    .topbar.collapsible .hamburger { display: none; }
    .topbar.collapsible .public-menu::details-content {
      content-visibility: visible;
    }
    .topbar.collapsible .public-menu > nav,
    .topbar.collapsible .public-menu[open] > nav {
      display: flex;
      flex-direction: row;
      flex-basis: auto;
      align-items: center;
      gap: var(--space-4);
      order: 0;
    }
    .topbar.collapsible nav a:not(.btn) { padding: 0; }
    .topbar.collapsible nav .nav-cta {
      margin-block: 0;
      padding: var(--space-1) var(--space-3);
      font-size: var(--fs-base-sm);
      white-space: nowrap;
    }
  }
}

.card .actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
}
fieldset {
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  padding: var(--space-3) var(--space-4);
  margin: 0 0 var(--space-4);
  min-width: 0;
}
/* Radio-card pickers use fieldset for semantics, not panel chrome. */
legend {
  padding: 0 var(--space-2);
  font-weight: var(--fw-bold);
  font-size: var(--fs-base-sm);
  color: var(--text);
}
input[readonly], textarea[readonly] {
  background: var(--surface);
  color: var(--text-dim);
  cursor: text;
}

/* Base h3/h4 scale (#1395 WS7). Only h1/h2 had element rules; bare
   <h3>/<h4> outside .tile fell to the UA's 700-weight defaults the
   h1/h2 comments explicitly avoid. */
h3 {
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  line-height: var(--lh-heading);
  margin: 0 0 var(--space-2);
}
h4 {
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  line-height: var(--lh-heading);
  margin: 0 0 var(--space-2);
}

/* Filled pills stay text-first: their visible status label (or signed P&L
   value) carries meaning without a generated symbol prefix. Semantic color
   supports scanning, while forced-colors mode below restores a boundary when
   alpha fills disappear. */

/* Labelled horizontal-scroll regions (#1395 WS7). Call sites add
   tabindex="0" + role="region" + a name so keyboard users can scroll
   and AT users know what the region holds; the focus ring marks the
   scrollable surface. */
.scroll-x:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Forced-colors (Windows High Contrast) baseline (#1395 WS7). The
   alpha-fill pills, checkbox-driven drawer, and accent focus ring
   otherwise lose their boundaries when the UA strips backgrounds. */
@media (forced-colors: active) {
  .pill { border: 1px solid CanvasText; }
  .btn { border: 1px solid ButtonText; }
  .banner { border: 1px solid CanvasText; }
  .nav-item[aria-current],
  .context-nav a[aria-current],
  .topbar nav a[aria-current="page"] { outline: 2px solid Highlight; }
  .banner-progress > span { background: Highlight; }
}

/* Reduced-motion escape hatch (WCAG 2.3.3, issue #533). The brief scrim
   opacity and control border-colour feedback stop for users who set the
   OS-level preference; the loading resolve runs only with no-preference. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto !important; }
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* Embedded chat surface (epic #638, Phase 1). Kept deliberately
   plain: the demo's job is to show the analyst frame, not to be a
   polished product chat. Radii are tokens (#1206), not literals, even
   though this gated-off surface is not a full skin member. */
.chat { max-width: 760px; margin: 0 auto; }
.chat-banner {
  background: var(--accent-bg);
  border: 1px solid var(--accent);
  color: var(--text);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius);
  font-size: var(--fs-base-sm);
  margin-bottom: var(--space-2);
}
.chat-transcript {
  min-height: 220px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: var(--space-2);
  margin-bottom: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  overflow-y: auto;
  max-height: 60vh;
}
.chat-empty { color: var(--text-dim); }
.chat-msg { padding: var(--space-1) var(--space-2); border-radius: var(--radius); }
.chat-msg p { margin: 0 0 0.4rem; white-space: pre-wrap; }
.chat-msg p:last-child { margin-bottom: 0; }
.chat-msg-footer { color: var(--text-dim); font-size: var(--fs-base-sm); }
.chat-msg-error p { color: var(--danger); }
.chat-form { display: flex; flex-direction: column; gap: var(--space-1); }
.chat-form textarea {
  width: 100%;
  font: inherit;
  resize: vertical;
}
.chat-form button { align-self: flex-end; }
.chat-tos { max-width: 640px; margin: 0 auto; }
.chat-tos-points { color: var(--text-dim); line-height: 1.6; }
.chat-tos-points li { margin-bottom: var(--space-1); }
.chat-tos-fine { font-size: var(--fs-base-sm); color: var(--text-dim); }

/* Long words remain readable when enlarged text leaves narrow prose tracks. */
body:not(.layout-sidebar) main { overflow-wrap: anywhere; }
.journal-preview .pill { white-space: normal; font-family: var(--font-sans); }

/* PS4: the public record uses the same working surface and factual rows as
   the journal. Scope composition to these pages; the shared frame, public
   navigation, and subsequent reading-page slices retain their own owners. */
.marketing-workspace { container: marketing-workspace / inline-size; max-width: 76rem; }
.marketing-workspace .btn,
.marketing-workspace summary { min-height: var(--control-target); align-content: center; }
.marketing-intro {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  align-items: start;
  gap: var(--space-12);
  padding-block: var(--space-8);
  margin-bottom: var(--space-8);
}
.marketing-intro > .hero {
  padding: 0;
  margin: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  min-width: 0;
}
.marketing-intro > .hero h1 { max-width: 16ch; }
.marketing-intro > .hero .lede { margin-bottom: var(--space-6); }
.marketing-intro .hero-cta { margin-block: var(--space-6) var(--space-3); }
.marketing-intro .hero-audience { margin-top: var(--space-6); }
.marketing-intro .hero-disclaimer { margin-top: var(--space-6); }
.marketing-intro > .journal-preview {
  min-width: 0;
  margin: 0;
  padding: var(--space-6);
  border: 0;
  border-radius: var(--radius-lg);
}
.marketing-intro .journal-preview-title { margin-block: var(--space-6); }
.record-symbol {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-bold);
  line-height: 1.2;
  margin-right: var(--space-2);
}
.marketing-intro .journal-preview-facts {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  margin-block: var(--space-4);
}
.marketing-home .marketing-intro { margin-bottom: 0; }
.marketing-home .home-context,
.marketing-home .home-trust {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  align-items: start;
  gap: var(--space-12);
  margin-bottom: 0;
}
.home-context h2,
.home-trust h2 { margin-top: 0; }
.home-context-copy > p,
.home-trust > div > p { max-width: var(--measure-prose); }
.home-context-note h3 { margin: 0 0 var(--space-4); font-size: var(--fs-md); }
.home-context-note dl {
  display: grid;
  grid-template-columns: 4rem minmax(0, 1fr);
  gap: var(--space-3) var(--space-4);
  margin-block: 0 var(--space-4);
}
.home-context-note dt { color: var(--text-dim); }
.home-context-note dd,
.home-context-note .muted-note { margin: 0; }
.home-trust > div > p:first-child { margin-top: 0; }
.record-event {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 3fr);
  gap: var(--space-3) var(--space-4);
  padding-block: var(--space-3);
  border-top: 1px solid var(--border);
  min-height: 3.25rem;
}
.record-event dt { margin: 0; font-size: var(--fs-base-sm); }
.record-event dd { font-size: var(--fs-base); line-height: var(--lh-body); }
.marketing-section {
  margin-block: 0 var(--space-8);
  padding-block: var(--space-8);
  border-top: 1px solid var(--border);
  min-width: 0;
}
.marketing-section > p { max-width: var(--measure-prose); }
.marketing-section .lede { margin-bottom: var(--space-6); }
.marketing-section .vignette-grid { gap: var(--space-6); }
.marketing-section .vignette {
  border: 0;
  border-radius: 0;
  background: transparent;
  padding: 0;
}
.marketing-section .vignette.after {
  padding-left: var(--space-6);
  border-left: 1px solid var(--border);
}
.marketing-section .vignette-question {
  max-width: var(--measure-prose);
  margin-block: var(--space-6);
}
.marketing-section .vignette-question,
.marketing-section .cite,
.marketing-section .step-num { font-family: var(--font-sans); font-variant-numeric: tabular-nums; }
.marketing-section .cite-src { font-size: var(--fs-base-sm); }
.marketing-section .tile-grid,
.feature-evidence { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-6); }
.marketing-section .tile {
  border: 0;
  border-radius: 0;
  background: transparent;
  padding: 0;
  max-width: var(--measure-prose);
}
.workflow-index { display: grid; gap: 0; }
.workflow-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  gap: var(--space-4) var(--space-6);
  padding-block: var(--space-4);
  border-top: 1px solid var(--border);
}
.workflow-row h3,
.workflow-row p,
.workflow-row ul { margin: 0; }
.workflow-row h3 { font-size: var(--fs-base); font-weight: var(--fw-bold); }
.workflow-row p { color: var(--text-dim); max-width: var(--measure-prose); }
.workflow-row h3 a { display: inline-flex; align-items: center; min-height: var(--control-target); }
.marketing-section .step-strip { padding: 0; margin: var(--space-6) 0 0; list-style: none; }
.marketing-section .step-strip { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.marketing-section .step { background: transparent; border: 0; border-radius: 0; padding: var(--space-4) 0; }
.marketing-disclosure {
  padding-block: var(--space-4);
  margin-bottom: var(--space-8);
  border-block: 1px solid var(--border);
  font-size: var(--fs-base-sm);
  color: var(--text-dim);
  max-width: var(--measure-support);
}
.marketing-disclosure > summary { min-height: var(--control-target); align-content: center; cursor: pointer; color: var(--text); }
.marketing-disclosure > p { margin-block: var(--space-3) 0; }
.marketing-disclosure + .marketing-section { border-top: 0; }
.feature-outcome { border-left: 2px solid var(--data-neutral); padding-left: var(--space-6); margin-top: var(--space-6); max-width: var(--measure-prose); }
.feature-outcome h3 { font-size: var(--fs-base); font-weight: var(--fw-bold); }
.marketing-features .feature-pillar {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  align-items: start;
  gap: var(--space-8);
  padding-block: var(--space-6);
  margin-block: 0;
}
.marketing-features .feature-lead,
.marketing-features .feature-detail { min-width: 0; }
.marketing-features .feature-detail > :first-child { margin-top: 0; }
.marketing-features .feature-outcome { padding-left: 0; border-left: 0; }
.marketing-heading { margin-bottom: var(--space-8); padding-block: var(--space-6); max-width: var(--measure-support); }
.marketing-pricing .pricing-heading { margin-bottom: var(--space-4); padding-bottom: 0; }
.marketing-pricing .pricing-heading h1 { font-size: var(--fs-2xl); line-height: 1.2; font-weight: var(--fw-bold); }
.marketing-pricing .pricing-plans { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-bottom: var(--space-8); }
.marketing-pricing .tier { border-color: var(--border); border-radius: var(--radius-lg); }
.marketing-pricing .tier.featured { background: var(--surface); border-color: var(--border-strong); }
.marketing-pricing .tier-name { color: var(--text); font-size: var(--fs-lg); margin: 0; }
.marketing-pricing .tier.featured .tier-name { color: var(--text); }
.marketing-pricing .tier-badge { background: var(--surface-2); color: var(--text); font-size: var(--fs-base-sm); }
.marketing-pricing .tier-price { font-family: var(--font-sans); font-weight: var(--fw-medium); line-height: 1.2; }
.marketing-pricing .pricing-closing { background: transparent; }
.marketing-pricing .faq dd { max-width: var(--measure-prose); line-height: var(--lh-prose); }
.marketing-campaign .campaign-task { max-width: 48rem; margin-inline: auto; border: 0; padding: var(--space-8) 0; background: transparent; }
.marketing-campaign .campaign-task .hero-cta { margin-top: var(--space-6); }
@container marketing-workspace (max-width: 50rem) {
  .marketing-intro { grid-template-columns: minmax(0, 1fr); gap: var(--space-8); }
  .marketing-intro > .hero h1 { max-width: 100%; }
  .marketing-home .home-context,
  .marketing-home .home-trust { grid-template-columns: minmax(0, 1fr); gap: var(--space-4); }
  .marketing-features .feature-pillar { grid-template-columns: minmax(0, 1fr); gap: var(--space-4); }
  .marketing-section .vignette-grid { grid-template-columns: minmax(0, 1fr); }
  .marketing-section .vignette.after { border-left: 0; border-top: 1px solid var(--border); padding: var(--space-6) 0 0; }
  .workflow-row { grid-template-columns: minmax(0, 1fr); gap: var(--space-2); }
  .marketing-section .step-strip { grid-template-columns: minmax(0, 1fr); }
}
@container journal-preview (max-width: 28rem) {
  .record-event { grid-template-columns: minmax(0, 1fr); gap: var(--space-1); }
  .record-event dt { margin: 0; }
}
@media (max-width: 899px) {
  .marketing-pricing .pricing-plans { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
  .marketing-intro { padding-block: var(--space-4); }
  .marketing-intro > .journal-preview { padding: var(--space-5); }
  .record-symbol { font-size: var(--fs-h1-mobile); }
  .marketing-pricing .pricing-heading h1 { font-size: var(--fs-h1-mobile); }
  .marketing-pricing .tier-name { font-size: var(--fs-md); }
}
/* Laptop-height windows. The two-column plans end about 786px down the
   page, and laptop browser windows run about 590 to 830px tall. Shorter
   windows tighten the space above the heading, the gap before the plans and
   the cards' rhythm so both whole cards share the first screen. The plan
   buttons keep their size, and the subgrid keeps both buttons and both
   feature lists on one line. */
@media (min-width: 900px) and (max-height: 840px) {
  .marketing-pricing .pricing-heading { padding-top: 0; }
  .marketing-pricing .pricing-heading .lede { margin-bottom: 0; }
  .marketing-pricing .pricing-plans { margin-top: 0; }
  .marketing-pricing .tier { padding: var(--space-5) var(--space-6) var(--space-4); gap: var(--space-2); }
  .marketing-pricing .tier-cta { padding-top: var(--space-1); }
  .marketing-pricing .tier-features { margin-top: var(--space-1); }
}
@media (min-width: 900px) and (max-height: 720px) {
  .marketing-pricing main { padding-top: var(--space-4); }
  .marketing-pricing .pricing-heading { margin-bottom: var(--space-2); }
  .marketing-pricing .tier-features { gap: var(--space-1); }
}

/* Home experience. The public Home is the one reviewed exception to the
   flat marketing grammar: a rotating set of fictional AI-client
   conversations beside an illustrative 3D price history. Everything here
   is CSS on script-free bytes. The illustration stays `aria-hidden`,
   carries a visible "Illustration" caption, never ticks like a live quote,
   and its fictional series is sideways so it cannot read as a performance
   claim. The static composition below is complete; motion lives only under
   `prefers-reduced-motion: no-preference`, animates opacity, transform or a
   motion-path offset alone so no layout moves, and the "Pause motion"
   control stops the conversation rotation, the ambient orbit and the
   source loop. docs/frontend-design-system.md records the exception and
   its limits. */
.marketing-home .marketing-intro {
  position: relative;
  isolation: isolate;
  grid-template-areas: "hero record" "stage record";
  grid-template-rows: auto 1fr;
  row-gap: 0;
}
.marketing-home .marketing-intro::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -6rem 0 -4rem;
  background:
    radial-gradient(30% 38% at 30% 76%, color-mix(in srgb, var(--accent) 9%, transparent), transparent 70%),
    radial-gradient(34% 42% at 72% 28%, color-mix(in srgb, var(--info) 7%, transparent), transparent 72%);
  pointer-events: none;
}
.marketing-home .marketing-intro > .hero { grid-area: hero; }
.marketing-home .marketing-intro > .home-chat {
  grid-area: record;
  position: relative;
  z-index: 2;
  border: 1px solid var(--border);
  background: var(--surface);
}
.marketing-home .market-stage-wrap {
  grid-area: stage;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-width: 0;
  min-height: 22rem;
}

/* The fictional AI-client window. Four fictional conversations share one
   stage cell, so the card keeps the tallest one's height and nothing moves
   when the examples change. Each one runs question, Slatemark tool calls,
   then the source- and time-labelled facts, with the question typed into
   the input at the bottom first. Statically the first example shows
   complete; a visually hidden radio group behind the chips below the stage
   picks another and stops the rotation. */
.marketing-home .home-chat-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--border);
}
.marketing-home .home-chat-dots { display: flex; gap: var(--space-2); }
.marketing-home .home-chat-dots > span {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  background: var(--surface-2);
}
.marketing-home .home-chat-client { color: var(--text-dim); font-size: var(--fs-base-sm); font-weight: var(--fw-medium); }
/* The connection chip: the pulse is decorative; the label carries it. */
.marketing-home .home-chat-conn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
  padding: var(--space-1) var(--space-3);
  border-radius: 999px;
  background: var(--accent-wash);
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  font-weight: var(--fw-medium);
}
.marketing-home .home-chat-pulse {
  position: relative;
  flex: none;
  width: 0.4375rem;
  height: 0.4375rem;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 50%, transparent);
}
.marketing-home .home-chat-pulse::after {
  content: "";
  position: absolute;
  inset: -0.25rem;
  border: 1px solid var(--accent);
  border-radius: 50%;
  opacity: 0;
}
.marketing-home .home-chat > h2 { margin-bottom: var(--space-4); }
.marketing-home .home-chat-stage { display: grid; margin: 0; padding: 0; list-style: none; }
.marketing-home .home-chat-example {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}
.marketing-home .home-chat-example + .home-chat-example { visibility: hidden; }
.marketing-home .home-chat-choice:checked ~ .home-chat-stage > .home-chat-example { visibility: hidden; }
.marketing-home #home-example-1:checked ~ .home-chat-stage > .home-chat-example:nth-child(1),
.marketing-home #home-example-2:checked ~ .home-chat-stage > .home-chat-example:nth-child(2),
.marketing-home #home-example-3:checked ~ .home-chat-stage > .home-chat-example:nth-child(3),
.marketing-home #home-example-4:checked ~ .home-chat-stage > .home-chat-example:nth-child(4) { visibility: visible; }
.marketing-home .home-chat-meta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
}
/* The question reads left to right with the rest of the transcript, its
   speaker named inline so it takes no line of its own. */
.marketing-home .home-chat-ask {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  color: var(--text);
}
.marketing-home .home-chat-ask::before,
.marketing-home .home-chat-reply::before {
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-medium);
}
.marketing-home .home-chat-ask::before { content: "You"; display: inline-block; margin-right: var(--space-2); }
.marketing-home .home-chat-reply::before { content: "Your AI"; display: block; padding-bottom: var(--space-1); }
.marketing-home .home-chat-tools { display: grid; gap: var(--space-1); margin: 0; padding: 0; list-style: none; }
.marketing-home .home-chat-tools > li {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--space-2);
  min-height: 1.75rem;
  padding-left: var(--space-6);
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
}
.marketing-home .home-chat-tools code { color: var(--text); overflow-wrap: anywhere; }
.marketing-home .home-chat-tools > li::before,
.marketing-home .home-chat-tools > li::after { content: ""; position: absolute; top: calc(50% - 0.4375rem); }
/* The pending ring shows only while a tool call runs. */
.marketing-home .home-chat-tools > li::before {
  left: 0;
  width: 0.875rem;
  height: 0.875rem;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  opacity: 0;
}
.marketing-home .home-chat-tools > li::after {
  left: 0.25rem;
  width: 0.375rem;
  height: 0.6875rem;
  border: solid var(--accent);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.marketing-home .marketing-intro .home-chat .journal-preview-facts { margin: 0; }
/* With room, the two facts sit side by side as tiles, which keeps the card
   short; a narrow card keeps them as rows. */
@container journal-preview (min-width: 30rem) {
  .marketing-home .home-chat-reply { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
  .marketing-home .home-chat-reply::before { grid-column: 1 / -1; padding-bottom: 0; }
  .marketing-home .home-chat-reply > .record-event {
    grid-template-columns: minmax(0, 1fr);
    align-content: start;
    gap: var(--space-1);
    min-height: 0;
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
  }
  .marketing-home .home-chat-reply .record-symbol { font-size: var(--fs-xl); }
}
/* A tile in a card just past that width is too narrow for the longest
   value, a price range, at that size; a step down keeps it on one line. */
@container journal-preview (min-width: 30rem) and (max-width: 34rem) {
  .marketing-home .home-chat-reply .record-symbol { font-size: var(--fs-lg); }
}
/* The input sits at the bottom of every example, as in an AI client. It is
   a picture of an input, hidden from assistive technology, with room for a
   two-line question so the box keeps one height across the examples. */
.marketing-home .home-chat-input {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
  min-height: 3.75rem;
  margin: auto 0 0;
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg);
  color: var(--text);
  font-size: var(--fs-base-sm);
  cursor: default;
}
.marketing-home .home-chat-input::after {
  content: "";
  position: absolute;
  inset: -1px;
  border: 1px solid var(--accent);
  border-radius: inherit;
  box-shadow: 0 0 0 3px var(--accent-wash);
  opacity: 0;
  pointer-events: none;
}
.marketing-home .home-chat-placeholder,
.marketing-home .home-chat-typed { grid-area: 1 / 1; }
.marketing-home .home-chat-placeholder { color: var(--text-dim); }
.marketing-home .home-chat-typed { opacity: 0; }
/* Each word sits under a cover in the input's own colour. Typing slides the
   cover off to the right, and the caret rides its leading edge, so letters
   appear left to right instead of a whole word at once. */
.marketing-home .home-chat-typed > span {
  position: relative;
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
}
.marketing-home .home-chat-typed > span::before,
.marketing-home .home-chat-typed > span::after {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
}
.marketing-home .home-chat-typed > span::before { top: 0; bottom: 0; background: var(--bg); }
.marketing-home .home-chat-typed > span::after {
  top: 0.1em;
  bottom: 0.1em;
  border-left: 2px solid var(--accent);
  opacity: 0;
}
.marketing-home .home-chat-send {
  position: relative;
  isolation: isolate;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius);
  background: var(--surface-2);
}
.marketing-home .home-chat-send::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--accent-wash-strong);
  box-shadow: inset 0 0 0 1px var(--accent);
  opacity: 0;
}
.marketing-home .home-chat-send::after {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  border: solid var(--text);
  border-width: 2px 0 0 2px;
  transform: translateY(0.125rem) rotate(45deg);
}
/* Chips below the stage name each example, like suggested questions. The
   radios they label carry the names for assistive technology. */
.marketing-home .home-chat-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-4);
}
.marketing-home .home-chat-tabs > label {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 2rem;
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text);
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-medium);
  cursor: pointer;
}
.marketing-home .home-chat-tabs > label:hover { border-color: var(--border-strong); }
/* A plan tag reads as a quiet second word behind a hairline rather than a
   box nested in the chip, so all four chips still fit one row in a
   full-width card. */
.marketing-home .home-chat-tabs .pill {
  margin-inline-start: calc(var(--space-1) * -0.5);
  padding: 0 0 0 0.3125rem;
  border-left: 1px solid var(--border-strong);
  border-radius: 0;
  background: none;
  color: var(--text-dim);
  font-weight: var(--fw-medium);
  line-height: 1;
}
/* The current example: a lit layer, plus a progress rule while the
   examples rotate. */
.marketing-home .home-chat-tabs > label::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--accent-wash-strong);
  box-shadow: inset 0 0 0 1px var(--accent);
  opacity: 0;
}
.marketing-home .home-chat-tabs > label::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--accent);
  transform-origin: left center;
  transform: scaleX(0);
}
.marketing-home .home-chat-tabs > label:first-child::before { opacity: 1; }
.marketing-home .home-chat-choice:checked ~ .home-chat-tabs > label::before { opacity: 0; }
.marketing-home #home-example-1:checked ~ .home-chat-tabs > label:nth-child(1)::before,
.marketing-home #home-example-2:checked ~ .home-chat-tabs > label:nth-child(2)::before,
.marketing-home #home-example-3:checked ~ .home-chat-tabs > label:nth-child(3)::before,
.marketing-home #home-example-4:checked ~ .home-chat-tabs > label:nth-child(4)::before { opacity: 1; }
.marketing-home #home-example-1:focus-visible ~ .home-chat-tabs > label:nth-child(1),
.marketing-home #home-example-2:focus-visible ~ .home-chat-tabs > label:nth-child(2),
.marketing-home #home-example-3:focus-visible ~ .home-chat-tabs > label:nth-child(3),
.marketing-home #home-example-4:focus-visible ~ .home-chat-tabs > label:nth-child(4) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.marketing-home .home-chat > .muted-note { margin-block: var(--space-4) 0; }

/* The illustrative 3D market. Price is height, time runs left to right,
   and every face is a token colour or a mix of two tokens. Geometry is a
   fictional daily series whose ATR(14) is the $6.40 the card shows. */
.marketing-home .market-scene {
  position: absolute;
  inset: -1.5rem -14rem 3rem -6rem;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, var(--bg) 22%);
  mask-image: linear-gradient(90deg, transparent, var(--bg) 22%);
}
/* One view per example over a shared floor, each its own 3D context, so a
   view can fade without flattening the scene inside it. Statically the
   first example's view shows; a picked example shows its own. */
.marketing-home .market-view {
  position: absolute;
  inset: 0;
  perspective: 56rem;
  perspective-origin: 45% -20%;
}
.marketing-home .market-view-dates,
.marketing-home .market-view-options,
.marketing-home .market-view-positions,
.marketing-home .marketing-intro:has(.home-chat-choice:checked) .market-view:not(.market-view-floor) { visibility: hidden; }
.marketing-home .marketing-intro:has(#home-example-1:checked) .market-view-price,
.marketing-home .marketing-intro:has(#home-example-2:checked) .market-view-dates,
.marketing-home .marketing-intro:has(#home-example-3:checked) .market-view-options,
.marketing-home .marketing-intro:has(#home-example-4:checked) .market-view-positions { visibility: visible; }
.marketing-home .market-stage {
  position: absolute;
  left: 33%;
  bottom: 33%;
  width: 0;
  height: 0;
  transform-style: preserve-3d;
  transform: rotateX(-14deg) rotateY(-34deg);
}
.marketing-home .market-stage > div,
.marketing-home .market-build > div,
.marketing-home .market-candles > span,
.marketing-home .market-candles > span > span,
.marketing-home .market-tag > div { position: absolute; transform-style: preserve-3d; }
/* A view's objects stand on the floor's origin, so scaling them to nothing
   in height lowers them into the floor. */
.marketing-home .market-build { left: 0; bottom: 0; width: 0; height: 0; }
.marketing-home .market-candles { left: 0; bottom: 0; }
.marketing-home .market-floor {
  left: -330px;
  bottom: -150px;
  width: 660px;
  height: 300px;
  transform: rotateX(90deg);
  background-color: var(--surface);
  background-image:
    linear-gradient(var(--border) 1px, transparent 1px),
    linear-gradient(90deg, var(--border) 1px, transparent 1px);
  background-size: 21px 21px;
  background-position: 0.5px 0;
  -webkit-mask-image: radial-gradient(closest-side, var(--bg) 35%, transparent);
  mask-image: radial-gradient(closest-side, var(--bg) 35%, transparent);
}
.marketing-home .market-candle { left: 0; bottom: 0; width: 0; height: 0; }
.marketing-home .market-candle::before {
  content: "";
  position: absolute;
  left: -13px;
  bottom: -13px;
  width: 26px;
  height: 26px;
  transform: translateY(-1px) rotateX(90deg);
  background: radial-gradient(closest-side, var(--bg), transparent);
}
/* Each box is a front face plus right (::before) and top (::after) faces. */
.marketing-home .market-wick { left: -1px; width: 2px; transform: translateZ(1px); }
.marketing-home .market-body { left: -6.5px; width: 13px; transform: translateZ(6.5px); }
.marketing-home .market-volume { left: -6.5px; bottom: 0; width: 13px; transform: translateZ(-24px); }
.marketing-home .market-candle > span::before,
.marketing-home .market-candle > span::after { content: ""; position: absolute; }
.marketing-home .market-candle > span::before {
  left: 100%;
  top: 0;
  height: 100%;
  transform-origin: left center;
  transform: rotateY(90deg);
}
.marketing-home .market-candle > span::after {
  left: 0;
  bottom: 100%;
  width: 100%;
  transform-origin: center bottom;
  transform: rotateX(90deg);
}
.marketing-home .market-wick::before { width: 2px; }
.marketing-home .market-wick::after { height: 2px; }
.marketing-home .market-body::before,
.marketing-home .market-volume::before { width: 13px; }
.marketing-home .market-body::after,
.marketing-home .market-volume::after { height: 13px; }
.marketing-home .market-candle.up > .market-body {
  background: color-mix(in srgb, var(--accent) 80%, var(--bg));
  box-shadow: 0 0 20px color-mix(in srgb, var(--accent) 8%, transparent);
}
.marketing-home .market-candle.up > .market-body::before { background: color-mix(in srgb, var(--accent) 46%, var(--bg)); }
.marketing-home .market-candle.up > .market-body::after { background: color-mix(in srgb, var(--accent) 72%, var(--text)); }
.marketing-home .market-candle.up > .market-wick,
.marketing-home .market-candle.up > .market-wick::after { background: var(--accent); }
.marketing-home .market-candle.up > .market-wick::before { background: color-mix(in srgb, var(--accent) 50%, var(--bg)); }
.marketing-home .market-candle.down > .market-body { background: color-mix(in srgb, var(--data-neutral) 60%, var(--bg)); }
.marketing-home .market-candle.down > .market-body::before { background: color-mix(in srgb, var(--data-neutral) 34%, var(--bg)); }
.marketing-home .market-candle.down > .market-body::after { background: color-mix(in srgb, var(--data-neutral) 82%, var(--text)); }
.marketing-home .market-candle.down > .market-wick,
.marketing-home .market-candle.down > .market-wick::after { background: var(--data-neutral); }
.marketing-home .market-candle.down > .market-wick::before { background: color-mix(in srgb, var(--data-neutral) 50%, var(--bg)); }
.marketing-home .market-volume { background: color-mix(in srgb, var(--data-neutral) 22%, var(--surface)); }
.marketing-home .market-volume::before { background: color-mix(in srgb, var(--data-neutral) 12%, var(--surface)); }
.marketing-home .market-volume::after { background: color-mix(in srgb, var(--data-neutral) 34%, var(--surface)); }
.marketing-home .market-candle:nth-child(1) { transform: translateX(-241.5px); }
.marketing-home .market-candle:nth-child(1) > .market-wick { bottom: 85.7px; height: 62.4px; }
.marketing-home .market-candle:nth-child(1) > .market-body { bottom: 115.7px; height: 6.5px; }
.marketing-home .market-candle:nth-child(1) > .market-volume { height: 11.6px; }
.marketing-home .market-candle:nth-child(2) { transform: translateX(-220.5px); }
.marketing-home .market-candle:nth-child(2) > .market-wick { bottom: 102.8px; height: 75.5px; }
.marketing-home .market-candle:nth-child(2) > .market-body { bottom: 127.4px; height: 18.2px; }
.marketing-home .market-candle:nth-child(2) > .market-volume { height: 13.9px; }
.marketing-home .market-candle:nth-child(3) { transform: translateX(-199.5px); }
.marketing-home .market-candle:nth-child(3) > .market-wick { bottom: 95.8px; height: 75.5px; }
.marketing-home .market-candle:nth-child(3) > .market-body { bottom: 131.3px; height: 18.2px; }
.marketing-home .market-candle:nth-child(3) > .market-volume { height: 9.9px; }
.marketing-home .market-candle:nth-child(4) { transform: translateX(-178.5px); }
.marketing-home .market-candle:nth-child(4) > .market-wick { bottom: 97.5px; height: 104.5px; }
.marketing-home .market-candle:nth-child(4) > .market-body { bottom: 124.8px; height: 39px; }
.marketing-home .market-candle:nth-child(4) > .market-volume { height: 15.6px; }
.marketing-home .market-candle:nth-child(5) { transform: translateX(-157.5px); }
.marketing-home .market-candle:nth-child(5) > .market-wick { bottom: 148.5px; height: 75.3px; }
.marketing-home .market-candle:nth-child(5) > .market-body { bottom: 171.6px; height: 22.1px; }
.marketing-home .market-candle:nth-child(5) > .market-volume { height: 17.7px; }
.marketing-home .market-candle:nth-child(6) { transform: translateX(-136.5px); }
.marketing-home .market-candle:nth-child(6) > .market-wick { bottom: 133.4px; height: 78.3px; }
.marketing-home .market-candle:nth-child(6) > .market-body { bottom: 172.9px; height: 15.6px; }
.marketing-home .market-candle:nth-child(6) > .market-volume { height: 12.9px; }
.marketing-home .market-candle:nth-child(7) { transform: translateX(-115.5px); }
.marketing-home .market-candle:nth-child(7) > .market-wick { bottom: 114.4px; height: 95.2px; }
.marketing-home .market-candle:nth-child(7) > .market-body { bottom: 143px; height: 32.5px; }
.marketing-home .market-candle:nth-child(7) > .market-volume { height: 15px; }
.marketing-home .market-candle:nth-child(8) { transform: translateX(-94.5px); }
.marketing-home .market-candle:nth-child(8) > .market-wick { bottom: 81.6px; height: 92.4px; }
.marketing-home .market-candle:nth-child(8) > .market-body { bottom: 114.4px; height: 35.1px; }
.marketing-home .market-candle:nth-child(8) > .market-volume { height: 16.7px; }
.marketing-home .market-candle:nth-child(9) { transform: translateX(-73.5px); }
.marketing-home .market-candle:nth-child(9) > .market-wick { bottom: 63.8px; height: 86.2px; }
.marketing-home .market-candle:nth-child(9) > .market-body { bottom: 89.7px; height: 20.8px; }
.marketing-home .market-candle:nth-child(9) > .market-volume { height: 19px; }
.marketing-home .market-candle:nth-child(10) { transform: translateX(-52.5px); }
.marketing-home .market-candle:nth-child(10) > .market-wick { bottom: 36px; height: 87.5px; }
.marketing-home .market-candle:nth-child(10) > .market-body { bottom: 72.8px; height: 22.1px; }
.marketing-home .market-candle:nth-child(10) > .market-volume { height: 20.7px; }
.marketing-home .market-candle:nth-child(11) { transform: translateX(-31.5px); }
.marketing-home .market-candle:nth-child(11) > .market-wick { bottom: 38.9px; height: 79.2px; }
.marketing-home .market-candle:nth-child(11) > .market-body { bottom: 70.2px; height: 26px; }
.marketing-home .market-candle:nth-child(11) > .market-volume { height: 16px; }
.marketing-home .market-candle:nth-child(12) { transform: translateX(-10.5px); }
.marketing-home .market-candle:nth-child(12) > .market-wick { bottom: 75.5px; height: 86.1px; }
.marketing-home .market-candle:nth-child(12) > .market-body { bottom: 100.1px; height: 26px; }
.marketing-home .market-candle:nth-child(12) > .market-volume { height: 13.3px; }
.marketing-home .market-candle:nth-child(13) { transform: translateX(10.5px); }
.marketing-home .market-candle:nth-child(13) > .market-wick { bottom: 72.5px; height: 92.7px; }
.marketing-home .market-candle:nth-child(13) > .market-body { bottom: 106.6px; height: 27.3px; }
.marketing-home .market-candle:nth-child(13) > .market-volume { height: 11.9px; }
.marketing-home .market-candle:nth-child(14) { transform: translateX(31.5px); }
.marketing-home .market-candle:nth-child(14) > .market-wick { bottom: 71.4px; height: 94.9px; }
.marketing-home .market-candle:nth-child(14) > .market-body { bottom: 101.4px; height: 39px; }
.marketing-home .market-candle:nth-child(14) > .market-volume { height: 14.3px; }
.marketing-home .market-candle:nth-child(15) { transform: translateX(52.5px); }
.marketing-home .market-candle:nth-child(15) > .market-wick { bottom: 121.2px; height: 83.3px; }
.marketing-home .market-candle:nth-child(15) > .market-body { bottom: 143px; height: 24.7px; }
.marketing-home .market-candle:nth-child(15) > .market-volume { height: 15.3px; }
.marketing-home .market-candle:nth-child(16) { transform: translateX(73.5px); }
.marketing-home .market-candle:nth-child(16) > .market-wick { bottom: 112.6px; height: 86.2px; }
.marketing-home .market-candle:nth-child(16) > .market-body { bottom: 150.8px; height: 23.4px; }
.marketing-home .market-candle:nth-child(16) > .market-volume { height: 12.6px; }
.marketing-home .market-candle:nth-child(17) { transform: translateX(94.5px); }
.marketing-home .market-candle:nth-child(17) > .market-wick { bottom: 119.6px; height: 92.6px; }
.marketing-home .market-candle:nth-child(17) > .market-body { bottom: 146.9px; height: 32.5px; }
.marketing-home .market-candle:nth-child(17) > .market-volume { height: 13.6px; }
.marketing-home .market-candle:nth-child(18) { transform: translateX(115.5px); }
.marketing-home .market-candle:nth-child(18) > .market-wick { bottom: 126px; height: 85.9px; }
.marketing-home .market-candle:nth-child(18) > .market-body { bottom: 157.3px; height: 27.3px; }
.marketing-home .market-candle:nth-child(18) > .market-volume { height: 11.2px; }
.marketing-home .market-candle:nth-child(19) { transform: translateX(136.5px); }
.marketing-home .market-candle:nth-child(19) > .market-wick { bottom: 109.3px; height: 87.4px; }
.marketing-home .market-candle:nth-child(19) > .market-body { bottom: 135.2px; height: 26px; }
.marketing-home .market-candle:nth-child(19) > .market-volume { height: 10.5px; }
.marketing-home .market-candle:nth-child(20) { transform: translateX(157.5px); }
.marketing-home .market-candle:nth-child(20) > .market-wick { bottom: 97.1px; height: 80.9px; }
.marketing-home .market-candle:nth-child(20) > .market-body { bottom: 132.6px; height: 22.1px; }
.marketing-home .market-candle:nth-child(20) > .market-volume { height: 12.2px; }
.marketing-home .market-candle:nth-child(21) { transform: translateX(178.5px); }
.marketing-home .market-candle:nth-child(21) > .market-wick { bottom: 128.7px; height: 79.4px; }
.marketing-home .market-candle:nth-child(21) > .market-body { bottom: 157.3px; height: 19.5px; }
.marketing-home .market-candle:nth-child(21) > .market-volume { height: 14.6px; }
.marketing-home .market-candle:nth-child(22) { transform: translateX(199.5px); }
.marketing-home .market-candle:nth-child(22) > .market-wick { bottom: 135.5px; height: 80.6px; }
.marketing-home .market-candle:nth-child(22) > .market-body { bottom: 158.6px; height: 23.4px; }
.marketing-home .market-candle:nth-child(22) > .market-volume { height: 11.6px; }
.marketing-home .market-candle:nth-child(23) { transform: translateX(220.5px); }
.marketing-home .market-candle:nth-child(23) > .market-wick { bottom: 108.9px; height: 71.6px; }
.marketing-home .market-candle:nth-child(23) > .market-body { bottom: 141.7px; height: 13px; }
.marketing-home .market-candle:nth-child(23) > .market-volume { height: 10.2px; }
.marketing-home .market-candle:nth-child(24) { transform: translateX(241.5px); }
.marketing-home .market-candle:nth-child(24) > .market-wick { bottom: 117px; height: 67.7px; }
.marketing-home .market-candle:nth-child(24) > .market-body { bottom: 144.3px; height: 10.4px; }
.marketing-home .market-candle:nth-child(24) > .market-volume { height: 12.9px; }
/* The latest quote as a level sheet through the history at $205.12. */
.marketing-home .market-level {
  left: -270px;
  bottom: 140.6px;
  width: 540px;
  height: 60px;
  transform: rotateX(90deg);
  background: linear-gradient(90deg, transparent, var(--accent-wash-strong) 35%, var(--accent-wash-strong));
}
.marketing-home .market-level-edge {
  left: -270px;
  bottom: 169.6px;
  width: 540px;
  height: 2px;
  transform: translateZ(30px);
  background: linear-gradient(90deg, transparent, var(--accent) 35%);
  box-shadow: 0 0 14px color-mix(in srgb, var(--accent) 50%, transparent);
}
/* The recent daily range as a $6.40 ruler beside the newest session. */
.marketing-home .market-ruler {
  left: 267.5px;
  bottom: 109.3px;
  width: 2px;
  height: 83.2px;
  transform: translateZ(8px);
  background: var(--accent);
  box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 50%, transparent);
}
.marketing-home .market-ruler::before,
.marketing-home .market-ruler::after {
  content: "";
  position: absolute;
  left: -5px;
  width: 12px;
  height: 2px;
  background: var(--accent);
}
.marketing-home .market-ruler::before { top: 0; }
.marketing-home .market-ruler::after { bottom: 0; }
.marketing-home .market-scan {
  left: -30px;
  bottom: 0;
  width: 60px;
  height: 220px;
  transform: translateX(-30px) rotateY(90deg);
  background: linear-gradient(0deg, var(--accent-wash-strong), transparent);
  opacity: 0;
}
/* Tags counter-rotate against the stage so their text faces the reader. */
.marketing-home .market-tag { left: 0; bottom: 0; width: 0; height: 0; }
.marketing-home .market-tag-quote { transform: translate3d(270px, -170.6px, 30px); }
.marketing-home .market-tag-range { transform: translate3d(276px, -128px, 8px); }
.marketing-home .market-billboard { left: 0; bottom: 0; transform: rotateY(34deg) rotateX(14deg); }
.marketing-home .market-billboard > span {
  position: absolute;
  left: var(--space-2);
  bottom: calc(var(--space-3) * -1);
  padding: 0 var(--space-2);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  line-height: var(--lh-body);
  white-space: nowrap;
}
/* The filing and Fed dates: July to October 2026 as standing month cards
   of day tiles, Sunday first, each cut to its own first and last weeks.
   Each dated day stands out of its true tile, pinned to its label: the
   filing flies a page. */
.marketing-home .market-month {
  bottom: 0;
  width: 124px;
  height: 116px;
  transform: translateZ(-22px);
  background: color-mix(in srgb, var(--data-neutral) 16%, var(--surface));
  box-shadow: inset 0 2px 0 var(--accent-wash-strong);
}
.marketing-home .market-month::before,
.marketing-home .market-month::after { content: ""; position: absolute; }
.marketing-home .market-month::before {
  left: 100%;
  top: 0;
  width: 6px;
  height: 100%;
  transform-origin: left center;
  transform: rotateY(90deg);
  background: color-mix(in srgb, var(--data-neutral) 10%, var(--surface));
}
.marketing-home .market-month::after {
  left: 0;
  bottom: 100%;
  width: 100%;
  height: 6px;
  transform-origin: center bottom;
  transform: rotateX(90deg);
  background: color-mix(in srgb, var(--data-neutral) 26%, var(--surface));
}
.marketing-home .market-month > span {
  position: absolute;
  left: 6px;
  top: 14px;
  width: 112px;
  height: 80px;
  transform: translateZ(0.5px);
  background: conic-gradient(from 90deg at 3px 3px, color-mix(in srgb, var(--data-neutral) 26%, var(--surface)) 25%, transparent 0) -1px -1px / 16px 16px;
}
.marketing-home .market-month-jul { left: -299px; }
.marketing-home .market-month-aug { left: -161px; }
.marketing-home .market-month-sep { left: -23px; }
.marketing-home .market-month-oct { left: 115px; }
.marketing-home .market-month-jul > span { clip-path: polygon(42.857% 0, 100% 0, 100% 80%, 85.714% 80%, 85.714% 100%, 0 100%, 0 20%, 42.857% 20%); }
.marketing-home .market-month-aug > span {
  height: 96px;
  clip-path: polygon(85.714% 0, 100% 0, 100% 83.333%, 28.571% 83.333%, 28.571% 100%, 0 100%, 0 16.667%, 85.714% 16.667%);
}
.marketing-home .market-month-sep > span { clip-path: polygon(28.571% 0, 100% 0, 100% 80%, 57.143% 80%, 57.143% 100%, 0 100%, 0 20%, 28.571% 20%); }
.marketing-home .market-month-oct > span { clip-path: polygon(57.143% 0, 100% 0, 100% 100%, 0 100%, 0 20%, 57.143% 20%); }
.marketing-home .market-day {
  bottom: 23px;
  height: 13px;
  background: color-mix(in srgb, var(--accent) 80%, var(--bg));
  box-shadow: 0 0 18px color-mix(in srgb, var(--accent) 50%, transparent);
}
.marketing-home .market-day::before,
.marketing-home .market-day::after { content: ""; position: absolute; }
.marketing-home .market-day::before {
  left: 100%;
  top: 0;
  height: 100%;
  transform-origin: left center;
  transform: rotateY(90deg);
  background: color-mix(in srgb, var(--accent) 46%, var(--bg));
}
.marketing-home .market-day::after {
  left: 0;
  bottom: 100%;
  width: 100%;
  transform-origin: center bottom;
  transform: rotateX(90deg);
  background: color-mix(in srgb, var(--accent) 72%, var(--text));
}
.marketing-home .market-day-filing { left: -211px; width: 13px; transform: translateZ(-14px); }
.marketing-home .market-day-fed { left: 155px; width: 29px; transform: translateZ(-10px); }
.marketing-home .market-day-filing::before { width: 8px; }
.marketing-home .market-day-filing::after { height: 8px; }
.marketing-home .market-day-fed::before { width: 12px; }
.marketing-home .market-day-fed::after { height: 12px; }
.marketing-home .market-beam {
  bottom: 36px;
  width: 2px;
  background: linear-gradient(var(--accent-wash-strong), var(--accent));
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 8%, transparent);
}
.marketing-home .market-beam-filing { left: -205.5px; height: 104px; transform: translateZ(-18px); }
.marketing-home .market-beam-fed { left: 168.5px; height: 104px; transform: translateZ(-16px); }
.marketing-home .market-page {
  left: -217.5px;
  bottom: 140px;
  width: 26px;
  height: 34px;
  transform: translateZ(-18px);
  clip-path: polygon(0 0, 70% 0, 100% 22%, 100% 100%, 0 100%);
  background:
    repeating-linear-gradient(color-mix(in srgb, var(--bg) 55%, var(--text)) 0 2px, transparent 2px 6px) 5px 11px / 16px 19px no-repeat,
    color-mix(in srgb, var(--text) 86%, var(--bg));
}
.marketing-home .market-tag-filing { transform: translate3d(-191.5px, -160px, -18px); }
.marketing-home .market-tag-fed { transform: translate3d(169.5px, -140px, -16px); }
/* Tags near the card's edge read leftward so the card never covers them. */
.marketing-home .market-tag-fed .market-billboard > span,
.marketing-home .market-tag-band .market-billboard > span { left: auto; right: var(--space-2); }
/* The implied move: from the latest price, a cone that widens to the
   October 16 expiration, where a ring and a ruler span the indicative
   range. It is symmetric, so it leans neither way. */
.marketing-home .market-spot-level {
  left: -300px;
  bottom: 117px;
  width: 450px;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--accent-wash-strong) 30%);
}
.marketing-home .market-cone,
.marketing-home .market-cone-flat {
  left: -200px;
  bottom: 38px;
  width: 350px;
  height: 160px;
  clip-path: polygon(0 50%, 100% 0, 100% 100%);
  background: linear-gradient(90deg, transparent, var(--accent-wash-strong));
}
.marketing-home .market-cone-flat {
  transform: rotateX(90deg);
  background: linear-gradient(90deg, transparent, var(--accent-wash));
}
.marketing-home .market-cone-edge {
  left: -200px;
  bottom: 117px;
  width: 359.03px;
  height: 2px;
  transform-origin: left center;
  background: linear-gradient(90deg, var(--accent-wash-strong), var(--accent));
  box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 8%, transparent);
}
.marketing-home .market-cone-edge-high { transform: rotate(-12.88deg); }
.marketing-home .market-cone-edge-low { transform: rotate(12.88deg); }
.marketing-home .market-cone-ring {
  left: 70px;
  bottom: 38px;
  width: 160px;
  height: 160px;
  box-sizing: border-box;
  border: 2px solid var(--accent);
  border-radius: 50%;
  transform: rotateY(90deg);
  background: radial-gradient(closest-side, transparent 60%, color-mix(in srgb, var(--accent) 6%, transparent));
  box-shadow: 0 0 18px color-mix(in srgb, var(--accent) 8%, transparent);
}
.marketing-home .market-cone-ring-third,
.marketing-home .market-cone-ring-two-thirds {
  border-width: 1px;
  border-color: color-mix(in srgb, var(--accent) 39%, transparent);
  background: none;
  box-shadow: none;
}
.marketing-home .market-cone-ring-third { left: -110px; bottom: 91.33px; width: 53.33px; height: 53.33px; }
.marketing-home .market-cone-ring-two-thirds { left: -20px; bottom: 64.67px; width: 106.67px; height: 106.67px; }
.marketing-home .market-cone-ruler {
  left: 149px;
  bottom: 38px;
  width: 2px;
  height: 160px;
  background: var(--accent);
  box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 50%, transparent);
}
.marketing-home .market-cone-ruler::before,
.marketing-home .market-cone-ruler::after {
  content: "";
  position: absolute;
  left: -5px;
  width: 12px;
  height: 2px;
  background: var(--accent);
}
.marketing-home .market-cone-ruler::before { top: 0; }
.marketing-home .market-cone-ruler::after { bottom: 0; }
.marketing-home .market-spot {
  left: -205px;
  bottom: 113px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 14px color-mix(in srgb, var(--accent) 50%, transparent);
}
.marketing-home .market-tag-move { transform: translate3d(152px, -198px, 0); }
.marketing-home .market-tag-band { transform: translate3d(148px, -38px, 0); }
/* Positions and dates: six fictional positions as equal lanes from
   September 18 to the end of October, so no size or value reads into
   them. The monthly expiration crosses them as a wall of light, lit where
   five of the six have listed options; the Fed meeting is a lower wall
   over its two days. */
.marketing-home .market-lanes { left: -270px; bottom: 0; }
.marketing-home .market-lanes > span,
.marketing-home .market-nodes > span { position: absolute; left: 0; bottom: 0; transform-style: preserve-3d; }
.marketing-home .market-lane { width: 460px; height: 6px; background: color-mix(in srgb, var(--data-neutral) 44%, var(--surface)); }
.marketing-home .market-lane::before,
.marketing-home .market-lane::after,
.marketing-home .market-node::before,
.marketing-home .market-node::after { content: ""; position: absolute; }
.marketing-home .market-lane::before,
.marketing-home .market-node::before {
  left: 100%;
  top: 0;
  height: 100%;
  transform-origin: left center;
  transform: rotateY(90deg);
}
.marketing-home .market-lane::after,
.marketing-home .market-node::after {
  left: 0;
  bottom: 100%;
  width: 100%;
  transform-origin: center bottom;
  transform: rotateX(90deg);
}
.marketing-home .market-lane::before { width: 8px; background: color-mix(in srgb, var(--data-neutral) 24%, var(--surface)); }
.marketing-home .market-lane::after { height: 8px; background: color-mix(in srgb, var(--data-neutral) 58%, var(--surface)); }
.marketing-home .market-lane:nth-child(1) { transform: translateZ(-66px); }
.marketing-home .market-lane:nth-child(2) { transform: translateZ(-46px); }
.marketing-home .market-lane:nth-child(3) { transform: translateZ(-26px); }
.marketing-home .market-lane:nth-child(4) { transform: translateZ(-6px); }
.marketing-home .market-lane:nth-child(5) { transform: translateZ(14px); }
.marketing-home .market-lane:nth-child(6) { transform: translateZ(34px); }
.marketing-home .market-fed-band {
  left: 138px;
  bottom: -65px;
  width: 21px;
  height: 132px;
  transform: translateZ(-20px) rotateX(90deg);
  background: var(--accent-wash-strong);
}
.marketing-home .market-wall {
  bottom: 0;
  width: 132px;
  transform: translateZ(-20px) rotateY(90deg);
  background: linear-gradient(0deg, color-mix(in srgb, var(--accent) 27%, transparent), var(--accent-wash) 70%, transparent);
  box-shadow: inset 0 -2px 0 var(--accent), inset 2px 0 0 var(--accent-wash-strong), inset -2px 0 0 var(--accent);
}
.marketing-home .market-wall-expiry { left: -38px; height: 160px; }
.marketing-home .market-wall-fed { left: 82px; height: 100px; }
.marketing-home .market-nodes { left: 23px; bottom: 6px; }
.marketing-home .market-node {
  width: 10px;
  height: 10px;
  background: color-mix(in srgb, var(--accent) 80%, var(--bg));
  box-shadow: 0 0 14px color-mix(in srgb, var(--accent) 50%, transparent);
}
.marketing-home .market-node::before { width: 10px; background: color-mix(in srgb, var(--accent) 46%, var(--bg)); }
.marketing-home .market-node::after { height: 10px; background: color-mix(in srgb, var(--accent) 72%, var(--text)); }
.marketing-home .market-node:nth-child(1) { transform: translateZ(-65px); }
.marketing-home .market-node:nth-child(2) { transform: translateZ(-45px); }
.marketing-home .market-node:nth-child(3) { transform: translateZ(-25px); }
.marketing-home .market-node:nth-child(4) { transform: translateZ(15px); }
.marketing-home .market-node:nth-child(5) { transform: translateZ(35px); }
.marketing-home .market-tag-expiry { transform: translate3d(28px, -160px, -20px); }
.marketing-home .market-tag-meeting { transform: translate3d(148px, -100px, -20px); }
.marketing-home .market-foot {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
  min-height: var(--control-target);
}
.marketing-home .market-caption { display: grid; margin: 0; color: var(--text-dim); font-size: var(--fs-base-sm); }
/* Each view names its own fictional subject; the captions share one cell
   and follow the views. */
.marketing-home .market-caption > span { grid-area: 1 / 1; }
.marketing-home .market-caption > span + span,
.marketing-home .marketing-intro:has(.home-chat-choice:checked) .market-caption > span { visibility: hidden; }
.marketing-home .marketing-intro:has(#home-example-1:checked) .market-caption > span:nth-child(1),
.marketing-home .marketing-intro:has(#home-example-2:checked) .market-caption > span:nth-child(2),
.marketing-home .marketing-intro:has(#home-example-3:checked) .market-caption > span:nth-child(3),
.marketing-home .marketing-intro:has(#home-example-4:checked) .market-caption > span:nth-child(4) { visibility: visible; }
.marketing-home .market-motion { display: none; margin: 0; }
.marketing-home .market-motion label { color: var(--text-dim); font-size: var(--fs-base-sm); cursor: pointer; }

/* Optional context: the illustrative private note as a stack of slates. */
.marketing-home .home-context { padding-bottom: var(--space-12); perspective: 70rem; }
.marketing-home .home-context-note {
  position: relative;
  padding: var(--space-6);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: 0 28px 56px var(--bg);
  transform-style: preserve-3d;
  transform-origin: 100% 50%;
  transform: rotateX(8deg) rotateY(-14deg);
}
.marketing-home .home-context-note::before,
.marketing-home .home-context-note::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  pointer-events: none;
}
.marketing-home .home-context-note::before {
  background: color-mix(in srgb, var(--surface) 72%, var(--bg));
  transform: translate3d(0, var(--space-4), -2.5rem);
}
.marketing-home .home-context-note::after {
  background: color-mix(in srgb, var(--surface) 44%, var(--bg));
  transform: translate3d(0, var(--space-8), -5rem);
}

/* Trust: what Slatemark does and does not do, beside a fictional tool
   receipt. The receipt is readable content: paper is the text role, ink the
   background role, and every mid tone mixes the two. It repeats only the
   reviewed fictional AAPL facts from the first example. */
.marketing-home .home-trust { align-items: center; }
.marketing-home .home-trust-copy > p { max-width: var(--measure-prose); }
.marketing-home .home-trust-copy > p:first-of-type { margin-top: 0; }
.marketing-home .home-ledger {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
  margin-block: var(--space-6);
}
.marketing-home .home-ledger > div {
  padding: var(--space-5);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.marketing-home .home-ledger h3 {
  margin: 0 0 var(--space-3);
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  font-weight: var(--fw-medium);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.marketing-home .home-ledger ul,
.marketing-home .home-plan ul { display: grid; gap: var(--space-3); margin: 0; padding: 0; list-style: none; }
.marketing-home .home-ledger li,
.marketing-home .home-plan li { position: relative; padding-left: var(--space-6); line-height: var(--lh-body); }
.marketing-home .home-ledger li::before,
.marketing-home .home-plan li::before { content: ""; position: absolute; }
.marketing-home .home-ledger-does li::before,
.marketing-home .home-plan li::before {
  left: 0.3125rem;
  top: 0.25rem;
  width: 0.375rem;
  height: 0.6875rem;
  border: solid var(--success);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.marketing-home .home-ledger-not li::before {
  left: 0.125rem;
  top: 0.375rem;
  width: 0.75rem;
  height: 0.75rem;
  background:
    linear-gradient(45deg, transparent calc(50% - 1px), var(--text-dim) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)),
    linear-gradient(-45deg, transparent calc(50% - 1px), var(--text-dim) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px));
}
.marketing-home .home-receipt-stage {
  position: relative;
  display: grid;
  place-items: center;
  min-width: 0;
  padding-block: var(--space-8);
  perspective: 120rem;
  filter: drop-shadow(1.5rem 2rem 1.75rem var(--bg));
}
.marketing-home .home-receipt-stage::before {
  content: "";
  position: absolute;
  inset: 5% 0;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--accent) 9%, transparent), transparent);
  pointer-events: none;
}
.marketing-home .home-receipt {
  position: relative;
  width: 100%;
  max-width: 25rem;
  padding: var(--space-6) var(--space-6) var(--space-12);
  background: var(--text);
  color: var(--bg);
  font-family: var(--font-mono);
  font-size: var(--fs-base-sm);
  line-height: 1.55;
  transform-style: preserve-3d;
  transform: rotateX(4deg) rotateY(-7deg);
  /* A torn, zig-zag lower edge. */
  -webkit-mask: conic-gradient(from -45deg at bottom, transparent, var(--bg) 1deg 89deg, transparent 90deg) 50% / 0.875rem 100%;
  mask: conic-gradient(from -45deg at bottom, transparent, var(--bg) 1deg 89deg, transparent 90deg) 50% / 0.875rem 100%;
}
.marketing-home .home-receipt > p { margin: 0; }
.marketing-home .home-receipt-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  color: color-mix(in srgb, var(--bg) 62%, var(--text));
  font-size: var(--fs-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.marketing-home .home-receipt-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--bg);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  letter-spacing: 0;
  text-transform: none;
}
/* The brand mark: a jade candle crossing a slate level line. */
.marketing-home .home-receipt-brand::before {
  content: "";
  width: 1.25rem;
  height: 1.25rem;
  background:
    linear-gradient(color-mix(in srgb, var(--accent) 34%, var(--bg)), color-mix(in srgb, var(--accent) 34%, var(--bg))) center 20% / 0.5rem 0.75rem no-repeat,
    linear-gradient(color-mix(in srgb, var(--accent) 34%, var(--bg)), color-mix(in srgb, var(--accent) 34%, var(--bg))) center / 2px 100% no-repeat,
    linear-gradient(var(--border), var(--border)) center 48% / 100% 2px no-repeat;
}
.marketing-home .home-receipt-sub {
  margin-top: var(--space-1);
  color: color-mix(in srgb, var(--bg) 62%, var(--text));
  font-size: var(--fs-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.marketing-home .home-receipt-rows,
.marketing-home .home-receipt-note {
  margin: var(--space-4) 0 0;
  padding-top: var(--space-4);
  border-top: 1.5px dashed color-mix(in srgb, var(--bg) 32%, var(--text));
}
.marketing-home .home-receipt-rows { display: grid; gap: var(--space-1); }
.marketing-home .home-receipt-rows > div { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-4); }
.marketing-home .home-receipt-rows > .home-receipt-value { align-items: center; }
.marketing-home .home-receipt-rows dt { color: color-mix(in srgb, var(--bg) 62%, var(--text)); }
.marketing-home .home-receipt-rows dd { margin: 0; font-weight: var(--fw-medium); text-align: right; }
.marketing-home .home-receipt-tool dd { color: color-mix(in srgb, var(--accent) 40%, var(--bg)); }
.marketing-home .home-receipt-value dd {
  font-family: var(--font-sans);
  font-size: var(--fs-2xl);
  font-weight: var(--fw-bold);
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.marketing-home .home-receipt-note {
  color: color-mix(in srgb, var(--bg) 62%, var(--text));
  font-size: var(--fs-micro);
  text-align: center;
}
.marketing-home .home-receipt-code {
  display: block;
  height: 2.375rem;
  margin-top: var(--space-4);
  background: repeating-linear-gradient(90deg, var(--bg) 0 2px, transparent 2px 4px, var(--bg) 4px 5px, transparent 5px 8px, var(--bg) 8px 11px, transparent 11px 12px, var(--bg) 12px 13px, transparent 13px 17px);
  opacity: 0.85;
}
.marketing-home .home-receipt-stamp {
  position: absolute;
  right: var(--space-6);
  bottom: 3.25rem;
  padding: var(--space-2);
  background: color-mix(in srgb, var(--text) 88%, transparent);
  border: 2px solid color-mix(in srgb, var(--accent) 28%, var(--bg));
  border-radius: var(--radius);
  color: color-mix(in srgb, var(--accent) 40%, var(--bg));
  font-size: var(--fs-micro);
  font-weight: var(--fw-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transform: rotate(-12deg) translateZ(1.875rem);
  opacity: 0.85;
}

/* Plans: the two public self-serve plans, in the Pricing page's words. */
.marketing-home .home-plans { margin-bottom: 0; }
.marketing-home .home-plans h2 { margin-top: 0; }
.marketing-home .home-plan-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6);
  margin-block: var(--space-6);
}
.marketing-home .home-plan {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
  padding: var(--space-8);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.marketing-home .home-plan-plus {
  border-color: color-mix(in srgb, var(--accent) 31%, var(--border));
  background: linear-gradient(160deg, var(--accent-wash), var(--surface) 45%);
}
.marketing-home .home-plan h3 {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin: 0;
  font-size: var(--fs-lg);
}
.marketing-home .home-plan h3 .pill { background: var(--surface-2); color: var(--text); font-weight: var(--fw-medium); white-space: normal; }
.marketing-home .home-plan-price {
  margin: 0;
  font-size: var(--fs-3xl-mobile);
  font-weight: var(--fw-bold);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.marketing-home .home-plan-price > span { color: var(--text-dim); font-size: var(--fs-base); font-weight: var(--fw-regular); }
.marketing-home .home-plan > .btn { align-self: flex-start; margin-top: auto; }

/* One connection: each source feeds Slatemark, which feeds your AI. The
   diagram restates the supporting line above it and stays aria-hidden. */
.marketing-home .home-flow {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  align-items: center;
  gap: var(--space-12);
  margin-bottom: 0;
}
.marketing-home .home-flow h2 { margin-top: 0; }
.marketing-home .home-flow-copy > p { max-width: var(--measure-prose); }
.marketing-home .flow { position: relative; min-width: 0; height: 21rem; perspective: 60rem; }
.marketing-home .flow-canvas {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 640px;
  height: 320px;
  transform-style: preserve-3d;
  transform: translate(-50%, -50%) rotateX(14deg) rotateY(-9deg) scale(0.9);
}
.marketing-home .flow-lines { position: absolute; left: 0; top: 0; width: 640px; height: 320px; overflow: visible; }
.marketing-home .flow-lines-narrow { display: none; }
.marketing-home .flow-line { stroke: var(--border-strong); stroke-width: 1.5; stroke-opacity: 0.5; }
.marketing-home .flow-source,
.marketing-home .flow-hub,
.marketing-home .flow-client {
  position: absolute;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-medium);
  transform: translateZ(18px);
  box-shadow: 0 14px 24px var(--bg);
}
.marketing-home .flow-source { left: 0; width: 176px; height: 40px; }
.marketing-home .flow-source::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--data-neutral);
}
/* A lit layer so the loop can light a source with opacity alone. */
.marketing-home .flow-source::after,
.marketing-home .flow-hub::after,
.marketing-home .flow-client::before {
  content: "";
  position: absolute;
  inset: -1px;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  box-shadow: 0 0 24px color-mix(in srgb, var(--accent) 8%, transparent);
  opacity: 0;
  pointer-events: none;
}
.marketing-home .flow-source-market { top: 20px; }
.marketing-home .flow-source-calc { top: 80px; }
.marketing-home .flow-source-sec { top: 140px; }
.marketing-home .flow-source-macro { top: 200px; }
.marketing-home .flow-source-context { top: 260px; }
.marketing-home .flow-hub {
  left: 300px;
  top: 100px;
  width: 120px;
  height: 120px;
  flex-direction: column;
  justify-content: center;
  padding: 0;
  border-color: var(--border-strong);
  background: var(--surface-2);
  transform: translateZ(34px);
}
/* The brand mark: a jade candle crossing a slate level line. */
.marketing-home .flow-hub-mark {
  position: relative;
  width: 50px;
  height: 46px;
  margin-bottom: var(--space-2);
  background: linear-gradient(var(--accent), var(--accent)) center 11px / 18px 22px no-repeat;
}
.marketing-home .flow-hub-mark::before,
.marketing-home .flow-hub-mark::after { content: ""; position: absolute; border-radius: 2px; }
.marketing-home .flow-hub-mark::before { left: 0; right: 0; top: 20px; height: 4px; background: var(--border-strong); }
.marketing-home .flow-hub-mark::after { left: 23px; top: 0; width: 4px; height: 46px; background: var(--accent); }
.marketing-home .flow-client {
  left: 500px;
  top: 116px;
  width: 140px;
  height: 88px;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-color: var(--border-strong);
}
.marketing-home .flow-client-bar {
  width: 33px;
  height: 6px;
  background: radial-gradient(circle at 3px 3px, var(--border-strong) 2.5px, transparent 3px) 0 0 / 11px 6px repeat-x;
}
.marketing-home .flow-client::after {
  content: "";
  height: 22px;
  background:
    linear-gradient(var(--surface-2), var(--surface-2)) 0 0 / 70% 8px no-repeat,
    linear-gradient(var(--accent-wash-strong), var(--accent-wash-strong)) 100% 100% / 55% 8px no-repeat;
}
.marketing-home .flow-pulse {
  position: absolute;
  left: 0;
  top: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 50%, transparent);
  offset-rotate: 0deg;
  opacity: 0;
}
.marketing-home .flow-pulse-market { offset-path: path("M 176 40 L 300 160"); }
.marketing-home .flow-pulse-calc { offset-path: path("M 176 100 L 300 160"); }
.marketing-home .flow-pulse-sec { offset-path: path("M 176 160 L 300 160"); }
.marketing-home .flow-pulse-macro { offset-path: path("M 176 220 L 300 160"); }
.marketing-home .flow-pulse-context { offset-path: path("M 176 280 L 300 160"); }
.marketing-home .flow-pulse-client { offset-path: path("M 420 160 L 500 160"); }

/* The reviewed Home motion. Durations, delays and keyframes are
   inventoried by the design-system gallery motion contract.
   - The illustration's entrance runs once, beside the first example, and
     ends within five seconds; its ambient orbit and the source loop run
     indefinitely inside hidden illustrations.
   - The conversation card rotates its four examples on one 48-second
     loop, 12 seconds each. Inside every example the same 12-second
     conversation runs in lockstep, so each shows from its start whenever
     its slot opens. Delayed parts fill backwards, or rest in a static
     state that hides them (the word covers and carets), so nothing shows
     early.
   - Focusing the card, the "Pause motion" control, or picking an example
     stops the rotation (WCAG 2.2.2). A resting pointer does not: one that
     happened to sit where the card loads froze it before its first
     example appeared, leaving an empty card until the pointer moved. */
@media (prefers-reduced-motion: no-preference) {
  .marketing-home .market-motion { display: flex; align-items: center; gap: var(--space-2); min-height: var(--control-target); }
  .marketing-home .market-stage { animation: home-orbit 20s ease-in-out infinite alternate; }
  .marketing-home .market-billboard { animation: home-billboard 20s ease-in-out infinite alternate; }
  .marketing-home .market-floor { animation: home-fade 0.8s ease-out both; }
  .marketing-home .market-body { animation: home-rise 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
  .marketing-home .market-wick { animation: home-rise-wick 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
  .marketing-home .market-volume { animation: home-rise-volume 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
  .marketing-home .market-candle:nth-child(1) > * { animation-delay: 0.30s; }
  .marketing-home .market-candle:nth-child(2) > * { animation-delay: 0.34s; }
  .marketing-home .market-candle:nth-child(3) > * { animation-delay: 0.38s; }
  .marketing-home .market-candle:nth-child(4) > * { animation-delay: 0.42s; }
  .marketing-home .market-candle:nth-child(5) > * { animation-delay: 0.46s; }
  .marketing-home .market-candle:nth-child(6) > * { animation-delay: 0.50s; }
  .marketing-home .market-candle:nth-child(7) > * { animation-delay: 0.54s; }
  .marketing-home .market-candle:nth-child(8) > * { animation-delay: 0.58s; }
  .marketing-home .market-candle:nth-child(9) > * { animation-delay: 0.62s; }
  .marketing-home .market-candle:nth-child(10) > * { animation-delay: 0.66s; }
  .marketing-home .market-candle:nth-child(11) > * { animation-delay: 0.70s; }
  .marketing-home .market-candle:nth-child(12) > * { animation-delay: 0.74s; }
  .marketing-home .market-candle:nth-child(13) > * { animation-delay: 0.78s; }
  .marketing-home .market-candle:nth-child(14) > * { animation-delay: 0.82s; }
  .marketing-home .market-candle:nth-child(15) > * { animation-delay: 0.86s; }
  .marketing-home .market-candle:nth-child(16) > * { animation-delay: 0.90s; }
  .marketing-home .market-candle:nth-child(17) > * { animation-delay: 0.94s; }
  .marketing-home .market-candle:nth-child(18) > * { animation-delay: 0.98s; }
  .marketing-home .market-candle:nth-child(19) > * { animation-delay: 1.02s; }
  .marketing-home .market-candle:nth-child(20) > * { animation-delay: 1.06s; }
  .marketing-home .market-candle:nth-child(21) > * { animation-delay: 1.10s; }
  .marketing-home .market-candle:nth-child(22) > * { animation-delay: 1.14s; }
  .marketing-home .market-candle:nth-child(23) > * { animation-delay: 1.18s; }
  .marketing-home .market-candle:nth-child(24) > * { animation-delay: 1.22s; }
  .marketing-home .market-candle::before { animation: home-fade 0.7s ease-out 0.9s both; }
  /* get_quote returns in the first example: the level sweeps through the
     history. */
  .marketing-home .market-level { animation: home-level 0.9s cubic-bezier(0.2, 0.8, 0.2, 1) 3.1s both; }
  .marketing-home .market-level-edge { animation: home-level-edge 0.9s cubic-bezier(0.2, 0.8, 0.2, 1) 3.1s both; }
  .marketing-home .market-tag-quote > .market-billboard > span { animation: home-pop 0.4s ease-out 3.5s both; }
  /* run_technical_analysis reads the history, then the range appears. */
  .marketing-home .market-scan { animation: home-scan 0.9s ease-in-out 3.2s both; }
  .marketing-home .market-ruler { animation: home-ruler 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) 3.8s both; }
  .marketing-home .market-tag-range > .market-billboard > span { animation: home-pop 0.4s ease-out 4.1s both; }
  /* The connection chip pulses. */
  .marketing-home .home-chat-pulse::after { animation: home-ping 1.8s ease-out infinite; }
  /* One slot per example, and the chip that names it. */
  .marketing-home .home-chat-stage > .home-chat-example { visibility: visible; animation: home-slot 48s linear infinite both; }
  .marketing-home .home-chat-tabs > label::before { animation: home-slot 48s linear infinite both; }
  .marketing-home .home-chat-tabs > label::after { animation: home-progress 48s linear infinite both; }
  .marketing-home .home-chat-stage > .home-chat-example:nth-child(2),
  .marketing-home .home-chat-tabs > label:nth-child(2)::before,
  .marketing-home .home-chat-tabs > label:nth-child(2)::after { animation-delay: 12s; }
  .marketing-home .home-chat-stage > .home-chat-example:nth-child(3),
  .marketing-home .home-chat-tabs > label:nth-child(3)::before,
  .marketing-home .home-chat-tabs > label:nth-child(3)::after { animation-delay: 24s; }
  .marketing-home .home-chat-stage > .home-chat-example:nth-child(4),
  .marketing-home .home-chat-tabs > label:nth-child(4)::before,
  .marketing-home .home-chat-tabs > label:nth-child(4)::after { animation-delay: 36s; }
  /* The illustration keeps the same slots: each example's view shows, its
     objects rising from the floor, while that example does. */
  .marketing-home .market-view-price,
  .marketing-home .market-view-dates,
  .marketing-home .market-view-options,
  .marketing-home .market-view-positions,
  .marketing-home .market-foot .market-caption > span { visibility: visible; animation: home-slot 48s linear infinite both; }
  .marketing-home .market-build { animation: home-build 48s linear infinite both; }
  .marketing-home .market-view-dates,
  .marketing-home .market-view-dates .market-build,
  .marketing-home .market-foot .market-caption > span:nth-child(2) { animation-delay: 12s; }
  .marketing-home .market-view-options,
  .marketing-home .market-view-options .market-build,
  .marketing-home .market-foot .market-caption > span:nth-child(3) { animation-delay: 24s; }
  .marketing-home .market-view-positions,
  .marketing-home .market-view-positions .market-build,
  .marketing-home .market-foot .market-caption > span:nth-child(4) { animation-delay: 36s; }
  /* The question types into the input: the caret sweeps one word every
     0.1s, and each sweep ends as the next begins. */
  .marketing-home .home-chat-placeholder { animation: home-placeholder 12s linear infinite; }
  .marketing-home .home-chat-typed,
  .marketing-home .home-chat-input::after { animation: home-typed 12s linear infinite; }
  .marketing-home .home-chat-typed > span::before { animation: home-word 12s linear infinite; }
  .marketing-home .home-chat-typed > span::after { animation: home-caret 12s linear infinite; }
  .marketing-home .home-chat-typed > span:nth-child(1)::before,
  .marketing-home .home-chat-typed > span:nth-child(1)::after { animation-delay: 0.35s; }
  .marketing-home .home-chat-typed > span:nth-child(2)::before,
  .marketing-home .home-chat-typed > span:nth-child(2)::after { animation-delay: 0.45s; }
  .marketing-home .home-chat-typed > span:nth-child(3)::before,
  .marketing-home .home-chat-typed > span:nth-child(3)::after { animation-delay: 0.55s; }
  .marketing-home .home-chat-typed > span:nth-child(4)::before,
  .marketing-home .home-chat-typed > span:nth-child(4)::after { animation-delay: 0.65s; }
  .marketing-home .home-chat-typed > span:nth-child(5)::before,
  .marketing-home .home-chat-typed > span:nth-child(5)::after { animation-delay: 0.75s; }
  .marketing-home .home-chat-typed > span:nth-child(6)::before,
  .marketing-home .home-chat-typed > span:nth-child(6)::after { animation-delay: 0.85s; }
  .marketing-home .home-chat-typed > span:nth-child(7)::before,
  .marketing-home .home-chat-typed > span:nth-child(7)::after { animation-delay: 0.95s; }
  .marketing-home .home-chat-typed > span:nth-child(8)::before,
  .marketing-home .home-chat-typed > span:nth-child(8)::after { animation-delay: 1.05s; }
  .marketing-home .home-chat-typed > span:nth-child(9)::before,
  .marketing-home .home-chat-typed > span:nth-child(9)::after { animation-delay: 1.15s; }
  .marketing-home .home-chat-typed > span:nth-child(10)::before,
  .marketing-home .home-chat-typed > span:nth-child(10)::after { animation-delay: 1.25s; }
  .marketing-home .home-chat-typed > span:nth-child(11)::before,
  .marketing-home .home-chat-typed > span:nth-child(11)::after { animation-delay: 1.35s; }
  .marketing-home .home-chat-typed > span:nth-child(12)::before,
  .marketing-home .home-chat-typed > span:nth-child(12)::after { animation-delay: 1.45s; }
  .marketing-home .home-chat-typed > span:nth-child(13)::before,
  .marketing-home .home-chat-typed > span:nth-child(13)::after { animation-delay: 1.55s; }
  .marketing-home .home-chat-typed > span:nth-child(14)::before,
  .marketing-home .home-chat-typed > span:nth-child(14)::after { animation-delay: 1.65s; }
  .marketing-home .home-chat-send::before { animation: home-ready 12s linear infinite; }
  .marketing-home .home-chat-send { animation: home-send 12s linear infinite; }
  /* Sent: the question, each tool call in turn, then the facts. */
  .marketing-home .home-chat-ask { animation: home-ask 12s linear infinite; }
  .marketing-home .home-chat-tools { animation: home-tools 12s linear infinite; }
  .marketing-home .home-chat-tools > li { animation: home-row 12s linear infinite backwards; }
  .marketing-home .home-chat-tools > li::before { animation: home-spin 12s linear infinite backwards; }
  .marketing-home .home-chat-tools > li::after { animation: home-done 12s linear infinite backwards; }
  .marketing-home .home-chat-tools > li:nth-child(2),
  .marketing-home .home-chat-tools > li:nth-child(2)::before,
  .marketing-home .home-chat-tools > li:nth-child(2)::after { animation-delay: 0.7s; }
  .marketing-home .home-chat-tools > li:nth-child(3),
  .marketing-home .home-chat-tools > li:nth-child(3)::before,
  .marketing-home .home-chat-tools > li:nth-child(3)::after { animation-delay: 1.4s; }
  .marketing-home .home-chat-reply { animation: home-answer 12s linear infinite; }
  .marketing-home .home-chat-reply > .record-event { animation: home-fact 12s linear infinite backwards; }
  .marketing-home .home-chat-reply > .record-event:nth-child(2) { animation-delay: 0.25s; }
  /* A picked example shows complete and still. */
  .marketing-home .home-chat-choice:checked ~ .home-chat-stage *,
  .marketing-home .home-chat-choice:checked ~ .home-chat-stage *::before,
  .marketing-home .home-chat-choice:checked ~ .home-chat-stage *::after,
  .marketing-home .home-chat-choice:checked ~ .home-chat-tabs > label::before,
  .marketing-home .home-chat-choice:checked ~ .home-chat-tabs > label::after { animation-name: none; }
  .marketing-home .marketing-intro:has(.home-chat-choice:checked) .market-view,
  .marketing-home .marketing-intro:has(.home-chat-choice:checked) .market-build,
  .marketing-home .marketing-intro:has(.home-chat-choice:checked) .market-caption > span { animation-name: none; }
  .marketing-home .home-chat:focus-within *,
  .marketing-home .home-chat:focus-within *::before,
  .marketing-home .home-chat:focus-within *::after { animation-play-state: paused; }
  .marketing-home .home-chat:focus-within ~ .market-stage-wrap .market-view,
  .marketing-home .home-chat:focus-within ~ .market-stage-wrap .market-build,
  .marketing-home .home-chat:focus-within ~ .market-stage-wrap .market-caption > span { animation-play-state: paused; }
  /* One source at a time feeds Slatemark, then your AI, on a 10s loop. */
  .marketing-home .flow-pulse { animation: home-lane 10s linear infinite; }
  .marketing-home .flow-source::after { animation: home-lit 10s linear infinite; }
  .marketing-home .flow-pulse-calc,
  .marketing-home .flow-source-calc::after { animation-delay: 2s; }
  .marketing-home .flow-pulse-sec,
  .marketing-home .flow-source-sec::after { animation-delay: 4s; }
  .marketing-home .flow-pulse-macro,
  .marketing-home .flow-source-macro::after { animation-delay: 6s; }
  .marketing-home .flow-pulse-context,
  .marketing-home .flow-source-context::after { animation-delay: 8s; }
  .marketing-home .flow-pulse-client { animation: home-out 2s linear infinite; }
  .marketing-home .flow-hub::after { animation: home-hub 2s linear infinite; }
  .marketing-home .flow-client::before { animation: home-reply 2s linear infinite; }
  .marketing-home:has(#market-motion-pause:checked) .market-scene,
  .marketing-home:has(#market-motion-pause:checked) .market-scene *,
  .marketing-home:has(#market-motion-pause:checked) .market-caption > span { animation-play-state: paused; }
  .marketing-home:has(#market-motion-pause:checked) .flow *,
  .marketing-home:has(#market-motion-pause:checked) .flow *::before,
  .marketing-home:has(#market-motion-pause:checked) .flow *::after,
  .marketing-home:has(#market-motion-pause:checked) .home-chat *,
  .marketing-home:has(#market-motion-pause:checked) .home-chat *::before,
  .marketing-home:has(#market-motion-pause:checked) .home-chat *::after { animation-play-state: paused; }
  /* Below the hero, motion follows the reader's own scrolling. */
  @supports (animation-timeline: view()) {
    .marketing-home .home-context-note {
      animation: home-stack linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 55%;
    }
    .marketing-home .home-receipt {
      animation: home-receipt linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 50%;
    }
  }
}
@keyframes home-orbit {
  from { transform: rotateX(-16deg) rotateY(-42deg); }
  to { transform: rotateX(-11deg) rotateY(-28deg); }
}
@keyframes home-billboard {
  from { transform: rotateY(42deg) rotateX(16deg); }
  to { transform: rotateY(28deg) rotateX(11deg); }
}
@keyframes home-fade { from { opacity: 0; } }
@keyframes home-rise { from { transform: translateZ(6.5px) scale3d(1, 0.001, 1); } }
@keyframes home-rise-wick { from { transform: translateZ(1px) scale3d(1, 0.001, 1); } }
@keyframes home-rise-volume { from { transform: translateZ(-24px) scale3d(1, 0.001, 1); } }
@keyframes home-level { from { transform: rotateX(90deg) scale3d(0.001, 1, 1); } }
@keyframes home-level-edge { from { transform: translateZ(30px) scale3d(0.001, 1, 1); } }
@keyframes home-ruler { from { transform: translateZ(8px) scale3d(1, 0.001, 1); } }
@keyframes home-scan {
  from { opacity: 0; transform: translateX(-30px) rotateY(90deg); }
  15% { opacity: 1; }
  85% { opacity: 1; }
  to { opacity: 0; transform: translateX(260px) rotateY(90deg); }
}
@keyframes home-pop { from { opacity: 0; transform: translateY(var(--space-2)) scale(0.9); } }
@keyframes home-ping {
  from { opacity: 0.9; transform: scale(0.6); }
  to { opacity: 0; transform: scale(1.8); }
}
/* 48-second rotation: each example owns the first quarter of its offset
   loop. */
@keyframes home-slot {
  from { opacity: 0; }
  0.625%, 23.75% { opacity: 1; }
  25%, to { opacity: 0; }
}
/* A view's objects rise from the floor as its slot opens and lower into it
   as the slot closes, easing out through the middle stop. */
@keyframes home-build {
  from { transform: scale3d(1, 0.001, 1); }
  0.7% { transform: scale3d(1, 0.85, 1); }
  1.25%, 23.75% { transform: none; }
  25%, to { transform: scale3d(1, 0.001, 1); }
}
@keyframes home-progress {
  from { transform: scaleX(0); }
  25% { transform: scaleX(1); }
  25.01%, to { transform: scaleX(0); }
}
/* 12-second conversation, as percentages of 12s (1% is 0.12s): typing
   0.3s to 2.1s, sent at 2.1s, tools from 2.5s, facts at 4.5s. */
@keyframes home-placeholder {
  from, 2.5% { opacity: 1; }
  3%, 17.5% { opacity: 0; }
  18.5%, to { opacity: 1; }
}
@keyframes home-typed {
  from, 2.5% { opacity: 0; }
  3%, 16.5% { opacity: 1; }
  17.5%, to { opacity: 0; }
}
/* A word's cover slides off in 0.1s (0.8333%), the spacing between words,
   and returns while the input is empty again. The caret rides the same
   edge and stays opaque until just after the next word starts, so there
   is always one caret while the question types; once past the edge it is
   clipped away. */
@keyframes home-word {
  from { transform: none; }
  0.8333%, 75% { transform: translateX(100%); }
  76%, to { transform: none; }
}
@keyframes home-caret {
  from { opacity: 1; transform: none; }
  0.8333%, 0.9% { opacity: 1; transform: translateX(100%); }
  0.91%, to { opacity: 0; transform: translateX(100%); }
}
@keyframes home-ready {
  from, 3.3% { opacity: 0; }
  4%, 17% { opacity: 1; }
  17.5%, to { opacity: 0; }
}
@keyframes home-send {
  from, 16% { transform: none; }
  16.8% { transform: scale(0.86); }
  17.6%, to { transform: none; }
}
@keyframes home-ask {
  from, 17.5% { opacity: 0; transform: translateY(var(--space-2)); }
  19%, to { opacity: 1; transform: none; }
}
@keyframes home-tools {
  from, 20.5% { opacity: 0; }
  20.6%, to { opacity: 1; }
}
@keyframes home-row {
  from, 20.8% { opacity: 0; }
  22%, to { opacity: 1; }
}
@keyframes home-spin {
  from, 20.8% { opacity: 0; transform: rotate(0deg); }
  20.9% { opacity: 1; transform: rotate(0deg); }
  25.8% { opacity: 1; transform: rotate(540deg); }
  25.9%, to { opacity: 0; transform: rotate(540deg); }
}
@keyframes home-done {
  from, 25.8% { opacity: 0; transform: rotate(45deg) scale(0.4); }
  27%, to { opacity: 1; transform: rotate(45deg); }
}
@keyframes home-answer {
  from, 37.5% { opacity: 0; }
  38.5%, to { opacity: 1; }
}
@keyframes home-fact {
  from, 37.5% { opacity: 0; transform: translateY(var(--space-1)); }
  39.5%, to { opacity: 1; transform: none; }
}
@keyframes home-lane {
  from { offset-distance: 0%; opacity: 0; }
  2% { opacity: 1; }
  8% { opacity: 1; }
  10%, to { offset-distance: 100%; opacity: 0; }
}
@keyframes home-lit {
  from, 16%, to { opacity: 0; }
  2%, 12% { opacity: 1; }
}
@keyframes home-out {
  from, 45% { offset-distance: 0%; opacity: 0; }
  50% { opacity: 1; }
  72% { opacity: 1; }
  75%, to { offset-distance: 100%; opacity: 0; }
}
@keyframes home-hub {
  from, 36%, 82%, to { opacity: 0; }
  46%, 66% { opacity: 1; }
}
@keyframes home-reply {
  from, 66%, to { opacity: 0; }
  76%, 92% { opacity: 1; }
}
@keyframes home-stack { from { transform: rotateX(18deg) rotateY(-26deg) translateZ(-3rem); } }
@keyframes home-receipt { from { transform: rotateX(18deg) rotateY(-28deg) translateZ(-2rem); } }
@container marketing-workspace (max-width: 50rem) {
  .marketing-home .marketing-intro {
    grid-template-areas: "hero" "record" "stage";
    grid-template-rows: auto;
    row-gap: var(--space-8);
  }
  /* In one column the scene stands in flow above its caption row, so a
     caption that wraps, or the "Pause motion" control wrapping under it,
     moves the scene up rather than running under it. The scene reaches up
     through the row gap to the card's edge. At scale 1, across the four
     views and the whole orbit, the tags span 500px of stage width centred
     112px right of the stage's origin, and the objects reach 251px above
     the origin and 129px below it. Each width step scales the stage so the
     tags fit the mask's solid band, centres them in it, and sizes the
     scene to hold every object with 0.5rem to spare above and below. */
  .marketing-home .market-stage-wrap { min-height: 0; }
  .marketing-home .market-scene {
    position: relative;
    inset: auto;
    height: 22rem;
    margin-top: calc(var(--space-6) * -1);
    -webkit-mask-image: linear-gradient(90deg, transparent, var(--bg) 6%, var(--bg) 94%, transparent);
    mask-image: linear-gradient(90deg, transparent, var(--bg) 6%, var(--bg) 94%, transparent);
  }
  .marketing-home .market-stage { left: calc(50% - 99px); bottom: 122px; scale: 0.88; }
  .marketing-home .home-context-note { transform: none; animation-name: none; }
  .marketing-home .home-flow { grid-template-columns: minmax(0, 1fr); gap: var(--space-6); }
  .marketing-home .flow { height: 19rem; }
  .marketing-home .home-plan-grid { grid-template-columns: minmax(0, 1fr); gap: var(--space-4); }
  .marketing-home .home-receipt-stage { padding-block: var(--space-4) var(--space-8); }
}
@container marketing-workspace (min-width: 50.01rem) and (max-width: 72rem) {
  .marketing-home .flow-canvas { transform: translate(-50%, -50%) rotateX(14deg) rotateY(-9deg) scale(0.72); }
}
@container marketing-workspace (max-width: 36rem) {
  .marketing-home .home-ledger { grid-template-columns: minmax(0, 1fr); }
  .marketing-home .home-plan { padding: var(--space-6); }
  /* A narrow column has no room for the receipt's tilt; it lies flat. */
  .marketing-home .home-receipt { padding-inline: var(--space-5); transform: none; animation-name: none; }
  .marketing-home .home-receipt-stamp { transform: rotate(-12deg); }
  .marketing-home .market-scene { height: 15.25rem; }
  .marketing-home .market-stage { left: calc(50% - 67px); bottom: 85px; scale: 0.6; }
}
@container marketing-workspace (max-width: 36rem) {
  .marketing-home .flow { height: 25rem; }
  .marketing-home .flow-canvas {
    width: 360px;
    height: 400px;
    transform: translate(-50%, -50%) rotateX(12deg) rotateY(-6deg);
  }
  .marketing-home .flow-lines-wide { display: none; }
  .marketing-home .flow-lines-narrow { display: block; width: 360px; height: 400px; }
  .marketing-home .flow-hub { left: 224px; top: 80px; }
  .marketing-home .flow-client { left: 214px; top: 300px; }
  .marketing-home .flow-pulse-market { offset-path: path("M 176 40 L 224 140"); }
  .marketing-home .flow-pulse-calc { offset-path: path("M 176 100 L 224 140"); }
  .marketing-home .flow-pulse-sec { offset-path: path("M 176 160 L 224 140"); }
  .marketing-home .flow-pulse-macro { offset-path: path("M 176 220 L 224 140"); }
  .marketing-home .flow-pulse-context { offset-path: path("M 176 280 L 224 140"); }
  .marketing-home .flow-pulse-client { offset-path: path("M 284 200 L 284 300"); }
}
@container marketing-workspace (max-width: 22rem) {
  .marketing-home .market-scene { height: 12.375rem; }
  .marketing-home .market-stage { left: calc(50% - 54px); bottom: 70px; scale: 0.48; }
  .marketing-home .flow-canvas { transform: translate(-50%, -50%) rotateX(12deg) rotateY(-6deg) scale(0.82); }
}
/* Phones keep the first sourced value inside the first 812px screen. */
@media (max-width: 640px) {
  .marketing-home .marketing-intro > .home-chat { padding: var(--space-4); }
  .marketing-home .marketing-intro { row-gap: var(--space-6); }
  .marketing-home .home-chat-bar { margin-bottom: var(--space-2); padding-bottom: 0; border-bottom: 0; }
  .marketing-home .home-chat-dots { display: none; }
  .marketing-home .home-chat > h2 { margin-bottom: var(--space-2); }
  .marketing-home .home-chat-example { gap: var(--space-2); }
  .marketing-home .home-chat-meta .pill { padding: 0 var(--space-1); }
  .marketing-home .home-chat-ask { padding: var(--space-2) var(--space-3); font-size: var(--fs-base-sm); }
  .marketing-home .home-chat-reply > .record-event { padding-block: var(--space-2); }
  .marketing-home .home-chat-reply::before { display: none; }
  .marketing-home .home-chat-tools { gap: 0; }
  .marketing-home .home-chat-tools > li { min-height: 1.5rem; }
  .marketing-home .marketing-intro > .hero .lede { margin-bottom: var(--space-4); }
  .marketing-home .marketing-intro .hero-cta { margin-block: var(--space-4) var(--space-2); }
}
/* Laptop and tablet windows. In two columns the headline scales between the
   approved 36px and 56px so it holds two lines, and the scene ends at its
   caption row, as it does in one column, so a wrapped caption or the "Pause
   motion" row never runs under it. The scene's mask clips whatever paints
   outside it, and its perspective is drawn from its own height, so the
   stage stands a third of the way up the scene and each width and height
   step scales it: across the four views and the whole orbit, every object
   stays inside the scene, below the hero text and above the caption row,
   and every tag stays clear of the card. */
@container marketing-workspace (min-width: 50.01rem) {
  .marketing-home .marketing-intro > .card.hero h1 {
    font-size: clamp(var(--fs-3xl-mobile), 5cqi - 0.15rem, var(--fs-3xl));
    text-wrap: balance;
  }
  .marketing-home .market-scene {
    position: relative;
    inset: auto;
    flex: 1 0 auto;
    margin: calc(var(--space-6) * -1) -14rem 0 -6rem;
  }
  .marketing-home .market-stage { scale: 0.84; }
  /* The scene's mask fades its left 22%, and the filing tag sits further
     left than any other view's tag, so the filing view stands 3.5rem right
     of the others: its tags start in the solid band through the whole orbit
     at every two-column step and stay clear of the card. */
  .marketing-home .market-view-dates .market-stage { translate: 3.5rem; }
}
@container marketing-workspace (min-width: 50.01rem) and (max-width: 68rem) {
  .marketing-home .market-stage { scale: 0.74; }
}
/* The composition above needs about 855px of viewport height; laptop
   browser windows run about 590 to 830px. Shorter windows step the rhythm,
   the card's chrome and the stage down so the hero, the whole card and the
   caption share the first screen, and the stage takes the height the card
   leaves beside the hero. */
@media (max-height: 840px) {
  @container marketing-workspace (min-width: 50.01rem) {
    .marketing-home .marketing-intro { padding-block: var(--space-2) var(--space-4); }
    .marketing-home .marketing-intro > .home-chat { padding: var(--space-5); }
    .marketing-home .home-chat-bar { margin-bottom: var(--space-3); padding-bottom: var(--space-2); }
    .marketing-home .home-chat > h2 { margin-bottom: var(--space-2); }
    .marketing-home .home-chat-example { gap: var(--space-2); }
    .marketing-home .home-chat-ask { padding: var(--space-2) var(--space-3); }
    .marketing-home .home-chat-tools { gap: 0; }
    .marketing-home .home-chat-tools > li { min-height: 1.5rem; }
    .marketing-home .home-chat-reply > .record-event { padding-block: var(--space-2); }
    .marketing-home .home-chat-tabs { margin-top: var(--space-3); }
    .marketing-home .home-chat > .muted-note { margin-top: var(--space-3); }
    .marketing-home .market-stage-wrap { align-self: stretch; min-height: 16.25rem; }
  }
  @container marketing-workspace (min-width: 68.01rem) {
    .marketing-home .market-stage { scale: 0.65; }
  }
}
@media (max-height: 720px) {
  @container marketing-workspace (min-width: 50.01rem) {
    .marketing-home .marketing-intro { margin-top: calc(var(--space-4) * -1); padding-top: 0; }
    .marketing-home .marketing-intro > .hero .lede { margin-bottom: var(--space-4); }
    .marketing-home .marketing-intro .hero-cta { margin-block: var(--space-4) var(--space-2); }
    .marketing-home .marketing-intro > .home-chat { padding: var(--space-4); }
    .marketing-home .home-chat-bar { margin-bottom: var(--space-2); padding-bottom: 0; border-bottom: 0; }
    .marketing-home .home-chat-meta .pill { padding: 0 var(--space-1); }
    .marketing-home .home-chat-ask { font-size: var(--fs-base-sm); }
    .marketing-home .home-chat-reply::before { display: none; }
    .marketing-home .home-chat-reply .record-symbol { font-size: var(--fs-lg); }
    .marketing-home .home-chat-tabs { margin-top: var(--space-2); }
    .marketing-home .home-chat > .muted-note { margin-top: var(--space-2); }
    .marketing-home .market-stage-wrap { min-height: 13.5rem; }
    .marketing-home .market-stage { scale: 0.6; }
  }
  @container marketing-workspace (min-width: 68.01rem) {
    .marketing-home .market-stage { scale: 0.46; }
  }
}
@media (forced-colors: active) {
  .marketing-home .market-stage-wrap,
  .marketing-home .flow,
  .marketing-home .home-receipt-code,
  .marketing-home .home-receipt-stamp { display: none; }
  .marketing-home .home-chat-ask,
  .marketing-home .home-chat-input,
  .marketing-home .home-receipt { border: 1px solid CanvasText; }
  .marketing-home .home-chat-tabs > label::before { box-shadow: none; border: 2px solid Highlight; }
}
@media print {
  .marketing-home .market-stage-wrap,
  .marketing-home .flow,
  .marketing-home .home-chat-tabs,
  .marketing-home .home-chat-input { display: none; }
}

/* Features experience. The public Features page is the second reviewed
   exception to the flat marketing grammar: an illustrated tour of what
   Slatemark supplies. Every illustration is aria-hidden decoration that
   restates the copy beside it. None shows a market value, a live quote,
   a chart Slatemark renders or an outcome. The static composition below
   is complete; motion lives only under `prefers-reduced-motion:
   no-preference`, animates opacity, transform or a motion-path offset so
   no layout moves, and the "Pause motion" control stops every loop.
   docs/frontend-design-system.md records the exception and its limits. */
.marketing-features .marketing-intro {
  position: relative;
  isolation: isolate;
  grid-template-areas: "hero record" "hero stage";
  grid-template-rows: auto 1fr;
  row-gap: var(--space-4);
}
.marketing-features .marketing-intro::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -6rem 0 -4rem;
  background:
    radial-gradient(32% 40% at 74% 80%, color-mix(in srgb, var(--accent) 9%, transparent), transparent 70%),
    radial-gradient(30% 36% at 24% 22%, color-mix(in srgb, var(--info) 7%, transparent), transparent 72%);
  pointer-events: none;
}
.marketing-features .marketing-intro > .hero { grid-area: hero; }

/* The record reads as the path one question takes: you ask, Slatemark
   supplies sourced results, your AI explains. A rail joins the three
   steps, and Slatemark's step carries the brand mark. */
.marketing-features .marketing-intro > .features-trace {
  grid-area: record;
  position: relative;
  border: 1px solid var(--border);
  background: var(--surface);
}
.marketing-features .features-trace::before {
  content: "";
  position: absolute;
  top: -1px;
  left: var(--space-8);
  right: var(--space-8);
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
}
.marketing-features .features-trace .journal-preview-facts { margin-block: var(--space-2); }
.marketing-features .features-trace .record-event {
  position: relative;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-1);
  min-height: 0;
  padding: var(--space-3) 0 var(--space-3) 3.25rem;
  border-top: 0;
}
.marketing-features .features-trace .record-event::before,
.marketing-features .features-trace .record-event::after { content: ""; position: absolute; }
.marketing-features .features-trace .record-event::before {
  left: 0;
  top: var(--space-3);
  width: 2.25rem;
  height: 2.25rem;
  box-sizing: border-box;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  background: radial-gradient(circle, var(--text-dim) 0 0.1875rem, transparent 0.25rem), var(--bg);
}
.marketing-features .features-trace .record-event::after {
  left: calc(1.125rem - 1px);
  top: calc(var(--space-3) + 2.25rem);
  bottom: calc(var(--space-3) * -1);
  width: 2px;
  background: linear-gradient(var(--border-strong), var(--accent));
  transform-origin: center top;
}
.marketing-features .features-trace .record-event:last-child::after { content: none; }
.marketing-features .features-trace .record-event:nth-child(2)::before {
  border-color: var(--accent);
  background:
    linear-gradient(var(--accent), var(--accent)) center / 2px 1.25rem no-repeat,
    linear-gradient(var(--border-strong), var(--border-strong)) center 46% / 1.25rem 2px no-repeat,
    linear-gradient(var(--accent), var(--accent)) center 38% / 0.5rem 0.625rem no-repeat,
    var(--bg);
  box-shadow: 0 0 0 4px var(--accent-wash-strong), 0 0 24px color-mix(in srgb, var(--accent) 8%, transparent);
}
.marketing-features .features-trace .record-event:nth-child(3)::before {
  border-color: var(--accent);
  background: radial-gradient(circle, var(--accent) 0 0.25rem, color-mix(in srgb, var(--accent) 9%, transparent) 0.3125rem 0.625rem, transparent 0.6875rem), var(--bg);
}

/* The illustrative stack under the record: the facts behind an answer.
   Five source layers rise into the answer, and a spark climbs the beam
   through them. Each layer is a 3D group whose face and glint are its
   pseudo-elements, so fading a face never flattens the group. Nothing
   ticks or counts, and no layer shows a value. */
.marketing-features .features-stage {
  grid-area: stage;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-width: 0;
  min-height: 18.5rem;
}
.marketing-features .features-scene {
  position: absolute;
  inset: 0 0 var(--control-target);
  overflow: hidden;
  perspective: 56rem;
  perspective-origin: 50% -30%;
  pointer-events: none;
}
.marketing-features .features-stack {
  position: absolute;
  left: 50%;
  top: 69%;
  width: 0;
  height: 0;
  transform-style: preserve-3d;
  transform: rotateX(58deg) rotateZ(-40deg);
}
.marketing-features .features-stack > span { position: absolute; transform-style: preserve-3d; }
.marketing-features .features-slate {
  left: -5rem;
  top: -3.25rem;
  width: 10rem;
  height: 6.5rem;
}
.marketing-features .features-slate::before,
.marketing-features .features-slate::after {
  content: "";
  position: absolute;
  inset: 0;
  box-sizing: border-box;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
}
.marketing-features .features-slate::before {
  background: linear-gradient(135deg, color-mix(in srgb, var(--surface-2) 72%, transparent), color-mix(in srgb, var(--surface) 55%, transparent));
}
.marketing-features .features-slate::after {
  border-color: var(--accent);
  background: var(--accent-wash);
  box-shadow: 0 0 28px color-mix(in srgb, var(--accent) 8%, transparent);
  opacity: 0;
}
.marketing-features .features-slate-context::before { border-style: dashed; }
.marketing-features .features-slate-macro { translate: 0 0 1.5rem; }
.marketing-features .features-slate-sec { translate: 0 0 3rem; }
.marketing-features .features-slate-calc { translate: 0 0 4.5rem; }
.marketing-features .features-slate-market { translate: 0 0 6rem; }
.marketing-features .features-slate-answer { translate: 0 0 8.5rem; }
.marketing-features .features-slate-answer::before {
  border-color: var(--accent);
  background:
    linear-gradient(var(--surface-2), var(--surface-2)) 0.875rem 1rem / 55% 0.4375rem no-repeat,
    linear-gradient(var(--border), var(--border)) 0.875rem 1.875rem / 70% 0.4375rem no-repeat,
    linear-gradient(var(--accent-wash-strong), var(--accent-wash-strong)) 0.875rem 2.75rem / 40% 0.4375rem no-repeat,
    color-mix(in srgb, var(--surface) 90%, transparent);
  box-shadow: 0 0 36px color-mix(in srgb, var(--accent) 8%, transparent);
}
.marketing-features .features-beam {
  left: -1px;
  top: 0;
  width: 2px;
  height: 8.5rem;
  transform-origin: center top;
  transform: rotateX(90deg);
  background: linear-gradient(var(--accent-wash-strong), var(--accent));
}
.marketing-features .features-spark {
  left: -0.3125rem;
  top: -0.3125rem;
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 50%, transparent);
  opacity: 0;
}
/* Tags counter-rotate against the stack so their text faces the reader.
   They alternate sides, starting with the answer on the right, so a
   compact stack still leaves each label its own line. */
.marketing-features .features-stack .features-tag {
  position: absolute;
  left: 100%;
  top: 100%;
  width: 0;
  height: 0;
  transform-style: preserve-3d;
  transform: rotateZ(40deg) rotateX(-58deg);
}
.marketing-features .features-slate-market .features-tag,
.marketing-features .features-slate-sec .features-tag,
.marketing-features .features-slate-context .features-tag { left: 0; top: 0; }
.marketing-features .features-tag > span {
  position: absolute;
  padding: 0 var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-medium);
  line-height: var(--lh-body);
  white-space: nowrap;
}
.marketing-features .features-stack .features-tag > span { left: var(--space-3); bottom: calc(var(--space-3) * -1); }
.marketing-features .features-slate-market .features-tag > span,
.marketing-features .features-slate-sec .features-tag > span,
.marketing-features .features-slate-context .features-tag > span { left: auto; right: var(--space-3); }
.marketing-features .features-stack .features-tag > span::before {
  content: "";
  position: absolute;
  right: 100%;
  top: 50%;
  width: var(--space-3);
  height: 1px;
  background: var(--border-strong);
}
.marketing-features .features-slate-market .features-tag > span::before,
.marketing-features .features-slate-sec .features-tag > span::before,
.marketing-features .features-slate-context .features-tag > span::before { left: 100%; right: auto; }
.marketing-features .features-slate-answer .features-tag > span { border-color: var(--accent); color: var(--accent); }
.marketing-features .features-slate-context .features-tag > span { border-style: dashed; color: var(--text-dim); }
.marketing-features .features-foot {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
  min-height: var(--control-target);
}
.marketing-features .features-caption { margin: 0; color: var(--text-dim); font-size: var(--fs-base-sm); }
.marketing-features .features-motion { display: none; margin: 0; }
.marketing-features .features-motion label { color: var(--text-dim); font-size: var(--fs-base-sm); cursor: pointer; }

/* Each section's illustration sits under its heading, where the lead
   column otherwise ends early. Shared pieces: a label chip, skeleton
   bars that stand in for values, and the brand mark. */
.marketing-features .features-visual {
  position: relative;
  min-width: 0;
  margin-top: var(--space-8);
  pointer-events: none;
}
.marketing-features .features-visual p { margin: 0; }
.marketing-features .features-chip {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-medium);
  line-height: var(--lh-body);
  white-space: nowrap;
}
.marketing-features .features-bar {
  display: block;
  flex: 1 1 auto;
  height: 0.5rem;
  border-radius: 999px;
  background: var(--surface-2);
}
.marketing-features .features-bar-value {
  flex: 0 1 6rem;
  height: 1rem;
  background: color-mix(in srgb, var(--data-neutral) 45%, var(--surface-2));
}
.marketing-features .features-bar-short { flex: 0 1 4rem; }
.marketing-features .features-mark {
  display: inline-block;
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  background:
    linear-gradient(var(--accent), var(--accent)) center / 12% 100% no-repeat,
    linear-gradient(var(--border-strong), var(--border-strong)) center 46% / 100% 10% no-repeat,
    linear-gradient(var(--accent), var(--accent)) center 36% / 38% 46% no-repeat;
}

/* Grounding: a lens passes over a result and shows the source and time
   fields each value carries. The cards share one width in container
   units so the lens's view lines up with the card under it. */
.marketing-features .features-lens {
  container-type: inline-size;
  max-width: 24rem;
  height: 12.5rem;
}
.marketing-features .features-lens-card {
  position: absolute;
  left: 0;
  top: 0;
  display: grid;
  align-content: center;
  gap: var(--space-2);
  box-sizing: border-box;
  width: 100cqi;
  height: 12.5rem;
  overflow: hidden;
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.marketing-features .features-lens-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 1.75rem;
}
.marketing-features .features-lens-row > .features-chip,
.marketing-features .features-lens-row > code { flex: none; }
.marketing-features .features-lens-row:nth-child(3) { margin-top: var(--space-2); padding-top: var(--space-3); border-top: 1px solid var(--border); }
/* At rest the lens frames the fields beside the chips. */
.marketing-features .features-lens-glass {
  position: absolute;
  left: calc(36cqi - 4rem);
  top: 2.25rem;
  width: 8rem;
  height: 8rem;
  box-sizing: border-box;
  overflow: hidden;
  border: 2px solid var(--accent);
  border-radius: 50%;
  box-shadow: 0 0 0 6px var(--accent-wash), 0 0 36px color-mix(in srgb, var(--accent) 8%, transparent), 0 18px 36px var(--bg);
}
.marketing-features .features-lens-xray {
  left: calc(-36cqi + 4rem - 2px);
  top: calc(-2.25rem - 2px);
  border-color: transparent;
  background:
    linear-gradient(var(--accent-wash) 1px, transparent 1px) 0 0 / 100% 0.75rem,
    linear-gradient(90deg, var(--accent-wash) 1px, transparent 1px) 0 0 / 0.75rem 100%,
    var(--bg);
}
.marketing-features .features-lens-xray code {
  color: var(--accent);
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-medium);
  line-height: var(--lh-body);
}
.marketing-features .features-lens-xray .features-chip { background: var(--accent-wash-strong); }

/* Journal: a private entry keeps the rule version it used, and the
   Strategy Scorecard waits for five scored trades before it shows
   figures. The dots are a count, not a result, so they stay neutral. */
.marketing-features .features-journal { max-width: 24rem; perspective: 60rem; }
.marketing-features .features-note {
  position: relative;
  display: grid;
  gap: var(--space-3);
  margin-inline-end: var(--space-8);
  padding: var(--space-5);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: 0 24px 48px var(--bg);
  transform-style: preserve-3d;
  transform-origin: 0 50%;
  transform: rotateX(4deg) rotateY(10deg);
}
.marketing-features .features-note::before,
.marketing-features .features-note::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.marketing-features .features-note::before {
  background: color-mix(in srgb, var(--surface) 70%, var(--bg));
  transform: translate3d(var(--space-4), calc(var(--space-3) * -1), -2rem);
}
.marketing-features .features-note::after {
  background: color-mix(in srgb, var(--surface) 42%, var(--bg));
  transform: translate3d(var(--space-8), calc(var(--space-6) * -1), -4rem);
}
.marketing-features .features-note-head,
.marketing-features .features-note-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
}
.marketing-features .features-note-head { flex-wrap: wrap; justify-content: space-between; color: var(--text); font-weight: var(--fw-medium); }
.marketing-features .features-note-head .features-chip { background: var(--accent-wash-strong); color: var(--accent); }
.marketing-features .features-note-row > span:first-child { flex: 0 1 7rem; min-width: 0; }
.marketing-features .features-journal > .features-gate {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  margin-top: var(--space-8);
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
}
.marketing-features .features-gate-dots { display: flex; gap: var(--space-2); }
.marketing-features .features-gate-dots > span {
  position: relative;
  width: 1rem;
  height: 1rem;
  box-sizing: border-box;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
}
.marketing-features .features-gate-dots > span::after {
  content: "";
  position: absolute;
  inset: 2px;
  border-radius: 50%;
  background: var(--data-neutral);
}

/* Ready-made questions drift past as suggestions. They are Home's
   fictional example questions, word for word, each with its plan. */
.marketing-features .features-marquee {
  display: grid;
  gap: var(--space-3);
  margin: 0 0 var(--space-6);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, var(--bg) 10%, var(--bg) 90%, transparent);
  mask-image: linear-gradient(90deg, transparent, var(--bg) 10%, var(--bg) 90%, transparent);
}
.marketing-features .features-marquee-track {
  display: flex;
  gap: var(--space-3);
  width: max-content;
  padding-inline-end: var(--space-3);
}
.marketing-features .features-marquee-row:nth-child(2) .features-marquee-track { transform: translateX(-18%); }
.marketing-features .features-question {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4) var(--space-2) var(--space-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-base-sm);
  white-space: nowrap;
}

/* Research breadth: Free's public sources orbit Slatemark. Labels turn
   against the ring so they always face the reader. */
.marketing-features .features-orbit {
  container-type: inline-size;
  height: 18rem;
  max-width: 28rem;
  overflow: hidden;
  perspective: 50rem;
  perspective-origin: 50% 10%;
  -webkit-mask-image: linear-gradient(90deg, transparent, var(--bg) 8%, var(--bg) 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, var(--bg) 8%, var(--bg) 92%, transparent);
}
.marketing-features .features-orbit-plane {
  position: absolute;
  left: 50%;
  top: 52%;
  width: 0;
  height: 0;
  transform-style: preserve-3d;
  transform: rotateX(64deg);
}
.marketing-features .features-orbit-plane > span,
.marketing-features .features-orbit-ring > span { position: absolute; transform-style: preserve-3d; }
.marketing-features .features-orbit-track {
  left: -34cqi;
  top: -34cqi;
  width: 68cqi;
  height: 68cqi;
  box-sizing: border-box;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  box-shadow: 0 0 40px color-mix(in srgb, var(--accent) 5%, transparent), inset 0 0 40px color-mix(in srgb, var(--accent) 6%, transparent);
}
.marketing-features .features-orbit-track-inner {
  left: -18cqi;
  top: -18cqi;
  width: 36cqi;
  height: 36cqi;
  border-style: dashed;
  border-color: var(--border);
  box-shadow: none;
}
.marketing-features .features-orbit-ring { left: 0; top: 0; width: 0; height: 0; }
.marketing-features .features-orbit-node { left: 0; top: 0; width: 0; height: 0; }
.marketing-features .features-orbit-node:nth-child(1) { transform: rotateZ(0deg) translateX(34cqi) rotateZ(0deg); }
.marketing-features .features-orbit-node:nth-child(2) { transform: rotateZ(45deg) translateX(34cqi) rotateZ(-45deg); }
.marketing-features .features-orbit-node:nth-child(3) { transform: rotateZ(90deg) translateX(34cqi) rotateZ(-90deg); }
.marketing-features .features-orbit-node:nth-child(4) { transform: rotateZ(135deg) translateX(34cqi) rotateZ(-135deg); }
.marketing-features .features-orbit-node:nth-child(5) { transform: rotateZ(180deg) translateX(34cqi) rotateZ(-180deg); }
.marketing-features .features-orbit-node:nth-child(6) { transform: rotateZ(225deg) translateX(34cqi) rotateZ(-225deg); }
.marketing-features .features-orbit-node:nth-child(7) { transform: rotateZ(270deg) translateX(34cqi) rotateZ(-270deg); }
.marketing-features .features-orbit-node:nth-child(8) { transform: rotateZ(315deg) translateX(34cqi) rotateZ(-315deg); }
.marketing-features .features-orbit-node::before {
  content: "";
  position: absolute;
  left: -0.3125rem;
  top: -0.3125rem;
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 50%, transparent);
}
.marketing-features .features-orbit .features-tag {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  transform-style: preserve-3d;
  transform: rotateX(-64deg);
}
.marketing-features .features-orbit .features-tag > span { left: 0; bottom: var(--space-2); translate: -50% 0; }
.marketing-features .features-orbit-core {
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  transform: rotateX(-64deg) translateY(-1.5rem);
}
.marketing-features .features-orbit-core::before {
  content: "";
  position: absolute;
  left: -3.5rem;
  top: -3.5rem;
  width: 7rem;
  height: 7rem;
  border-radius: 50%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--accent) 9%, transparent), transparent);
}
.marketing-features .features-orbit-core > .features-mark {
  position: absolute;
  left: -1.75rem;
  top: -1.75rem;
  width: 3.5rem;
  height: 3.5rem;
  box-sizing: border-box;
  padding: var(--space-2);
  border: 1px solid var(--accent);
  border-radius: var(--radius-lg);
  background-color: var(--surface-2);
  background-origin: content-box;
  box-shadow: 0 0 28px color-mix(in srgb, var(--accent) 8%, transparent);
}

/* Catalyst calendar: market dates land in your own calendar, with an
   optional reminder. The grid has no numbers, so it names no date. */
.marketing-features .features-calendar { max-width: 22rem; perspective: 60rem; }
.marketing-features .features-calendar-card {
  position: relative;
  padding: var(--space-4) var(--space-4) var(--space-5);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: 0 24px 48px var(--bg);
  transform-origin: 0 50%;
  transform: rotateX(4deg) rotateY(10deg);
}
.marketing-features .features-calendar-card > .features-calendar-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
  color: var(--text);
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-medium);
}
.marketing-features .features-calendar-head .features-chip { background: var(--accent-wash-strong); color: var(--accent); }
.marketing-features .features-calendar-card > .features-calendar-days {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  margin-bottom: var(--space-1);
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
  text-align: center;
}
.marketing-features .features-calendar-grid {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding-top: 8.25rem;
}
.marketing-features .features-calendar-grid::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 7.5rem;
  box-sizing: border-box;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background:
    linear-gradient(var(--border) 1px, transparent 1px) 0 0 / 100% 20%,
    linear-gradient(90deg, var(--border) 1px, transparent 1px) 0 0 / calc(100% / 7) 100%;
}
.marketing-features .features-event {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--text);
  font-size: var(--fs-base-sm);
}
/* Rows are 1.5rem tall: expiration sits in the third week's Friday and
   the Fed meeting across the fifth week's Tuesday and Wednesday. */
.marketing-features .features-event::before {
  content: "";
  position: absolute;
  top: calc(3rem + 1px);
  left: calc(500% / 7 + 1px);
  width: calc(100% / 7 - 1px);
  height: calc(1.5rem - 1px);
  background: var(--accent-wash-strong);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.marketing-features .features-event-fed::before {
  top: calc(6rem + 1px);
  left: calc(200% / 7 + 1px);
  width: calc(200% / 7 - 1px);
  background: var(--info-bg);
  box-shadow: inset 0 0 0 1px var(--info);
}
.marketing-features .features-event::after {
  content: "";
  width: 0.625rem;
  height: 0.625rem;
  order: -1;
  border-radius: 2px;
  background: var(--accent);
}
.marketing-features .features-event-fed::after { background: var(--info); }
.marketing-features .features-reminder {
  position: absolute;
  right: 6rem;
  top: calc(var(--space-4) * -1);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text);
  font-size: var(--fs-base-sm);
  box-shadow: 0 12px 24px var(--bg);
}
.marketing-features .features-reminder::before {
  content: "";
  width: 0.625rem;
  height: 0.75rem;
  border-radius: 50% 50% 2px 2px / 60% 60% 2px 2px;
  background: var(--accent);
  box-shadow: 0 0.1875rem 0 -0.0625rem var(--accent);
}

/* Brokerage: account facts flow one way, into Slatemark. The way back,
   to place orders or move funds, does not exist, so its lane is locked. */
.marketing-features .features-boundary {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  align-items: center;
  gap: var(--space-6) var(--space-3);
  max-width: 28rem;
}
.marketing-features .features-node {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  grid-row: 1 / 3;
  min-height: 7.5rem;
  padding: var(--space-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-medium);
  text-align: center;
}
.marketing-features .features-node-broker { grid-column: 1; max-width: 6rem; }
.marketing-features .features-node-broker::before {
  content: "";
  width: 1.5rem;
  height: 1.25rem;
  background:
    linear-gradient(var(--data-neutral), var(--data-neutral)) 0 0 / 100% 3px no-repeat,
    linear-gradient(90deg, var(--data-neutral) 3px, transparent 3px) 2px 5px / 0.4375rem 0.625rem repeat-x,
    linear-gradient(var(--data-neutral), var(--data-neutral)) 0 100% / 100% 3px no-repeat;
}
.marketing-features .features-node-slatemark {
  grid-column: 3;
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-wash), 0 0 28px color-mix(in srgb, var(--accent) 8%, transparent);
}
.marketing-features .features-lane {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  grid-column: 2;
  min-height: 3rem;
  padding-top: var(--space-6);
}
.marketing-features .features-lane::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: var(--space-3);
  height: 2px;
  background: linear-gradient(90deg, var(--data-neutral), var(--accent));
}
.marketing-features .features-lane::after {
  content: "";
  position: absolute;
  right: 0;
  top: calc(var(--space-3) - 0.3125rem);
  width: 0.5rem;
  height: 0.5rem;
  border: solid var(--accent);
  border-width: 2px 2px 0 0;
  transform: rotate(45deg);
}
.marketing-features .features-lane-label {
  position: absolute;
  left: 50%;
  top: calc(var(--space-3) - 0.75rem);
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--accent);
  font-size: var(--fs-base-sm);
  font-weight: var(--fw-medium);
  line-height: var(--lh-body);
  translate: -50% 0;
}
.marketing-features .features-lane-track {
  display: flex;
  flex: 1 1 100%;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
}
.marketing-features .features-packet {
  padding: 0 var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  font-size: var(--fs-base-sm);
  line-height: var(--lh-body);
  white-space: nowrap;
}
.marketing-features .features-lane-blocked { grid-row: 2; }
.marketing-features .features-lane-blocked::before {
  background: repeating-linear-gradient(90deg, var(--border-strong) 0 0.375rem, transparent 0.375rem 0.75rem);
}
.marketing-features .features-lane-blocked::after {
  left: 0;
  right: auto;
  border-color: var(--border-strong);
  border-width: 0 0 2px 2px;
}
.marketing-features .features-lock {
  position: absolute;
  left: 50%;
  top: calc(var(--space-3) - 0.375rem);
  width: 1.125rem;
  height: 0.875rem;
  border-radius: 3px;
  background: var(--text-dim);
  box-shadow: 0 0 0 0.25rem var(--bg);
  translate: -50% 0;
}
.marketing-features .features-lock::before {
  content: "";
  position: absolute;
  left: 0.1875rem;
  bottom: 100%;
  width: 0.75rem;
  height: 0.5rem;
  box-sizing: border-box;
  border: 2px solid var(--text-dim);
  border-bottom: 0;
  border-radius: 0.375rem 0.375rem 0 0;
}
.marketing-features .features-blocked {
  color: var(--text-dim);
  font-size: var(--fs-base-sm);
  text-decoration: line-through;
  white-space: nowrap;
}

/* Closing: one lit panel with the brand mark on its level line. */
.marketing-features .marketing-closing {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin-top: var(--space-8);
  padding: var(--space-12) var(--space-8);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(50% 90% at 86% 50%, color-mix(in srgb, var(--accent) 9%, transparent), transparent 72%),
    linear-gradient(160deg, var(--surface), var(--bg) 72%);
}
.marketing-features .marketing-closing > h2,
.marketing-features .marketing-closing > .lede,
.marketing-features .marketing-closing > .hero-cta { position: relative; max-width: 36rem; }
.marketing-features .features-closing-art {
  position: absolute;
  z-index: -1;
  top: 0;
  right: 0;
  bottom: 0;
  width: 42%;
  pointer-events: none;
}
.marketing-features .features-closing-level {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--border-strong) 30%, var(--border-strong));
}
.marketing-features .features-closing-sweep {
  position: absolute;
  left: 0;
  top: calc(50% - 1px);
  width: 30%;
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  box-shadow: 0 0 16px color-mix(in srgb, var(--accent) 50%, transparent);
  opacity: 0;
}
.marketing-features .features-closing-art > .features-mark {
  position: absolute;
  right: 20%;
  top: calc(50% - 3.5rem);
  width: 7rem;
  height: 7rem;
  background:
    linear-gradient(var(--accent), var(--accent)) center / 3px 100% no-repeat,
    linear-gradient(var(--accent), var(--accent)) center 40% / 1.75rem 3.25rem no-repeat;
  filter: drop-shadow(0 0 18px color-mix(in srgb, var(--accent) 8%, transparent)) drop-shadow(0 0 36px color-mix(in srgb, var(--accent) 8%, transparent));
}

/* The reviewed Features motion. Durations, delays and keyframes are
   inventoried by the design-system gallery motion contract.
   - The record traces its three steps and the stack assembles once,
     ending within five seconds.
   - The stack's sway and climbing spark, the orbit, the question drift,
     the brokerage lane and the closing sweep run indefinitely inside
     hidden illustrations. "Pause motion" stops them all (WCAG 2.2.2).
   - The lens, the journal entry, the Scorecard count and the calendar
     move only with the reader's own scrolling, where scroll timelines
     are supported. */
@media (prefers-reduced-motion: no-preference) {
  .marketing-features .features-motion { display: flex; align-items: center; gap: var(--space-2); min-height: var(--control-target); }
  .marketing-features .features-trace .record-event { animation: features-rise 0.6s cubic-bezier(0.2, 0.8, 0.2, 1) 0.2s both; }
  .marketing-features .features-trace .record-event::before { animation: features-node 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) 0.2s both; }
  .marketing-features .features-trace .record-event::after { animation: features-draw 0.45s ease-out 0.6s both; }
  .marketing-features .features-trace .record-event:nth-child(2),
  .marketing-features .features-trace .record-event:nth-child(2)::before { animation-delay: 0.65s; }
  .marketing-features .features-trace .record-event:nth-child(2)::after { animation-delay: 1.05s; }
  .marketing-features .features-trace .record-event:nth-child(3),
  .marketing-features .features-trace .record-event:nth-child(3)::before { animation-delay: 1.1s; }
  .marketing-features .features-slate { animation: features-assemble 0.8s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
  .marketing-features .features-slate::before { animation: features-fade 0.5s ease-out both; }
  .marketing-features .features-slate-context,
  .marketing-features .features-slate-context::before { animation-delay: 0.3s; }
  .marketing-features .features-slate-macro,
  .marketing-features .features-slate-macro::before { animation-delay: 0.42s; }
  .marketing-features .features-slate-sec,
  .marketing-features .features-slate-sec::before { animation-delay: 0.54s; }
  .marketing-features .features-slate-calc,
  .marketing-features .features-slate-calc::before { animation-delay: 0.66s; }
  .marketing-features .features-slate-market,
  .marketing-features .features-slate-market::before { animation-delay: 0.78s; }
  .marketing-features .features-slate-answer,
  .marketing-features .features-slate-answer::before { animation-delay: 1.1s; }
  .marketing-features .features-stack .features-tag > span { animation: features-pop 0.4s ease-out both; }
  .marketing-features .features-slate-context .features-tag > span { animation-delay: 0.9s; }
  .marketing-features .features-slate-macro .features-tag > span { animation-delay: 1.02s; }
  .marketing-features .features-slate-sec .features-tag > span { animation-delay: 1.14s; }
  .marketing-features .features-slate-calc .features-tag > span { animation-delay: 1.26s; }
  .marketing-features .features-slate-market .features-tag > span { animation-delay: 1.38s; }
  .marketing-features .features-slate-answer .features-tag > span { animation-delay: 1.7s; }
  .marketing-features .features-beam { animation: features-beam 0.9s cubic-bezier(0.2, 0.8, 0.2, 1) 1.2s both; }
  /* Loops inside hidden illustrations. */
  .marketing-features .features-stack { animation: features-sway 18s ease-in-out infinite alternate; }
  .marketing-features .features-stack .features-tag { animation: features-face 18s ease-in-out infinite alternate; }
  .marketing-features .features-spark { animation: features-climb 5s linear 2.4s infinite; }
  .marketing-features .features-slate::after { animation: features-glint 5s linear infinite; }
  .marketing-features .features-slate-context::after { animation-delay: 2.5s; }
  .marketing-features .features-slate-macro::after { animation-delay: 2.95s; }
  .marketing-features .features-slate-sec::after { animation-delay: 3.4s; }
  .marketing-features .features-slate-calc::after { animation-delay: 3.85s; }
  .marketing-features .features-slate-market::after { animation-delay: 4.3s; }
  .marketing-features .features-slate-answer::after { animation-delay: 4.9s; }
  .marketing-features .features-orbit-ring { animation: features-spin 64s linear infinite; }
  .marketing-features .features-orbit .features-tag { animation: features-spin-face 64s linear infinite; }
  .marketing-features .features-marquee-row:nth-child(1) .features-marquee-track { animation: features-drift 70s linear infinite; }
  .marketing-features .features-marquee-row:nth-child(2) .features-marquee-track { animation: features-drift-back 80s linear infinite; }
  /* Packets cross the read lane at full strength; the track's clipped,
     faded ends hide where they enter and leave. */
  .marketing-features .features-lane-track {
    position: relative;
    display: block;
    height: 1.5rem;
    overflow: hidden;
    container-type: inline-size;
    -webkit-mask-image: linear-gradient(90deg, transparent, var(--bg) 14%, var(--bg) 86%, transparent);
    mask-image: linear-gradient(90deg, transparent, var(--bg) 14%, var(--bg) 86%, transparent);
  }
  .marketing-features .features-lane-track > .features-packet {
    position: absolute;
    left: 0;
    top: 0;
    animation: features-lane 7.5s linear infinite both;
  }
  .marketing-features .features-lane-track > .features-packet:nth-child(2) { animation-delay: 2.5s; }
  .marketing-features .features-lane-track > .features-packet:nth-child(3) { animation-delay: 5s; }
  .marketing-features .features-closing-sweep { animation: features-sweep 6s ease-in-out infinite; }
  .marketing-features:has(#features-motion-pause:checked) [aria-hidden="true"] *,
  .marketing-features:has(#features-motion-pause:checked) [aria-hidden="true"] *::before,
  .marketing-features:has(#features-motion-pause:checked) [aria-hidden="true"] *::after { animation-play-state: paused; }
  /* Below the hero, these move only with the reader's own scrolling. */
  @supports (animation-timeline: view()) {
    .marketing-features .features-lens { view-timeline: --features-lens block; }
    .marketing-features .features-lens-glass {
      animation: features-lens linear both;
      animation-timeline: --features-lens;
      animation-range: cover 15% cover 85%;
    }
    .marketing-features .features-lens-xray {
      animation: features-lens-view linear both;
      animation-timeline: --features-lens;
      animation-range: cover 15% cover 85%;
    }
    .marketing-features .features-note,
    .marketing-features .features-calendar-card {
      animation: features-settle linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 45%;
    }
    .marketing-features .features-journal { view-timeline: --features-journal block; }
    .marketing-features .features-gate-dots > span::after {
      animation: features-count linear both;
      animation-timeline: --features-journal;
      animation-range: cover 30% cover 38%;
    }
    .marketing-features .features-gate-dots > span:nth-child(2)::after { animation-range: cover 36% cover 44%; }
    .marketing-features .features-gate-dots > span:nth-child(3)::after { animation-range: cover 42% cover 50%; }
    .marketing-features .features-gate-dots > span:nth-child(4)::after { animation-range: cover 48% cover 56%; }
    .marketing-features .features-gate-dots > span:nth-child(5)::after { animation-range: cover 54% cover 62%; }
  }
}
@keyframes features-rise { from { opacity: 0; transform: translateY(var(--space-2)); } }
@keyframes features-node { from { opacity: 0; transform: scale(0.4); } }
@keyframes features-draw { from { transform: scaleY(0); } }
@keyframes features-assemble { from { transform: translateZ(3rem); } }
@keyframes features-fade { from { opacity: 0; } }
@keyframes features-pop { from { opacity: 0; transform: translateX(calc(var(--space-2) * -1)); } }
@keyframes features-beam { from { transform: rotateX(90deg) scaleY(0.001); } }
@keyframes features-sway {
  from { transform: rotateX(58deg) rotateZ(-33deg); }
  to { transform: rotateX(58deg) rotateZ(-47deg); }
}
@keyframes features-face {
  from { transform: rotateZ(33deg) rotateX(-58deg); }
  to { transform: rotateZ(47deg) rotateX(-58deg); }
}
/* The spark climbs 8.5rem in the first 60% of each 5s loop, so it
   passes a layer every 0.45s or so; each layer glints as it passes. */
@keyframes features-climb {
  from { opacity: 0; transform: translateZ(0); }
  4% { opacity: 1; }
  56% { opacity: 1; }
  60%, to { opacity: 0; transform: translateZ(8.5rem); }
}
@keyframes features-glint {
  from, 16%, to { opacity: 0; }
  3%, 7% { opacity: 1; }
}
@keyframes features-spin { to { transform: rotateZ(360deg); } }
@keyframes features-spin-face {
  from { transform: rotateZ(0deg) rotateX(-64deg); }
  to { transform: rotateZ(-360deg) rotateX(-64deg); }
}
@keyframes features-drift { to { transform: translateX(-50%); } }
@keyframes features-drift-back {
  from { transform: translateX(-50%); }
  to { transform: translateX(0); }
}
@keyframes features-lane {
  from { transform: translateX(-100%); }
  33.33%, to { transform: translateX(100cqi); }
}
@keyframes features-sweep {
  from { opacity: 0; transform: translateX(0); }
  15% { opacity: 1; }
  70% { opacity: 1; }
  85%, to { opacity: 0; transform: translateX(240%); }
}
/* The lens never travels past the card's edges, even with enlarged text:
   it rests 36cqi from the left, so it has less room that way. */
@keyframes features-lens {
  from { transform: translate(calc(min(20cqi, 36cqi - 4rem - 2px) * -1), -0.75rem); }
  to { transform: translate(min(36cqi, 64cqi - 4rem - 2px), 0.75rem); }
}
@keyframes features-lens-view {
  from { transform: translate(min(20cqi, 36cqi - 4rem - 2px), 0.75rem); }
  to { transform: translate(calc(min(36cqi, 64cqi - 4rem - 2px) * -1), -0.75rem); }
}
@keyframes features-settle { from { transform: rotateX(22deg) rotateY(34deg) translateZ(-3rem); } }
@keyframes features-count { from { opacity: 0; transform: scale(0.2); } }
@container marketing-workspace (max-width: 50rem) {
  .marketing-features .marketing-intro {
    grid-template-areas: "hero" "record" "stage";
    grid-template-rows: auto;
    row-gap: var(--space-8);
  }
  .marketing-features .features-stage { min-height: 17rem; }
  .marketing-features .features-visual { margin-top: var(--space-6); }
}
@container marketing-workspace (max-width: 36rem) {
  .marketing-features .features-stage { min-height: 15rem; }
  .marketing-features .features-stack { top: 62%; scale: 0.8; }
  .marketing-features .features-note { transform: none; animation-name: none; }
  .marketing-features .features-calendar-card { transform: none; animation-name: none; }
  .marketing-features .features-boundary { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .marketing-features .features-node { grid-row: 1; min-height: 0; max-width: none; flex-direction: row; }
  .marketing-features .features-node-broker { grid-column: 1; }
  .marketing-features .features-node-slatemark { grid-column: 2; }
  .marketing-features .features-lane-read { grid-column: 1 / -1; grid-row: 2; }
  .marketing-features .features-lane-blocked { grid-column: 1 / -1; grid-row: 3; }
  .marketing-features .marketing-closing { padding: var(--space-8) var(--space-5); }
  /* A narrow panel has no room beside its copy: the level line and its
     sweep run along the bottom edge, and the candle steps aside. */
  .marketing-features .features-closing-art { top: auto; left: 0; width: auto; height: var(--space-8); }
  .marketing-features .features-closing-art > .features-mark { display: none; }
}
@container marketing-workspace (max-width: 22rem) {
  .marketing-features .features-stack { scale: 0.68; }
}
@media (forced-colors: active) {
  .marketing-features .features-stage,
  .marketing-features .features-visual,
  .marketing-features .features-closing-art { display: none; }
}
@media print {
  .marketing-features .features-stage,
  .marketing-features .features-visual,
  .marketing-features .features-closing-art { display: none; }
}

/* PS5 public reading pages share the dark shell. Legal classes live on body
   so the immutable legal-body extraction delimiters and content stay exact. */
.shell.reading-page,
.reading-legal main > .shell { max-width: 46rem; }
.reading-heading { margin-bottom: var(--space-8); padding-block: var(--space-6); }
.reading-section,
.reading-legal main .card {
  border: 0;
  border-top: 1px solid var(--border);
  border-radius: 0;
  background: transparent;
  padding: var(--space-8) 0 0;
  margin: 0 0 var(--space-8);
  min-width: 0;
}
.reading-legal main .card:first-child { border: 0; padding-top: var(--space-6); }
body.layout-marketing .reading-page h1,
body.reading-legal h1 { font-size: var(--fs-2xl); line-height: 1.2; font-weight: var(--fw-bold); }
.reading-page p,
.reading-page li,
.reading-page dd { line-height: var(--lh-prose); }
.reading-page p,
.reading-page ul,
.reading-page ol { max-width: var(--measure-prose); }
.reading-page p.lede { font-size: var(--fs-base); line-height: var(--lh-prose); margin-bottom: var(--space-6); }
.reading-page .reading-section p,
.reading-legal main p { margin-block: 0 var(--space-4); }
.reading-page h2 { margin-bottom: var(--space-4); }
.reading-page h3 { margin-block: var(--space-6) var(--space-3); }
.reading-page h2,
.reading-page h3,
.reading-page [id] { scroll-margin-top: var(--space-6); }
.reading-page li + li { margin-top: var(--space-3); }
.reading-page a { overflow-wrap: anywhere; }
.reading-page .hero-disclaimer { padding-block: var(--space-4); border-block: 1px solid var(--border); color: var(--text); font-size: var(--fs-base-sm); }
.reading-legal main p,
.reading-legal main li,
.reading-legal main .kicker { color: var(--text); font-weight: var(--fw-regular); }
.reading-page .cite { font-family: var(--font-sans); }
.reading-page .cite-src { font-size: var(--fs-base-sm); }
.reading-workflow .reading-heading { padding-block: 0; margin-bottom: 0; }
.reading-workflow .reading-heading .lede { margin-bottom: var(--space-4); }
.reading-workflow .reading-heading .hero-cta { margin-bottom: var(--space-3); }
.reading-workflow .hero-disclaimer { border-bottom: 0; padding-block: var(--space-3) 0; color: var(--text-dim); }
.reading-workflow > .reading-heading + .reading-section { border-top: 0; padding-top: var(--space-4); }
.reading-workflow .workflow-browse { margin: var(--space-3) 0 0; }
.reading-copy-help { font-size: var(--fs-base-sm); color: var(--text-dim); margin-bottom: var(--space-8); }
.reading-disclosure > summary { min-height: var(--control-target); cursor: pointer; align-content: center; }
.reading-disclosure > summary::-webkit-details-marker { display: none; }
.reading-disclosure > summary::before { content: "▸"; margin-right: var(--space-2); }
.reading-disclosure[open] > summary::before { transform: rotate(90deg); }
.reading-disclosure[open] > section { margin-top: var(--space-6); }
.reading-disclosure[open] > p { margin-top: var(--space-6); }
.reading-link { display: inline-flex; align-items: center; min-height: var(--control-target); }
.workflow-steps { padding-left: var(--space-6); margin: 0; }
.workflow-step { padding: var(--space-4) 0 var(--space-6) var(--space-3); border-bottom: 1px solid var(--border); }
.workflow-step::marker { color: var(--accent); font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; }
.workflow-step:last-child { border-bottom: 0; padding-bottom: 0; }
.workflow-step .step-body { display: block; }
.workflow-step .step-title { font-size: var(--fs-base); margin: 0 0 var(--space-3); }
.workflow-step .step-detail { color: var(--text); font-size: var(--fs-base); line-height: var(--lh-prose); }
.workflow-setup,
.workflow-question { margin-top: var(--space-6); }
.workflow-question { padding: var(--space-4); background: var(--surface); border-radius: var(--radius-lg); }
.workflow-subheading { font-size: var(--fs-base); margin: 0 0 var(--space-3); font-weight: var(--fw-bold); }
.workflow-question .input { font-family: var(--font-sans); }
.reading-guide .faq { grid-template-columns: minmax(0, 1fr); gap: var(--space-3); }
.reading-guide .faq dt { margin: var(--space-3) 0 0; line-height: var(--lh-heading); }
.reading-guide .faq dd { padding-bottom: var(--space-6); border-bottom: 1px solid var(--border); color: var(--text); line-height: var(--lh-prose); }
.reading-guide .faq dd:last-child { border-bottom: 0; padding-bottom: 0; }
@media (max-width: 640px) {
  body.layout-marketing .reading-page h1,
  body.reading-legal h1 { font-size: var(--fs-h1-mobile); }
  .reading-heading { padding-block: var(--space-4); }
  .workflow-step { padding-left: var(--space-1); }
}
/* Print is a paper adaptation only. Browser screen colors remain dark;
   every operative legal paragraph and link stays present and selectable. */
@media print {
  body.reading-legal { background: var(--print-paper); color: var(--print-ink); color-scheme: light; }
  body.reading-legal main,
  body.reading-legal main *,
  body.reading-legal main .kicker { background: transparent; color: var(--print-ink); border-color: var(--print-ink); box-shadow: none; }
  body.reading-legal .topbar,
  body.reading-legal .skip-link,
  body.reading-legal .footer { display: none; }
  .reading-legal main { padding: 0; }
  .reading-legal main > .shell { max-width: 46rem; padding: 0; }
  .reading-legal main h1,
  .reading-legal main h2,
  .reading-legal main h3 { break-after: avoid; }
  .reading-legal main p,
  .reading-legal main li { orphans: 3; widows: 3; }
  .reading-legal main a { text-decoration: underline; }
}
