/* =========================================================================
   Haeeum · Dashboard Design System
   -------------------------------------------------------------------------
   Static visual mock. No functionality. Every colour, size and radius here
   is intentional and should be preserved when this design is rebuilt in
   the production app. See DESIGN-NOTES.md for what is new vs the existing
   `docs/haeeum_design.md`.
   ========================================================================= */

/* --- 1. Reset -------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
img, svg { display: block; }
ul { list-style: none; margin: 0; padding: 0; }
table { border-collapse: collapse; width: 100%; }

/* --- 2. Design tokens ------------------------------------------------ */
:root {
  /* Surface — the greys behind everything.
     Note we now use a slightly cooler outer canvas (#eeeeee) than the
     `haeeum_design.md` `canvas-soft: #f9f9f9`, because the dashboard
     needs three distinct greys (frame → panel → surface) instead of two. */
  --canvas:        #eeeeee;   /* outermost body */
  --canvas-frame:  #f5f5f5;   /* main working area inside the frame */
  --canvas-soft:   #f9f9f9;   /* zebra rows, hover fills */
  --surface:       #ffffff;   /* cards, sidebar, buttons */
  --hairline:      #ebebeb;   /* 1px borders */
  --hairline-strong:#e0e0e0;  /* frame outline (needs a touch more contrast) */

  /* Ink — text colours */
  --ink:            #131313;
  --ink-secondary:  #6b6b70;
  --ink-muted:      #9a9a9f;
  --ink-faint:      #b1c0cb;

  /* Nav category colours — reused directly from the existing editorial
     palette in `haeeum_design.md`. Assigned to sections by temperature:
     warm at the top, cool at the bottom. */
  --nav-overview:  #ff8550;   /* accent-orange       (soft coral) */
  --nav-calendar:  #f65108;   /* accent-orange-deep  (vivid orange) */
  --nav-work:      #b83274;   /* accent-magenta */
  --nav-reports:   #3f269a;   /* accent-violet */
  --nav-billing:   #3f269a;   /* accent-violet — footer group */
  --nav-contact:   #3f269a;

  /* Status pills — tinted background + saturated text.
     Category tags (SEO, Email) share the same tint pairs as the matching
     process status, so a viewer only learns two colours. */
  --status-progress-bg: #f5efff; --status-progress-fg: #6d28d9;
  --status-review-bg:   #eef4ff; --status-review-fg:   #2563eb;
  --status-complete-bg: #ecfdf3; --status-complete-fg: #16a34a;

  /* Metric deltas — green up, red down. Very small pills. */
  --metric-up-bg:   #ecfdf3; --metric-up-fg:   #16a34a;
  --metric-down-bg: #fef2f2; --metric-down-fg: #dc2626;

  /* Positive-action tokens — softer than the delta green because these are
     button surfaces, not tiny inline pills. Used by the .btn--approve tick
     and reusable for any future affirmative confirm affordance. */
  --positive-bg:     #f0fdf4;
  --positive-border: #bbf7d0;
  --positive-fg:     #15803d;
  --positive-bg-h:   #dcfce7;
  --positive-border-h: #86efac;

  /* Warning tokens — orange family for "attention needed" states. Used by
     the .pill--warning admin status ("Setup needed") and reusable for any
     future caution/needs-action affordance. */
  --warning-bg:      #fff7ed;
  --warning-border:  #fed7aa;
  --warning-fg:      #c2410c;

  /* Danger tokens — red family for irreversible / destructive actions.
     Used by the admin bar, .btn--danger, and .card--danger. */
  --danger-bg:       #fef2f2;
  --danger-border:   #fecaca;
  --danger-fg:       #dc2626;
  --danger-fg-h:     #b91c1c;

  /* Calendar event tokens — five colourways matching the sidebar palette.
     Solid = coloured fill; Outline = white with coloured border + text. */
  --event-neutral-bg:  #ffffff;  --event-neutral-fg:  var(--ink);
  --event-neutral-br:  var(--hairline);
  --event-blue-bg:     #eaf1ff;  --event-blue-fg:     #1e40af;
  --event-pink-bg:     #fce8f0;  --event-pink-fg:     #b83274;
  --event-purple-bg:   #efe8ff;  --event-purple-fg:   #5b21b6;
  --event-orange-bg:   #fff3e6;  --event-orange-fg:   #c2410c;
  --event-orange-dot:  #f97316;

  /* Typography */
  --font-body:  'Figtree', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-brand: 'Archivo Black', 'Figtree', sans-serif;
  --font-board: 'Doto', ui-monospace, 'Courier New', monospace;
  --font-mono:  ui-monospace, 'JetBrains Mono', SFMono-Regular, monospace;
  --font-tech:  'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;

  /* Airport / arrival board — used by .card--board (Meeting card). */
  --board-bg:    #131313;
  --board-amber: #ff9d3d;
  --board-dim:   rgba(255,255,255,0.55);
  --board-fade:  rgba(255,255,255,0.08);

  /* Radii */
  --r-xs:   4px;
  --r-sm:   6px;
  --r-md:   8px;
  --r-lg:  10px;
  --r-xl:  12px;
  --r-app: 20px;   /* outer app frame */
  --r-full: 9999px;

  /* Elevation — flat + one soft raise */
  --shadow-frame: 0 1px 2px rgba(0,0,0,0.03), 0 10px 40px rgba(0,0,0,0.05);
  --shadow-card:  0 1px 1px rgba(0,0,0,0.02);

  /* Spacing scale — 4px base */
  --s-1: 4px;   --s-2: 8px;   --s-3: 12px;  --s-4: 16px;
  --s-5: 20px;  --s-6: 24px;  --s-7: 28px;  --s-8: 32px;
  --s-10: 40px; --s-12: 48px;

  /* Sidebar geometry */
  --sidebar-w: 232px;
  --sidebar-pad: 20px;
}

/* --- 3. Base ---------------------------------------------------------- */
body {
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.4;
  color: var(--ink);
  background: var(--canvas-frame);           /* body IS the canvas now */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  padding: 16px;                             /* space around floating sidebar/cards */
  min-height: 100vh;
}

/* --- 4. App shell ---------------------------------------------------- */
/* No outer frame chrome — the sidebar and cards float on the canvas
   directly. The frame here is just a layout grid: sidebar column + main
   column with a gap between them. */
.app-frame {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  gap: 20px;
  min-height: calc(100vh - 32px);
}

/* --- 5. Sidebar ------------------------------------------------------- */
/* Floating panel: rounded on all four corners, sticky-pinned to the top
   of the viewport, capped at viewport height so it never grows with the
   scrolling main content. Content inside scrolls internally if it ever
   overflows (currently it doesn't at any reasonable viewport). */
.sidebar {
  position: sticky;
  top: 16px;
  align-self: start;                        /* don't stretch to grid height */
  height: calc(100vh - 32px);               /* full viewport minus body padding */
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-app);
  box-shadow: var(--shadow-frame);
  padding: var(--sidebar-pad);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}

.brand {
  padding: 8px 8px 32px;
  font-family: var(--font-brand);
  font-size: 24px;
  letter-spacing: -0.01em;
  color: var(--ink);
  line-height: 1;
  /* The Figma logo reads heavier than any web font can render at this size.
     Stacking multiple offset text-shadows fakes the extra ink weight so the
     wordmark keeps its "chunky" quality without shipping a custom face. */
  text-shadow:
     0.6px 0 0 currentColor,
    -0.6px 0 0 currentColor,
     0 0.4px 0 currentColor;
}

.sidebar-section-label {
  font-size: 13px;
  color: var(--ink-secondary);
  padding: 0 12px 8px;
  font-weight: 400;
}

.nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Nav row — colour bar (left), icon, label. Active gets a soft fill. */
.nav-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 12px 9px 20px;         /* left pad makes room for the bar */
  border-radius: var(--r-md);
  color: var(--ink);
  font-size: 15px;
  font-weight: 400;
  transition: background 120ms ease;
}
.nav-row::before {                    /* the coloured left bar */
  content: '';
  position: absolute;
  left: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 18px;
  border-radius: 2px;
  background: var(--_bar, var(--ink-faint));
}
.nav-row:hover { background: rgba(19,19,19,0.03); }
.nav-row[aria-current="page"] { background: #f4f4f4; }
.nav-row .nav-icon { width: 18px; height: 18px; color: var(--ink-secondary); stroke-width: 1.6; }
.nav-row[aria-current="page"] .nav-icon { color: var(--ink); }

/* Bar colour per section — assigned via data-section */
.nav-row[data-section="overview"] { --_bar: var(--nav-overview); }
.nav-row[data-section="calendar"] { --_bar: var(--nav-calendar); }
.nav-row[data-section="work"]     { --_bar: var(--nav-work); }
.nav-row[data-section="reports"]  { --_bar: var(--nav-reports); }
.nav-row[data-section="billing"]  { --_bar: var(--nav-billing); }
.nav-row[data-section="contact"]  { --_bar: var(--nav-contact); }

/* Nav rows without an icon (currently just Billing). The label sits
   directly after the colour bar with no reserved icon slot, so we drop
   the flex gap that would otherwise create a floating empty space. */
.nav-row--noicon { gap: 0; }

/* Sidebar footer — Billing/Contact + profile pushed to bottom */
.sidebar-footer {
  margin-top: auto;
  padding-top: var(--s-4);
}

.profile {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  margin-top: 12px;
  border-top: 1px solid var(--hairline);
  padding-top: 20px;
}
.profile-avatar {
  width: 36px;
  height: 36px;
  border-radius: var(--r-full);
  background: #d9d9dc;
  flex-shrink: 0;
}
.profile-name {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.2;
}
.profile-email {
  font-size: 12px;
  color: var(--ink-secondary);
  line-height: 1.2;
  margin-top: 2px;
}

/* --- 6. Main area ---------------------------------------------------- */
/* Main flows on the canvas next to the sidebar. Body padding + grid gap
   handle exterior spacing, so main only needs a small top offset to
   keep the page title aligned with the sidebar's top edge. */
.main {
  padding: 8px 0 0 0;
  min-width: 0;                       /* lets children shrink */
}

.page-header {
  padding-bottom: 20px;
  margin-bottom: 24px;
  border-bottom: 1px solid var(--hairline);
}
.page-title {
  margin: 0;
  font-size: 32px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  line-height: 1.1;
}

/* --- 7. Card primitive ---------------------------------------------- */
/* Every section on the page (Approvals, Current work, Calendar, …) uses
   the same card chrome. Header + body pattern; children control layout.
   Flex column so single-record cards can grow their data row to fill
   height when they sit next to a taller sibling in a cards-row. */
.card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
/* Vertical spacing between top-level cards on the page. Scoped to direct
   children of .main so that cards inside a .cards-row (side-by-side)
   aren't pushed down by 20px — they're siblings in a grid, not stacked. */
.main > .card + .card,
.main > .cards-row + .card {
  margin-top: 20px;
}

/* The last flex-list row in any card expands to fill remaining vertical
   space. Content is already `align-items: center` inside the row, so the
   record sits in the visual centre of that space rather than at the top
   with empty canvas beneath it. Harmless for multi-record cards because
   they naturally consume the available height already. */
.card > .data-list-row:last-of-type { flex: 1; }

/* Airport arrival board variant — dark surface, uppercase labels, big
   amber Doto values with a soft LED-style glow. Used by the Upcoming
   meeting card as a deliberate "feature moment" against the otherwise
   quiet white-card grid. The variant only restyles chrome; it inherits
   all the flex-column + fill-tail behaviour from the base .card. */
.card--board {
  background: var(--board-bg);
  border-color: var(--board-bg);
  color: rgba(255,255,255,0.9);
}
.card--board .card-header {
  color: var(--board-dim);
  border-bottom-color: var(--board-fade);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 12px;
  font-weight: 600;
}
/* Meeting-link button pops as a subtle amber-outline pill instead of the
   default dark primary (which would vanish on the black card). */
.card--board .btn--primary {
  background: transparent;
  border: 1px solid rgba(255,157,61,0.35);
  color: var(--board-amber);
}
.card--board .btn--primary:hover {
  background: rgba(255,157,61,0.08);
  border-color: rgba(255,157,61,0.55);
  opacity: 1;
}

/* The "board face" — vertical stack of hero time, sub date, agenda
   prose. Grows to fill remaining card height so the content sits in the
   visual centre when the card is stretched to match its sibling.
   Sizes are deliberately compact so the natural height of this face is
   *shorter* than the Approvals card — the grid then stretches the board
   to match Approvals, and centering keeps things looking intentional. */
.board-face {
  flex: 1;
  padding: 14px 20px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
}
.board-value {
  font-family: var(--font-board);
  font-weight: 700;
  color: var(--board-amber);
  text-transform: uppercase;
  text-shadow: 0 0 8px rgba(255,157,61,0.35);
  line-height: 1;
  letter-spacing: 0;
}
.board-value--hero { font-size: 26px; }
.board-value--sub  { font-size: 13px; opacity: 0.85; margin-top: 4px; }
/* Agenda prose stays in regular sans — Doto is a display font, not built
   for running text longer than a few words. Sits below the numeric stack
   with a divider gap. */
.board-agenda {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--board-fade);
  color: rgba(255,255,255,0.65);
  font-size: 13px;
  line-height: 1.35;
}

/* --- 8c. Metric grid — Bi-weekly report ------------------------------
   3×2 grid of metric tiles. Each tile carries a small label, a big
   tabular value, a delta pill and a sparkline that trends with the
   metric. The grid uses a 1px gap on a hairline background so the
   dividers between tiles are the hairline itself — cheaper than
   painting borders on every tile and clips cleanly at the card edges. */
.metric-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--hairline);
}
.metric-tile {
  background: var(--surface);
  padding: 18px 20px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}
.metric-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 22px;                          /* keeps tiles aligned when delta is absent */
}
.metric-label {
  font-size: 13px;
  color: var(--ink-secondary);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.metric-value {
  font-size: 26px;
  font-weight: 700;
  color: var(--ink);
  line-height: 1;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
/* Delta pill in a tile — same visual language as the .delta pill used
   elsewhere, no left margin since it's a flex sibling here. */
.metric-tile .delta { margin-left: 0; }

/* Sparklines — inline SVG, height dictated by container, width fills.
   Colour matched to the delta direction so trend reads at a glance.
   No end-cap dot: circles get warped by preserveAspectRatio="none"
   (which we need so the polyline fills the container width), and modern
   sparklines look cleaner without one anyway. */
.metric-spark {
  display: block;
  width: 100%;
  height: 28px;
  overflow: visible;
}
.metric-spark--up   { color: var(--metric-up-fg); }
.metric-spark--down { color: var(--metric-down-fg); }
.metric-spark .spark-line { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.metric-spark .spark-area { fill: currentColor; opacity: 0.12; }

/* Display-number variant — for count metrics where there's nothing to
   trend, we skip the sparkline and render the value as a big amber Doto
   number instead. Same visual language as the airport board's time
   value (Doto + amber glow), tying the two "feature moments" on the
   page together. Doto's cap height is roughly 60% of its em, so the
   font-size runs much larger than the sans values to feel comparable. */
.metric-tile--display .metric-display {
  font-family: var(--font-board);
  font-weight: 700;
  font-size: 80px;
  line-height: 1;
  color: var(--board-amber);
  text-shadow: 0 0 12px rgba(255,157,61,0.25);
  letter-spacing: 0;
  flex: 1;
  display: flex;
  align-items: center;
  margin: 4px 0 -4px;                       /* optical alignment */
}

.card-header {
  padding: 12px 20px;
  border-bottom: 1px solid var(--hairline);
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 52px;
}
.card-header--centered { justify-content: center; }
/* When the header hosts a CTA on the right, the CTA sits flush. Content
   before it (the title) takes remaining space. */
.card-header > .btn { margin-left: auto; }

/* Two-up row (Approvals + Upcoming meeting).
   Approvals is the priority (a work-in-progress queue) so it gets ~2/3
   of the row. The Meeting board sits at ~1/3 — enough space to display
   the next meeting's time + date + title stacked, while keeping the
   focus on the actionable queue. */
.cards-row {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 20px;
}

/* --- 8. Data table --------------------------------------------------- */
/* One table style covers every list on the page. Column widths are set
   per-instance via inline style so each section can breathe. */
.data-table {
  font-size: 14px;
}
.data-table th {
  text-align: left;
  padding: 10px 16px;
  font-weight: 400;
  font-size: 13px;
  color: var(--ink-secondary);
  border-bottom: 1px solid var(--hairline);
  background: var(--canvas-soft);
  white-space: nowrap;
}
.data-table th .sort-caret {
  display: inline-block;
  margin-left: 4px;
  color: var(--ink-muted);
  font-size: 11px;
}
.data-table td {
  padding: 16px 16px;
  border-bottom: 1px solid var(--hairline);
  vertical-align: middle;
  color: var(--ink);
}
.data-table tr:last-child td { border-bottom: 0; }
/* First/last cells get a touch more edge padding so content doesn't kiss the card border. */
.data-table th:first-child, .data-table td:first-child { padding-left: 20px; }
.data-table th:last-child,  .data-table td:last-child  { padding-right: 20px; }

/* Auto layout variant — cells size to their content instead of the % widths.
   Used by the Upcoming meeting card, where a fixed-width table can't
   guarantee enough room for the inline avatar + name + CTA. */
.data-table--auto { table-layout: auto; width: 100%; }
.data-table--auto th, .data-table--auto td { white-space: nowrap; }

/* --- 8b. Data list — flex-based table alternative -------------------
   Used by any card whose rows need to hold heavy inline content — an
   avatar + name + CTA, or a tag + task + two action buttons — that a
   rigid table column can't guarantee room for. Behaves visually like a
   table (header labels row + value rows) but flex sizing prevents the
   overflow-clip problem the Meeting card ran into with `table-layout`.
   Supports either a single row (Meeting) or a stack (Approvals). */
.data-list-head, .data-list-row {
  display: flex;
  align-items: center;
  padding: 0 20px;
}
.data-list-head {
  padding-top: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--hairline);
  font-size: 13px;
  color: var(--ink-secondary);
  gap: 20px;
  background: var(--canvas-soft);
}
.data-list-row {
  padding-top: 16px;
  padding-bottom: 16px;
  font-size: 14px;
  color: var(--ink);
  gap: 20px;
  min-height: 60px;
  border-bottom: 1px solid var(--hairline);
}
.data-list-row:last-child { border-bottom: 0; }

/* Cell widths are set per-column via inline style so the header labels
   and value rows line up. `--grow` fills remaining space; `--stack` makes
   a cell hold a two-line block (primary text + muted subtitle). */
.data-cell { min-width: 0; }
.data-cell--grow { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; }
.data-cell--stack { flex-direction: column; align-items: flex-start; gap: 4px; }
.data-cell--who { flex: 1; display: flex; align-items: center; gap: 10px; }
.data-cell--who .btn { margin-left: auto; }
.data-cell--actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-shrink: 0; }

/* Two-line row content — primary line (usually tag + title) + muted meta line.
   The primary line handles overflow so long titles ellipsize cleanly. */
.stack-primary {
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 100%;
  overflow: hidden;
  font-size: 14px;
  color: var(--ink);
}
.stack-primary > *:not(.tag) {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.stack-meta {
  font-size: 13px;
  color: var(--ink-secondary);
}

/* Cell content patterns */
.cell-task-title { font-weight: 600; color: var(--ink); }
.cell-task-sub   { font-size: 13px; color: var(--ink-secondary); margin-top: 2px; }
.cell-numeric    { font-variant-numeric: tabular-nums; white-space: nowrap; }
.cell-actions    { text-align: right; white-space: nowrap; }
.cell-icon       { width: 36px; text-align: center; }
.cell-nowrap     { white-space: nowrap; }

/* Avatar in a cell */
.avatar-sm {
  width: 28px;
  height: 28px;
  border-radius: var(--r-full);
  background: #d9d9dc center/cover;
  display: inline-block;
  vertical-align: middle;
}
.avatar-inline {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.avatar-inline .avatar-sm { width: 32px; height: 32px; }

/* Row of avatar + participant text (Approvals) */
.who-with {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: var(--ink);
}

/* Kebab menu placeholder */
.kebab {
  color: var(--ink-muted);
  padding: 4px 8px;
  border-radius: var(--r-sm);
  font-size: 18px;
  letter-spacing: 1px;
  line-height: 1;
}
.kebab:hover { background: var(--canvas-soft); color: var(--ink); }

/* --- 9. Badges, pills, tags ----------------------------------------- */
/* Pill — the shared shape for every state indicator on the page. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: var(--r-full);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.4;
  white-space: nowrap;
}
.pill::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: var(--r-full);
  background: currentColor;
  opacity: 0.9;
  flex-shrink: 0;
}
.pill--no-dot::before { display: none; }

/* Pill variants — status & category share tints */
.pill--progress { background: var(--status-progress-bg); color: var(--status-progress-fg); }
.pill--review   { background: var(--status-review-bg);   color: var(--status-review-fg); }

/* Complete — deliberately distinct from the tinted "in-flight" pills
   (In Progress, Ready for Review). Those signal active work with
   colour; Complete is a finalised state and wears a formal white
   badge with a solid green dot instead. Reads as "closed" rather
   than "look at me". */
.pill--complete {
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--hairline);
  padding: 6px 12px;
  font-size: 13px;
  gap: 8px;
}
.pill--complete::before {
  background: var(--metric-up-fg);
  opacity: 1;
  width: 10px;
  height: 10px;
}

.pill--seo   { background: var(--status-progress-bg); color: var(--status-progress-fg); }
.pill--email { background: var(--status-review-bg);   color: var(--status-review-fg); }

/* Category tag = smaller pill without dot */
.tag {
  display: inline-block;
  padding: 3px 8px;
  border-radius: var(--r-full);
  font-size: 11px;
  font-weight: 500;
}
.tag--seo   { background: var(--status-progress-bg); color: var(--status-progress-fg); }
.tag--email { background: var(--status-review-bg);   color: var(--status-review-fg); }

/* Metric delta pill (↑ 20%, ↓ 4%) */
.delta {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 8px;
  border-radius: var(--r-full);
  font-size: 12px;
  font-weight: 500;
  margin-left: 8px;
  font-variant-numeric: tabular-nums;
}
.delta--up   { background: var(--metric-up-bg);   color: var(--metric-up-fg); }
.delta--down { background: var(--metric-down-bg); color: var(--metric-down-fg); }

/* --- 10. Buttons ----------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border-radius: var(--r-md);
  font-size: 13px;
  font-weight: 500;
  transition: opacity 120ms ease, background 120ms ease;
  border: 1px solid transparent;
  line-height: 1.4;
  white-space: nowrap;
}
.btn svg { width: 14px; height: 14px; stroke-width: 2; }

.btn--primary {
  background: var(--ink);
  color: var(--surface);
}
.btn--primary:hover { opacity: 0.9; }

.btn--secondary {
  background: var(--surface);
  color: var(--ink);
  border-color: var(--hairline);
}
.btn--secondary:hover { background: var(--canvas-soft); }

.btn--ghost {
  background: transparent;
  color: var(--ink);
}
.btn--ghost:hover { background: var(--canvas-soft); }

.btn--icon {
  padding: 8px;
  width: 34px;
  height: 34px;
  justify-content: center;
  color: var(--ink-secondary);
}
.btn--icon.btn--secondary { color: var(--ink); }

/* Approve — soft green badge, used for affirmative confirm actions.
   Defaults to a text button (used in Task page CTAs); combine with
   `.btn--icon` to get the compact icon-only variant (used in the
   Approvals card rows). Uses `--positive-*` tokens so any future
   confirm affordance can share the same visual language. */
.btn--approve {
  background: var(--positive-bg);
  color: var(--positive-fg);
  border: 1.5px solid var(--positive-border);
  padding: 7px 14px;
  font-weight: 600;
}
.btn--approve.btn--icon {
  padding: 0;
  width: 34px;
  height: 34px;
  justify-content: center;
}
.btn--approve:hover {
  background: var(--positive-bg-h);
  border-color: var(--positive-border-h);
  opacity: 1;
}
.btn--approve svg { stroke-width: 2.5; }
.btn--approve.btn--icon svg { width: 16px; height: 16px; }

/* View task / meeting link buttons are compact pill-primary */
.btn--task {
  padding: 7px 14px;
  border-radius: var(--r-md);
  font-size: 13px;
}

/* --- 11. Progress bar ---------------------------------------------- */
/* Used in the Current work "Current Stage" column. */
.progress {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 130px;
}
.progress-track {
  flex: 1;
  height: 6px;
  background: #ececec;
  border-radius: var(--r-full);
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  background: var(--ink);
  border-radius: var(--r-full);
}
.progress-value {
  font-size: 13px;
  color: var(--ink-secondary);
  min-width: 32px;
  font-variant-numeric: tabular-nums;
}

/* --- 12. Calendar --------------------------------------------------- */
.calendar-toolbar {
  display: flex;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid var(--hairline);
  gap: 16px;
}

.date-badge {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 62px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  padding: 6px 0;
}
.date-badge-month {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--ink-secondary);
  text-transform: uppercase;
}
.date-badge-day {
  font-size: 26px;
  font-weight: 700;
  line-height: 1;
  margin-top: 4px;
  color: var(--nav-reports);          /* violet accent */
}

.calendar-title-block {
  flex: 1;
  min-width: 0;
}
.calendar-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--ink);
  line-height: 1.2;
}
.week-pill {
  display: inline-block;
  padding: 3px 10px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-secondary);
}
.calendar-range {
  font-size: 14px;
  color: var(--ink-secondary);
  margin-top: 4px;
}

.calendar-controls {
  display: flex;
  align-items: center;
  gap: 8px;
}
.calendar-controls .select {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--ink);
  font-size: 13px;
  font-weight: 500;
}
.calendar-controls .select svg { width: 14px; height: 14px; color: var(--ink-secondary); }

/* Calendar grid */
.calendar-grid {
  display: grid;
  grid-template-columns: 60px repeat(7, 1fr);
  border-top: 1px solid var(--hairline);
}
.calendar-day-head {
  padding: 12px 10px;
  font-size: 13px;
  color: var(--ink-secondary);
  border-bottom: 1px solid var(--hairline);
  border-right: 1px solid var(--hairline);
  text-align: left;
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.calendar-day-head:last-child { border-right: 0; }
.calendar-day-head .num { font-weight: 700; color: var(--ink); font-size: 14px; }
.calendar-day-head--today .num {
  background: var(--nav-reports);
  color: #fff;
  width: 22px;
  height: 22px;
  border-radius: var(--r-full);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
}

.calendar-timeslot {
  padding: 8px 12px;
  font-size: 12px;
  color: var(--ink-muted);
  border-bottom: 1px solid var(--hairline);
  border-right: 1px solid var(--hairline);
  min-height: 96px;
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;         /* label sits top-right */
}

.calendar-cell {
  border-bottom: 1px solid var(--hairline);
  border-right: 1px solid var(--hairline);
  min-height: 96px;
  padding: 6px;
  position: relative;
}
.calendar-cell:nth-last-child(-n+7) { border-bottom: 0; }
.calendar-cell:last-child { border-right: 0; }

/* Event pill inside a cell */
.event {
  display: block;
  padding: 8px 10px;
  border-radius: var(--r-md);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  border: 1px solid transparent;
}
.event-time {
  display: block;
  font-size: 12px;
  font-weight: 400;
  margin-top: 3px;
  opacity: 0.9;
}
.event--neutral { background: var(--event-neutral-bg); color: var(--event-neutral-fg);
                  border-color: var(--event-neutral-br); }
.event--blue    { background: var(--event-blue-bg);    color: var(--event-blue-fg); }
.event--pink    { background: var(--event-pink-bg);    color: var(--event-pink-fg); }
.event--purple  { background: var(--event-purple-bg);  color: var(--event-purple-fg); }
.event--orange  { background: var(--event-orange-bg);  color: var(--event-orange-fg);
                  position: relative; }
.event--orange::after {
  content: '';
  position: absolute;
  top: 8px; right: 8px;
  width: 7px; height: 7px;
  border-radius: var(--r-full);
  background: var(--event-orange-dot);
}

/* Multi-slot events grow to fill their parent cell. Combine with a cell
   spanning multiple grid rows (via inline `grid-row: span 2`) to visually
   cover two time slots. */
.event--tall {
  min-height: 168px;
  height: 100%;
}
.calendar-cell--span-2 { grid-row: span 2; }
.calendar-cell--span-2 .event { height: 100%; }

/* --- 13. Utilities -------------------------------------------------- */
.hstack { display: inline-flex; align-items: center; gap: 8px; }
.right  { text-align: right; }
.muted  { color: var(--ink-secondary); }
.tabular { font-variant-numeric: tabular-nums; }

/* --- 15. Task detail page ------------------------------------------- */
/* All styles below are used only by work-task.html. Grouped together
   so they can be lifted out into a separate stylesheet later if the
   design system grows beyond one file. */

/* Breadcrumb — small path above the page title. Links dim, current
   page is full ink. */
.breadcrumb {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--ink-secondary);
  margin-bottom: 14px;
}
.breadcrumb a { color: inherit; transition: color 120ms ease; }
.breadcrumb a:hover { color: var(--ink); }
.breadcrumb-sep { color: var(--ink-faint); }
.breadcrumb-current { color: var(--ink); font-weight: 500; }

/* Task header — title + inline meta + right-aligned action group.
   Replaces the standard .page-header on task detail views. */
.task-header {
  display: flex;
  align-items: flex-start;
  gap: 24px;
  padding-bottom: 24px;
  margin-bottom: 24px;
  border-bottom: 1px solid var(--hairline);
}
.task-header-content { flex: 1; min-width: 0; }
.task-header-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
  padding-top: 4px;
}
.task-title {
  margin: 0;
  font-size: 32px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--ink);
}
.task-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 12px;
  font-size: 14px;
  color: var(--ink-secondary);
}
.task-meta .task-meta-sep { color: var(--ink-faint); }

/* Two-column layout for the task body. Sidebar is narrower than the
   main preview so the content stays the visual anchor. */
.task-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 20px;
  align-items: start;
}

/* Browser-chrome preview — the content the client is being asked to
   review, dressed as a mini website preview. Signals "this is what
   your site will look like" rather than "here's a wall of raw text". */
.preview-frame {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.preview-chrome {
  background: var(--canvas-soft);
  padding: 10px 14px;
  border-bottom: 1px solid var(--hairline);
  display: flex;
  align-items: center;
  gap: 12px;
}
.preview-dots { display: flex; gap: 6px; flex-shrink: 0; }
.preview-dot {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: #e0e0e0;
}
.preview-url {
  flex: 1;
  background: var(--surface);
  border: 1px solid var(--hairline);
  padding: 5px 12px;
  border-radius: var(--r-sm);
  font-size: 12px;
  color: var(--ink-secondary);
  text-align: center;
  font-family: var(--font-mono);
  max-width: 500px;
  margin: 0 auto;
}

/* Preview body — a mock blog article. Serifed for that "editorial"
   feel and to visually distance the preview from the surrounding UI. */
.preview-body {
  padding: 48px 64px 56px;
}
.preview-hero {
  height: 220px;
  border-radius: var(--r-lg);
  margin-bottom: 32px;
  background:
    radial-gradient(circle at 30% 40%, rgba(255,255,255,0.4) 0%, transparent 40%),
    linear-gradient(135deg, #ff9d3d 0%, #b83274 60%, #3f269a 100%);
}
.preview-eyebrow {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--nav-work);
  margin-bottom: 12px;
}
.preview-title {
  margin: 0 0 12px;
  font-family: 'Georgia', 'Times New Roman', serif;
  font-size: 34px;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.preview-byline {
  font-size: 14px;
  color: var(--ink-secondary);
  margin-bottom: 28px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--hairline);
}
.preview-body p {
  font-family: 'Georgia', 'Times New Roman', serif;
  font-size: 17px;
  line-height: 1.7;
  color: #2a2a2a;
  margin: 0 0 18px;
}
.preview-body p:first-of-type::first-letter {
  float: left;
  font-size: 58px;
  line-height: 1;
  font-weight: 700;
  padding: 6px 10px 0 0;
  color: var(--ink);
}

/* Side column — stack of narrow cards. All override the standard card
   padding to feel tighter. */
.task-side {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.side-body {
  padding: 16px 18px 18px;
}
/* Side cards get a smaller header font — they're supporting cast. */
.task-side .card-header {
  padding: 12px 18px;
  font-size: 13px;
  min-height: 44px;
}
/* Side variant of the board — hero size scaled down to fit the narrow
   column, otherwise inherits everything from .card--board. */
.task-side .card--board .board-face { padding: 20px 18px; }
.task-side .card--board .board-value--hero { font-size: 32px; }
.task-side .card--board .board-value--sub  { font-size: 13px; }
.task-side .card--board .board-agenda { font-size: 13px; margin-top: 12px; padding-top: 12px; }

/* Detail rows — label:value pairs used in the sidebar cards. */
.detail-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.detail-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
}
.detail-label { color: var(--ink-secondary); }
.detail-value { color: var(--ink); font-weight: 500; text-align: right; }

/* Timeline — vertical line with status-coloured dots. Used in the
   Activity card. Mimics how Linear/GitHub show issue history. */
.timeline {
  position: relative;
  padding-left: 22px;
}
.timeline::before {
  content: '';
  position: absolute;
  left: 5px;
  top: 6px;
  bottom: 6px;
  width: 1px;
  background: var(--hairline);
}
.timeline-item {
  position: relative;
  padding-bottom: 16px;
  font-size: 13px;
  color: var(--ink);
  line-height: 1.4;
}
.timeline-item:last-child { padding-bottom: 0; }
.timeline-item::before {
  content: '';
  position: absolute;
  left: -22px;
  top: 4px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--ink-muted);
  box-sizing: border-box;
}
.timeline-item[data-kind="approve"]::before { border-color: var(--metric-up-fg); }
.timeline-item[data-kind="review"]::before  { border-color: var(--status-review-fg); }
.timeline-item[data-kind="submit"]::before  { border-color: var(--status-progress-fg); }
.timeline-item[data-kind="comment"]::before { border-color: var(--ink-muted); }
.timeline-actor { font-weight: 600; }
.timeline-desc  { color: var(--ink-secondary); }
.timeline-time  { font-size: 12px; color: var(--ink-muted); margin-top: 2px; }

/* Comments section — sits below the preview + sidebar layout. */
.comment-section {
  margin-top: 32px;
  padding-top: 28px;
  border-top: 1px solid var(--hairline);
}
.section-title {
  margin: 0 0 20px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  display: flex;
  align-items: center;
  gap: 8px;
}
.section-title-count {
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-secondary);
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  padding: 1px 8px;
  border-radius: var(--r-full);
}

.comment-list {
  display: flex;
  flex-direction: column;
  gap: 24px;
  margin-bottom: 24px;
}
.comment {
  display: flex;
  gap: 12px;
}
.comment-avatar {
  width: 36px;
  height: 36px;
  border-radius: var(--r-full);
  flex-shrink: 0;
  background: #d9d9dc;
}
.comment-body { flex: 1; min-width: 0; }
.comment-bubble {
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  padding: 12px 14px;
}
.comment--own .comment-bubble {
  background: var(--surface);
}
.comment-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 4px;
}
.comment-author { font-weight: 600; font-size: 13px; color: var(--ink); }
.comment-time { font-size: 12px; color: var(--ink-muted); }
.comment-text {
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
}

/* Composer — the "add a comment" input at the bottom of the thread.
   Textarea styled to look intentional rather than default-browser. */
.composer {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}
.composer-body { flex: 1; min-width: 0; }
.composer textarea {
  width: 100%;
  min-height: 80px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  padding: 12px 14px;
  background: var(--surface);
  font-family: inherit;
  font-size: 14px;
  color: var(--ink);
  resize: vertical;
  transition: border-color 120ms ease;
}
.composer textarea:focus {
  outline: none;
  border-color: var(--ink-secondary);
}
.composer-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 10px;
}

/* --- 17. Month calendar (calendar.html) ----------------------------
   The Calendar page uses month view only — content cadence is sparse
   enough (~1-2 items per week) that day/week views would feel empty.
   All classes below prefixed .month-* to keep them distinct from the
   older .calendar-* week-view classes retained in §12. */

/* Toolbar row above the grid — month nav + filter segmented control. */
.month-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}
.month-nav {
  display: flex;
  align-items: center;
  gap: 12px;
}
.month-title {
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--ink);
  min-width: 200px;
}

/* Segmented control — used for the All/Blogs/Emails filter. General
   enough to live outside the calendar scope if we need it elsewhere. */
.segmented {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
}
.segmented-item {
  padding: 5px 14px;
  border-radius: calc(var(--r-md) - 3px);
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-secondary);
  background: transparent;
  transition: color 120ms ease;
}
.segmented-item:hover { color: var(--ink); }
.segmented-item[aria-selected="true"] {
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 1px 2px rgba(0,0,0,0.06);
}

/* The month grid itself — 7 columns, natural row height driven by cell
   min-height. Border-top+left on the grid + right+bottom on each cell
   forms the divider skeleton without doubling up strokes. */
.month-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  border-top: 1px solid var(--hairline);
  border-left: 1px solid var(--hairline);
  background: var(--surface);
  border-radius: var(--r-xl);
  overflow: hidden;
}

.month-day-head {
  padding: 11px 14px;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-secondary);
  background: var(--canvas-soft);
  border-right: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}

.month-cell {
  min-height: 128px;
  padding: 10px;
  border-right: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--surface);
  transition: background 120ms ease;
}
.month-cell:hover { background: #fbfbfc; }

/* Day-of-month number in the top-left of the cell. */
.month-cell-num {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  line-height: 1;
  padding: 2px 4px;
  align-self: flex-start;
}

/* Days from the previous/next month — visible but dimmed so the current
   month reads as the visual centre. */
.month-cell--other { background: var(--canvas-soft); }
.month-cell--other .month-cell-num { color: var(--ink-faint); font-weight: 400; }

/* Weekends — very subtle tint on the current-month cells only. Works
   with the muted background of --other cells because both use the same
   canvas-soft token. */
.month-cell--weekend:not(.month-cell--other) {
  background: color-mix(in oklab, var(--surface) 96%, var(--canvas));
}

/* Today — day number gets the violet circle (same treatment as the old
   week-view toolbar's "Fri 8" today badge). */
.month-cell--today .month-cell-num {
  background: var(--nav-reports);
  color: #fff;
  width: 24px;
  height: 24px;
  border-radius: var(--r-full);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  font-weight: 600;
}

/* Event pill inside a cell. Category tag on top, title below — a
   two-line stack because the ~156px cell width can't fit "SEO ·
   September Blog Post #3" inline. */
.month-event {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  cursor: pointer;
  min-width: 0;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.month-event:hover {
  border-color: var(--ink-muted);
  box-shadow: 0 1px 2px rgba(0,0,0,0.04);
}
.month-event--blog { border-left: 3px solid var(--status-progress-fg); }
.month-event--email { border-left: 3px solid var(--status-review-fg); }

.month-event-tag {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 2px 6px;
  border-radius: var(--r-full);
  align-self: flex-start;
  line-height: 1.4;
}
.month-event--blog .month-event-tag {
  background: var(--status-progress-bg);
  color: var(--status-progress-fg);
}
.month-event--email .month-event-tag {
  background: var(--status-review-bg);
  color: var(--status-review-fg);
}
.month-event-title {
  font-size: 12px;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

/* Past events — subtle "already posted" state. Green tick appended
   inline with the tag. */
.month-event--past { opacity: 0.7; }
.month-event--past .month-event-tag::after {
  content: ' ✓';
  color: var(--metric-up-fg);
  font-weight: 700;
}

/* --- 19. Contact page ----------------------------------------------
   Warmer treatment than the other pages — this is where the client
   goes to talk to a person. Big featured contact card at the top,
   team grid below, and a fallback contact-methods row at the bottom.
   Signature warm-to-cool gradient (also used on the Task preview
   hero) is reused for the primary card's portrait side so the page
   feels intentional rather than just a wall of cards. */

/* Section titles between blocks — smaller than page headers but bigger
   than card headers. Used to break the page into "Your team" / "Other
   ways to reach us". */
.page-section-title {
  margin: 32px 0 16px;
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.005em;
}

/* Featured primary-contact card — split into a coloured portrait side
   and a white info side. The portrait uses the app's signature warm-
   to-cool gradient to signal "this is the hero." */
.contact-hero {
  display: grid;
  grid-template-columns: 320px 1fr;
  overflow: hidden;
  padding: 0;                                     /* card children handle padding */
}
.contact-hero-portrait {
  padding: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  background:
    radial-gradient(circle at 30% 30%, rgba(255,255,255,0.35) 0%, transparent 45%),
    linear-gradient(135deg, #ff9d3d 0%, #b83274 55%, #3f269a 100%);
}

/* Extra-large avatar for the hero. Initial rendered directly for the
   mock; production would swap in a real photo. */
.avatar-xl {
  width: 140px;
  height: 140px;
  border-radius: var(--r-full);
  background: rgba(255,255,255,0.18);
  border: 4px solid rgba(255,255,255,0.5);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-brand);
  font-size: 64px;
  line-height: 1;
  letter-spacing: -0.02em;
  backdrop-filter: blur(4px);
  position: relative;
}

/* Availability dot — appended to any avatar (`--md` or `--xl`) as a
   status indicator. Green = online, amber = away, grey = offline. */
.avatar-status {
  position: absolute;
  right: 4px;
  bottom: 4px;
  width: 18px;
  height: 18px;
  border-radius: var(--r-full);
  border: 3px solid var(--surface);
  background: var(--metric-up-fg);
}
.avatar-status[data-status="away"] { background: #eab308; }
.avatar-status[data-status="offline"] { background: var(--ink-muted); }
.avatar-xl .avatar-status {
  width: 24px;
  height: 24px;
  border-width: 4px;
  right: 8px;
  bottom: 8px;
}

/* Info side of the hero */
.contact-hero-info {
  padding: 36px 40px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
}
.contact-hero-eyebrow {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-secondary);
}
.contact-hero-name {
  margin: 4px 0 2px;
  font-size: 32px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  line-height: 1.1;
}
.contact-hero-role {
  color: var(--ink-secondary);
  font-size: 15px;
  margin-bottom: 4px;
}
.contact-hero-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--ink-secondary);
  margin-top: 8px;
}
.contact-hero-status::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: var(--r-full);
  background: var(--metric-up-fg);
  box-shadow: 0 0 0 3px rgba(22,163,74,0.15);
}
.contact-hero-bio {
  color: var(--ink);
  font-size: 15px;
  line-height: 1.55;
  margin: 20px 0 0;
  max-width: 540px;
}
.contact-hero-actions {
  display: flex;
  gap: 10px;
  margin-top: 24px;
}
.contact-hero-actions .btn { padding: 10px 18px; }

/* --- Team grid --------------------------------------------------------
   4-column grid of secondary team members. Each card is centred,
   compact and scannable. */
.team-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}
.team-card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-xl);
  padding: 24px 20px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: border-color 120ms ease, transform 120ms ease;
}
.team-card:hover {
  border-color: var(--ink-muted);
  transform: translateY(-1px);
}
.team-avatar {
  width: 64px;
  height: 64px;
  border-radius: var(--r-full);
  margin-bottom: 14px;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-brand);
  font-size: 26px;
  letter-spacing: -0.02em;
  position: relative;
  flex-shrink: 0;
}
.team-avatar .avatar-status {
  width: 14px;
  height: 14px;
  border-width: 2.5px;
  right: 0;
  bottom: 0;
}
.team-name {
  font-weight: 600;
  color: var(--ink);
  font-size: 15px;
  margin-bottom: 2px;
}
.team-role {
  color: var(--ink-secondary);
  font-size: 13px;
  margin-bottom: 16px;
  line-height: 1.35;
  min-height: 34px;                              /* keeps buttons aligned across cards */
}
.team-card .btn {
  width: 100%;
  justify-content: center;
}

/* --- Contact methods (fallback row) ---------------------------------
   3-up row: email · phone · address. Each card has a violet-tinted
   icon (Contact section colour) and a label / value stack. */
.contact-methods {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
.contact-method {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-xl);
  padding: 24px 24px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.contact-method-icon {
  width: 44px;
  height: 44px;
  border-radius: var(--r-md);
  background: color-mix(in oklab, var(--nav-contact) 12%, var(--surface));
  color: var(--nav-contact);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 16px;
}
.contact-method-icon svg { width: 20px; height: 20px; stroke-width: 1.75; }
.contact-method-label {
  font-size: 13px;
  color: var(--ink-secondary);
}
.contact-method-value {
  font-size: 17px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.005em;
}
.contact-method-hint {
  font-size: 12px;
  color: var(--ink-muted);
  margin-top: 4px;
}

/* --- 21. Shared page toolbars, search, badges ----------------------- */

/* Toolbar row above card content — search on the left, segmented filter
   on the right. Wraps on narrow viewports. */
.page-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

/* Search input — labels are inside a bordered pill with a leading icon.
   Focus state deepens the border rather than adding a bright outline. */
.search-input {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  padding: 8px 14px;
  min-width: 280px;
  color: var(--ink-secondary);
  transition: border-color 120ms ease;
}
.search-input:focus-within { border-color: var(--ink-secondary); }
.search-input svg { width: 16px; height: 16px; flex-shrink: 0; stroke-width: 2; }
.search-input input {
  border: 0;
  background: transparent;
  outline: none;
  font: inherit;
  color: var(--ink);
  width: 100%;
  min-width: 0;
}
.search-input input::placeholder { color: var(--ink-muted); }

/* Count badge inside a segmented tab — the ink pill inverts when active. */
.segmented-item .badge {
  display: inline-flex;
  align-items: center;
  padding: 1px 7px;
  border-radius: var(--r-full);
  background: var(--canvas);
  color: var(--ink-secondary);
  font-size: 10px;
  font-weight: 700;
  margin-left: 6px;
  min-width: 20px;
  justify-content: center;
  line-height: 1.4;
}
.segmented-item[aria-selected="true"] .badge {
  background: var(--ink);
  color: var(--surface);
}

/* Count badge inside a card header title — subtler than the tab badge,
   used to number the items inside a section. */
.card-header-count {
  display: inline-flex;
  align-items: center;
  padding: 2px 9px;
  margin-left: 8px;
  border-radius: var(--r-full);
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  color: var(--ink-secondary);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.4;
}

/* --- 22. Reports page — chart, big metric grid ---------------------- */

/* Chart shell — headline + big value on top, then the chart itself. */
.chart-shell { padding: 24px 24px 16px; }
.chart-legend {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 20px;
}
.chart-legend-value {
  font-size: 30px;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.02em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.chart-legend-delta { margin-left: 0; }
.chart-legend-hint {
  font-size: 13px;
  color: var(--ink-secondary);
  margin-left: 4px;
}

/* Chart body — grid so the y-axis labels align with the chart area. */
.chart {
  display: grid;
  grid-template-columns: 44px 1fr;
  gap: 12px;
  height: 220px;
}
.chart-y-axis {
  display: flex;
  flex-direction: column-reverse;
  justify-content: space-between;
  padding: 2px 0;
  font-size: 11px;
  color: var(--ink-muted);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.chart-area { position: relative; height: 100%; }
.chart-area svg { width: 100%; height: 100%; display: block; }
.chart-x-axis {
  display: flex;
  justify-content: space-between;
  padding: 10px 0 0 56px;
  font-size: 11px;
  color: var(--ink-muted);
}

/* Big metric tiles for the Reports page. Same class base as `.metric-tile`
   but scaled up — used for the four headline KPIs at the top of the page. */
.metric-tile--lg { padding: 22px 24px 20px; }
.metric-tile--lg .metric-label { font-size: 14px; }
.metric-tile--lg .metric-value { font-size: 34px; margin-top: 4px; }
.metric-tile--lg .metric-spark { height: 32px; }

/* --- 23. Billing page ------------------------------------------------ */

/* Plan card layout — hero section (plan name + price) sits above a
   feature list, with a footer for actions. */
.plan-hero {
  padding: 24px 24px 20px;
  border-bottom: 1px solid var(--hairline);
}
.plan-hero-eyebrow {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-secondary);
  margin-bottom: 8px;
}
.plan-hero-name {
  margin: 0 0 4px;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  line-height: 1.1;
}
.plan-hero-price {
  color: var(--ink-secondary);
  font-size: 15px;
}
.plan-features {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 20px 24px;
  flex: 1;
}
.plan-feature {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 14px;
  color: var(--ink);
}
.plan-feature-icon {
  width: 22px;
  height: 22px;
  border-radius: var(--r-full);
  background: var(--positive-bg);
  border: 1px solid var(--positive-border);
  color: var(--positive-fg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.plan-feature-icon svg { width: 12px; height: 12px; stroke-width: 3; }
.plan-footer {
  padding: 20px 24px;
  border-top: 1px solid var(--hairline);
  display: flex;
  gap: 10px;
}

/* Card brand box — visual representation of a payment method. Used in
   the Payment method card. */
.card-brand {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: var(--canvas-soft);
}
.card-brand-mark {
  width: 44px;
  height: 30px;
  border-radius: 4px;
  background: linear-gradient(135deg, #1a1f71 0%, #2a3a9f 100%);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-brand);
  font-size: 11px;
  letter-spacing: 0.06em;
}
.card-brand-info { display: flex; flex-direction: column; gap: 2px; line-height: 1.3; }
.card-brand-number { font-weight: 600; font-size: 14px; color: var(--ink); }
.card-brand-expiry { font-size: 12px; color: var(--ink-secondary); }

/* Two-column billing detail body — for Payment method / Billing details. */
.card-body { padding: 20px 24px; }
.address-block {
  font-size: 14px;
  color: var(--ink);
  line-height: 1.5;
  padding: 12px 16px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: var(--canvas-soft);
}
.address-block strong { display: block; margin-bottom: 4px; }

/* --- 24. Work page (mostly reuses existing patterns) ---------------- */

/* Nothing new — Work grouped sections use .card + .data-list-row and
   .data-table primitives already defined. Only additional style is
   the shared page-toolbar / search / segmented-badge above. */

/* --- 26. Admin mode ------------------------------------------------
   Structurally different from the client dashboard: persistent DARK
   RAIL on the left (contains ambient system context — sync status +
   full clients list), light main workspace on the right. Client
   dashboard has a WHITE sidebar with navigation; admin has a DARK
   rail with operational context. Instantly different at a glance.
   
   Typography also shifts — JetBrains Mono for technical values
   (timestamps, DB URLs, Notion keys) because staff need to read them
   *exactly*, not just recognise them. */

/* Red admin bar. Sticky, always visible, with a live pulse dot. */
.admin-bar {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--danger-fg);
  color: #fff;
  padding: 10px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  font-size: 13px;
  font-weight: 500;
  box-shadow: 0 2px 8px rgba(220,38,38,0.15);
}
.admin-bar-left { display: inline-flex; align-items: center; gap: 12px; }
.admin-bar-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 3px 10px 3px 9px;
  background: rgba(255,255,255,0.18);
  border-radius: var(--r-full);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.admin-bar-badge::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: var(--r-full);
  background: #fff;
  box-shadow: 0 0 0 3px rgba(255,255,255,0.35);
  animation: admin-pulse 2.4s ease-in-out infinite;
}
@keyframes admin-pulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 3px rgba(255,255,255,0.35); }
  50% { opacity: 0.55; box-shadow: 0 0 0 5px rgba(255,255,255,0.12); }
}
.admin-bar-hint { opacity: 0.85; font-weight: 400; }
.admin-bar-hint strong { font-weight: 600; opacity: 1; }
.admin-bar-right {
  display: inline-flex;
  align-items: center;
  gap: 14px;
}
.admin-bar-avatar {
  width: 28px;
  height: 28px;
  border-radius: var(--r-full);
  background: rgba(255,255,255,0.25);
  border: 2px solid rgba(255,255,255,0.4);
}
.admin-bar-link {
  color: #fff;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: var(--r-md);
  transition: background 120ms ease;
}
.admin-bar-link:hover { background: rgba(255,255,255,0.15); }

/* Admin body: zero padding, cool near-white background. The shell owns
   the whole viewport below the sticky admin bar. */
body.admin-body {
  padding: 0;
  background: #f6f6f7;
}

/* Admin shell: rail (fixed 280px, dark) + workspace (fluid, light).
   Grid rather than flex so the rail's `align-self: start` + sticky
   positioning combine cleanly. The gradient background paints the
   rail's column dark for the full page height so the rail doesn't
   look like it "ends" on scroll — the actual .admin-rail element
   just floats sticky on top of that dark strip. */
.admin-shell {
  display: grid;
  grid-template-columns: 280px 1fr;
  min-height: calc(100vh - 44px);
  background: linear-gradient(to right, #131313 0, #131313 280px, transparent 280px);
}

/* ── The dark rail ──────────────────────────────────────────────── */
.admin-rail {
  position: sticky;
  top: 44px;
  align-self: start;
  height: calc(100vh - 44px);
  background: #131313;
  color: rgba(255,255,255,0.9);
  padding: 18px 14px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  overflow-y: auto;
  border-right: 1px solid rgba(0,0,0,0.4);
}

/* Section labels inside the rail — small caps, dim, with an optional
   right-aligned count. */
.rail-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.45);
  padding: 0 6px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.rail-label-count {
  font-family: var(--font-tech);
  font-size: 10px;
  color: rgba(255,255,255,0.6);
  padding: 1px 6px;
  background: rgba(255,255,255,0.08);
  border-radius: var(--r-full);
  letter-spacing: 0;
}

/* Compact sync widget at the top of the rail. */
.rail-sync {
  padding: 12px 14px;
  background: rgba(255,255,255,0.04);
  border-radius: var(--r-md);
  border: 1px solid rgba(255,255,255,0.08);
}
.rail-sync-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 600;
  color: rgba(255,255,255,0.95);
  margin-bottom: 4px;
}
.rail-sync-head::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: var(--r-full);
  background: var(--metric-up-fg);
  box-shadow: 0 0 0 3px rgba(22,163,74,0.25);
}
.rail-sync-time {
  font-family: var(--font-tech);
  font-size: 11px;
  color: rgba(255,255,255,0.55);
  letter-spacing: -0.01em;
}
.rail-sync-meta {
  font-family: var(--font-tech);
  font-size: 10px;
  color: rgba(255,255,255,0.45);
  margin-top: 6px;
  letter-spacing: -0.01em;
}
.rail-sync-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  margin-top: 12px;
  padding: 7px 10px;
  background: rgba(255,255,255,0.1);
  border: 1px solid rgba(255,255,255,0.14);
  color: #fff;
  border-radius: var(--r-sm);
  font-size: 12px;
  font-weight: 500;
  transition: background 120ms ease;
}
.rail-sync-btn:hover { background: rgba(255,255,255,0.16); }
.rail-sync-btn svg { width: 12px; height: 12px; }

/* Search input in the rail — flat, dark, transparent. */
.rail-search {
  position: relative;
  margin: 0 -4px;
}
.rail-search svg {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 12px;
  height: 12px;
  color: rgba(255,255,255,0.4);
  pointer-events: none;
}
.rail-search input {
  width: 100%;
  padding: 7px 10px 7px 32px;
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.1);
  color: #fff;
  border-radius: var(--r-sm);
  font: inherit;
  font-size: 12px;
  outline: none;
  transition: border-color 120ms ease, background 120ms ease;
}
.rail-search input::placeholder { color: rgba(255,255,255,0.4); }
.rail-search input:focus {
  border-color: rgba(255,255,255,0.25);
  background: rgba(255,255,255,0.08);
}

/* Client list — one entry per client, with a status dot on the left,
   name + meta stacked. Selected client (aria-current="page") gets a
   subtle highlight so you always know where you are. */
.rail-clients {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0 -4px;
}
.rail-client {
  padding: 9px 10px 9px 26px;
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background 120ms ease;
  display: flex;
  flex-direction: column;
  gap: 1px;
  position: relative;
  color: rgba(255,255,255,0.9);
}
.rail-client:hover { background: rgba(255,255,255,0.05); }
.rail-client[aria-current="page"] {
  background: rgba(255,255,255,0.09);
}
.rail-client::before {
  content: '';
  position: absolute;
  left: 12px;
  top: 15px;
  width: 6px;
  height: 6px;
  border-radius: var(--r-full);
  background: rgba(255,255,255,0.3);
}
.rail-client[data-status="healthy"]::before {
  background: var(--metric-up-fg);
  box-shadow: 0 0 0 2px rgba(22,163,74,0.25);
}
.rail-client[data-status="warning"]::before {
  background: var(--warning-fg);
  box-shadow: 0 0 0 2px rgba(194,65,12,0.28);
}
.rail-client-name {
  font-size: 13px;
  font-weight: 500;
  color: #fff;
}
.rail-client-meta {
  font-size: 11px;
  color: rgba(255,255,255,0.5);
  font-family: var(--font-tech);
  letter-spacing: -0.01em;
}

/* Add client button — dashed border, matches the rail aesthetic. */
.rail-add {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  padding: 8px;
  background: transparent;
  border: 1px dashed rgba(255,255,255,0.18);
  color: rgba(255,255,255,0.65);
  border-radius: var(--r-sm);
  font-size: 12px;
  font-weight: 500;
  margin-top: 4px;
  transition: color 120ms ease, border-color 120ms ease;
}
.rail-add:hover { color: #fff; border-color: rgba(255,255,255,0.35); }

/* Rail footer — sits at the bottom regardless of client-list height. */
.rail-footer {
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid rgba(255,255,255,0.08);
  font-size: 11px;
  color: rgba(255,255,255,0.4);
  font-family: var(--font-tech);
  padding-left: 6px;
  letter-spacing: -0.01em;
}

/* ── The light main workspace ──────────────────────────────────── */
.admin-content {
  padding: 32px 40px 60px;
  min-width: 0;
}

/* Admin content header — page title + subtitle + optional actions
   on the right. Denser than the client-dashboard .page-header. */
.admin-content-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  padding-bottom: 20px;
  margin-bottom: 24px;
  border-bottom: 1px solid var(--hairline);
}
.admin-content-header h1 {
  margin: 0 0 4px;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  line-height: 1.1;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.admin-content-header p {
  margin: 0;
  color: var(--ink-secondary);
  font-size: 14px;
}
.admin-content-header p .tech { margin-left: 4px; }
.admin-content-actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

/* System stat tiles — 4-up row of at-a-glance operational numbers.
   Deliberately denser than the client Reports metric tiles. */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 24px;
}
.stat-tile {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  padding: 14px 16px;
}
.stat-tile-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-secondary);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 8px;
}
.stat-tile-value {
  font-size: 26px;
  font-weight: 700;
  color: var(--ink);
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.stat-tile-unit {
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-secondary);
  letter-spacing: 0;
}

/* Technical values — inline monospace pill. Used for timestamps,
   database URLs, Notion IDs, keys, etc. */
.tech {
  font-family: var(--font-tech);
  font-size: 12px;
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  padding: 1px 7px;
  border-radius: 4px;
  color: var(--ink);
  letter-spacing: -0.02em;
  font-weight: 500;
}
.tech--dim { color: var(--ink-secondary); background: transparent; border: 0; padding: 0; }

/* Admin card — same base as client card but slightly denser padding
   and a marginally tighter radius so it feels "operational." */
.admin-card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  overflow: hidden;
}
.admin-card + .admin-card { margin-top: 16px; }
.admin-card-header {
  padding: 12px 18px;
  border-bottom: 1px solid var(--hairline);
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--canvas-soft);
}
.admin-card-header-title { display: flex; align-items: center; gap: 10px; }
.admin-card-header-meta { font-size: 12px; font-weight: 400; color: var(--ink-secondary); }
.admin-card-body { padding: 16px 18px; }

/* Activity log — clean, dense, monospaced timestamps on the left. */
.activity-log {
  display: flex;
  flex-direction: column;
}
.activity-item {
  padding: 10px 18px;
  border-bottom: 1px solid var(--hairline);
  display: grid;
  grid-template-columns: 90px auto 1fr auto;
  align-items: center;
  gap: 14px;
  font-size: 13px;
}
.activity-item:last-child { border-bottom: 0; }
.activity-time {
  font-family: var(--font-tech);
  font-size: 11px;
  color: var(--ink-muted);
  letter-spacing: -0.01em;
}
.activity-actor {
  font-weight: 600;
  color: var(--ink);
}
.activity-actor--system { color: var(--ink-secondary); font-weight: 500; }
.activity-desc {
  color: var(--ink-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.activity-kind {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: var(--r-full);
  background: var(--canvas-soft);
  color: var(--ink-secondary);
}
.activity-kind--sync    { background: var(--positive-bg); color: var(--positive-fg); }
.activity-kind--edit    { background: var(--status-review-bg); color: var(--status-review-fg); }
.activity-kind--create  { background: var(--status-progress-bg); color: var(--status-progress-fg); }
.activity-kind--warn    { background: var(--warning-bg); color: var(--warning-fg); }

/* Status pills used in admin (loud tinted style, not the recede-y
   white pill from the client's Complete pattern). */
.pill--healthy {
  background: var(--positive-bg);
  color: var(--positive-fg);
  border: 1px solid var(--positive-border);
  padding: 4px 10px;
  font-size: 12px;
  gap: 7px;
}
.pill--healthy::before {
  background: var(--positive-fg);
  opacity: 1;
  width: 7px;
  height: 7px;
}
.pill--warning {
  background: var(--warning-bg);
  color: var(--warning-fg);
  border: 1px solid var(--warning-border);
  padding: 4px 10px;
  font-size: 12px;
  gap: 7px;
}
.pill--warning::before {
  background: var(--warning-fg);
  opacity: 1;
  width: 7px;
  height: 7px;
}

/* Section banner between admin cards — subtle canvas-soft strip. */
.admin-section {
  margin: 28px 0 12px;
  padding: 14px 18px;
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
}
.admin-section-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink);
  margin-bottom: 3px;
}
.admin-section-desc {
  font-size: 12px;
  color: var(--ink-secondary);
  line-height: 1.5;
}
.admin-section--danger {
  background: var(--danger-bg);
  border-color: var(--danger-border);
}
.admin-section--danger .admin-section-label { color: var(--danger-fg); }
.admin-section--danger .admin-section-desc { color: var(--danger-fg); opacity: 0.9; }

/* Form inputs — general text/date/email/url inputs scoped to admin. */
.form-input,
.admin-body input[type="text"],
.admin-body input[type="email"],
.admin-body input[type="url"],
.admin-body input[type="date"],
.admin-body input[type="search"],
.admin-body textarea {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  background: var(--surface);
  font: inherit;
  font-size: 13px;
  color: var(--ink);
  transition: border-color 120ms ease;
  min-width: 0;
}
.form-input:focus,
.admin-body input:focus,
.admin-body textarea:focus {
  outline: none;
  border-color: var(--ink-secondary);
}
.form-input::placeholder,
.admin-body input::placeholder,
.admin-body textarea::placeholder {
  color: var(--ink-muted);
}
.admin-body textarea {
  min-height: 72px;
  resize: vertical;
  font-family: var(--font-body);
}
/* Input variant that shows technical values in monospace inline. */
.admin-body input.tech-input {
  font-family: var(--font-tech);
  font-size: 12px;
  letter-spacing: -0.01em;
}

.form-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
}
.form-row > input, .form-row > textarea { flex: 1; }
.form-row > .btn { flex-shrink: 0; }
.form-row + .form-row,
.form-row + .form-message,
.form-message + .form-row { margin-top: 10px; }

.form-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.form-grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr auto; gap: 8px; }
.form-grid-2 + .form-grid-2, .form-grid-2 + .form-grid-3, .form-grid-3 + .form-grid-2 { margin-top: 8px; }

.form-message { font-size: 12px; color: var(--ink-secondary); }
.form-error   { color: var(--danger-fg); font-size: 12px; margin-top: 6px; }
.form-hint    { color: var(--ink-secondary); font-size: 13px; margin: 0 0 12px; line-height: 1.5; }

/* Alert box — status/message container. */
.alert-box {
  padding: 12px 16px;
  border-radius: var(--r-md);
  border: 1px solid var(--hairline);
  background: var(--canvas-soft);
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink);
  margin-top: 12px;
}
.alert-box--success {
  background: var(--positive-bg);
  border-color: var(--positive-border);
  color: var(--positive-fg);
}
.alert-box--warning {
  background: var(--warning-bg);
  border-color: var(--warning-border);
  color: var(--warning-fg);
}
.alert-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 600;
  margin-bottom: 3px;
}
.alert-title::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: var(--r-full);
  background: currentColor;
  flex-shrink: 0;
}
.alert-title .tech { color: var(--ink); font-weight: 500; }

/* Empty-state text block. */
.empty-state {
  padding: 16px 18px;
  color: var(--ink-secondary);
  font-size: 13px;
  background: var(--canvas-soft);
  border: 1px dashed var(--hairline-strong);
  border-radius: var(--r-sm);
  line-height: 1.5;
}

/* Toggle button — dark = on. */
.toggle-btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 6px 12px 6px 12px;
  border-radius: var(--r-sm);
  font-size: 12px;
  font-weight: 500;
  border: 1px solid var(--hairline);
  background: var(--surface);
  color: var(--ink);
  transition: all 120ms ease;
}
.toggle-btn-state {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: var(--r-full);
  background: var(--canvas-soft);
  color: var(--ink-secondary);
}
.toggle-btn--on {
  background: var(--ink);
  color: var(--surface);
  border-color: var(--ink);
}
.toggle-btn--on .toggle-btn-state {
  background: rgba(255,255,255,0.15);
  color: #fff;
}

/* Danger button. */
.btn--danger {
  background: var(--danger-fg);
  color: #fff;
  border: 0;
}
.btn--danger:hover { background: var(--danger-fg-h); opacity: 1; }

/* Managed-elsewhere tag. */
.managed-tag {
  font-family: var(--font-tech);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink-muted);
  padding: 2px 8px;
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  border-radius: var(--r-full);
}

/* Muted body text helper (used in admin). */
.admin-body .muted { color: var(--ink-secondary); }

/* --- 28. Playbook (inside Operations shell) -------------------------
   Playbook is the first tool inside Haeeum Operations. Renders inside
   the shared .ops-shell / .ops-main (see §29). The Playbook page
   itself is: page-header + count subtitle, toolbar (wide search +
   New article), department filter tabs (segmented), one dense
   article list where each row is an <a>. Everything decorative was
   stripped in the transition from Client Portal aesthetics — this is
   a filing system, not a marketing surface. */

/* Subtitle line under the main page title — just a muted second line
   for count / status info. */
.page-header-sub {
  margin-top: 8px;
  font-size: 14px;
  color: var(--ink-secondary);
  font-weight: 400;
}

/* Wide search variant — on the Playbook the search is the primary
   entry point, so it grows to fill the toolbar's flex column instead
   of sitting at the standard 280px minimum. */
.search-input--wide { min-width: 0; flex: 1; }

/* --- Segmented control · tabs variant --------------------------------
   The existing `.segmented` (see §17) is a compact filter chip; the
   `--tabs` modifier scales it up to work as the page's primary filter
   row. Larger padding, own line, and a hairline divider between the
   live departments and the disabled "coming soon" ones so the roadmap
   is visible without being clickable. */
.segmented--tabs {
  margin-bottom: 16px;
  padding: 4px;
  gap: 2px;
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  max-width: 100%;
}
.segmented--tabs .segmented-item {
  padding: 7px 14px;
  font-size: 13px;
}

/* Vertical divider between department groups in the tab row (live /
   coming-soon). Renders as a 1px hairline set into the tab row's
   canvas-soft background. */
.segmented-divider {
  display: inline-block;
  width: 1px;
  height: 18px;
  background: var(--hairline);
  margin: 0 6px;
}

/* Disabled segmented tab — for departments with no articles yet. The
   label stays visible (so the roadmap reads) but greyed out and
   non-interactive. Badge shows an em-dash rather than a count. */
.segmented-item--disabled {
  color: var(--ink-muted);
  cursor: default;
}
.segmented-item--disabled:hover { color: var(--ink-muted); }
.segmented-item--disabled .badge {
  background: transparent;
  color: var(--ink-muted);
}

/* --- Data list · index variant --------------------------------------
   Modifier on the flex-based `.data-list-row` primitive (see §8b).
   Rows are rendered as <a> elements, so the whole row is a real link
   — no positioning tricks, no CSS gymnastics, HTML-valid, screen
   readers see one link per row with the article title as anchor
   text. Adds row hover (canvas-soft) and tightens the row height a
   touch for filing-system density. */
.data-list-index {
  display: flex;
  flex-direction: column;
}
.data-list-index .data-list-row {
  color: var(--ink);                         /* anchor inheriting ink, not blue */
  padding-top: 12px;
  padding-bottom: 12px;
  min-height: 52px;
  transition: background 100ms ease;
  cursor: pointer;
}
.data-list-index .data-list-row:hover {
  background: var(--canvas-soft);
}
.data-list-index .data-list-row:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: -2px;
}

/* Article title — the primary text in each row. No underline, no
   coloured link treatment; the row hover carries the interactivity
   affordance. */
.article-title {
  font-weight: 500;
  color: var(--ink);
}

/* --- Tag palette additions ------------------------------------------
   Department tags — coloured to match each department's identity.
   One tag per row keeps the visual quiet: the row scans as
   "title · department · when · who" with the coloured chip anchoring
   the department column at a glance. */

.tag--onboarding {
  background: color-mix(in srgb, var(--nav-overview) 15%, white);
  color: #a3410c;
}
.tag--tools {
  background: var(--canvas-soft);
  color: var(--ink-secondary);
  border: 1px solid var(--hairline);
}
.tag--sales {
  background: color-mix(in srgb, var(--nav-calendar) 15%, white);
  color: #9a3412;
}
.tag--seo-dept {
  background: color-mix(in srgb, var(--nav-work) 12%, white);
  color: var(--nav-work);
}

/* Meta cell — dates and other technical values render in JetBrains
   Mono. This is the same signature the admin pages use (see §1g-2):
   monospace tells the reader "this is data the tool cares about" and
   makes the Playbook feel like an internal tool rather than a
   marketing surface. */
.cell-meta {
  font-family: var(--font-tech);
  font-size: 12.5px;
  color: var(--ink-secondary);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* --- 29. Operations shell ------------------------------------------
   The application shell shared across EVERY Operations tool: Playbook
   (built), CRM, Projects, Clients, Reports, Audits, Assets,
   Automations, Billing, Team, Settings (all to come).

   Copy the sidebar HTML block from index.html into every Operations
   page. The only thing that changes per-page is which .ops-nav-row
   carries aria-current="page". The tool's content lives inside the
   shell's .ops-main.

   Design intent — Operations shares Client Portal's design tokens
   (typography, spacing, colours, buttons, tags) but the personality
   is different: no coloured section bars (those are the Client
   Portal's editorial flourish), denser padding, monospace touches
   for kbd hints and technical values, subtle borders instead of
   soft shadows. "We're here to get work done" rather than "We're
   here to explain". */

/* Body reset for Operations pages — no body padding (the shell owns
   viewport edges), same canvas colour as Client Portal so the two
   products feel like the same company. */
.ops-body {
  padding: 0;
  background: var(--canvas-frame);
  min-height: 100vh;
}

/* Shell grid — fixed sidebar + fluid content. Sidebar column is
   narrow (220px) for information density; 12 nav rows still fit
   comfortably. Grows to 100vh so the sidebar's sticky positioning
   works out of the box. */
.ops-shell {
  display: grid;
  grid-template-columns: 220px 1fr;
  min-height: 100vh;
}

/* --- Sidebar ---------------------------------------------------------
   White surface with a hairline right border (not a rounded floating
   panel — this is a fixed workspace chrome, not a "card"). Sticky-
   pinned so scrolling the content area leaves the nav in place. */
.ops-sidebar {
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  background: var(--surface);
  border-right: 1px solid var(--hairline);
  padding: 16px 12px 12px;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  min-width: 0;
}

/* Brand block — HAEEUM wordmark + small "OPERATIONS" sub-brand
   underneath. The sub-brand is the fastest visual signal that
   you're in Operations, not Client Portal. */
.ops-brand-block {
  padding: 4px 10px 14px;
}
.ops-brand {
  font-family: var(--font-brand);
  font-size: 20px;
  letter-spacing: -0.01em;
  color: var(--ink);
  line-height: 1;
  text-shadow:
     0.5px 0 0 currentColor,
    -0.5px 0 0 currentColor,
     0 0.3px 0 currentColor;
}
.ops-brand-sub {
  margin-top: 4px;
  font-size: 10px;
  font-weight: 600;
  color: var(--ink-secondary);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

/* Global search / command palette entry point. Renders as an
   input-shaped button — click or ⌘K opens the palette. The kbd hint
   on the right advertises the keyboard shortcut, which is the primary
   way experienced users will interact with it. */
.ops-search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px 6px 10px;
  margin-bottom: 14px;
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  color: var(--ink-secondary);
  font-size: 13px;
  text-align: left;
  transition: border-color 120ms ease, background 120ms ease;
  width: 100%;
}
.ops-search:hover {
  background: var(--surface);
  border-color: var(--hairline-strong);
  color: var(--ink);
}
.ops-search svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  stroke-width: 2;
}
.ops-search-placeholder {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Keyboard-shortcut chip. Monospace so the ⌘K reads clearly, subtle
   double-bottom-border for the "physical key" feel. Reusable across
   Operations any time a kbd shortcut is surfaced (menu items,
   tooltips, empty-state hints). */
.ops-kbd {
  font-family: var(--font-tech);
  font-size: 10px;
  font-weight: 500;
  padding: 1px 5px 2px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-bottom-width: 2px;
  border-radius: 4px;
  color: var(--ink-secondary);
  line-height: 1.4;
  white-space: nowrap;
  flex-shrink: 0;
}

/* Nav list — flat, dense, no group labels (12 items scans fine at
   this scale). If the list grows past ~15 items, consider adding
   .ops-nav-label small-caps section headers between rows. */
.ops-nav {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

/* Nav row — icon + label. No coloured left bar (that's Client
   Portal's editorial pattern). Active state is a subtle canvas-soft
   fill + full-strength icon; muted icon by default gives the nav a
   quiet resting state that snaps into focus on hover / active. */
.ops-nav-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border-radius: var(--r-sm);
  color: var(--ink-secondary);
  font-size: 13px;
  font-weight: 500;
  transition: background 100ms ease, color 100ms ease;
  min-height: 30px;
}
.ops-nav-row:hover {
  background: var(--canvas-soft);
  color: var(--ink);
}
.ops-nav-row[aria-current="page"] {
  background: var(--canvas-soft);
  color: var(--ink);
  font-weight: 600;
}
.ops-nav-icon {
  width: 16px;
  height: 16px;
  color: currentColor;
  stroke-width: 1.75;
  opacity: 0.6;
  flex-shrink: 0;
  transition: opacity 100ms ease;
}
.ops-nav-row:hover .ops-nav-icon,
.ops-nav-row[aria-current="page"] .ops-nav-icon {
  opacity: 1;
}

/* Optional section label between nav rows — small-caps header for
   grouping when the flat list gets too long. Not used yet; here so
   any future page can drop it in without a new CSS pass. */
.ops-nav-label {
  padding: 12px 12px 4px;
  font-size: 10px;
  font-weight: 600;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* Sidebar footer — profile pinned to bottom via margin-top:auto on
   the flex column. Divider above separates it from the nav so the
   two zones read as distinct. */
.ops-sidebar-footer {
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px solid var(--hairline);
}

/* Profile block — denser than Client Portal's equivalent. No avatar
   border or padding-heavy card feel. */
.ops-profile {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--r-sm);
}
.ops-profile-avatar {
  width: 28px;
  height: 28px;
  border-radius: var(--r-full);
  background: #d9d9dc;
  flex-shrink: 0;
}
.ops-profile-text { min-width: 0; }
.ops-profile-name {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ops-profile-email {
  font-size: 11px;
  color: var(--ink-secondary);
  line-height: 1.2;
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --- Content area ---------------------------------------------------
   Owned by the currently-active tool. Default is a comfortable
   reading width (1400px max) with generous padding. Tools that need
   full viewport width (Kanban boards, wide data grids) add the
   `--wide` modifier to opt out of the cap. */
.ops-main {
  padding: 28px 36px 48px;
  min-width: 0;
  max-width: 1400px;
  justify-self: center;
  width: 100%;
}
.ops-main--wide {
  max-width: none;
}

/* Vertical spacing between top-level cards inside a tool's content
   area. Mirrors the .main > .card + .card rule from Client Portal
   but scoped to .ops-main so the two products don't interfere. */
.ops-main > .card + .card,
.ops-main > .cards-row + .card,
.ops-main > .page-toolbar + .card,
.ops-main > .segmented + .card {
  margin-top: 20px;
}

/* --- 30. Playbook article (article.html) ----------------------------
   The document view for a single Playbook article. Lives inside the
   Operations shell (see §29). Priority is making processes extremely
   easy to read and follow while someone is actually doing the work —
   so the layout is a reading column at a comfortable measure, with a
   subtle right-side TOC on articles that earn one.

   Design intent — the DOCUMENT is the primary visual structure, not
   surrounding chrome. No section cards, no big empty states, no
   decorative panels. Type hierarchy, spacing rhythm and one dedicated
   step primitive do all the work. Every primitive here is prefixed
   `article-` or scoped inside `.article-body` so it can't clash with
   anything reused from Client Portal. */

/* --- Page layout ---------------------------------------------------
   Two variants:
   • .article-page — single centred reading column (~720px). For
     short articles where a TOC would be UI-for-UI's-sake.
   • .article-page--with-toc — reading column + 180px sticky TOC on
     the right, as a flex sibling. Used for substantial articles
     with 5+ H2 sections.

   Structure inside --with-toc:
     .article-main   (topbar + header + body — the reading column)
     .article-toc    (sticky sibling, aligned to top of main) */

.article-page {
  max-width: 720px;
  margin: 0 auto;
  padding: 8px 0 60px;
}

.article-page--with-toc {
  max-width: 960px;
  margin: 0 auto;
  padding: 8px 0 60px;
  display: flex;
  align-items: flex-start;
  gap: 60px;
}
.article-main {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 720px;
}
.article-page--with-toc > .article-toc {
  flex: 0 0 180px;
  align-self: flex-start;
  position: sticky;
  top: 24px;
  padding-top: 4px;
}

/* --- Topbar (back link + edit action) -----------------------------
   Sits above the header on the same row. Back link on the left,
   Edit button on the right — mirrors GitHub/Notion/GitLab. */
.article-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
}
.article-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--ink-secondary);
  transition: color 100ms ease;
}
.article-back:hover { color: var(--ink); }
.article-back svg { width: 14px; height: 14px; stroke-width: 2; }

/* --- Article header (title + meta) --------------------------------
   Title, then a single meta row with department tag, updated date
   and author. Divider hairline below separates header from body
   without needing a heavy card. */
.article-header {
  padding-bottom: 24px;
  margin-bottom: 32px;
  border-bottom: 1px solid var(--hairline);
}
.article-title {
  margin: 0 0 16px;
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--ink);
  line-height: 1.15;
}
.article-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 13px;
  color: var(--ink-secondary);
}
.article-meta-sep {
  color: var(--ink-muted);
}
.article-meta-date {
  font-size: 12.5px;
}

/* --- TOC (subtle right-side sticky) --------------------------------
   Just links, no chrome. A vertical hairline on the left with the
   active item's left border inking-in acts as a scroll indicator.
   Only lists H2s — H3 subsections would over-crowd this at 180px. */
.article-toc {
  align-self: start;
  position: sticky;
  top: 24px;
  padding-top: 4px;
}
.article-toc-label {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
  padding: 0 0 10px 12px;
}
.article-toc-list {
  list-style: none;
  padding: 0;
  margin: 0;
  border-left: 1px solid var(--hairline);
}
.article-toc-list li a {
  display: block;
  padding: 5px 12px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-secondary);
  border-left: 1px solid transparent;
  margin-left: -1px;
  transition: color 100ms ease, border-color 100ms ease;
}
.article-toc-list li a:hover { color: var(--ink); }
.article-toc-list li a.is-active {
  color: var(--ink);
  border-left-color: var(--ink);
  font-weight: 600;
}

/* --- Article body typography --------------------------------------
   Everything scoped inside `.article-body` so we can style markdown
   output without leaking into other Operations tools.

   Line height and vertical rhythm are the main levers here — not
   type size. 15px at line-height 1.65 reads calmly through long
   procedures without feeling loose. */

.article-body {
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink);
}

.article-body > *:first-child { margin-top: 0; }
.article-body > *:last-child { margin-bottom: 0; }

.article-body p {
  margin: 0 0 16px;
}

/* Lead paragraph — slightly larger, sets the tone for the article.
   Used sparingly at the top; markdown authors don't need to reach for
   it, it's here as a house style option. */
.article-lead {
  font-size: 16.5px;
  line-height: 1.6;
  color: var(--ink);
}

/* Headings — the primary structure of the document. Generous top
   margins on H2 to break the article into visible sections at a
   glance while scrolling. */
.article-body h2 {
  margin: 40px 0 14px;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
  line-height: 1.25;
  scroll-margin-top: 24px;                    /* space above TOC anchor jumps */
}
.article-body h3 {
  margin: 28px 0 10px;
  font-size: 17px;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.3;
  scroll-margin-top: 24px;
}
.article-body h4 {
  margin: 20px 0 8px;
  font-size: 14px;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: 0.01em;
  line-height: 1.35;
}

/* Links — ink text with a hairline underline that darkens on hover.
   Same pattern as the row-link primitive; consistent throughout
   Operations. */
.article-body a {
  color: var(--ink);
  border-bottom: 1px solid var(--hairline-strong);
  transition: border-color 120ms ease;
}
.article-body a:hover { border-bottom-color: var(--ink); }

/* Strong / emphasis — bold reads as "look here" in a procedure so
   the weight jump is deliberate. */
.article-body strong { font-weight: 600; color: var(--ink); }
.article-body em { font-style: italic; }

/* Unordered lists — for prerequisites, deliverables, "what to
   record" material. Not for procedures — use .steps instead. */
.article-body ul {
  margin: 0 0 16px;
  padding-left: 22px;
}
.article-body ul li {
  margin-bottom: 6px;
  line-height: 1.55;
}
.article-body ul li::marker {
  color: var(--ink-muted);
}

/* --- Numbered steps -----------------------------------------------
   The star primitive of the article page. Numbered instructions get
   a monospace number chip on the left and a wide content area on the
   right — the number reads as an anchor point while someone is
   actually doing the work.

   Uses CSS counters so the markdown stays clean (<ol class="steps">
   <li>...</li></ol>) and can hold nested content: multiple
   paragraphs, code blocks, screenshots, notes. */
.article-body .steps {
  counter-reset: step;
  list-style: none;
  padding: 0;
  margin: 20px 0 24px;
}
.article-body .steps > li {
  counter-increment: step;
  position: relative;
  padding: 16px 0 16px 48px;
  border-top: 1px solid var(--hairline);
}
.article-body .steps > li:first-child {
  border-top: 0;
  padding-top: 4px;
}
.article-body .steps > li:last-child {
  padding-bottom: 4px;
}
.article-body .steps > li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 16px;
  width: 28px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-tech);
  font-size: 12px;
  font-weight: 600;
  color: var(--ink);
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  border-radius: 5px;
  font-variant-numeric: tabular-nums;
}
.article-body .steps > li:first-child::before { top: 4px; }

/* Content inside a step. The primary line is the imperative
   ("Sign in to…"), the note line is the "why / how / what if"
   context. Both live in normal <p> tags with the class applied. */
.article-body .step-primary {
  margin: 0 0 6px;
  font-size: 15px;
  color: var(--ink);
  line-height: 1.55;
}
.article-body .step-note {
  margin: 4px 0 0;
  font-size: 14px;
  color: var(--ink-secondary);
  line-height: 1.55;
}
.article-body .step-primary:last-child,
.article-body .step-note:last-child { margin-bottom: 0; }

/* Nested content inside a step (code block, figure) needs to sit
   inside the step's padding without collapsing margins. */
.article-body .steps > li > pre {
  margin: 8px 0 4px;
}
.article-body .steps > li > figure {
  margin: 12px 0 4px;
}

/* --- Code -----------------------------------------------------------
   Inline code in a subtle canvas-soft chip; block code with a light
   border and padding. Both use JetBrains Mono (`--font-tech`), same
   font as timestamps in the index and IDs in the admin — Operations'
   consistent "technical value" signature. */
.article-body code {
  font-family: var(--font-tech);
  font-size: 0.88em;
  padding: 1px 6px;
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  border-radius: 4px;
  color: var(--ink);
}
.article-body pre {
  font-family: var(--font-tech);
  font-size: 13px;
  line-height: 1.55;
  padding: 12px 14px;
  margin: 16px 0;
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  overflow-x: auto;
  color: var(--ink);
}
.article-body pre code {
  background: none;
  border: 0;
  padding: 0;
  font-size: 13px;
  border-radius: 0;
}

/* --- Blockquote ----------------------------------------------------
   Soft pull quote — a "why does this matter" aside. Left hairline
   with muted text; no italics (that's editorial territory). */
.article-body blockquote {
  margin: 20px 0;
  padding: 4px 0 4px 20px;
  border-left: 3px solid var(--hairline-strong);
  color: var(--ink-secondary);
}
.article-body blockquote p {
  margin: 0 0 8px;
}
.article-body blockquote p:last-child { margin-bottom: 0; }

/* --- Callout ------------------------------------------------------
   For notes and warnings that matter to the *procedure* (blockquote
   is for context / colour; callout is for "do not miss this"). Two
   variants — plain (neutral note) and --warning (attention). */
.article-body .callout {
  margin: 20px 0;
  padding: 12px 16px;
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--ink);
  border-radius: var(--r-sm);
}
.article-body .callout p:first-child { margin-top: 0; }
.article-body .callout p:last-child { margin-bottom: 0; }
.article-body .callout--warning {
  background: var(--warning-bg);
  border-color: var(--warning-border);
  border-left-color: var(--warning-fg);
  color: var(--warning-fg);
}
.article-body .callout--warning p {
  color: #7a2e0a;                             /* darker read on tinted bg */
}

/* --- Tables in body -----------------------------------------------
   Lighter than the .data-table primitive — no wrapping card, no
   heavy row padding. Meant for reference material (event names,
   settings, quick lookups). */
.article-body table {
  width: 100%;
  border-collapse: collapse;
  margin: 16px 0 20px;
  font-size: 14px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  overflow: hidden;
}
.article-body th {
  text-align: left;
  padding: 10px 14px;
  font-weight: 600;
  font-size: 12.5px;
  color: var(--ink);
  background: var(--canvas-soft);
  border-bottom: 1px solid var(--hairline);
  white-space: nowrap;
}
.article-body td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--hairline);
  vertical-align: top;
  line-height: 1.55;
}
.article-body tr:last-child td { border-bottom: 0; }

/* --- Figures / images ---------------------------------------------
   Screenshots are the workhorse illustration in a Playbook article.
   Default figure sits at body width. `.fig--wide` is the affordance
   for when an image genuinely needs more room — currently caps at
   body width in this layout (the sticky TOC eats the right-hand
   overflow space), but the modifier is here for a future layout
   variant that provides room to break out. */
.article-body figure {
  margin: 20px 0 24px;
}
.article-body .fig img {
  width: 100%;
  height: auto;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  display: block;
}
.article-body figcaption {
  margin-top: 8px;
  font-size: 12.5px;
  color: var(--ink-secondary);
  line-height: 1.5;
}

/* Placeholder for screenshots we don't have yet. Dashed border, aspect
   ratio 16/9, monospace label — reads as "this will be a real
   screenshot later" without pretending to be one. */
.article-body .fig-placeholder {
  aspect-ratio: 16 / 9;
  background: var(--canvas-soft);
  border: 1px dashed var(--hairline-strong);
  border-radius: var(--r-md);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 20px;
  color: var(--ink-secondary);
  font-size: 13px;
  text-align: center;
}
.article-body .fig-placeholder-tag {
  font-family: var(--font-tech);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-muted);
  padding: 2px 8px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 4px;
}

/* Horizontal rule between article sections that need a hard break
   (e.g. before "Common issues"). Subtle — just a hairline. */
.article-body hr {
  border: 0;
  border-top: 1px solid var(--hairline);
  margin: 32px 0;
}

/* --- 31. Playbook walkthrough (article.html) ------------------------
   A guided flow, not a document. Sections are shown one at a time,
   the current section fills the workspace, steps are interactive
   checkboxes, values (naming conventions, code, URLs) have copy
   buttons. Progress dots at the top show overall position and stay
   clickable for jumping around.

   Structure:
     .walkthrough
       .walkthrough-topbar        (back + article identity + edit)
       .wt-progress               (dots + "X of 8 complete" label)
       .wt-sections
         .wt-section (cover)      (initial screen, no dots visible)
         .wt-section (1..8)       (work sections with interactive steps)
         .wt-section (done)       (celebration + link to what's next)

   Same Operations tokens as everything else. Engagement comes from
   interaction (checking, copying, advancing) and focus (one thing
   at a time), not from decoration. */

.walkthrough {
  max-width: 720px;
  margin: 0 auto;
  padding: 4px 0 60px;
}

/* --- Topbar ---------------------------------------------------------
   Persistent identity across every section — back link on the left,
   article name (with tag) in the middle, Edit on the right. Compact
   so it doesn't compete with the section content below. */
.walkthrough-topbar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--hairline);
  margin-bottom: 32px;
}
.walkthrough-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--ink-secondary);
  transition: color 100ms ease;
  flex-shrink: 0;
}
.walkthrough-back:hover { color: var(--ink); }
.walkthrough-back svg { width: 14px; height: 14px; stroke-width: 2; }

.walkthrough-topbar-title {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  justify-content: center;
}
.walkthrough-topbar-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Progress dots + label ----------------------------------------
   Visible on every screen except .wt-section--cover. Dots connect
   with a hairline; complete dots ink-in and darken the line to
   their left; current dot is a ring. Small "X of 8 complete" label
   sits underneath so the state has words too. */
.wt-progress {
  margin-bottom: 40px;
  transition: opacity 200ms ease;
}
.wt-progress.is-hidden {
  opacity: 0;
  height: 0;
  margin: 0;
  overflow: hidden;
  pointer-events: none;
}
.wt-dots {
  list-style: none;
  padding: 0;
  margin: 0 0 10px;
  display: flex;
  align-items: center;
  gap: 0;
}
.wt-dots li {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 24px;
}
/* Connector line to the LEFT of each dot (except the first). */
.wt-dots li:not(:first-child)::before {
  content: '';
  position: absolute;
  right: 50%;
  left: -50%;
  top: 50%;
  transform: translateY(-50%);
  height: 1px;
  background: var(--hairline);
  z-index: 0;
}
.wt-dots li.is-linked::before {
  background: var(--ink);
}
.wt-dots button {
  position: relative;
  z-index: 1;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1.5px solid var(--hairline-strong);
  background: var(--surface);
  color: transparent;                 /* the numeric labels are for screen readers */
  font-size: 10px;
  cursor: pointer;
  padding: 0;
  transition: transform 120ms ease, border-color 120ms ease, background 120ms ease;
}
.wt-dots button:hover {
  transform: scale(1.2);
  border-color: var(--ink);
}
.wt-dots li.is-complete button {
  background: var(--ink);
  border-color: var(--ink);
}
.wt-dots li.is-current button {
  background: var(--surface);
  border: 2px solid var(--ink);
  width: 16px;
  height: 16px;
}
.wt-progress-label {
  font-size: 11.5px;
  font-family: var(--font-tech);
  color: var(--ink-secondary);
  letter-spacing: 0.02em;
  text-align: right;
}

/* --- Sections ------------------------------------------------------
   Only the active one is visible. A small transition when switching
   sections makes the jump feel deliberate rather than jarring. */
.wt-sections {
  position: relative;
}
.wt-section {
  display: none;
}
.wt-section.is-active {
  display: block;
  animation: wt-section-in 220ms ease both;
}
@keyframes wt-section-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* --- Section header (eyebrow + big title + lead) -------------------
   The title is bigger than the article version — this is one focused
   thing, so it earns the space. The lead paragraph is set slightly
   larger and calmer than body copy. */
.wt-section-header {
  margin-bottom: 32px;
}
.wt-eyebrow {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-bottom: 12px;
  font-family: var(--font-tech);
}
.wt-title {
  margin: 0 0 12px;
  font-size: 34px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  line-height: 1.1;
}
.wt-lead {
  margin: 0;
  font-size: 17px;
  line-height: 1.55;
  color: var(--ink-secondary);
  max-width: 620px;
}

/* --- Cover screen --------------------------------------------------
   The first thing you see when opening the walkthrough. Sets
   expectations (title, why it exists, how long), then a big Start
   button. No progress dots yet — you haven't started. */
.wt-section--cover .wt-cover {
  padding-top: 8px;
}
.wt-cover-eyebrow {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-family: var(--font-tech);
  margin-bottom: 16px;
}
.wt-cover-title {
  margin: 0 0 16px;
  font-size: 42px;
  font-weight: 700;
  letter-spacing: -0.025em;
  color: var(--ink);
  line-height: 1.05;
}
.wt-cover-lead {
  margin: 0 0 32px;
  font-size: 19px;
  line-height: 1.5;
  color: var(--ink-secondary);
  max-width: 620px;
}

/* Fact strip — time, sections, owner, updated. Reads like the top of
   a recipe card. Monospace for the numeric values. */
.wt-cover-facts {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  padding: 14px 0;
  margin-bottom: 32px;
}
.wt-fact-label {
  font-size: 10px;
  font-weight: 600;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 4px;
}
.wt-fact-value {
  font-size: 15px;
  font-weight: 500;
  color: var(--ink);
}
.wt-cover-blurb {
  margin-bottom: 40px;
  color: var(--ink);
  font-size: 15px;
  line-height: 1.65;
}
.wt-cover-blurb p { margin: 0 0 12px; }

.wt-cover-cta {
  text-align: left;
}
.wt-cover-cta-note {
  margin-top: 14px;
  font-size: 13px;
  color: var(--ink-secondary);
}
.wt-linkish {
  background: none;
  border: 0;
  padding: 0;
  color: var(--ink);
  border-bottom: 1px solid var(--hairline-strong);
  cursor: pointer;
  font: inherit;
  transition: border-color 120ms ease;
}
.wt-linkish:hover { border-bottom-color: var(--ink); }

/* --- Interactive steps ---------------------------------------------
   The star of the walkthrough. Each step is a big clickable target:
   click anywhere on the step (thanks to the wrapping <label>) to
   toggle done. Done state dims the step and inks the checkbox. */
.wt-steps {
  list-style: none;
  padding: 0;
  margin: 0 0 32px;
}
.wt-step {
  margin: 0;
}
.wt-step + .wt-step {
  border-top: 1px solid var(--hairline);
}
.wt-step > label {
  display: grid;
  grid-template-columns: 28px 1fr auto;
  gap: 16px;
  padding: 18px 4px;
  cursor: pointer;
  align-items: start;
  border-radius: var(--r-sm);
  transition: background 120ms ease;
}
.wt-step > label:hover {
  background: var(--canvas-soft);
}
.wt-check {
  appearance: none;
  -webkit-appearance: none;
  width: 22px;
  height: 22px;
  border: 1.5px solid var(--hairline-strong);
  border-radius: 6px;
  background: var(--surface);
  margin: 1px 0 0;
  cursor: pointer;
  position: relative;
  flex-shrink: 0;
  transition: background 120ms ease, border-color 120ms ease;
}
.wt-check:hover {
  border-color: var(--ink);
}
.wt-check:checked {
  background: var(--ink);
  border-color: var(--ink);
}
.wt-check:checked::after {
  content: '';
  position: absolute;
  left: 6px;
  top: 2px;
  width: 6px;
  height: 11px;
  border: solid var(--surface);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.wt-check:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.wt-step-body {
  min-width: 0;
}
.wt-step-title {
  font-size: 16.5px;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.45;
  margin-bottom: 4px;
}
.wt-step-title strong { font-weight: 600; }
.wt-step-note {
  margin: 6px 0 0;
  font-size: 14.5px;
  color: var(--ink-secondary);
  line-height: 1.55;
}

/* Done state — dim the title, keep the note readable, strike through
   the title so it feels finished. */
.wt-step.is-done .wt-step-title {
  color: var(--ink-muted);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--ink-muted);
}
.wt-step.is-done .wt-step-note {
  opacity: 0.6;
}

/* Inline code inside step content — same treatment as elsewhere. */
.wt-step-title code,
.wt-step-note code {
  font-family: var(--font-tech);
  font-size: 0.85em;
  padding: 1px 5px;
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  border-radius: 4px;
  color: var(--ink);
}
.wt-step-note a {
  color: var(--ink);
  border-bottom: 1px solid var(--hairline-strong);
  transition: border-color 120ms ease;
}
.wt-step-note a:hover { border-bottom-color: var(--ink); }

/* --- Copy block ----------------------------------------------------
   Value + Copy button. Used for naming conventions, domain formats,
   Measurement IDs — anything the user will paste into GA4. Click
   the button, it's in the clipboard. Immediate feedback: label
   flips to "Copied" for a moment. */
.wt-copy {
  display: flex;
  align-items: stretch;
  gap: 0;
  margin: 10px 0 6px;
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  overflow: hidden;
  max-width: 480px;
}
.wt-copy > code {
  flex: 1;
  padding: 10px 14px;
  font-family: var(--font-tech);
  font-size: 13px;
  color: var(--ink);
  background: none;
  border: 0;
  border-radius: 0;
  min-width: 0;
  overflow-x: auto;
  white-space: nowrap;
}
.wt-copy-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 14px;
  background: var(--surface);
  border: 0;
  border-left: 1px solid var(--hairline);
  color: var(--ink-secondary);
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.wt-copy-btn svg {
  width: 13px;
  height: 13px;
  stroke-width: 2;
}
.wt-copy-btn:hover {
  background: var(--canvas-soft);
  color: var(--ink);
}
.wt-copy-btn.is-copied {
  color: var(--success-fg);
}

/* --- Reference blocks (tables inside a section) --------------------
   For the conversions table etc. Table itself uses the existing
   `.article-body table` styling from §30 — this just wraps it with
   a small label. */
.wt-reference {
  margin: 8px 0 24px;
}
.wt-reference-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 10px;
}
.wt-reference table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  overflow: hidden;
}
.wt-reference th {
  text-align: left;
  padding: 10px 14px;
  font-weight: 600;
  font-size: 12px;
  color: var(--ink);
  background: var(--canvas-soft);
  border-bottom: 1px solid var(--hairline);
}
.wt-reference td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--hairline);
  vertical-align: top;
  line-height: 1.5;
  color: var(--ink);
}
.wt-reference tr:last-child td { border-bottom: 0; }
.wt-reference code {
  font-family: var(--font-tech);
  font-size: 0.9em;
  padding: 1px 5px;
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  border-radius: 4px;
}

/* --- Callouts inside a section (reused from §30) ------------------
   Bring the same callout treatment into the walkthrough scope so
   procedural warnings still stand out. */
.wt-section .callout {
  margin: 16px 0 24px;
  padding: 12px 16px;
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--ink);
  border-radius: var(--r-sm);
}
.wt-section .callout p:first-child { margin-top: 0; }
.wt-section .callout p:last-child { margin-bottom: 0; }
.wt-section .callout--warning {
  background: var(--warning-bg);
  border-color: var(--warning-border);
  border-left-color: var(--warning-fg);
}
.wt-section .callout--warning p {
  color: #7a2e0a;
  line-height: 1.55;
}

/* --- Figures inside a section (reused from §30 pattern) -----------
   Screenshot placeholder styling for the interim before real
   images exist. */
.wt-fig {
  margin: 20px 0 24px;
}
.wt-fig .fig-placeholder {
  aspect-ratio: 16 / 9;
  background: var(--canvas-soft);
  border: 1px dashed var(--hairline-strong);
  border-radius: var(--r-md);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 20px;
  color: var(--ink-secondary);
  font-size: 13px;
  text-align: center;
}
.wt-fig .fig-placeholder-tag {
  font-family: var(--font-tech);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-muted);
  padding: 2px 8px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 4px;
}
.wt-fig figcaption {
  margin-top: 8px;
  font-size: 12.5px;
  color: var(--ink-secondary);
  line-height: 1.5;
}

/* --- FAQ (used on the Common issues section) ----------------------
   Native <details> for accessibility. Reads as a lightweight
   accordion inside the walkthrough. */
.wt-faq {
  margin: 0 0 32px;
  border-top: 1px solid var(--hairline);
}
.wt-faq-item {
  border-bottom: 1px solid var(--hairline);
}
.wt-faq-item > summary {
  list-style: none;
  padding: 16px 4px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  cursor: pointer;
  font-size: 15.5px;
  font-weight: 500;
  color: var(--ink);
  transition: color 100ms ease;
}
.wt-faq-item > summary::-webkit-details-marker { display: none; }
.wt-faq-item > summary:hover { color: var(--ink); }
.wt-faq-item > summary svg {
  width: 16px;
  height: 16px;
  stroke-width: 2;
  color: var(--ink-secondary);
  transition: transform 200ms ease;
  flex-shrink: 0;
}
.wt-faq-item[open] > summary svg {
  transform: rotate(180deg);
}
.wt-faq-a {
  padding: 0 4px 18px;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--ink-secondary);
}
.wt-faq-a p { margin: 0 0 10px; }
.wt-faq-a p:last-child { margin-bottom: 0; }
.wt-faq-a a {
  color: var(--ink);
  border-bottom: 1px solid var(--hairline-strong);
}
.wt-faq-a a:hover { border-bottom-color: var(--ink); }

/* --- Section navigation buttons (Prev / Continue) ------------------
   Bottom of every work section. Prev on the left, Continue on the
   right. The Continue button names what's next — "Configure the
   data stream →" not just "Next →". You always know what's coming. */
.wt-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: 28px;
  margin-top: 32px;
  border-top: 1px solid var(--hairline);
}
.wt-nav .btn { flex-shrink: 0; }
.wt-nav .btn svg { width: 14px; height: 14px; stroke-width: 2; }

/* Big Continue button — primary CTA per section. */
.btn.btn--lg {
  padding: 10px 18px;
  font-size: 14px;
  gap: 8px;
}
.btn.btn--xl {
  padding: 14px 24px;
  font-size: 16px;
  gap: 10px;
  border-radius: var(--r-md);
}
.btn.btn--xl svg { width: 16px; height: 16px; stroke-width: 2; }

/* --- Done screen ---------------------------------------------------
   Final state. A clear checkmark, a summary line, then a link to the
   next thing in the sequence. The walkthrough ends earned. */
.wt-section--done .wt-done {
  padding: 20px 0 0;
  text-align: left;
}
.wt-done-mark {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--surface);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 20px;
}
.wt-done-mark svg {
  width: 28px;
  height: 28px;
  stroke-width: 2.5;
}
.wt-done-title {
  margin: 0 0 12px;
  font-size: 32px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  line-height: 1.15;
}
.wt-done-lead {
  margin: 0 0 32px;
  font-size: 17px;
  color: var(--ink-secondary);
  line-height: 1.55;
  max-width: 620px;
}
.wt-done-next {
  margin-bottom: 32px;
  padding: 20px;
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
}
.wt-done-next-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-bottom: 12px;
  font-family: var(--font-tech);
}
.wt-done-next-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px;
  margin: -8px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  color: var(--ink);
  transition: border-color 120ms ease, transform 120ms ease;
}
.wt-done-next-link:hover {
  border-color: var(--ink);
  transform: translateY(-1px);
}
.wt-done-next-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 2px;
}
.wt-done-next-note {
  font-size: 13px;
  color: var(--ink-secondary);
}
.wt-done-next-link svg {
  width: 18px;
  height: 18px;
  stroke-width: 2;
  color: var(--ink-secondary);
  flex-shrink: 0;
}
.wt-done-actions {
  display: flex;
  gap: 10px;
}

/* --- 27. Responsive (light-touch) ---------------------------------- */
@media (max-width: 1100px) {
  /* Article page — before mobile, drop the TOC. 720 body + 60 gap +
     180 toc = 960, and once the ops-main padding eats into that on
     laptop widths the TOC gets awkward. Reading column alone reads
     better than a squeezed TOC. */
  .article-page--with-toc {
    display: block;
    max-width: 720px;
  }
  .article-page--with-toc > .article-toc { display: none; }
}

@media (max-width: 1024px) {
  .cards-row { grid-template-columns: 1fr; }
  .app-frame { grid-template-columns: 200px 1fr; }
  .main { padding: 24px 20px; }
  .task-layout { grid-template-columns: 1fr; }
  .preview-body { padding: 32px 32px 40px; }
  .team-grid { grid-template-columns: repeat(2, 1fr); }
  .contact-methods { grid-template-columns: 1fr; }
  .contact-hero { grid-template-columns: 1fr; }
  .contact-hero-portrait { padding: 32px; }
  .admin-main { padding: 24px 20px 60px; }
  .client-list-head, .client-row { grid-template-columns: 130px 1fr 80px 100px 100px 70px; gap: 12px; }
  .form-grid-3 { grid-template-columns: 1fr; }
}
@media (max-width: 720px) {
  body { padding: 0; }
  .app-frame { border-radius: 0; border: 0; min-height: 100vh; grid-template-columns: 1fr; }
  .sidebar { display: none; }
  .calendar-grid { grid-template-columns: 44px repeat(7, minmax(90px, 1fr)); overflow-x: auto; }
  .page-toolbar { flex-direction: column; align-items: stretch; }
  .page-toolbar .btn { align-self: flex-end; }
  /* Operations shell — collapse sidebar (no hamburger yet), content
     goes full-width. Operations tools aren't optimised for mobile;
     this is a graceful fallback, not a phone-first design. */
  .ops-shell { grid-template-columns: 1fr; }
  .ops-sidebar { display: none; }
  .ops-main { padding: 20px 16px 40px; }
  /* Article page — TOC doesn't render inside the shell on mobile;
     the mobile view is single-column reading. */
  .article-page--with-toc {
    display: block;
    max-width: 720px;
    margin: 0 auto;
  }
  .article-page--with-toc > .article-toc { display: none; }
  /* Walkthrough — cover facts wrap to 2 columns; nav buttons stack. */
  .wt-cover-title { font-size: 32px; }
  .wt-cover-lead  { font-size: 16px; }
  .wt-title { font-size: 26px; }
  .wt-lead { font-size: 15px; }
  .wt-cover-facts { grid-template-columns: repeat(2, 1fr); gap: 12px 20px; }
  .wt-nav { flex-direction: column-reverse; align-items: stretch; }
  .wt-nav .btn { width: 100%; justify-content: center; }
  .walkthrough-topbar-title { display: none; }
  /* Playbook list — hide Updated + Author on mobile so Title +
     Department fit. On a narrow phone the row still communicates
     the essentials (what it is, which department). */
  .data-list-index .data-cell:nth-child(3),
  .data-list-index .data-cell:nth-child(4) { display: none; }
}

/* =====================================================================
   §36 · WALKTHROUGH ADDITIONS
   ---------------------------------------------------------------------
   Two components the GA4 walkthrough didn't need but real processes do:
   a multi-line copy block (DNS records, email templates) and a decision
   branch (where a process forks based on the client's situation).
   Both reuse existing tokens — no new colours, no new radii.
   ===================================================================== */

/* --- Multi-line copy block ------------------------------------------
   .wt-copy is a single-line value + button. This variant stacks the
   button above a <pre> for records, snippets and email templates. */
.wt-copy--block {
  display: block;
  max-width: 100%;
  overflow: hidden;
}
.wt-copy--block .wt-copy-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 8px 8px 14px;
  background: var(--surface);
  border-bottom: 1px solid var(--hairline);
}
.wt-copy--block .wt-copy-name {
  font-family: var(--font-tech);
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink-muted);
}
.wt-copy--block .wt-copy-btn {
  border-left: 0;
  border-radius: var(--r-sm);
  padding: 6px 10px;
}
.wt-copy--block pre {
  margin: 0;
  padding: 14px;
  font-family: var(--font-tech);
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--ink);
  white-space: pre-wrap;
  word-break: break-word;
  overflow-x: auto;
}

/* --- Decision branch -------------------------------------------------
   A process fork. Two or three mutually exclusive situations, each
   with its own instruction. Deliberately flat — no cards, no shadows,
   just hairlines and a mono label so it reads as structure. */
.wt-branch {
  margin: 20px 0 24px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  overflow: hidden;
}
.wt-branch-label {
  padding: 10px 16px;
  background: var(--canvas-soft);
  border-bottom: 1px solid var(--hairline);
  font-family: var(--font-tech);
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink-muted);
}
.wt-branch-option {
  padding: 16px;
  border-bottom: 1px solid var(--hairline);
}
.wt-branch-option:last-child { border-bottom: 0; }
.wt-branch-case {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 6px;
}
.wt-branch-key {
  flex: none;
  font-family: var(--font-tech);
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-muted);
  padding-top: 1px;
}
.wt-branch-title {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.4;
}
.wt-branch-option p {
  margin: 0 0 8px 26px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-secondary);
}
.wt-branch-option p:last-child { margin-bottom: 0; }
.wt-branch-option code {
  font-family: var(--font-tech);
  font-size: 12.5px;
  background: var(--canvas-soft);
  border: 1px solid var(--hairline);
  border-radius: var(--r-xs);
  padding: 1px 5px;
}
.wt-branch-option a { color: var(--ink); border-bottom: 1px solid var(--hairline-strong); text-decoration: none; }
.wt-branch-option a:hover { border-bottom-color: var(--ink); }

@media (max-width: 720px) {
  .wt-branch-option p { margin-left: 0; }
}

/* =====================================================================
   §37 · SECTION HELP PROMPT
   ---------------------------------------------------------------------
   Sits at the foot of every walkthrough section. Holds the context and
   caveats that used to clutter the page as prose, in a form you copy
   into a chat when a step isn't clear.

   Deliberately dark: it reads as a tool, not as content, so the eye
   skips it when you're just running the checklist.
   ===================================================================== */

.wt-prompt {
  margin: 32px 0 8px;
  border-radius: var(--r-md);
  background: #17171a;
  overflow: hidden;
}

.wt-prompt-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 10px 10px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.09);
}

.wt-prompt-label {
  font-family: var(--font-tech);
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: rgba(255, 255, 255, 0.5);
}

.wt-prompt-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 11px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.92);
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease;
}
.wt-prompt-btn:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.26);
}
.wt-prompt-btn:focus-visible {
  outline: 2px solid var(--accent, #f65108);
  outline-offset: 2px;
}
.wt-prompt-btn svg {
  width: 13px;
  height: 13px;
  stroke-width: 1.8;
}
.wt-prompt-btn.is-copied {
  background: rgba(255, 255, 255, 0.18);
  border-color: rgba(255, 255, 255, 0.34);
}

.wt-prompt-body {
  margin: 0;
  padding: 14px 16px 16px;
  max-height: 200px;
  overflow-y: auto;
  font-family: var(--font-tech);
  font-size: 12px;
  line-height: 1.75;
  color: rgba(255, 255, 255, 0.62);
  white-space: pre-wrap;
  word-break: break-word;
}
.wt-prompt-body::-webkit-scrollbar { width: 9px; }
.wt-prompt-body::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.14);
  border-radius: 5px;
}

@media (max-width: 720px) {
  .wt-prompt-body { max-height: 150px; font-size: 11.5px; }
}


/* =====================================================================
   §38 · STEP NOTES
   ---------------------------------------------------------------------
   Optional per-step scratch space, hidden until asked for. An input
   that is present but invisible still takes up height, which left
   unexplained gaps between rows — so the field is removed from flow
   entirely and a + on the row brings it in.

   The input sits outside the <label> so clicking it never toggles the
   checkbox.
   ===================================================================== */

/* The + button. Lives in the label's third column, fades in with the
   row so a clean checklist stays clean. */
.wt-note-add {
  grid-column: 3;
  align-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: none;
  color: var(--ink-muted);
  cursor: pointer;
  opacity: 0;
  transition: opacity 130ms ease, background 130ms ease,
              border-color 130ms ease, color 130ms ease;
}
.wt-note-add svg { width: 15px; height: 15px; stroke-width: 1.8; }

.wt-step:hover .wt-note-add,
.wt-note-add:focus-visible {
  opacity: 1;
}
.wt-note-add:hover {
  background: var(--surface);
  border-color: var(--hairline-strong);
  color: var(--ink);
}
.wt-note-add:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 1px;
}

/* Touch devices have no hover, so keep it permanently visible there. */
@media (hover: none) {
  .wt-note-add { opacity: 0.45; }
}

/* Hidden entirely until opened — no height, no gap. */
.wt-note {
  display: none;
  width: calc(100% - 44px);
  margin: -6px 0 14px 44px;
  padding: 4px 0;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  background: none;
  font-family: inherit;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink);
  transition: border-color 140ms ease;
}
.wt-step.note-open .wt-note { display: block; }
.wt-step.note-open .wt-note-add { display: none; }

.wt-note::placeholder { color: var(--ink-faint, #b4b4bb); font-size: 13px; }
.wt-note:focus {
  outline: none;
  border-bottom-color: var(--ink);
}

@media (max-width: 720px) {
  .wt-note { width: 100%; margin-left: 0; }
}

/* =====================================================================
   §39 · PROCESS FILES
   ---------------------------------------------------------------------
   Downloadable assets that ship with the process. Kept in the project's
   /assets folder so a file can never drift away from the page that
   references it.
   ===================================================================== */

.wt-files {
  margin: 28px 0;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  overflow: hidden;
}

.wt-files-label {
  padding: 10px 16px;
  background: var(--canvas-soft);
  border-bottom: 1px solid var(--hairline);
  font-family: var(--font-tech);
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink-muted);
}

.wt-file {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 16px;
  border-bottom: 1px solid var(--hairline);
  text-decoration: none;
  color: inherit;
  transition: background 130ms ease;
}
.wt-file:last-child { border-bottom: 0; }
.wt-file:hover { background: var(--canvas-soft); }
.wt-file:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: -2px;
}

.wt-file-icon {
  flex: none;
  width: 17px;
  height: 17px;
  stroke-width: 1.6;
  color: var(--ink-muted);
}

.wt-file-text { flex: 1; min-width: 0; }

.wt-file-name {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.35;
}

.wt-file-note {
  margin-top: 2px;
  font-size: 13px;
  color: var(--ink-secondary);
  line-height: 1.45;
}

.wt-file-meta {
  flex: none;
  font-family: var(--font-tech);
  font-size: 11px;
  color: var(--ink-muted);
  letter-spacing: 0.02em;
}

.wt-file-get {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink);
}
.wt-file-get svg { width: 13px; height: 13px; stroke-width: 1.8; }
.wt-file:hover .wt-file-get { text-decoration: underline; }

@media (max-width: 620px) {
  .wt-file { flex-wrap: wrap; gap: 8px 12px; }
  .wt-file-meta { order: 3; }
  .wt-file-get { order: 4; margin-left: auto; }
}

/* =====================================================================
   §40 · PROMPT INPUTS
   ---------------------------------------------------------------------
   A small form whose values are substituted into a prompt block on the
   same page. The CM fills it once and copies a finished prompt rather
   than editing placeholders in a text file.
   ===================================================================== */

.wt-form {
  margin: 24px 0 8px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px 20px;
}
.wt-form-field { display: flex; flex-direction: column; gap: 5px; }
.wt-form-field--wide { grid-column: 1 / -1; }

.wt-form-field > span {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-secondary);
}

.wt-form-field input,
.wt-form-field textarea {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  font-family: inherit;
  font-size: 14px;
  line-height: 1.45;
  color: var(--ink);
  transition: border-color 130ms ease, box-shadow 130ms ease;
}
.wt-form-field textarea { min-height: 72px; resize: vertical; }
.wt-form-field input::placeholder,
.wt-form-field textarea::placeholder { color: var(--ink-faint, #b4b4bb); }
.wt-form-field input:focus,
.wt-form-field textarea:focus {
  outline: none;
  border-color: var(--ink);
  box-shadow: 0 0 0 3px rgba(23, 23, 26, 0.08);
}

/* Colour fields show a swatch of whatever's typed. */
.wt-form-field--colour { position: relative; }
.wt-form-field--colour input { padding-left: 34px; }
.wt-form-swatch {
  position: absolute;
  left: 11px;
  bottom: 10px;
  width: 16px;
  height: 16px;
  border-radius: 4px;
  border: 1px solid rgba(0, 0, 0, 0.12);
  background: transparent;
  pointer-events: none;
}

/* Unfilled placeholders stand out in the rendered prompt so a missed
   field is obvious before copying. */
.wt-prompt-body .wt-unfilled {
  color: #f6a06a;
}

@media (max-width: 720px) {
  .wt-form { grid-template-columns: 1fr; }
}
