/* Semantic component classes replacing the original Tailwind utility soup.
   Ported from src/components/Navigation.tsx and src/app/page.tsx (hero +
   disclaimer). Mobile-first; lg breakpoint = 1024px, md = 768px. */

[x-cloak] { display: none !important; }

/* ── Boot layout shift ──
   The router fetches the route fragment and injects it into #view after boot,
   so on a hard reload the shell paints with #view at zero height and the footer
   lands directly under the nav, near the top of the viewport. When the fragment
   arrives the footer is shoved down the page, which is a large and very visible
   layout shift on every cold load.

   Reserving a viewport of height WHILE #view is empty holds the footer below
   the fold until there is something to sit under. The selector stops matching
   the moment the fragment is injected, so no rendered route inherits a
   min-height it did not ask for, and a route that legitimately renders short
   content is unaffected. */
#view:empty { min-height: 100vh; }

/* pulse (was Tailwind animate-pulse) */
@keyframes rmPulse { 0%,100% { opacity: 1; } 50% { opacity: 0.5; } }
.rm-pulse { animation: rmPulse 2s cubic-bezier(0.4,0,0.6,1) infinite; }

.container { max-width: 80rem; margin-inline: auto; }

/* ── Primary button ── */
.btn-primary {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1rem 2rem;
  background: var(--color-accent);
  color: var(--color-void);
  font-family: var(--font-mono);
  font-size: 0.875rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  text-decoration: none;
  transition: background-color 0.3s;
}
.btn-primary:hover { background: #fff; }
.btn-primary--sm { padding: 0.625rem 1.25rem; font-size: 0.75rem; gap: 0; }
.btn-arrow__icon { transition: transform 0.3s; }
.btn-arrow:hover .btn-arrow__icon { transform: translateX(4px); }

/* ════════ Navigation ════════ */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  background: transparent;
  transition: all 0.5s;
}
.nav--solid {
  background: rgba(5, 5, 8, 0.92);
  backdrop-filter: blur(16px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.nav__inner { max-width: 80rem; margin-inline: auto; padding-inline: 1.5rem; }
.nav__row { display: flex; align-items: center; justify-content: space-between; height: 4rem; }
.nav__logo { display: flex; align-items: center; height: 4rem; padding-block: 0.5rem; }
.nav__logo img { height: 45px; width: auto; object-fit: contain; }

.nav__links, .nav__ctas { display: none; }
.nav__links { align-items: center; gap: 0.25rem; }
.nav__ctas { align-items: center; gap: 0.75rem; }

.nav__link {
  position: relative;
  padding: 0.5rem 1rem;
  font-family: var(--font-sans);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-muted);
  text-decoration: none;
  transition: color 0.3s;
}
.nav__link:hover { color: var(--color-accent); }
.nav__underline {
  position: absolute;
  bottom: 0; left: 1rem; right: 1rem;
  height: 1px;
  background: var(--color-accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s;
}
.nav__link:hover .nav__underline { transform: scaleX(1); }

.nav__toggle {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.375rem;
  width: 2.5rem; height: 2.5rem;
  background: none; border: none; cursor: pointer;
}
.nav__bar { width: 1.25rem; height: 1px; background: var(--color-text); transition: all 0.3s; }
.nav__bar--top-open { transform: rotate(45deg) translateY(3.5px); }
.nav__bar--bot-open { transform: rotate(-45deg) translateY(-3.5px); }

.nav__mobile { background: var(--color-deep); border-top: 1px solid var(--color-border); }
.nav__mobile-inner { padding: 1.5rem; display: flex; flex-direction: column; gap: 1rem; }
.nav__mlink {
  font-family: var(--font-sans); font-size: 0.875rem;
  text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--color-text-muted); text-decoration: none; transition: color 0.2s;
}
.nav__mlink:hover { color: var(--color-accent); }
.nav__mobile-cta { margin-top: 1rem; justify-content: center; }

@media (min-width: 1024px) {
  .nav__inner { padding-inline: 2rem; }
  .nav__row, .nav__logo { height: 5rem; }
  .nav__links, .nav__ctas { display: flex; }
  .nav__toggle, .nav__mobile { display: none; }
}

/* ════════ Hero ════════ */
.hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  overflow: hidden;
}
.hero__grid { position: absolute; inset: 0; opacity: 0.4; z-index: 0; }
.hero__substrate { position: absolute; inset: 0; z-index: 2; display: block; }
.hero__fade {
  position: absolute; inset: 0; z-index: 4; pointer-events: none;
  background: linear-gradient(to bottom, transparent, transparent, var(--color-void));
}
.hero__content {
  position: relative; z-index: 10;
  width: 100%; max-width: 80rem; margin-inline: auto;
  padding: 8rem 1.5rem 5rem;
}
.hero__cols { display: grid; gap: 4rem; align-items: center; }
.hero__copy { display: flex; flex-direction: column; gap: 2rem; }

.badge {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.375rem 0.75rem;
  font-family: var(--font-mono); font-size: 10px;
  text-transform: uppercase; letter-spacing: 0.2em;
  color: var(--color-accent);
  border: 1px solid rgba(0, 229, 255, 0.3);
  background: rgba(0, 229, 255, 0.05);
}
.badge__dot {
  width: 0.375rem; height: 0.375rem; border-radius: 9999px;
  background: var(--color-accent);
  animation: rmPulse 2s cubic-bezier(0.4,0,0.6,1) infinite;
}

.hero__title { font-size: 3rem; line-height: 0.95; letter-spacing: -0.025em; margin: 0; }
.hero__title-serif { font-family: var(--font-display); font-weight: 700; }
.hero__title-bold { font-family: var(--font-display); font-weight: 700; }
.hero__lede {
  font-size: 1.125rem; color: var(--color-text-muted);
  max-width: 32rem; line-height: 1.625; font-weight: 300; margin: 0;
}
.hero__stats { display: flex; gap: 2rem; padding-top: 1rem; }
.stat { display: flex; flex-direction: column; gap: 0.25rem; }
.stat__value { font-size: 1.25rem; font-family: var(--font-mono); font-weight: 700; color: var(--color-text); }
.stat__label { font-size: 10px; font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.2em; color: var(--color-text-dim); }
.hero__cta { display: flex; flex-wrap: wrap; gap: 1rem; padding-top: 1rem; }

.hero__terminal { width: 100%; }
.terminal-wrap { position: relative; }
.terminal { background: var(--color-deep); border: 1px solid var(--color-border); border-radius: 2px; overflow: hidden; }
.terminal__bar {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface);
}
.terminal__dots { display: flex; gap: 0.375rem; }
.dot { width: 0.625rem; height: 0.625rem; border-radius: 9999px; opacity: 0.6; }
.dot--warn { background: var(--color-warn); }
.dot--amber { background: #eab308; }
.dot--accent { background: var(--color-accent); }
.terminal__title { font-size: 10px; font-family: var(--font-mono); color: var(--color-text-dim); margin-left: 0.5rem; }
.terminal__body { padding: 1.25rem; font-family: var(--font-mono); font-size: 13px; line-height: 1.625; min-height: 340px; }

/* Boot reveal. Each row carries its own --d (accumulated in buildTerminalLines),
   so the browser owns the easing on the compositor and there is no per-line JS
   timer. A row animates once, when it is created. The movement is 3px on
   purpose: a terminal line should settle, not fly in. */
.term-line {
  white-space: pre-wrap;
  animation: termLineIn 260ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
  animation-delay: var(--d, 0ms);
}
@keyframes termLineIn {
  from { opacity: 0; transform: translateY(3px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .term-line { animation: none; opacity: 1; transform: none; }
}
.term-line--cmd { color: var(--color-text); }
.term-line--accent { color: var(--color-accent); }
.term-line--ready { color: #fff; font-weight: 700; }
.term-line--muted { color: var(--color-text-muted); }
.term-line--blank { height: 1rem; }
.terminal__cursor {
  display: inline-block; width: 0.5rem; height: 1rem;
  background: var(--color-accent); margin-left: 0.25rem;
  animation: rmPulse 2s cubic-bezier(0.4,0,0.6,1) infinite;
}

.terminal__deco { position: absolute; }
.terminal__deco--a { top: -1rem; right: -1rem; width: 6rem; height: 6rem; border: 1px solid rgba(0,229,255,0.1); transform: rotate(12deg); }
.terminal__deco--b { bottom: -1.5rem; left: -1.5rem; width: 4rem; height: 4rem; border: 1px solid rgba(68,136,255,0.1); transform: rotate(-6deg); }

.hero__scroll {
  position: absolute; bottom: 2rem; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 0.5rem; opacity: 0.4;
}
.hero__scroll-label { font-size: 9px; font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.3em; color: var(--color-text-dim); }
.hero__scroll-line { width: 1px; height: 2rem; background: linear-gradient(to bottom, var(--color-text-dim), transparent); }

@media (min-width: 768px) {
  .hero__title { font-size: 3.75rem; }
  .hero__lede { font-size: 1.25rem; }
}
@media (min-width: 1024px) {
  .hero__content { padding: 10rem 2rem 8rem; }
  .hero__cols { grid-template-columns: 1fr 1fr; gap: 5rem; }
  .hero__title { font-size: 4.5rem; }
}

/* ════════ Disclaimer ════════ */
.disclaimer { background: #1a1408; border-block: 1px solid rgba(245, 166, 35, 0.3); }
.disclaimer__inner { max-width: 56rem; margin-inline: auto; padding: 1.5rem; text-align: center; }
.disclaimer__text { font-size: 0.875rem; font-family: var(--font-sans); color: #f5a623; margin: 0; }
.disclaimer__text a { text-decoration: underline; color: inherit; }
.disclaimer__text a:hover { color: var(--color-accent); }
.disclaimer__sub { font-size: 0.75rem; font-family: var(--font-sans); color: rgba(245, 166, 35, 0.5); margin: 0.5rem 0 0; }
@media (min-width: 768px) { .disclaimer__text { font-size: 1rem; } }

/* The footer lives in sections/footer.css, which is the real port of the
   original site's markup. A stub predating that port used to sit here and drew
   a SECOND rule: `.footer` carried its own border-top plus 2rem of padding, and
   the first `.footer__section` inside it carries one too, so every page ended
   on two parallel hairlines 32px apart, the lower one inset by the stub's
   1.5rem side padding. The stub also silently made `.footer__inner` a flex
   container (sections/footer.css never sets `display`, so those declarations
   won by default rather than by intent) and defined `.footer__mark` /
   `.footer__legal`, which no markup has ever used. */

/* ════════ Comment thread (Postgres-backed; original site parity) ════════ */
.comments { border-top: 1px solid var(--color-border); padding: 4rem 1.5rem; }
.comments__inner { max-width: 48rem; margin-inline: auto; }
.comments__title { font-family: var(--font-mono); letter-spacing: 0.12em; text-transform: uppercase; color: var(--color-text); margin: 0 0 0.25rem; }
.comments__sub { font-size: 0.875rem; color: var(--color-text-dim); margin: 0 0 2rem; }
.comments__state { font-family: var(--font-mono); font-size: 0.875rem; color: var(--color-text-dim); }
.comments__state--err { color: var(--color-warn); }
.comments__list { list-style: none; margin: 0 0 2rem; padding: 0; display: flex; flex-direction: column; gap: 1rem; }
.comments__empty { font-size: 0.875rem; color: var(--color-text-dim); }
.comment { border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); padding: 1rem 1.25rem; }
.comment__head { display: flex; align-items: baseline; gap: 0.75rem; margin-bottom: 0.4rem; }
.comment__author { font-family: var(--font-mono); font-size: 0.875rem; color: var(--color-accent); }
.comment__when { font-size: 0.75rem; color: var(--color-text-dim); }
.comment__body { margin: 0; color: var(--color-text); line-height: 1.55; white-space: pre-wrap; word-break: break-word; }
.comments__form { display: flex; flex-direction: column; gap: 0.75rem; }
.comments__input, .comments__textarea {
  width: 100%; box-sizing: border-box; background: var(--color-void); color: var(--color-text);
  border: 1px solid var(--color-border); border-radius: var(--radius); padding: 0.65rem 0.85rem;
  font-family: var(--font-sans); font-size: 0.9375rem; resize: vertical;
}
.comments__input:focus, .comments__textarea:focus { outline: none; border-color: var(--color-accent); }
.comments__actions { display: flex; justify-content: flex-end; }
.comments__notice { margin: 0; font-family: var(--font-mono); font-size: 0.8125rem; color: var(--color-warn); }

/* ════════ Shared data-view components ════════
   Page-agnostic building blocks for data dashboards (regime, allocation, …).
   Each rule is the SINGLE SOURCE OF TRUTH: the neutral .rm-* name is grouped
   with the original regime .rv__* (and swarm .sv__*) selector, copying
   regime's exact values, so both the reference page and new pages render
   identically from one block. The matching regime/swarm blocks were
   removed from views.css. Regime-DOMAIN styling (hero, backtests, correlations,
   sparklines, posbars, indicator cells, pie, methodology) stays in views.css. */

/* eyebrow (kicker) */
.rm-eyebrow, .rv__eyebrow, .sv__eyebrow {
  font-family: var(--font-mono); font-size: 10px; text-transform: uppercase;
  letter-spacing: 0.3em; color: var(--color-accent);
}
.rm-eyebrow--accent, .rv__eyebrow--accent { color: var(--color-accent); }

/* loading / error states */
.rm-loading, .rv__loading, .sv__loading, .sv__empty { color: var(--color-text-muted); font-family: var(--font-mono); }
.rm-error, .rv__error, .sv__error { color: var(--color-warn); font-family: var(--font-mono); }

/* section head + title + as-of */
.rm-section-head, .rv__dash-head { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
.rm-section-title, .rv__dash-title { font-size: 1.6rem; font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: -0.01em; margin: 0.35rem 0 0; }
.rm-asof, .rv__asof { font-family: var(--font-mono); font-size: 11px; color: var(--color-text-dim); }

/* /regime row-level provenance badge (issue #397): which data source wrote the
   served snapshot. Stacks under the as-of label, right-aligned to match. 'live'
   reads neutral (the healthy default); 'hermetic'/'fixture'/'seed' read amber
   (the existing non-live warn tone, matching .alloc-aum__prov on /allocation)
   since they mean the served data is not this run's real production fetch. */
.rv__asof-wrap { display: flex; flex-direction: column; align-items: flex-end; gap: 0.3rem; }
.rv__prov {
  font-family: var(--font-mono); font-size: 10px; text-transform: uppercase;
  letter-spacing: 0.15em; padding: 0.2rem 0.5rem; border-radius: var(--radius);
  border: 1px solid var(--color-border); color: var(--color-text-dim);
}
.rv__prov--hermetic, .rv__prov--fixture, .rv__prov--seed {
  color: var(--color-warn); border-color: rgba(232, 166, 64, 0.4); background: rgba(232, 166, 64, 0.08);
}

/* summary / stat card grid + card */
.rm-cards, .rv__cards { display: grid; grid-template-columns: 1fr; gap: 0.8rem; }
.rm-card, .rv__card {
  background: rgba(16, 20, 28, 0.4); border: 1px solid var(--color-border);
  border-radius: var(--radius); padding: 1rem; display: flex; flex-direction: column;
}
.rm-card-eyebrow, .rv__card-eyebrow { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.3em; color: var(--color-text-muted); }
.rm-card-val, .rv__card-val { font-size: 1.9rem; font-weight: 500; margin-top: 0.35rem; color: var(--color-text); font-family: var(--font-mono); }
.rm-card-foot, .rv__card-foot { font-family: var(--font-mono); font-size: 11px; color: var(--color-text-dim); margin-top: 0.55rem; }

/* chart card shell */
.rm-chartcard, .rv__chart-card { border: 1px solid var(--color-border); border-radius: var(--radius); padding: 1rem; background: rgba(16, 20, 28, 0.4); }
.rm-chartcard-head, .rv__chart-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.7rem; margin-bottom: 0.7rem; }
.rm-chartcard-title-group, .rv__chart-title-group { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.rm-chartcard-title, .rv__chart-title { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.3em; color: var(--color-text-muted); }
.rm-chart, .rv__chart { height: 260px; background: transparent; border: 0; border-radius: 0; padding: 0; margin: 0; }

/* toggle chips */
.rm-chips, .rv__chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.rm-chip, .rv__chip {
  font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.2em;
  padding: 0.25rem 0.5rem; border-radius: var(--radius); border: 1px solid var(--color-border);
  color: var(--color-text-muted); background: transparent; cursor: pointer; transition: color 0.15s, border-color 0.15s, background 0.15s;
}

/* Announced to screen readers, never painted. The clip-path pair is the
   modern-safe form: `display:none` and `visibility:hidden` remove the node from
   the accessibility tree, and a live region that is not in the tree announces
   nothing. */
.rm-visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; white-space: nowrap; border: 0;
  clip: rect(0 0 0 0); clip-path: inset(50%);
}

/* Status chip — the one shape that means "this is a STATE", site-wide.
   Four near-identical families already existed before this (.regime-pill,
   .adm-badge, .read--*, .stance--*), each re-deriving the same small mono
   uppercase chip for its own page, which is why the same idea reads slightly
   differently depending on where you are standing. New state indicators use
   this; the existing four are candidates to converge onto it, but that is a
   sweep of its own and does not belong inside a feature change.

   Tone carries meaning and form carries discipline, per the covenant: the dot
   is where the hue lives, so green stays a mass and Beacon stays a POINT well
   under 12px. Neither colour is ever the chip's fill. */
.rm-status {
  display: inline-flex; align-items: center; gap: 0.42rem; white-space: nowrap;
  padding: 0.24rem 0.6rem; border-radius: var(--radius);
  border: 1px solid var(--color-border); background: transparent;
  font-family: var(--font-mono); font-size: 0.68rem;
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--color-text-muted);
}
.rm-status__dot { width: 7px; height: 7px; flex: 0 0 auto; }

/* Waiting on somebody. Deliberately neutral: nothing is wrong, and colouring
   an ordinary wait as though it were an alert is how a UI cries wolf. */
.rm-status--pending .rm-status__dot { background: var(--color-text-dim); }

/* Value gained, and loss or attention. Both tones brighten the LABEL and let
   the 7px dot carry the hue; neither tints its border.
   The borders used to be rgba() tints of green and Beacon, which broke the
   covenant twice: green became a thin line where it is defined as a mass, and
   Beacon became a rail, measured at 129px and 199px wide on the rejected state
   where three alert chips also made it a series. Both are capped at "a point".
   Worth noting for anyone auditing this later: an rgba() tint of Beacon does
   not equal `rgb(255, 122, 41)` in computed styles, so a naive equality sweep
   reports the page clean. Compare by hue, not by string. */
.rm-status--good { color: var(--color-text); }
.rm-status--good .rm-status__dot { background: var(--color-green); }

.rm-status--alert { color: var(--color-text); }
.rm-status--alert .rm-status__dot { background: var(--color-beacon); }

/* A state with a clock running on it. Beacon is the attention hue and stays a
   POINT, so the signal is the dot's opacity, not a colour spreading anywhere.
   Opacity only: no glow, no scale, nothing that moves layout. */
.rm-status--live .rm-status__dot { background: var(--color-beacon); animation: rm-status-live 2.2s ease-in-out infinite; }
@keyframes rm-status-live { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@media (prefers-reduced-motion: reduce) { .rm-status--live .rm-status__dot { animation: none; } }

/* Figure strip — "what this thing has actually done", as counts.
   Promoted verbatim from the member profile's scoped styles, where it was the
   only copy, so the application status page could show the same record in the
   same shape instead of growing a second figure treatment beside it.
   Mono and tabular so columns align; no figure is ever cyan or green, because a
   count is a figure and green is reserved for money as a mass. Cyan seams the
   strip as a line across the top, and never fills it. */
.rm-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px;
            margin: 1.35rem 0 1.6rem; padding: 0; background: var(--color-border);
            border-top: 1px solid var(--color-accent); }
.rm-stat { background: var(--color-surface); padding: 0.7rem 0.85rem; }
.rm-stat dt { font-family: var(--font-mono); font-size: 0.6rem; text-transform: uppercase;
              letter-spacing: 0.16em; color: var(--color-text-muted); }
.rm-stat dd { margin: 0.35rem 0 0; font-family: var(--font-mono); font-size: 1.1rem;
              font-variant-numeric: tabular-nums; color: var(--color-text); }
/* The one failure this strip can report is a take whose signature did not
   verify. Beacon is that hue, and stays a POINT beside the figure rather than
   recolouring it: the number is still a number. */
.rm-stat--alert dd::after { content: ""; display: inline-block; width: 8px; height: 8px;
                            margin-left: 0.5rem; background: var(--color-beacon); vertical-align: middle; }
@media (max-width: 560px) { .rm-stats { grid-template-columns: 1fr; } }

/* ── Action row: one thing to do, then the places to go ─────────────────────
   Replaces two different, both-broken treatments in the onboarding flow.

   On the status page a row of three links read as one primary and two
   secondaries in the source, and as three identical items on screen: the group
   rule `.ap-links a { color: accent }` (0,3,1) outranked
   `.ap-links__quiet { color: text-muted }` (0,3,0), so the "quiet" links were
   never quiet a single frame. On the apply page the same job was done by four
   links glued into a prose sentence with middots.

   The hierarchy here is carried by HOW MUCH BEAM LINE a control gets, which is
   the one thing the covenant already says cyan is for: the action is enclosed
   by a rule on four sides, a destination is underscored by a rule on one, and
   prose links get none. That leaves the LABELS free to be plain text, which is
   what pulls cyan back out of the type: on the status page cyan was 26% of all
   rendered characters, against 2% on the apply page, and every one of those
   characters was a control that could have been white.

   Each destination carrying its own rule, ending at its own last letter, is
   also what stops two adjacent links reading as one phrase — the actual defect,
   which no amount of gap between them fixes.

   Selectors are doubled (.rm-actions .rm-actions__link, 0,2,0) so the component
   survives being dropped into a page with a scoped `.ap a` (0,1,1) link rule,
   rather than silently losing to it the way .ap-links__quiet did. */
.rm-actions { display: flex; flex-wrap: wrap; align-items: center;
              column-gap: 1.6rem; row-gap: .35rem; margin: 1.8rem 0 0;
              font-family: var(--font-mono); font-size: 0.72rem;
              text-transform: uppercase; letter-spacing: 0.12em; }

/* The action. Outlined, never filled: cyan behind a label is cyan as mass. */
.rm-actions .rm-actions__do {
  display: inline-flex; align-items: center; gap: .5rem; min-height: 44px;
  padding: 0 1rem; color: var(--color-text); text-decoration: none;
  border: 1px solid var(--color-accent); border-radius: var(--radius);
}
.rm-actions .rm-actions__do:hover { background: var(--color-accent-glow); color: var(--color-text); }

/* A destination. Underscored rather than recoloured, so the words stay legible
   type and the cyan stays a rule. */
.rm-actions .rm-actions__link {
  display: inline-flex; align-items: center; min-height: 44px;
  color: var(--color-text-soft); text-decoration: underline;
  text-decoration-color: var(--color-accent-line);
  text-decoration-thickness: 1px; text-underline-offset: 6px;
}
.rm-actions .rm-actions__link:hover {
  color: var(--color-text); text-decoration-color: var(--color-accent);
}

/* ── Swarm disclaimer ───────────────────────────────────────────────────
   Closes the page, above the footer, on every swarm surface. Quiet but not
   hidden: it sits at the label rung with a full-width hairline above it, so it
   reads as the page's closing statement rather than as fine print smuggled in
   under a fold. No hue — a disclaimer that needs a colour to be noticed is
   competing with the data, and Beacon here would read as an error state. */
.rm-disclaimer { display: block; margin: 3rem 0 0; padding-top: 1.1rem;
                 border-top: 1px solid var(--color-border); }
.rm-disclaimer__label { margin: 0 0 .5rem; font-family: var(--font-mono);
                        font-size: 10px; text-transform: uppercase;
                        letter-spacing: 0.3em; color: var(--color-text-muted); }
.rm-disclaimer__body { margin: 0; max-width: 78ch; font-size: 0.85rem;
                       line-height: 1.65; color: var(--color-text-muted); }

/* legend (colored swatches) */
.rm-legend, .rv__legend { display: inline-flex; align-items: center; gap: 0.5rem; font-family: var(--font-mono); font-size: 10px; text-transform: none; letter-spacing: normal; color: var(--color-text-muted); }
.rm-legend-item, .rv__legend-item { display: inline-flex; align-items: center; gap: 0.25rem; }
.rm-legend-swatch, .rv__legend-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 2px; }

/* data table */
.rm-table-scroll, .rv__table-scroll { overflow-x: auto; }
.rm-table, .rv__table { width: 100%; border-collapse: collapse; font-size: 12px; line-height: 1.26; }
.rm-table thead th, .rv__table thead th { font-family: var(--font-mono); font-weight: 400; color: var(--color-text-dim); text-align: left; padding: 0.44rem 0.5rem; white-space: nowrap; }
.rm-table thead th:first-child, .rv__table thead th:first-child { padding-left: 1rem; }
.rm-table thead th:last-child, .rv__table thead th:last-child { padding-right: 1rem; }
.rm-table td, .rv__table td { padding: 0.44rem 0.5rem; border-top: 1px solid var(--color-border); vertical-align: middle; }
.rm-table td:first-child, .rv__table td:first-child { padding-left: 1rem; }
.rm-table td:last-child, .rv__table td:last-child { padding-right: 1rem; }
.rm-num, .rv__num { text-align: right; font-family: var(--font-mono); }
.rm-muted, .rv__muted { color: var(--color-text-muted); }

/* card / section foot note */
.rm-foot, .rv__foot { padding: 0.85rem 1rem; border-top: 1px solid var(--color-border); font-family: var(--font-mono); font-size: 10px; color: var(--color-text-dim); line-height: 1.6; }
.rm-foot p, .rv__foot p { margin: 0 0 0.4rem; }
.rm-foot p:last-child, .rv__foot p:last-child { margin-bottom: 0; }
.rm-foot strong, .rv__foot strong { color: var(--color-text-muted); }

@media (min-width: 768px) {
  .rm-cards, .rv__cards { grid-template-columns: repeat(4, 1fr); }
}

/* ── Unified page-hero anchor ─────────────────────────────────────────────
   Every top-level nav page opens with a full-bleed hero band. These rules pin
   the title block to the same offset from the viewport top on ALL of them, so
   the headline lands in the exact same place as you navigate. Each hero's own
   inline stylesheet still owns its size/genart; this only fixes the anchor.
   !important is used deliberately: the per-page inline <style> is injected
   after this shared sheet and would otherwise win the cascade. */
.a2-hero, .sv__hero, .rv__hero, .tok__hero, .md-hero, .cl__hero, .sk__head {
  /* Top-aligned, not centred. Centring looks right on any one page but breaks
     the thing this rule exists for: these blocks are different heights (a lede
     wraps to one line on /tokenomics and three on /projects), so centring made
     the headline land in a different place on every page, varying by 55px.
     Pinning the top is what keeps the headline still as you navigate. */
  align-items: flex-start !important;
  position: relative;
}
.a2-hero__inner, .sv__hero-inner, .rv__hero-inner, .tok__hero-inner,
.md-hero__inner, .cl__hero-inner, .sk__head-inner {
  /* 10rem rather than the original 8rem: it sits a typical block near the
     middle of the band instead of high in it, which was the complaint, while
     keeping every headline on the identical offset. */
  padding-top: 10rem !important;
  padding-bottom: 2.5rem !important;
  position: relative;
  z-index: 1;
}

/* ── One headline, everywhere ──
   Measured across the nav pages before this rule: five different sizes (56,
   57.6, 60 and 64px), and /media set in Space Grotesk with no uppercase while
   every other hero used the condensed display face. Navigating between pages
   made the headline change size and typeface. !important for the same reason
   the rules above use it: each page's inline <style> is injected after this
   sheet and would otherwise win. */
.sk__title, .rv__title, .tok__h1, .a2-hero__title,
.md-hero__title, .cl__h1, .sv__title {
  font-family: var(--font-display) !important;
  font-weight: 700 !important;
  font-size: clamp(2.5rem, 4.2vw, 3.75rem) !important;
  line-height: 1.05 !important;
  letter-spacing: -0.01em !important;
  text-transform: uppercase !important;
  /* /regime and /swarm carried an 8px top margin, which is enough to read
     as a jump when the headline is otherwise pinned to the same offset. */
  margin-top: 0 !important;
}

/* ── Hero legibility ──
   Every hero lede is set over a live canvas, and measured against the composited
   art the muted text colour was 3.76:1 on /media, 5.05:1 on /skills and 5.07:1
   on /regime. WCAG AA for body text is 4.5:1, so one page failed outright and
   the others cleared it only on average — a bright stroke passing directly
   behind a glyph is worse than the mean.

   Two flat changes, no gradient and no shadow. A uniform veil sits over the art
   and under the content, and the lede steps up to the brighter reading grey the
   apply page already defines for long copy. Together they take /media to about
   7.9:1 while leaving the art plainly visible. */
.a2-hero__viz, .sv__hero-field, .rv__hero-art, .tok__hero-art,
.md-hero__art, .cl__hero-art, .sk__head-viz {
  z-index: 0;
}
/* ::before, not ::after. Four of these heroes already define their own ::after
   for a bottom fade, and the per-page inline <style> is injected after this
   sheet, so an ::after veil here loses the cascade on exactly the pages whose
   art is busiest. No hero defines a ::before. */
.a2-hero::before, .sv__hero::before, .rv__hero::before, .tok__hero::before,
.md-hero::before, .cl__hero::before, .sk__head::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(6, 8, 12, 0.35);
  pointer-events: none;
  z-index: 0;
}
.a2-hero__lede, .sv__lede, .rv__hero-sub, .tok__lede,
.md-hero__lede, .cl__lede, .sk__lede {
  color: #aeb6c6 !important;
}
