/* ==========================================================================
   OCA Hub — shared shell
   Requires /design/tokens.css to be linked FIRST.

   Everything every hub page has in common: the page reset, the floating nav,
   section rhythm, the tri-colour stripe, action pills and the footer. Page-
   specific components (maps, constellations, tables of one page's own shape)
   stay in that page's own <style> block — but they must also be authored
   against the semantic tokens, never raw values.

   Before adding a rule here, check it is genuinely shared. Before adding a
   rule to a page, check it is genuinely NOT.
   ========================================================================== */

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--surface-canvas);
  color: var(--text-primary);
  font-family: var(--font-grotesk);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  margin: 0;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

::selection { background: var(--action-primary); color: var(--text-on-action); }

/* Any element carrying data-theme paints its own ground and re-resolves its
   own colour. Redeclaring the tokens is not enough by itself: descendants
   inherit body's ALREADY-COMPUTED colour, so without this a dark section
   would keep black text on a black ground. Put data-theme="dark" on a
   section, a band, or a whole page and everything inside adapts. */
[data-theme] { background: var(--surface-canvas); color: var(--text-primary); }

.wrap { max-width: var(--page-max-width); margin: 0 auto; padding: 0 var(--spacing-32); }

h1, h2, h3 { margin: 0; text-wrap: balance; font-weight: var(--weight-regular); letter-spacing: var(--tracking-heading); }
p { margin: 0 0 1em; }
a { color: var(--accent-text); }

/* --------------------------------------------------------------------------
   Typographic voices

   Two faces, strict roles. The serif at 300 carries editorial moments — page
   titles, section openers, pull quotes. The grotesque carries everything
   functional. Never push the serif above 300; the whisper weight is the
   system's signature.
   -------------------------------------------------------------------------- */

.editorial {
  font-family: var(--font-serif);
  font-weight: var(--weight-light);
  letter-spacing: var(--tracking-display);
  line-height: var(--leading-heading-lg);
}

/* Violet highlight inside an editorial headline — the one place colour is
   allowed to enter display type. */
.accent { color: var(--accent-text); }

.mono {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.lede, .prose { color: var(--text-secondary); max-width: 64ch; font-size: var(--text-subheading); line-height: var(--leading-subheading); }
.prose { max-width: 66ch; }
.lede b, .prose b { color: var(--text-primary); font-weight: 500; }

/* --------------------------------------------------------------------------
   Floating nav — the one element in the system allowed a shadow, and the only
   thing that breaks the page rhythm. It floats centred with white space on
   both sides rather than spanning full width.
   -------------------------------------------------------------------------- */

.masthead { position: fixed; top: var(--spacing-24); left: 0; right: 0; z-index: 50; pointer-events: none; }
.masthead-inner {
  max-width: var(--page-max-width);
  margin: 0 auto;
  pointer-events: auto;
  position: relative;
  background: var(--surface-canvas);
  border-radius: var(--radius-surface);
  box-shadow: var(--shadow-nav);
  padding: 0 var(--spacing-32); /* matches .wrap so the logo aligns to the headline */
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 56px;
}
@media (max-width: 1264px) { .masthead-inner { margin: 0 var(--spacing-32); } }

.brand { display: flex; align-items: center; gap: var(--spacing-12); }
.brand .oca { font-weight: 600; font-size: var(--text-body); letter-spacing: var(--tracking-heading); color: var(--text-primary); text-decoration: none; }
.brand .doc { color: var(--text-muted); }

/* Global nav — ghost links in the pill, one per top-level section. In normal
   flex flow (not absolutely centred) so it can never overlap the brand on
   its left or the session cluster on its right: it centres itself in
   whatever space is genuinely free and shrinks before it collides. */
.navlinks { display: flex; gap: var(--spacing-24); margin: 0 auto; padding: 0 var(--spacing-24); flex-wrap: nowrap; min-width: 0; }
.navlinks a { color: var(--text-primary); text-decoration: none; font-size: var(--text-body); transition: color 0.25s; white-space: nowrap; }
.navlinks a:hover { color: var(--accent-text); }
.navlinks a[aria-current] { color: var(--accent-text); }
@media (max-width: 1120px) { .navlinks { gap: var(--spacing-16); } }
/* Breadcrumb mastheads carry more text than the home's (OCA / Projects /
   Kurdflix plus six sections plus the counter). In Inter that no longer fits
   the 1200px bar at the default gap, so the nav tightens whenever crumbs are
   present, and the counter yields first as the bar narrows. */
.masthead-inner:has(.crumbs) .navlinks { gap: var(--spacing-16); padding: 0 var(--spacing-16); }
@media (max-width: 1264px) { .masthead-inner:has(.crumbs) .count, .masthead-inner:has(.crumbs) .live { display: none; } }

/* Breadcrumb trail in the brand slot: OCA / section / page. One click steps
   up a level; the current page is inert ink. */
.crumbs { display: flex; align-items: center; gap: var(--spacing-8); color: var(--text-muted); }
.crumbs a { color: var(--text-muted); text-decoration: none; transition: color 0.25s; }
.crumbs a:hover { color: var(--accent-text); }
.crumbs i { font-style: normal; color: var(--border-inactive); }
.crumbs .here { color: var(--text-primary); }

.backlink { color: var(--text-muted); text-decoration: none; transition: color 0.25s; }
.backlink:hover { color: var(--accent-text); }

.count { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.count b { color: var(--text-primary); font-weight: 500; }

/* Session cluster on the nav's right edge: the page's context slot (count or
   live dot) plus the sign-out pill the gate injects. Kept as one flex group so
   the masthead's space-between still sees exactly two in-flow children. */
.mast-session { display: flex; align-items: center; gap: var(--spacing-16); flex: none; }
/* When the owner's view switcher is present the cluster is at its widest —
   drop the page-context slot from the bar (countdown or updated-date; both
   live in the page content too) so the section links always keep their room. */
.mast-session:has(.viewas-wrap) > .count,
.mast-session:has(.viewas-wrap) > .live { display: none; }
.signout {
  font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  background: none; border: 1px solid var(--border-hairline); border-radius: var(--radius-pill);
  color: var(--text-muted); padding: 5px 12px; cursor: pointer;
  transition: color 0.25s, border-color 0.25s;
}
.signout:hover { color: var(--accent-text); border-color: var(--border-focus); }

/* Owner-only view switcher, injected by the gate next to sign-out: a pill
   trigger and a small menu hanging below the masthead. The menu shares the
   nav's shadow — it is part of the one floating element allowed one. */
.viewas-wrap { position: relative; }
.viewas {
  font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  background: var(--surface-canvas); border: 1px solid var(--border-hairline);
  border-radius: var(--radius-pill); color: var(--text-secondary);
  padding: 5px 12px; cursor: pointer;
  transition: color 0.25s, border-color 0.25s;
}
.viewas::after { content: " ▾"; color: var(--text-muted); }
.viewas:hover { color: var(--accent-text); border-color: var(--border-focus); }
.viewas:focus-visible { outline: 1px solid var(--border-focus); outline-offset: 2px; }
.viewas-menu {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 60;
  display: none; flex-direction: column; min-width: 180px;
  background: var(--surface-canvas); border: 1px solid var(--border-hairline);
  border-radius: var(--radius-surface); box-shadow: var(--shadow-nav);
  padding: 6px;
}
.viewas-wrap.open .viewas-menu { display: flex; }
.viewas-menu button {
  font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase; text-align: left;
  background: none; border: none; border-radius: 10px;
  color: var(--text-secondary); padding: 9px 12px; cursor: pointer;
  transition: background 0.2s, color 0.2s;
}
.viewas-menu button:hover { background: var(--surface-card); color: var(--text-primary); }
.viewas-menu button[aria-current] { color: var(--accent-text); }

/* Owner-only rooms — Finance, Map, Access — grouped under one "Owner ▾" nav
   item (injected by the gate) so the masthead never overflows. The menu
   mirrors the view switcher's. */
.navmore-wrap { position: relative; display: flex; align-items: center; }
.navmore {
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: inherit; font-size: var(--text-body); color: var(--text-primary);
  white-space: nowrap; transition: color 0.25s;
}
.navmore::after { content: " ▾"; color: var(--text-muted); }
.navmore:hover, .navmore[aria-current] { color: var(--accent-text); }
.navmore:focus-visible { outline: 1px solid var(--border-focus); outline-offset: 2px; }
.navmore-menu {
  position: absolute; top: calc(100% + 16px); left: 50%; transform: translateX(-50%); z-index: 60;
  display: none; flex-direction: column; min-width: 160px;
  background: var(--surface-canvas); border: 1px solid var(--border-hairline);
  border-radius: var(--radius-surface); box-shadow: var(--shadow-nav);
  padding: 6px;
}
.navmore-wrap.open .navmore-menu { display: flex; }
.navmore-menu a {
  font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase; text-decoration: none;
  border-radius: 10px;
  color: var(--text-secondary); padding: 9px 12px;
  transition: background 0.2s, color 0.2s;
}
.navmore-menu a:hover { background: var(--surface-card); color: var(--text-primary); }
.navmore-menu a[aria-current] { color: var(--accent-text); }

@media (max-width: 640px) { .signout, .viewas-wrap { display: none; } }

/* In-page section links (the Axiom view, the partner workspaces): a jump
   lands with the section's top edge just under the floating nav. Matches
   LINE in /js/sections.js, which also marks the section in view with
   aria-current on its masthead link. */
[id] { scroll-margin-top: 120px; }

/* The "Back to Projects" pill /js/sections.js shows after an in-page jump —
   bottom right, opposite the owner's bottom-left .hub-back. */
.return {
  position: fixed; bottom: var(--spacing-20); right: var(--spacing-20); z-index: 90;
  font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  padding: 10px 18px 10px 14px; border-radius: var(--radius-pill);
  background: var(--surface-canvas); color: var(--text-primary);
  border: 1px solid var(--border-hairline); box-shadow: var(--shadow-nav);
  cursor: pointer; display: flex; align-items: center; gap: 8px;
  transition: color 0.25s, border-color 0.25s;
}
.return[hidden] { display: none; }
.return::before { content: "\2190"; color: var(--accent-text); }
.return:hover { color: var(--accent-text); border-color: var(--border-focus); }
.return:focus-visible { outline: 1px solid var(--border-focus); outline-offset: 2px; }
@media (prefers-reduced-motion: no-preference) {
  .return:not([hidden]) { animation: hub-return-in 0.25s ease-out; }
}
@keyframes hub-return-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* Read-progress hairline, pinned to the nav's lower edge and clipped to its
   rounded corners. */
.progress { position: absolute; bottom: 0; left: 0; height: 2px; width: 0%; background: var(--action-primary); border-bottom-left-radius: var(--radius-surface); }

.live { display: flex; align-items: center; gap: var(--spacing-8); color: var(--text-muted); }
.live .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent-status); }
@media (prefers-reduced-motion: no-preference) { .live .dot { animation: hub-pulse 2.2s ease-in-out infinite; } }
@keyframes hub-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }

/* Narrowing order: the countdown text goes first, then page context, then
   the sign-out pill; the section links are the last thing standing. */
@media (max-width: 1024px) { .masthead .count, .masthead .live { display: none; } }
@media (max-width: 960px) { .brand .doc, .brand .crumbs { display: none; } }
@media (max-width: 640px) {
  .masthead .backlink { display: none; }
  /* Five or six section links do not fit a 375px bar even at the small size.
     The nav scrolls sideways instead of pushing the masthead — and with it
     the last link — past the right edge of the screen. */
  .navlinks { gap: var(--spacing-16); overflow-x: auto; scrollbar-width: none; }
  .navlinks::-webkit-scrollbar { display: none; }
  .navlinks a, .navmore { font-size: var(--text-small); }
  /* Five-plus non-wrapping links don't fit a phone-width pill; let the row
     scroll sideways inside it instead of overflowing the masthead. */
  .navlinks { overflow-x: auto; scrollbar-width: none; }
  .navlinks::-webkit-scrollbar { display: none; }
}

/* --------------------------------------------------------------------------
   Scroll reveals
   -------------------------------------------------------------------------- */

html.js .r { opacity: 0; transform: translateY(18px); transition: opacity 0.7s cubic-bezier(0.16,1,0.3,1), transform 0.7s cubic-bezier(0.16,1,0.3,1); }
html.js .r.in { opacity: 1; transform: none; }
html.js .r.d1 { transition-delay: 0.08s; }
html.js .r.d2 { transition-delay: 0.16s; }
@media (prefers-reduced-motion: reduce) { html.js .r { opacity: 1; transform: none; transition: none; } }

/* --------------------------------------------------------------------------
   Section rhythm

   Section transitions are the tri-colour stripe, not a whitespace gap and not
   a hairline rule. Use it as a closing band between content bands only.
   -------------------------------------------------------------------------- */

section { padding: var(--spacing-80) 0; }
/* Adjacent sections are parted by a hairline; the stripe is a closing band
   between major content bands, never inline decoration between every block. */
section + section { border-top: 1px solid var(--border-subtle); }

.stripe { height: 3px; display: grid; grid-template-columns: 1fr 1fr 1fr; }
.stripe i:nth-child(1) { background: var(--color-mint-pulse); }
.stripe i:nth-child(2) { background: var(--action-primary); }
.stripe i:nth-child(3) { background: var(--color-ink-black); }

.sec-head { display: flex; align-items: baseline; gap: var(--spacing-16); margin-bottom: var(--spacing-24); }
.sec-head .no { color: var(--accent-text); font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500; letter-spacing: 0.16em; font-variant-numeric: tabular-nums; }
/* Styled directly rather than relying on a `mono` class, so a section label
   looks the same on every page whether or not the markup remembers it. */
.sec-head .lab { color: var(--text-muted); font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; }

section h2 { font-size: clamp(2rem, 4.6vw, 3.2rem); line-height: var(--leading-heading-lg); margin-bottom: var(--spacing-28); max-width: 26ch; }

/* Hero block shared by every page. Top padding clears the floating nav. */
.hero { position: relative; padding: 150px 0 var(--spacing-80); overflow: hidden; }
.hero .wrap { position: relative; z-index: 2; }
.hero h1 { font-size: clamp(2.6rem, 6.4vw, 4.6rem); line-height: var(--leading-display); max-width: 34ch; text-wrap: balance; }
.hero-sub { font-size: var(--text-subheading); line-height: var(--leading-subheading); color: var(--text-secondary); max-width: 54ch; margin-top: var(--spacing-24); }

.kicker, .hero-eyebrow { color: var(--accent-text); margin-bottom: var(--spacing-24); display: flex; align-items: center; gap: var(--spacing-12); }
.kicker::before, .hero-eyebrow::before { content: ""; width: 40px; height: 1px; background: var(--action-primary); }

/* --------------------------------------------------------------------------
   Full-bleed photographic band

   The one element allowed to break the white canvas edge to edge. Imagery in
   this system documents rather than decorates, so a band gets the full width
   and a single editorial line — never a caption-sized inset.

   Mirrors the deck's photo slides: ink scrim for legibility, white type, and
   the tri-colour stripe closing the lower edge. Type over photography stays
   monochrome — neither accent survives an arbitrary photograph.
   -------------------------------------------------------------------------- */

.band { position: relative; height: clamp(320px, 52vh, 560px); overflow: hidden; }
.band img { width: 100%; height: 100%; object-fit: cover; display: block; }
.band::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(0,0,0,0.30) 0%, rgba(0,0,0,0.10) 45%, rgba(0,0,0,0.55) 100%),
    linear-gradient(90deg, rgba(0,0,0,0.62) 0%, rgba(0,0,0,0.28) 55%, rgba(0,0,0,0.10) 100%);
}
.band-copy { position: absolute; inset: 0; z-index: 2; display: flex; align-items: center; }
.band-copy .eyebrow {
  color: rgba(255,255,255,0.78); display: block; margin-bottom: var(--spacing-16);
}
.band-copy h2 {
  color: var(--color-pure-white);
  font-size: clamp(1.8rem, 4vw, 3rem);
  line-height: var(--leading-heading);
  max-width: 20ch;
  margin: 0;
}
.band-copy p {
  color: rgba(255,255,255,0.82);
  max-width: 52ch; margin: var(--spacing-16) 0 0;
  font-size: var(--text-body); line-height: var(--leading-body);
}
.band .stripe { position: absolute; left: 0; right: 0; bottom: 0; z-index: 3; }

/* --------------------------------------------------------------------------
   Surfaces

   Flat, hairline-bordered, 16px radius. No drop shadows on content, ever —
   shadow belongs to the nav alone. No gradient fills.
   -------------------------------------------------------------------------- */

/* NB: no generic `.panel` here — kurdflix.html already uses `.panel` for a
   borderless column inside a bordered grid, and a shared definition would
   fight it. Use `.hairgrid` or a page-local class instead. */

/* Hairline-divided grid. Set --cols for the column count; children are the
   cells. Collapses to a single column under 780px. */
.hairgrid {
  display: grid;
  grid-template-columns: repeat(var(--cols, 3), 1fr);
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-surface);
  overflow: hidden;
}
.hairgrid > * { padding: var(--card-padding); border-left: 1px solid var(--border-hairline); }
.hairgrid > *:first-child { border-left: none; }
@media (max-width: 780px) {
  .hairgrid { grid-template-columns: 1fr; }
  .hairgrid > * { border-left: none; border-top: 1px solid var(--border-hairline); }
  .hairgrid > *:first-child { border-top: none; }
}

/* Project rows — the canonical listing of the five fronts, shared by the hub
   home and the projects index. */
.fronts { border: 1px solid var(--border-hairline); border-radius: var(--radius-surface); overflow: hidden; }
.front {
  display: grid; grid-template-columns: 44px 1fr auto;
  gap: var(--spacing-20); align-items: center;
  padding: var(--spacing-20) var(--spacing-24);
  border-top: 1px solid var(--border-subtle);
  transition: background 0.3s, padding-left 0.3s;
  text-decoration: none; color: var(--text-primary); cursor: pointer;
}
.front:focus-visible { outline: 1px solid var(--border-focus); outline-offset: -1px; }
.front:first-child { border-top: none; }
.front:hover { background: var(--surface-card); padding-left: var(--spacing-32); }
@media (prefers-reduced-motion: reduce) { .front { transition: none; } .front:hover { padding-left: var(--spacing-24); } }
@media (max-width: 700px) { .front { grid-template-columns: 44px 1fr; } .front .st { grid-column: 2; justify-self: start; } }
.front .pn { color: var(--action-primary); font-size: var(--text-caption); font-weight: 500; letter-spacing: 0.16em; }
.front .fn b { display: block; font-weight: 500; font-size: var(--text-subheading); letter-spacing: var(--tracking-heading); }
.front .fn span { color: var(--text-secondary); font-size: var(--text-body); }

/* Document cards — flat, hairline, no shadow and no lift. Hover moves the
   border to violet and slides the arrow; that is the whole affordance.
   Shared by the hub home and the strategy index. */
.docs { display: grid; grid-template-columns: 1fr 1fr; gap: var(--spacing-20); }
@media (max-width: 800px) { .docs { grid-template-columns: 1fr; } }
.doccard {
  position: relative; display: flex; flex-direction: column;
  text-decoration: none; color: var(--text-primary);
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-surface);
  background: var(--surface-canvas);
  padding: var(--card-padding);
  transition: border-color 0.35s;
}
.doccard:hover { border-color: var(--border-focus); }
.doccard:focus-visible { outline: 1px solid var(--border-focus); outline-offset: 2px; }
.doccard .tag { color: var(--action-primary); display: block; margin-bottom: var(--spacing-16); }
.doccard h3 { font-size: var(--text-heading-sm); margin-bottom: var(--spacing-12); }
.doccard p { color: var(--text-secondary); font-size: var(--text-body); margin: 0 0 var(--spacing-20); line-height: var(--leading-body); }
.doccard .foot { display: flex; align-items: center; justify-content: space-between; margin-top: auto; }
.doccard:hover .expand { border-color: var(--border-focus); }

/* Prev/next project switcher — closes every project page so sibling fronts
   are one click apart without going back through the index. */
.projnav { display: flex; justify-content: space-between; gap: var(--spacing-20); flex-wrap: wrap; }
.projnav a { text-decoration: none; color: var(--text-primary); }
.projnav a .mono { color: var(--text-muted); display: block; margin-bottom: var(--spacing-8); transition: color 0.25s; }
.projnav a b { font-weight: 500; font-size: var(--text-subheading); letter-spacing: var(--tracking-heading); }
.projnav a:hover .mono { color: var(--accent-text); }
.projnav .next { text-align: right; margin-left: auto; }

/* Inverted block. Ink-black fill carries emphasis without introducing a third
   accent colour — the system has exactly two chromatic notes and neither is
   spendable on "this row is important". */
.invert { background: var(--color-ink-black); color: var(--color-pure-white); }
.invert p, .invert li, .invert span { color: color-mix(in srgb, var(--color-pure-white) 78%, var(--color-ink-black)); }
.invert b, .invert h3, .invert strong { color: var(--color-pure-white); }
.invert .lab, .invert .mono { color: color-mix(in srgb, var(--color-pure-white) 60%, var(--color-ink-black)); }

/* --------------------------------------------------------------------------
   Actions

   The violet pill is the system's one action shape. Never rectangular, never
   a 4–8px radius, never mint-filled — mint is a status colour.
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; gap: var(--spacing-8);
  background: var(--action-primary); color: var(--text-on-action);
  font-size: var(--text-body); font-weight: var(--weight-regular);
  border-radius: var(--radius-pill); padding: 10px 20px;
  text-decoration: none; border: none; cursor: pointer;
}
.btn:hover { background: color-mix(in srgb, var(--action-primary) 88%, var(--color-ink-black)); }

.expand {
  width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid var(--border-hairline); background: var(--surface-canvas);
  color: var(--text-primary); display: grid; place-items: center;
  font-size: var(--text-subheading); line-height: 1;
  transition: border-color 0.25s; flex: none;
}

/* Status chips. Pill-shaped, and mint carries status while violet is reserved
   for actions — so a status chip never takes a violet fill. */
.chip, .flag, .who, .st {
  display: inline-block;
  font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  padding: 5px 12px; border-radius: var(--radius-pill);
  border: 1px solid var(--border-inactive); color: var(--text-secondary);
  white-space: nowrap;
}
.chip.go, .st.go { border-color: var(--accent-status); color: var(--color-ash-gray); background: color-mix(in srgb, var(--accent-status) 16%, transparent); }
.chip.hot, .st.hot { border-color: var(--color-ink-black); background: var(--color-ink-black); color: var(--color-pure-white); }

.due { font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-meta); white-space: nowrap; }

/* --------------------------------------------------------------------------
   Numbered sequence list — shared by "next actions", "advice", "what happens
   next" across pages.
   -------------------------------------------------------------------------- */

.numlist { counter-reset: n; list-style: none; padding: 0; margin: var(--spacing-40) 0 0; max-width: 820px; }
.numlist li { counter-increment: n; display: grid; grid-template-columns: 56px 1fr auto; gap: var(--spacing-20); padding: var(--spacing-20) 0; border-top: 1px solid var(--border-subtle); align-items: start; }
.numlist li:first-child { border-top: none; }
.numlist li::before { content: counter(n, decimal-leading-zero); font-family: var(--font-mono); font-weight: 500; font-size: var(--text-caption); color: var(--accent-text); padding-top: 6px; font-variant-numeric: tabular-nums; }
.numlist b { color: var(--text-primary); font-weight: 500; }
.numlist span.what, .numlist > li > span > span { color: var(--text-secondary); display: block; font-size: var(--text-body); line-height: var(--leading-body); }
@media (max-width: 640px) { .numlist li { grid-template-columns: 40px 1fr; } .numlist .who { grid-column: 2; justify-self: start; } }

/* --------------------------------------------------------------------------
   Tables
   -------------------------------------------------------------------------- */

.tablebox { overflow-x: auto; margin-top: var(--spacing-40); border: 1px solid var(--border-hairline); border-radius: var(--radius-surface); }
table { border-collapse: collapse; width: 100%; }
th, td { text-align: left; padding: 14px 18px; border-bottom: 1px solid var(--border-subtle); font-size: var(--text-body); vertical-align: top; }
th { font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-muted); }
tr:last-child td { border-bottom: none; }
td.num { font-family: var(--font-mono); font-size: var(--text-small); font-variant-numeric: tabular-nums; white-space: nowrap; }
td .note { display: block; font-size: var(--text-small); color: var(--text-muted); margin-top: 4px; }
td.tbd { color: var(--text-muted); font-style: italic; white-space: nowrap; }

/* --------------------------------------------------------------------------
   Mission timelines & the updates feed

   Rendered by /js/mission.js from /data/program.js (internal pages) or
   /data/partner-plan.js (partner pages). Nothing here is hand-positioned:
   bar geometry, statuses, day counts and the today line are computed from
   the current date at render time. Colour follows the system's rules —
   mint carries status (done, and the today line), ink carries the active
   bar, hairline is the future, dashed is not-yet-scheduled. Violet stays
   reserved for actions and the label voice.
   -------------------------------------------------------------------------- */

.gantt { border: 1px solid var(--border-hairline); border-radius: var(--radius-surface); margin-top: var(--spacing-40); padding: var(--card-padding); }
.gantt .gtop { display: flex; align-items: baseline; justify-content: space-between; gap: var(--spacing-16); flex-wrap: wrap; margin-bottom: var(--spacing-8); }
.gantt .gtop .ttl { font-weight: 500; font-size: var(--text-subheading); letter-spacing: var(--tracking-heading); }
.gantt .gtop .rng { color: var(--text-muted); }

.gantt .gscale { display: grid; grid-template-columns: var(--gantt-lab, 200px) 1fr; gap: var(--spacing-20); }
.gantt .gscale .gticks { position: relative; height: 24px; grid-column: 2; }
.gantt .gtick { position: absolute; top: 4px; transform: translateX(-50%); font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.gantt .gtick.first { transform: none; }
.gantt .gtick.last { transform: translateX(-100%); }

.gantt .grow { display: grid; grid-template-columns: var(--gantt-lab, 200px) 1fr; gap: var(--spacing-20); align-items: center; padding: 9px 0; border-top: 1px solid var(--border-subtle); }
.gantt .grow .glab { font-size: var(--text-small); line-height: 1.45; color: var(--text-secondary); }
.gantt .grow .glab b { color: var(--text-primary); font-weight: 500; display: block; }
.gantt .grow .glab a { color: var(--text-primary); text-decoration: none; }
.gantt .grow .glab a:hover { color: var(--accent-text); }
.gantt .grow .glab .sub { display: block; color: var(--text-muted); font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; margin-top: 3px; }

.gantt .gtrack { position: relative; height: 26px; border-radius: var(--radius-pill); background: color-mix(in srgb, var(--border-subtle) 45%, transparent); }
.gantt .gbar { position: absolute; top: 4px; bottom: 4px; min-width: 12px; border-radius: var(--radius-pill); border: 1px solid var(--border-inactive); background: var(--surface-canvas); }
.gantt .gbar.done { border-color: var(--accent-status); background: color-mix(in srgb, var(--accent-status) 18%, transparent); }
.gantt .gbar.now { border-color: var(--color-ink-black); background: var(--color-ink-black); }
.gantt .gbar.tbd { border-style: dashed; background: transparent; }

.gantt .gtoday { position: absolute; top: -3px; bottom: -3px; width: 2px; border-radius: 1px; background: var(--accent-status); }
.gantt .gtoday-tick { position: absolute; top: 4px; transform: translateX(-50%); font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-ash-gray); white-space: nowrap; }

.gantt .gms { position: absolute; top: 50%; width: 9px; height: 9px; transform: translate(-50%, -50%) rotate(45deg); background: var(--color-ink-black); }
.gantt .gms.done { background: var(--accent-status); }

.gantt .gnote { color: var(--text-muted); font-size: var(--text-small); margin: var(--spacing-16) 0 0; max-width: 70ch; }

/* The milestone ledger under a chart: what the diamonds mean, with the
   countdown computed live. */
.gantt .gmslist { list-style: none; margin: var(--spacing-20) 0 0; padding: 0; border-top: 1px solid var(--border-subtle); }
.gantt .gmslist li { display: flex; align-items: baseline; gap: var(--spacing-16); padding: 8px 0; border-top: 1px solid var(--border-subtle); font-size: var(--text-body); color: var(--text-secondary); }
.gantt .gmslist li:first-child { border-top: none; }
.gantt .gmslist .d { font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); flex: none; width: 84px; font-variant-numeric: tabular-nums; }
.gantt .gmslist b { color: var(--text-primary); font-weight: 500; }
.gantt .gmslist .in { margin-left: auto; font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-meta); white-space: nowrap; }
.gantt .gmslist .in.done { color: var(--color-ash-gray); }
.gantt .gmslist .in.today { color: var(--color-ash-gray); }

@media (max-width: 680px) {
  .gantt .gscale { display: none; }
  .gantt .grow { grid-template-columns: 1fr; gap: var(--spacing-8); }
  .gantt .gmslist .in { display: none; }
}

/* The updates feed — one dated row per update, rendered newest-first from
   the shared data file. */
.feed { list-style: none; margin: var(--spacing-40) 0 0; padding: 0; border: 1px solid var(--border-hairline); border-radius: var(--radius-surface); overflow: hidden; }
.feed li { display: grid; grid-template-columns: 70px 120px 1fr; gap: var(--spacing-20); padding: 14px 18px; border-top: 1px solid var(--border-subtle); align-items: baseline; }
.feed li:first-child { border-top: none; }
.feed .fd { font-family: var(--font-mono); font-size: var(--text-small); color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.feed .fp { font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--action-primary); }
.feed .fp a { color: inherit; text-decoration: none; }
.feed .fp a:hover { color: var(--accent-text); }
.feed .ft { color: var(--text-secondary); font-size: var(--text-body); line-height: var(--leading-body); }
.feed .ft b { color: var(--text-primary); font-weight: 500; }
.feed .fby { color: var(--text-muted); font-size: var(--text-small); }
.feed.compact li { padding: 11px 18px; }
@media (max-width: 700px) { .feed li { grid-template-columns: 70px 1fr; } .feed .ft { grid-column: 1 / -1; } }

/* --------------------------------------------------------------------------
   Footer and the persistent hub return link
   -------------------------------------------------------------------------- */

footer { padding: var(--spacing-40) 0 var(--spacing-64); }
footer .wrap { display: flex; justify-content: space-between; gap: var(--spacing-20); flex-wrap: wrap; }
footer p { color: var(--text-muted); margin: 0; }

/* The owner's sitemap — injected by gate.js into the owner session only:
   every page of the hub, grouped in one closing footer. The markup never
   ships to any other audience, so partner pages stay sealed. */
.sitemap { border-top: 1px solid var(--border-subtle); padding: var(--spacing-48) 0 var(--spacing-64); }
.sitemap .wrap { display: block; }
.sitemap .sitemap-note { color: var(--text-meta); margin: 0 0 var(--spacing-40); }
.sitemap-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--spacing-40) var(--spacing-32); }
.sitemap-cols > div { display: flex; flex-direction: column; gap: var(--spacing-8); }
.sitemap-cols .mono { color: var(--text-muted); margin: 0 0 var(--spacing-8); }
.sitemap-cols a { color: var(--text-secondary); font-size: var(--text-small); text-decoration: none; transition: color 0.25s; width: fit-content; }
.sitemap-cols a:hover, .sitemap-cols a[aria-current] { color: var(--accent-text); }

.hub-back {
  position: fixed; bottom: var(--spacing-20); left: var(--spacing-20); z-index: 90;
  font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase; text-decoration: none;
  padding: 10px 18px; border-radius: var(--radius-pill);
  background: var(--action-primary); color: var(--text-on-action); border: none;
}
.hub-back:hover { background: color-mix(in srgb, var(--action-primary) 88%, var(--color-ink-black)); }

/* --------------------------------------------------------------------------
   Work — the task layer (rendered by /js/work.js from /data/program.js)

   The app shell and every task-shaped component: the sidebar, the board
   lanes and cards, the list, the filter bar, the home tiles, the project
   page rows and the count badges. Same rules as the rest of the system:
   hairline surfaces, mint for status, ink for "now", violet only on the
   label voice and actions. A late date is the one thing allowed to shout,
   and it does it in ink, not in a third colour.
   -------------------------------------------------------------------------- */

/* Count badge — inside nav links, sidebar rows and lane headings. */
.navct, .ct {
  display: inline-block; margin-left: 8px; padding: 1px 8px; border-radius: var(--radius-pill);
  font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500;
  font-variant-numeric: tabular-nums; font-style: normal; letter-spacing: 0.04em;
  background: var(--surface-card); color: var(--text-secondary); vertical-align: 2px;
}
.navct { padding: 0 7px; font-size: 12px; }
.ct.late { background: var(--color-ink-black); color: var(--color-pure-white); }
.openct { display: block; margin-top: 4px; font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-meta); font-style: normal; }

/* ---- the sidebar shell ---- */
:root { --sidebar-w: 248px; }
.sidebar { display: none; }
@media (min-width: 1025px) {
  .sidebar {
    display: flex; flex-direction: column; gap: var(--spacing-28);
    position: fixed; top: 0; left: 0; bottom: 0; width: var(--sidebar-w); z-index: 40;
    background: var(--surface-canvas); border-right: 1px solid var(--border-subtle);
    padding: var(--spacing-24) var(--spacing-16) var(--spacing-20); overflow-y: auto; scrollbar-width: thin;
  }
  body:has(> .sidebar) { padding-left: var(--sidebar-w); }
  body:has(> .sidebar) .masthead { left: var(--sidebar-w); }
  body:has(> .sidebar) .navlinks { display: none; }
  body:has(> .sidebar) .hub-back { left: calc(var(--sidebar-w) + var(--spacing-20)); }
}
.sb-brand { display: flex; align-items: baseline; gap: var(--spacing-8); text-decoration: none; color: var(--text-primary); padding: 4px var(--spacing-12); }
.sb-brand .oca { font-weight: 600; font-size: var(--text-body); letter-spacing: var(--tracking-heading); }
.sb-brand .mono { color: var(--text-muted); font-size: 11px; }
.sb-group { display: flex; flex-direction: column; gap: 2px; }
.sb-lab { color: var(--text-muted); padding: 0 var(--spacing-12); margin-bottom: var(--spacing-8); }
.sb-item {
  display: flex; align-items: center; justify-content: space-between; gap: var(--spacing-8);
  padding: 7px var(--spacing-12); border-radius: 10px;
  color: var(--text-primary); text-decoration: none; font-size: var(--text-small);
  transition: background 0.2s, color 0.2s;
}
.sb-item:hover { background: var(--surface-card); }
.sb-item[aria-current] { background: var(--surface-card); color: var(--accent-text); }
.sb-item .sb-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sb-item .ct { margin-left: auto; }
.sb-item.me .sb-name::after { content: " · you"; color: var(--text-muted); font-size: var(--text-caption); }
.sb-foot { margin-top: auto; padding: var(--spacing-12) var(--spacing-12) 0; color: var(--text-muted); border-top: 1px solid var(--border-subtle); font-size: 11px; }

/* ---- toolbar: views + filters ---- */
.work-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--spacing-12) var(--spacing-16); margin-top: var(--spacing-32); }
.views { display: inline-flex; padding: 3px; border: 1px solid var(--border-hairline); border-radius: var(--radius-pill); }
.views button {
  font: inherit; font-size: var(--text-small); background: none; border: none; cursor: pointer;
  padding: 6px 14px; border-radius: var(--radius-pill); color: var(--text-secondary);
  transition: background 0.2s, color 0.2s;
}
.views button[aria-pressed="true"] { background: var(--color-ink-black); color: var(--color-pure-white); }
.filters { display: flex; flex-wrap: wrap; align-items: center; gap: var(--spacing-8); margin-left: auto; }
.sel {
  font: inherit; font-size: var(--text-small); color: var(--text-primary);
  background: var(--surface-canvas); border: 1px solid var(--border-hairline); border-radius: var(--radius-pill);
  padding: 6px 30px 6px 14px; appearance: none; -webkit-appearance: none; cursor: pointer;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23707070' stroke-width='1.4'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center;
}
.sel:focus-visible { outline: 1px solid var(--border-focus); outline-offset: 2px; }
.sel.me { color: var(--text-muted); }
.tog {
  font: inherit; font-size: var(--text-small); cursor: pointer;
  background: var(--surface-canvas); border: 1px solid var(--border-hairline); border-radius: var(--radius-pill);
  padding: 6px 14px; color: var(--text-secondary); transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.tog:hover { border-color: var(--border-focus); color: var(--accent-text); }
.tog[aria-pressed="true"] { background: color-mix(in srgb, var(--accent-status) 16%, transparent); border-color: var(--accent-status); color: var(--color-ash-gray); }
.work-line { color: var(--text-muted); margin: var(--spacing-20) 0 0; }
.work-sub { color: var(--text-muted); margin: var(--spacing-40) 0 0; }
[hidden] { display: none !important; }

/* ---- the board ---- */
.board { display: grid; grid-template-columns: repeat(5, minmax(200px, 1fr)); gap: var(--spacing-16); margin-top: var(--spacing-24); align-items: start; }
@media (max-width: 1400px) { .board { grid-template-columns: repeat(5, minmax(210px, 1fr)); overflow-x: auto; padding-bottom: var(--spacing-8); } }
@media (max-width: 900px) { .board { grid-template-columns: 1fr; } }
.lane { display: flex; flex-direction: column; gap: var(--spacing-12); min-width: 0; }
.lane-h { display: flex; align-items: center; gap: var(--spacing-8); font-size: var(--text-body); font-weight: 500; letter-spacing: var(--tracking-heading); padding: 0 4px; }
.lane-h .ct { margin-left: 0; }
.lane.doing .lane-h .ct { background: color-mix(in srgb, var(--accent-status) 18%, transparent); color: var(--color-ash-gray); }
.lane.waiting .lane-h .ct, .lane.decision .lane-h .ct { background: var(--color-ink-black); color: var(--color-pure-white); }
.lane-empty { color: var(--text-muted); font-size: var(--text-small); padding: var(--spacing-12) 4px; margin: 0; }

.card {
  display: flex; flex-direction: column; gap: 8px;
  border: 1px solid var(--border-hairline); border-radius: var(--radius-surface); background: var(--surface-canvas);
  padding: var(--spacing-16) var(--spacing-16) 14px;
  transition: border-color 0.25s;
}
.card:hover { border-color: var(--border-focus); }
.card.done { opacity: 0.62; }
.card.doing { border-color: var(--color-ink-black); }
.card .ctop { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.pchip { color: var(--action-primary); text-decoration: none; font-size: 11px; letter-spacing: 0.12em; }
.pchip:hover { text-decoration: underline; }
.kchip { font-size: 11px; letter-spacing: 0.12em; color: var(--text-primary); border: 1px solid var(--border-inactive); border-radius: var(--radius-pill); padding: 1px 8px; }
.card .ttl { font-weight: 500; font-size: var(--text-body); line-height: 1.35; letter-spacing: var(--tracking-heading); }
.card .what { color: var(--text-secondary); font-size: var(--text-small); line-height: 1.45; margin: 0; }
.card .wait { color: var(--text-primary); margin: 0; font-size: 11px; }
.card .meta { display: flex; justify-content: space-between; align-items: baseline; gap: var(--spacing-8); margin-top: 4px; border-top: 1px solid var(--border-subtle); padding-top: 10px; }
.card .own { font-size: var(--text-caption); color: var(--text-meta); text-align: right; }

/* Due states are shared by cards, rows and the list. */
.due { font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); white-space: nowrap; }
.due.soon { color: var(--color-ash-gray); }
.due.late { background: var(--color-ink-black); color: var(--color-pure-white); padding: 2px 8px; border-radius: var(--radius-pill); }
.due.done { color: var(--text-muted); }

/* ---- the list ---- */
.worklist { margin-top: var(--spacing-24); }
.worklist td.task b { display: block; font-weight: 500; }
.worklist td.task .note { display: block; font-size: var(--text-small); color: var(--text-secondary); margin-top: 3px; }
.worklist td.task .note.wait { color: var(--text-primary); }
.worklist td.proj a { text-decoration: none; }
.worklist td.own { color: var(--text-meta); font-size: var(--text-small); white-space: nowrap; }
.worklist td.due { vertical-align: middle; }
.worklist tr.done td { color: var(--text-muted); }
.worklist tr.done td b { color: var(--text-meta); }
.worklist td.empty { color: var(--text-muted); }

/* ---- rows: project "Next" and the home list ---- */
.tasklist { margin-top: var(--spacing-32); border: 1px solid var(--border-hairline); border-radius: var(--radius-surface); overflow: hidden; }
.tl-line { color: var(--text-muted); margin: 0; padding: 14px 18px; border-bottom: 1px solid var(--border-subtle); }
.tl-foot { margin: 0; padding: 14px 18px; border-top: 1px solid var(--border-subtle); }
.trow { display: grid; grid-template-columns: 120px 1fr auto auto; gap: var(--spacing-16); align-items: start; padding: 14px 18px; border-top: 1px solid var(--border-subtle); }
.trow:first-child, .tl-line + .trow { border-top: none; }
.trow.done { opacity: 0.62; }
.trow .st { justify-self: start; }
.trow .tb b { display: block; font-weight: 500; }
.trow .tb .what { display: block; color: var(--text-secondary); font-size: var(--text-small); line-height: 1.45; margin-top: 3px; }
.trow .tb .pchip { display: inline-block; margin-top: 6px; }
.trow .who { border: none; padding: 0; color: var(--text-meta); text-transform: none; letter-spacing: 0; font-family: var(--font-grotesk); font-size: var(--text-small); white-space: normal; text-align: right; max-width: 140px; }
.trow .due { padding-top: 3px; }
@media (max-width: 700px) { .trow { grid-template-columns: 1fr; gap: 6px; } .trow .who { text-align: left; } }
.mine .mine-h { display: flex; justify-content: space-between; align-items: baseline; gap: var(--spacing-16); flex-wrap: wrap; color: var(--text-muted); }
.mine .tasklist { margin-top: var(--spacing-12); }
.mine .lane-empty { padding: var(--spacing-16) 18px; }

/* Decisions on a project page: the question list, with who decides. */
.qs .qmeta { display: flex; gap: var(--spacing-12); flex-wrap: wrap; margin-top: 6px; color: var(--text-meta); }
.qs b { color: var(--text-primary); font-weight: 500; }
.qs li.done { color: var(--text-muted); }

/* ---- home tiles ---- */
.dash { margin-top: var(--spacing-24); }
.dash .cell { text-decoration: none; color: var(--text-primary); display: flex; flex-direction: column; transition: background 0.3s; }
.dash .cell:hover { background: var(--surface-card); }
.dash .cell .v { font-size: var(--text-heading); font-weight: var(--weight-regular); line-height: 1.1; font-variant-numeric: tabular-nums; }
.dash .cell .v.hot { color: var(--action-primary); }
.dash .cell .k { color: var(--text-muted); margin-top: var(--spacing-8); }

/* Compact hero for working pages: the state line, then the tool. */
.hero.compact { padding: 130px 0 var(--spacing-32); }
.hero.compact h1 { font-size: clamp(1.8rem, 3.6vw, 2.6rem); line-height: 1.1; }
