/* ehsto.dev — design system (framework primitives only)
 *
 * Apply data-theme="dark" or "light" on <html>. This file is the
 * portable, exportable design system. ehsto.dev's own UI lives in a
 * separate app.css that's loaded only by index.html — consuming
 * projects don't need it.
 *
 * File layout:
 *   SECTION 1 — Tokens, themes, base reset
 *   SECTION 2 — Framework primitives
 *     · Typography
 *     · Layout regions, header, nav, footer
 *     · App-shell, section-block, header-section, columns-block
 *     · Card, form, button, table, empty-state, status / alerts
 *     · Utilities
 *
 * Mobile-first throughout. Each component carries its own breakpoint
 * overrides locally — there are no monolithic "iPad" / "Desktop" blocks. */


/* ============================================================
 * SECTION 1 — TOKENS, THEMES, BASE
 * ============================================================ */

/* ─── DESIGN TOKENS ──────────────────────────────────────── */
:root {
  /* Typography */
  --font-family-01: Arial, Helvetica, sans-serif;
  --font-family-02: monospace;

  /* Spacing scale (multiples of 3) */
  --space-3: 3px;
  --space-6: 6px;
  --space-9: 9px;
  --space-12: 12px;
  --space-15: 15px;
  --space-18: 18px;
  --space-21: 21px;
  --space-24: 24px;
  --space-30: 30px;
  --space-36: 36px;
  --space-42: 42px;
  --space-60: 60px;
  --space-90: 90px;

  /* Layout */
  --gap: 9px;
  --secondary-header-height: 50px;
  --content-max: 1400px;

  /* Type scale — headings */
  --fs-h0: 3.6rem;
  --fs-h1: 2.7rem;
  --fs-h2: 2.1rem;
  --fs-h3: 1.5rem;
  --fs-h4: 1.2rem;
  --fs-h5: 0.9rem;
  --fs-h6: 0.9rem;

  /* Type scale — body & components */
  --fs-body: 0.9rem;
  --fs-small: 0.72rem;
  --fs-input: 0.72rem;
  --fs-input-focus: 0.8rem;
  --fs-button: 0.9rem;
  --fs-button-small: 0.8rem;
  --fs-table: 0.85rem;
  --fs-table-header: 0.82rem;
}

/* ─── COLOR THEMES ───────────────────────────────────────── */
html[data-theme="dark"] {
  --color-foreground: rgb(201, 201, 201);
  --color-foreground-rgb: 201, 201, 201;
  --color-foreground-brighter: rgb(255, 255, 255);
  --color-foreground-darker: rgb(99, 99, 99);

  --color-background: rgb(19, 19, 19);
  --color-background-rgb: 19, 19, 19;
  --color-background-brighter: rgb(51, 51, 51);
  --color-background-darker: rgb(15, 15, 15);

  --color-accent-01: rgba(150, 222, 162, 1);
  --color-accent-01-rgb: 150, 222, 162;
  --color-accent-01-brighter: rgba(150, 222, 162, 0.9);
  --color-accent-01-darker: rgb(18, 45, 30);

  --color-accent-02: rgb(228, 105, 105);
  --color-accent-02-rgb: 228, 105, 105;
  --color-accent-02-brighter: rgb(246, 135, 135);
  --color-accent-02-darker: rgb(153, 45, 45);

  --color-accent-03: rgb(201, 153, 78);
  --color-accent-03-rgb: 201, 153, 78;
  --color-accent-03-brighter: rgb(222, 186, 123);
  --color-accent-03-darker: rgb(154, 113, 51);
}

html[data-theme="light"] {
  --color-foreground: rgb(51, 51, 51);
  --color-foreground-rgb: 51, 51, 51;
  --color-foreground-brighter: rgb(0, 0, 0);
  --color-foreground-darker: rgb(162, 115, 103);

  --color-background: rgb(249, 238, 221);
  --color-background-rgb: 249, 238, 221;
  --color-background-brighter: rgb(224, 215, 204);
  --color-background-darker: rgb(255, 247, 235);

  --color-accent-01: rgb(56, 142, 80);
  --color-accent-01-rgb: 56, 142, 80;
  --color-accent-01-brighter: rgb(38, 110, 60);
  --color-accent-01-darker: rgb(190, 222, 200);

  --color-accent-02: rgb(184, 52, 29);
  --color-accent-02-rgb: 184, 52, 29;
  --color-accent-02-brighter: rgb(150, 40, 20);
  --color-accent-02-darker: rgb(240, 200, 195);

  --color-accent-03: rgb(154, 113, 51);
  --color-accent-03-rgb: 154, 113, 51;
  --color-accent-03-brighter: rgb(120, 85, 35);
  --color-accent-03-darker: rgb(232, 215, 180);
}

/* ─── BASE RESET ─────────────────────────────────────────── */
* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  color: var(--color-foreground);
  font-family: var(--font-family-01);
  font-size: 1rem;
  line-height: 1.5;
}


/* ============================================================
 * SECTION 2 — FRAMEWORK PRIMITIVES
 * ============================================================ */

/* ─── TYPOGRAPHY ─────────────────────────────────────────── */
h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: var(--font-family-01);
  color: var(--color-foreground);
  margin: var(--space-42) 0 var(--space-30) 0;
  /* When the page is anchor-scrolled (e.g. from sidebar nav), keep the
   * heading below the sticky header instead of behind it. */
  scroll-margin-top: var(--space-90);
}

/* h0 is a ceremonial scale above h1 — used for the largest display text on
 * a page (hero headings, cover-page titles). Not a native HTML element;
 * apply as a class on any heading element where you want this scale. */
.h0 {
  font-family: var(--font-family-01);
  font-size: var(--fs-h0);
  font-weight: 600;
  line-height: 4.2rem;
  color: var(--color-foreground);
  margin: var(--space-30) 0 var(--space-30) 0;
  padding-top: var(--space-21);
}

/* Mobile-first: h1/h2/h3 use smaller base sizes for narrow viewports. At
 * ≥768px the media-query block below restores the desktop token sizes.
 * Line-heights flex with the font-size at each breakpoint. */
h1 {
  font-size: 1.9rem;
  font-weight: 600;
  line-height: 1.3;
  padding-top: var(--space-21);
  margin: var(--space-30) 0 var(--space-30) 0;
}

h2 {
  font-size: 1.6rem;
  font-weight: 600;
  border-top: 3px solid var(--color-foreground);
  line-height: 1.3;
  padding-top: 18px;
  margin: var(--space-60) 0 var(--space-42) 0;
}

h3 {
  font-size: 1.2rem;
  font-weight: 600;
  line-height: 1.4;
  margin: var(--space-60) 0 var(--space-12) 0;
}

@media (min-width: 768px) {
  h1 {
    font-size: var(--fs-h1);
    line-height: 3.6rem;
  }
  h2 {
    font-size: var(--fs-h2);
    line-height: 2.1rem;
  }
  h3 {
    font-size: var(--fs-h3);
    line-height: 1.8rem;
  }
}

h4 {
  font-size: var(--fs-h4);
  line-height: 1.5rem;
  font-weight: 500;
  margin: var(--space-42) 0 var(--space-12) 0;
}

h5 {
  font-size: var(--fs-h5);
  line-height: 1.5rem;
  text-transform: uppercase;
  font-weight: 600;
}

h6 {
  font-size: var(--fs-h6);
  line-height: 1.5rem;
  margin: 0;
  padding: 0 0 var(--space-9) 0;
}

p {
  font-size: var(--fs-body);
  line-height: 1.6;
  letter-spacing: 0.01rem;
  margin: var(--space-12) 0;
}

strong {
  font-weight: 600;
}

em {
  font-style: italic;
}

a {
  color: var(--color-foreground);
  text-decoration: underline;
  text-underline-offset: 0.12rem;
}

a:hover {
  color: var(--color-foreground-brighter);
}

ul,
ol {
  margin: var(--space-12) 0;
  padding-left: var(--space-18);
}

li {
  margin-bottom: var(--space-6);
  line-height: 1.5;
}

code {
  font-family: var(--font-family-02);
  font-size: 0.90em;
  background: var(--color-background-darker);
  padding: 0.2em 0.4em;
  border-radius: 2px;
}

pre.code-block {
  font-family: var(--font-family-02);
  font-size: var(--fs-small);
  background: var(--color-background-darker);
  border: 1px solid var(--color-background-brighter);
  padding: var(--space-12);
  margin: var(--space-12) 0;
  white-space: pre-wrap;
  overflow-x: auto;
}

/* Typography modifiers */
.text-muted {
  color: var(--color-foreground-darker);
}

.text-mono {
  font-family: var(--font-family-02);
}

.hint {
  font-size: var(--fs-small);
  letter-spacing: 0.03rem;
  color: var(--color-foreground);
  line-height: 1.4;
  opacity: 0.72;
}

.eyebrow {
  font-family: var(--font-family-01);
  font-size: var(--fs-small);
  text-transform: uppercase;
  letter-spacing: 0.06rem;
  color: var(--color-foreground);
}

/* Brand mark */
.brand {
  font-family: var(--font-family-01);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 2.4rem;
  margin: 0;
  color: var(--color-foreground);
  border-top: 0;
  padding-top: 0;
  text-transform: lowercase;
}

.brand__secondary {
  padding-left: 1px;
  font-weight: 100;
  letter-spacing: 0.03rem;
  font-style: italic;
  color: var(--color-foreground-darker);
}

/* When the brand wraps a link to the home page, the anchor must inherit
 * the brand's font, weight, colour and tracking — otherwise the browser
 * applies its link colour and underline and breaks the wordmark. The
 * .brand__secondary span inside still wins on colour + style because its
 * own rules are more specific. */
.brand a {
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-decoration: none;
}

.brand a:hover {
  color: var(--color-foreground-brighter);
}

/* ─── LAYOUT REGIONS ─────────────────────────────────────── */
/* The whole page sits on --color-background-darker.
 * The header sits on the same darker background (no divider).
 * <main> is a lighter rectangle (--color-background) with a 6px gap on all
 * four sides — a "framed" layout where the darker background shows through.
 * Mobile-first: base styles target <768px, then upgrade at 768px and 1024px. */

html,
body {
  background-color: var(--color-background-darker);
}

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

/* The lighter rectangle that "floats" inside the darker page.
 * 6px gap on all sides via margin. No max-width. Full bleed.
 * <main> is also the mount target — the router writes each view's HTML
 * into it directly via innerHTML. */
main {
  margin: 0px;
  padding: var(--space-6);
  flex: 1 1 auto;
}

@media (min-width: 768px) {
  main {
    margin: 0 6px 6px 6px;
  }
}

/* ─── HEADER ─────────────────────────────────────────────── */
/* Sticky-on-scroll-up: header is always position: sticky; the
 * .header--hidden state class translates it off-screen when the user is
 * scrolling DOWN. When they scroll UP (or are at the top of the page),
 * the class is removed and the header slides back in. JS handles the
 * direction detection; CSS handles the transform + transition. */
header {
  background-color: var(--color-background-darker);
  padding: var(--space-12) var(--space-24);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-18);
  flex-wrap: nowrap;
  position: sticky;
  top: 0;
  z-index: 100;
  transition: transform 0.25s ease;
}

header.header--hidden {
  transform: translateY(-100%);
}

@media (min-width: 768px) {
  header {
    padding: var(--space-15) var(--space-30) var(--space-12) var(--space-30);
  }
}

/* Header nav — on mobile, hidden by default and revealed as a dropdown
 * panel below the header when .is-open is toggled by the hamburger. At
 * iPad+ (≥768px) it sits inline to the right of the brand. */
.header__nav {
  display: none;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background-color: var(--color-background-darker);
  border-bottom: 1px solid var(--color-background-brighter);
  padding: var(--space-9) var(--space-18);
  z-index: 100;
}

.header__nav.is-open {
  display: flex;
}

.header__nav a {
  font-family: var(--font-family-01);
  font-size: var(--fs-body);
  text-transform: uppercase;
  letter-spacing: 0.06rem;
  color: var(--color-foreground);
  text-decoration: none;
  transition: color 0.2s ease;
  opacity: 0.9;
  padding: var(--space-12) 0;
}

.header__nav a:last-child {
  border-bottom: 0;
}

.header__nav a:hover {
  color: var(--color-foreground-brighter);
}

.header__nav a.is-active {
  color: var(--color-foreground-brighter);
}

@media (min-width: 768px) {
  .header__nav {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-21);
    position: static;
    background: transparent;
    border: 0;
    padding: 0;
    margin-right: auto;
  }
  .header__nav a {
    font-size: 11px;
    padding: 0;
    border-bottom: 0;
  }
}

/* Header action group — brand-side wrapper for theme toggle + hamburger. */
.header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-9);
  flex: 0 0 auto;
}

/* Brand sizing inside the header (overrides the typography-section base
 * for the header context). iPad+ restores the larger line-height. */
.brand {
  font-size: 1rem;
  line-height: 1.6rem;
}

.brand__secondary {
  font-size: 0.9rem;
}

@media (min-width: 768px) {
  .brand {
    font-size: 1rem;
    line-height: 2.1rem;
  }
  .brand__secondary {
    font-size: inherit;
  }
}

/* Hamburger button — shown on mobile (sits to the right of the theme
 * toggle inside .header__actions), hidden on iPad+. Toggling adds
 * .is-open to .header__nav to reveal the dropdown. */
.hamburger {
  background: transparent;
  border: 0px solid var(--color-foreground-darker);
  color: var(--color-foreground);
  width: 32px;
  height: 32px;
  padding: 0;
  margin-right: -6px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  border-radius: 2px;
  transition: all 0.2s ease;
}

.hamburger:hover {
  color: var(--color-foreground-brighter);
}

/* When the menu is open, mark the button distinctly so users see it's
 * the active trigger. */
.hamburger[aria-expanded="true"] {
  color: var(--color-foreground-brighter);
}

@media (min-width: 768px) {
  .hamburger {
    display: none;
  }
}

/* Theme toggle — pair of icon buttons (sun / moon) in the header. */
.theme-toggle {
  display: inline-flex;
  gap: var(--space-9);
  align-items: center;
  align-self: center;
}

.theme-toggle button {
  background: transparent;
  color: var(--color-foreground-darker);
  border: 0;
  padding: var(--space-3);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  line-height: 1;
  opacity: 0.7;
  transition: opacity 0.2s ease, color 0.2s ease;
}

.theme-toggle button:hover {
  opacity: 1;
  color: var(--color-foreground-brighter);
}

.theme-toggle button.is-active {
  opacity: 1;
  color: var(--color-foreground-darker);
}

/* ─── NAVIGATION (tab strip) ──────────────────────────────── */
/* Generic tab pattern. A <nav> with buttons[data-tab] switches between
 * [data-panel] siblings via a delegated handler. Mobile: vertical
 * stacked tabs. iPad+: horizontal paper-folder tabs that visually merge
 * into the panel below them. */
nav {
  display: flex;
  flex-direction: column;
  padding: 0;
  margin: 6px;
  margin-bottom: 0;
  border-bottom: 0;
}

nav button {
  background-color: var(--color-background-darker);
  border: 0;
  border-bottom: 1px solid var(--color-background-brighter);
  padding: var(--space-12) var(--space-18);
  font-family: var(--font-family-01);
  font-size: var(--fs-small);
  text-transform: uppercase;
  letter-spacing: 0.06rem;
  color: var(--color-foreground);
  cursor: pointer;
  transition: color 0.2s ease, background-color 0.2s ease;
  opacity: 0.9;
  text-align: left;
  width: 100%;
}

nav button:last-child {
  border-bottom: 0;
}

nav button:hover {
  color: var(--color-foreground-brighter);
  opacity: 1;
}

nav button.is-active {
  color: var(--color-foreground-brighter);
  opacity: 1;
  font-weight: 600;
}

.panel {
  display: none;
}

.panel.is-active {
  display: block;
}

/* Standalone (embedded) tabs pattern.
 *
 * The page-chrome nav sits as a sibling of <main>; its panels are nested
 * INSIDE main. So `nav ~ .panel` and `nav:has(~ .panel)` deliberately do
 * NOT match the chrome case — main intervenes.
 *
 * They DO match the standalone case: a <nav> with .panel siblings inside any
 * content container (e.g. the Tabs demo on the components docs page).
 *
 * Rules:
 *  - Strip the chrome nav margin so the embedded nav sits flush with content.
 *  - Give panels their own padding (no need for inline styles per panel).
 *  - At iPad+ the active panel gets a bordered surface — this is the "folder
 *    face" that the active tab's bottom edge merges into. The active tab's
 *    `margin-bottom: -1px` + `border-bottom: --color-background` mask the
 *    panel's top border in the slice beneath the active tab. */
nav:has(~ .panel) {
  margin: 0;
}

nav ~ .panel {
  padding: var(--space-18);
  margin-bottom: var(--space-18);
}

.panel__intro {
  font-family: var(--font-family-01);
  font-size: var(--fs-small);
  color: var(--color-foreground-darker);
  text-transform: uppercase;
  letter-spacing: 0.06rem;
  margin-bottom: var(--space-24);
}

@media (min-width: 768px) {
  /* Paper-folder horizontal tabs.
   * Nav itself is transparent. Each tab is an independent surface:
   *  - Inactive tab = --color-background-darker with 1px border (looks like a
   *    card sitting on the darker page).
   *  - Active tab  = --color-background (same as main) with no bottom border
   *    so it visually merges into main below it. */
  nav {
    display: flex;
    flex-direction: row;
    align-items: flex-end;
    margin: 0px 6px 0 6px;
    padding: 0;
    background-color: transparent;
    gap: 6px;
  }

  nav button {
    width: auto;
    border: 1px solid var(--color-background-brighter);
    border-bottom: 0;
    /* tabs sit on top of main; no bottom edge */
    background-color: var(--color-background-darker);
    color: var(--color-foreground);
    padding: var(--space-12) var(--space-18);
  }

  nav button:hover {
    color: var(--color-foreground-brighter);
    background-color: var(--color-background-darker);
  }

  nav button.is-active {
    background-color: var(--color-background);
    color: var(--color-foreground-brighter);
    font-weight: 600;
    /* Active tab is the same surface as main — no border between them.
     * The 1px border-bottom in --color-background mask any rendering seam. */
    border-bottom: 1px solid var(--color-background);
    margin-bottom: -1px;
    position: relative;
    z-index: 1;
  }

  /* Main touches nav (no gap between them) so the active tab merges in */
  nav+main {
    margin-top: 0;
  }

  nav ~ .panel.is-active {
    border: 1px solid var(--color-background-brighter);
  }
}

/* ─── FOOTER ─────────────────────────────────────────────── */
footer {
  background-color: var(--color-background-darker);
  padding: var(--space-12) var(--space-18);
  font-family: var(--font-family-01);
  font-size: var(--fs-small);
  color: var(--color-foreground-darker);
  text-transform: uppercase;
  letter-spacing: 0.06rem;
  display: flex;
  justify-content: space-between;
  gap: var(--space-12);
  flex-wrap: wrap;
}

@media (min-width: 768px) {
  footer {
    padding: var(--space-18) var(--space-24);
  }
}

/* ─── APP-SHELL ──────────────────────────────────────────── */
/* Sidebar + main split for tool / app-style pages.
 * Pattern: <div class="app-shell"> with two children:
 *   <aside class="app-shell__sidebar"> ... .card sections ... </aside>
 *   <div class="app-shell__main"> ... page content ... </div>
 *
 * Mobile-first: single column stack (sidebar, main). At ≥1024px, becomes
 * a grid with a 390px sidebar + 1fr main column. Optional
 * .app-shell__sidebar--sticky keeps the sidebar visible while the main
 * column scrolls. If a .header-section is needed above, place it as a
 * sibling of the .app-shell — not inside. */
.app-shell {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-9);
  min-height: 100%;
  padding: 0;
  /* Negative horizontal margin pulls the app-shell out to fill main's
   * full width edge-to-edge, cancelling main's horizontal padding so the
   * darker app-shell background reaches main's border. Matched to main's
   * padding at each breakpoint. */
  margin: 0;
  background: var(--color-background-darker);
}

@media (min-width: 768px) {
  .app-shell {
    margin: 0;
  }
}

/* Sidebar default-hidden on mobile (sidebar pages compress to a single
 * column of collapsible cards). Revealed at desktop (≥1024px) in the
 * breakpoint block below. */
.app-shell__sidebar {
  display: none;
}

/* Editor-first variant: the sidebar holds the editor and the main column
 * holds a read-only preview. On mobile both stack — editor cards on top,
 * preview below. On desktop the layout becomes the standard two-column
 * grid (sidebar sticky, main beside it). Used by the Brief intake. */
.app-shell--editor-first .app-shell__sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-9);
  min-width: 0;
}

.app-shell__main {
  min-width: 0;
  border: 1px solid var(--color-background-brighter);
  background-color: var(--color-background);
  padding: var(--space-12) var(--space-18);
}

@media (min-width: 1024px) {
  /* App-shell becomes two-column: 390px sidebar + 1fr main. */
  .app-shell {
    grid-template-columns: 390px 1fr;
    gap: var(--space-9);
  }
  /* Sidebar revealed at desktop — undoes the mobile display: none. */
  .app-shell__sidebar {
    display: flex;
    flex-direction: column;
    gap: var(--space-9);
    min-width: 0;
  }
  /* Sticky variant — sidebar stays in view while main scrolls. top accounts
   * for the sticky header above (~70-90px tall). Capped at viewport height
   * minus the same offset so it doesn't overflow off the bottom edge. */
  .app-shell__sidebar--sticky {
    position: sticky;
    top: var(--space-12);
    align-self: start;
    max-height: calc(100vh - var(--space-12) - var(--space-12));
    overflow-y: auto;
    border-top: 1px solid var(--color-background-brighter);
  }
}

/* Nav-list — auto-numbered ordered list for sidebar navigation.
 * Designed to live inside a .card__body in the sidebar. Items show as
 * "00.", "01." etc via list-style-type: decimal-leading-zero. The native
 * `start` attribute on <ol> is honoured (start="0" → 00, default → 01).
 * Active link gets .is-active (accent-01 green, bold). */
.nav-list {
  list-style: decimal-leading-zero outside;
  padding: 0 0 0 var(--space-30);
  margin: 0;
}
.nav-list li {
  margin: 0;
  padding: var(--space-3) 0;
  line-height: 1.5;
}
.nav-list li::marker {
  font-family: var(--font-family-02);
  font-size: var(--fs-small);
  color: var(--color-foreground-darker);
}
.nav-list a {
  color: var(--color-foreground);
  text-decoration: none;
  font-family: var(--font-family-01);
  font-size: var(--fs-body);
  transition: color 0.2s ease;
}
.nav-list a:hover {
  color: var(--color-foreground-brighter);
}
.nav-list a.is-active {
  color: var(--color-accent-01);
  font-weight: 600;
}

/* ─── SECTION BLOCK ──────────────────────────────────────── */
/* Standard content block — sets the page's horizontal gutter so headings,
 * text, and inline children don't sit flush against the framed <main>
 * border. Apply to any wrapper that contains prose-level content. */
.section-block {
  margin: 0px 18px;
}

/* ─── HEADER SECTION ─────────────────────────────────────── */
/* Standard page header — appears once at the top of every routed view.
 * Stacks an eyebrow, an h1, and an h4 (subtitle). The h4 is optional;
 * sub-route headers that have no subtitle (Style Guide items, Core
 * sections) just omit it. The trailing border + bottom margin separates
 * the header from the page body. */
.header-section {
  padding: var(--space-42) 0 var(--space-30);
  margin: var(--space-30) var(--space-18) var(--space-60) var(--space-18);
}

@media (min-width: 768px) {
  /* NOTE: max-width here is a deliberate exception to the "no max-width
   * on main content" rule — the header reads better at a constrained
   * measure on iPad+. If the rule is tightened, reconsider this. */
  .header-section {
    max-width: 800px;
  }
}

.header-section .eyebrow {
  display: block;
  margin-bottom: var(--space-9);
}

.header-section h1 {
  margin: 0;
  padding-top: var(--space-21);
  border-top: 0;
}

.header-section h4 {
  margin: var(--space-12) 0 0 0;
  font-weight: 400;
  color: var(--color-foreground);
  line-height: 1.5;
  letter-spacing: 0.01rem;
  opacity: 0.8;
}

/* ─── COLUMNS BLOCK ──────────────────────────────────────── */
/* Responsive grid of equal-width columns that auto-fit to the viewport.
 * Single column when there isn't room for two; otherwise as many as fit
 * with each column at least 240px wide. Same grid the Home page pillars
 * use. The class is layout-only — apply margins on a wrapper if needed. */
.columns-block {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--space-18);
  align-items: stretch;
}

/* Cards inside a columns-block size to their content and stretch within
 * a row so neighbouring cards share equal heights (via the parent's
 * align-items: stretch). Each card is a flex column so the body absorbs
 * the slack, and any .row-actions inside the body gets pushed to the
 * bottom edge via margin-top: auto. */
.columns-block .card {
  display: flex;
  flex-direction: column;
}

.columns-block .card__body {
  display: flex;
  flex-direction: column;
  flex: 1;
}

.columns-block .card__body .row-actions {
  margin-top: auto;
  padding-top: var(--space-21);
}

/* ─── CARD ───────────────────────────────────────────────── */
/* Card structure:
 *   .card
 *     .card__header   — always visible, fixed 42px, holds title + actions
 *     .card__body     — collapses when .card--collapsed is set on .card
 *
 * Padding lives on the header and body — not on .card — so the header sits
 * flush against the card border. */
.card {
  border: 1px solid var(--color-background-brighter);
  background-color: var(--color-background);
  padding: 0;
  margin: var(--gap) 0px;
}

/* Coloured card variants — each variant declares only its accent palette via
 * two scoped custom properties. The shared colouring rules further down read
 * from these properties, so adding a new variant (e.g. .card--success) is a
 * one-block change: declare the palette here, then extend the :is() lists
 * below. No need to duplicate border / title / icon rules per variant. */
.card--danger {
  --card-accent: var(--color-accent-02);
  --card-accent-darker: var(--color-accent-02-darker);
}

:is(.card--danger) {
  border-color: var(--card-accent-darker);
}

/* Flush variant — strips the card's outer margin. Use when the parent
 * container handles spacing itself (e.g. flex/grid gap in the sidebar),
 * so the card doesn't double-space against the gap. */
.card--flush {
  margin: 0;
}

.card__header {
  height: var(--space-42);
  padding: 0 var(--space-18);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  border-bottom: 1px solid var(--color-background-brighter);
}

:is(.card--danger) .card__header {
  border-bottom-color: var(--card-accent-darker);
}

/* When collapsed, only the header is shown — drop its bottom border so the
 * card doesn't show a double 1px line (header border + card outer border). */
.card--collapsed .card__header {
  border-bottom: 0;
}

.card__header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-9);
  flex: 0 0 auto;
}

.card__toggle,
.card__drag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  background: transparent;
  border: 0;
  color: var(--color-foreground);
  cursor: pointer;
  transition: color 0.2s ease, transform 0.2s ease;
}

.card__toggle:hover,
.card__drag:hover {
  color: var(--color-foreground);
}

.card__drag {
  cursor: grab;
}

/* Chevron points UP when expanded (click to collapse upward); rotates 180°
 * to point DOWN when collapsed (click to expand downward). The arrow always
 * indicates the direction the body content is, or will be, relative to the
 * header. */
.card--collapsed .card__toggle {
  transform: rotate(180deg);
}

.card__title {
  font-family: var(--font-family-01);
  font-size: var(--fs-body);
  text-transform: uppercase;
  letter-spacing: 0.06rem;
  color: var(--color-foreground);
  margin: 0;
  padding: 6px 0 0 0;
  border: 0;
  font-weight: 600;
  flex: 1 1 auto;
  min-width: 0;
}

/* Coloured card variants colour everything inside the card — title, body,
 * note, and header icons — so the surface reads as a single unified state
 * rather than a neutral card with a coloured outline. Colours come from the
 * scoped --card-accent / --card-accent-darker properties set by each variant
 * at the top of the card block. */
:is(.card--danger) .card__title,
:is(.card--danger) .card__body,
:is(.card--danger) .card__note {
  color: var(--card-accent);
}

:is(.card--danger) .card__toggle,
:is(.card--danger) .card__drag {
  color: var(--card-accent-darker);
}

:is(.card--danger) .card__toggle:hover,
:is(.card--danger) .card__drag:hover {
  color: var(--card-accent);
}

.card__body {
  padding: var(--space-18);
}

.card--collapsed .card__body {
  display: none;
}

.card__note {
  font-family: var(--font-family-01);
  font-size: var(--fs-body);
  color: var(--color-foreground);
  opacity: 0.85;
  margin-bottom: var(--space-12);
  line-height: 1.5;
}

/* ─── FORM ───────────────────────────────────────────────── */
/* Mouse focus: hide the browser default outline (custom focus styles
 * on inputs, brief-doc fields etc. provide the visual feedback).
 * Keyboard focus: a thin foreground outline so a11y tabbing works. */
*:focus {
  outline: none;
}

*:focus-visible {
  outline: 2px solid var(--color-foreground);
  outline-offset: 2px;
}

input,
select,
textarea,
button {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  border-radius: 0;
  outline: none;
  background-color: var(--color-background-darker);
  border: 1px solid var(--color-background-brighter);
  color: var(--color-foreground);
  transition: all 0.2s ease;
}

label {
  display: block;
  font-family: var(--font-family-01);
  font-size: var(--fs-small);
  text-transform: uppercase;
  letter-spacing: 0.06rem;
  color: var(--color-foreground);
  margin: var(--space-12) 0 var(--space-6);
  opacity: 0.9;
}

input[type="text"],
input[type="date"],
input[type="number"],
input[type="email"],
input[type="password"],
input[type="search"],
input[type="tel"],
input[type="url"],
textarea,
select {
  width: 100%;
  padding: var(--space-6) var(--space-9);
  font-family: var(--font-family-02);
  font-size: var(--fs-input);
  font-weight: 200;
  letter-spacing: 0.06rem;
  opacity: 0.9;
  color: var(--color-foreground);
  background-color: var(--color-background-darker);
  border: 1px solid var(--color-background-brighter);
}

select {
  padding-right: var(--space-30);
  cursor: pointer;
  text-transform: uppercase;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M0 0 L5 6 L10 0' fill='none' stroke='%23999' stroke-width='1'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-12) center;
}

input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
}

input:focus,
select:focus,
textarea:focus {
  border: 1px solid var(--color-foreground-darker);
  color: var(--color-foreground-brighter);
  opacity: 1;
  font-size: var(--fs-input-focus);
  font-weight: 600;
  /* The border colour change is the focus indicator — suppress the
   * universal :focus-visible 2px outline. */
  outline: none;
}

::placeholder {
  color: var(--color-foreground);
  opacity: 0.4;
}

input:disabled,
select:disabled,
textarea:disabled,
button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ─── BUTTON ─────────────────────────────────────────────── */
button.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6) var(--space-12);
  font-family: var(--font-family-01);
  font-size: var(--fs-button);
  font-weight: 500;
  cursor: pointer;
  background-color: var(--color-background);
  color: var(--color-foreground);
  border: 1px solid rgba(var(--color-foreground-rgb), 0.6);
  border-radius: 2px;
  transition: all 0.2s ease;
  letter-spacing: 0;
  text-transform: none;
}

button.button:hover {
  background-color: var(--color-background-darker);
  color: var(--color-foreground-brighter);
  border: 1px solid var(--color-foreground-brighter);
  opacity: 1;
}

button.button--secondary {
  background-color: transparent;
  color: var(--color-foreground);
  border: 1px solid var(--color-foreground-darker);
}

button.button--secondary:hover {
  color: var(--color-foreground-brighter);
  border-color: var(--color-foreground);
  background-color: transparent;
}

button.button--danger {
  background-color: transparent;
  color: var(--color-accent-02);
  border: 1px solid var(--color-accent-02-darker);
}

button.button--danger:hover {
  background-color: rgba(var(--color-accent-02-rgb), 0.1);
  color: var(--color-accent-02-brighter);
  border-color: var(--color-accent-02);
}

button.button--small {
  padding: var(--space-3) var(--space-9);
  font-size: var(--fs-button-small);
  height: auto;
  width: max-content;
  font-weight: 500;
}

button.button:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

/* :active (pressed) — subtle opacity dip across all button variants */
button.button:active,
button.button--secondary:active,
button.button--danger:active {
  opacity: 0.85;
}

/* ─── TABLE ──────────────────────────────────────────────── */
table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-family: var(--font-family-02);
  font-size: var(--fs-table);
  border: 1px solid var(--color-foreground-darker);
  margin-top: var(--space-42);
}

th,
td {
  text-align: left;
  padding: var(--space-3) var(--space-9);
  border-right: 1px solid var(--color-background-brighter);
  border-bottom: 1px solid var(--color-background-brighter);
  vertical-align: middle;
}

th:last-child,
td:last-child {
  border-right: none;
  text-align: center;
}

/* The VERY last row of the table has no bottom border (the table's own
 * outer border handles the bottom edge). Scoped by parent section so that
 * when a tfoot follows tbody, the last tbody row keeps its border and the
 * separator between body and footer is preserved. */
tbody:last-child > tr:last-child td,
tfoot:last-child > tr:last-child td {
  border-bottom: none;
}

th {
  background-color: var(--color-background);
  border-bottom: 1px solid var(--color-foreground-darker);
  font-family: var(--font-family-01);
  font-size: var(--fs-table-header);
  padding: var(--space-9);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.06rem;
  color: var(--color-foreground-brighter);
  opacity: 0.9;
}

td {
  color: var(--color-foreground);
}

td.num,
th.num {
  text-align: right;
}

.data-table--02 {
  font-size: var(--fs-small);
}

.data-table--02 th,
.data-table--02 td {
  padding: var(--space-3) var(--space-9);
}

.data-table--02 th {
  font-size: var(--fs-small);
  padding: var(--space-6) var(--space-9);
}

/* Modifier: opt out of the global "last cell is centred" rule. Use on
 * reference tables where the last column is descriptive prose. */
.data-table--last-left th:last-child,
.data-table--last-left td:last-child { text-align: left; }

/* Variant 03 — table-card.
 * A wrapper that holds a table together with its own header and footer in a
 * single bordered container. The wrapper carries the only outer border; the
 * inner table drops its border so the two don't double up.
 *
 *   <div class="table-card">
 *     <div class="table-card__header">
 *       <span class="table-card__title">Title</span>
 *       <span class="table-card__subtitle">Subtitle</span>
 *     </div>
 *     <table>…</table>
 *     <div class="table-card__footer">x-small footer note</div>
 *   </div>
 *
 * Header and footer are plain divs with no borders — the container border
 * frames the whole thing; the table's internal cell borders provide rhythm. */
.table-card {
  border: 1px solid var(--color-foreground-darker);
  background-color: var(--color-background);
  margin: 42px 0px 60px 0px;
}
.table-card > table {
  border: 1px solid var(--color-foreground-darker);
    width: calc(100% - 42px);
    margin: auto;
}
.table-card__header {
  padding: var(--space-21) var(--space-21) var(--space-30) var(--space-21);
  border: 0;
}
.table-card__title {
  display: block;
  font-family: var(--font-family-01);
  font-size: var(--fs-small);
  text-transform: uppercase;
  letter-spacing: 0.06rem;
  color: var(--color-foreground-brighter);
  font-weight: 600;
}
.table-card__subtitle {
  display: block;
  font-family: var(--font-family-01);
  font-size: var(--fs-small);
  color: var(--color-foreground);
  font-weight: 400;
  line-height: 1.4;
  margin-top: var(--space-3);
  letter-spacing: 0;
  text-transform: none;
  opacity: 0.8;
}
.table-card__footer {
  padding: var(--space-9) var(--space-18) var(--space-21) var(--space-18);
  font-family: var(--font-family-01);
  font-size: var(--fs-small);
  color: var(--color-foreground-darker);
  font-style: italic;
  border: 0;
}

/* Inside a table-card, the last data row keeps its bottom border so a crisp
 * 1px line separates data from the footer DIV. The global last-row override
 * (which strips the border to avoid doubling against an outer table border)
 * doesn't apply here because the table-card has its own outer border. */
.table-card tbody:last-child > tr:last-child td {
  border-bottom: 1px solid var(--color-background-brighter);
}

/* ─── EMPTY STATE ────────────────────────────────────────── */
.empty-state {
  padding: var(--space-42) var(--space-18);
  margin: var(--space-30) auto;
  text-align: center;
  color: var(--color-foreground-darker);
  font-family: var(--font-family-01);
  font-size: var(--fs-body);
  border: 1px dashed var(--color-background-brighter);
  background-color: var(--color-background-darker);
}

/* ─── STATUS / ALERTS ────────────────────────────────────── */
.status {
  font-family: var(--font-family-01);
  font-size: var(--fs-small);
  color: var(--color-foreground-darker);
  margin-left: var(--space-12);
}

.status--error {
  color: var(--color-accent-02);
}

.status--success {
  color: var(--color-accent-01);
}

.alert {
  padding: var(--space-12) var(--space-18);
  margin: var(--space-30) 0;
  font-size: var(--fs-body);
}

.alert--info {
  background-color: rgba(var(--color-foreground-rgb), 0.1);
  border: 1px solid var(--color-foreground-darker);
  color: var(--color-foreground-brighter);
}

.alert--success {
  background-color: rgba(var(--color-accent-01-rgb), 0.1);
  border: 1px solid var(--color-accent-01-darker);
  color: var(--color-accent-01-brighter);
}

.alert--warning {
  background-color: rgba(var(--color-accent-03-rgb), 0.1);
  border: 1px solid var(--color-accent-03-darker);
  color: var(--color-accent-03-brighter);
}

.alert--error {
  background-color: rgba(var(--color-accent-02-rgb), 0.1);
  border: 1px solid var(--color-accent-02-darker);
  color: var(--color-accent-02-brighter);
}

/* ─── UTILITY ────────────────────────────────────────────── */
.cell-clickable {
  cursor: pointer;
  border-bottom: 1px dotted var(--color-foreground-darker);
}

.row-actions {
  display: flex;
  gap: var(--space-9);
  align-items: center;
  flex-wrap: wrap;
}

.mt-sm {
  margin-top: var(--space-6);
}

.mt-md {
  margin-top: var(--space-12);
}

.mt-lg {
  margin-top: var(--space-15);
}

.mt-0 {
  margin-top: 0;
}

.mb-sm {
  margin-bottom: var(--space-9);
}
