/* narve-redesign.css — substantive site-wide visual refresh.
 *
 * Loaded LAST (after gateway.css → components.css → mobile-a11y.css →
 * narve-polish.css) via pwa_middleware. Where polish.css adds motion
 * + focus rhythm, this file changes the actual VISUAL composition of
 * every shared surface — hub cards, page headers, sidebar, hero
 * blocks, tables, buttons, inputs, and the long-form reading layer.
 *
 * Strict rules (per narve-design skill, not negotiable):
 *   - Monochrome only. The accent dot on hub cards is the single
 *     sanctioned hue use; nothing else carries colour.
 *   - Three typefaces only: Inter (body), Geist Mono (numerals), and
 *     Instrument Serif Italic (display via --font-display).
 *   - Tokens, never raw values. If a token doesn't exist, the design
 *     uses the closest one rather than introducing a hex.
 *   - Information density over roominess. Power users open this app
 *     daily; we design for them, not first-time visitors.
 *   - One canonical curve everywhere (defined in narve-polish.css):
 *     cubic-bezier(0.2, 0, 0, 1).
 *   - Light + dark theme parity: every rule below uses tokens that
 *     flip with `[data-theme]`.
 *
 * Notes on overrides:
 *   gateway.css already paints most of these surfaces. We override
 *   selectively (higher-specificity body-prefixed selectors where a
 *   class-only rule already exists) so the diff stays auditable
 *   without rewriting gateway.css line-for-line. A future rebase of
 *   gateway.css would absorb these.
 */


/* ════════════════════════════════════════════════════════════════════
 * 1. Page header — display Instrument Serif italic, confident scale
 * ════════════════════════════════════════════════════════════════════ */
body .page-header {
  margin-bottom: var(--space-10, 40px);
  padding-bottom: var(--space-5, 24px);
  border-bottom: 1px solid var(--border-default);
}
body .page-title {
  /* Instrument Serif italic at display size — the single page-level
   * "feature" headline narve.ai uses everywhere. Smaller pages can
   * opt out by adding `data-display="ui"` on the h1 and the rule
   * below kicks back into Inter at the previous size. */
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(34px, 4.5vw, 52px);
  letter-spacing: -0.025em;
  line-height: 1.04;
  color: var(--text-primary);
  margin: 0 0 var(--space-3, 12px);
}
body .page-title[data-display="ui"] {
  font-family: var(--font-ui);
  font-style: normal;
  font-weight: 500;
  font-size: var(--text-3xl);
  letter-spacing: -0.02em;
}
body .page-subtitle {
  font-size: var(--text-md);
  color: var(--text-secondary);
  line-height: 1.55;
  max-width: 56ch;
  margin: 0;
}
body .breadcrumb {
  font-size: var(--text-sm);
  color: var(--text-tertiary);
  letter-spacing: 0.02em;
  margin-bottom: var(--space-3, 12px);
}
body .breadcrumb-item.current {
  color: var(--text-secondary);
}


/* ════════════════════════════════════════════════════════════════════
 * 2. Hub /dashboards — refined card composition, no hover lift
 * ════════════════════════════════════════════════════════════════════ */
body .dash-grid {
  /* Slightly denser tile grid — power users skim 6 cards at a glance,
   * not 3 spaced ones. */
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
  gap: var(--space-4, 16px);
}
body .dash-card {
  padding: var(--space-5, 24px) var(--space-5, 24px) var(--space-4, 20px);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  background: var(--bg-surface);
  /* No box-shadow at rest — flat, confident card. The accent bar at
   * top is the visual signal, not a soft drop-shadow. */
  box-shadow: none;
  transition: border-color var(--duration-base, 0.2s) var(--ease-canonical),
              background var(--duration-base, 0.2s) var(--ease-canonical);
}
body .dash-card::before {
  /* The 3px accent bar is the only sanctioned hue in the entire
   * design system. Make it confident: 4px, full opacity, sharp edge. */
  height: 3px;
  opacity: 1;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
@media (hover: hover) and (pointer: fine) {
  body .dash-card:hover {
    transform: none;          /* kill the gateway.css 2px lift */
    box-shadow: none;          /* kill the hover shadow growth */
    border-color: var(--text-primary);
    background: var(--bg-raised);
  }
  body .dash-card:hover::before {
    height: 4px;
  }
}
body .dash-accent-dot {
  /* gateway.css ships an 8×8 dot with a soft outer halo. Keep the dot,
   * drop the halo — narve.ai isn't a glow brand. */
  width: 10px;
  height: 10px;
  box-shadow: none;
  border: 1px solid color-mix(in srgb, var(--accent) 70%, var(--text-primary));
}
body .badge {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: var(--radius-xs);
  color: var(--text-tertiary);
  border: 1px solid var(--border-subtle);
  background: transparent;
}
body .dash-card-title {
  font-family: var(--font-ui);
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.2;
  margin: 0 0 var(--space-2, 8px);
}
body .dash-card-desc {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.55;
  margin: 0 0 var(--space-3, 12px);
  /* Cap to two lines so card heights stay rhythmic. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
body .dash-card-price {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  letter-spacing: 0.02em;
  margin-bottom: var(--space-4, 16px);
}
body .dash-card-action,
body .card-cta {
  /* Black bar CTA, full-width, confident. Same 44px tap-target floor
   * mobile-a11y.css enforces. */
  background: var(--text-primary);
  color: var(--bg-base);
  border: 1px solid var(--text-primary);
  padding: 10px 14px;
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: 500;
  text-align: center;
  text-decoration: none;
  letter-spacing: 0.02em;
}
body .dash-card-action:hover,
body .card-cta:hover {
  background: var(--text-secondary);
  border-color: var(--text-secondary);
}


/* ════════════════════════════════════════════════════════════════════
 * 3. Sidebar — denser, confident active state
 * ════════════════════════════════════════════════════════════════════ */
body .sidebar,
body .narve-sidebar {
  padding: var(--space-4, 16px) var(--space-3, 12px);
  gap: var(--space-2, 8px);
  border-right: 1px solid var(--border-default);
}
body .sidebar-logo,
body .narve-sidebar-logo {
  padding: var(--space-1, 4px) var(--space-3, 12px);
  margin-bottom: var(--space-4, 16px);
}
body .sidebar-logo-text {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.02em;
  font-size: var(--text-md);
}
body .nav-section-header {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  /* Was --text-quaternary (#bbbbbb on #fafafa = 1.83:1 — fails AA).
     Switched to --text-tertiary (#6e6e6e = 4.74:1 on #fafafa) so the
     sidebar section headings meet AA body contrast. */
  color: var(--text-tertiary);
  padding: var(--space-3, 12px) var(--space-3, 12px) var(--space-1, 4px);
  margin-top: var(--space-3, 12px);
}
body .nav-section-header:first-child {
  margin-top: 0;
}
body .nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-2, 8px);
  padding: 7px var(--space-3, 12px);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  font-weight: 500;
  text-decoration: none;
  letter-spacing: 0.005em;
  transition: background var(--duration-fast, 0.12s) var(--ease-canonical),
              color var(--duration-fast, 0.12s) var(--ease-canonical);
}
body .nav-item:hover {
  background: var(--bg-inset);
  color: var(--text-primary);
}
body .nav-item.active {
  background: var(--bg-inset);
  color: var(--text-primary);
  font-weight: 600;
  /* Hairline left rail signals selected without a coloured pill. */
  box-shadow: inset 2px 0 0 var(--text-primary);
}
body .nav-item-icon {
  flex-shrink: 0;
  opacity: 0.7;
}
body .nav-item.active .nav-item-icon {
  opacity: 1;
}
body .sidebar-user,
body .narve-sidebar-user {
  margin-top: auto;
  padding: var(--space-3, 12px);
  border-top: 1px solid var(--border-subtle);
  gap: var(--space-2, 8px);
}
body .sidebar-user-avatar {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
}
body .sidebar-user-name {
  font-size: var(--text-sm);
  font-weight: 500;
}


/* ════════════════════════════════════════════════════════════════════
 * 4. Buttons — uniform monochrome system
 * ════════════════════════════════════════════════════════════════════ */
body .btn-primary,
body button.btn-primary,
body input[type="submit"].btn-primary {
  background: var(--text-primary);
  color: var(--bg-base);
  border: 1px solid var(--text-primary);
  padding: 10px var(--space-4, 16px);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-canonical),
              transform var(--duration-fast) var(--ease-canonical);
}
body .btn-primary:hover {
  background: var(--text-secondary);
  border-color: var(--text-secondary);
}
body .btn-primary:active {
  transform: translateY(1px);
}
body .btn-secondary,
body button.btn-secondary {
  background: transparent;
  color: var(--text-primary);
  border: 1px solid var(--border-default);
  padding: 10px var(--space-4, 16px);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: 500;
  cursor: pointer;
}
body .btn-secondary:hover {
  border-color: var(--text-primary);
  background: var(--interactive-ghost);
}
body .btn-ghost,
body button.btn-ghost {
  background: transparent;
  color: var(--text-secondary);
  border: 0;
  padding: 8px var(--space-3, 12px);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: 500;
  cursor: pointer;
}
body .btn-ghost:hover {
  background: var(--interactive-ghost);
  color: var(--text-primary);
}


/* ════════════════════════════════════════════════════════════════════
 * 5. Inputs / forms — confident focus, tabular numerics
 * ════════════════════════════════════════════════════════════════════ */
body input[type="text"],
body input[type="email"],
body input[type="password"],
body input[type="search"],
body input[type="number"],
body input[type="tel"],
body input[type="url"],
body select,
body textarea {
  background: var(--bg-base);
  color: var(--text-primary);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: 10px 12px;
  font-family: inherit;
  font-size: var(--text-sm);
  line-height: 1.5;
  transition: border-color var(--duration-fast, 0.12s) var(--ease-canonical),
              box-shadow var(--duration-fast, 0.12s) var(--ease-canonical);
}
body input[type="number"],
body input[data-numeric] {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
body input:focus,
body select:focus,
body textarea:focus {
  outline: none;
  border-color: var(--text-primary);
  box-shadow: 0 0 0 3px var(--interactive-ghost);
}
body input:focus-visible,
body select:focus-visible,
body textarea:focus-visible {
  outline: 2px solid var(--ring, var(--text-primary));
  outline-offset: 2px;
}
body label {
  display: block;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-secondary);
  margin-bottom: var(--space-1, 4px);
  letter-spacing: 0.005em;
}


/* ════════════════════════════════════════════════════════════════════
 * 6. Tables — dense, readable, monochrome
 * ════════════════════════════════════════════════════════════════════ */
body table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}
body table thead th {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-tertiary);
  text-align: left;
  padding: var(--space-2, 8px) var(--space-3, 12px);
  border-bottom: 1px solid var(--border-default);
}
body table tbody td {
  padding: var(--space-3, 12px);
  border-bottom: 1px solid var(--border-ghost);
  color: var(--text-primary);
  vertical-align: middle;
}
body table tbody tr:last-child td {
  border-bottom: 0;
}
body table tbody tr {
  transition: background var(--duration-fast) var(--ease-canonical);
}
@media (hover: hover) {
  body table tbody tr:hover {
    background: var(--bg-inset);
  }
}
body table td.numeric,
body table td.tabular,
body table th.numeric {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  text-align: right;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}


/* ════════════════════════════════════════════════════════════════════
 * 7. Subproduct landing — bigger Instrument Serif hero
 * ════════════════════════════════════════════════════════════════════ */
body .shell {
  max-width: 1240px;
  padding: var(--space-7, 28px) var(--space-8, 32px) var(--space-16, 96px);
  margin: 0 auto;
}
body .shell .topbar {
  margin-bottom: clamp(48px, 8vw, 96px);
}
body .shell .wordmark {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  letter-spacing: -0.04em;
  font-style: italic;
  color: var(--text-primary);
}
body .shell .wordmark-divider {
  font-family: var(--font-ui);
  font-style: normal;
  color: var(--text-tertiary);
  margin: 0 var(--space-2, 8px);
  font-size: var(--text-md);
}
body .shell .wordmark-slug {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-style: normal;
  letter-spacing: 0;
  color: var(--text-secondary);
  text-transform: lowercase;
}
body .shell .top-note {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.16em;
  color: var(--text-tertiary);
  text-transform: uppercase;
}
body .shell .hero-grid {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: var(--space-12, 64px);
  align-items: start;
  min-height: clamp(420px, 70vh, 720px);
}
@media (max-width: 720px) {
  body .shell .hero-grid {
    grid-template-columns: 1fr;
    gap: var(--space-8, 32px);
    min-height: 0;
  }
}
body .shell .hero-label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin: 0 0 var(--space-5, 24px);
}
body .shell .hero-grid h1,
body .shell h1.hero {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  /* Confident display scale — fluid 56→88px. Keeps the hero a single
   * focal point even at 1440 width. */
  font-size: clamp(56px, 7vw, 88px);
  line-height: 0.98;
  letter-spacing: -0.035em;
  color: var(--text-primary);
  margin: 0 0 var(--space-6, 28px);
  /* Two-word display lines benefit from a slight balance. */
  text-wrap: balance;
}
body .shell .sub {
  font-size: var(--text-md);
  line-height: 1.55;
  color: var(--text-secondary);
  max-width: 52ch;
  margin: 0 0 var(--space-8, 32px);
}
body .shell .price-card {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-5, 24px);
  max-width: 480px;
}
body .shell .price-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-3, 12px);
  margin-bottom: var(--space-4, 16px);
}
body .shell .price-usd {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(32px, 4vw, 44px);
  letter-spacing: -0.02em;
  color: var(--text-primary);
}
body .shell .price-gbp {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  color: var(--text-tertiary);
  text-transform: uppercase;
}
body .shell .cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  background: var(--text-primary);
  color: var(--bg-base);
  border: 1px solid var(--text-primary);
  padding: 14px var(--space-4, 16px);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0.02em;
  text-decoration: none;
  transition: background var(--duration-fast, 0.12s) var(--ease-canonical);
}
body .shell .cta:hover {
  background: var(--text-secondary);
  border-color: var(--text-secondary);
}
body .shell .or-divider {
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-quaternary);
  margin: var(--space-4, 16px) 0;
  position: relative;
}
body .shell .or-divider::before,
body .shell .or-divider::after {
  content: '';
  position: absolute;
  top: 50%;
  width: calc(50% - 28px);
  height: 1px;
  background: var(--border-subtle);
}
body .shell .or-divider::before { left: 0; }
body .shell .or-divider::after  { right: 0; }
body .shell .bundle-card {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.55;
}
body .shell .bundle-math {
  display: block;
  margin-top: var(--space-2, 8px);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  letter-spacing: 0.02em;
}

/* Floating numbers — strictly monochrome. Six per-slug animation
 * classes (`anim-flicker`, `anim-drift`, `anim-tectonic`, `anim-frenetic`,
 * `anim-measured`, `anim-pulse`) only change DURATION + opacity range,
 * never colour. Existing CSS may set hue tints; override here to
 * enforce monochrome. */
body .shell .numbers,
body .shell .floating-number,
body .shell [class*="floating"] {
  color: var(--text-tertiary);
}
body .shell .numbers > * {
  font-family: var(--font-display);
  font-style: italic;
  color: var(--text-quaternary);
}

/* Stat pill row below hero. */
body .shell .pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3, 12px);
  margin-top: var(--space-12, 64px);
  padding-top: var(--space-6, 28px);
  border-top: 1px solid var(--border-subtle);
}
body .shell .pill {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  padding: var(--space-2, 8px) var(--space-4, 16px);
  border-radius: var(--radius-full);
  border: 1px solid var(--border-subtle);
}


/* ════════════════════════════════════════════════════════════════════
 * 8. Auth funnel — confident gate / token / login cards
 * ════════════════════════════════════════════════════════════════════ */
body .gate-card,
body .auth-card,
body .token-card,
body .login-card,
body .signup-card,
body .reset-card {
  background: var(--bg-float);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xl);
  padding: var(--space-10, 40px) var(--space-8, 32px);
  max-width: 420px;
  width: 100%;
  margin: 0 auto;
  transition: border-color var(--duration-base, 0.2s) var(--ease-canonical);
}
body .gate-heading,
body .auth-heading,
body .token-heading {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: var(--text-2xl);
  letter-spacing: -0.02em;
  color: var(--text-primary);
  margin: 0 0 var(--space-6, 28px);
  text-align: center;
}
body .gate-input,
body .auth-input,
body .token-input {
  width: 100%;
  background: var(--bg-base);
  color: var(--text-primary);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: 14px var(--space-3, 12px);
  font-family: var(--font-mono);
  font-size: var(--text-md);
  letter-spacing: 0.04em;
  text-align: center;
  margin-bottom: var(--space-3, 12px);
}
body .gate-btn,
body .auth-submit,
body .token-submit {
  width: 100%;
  background: var(--text-primary);
  color: var(--bg-base);
  border: 1px solid var(--text-primary);
  padding: 14px;
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0.02em;
  cursor: pointer;
}


/* ════════════════════════════════════════════════════════════════════
 * 9. Long-form pages — terms, privacy, dpa, methodology, faq
 * ════════════════════════════════════════════════════════════════════ */
body .legal-page,
body .doc-page,
body .markdown-body {
  max-width: 68ch;
  margin: 0 auto;
  padding: var(--space-10, 40px) var(--space-6, 28px) var(--space-16, 96px);
  font-size: var(--text-md);
  line-height: 1.7;
  color: var(--text-secondary);
}
body .legal-page h1,
body .doc-page h1,
body .markdown-body h1 {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(40px, 5vw, 56px);
  letter-spacing: -0.025em;
  line-height: 1.05;
  color: var(--text-primary);
  margin: 0 0 var(--space-8, 32px);
}
body .legal-page h2,
body .doc-page h2,
body .markdown-body h2 {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: var(--text-lg);
  letter-spacing: -0.01em;
  color: var(--text-primary);
  margin: var(--space-10, 40px) 0 var(--space-3, 12px);
  padding-top: var(--space-6, 28px);
  border-top: 1px solid var(--border-subtle);
}
body .legal-page h3,
body .doc-page h3 {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: var(--text-md);
  color: var(--text-primary);
  margin: var(--space-6, 28px) 0 var(--space-2, 8px);
}
body .legal-page p,
body .doc-page p {
  margin: 0 0 var(--space-4, 16px);
}
body .legal-page a,
body .doc-page a {
  color: var(--text-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--border-strong);
  text-decoration-thickness: 1px;
  transition: text-decoration-color var(--duration-fast, 0.12s) var(--ease-canonical);
}
body .legal-page a:hover,
body .doc-page a:hover {
  text-decoration-color: var(--text-primary);
}
body .legal-page ul,
body .legal-page ol,
body .doc-page ul,
body .doc-page ol {
  padding-left: var(--space-5, 24px);
  margin: 0 0 var(--space-4, 16px);
}
body .legal-page li,
body .doc-page li {
  margin-bottom: var(--space-2, 8px);
}
body .legal-page code,
body .doc-page code,
body .markdown-body code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--bg-inset);
  padding: 1px 6px;
  border-radius: var(--radius-xs);
  color: var(--text-primary);
}


/* ════════════════════════════════════════════════════════════════════
 * 10. Modals + dialogs — flat, confident
 * ════════════════════════════════════════════════════════════════════ */
body .nv-modal,
body [role="dialog"] {
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(2px);
}
body .nv-modal__panel,
body [role="dialog"] > .panel,
body .narve-sc-panel {
  background: var(--bg-float);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  padding: var(--space-6, 28px);
}
body .nv-modal__title,
body .narve-sc-title {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: var(--text-xl);
  letter-spacing: -0.02em;
  color: var(--text-primary);
  margin: 0 0 var(--space-3, 12px);
}


/* ════════════════════════════════════════════════════════════════════
 * 11. Settings + admin cards — uniform shell
 * ════════════════════════════════════════════════════════════════════ */
body .settings-card,
body .admin-card,
body .nv-card {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-5, 24px);
  margin-bottom: var(--space-4, 16px);
}
body .settings-section-title,
body .admin-section-title,
body .nv-card-title {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: var(--text-md);
  letter-spacing: -0.005em;
  color: var(--text-primary);
  margin: 0 0 var(--space-1, 4px);
}
body .settings-section-desc,
body .admin-section-desc,
body .nv-card-desc {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.55;
  margin: 0 0 var(--space-4, 16px);
  max-width: 56ch;
}


/* ════════════════════════════════════════════════════════════════════
 * 12. Footer — uniform, monochrome, monospace navigation
 * ════════════════════════════════════════════════════════════════════ */
body .footer-nav,
body .site-footer {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  padding: var(--space-8, 32px) var(--space-4, 16px);
  border-top: 1px solid var(--border-subtle);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-4, 16px);
}
body .footer-nav a,
body .site-footer a {
  color: var(--text-tertiary);
  text-decoration: none;
}
body .footer-nav a:hover,
body .site-footer a:hover {
  color: var(--text-primary);
}


/* ════════════════════════════════════════════════════════════════════
 * 13. Empty states — confident, instructional
 * ════════════════════════════════════════════════════════════════════ */
body .nv-empty,
body .empty-state {
  text-align: center;
  padding: var(--space-12, 64px) var(--space-6, 28px);
  border: 1px dashed var(--border-default);
  border-radius: var(--radius-lg);
  background: transparent;
}
body .nv-empty__title,
body .empty-state h2 {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: var(--text-xl);
  color: var(--text-primary);
  margin: 0 0 var(--space-2, 8px);
}
body .nv-empty__body,
body .empty-state p {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.55;
  max-width: 48ch;
  margin: 0 auto var(--space-5, 24px);
}


/* ════════════════════════════════════════════════════════════════════
 * 14. Density toggle hooks — `[data-density="compact"]` flips spacing
 * ════════════════════════════════════════════════════════════════════ */
[data-density="compact"] body .dash-card,
body[data-density="compact"] .dash-card {
  padding: var(--space-4, 16px) var(--space-4, 16px) var(--space-3, 12px);
}
[data-density="compact"] body .nav-item,
body[data-density="compact"] .nav-item {
  padding: 5px var(--space-3, 12px);
  font-size: 13px;
}
[data-density="compact"] body table tbody td,
body[data-density="compact"] table tbody td {
  padding: 6px var(--space-3, 12px);
}
[data-density="compact"] body .settings-card,
body[data-density="compact"] .settings-card {
  padding: var(--space-4, 16px);
}


/* ════════════════════════════════════════════════════════════════════
 * 15. Page-header layout — title + actions stack on mobile, side-by-side
 *     on desktop. Fixes overlap of `.page-actions` (pills, CTAs) on top
 *     of an Instrument Serif italic title at narrow widths.
 * ════════════════════════════════════════════════════════════════════ */
body .page-header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3, 12px) var(--space-5, 24px);
}
body .page-header > .page-title,
body .page-header > h1 {
  flex: 1 1 100%;
  min-width: 0;
}
body .page-header > .page-subtitle,
body .page-header > p {
  flex: 1 1 100%;
}
body .page-header > .page-actions {
  flex: 0 0 auto;
  margin-left: auto;
}
@media (min-width: 720px) {
  body .page-header > .page-title,
  body .page-header > h1 {
    flex: 1 1 auto;
  }
  body .page-header > .page-actions {
    align-self: flex-start;
    /* Lift pills onto the same baseline as the title rather than the
     * subtitle below it. */
    order: 2;
  }
  body .page-header > .page-subtitle,
  body .page-header > p {
    order: 3;
    flex: 1 1 100%;
  }
}


/* ════════════════════════════════════════════════════════════════════
 * 16. Plan-badge — monochrome, monospace, inline in .page-actions
 * ════════════════════════════════════════════════════════════════════ */
body .plan-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1, 4px);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
  background: var(--bg-inset);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full);
  padding: 6px var(--space-3, 12px);
  white-space: nowrap;
}
body .plan-badge[data-state="depleted"] {
  /* Depleted credits: differentiation through weight + border, not hue. */
  font-weight: 700;
  color: var(--text-primary);
  border-color: var(--text-primary);
}
body .plan-badge a {
  color: var(--text-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-color: var(--border-strong);
}
body .plan-badge a:hover {
  text-decoration-color: var(--text-primary);
}
body .plan-badge--noplan {
  border-style: dashed;
}


/* ════════════════════════════════════════════════════════════════════
 * UNIVERSAL FRAME — every page, all four sides.
 *
 * Rule of the rule: every served HTML document, regardless of which
 * shell it uses (.app-shell / .src-shell / .c-wrap / .landing-body /
 * bare main), must show a visible border + padding on top, bottom,
 * left, right. Power users open this app daily — frames give every
 * page a consistent silhouette.
 *
 * Strategy:
 *   1. body gets perimeter padding so nothing sits flush against the
 *      viewport edge.
 *   2. The first structural child of body — whichever shell it is —
 *      gets a border on all four sides + min-height so the frame
 *      reaches the bottom of the viewport even on short pages.
 *   3. ``!important`` on the frame so older page-specific rules
 *      can't accidentally strip a side off in compact mode.
 *   4. Density-aware via the var(--page-pad-*) tokens so compact
 *      mode tightens, not breaks, the frame.
 *
 * Pages that genuinely need a full-bleed canvas (currently none —
 * landing already opts in) can carry .page-frame--off on their
 * top-level wrapper to disable. Audit before adding the class.
 * ════════════════════════════════════════════════════════════════════ */

body {
  /* Perimeter padding — every viewport edge breathes. Density flips
     the value via [data-density]. */
  padding: var(--page-pad, 24px) !important;
  background: var(--bg-base);
  /* 100dvh sidesteps the iOS Safari 100vh crop. 100vh stays as the
     fallback for browsers that don't grok the dynamic-viewport unit. */
  min-height: 100vh;
  min-height: 100dvh;
  box-sizing: border-box;
}

/* Top-level wrappers — every narve template uses one of these.
   Selectors broadened on 2026-05-03 after a probe found the real DOM
   uses .pr-page / .pr-hero / .wrap on apex/marketing pages, NOT
   .app-shell / .landing-body as we'd assumed. The fallback `main` /
   `article` selectors catch any future page that uses an unknown
   wrapper class. */
body > .app-shell,
body > .src-shell,
body > .c-wrap,
body > .wrap,
body > .pr-page,
body > .pr-hero,
body > .landing-body,
body > .auth-shell,
body > main:not([class*="page-frame--off"]):not(.nv-error):not(.gate-card):not(.auth-card):not(.faq-shell):not(.about-shell),
body > article {
  border: 1px solid var(--border-default) !important;
  border-radius: var(--radius-md, 10px) !important;
  background: var(--bg-surface, var(--surface, var(--bg-base))) !important;
  padding: var(--space-6, 32px) var(--space-6, 32px) !important;
  min-height: calc(100vh - 96px);
  min-height: calc(100dvh - 96px);
  box-sizing: border-box;
  overflow: hidden;
}

/* App-shell uses CSS grid for sidebar + main + status — the frame
   needs to wrap the grid, not break it. Override only the layout-
   conflicting bits. */
body > .app-shell {
  /* Padding handled by the grid's children; perimeter padding only
     here so the grid fills the frame edge-to-edge. */
  padding: 0 !important;
  overflow: visible;
}

/* For app-shell pages, only the sidebar separator is owned here —
   .main-content padding is left to gateway.css's native rule
   (.main-content { padding: var(--space-4) var(--page-pad) var(--page-pad); })
   so we don't triple-stack body padding + frame padding + main padding.
   Removed 2026-05-15: redundant `padding: var(--space-5) var(--space-6)`
   override was adding 24px/32px on top of gateway.css's own padding and
   the body perimeter, producing 100px+ of cumulative chrome on dashboard
   routes. gateway.css owns .main-content padding; we own the border only. */
body > .app-shell > .main-content {
  border-left: 1px solid var(--border-default);
}

/* Compact density tightens but never kills the frame. */
[data-density="compact"] body {
  padding: var(--space-3, 12px) var(--space-3, 12px) !important;
}
[data-density="compact"] body > .app-shell,
[data-density="compact"] body > .src-shell,
[data-density="compact"] body > .c-wrap,
[data-density="compact"] body > .wrap,
[data-density="compact"] body > .pr-page,
[data-density="compact"] body > .pr-hero,
[data-density="compact"] body > .landing-body,
[data-density="compact"] body > .auth-shell,
[data-density="compact"] body > main:not(.nv-error):not(.gate-card):not(.auth-card):not(.faq-shell):not(.about-shell),
[data-density="compact"] body > article {
  padding: var(--space-4, 16px) var(--space-4, 16px) !important;
}
/* Compact-density override for .main-content removed 2026-05-15:
   redundant with gateway.css/components.css [data-density="compact"]
   rules that already tighten .main-content padding. Leaving it here
   re-introduced the triple-stack in compact mode. */

/* Mobile (narrow viewport) — frame stays but tightens to keep content
   readable. Sidebar collapses on app-shell so we re-bleed the main. */
@media (max-width: 720px) {
  body {
    padding: var(--space-3, 12px) var(--space-3, 12px) !important;
  }
  body > .app-shell,
  body > .src-shell,
  body > .c-wrap,
  body > .wrap,
  body > .pr-page,
  body > .pr-hero,
  body > .landing-body,
  body > .auth-shell,
  body > main:not(.nv-error):not(.gate-card):not(.auth-card):not(.faq-shell):not(.about-shell),
  body > article {
    padding: var(--space-4, 16px) var(--space-3, 12px) !important;
    border-radius: var(--radius-sm, 6px) !important;
  }
  body > .app-shell > .main-content {
    /* Mobile padding is owned by mobile-a11y.css and gateway.css's
       responsive .main-content rules — we only drop the sidebar
       separator since the sidebar collapses on narrow viewports. */
    border-left: 0;
  }
}

/* Pages with their own opinionated layout (auth funnel, error pages,
   public marketing, long-form content) opt out cleanly.
   These wrappers ship their own card / hero / centered-column composition
   and looked malformed inside the universal frame (a card-inside-a-card
   silhouette). The frame is for dashboards + app surfaces; everything
   below has its own page-level CSS file in static/pages/. */
body > main.nv-error,
body > main.gate-card,           /* /gate, /support, /enquire, /contact, /404, /403, /500, /maintenance */
body > main.auth-card,           /* /login, /token, /signup, /forgot-password */
body > main.faq-shell,           /* /faq */
body > main.about-shell,         /* /about */
body > .auth-canvas,
body > .auth-wrap,               /* /forgot-password outer */
body > .gate-canvas,
body > .legal-shell,             /* /terms, /privacy, /dpa */
body[data-no-frame] > * {
  border: 0 !important;
  background: transparent !important;
  min-height: auto;
  overflow: visible !important;
  /* Padding is left to the page-specific CSS (static/pages/<page>.css)
     so the opted-out wrapper renders with its own intended inner
     rhythm, not the frame's 32px. */
}
