/* ============================================================================
   tabs.css — the vertical rail for The Company OS Method cluster, plus the
   hero breadcrumb those ten routes share.
   ----------------------------------------------------------------------------
   Loaded only by the ten routes that share the rail (the page module exports
   `css`), so the shared sheets stay the size they are. Everything is scoped
   under .tabs so it cannot leak into another grid — with one named exception,
   .tabs-crumb, which renders in the page hero above the grid and is documented
   at its rule below.

   The rail rows are <a> links to the sibling routes, not tab buttons: each
   route is a distinct document now (see src/pages/ai-system.mjs for why), and
   the current row is marked with aria-current="page". The visual treatment is
   unchanged from the tab era on purpose — same rail, same active row — so the
   consolidation reads the same while every URL carries only its own content.

   The pattern was specified from a Flowbite vertical-tab example. That example
   is Tailwind and this site has no Tailwind, so nothing was pasted: the same
   shape is rebuilt here on the tokens in tokens.css and the conventions in
   shell3.css.

   ONE DELIBERATE DEPARTURE FROM THE SPEC, AND THE MEASUREMENT BEHIND IT.
   Recomputed for Brand OS v3.0 "Atlas", 2026-08-13. The brief asked for the
   active tab to be --spark with white text. Paper White on True North
   (#FFFFFF on #FF6B1C) measures 2.85:1. AA needs 4.5:1 for text and 3:1 even
   for large text, so it fails at every size, and v3 raises that from an
   observation to the one explicitly labelled LAW in the whole colour section:
   True North is "never type on white at any size. On light grounds it is a
   fill, a rule, or a shape." A site whose argument is that it writes its
   contrast failures down as rules rather than nudging them away cannot ship
   that combination in its own navigation.

   So the active tab is Midnight Green filled with Paper White text, which
   measures 15.83:1 — the single pair v3 collapsed the old five-dark ladder
   into, and the same treatment the site's existing tab pattern already uses.
   The brand colour still marks the active row, in the one role it is legal
   for on a dark ground: a shape, not type. It is the 3px edge bar and the
   icon. Identical read at a glance, legible for everyone, no law broken.

   Every ratio in this file was recomputed against the v3 hexes, not carried
   over. The two that moved: 11.9:1 -> 15.83:1 for ink on paper, because both
   ends of that pair changed, and 4.0:1 -> 5.56:1 for True North on the dark
   ground, which is the one place in the whole palette that GAINED — at 5.56:1
   it is now legal for body text on Midnight Green.
   ========================================================================= */

.tabs {
  display: grid;
  gap: 22px;
  align-items: start;
}

@media (min-width: 768px) {
  .tabs { grid-template-columns: 258px minmax(0, 1fr); gap: 30px; }
}

/* ---- the rail -------------------------------------------------------------
   Vertical from 768px up. Below that it becomes a horizontal strip that
   scrolls, because ten stacked rows above every panel would push the content
   off a phone screen entirely. */
.tabs-rail {
  display: flex;
  gap: 4px;
  flex-direction: row;
  overflow-x: auto;
  overflow-y: hidden;
  padding-bottom: 6px;
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
}

@media (min-width: 768px) {
  .tabs-rail {
    flex-direction: column;
    overflow: visible;
    padding-bottom: 0;
    position: sticky;
    top: calc(var(--hd-h) + 14px);
  }
}

.tabs-tab {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex: none;
  width: auto;
  text-align: left;
  font-family: var(--font-display);
  font-size: var(--step--1);
  font-weight: 600;
  line-height: 1.25;
  color: var(--muted);
  /* These rows are links now, but they must not read as prose links: the rail
     is navigation chrome, and ten underlines would be ten shouts. */
  text-decoration: none;
  background: transparent;
  border: 1px solid transparent;
  border-left: 3px solid transparent;
  border-radius: var(--r);
  padding: 11px 14px;
  white-space: nowrap;
  scroll-snap-align: start;
  transition: background var(--t-hover) var(--ease), color var(--t-hover) var(--ease), border-color var(--t-hover) var(--ease);
}

@media (min-width: 768px) {
  .tabs-tab { width: 100%; white-space: normal; }
}

.tabs-tab:hover { background: var(--band); color: var(--ink); }
.tabs-tab:active { transition-duration: var(--t-press); }

.tabs-tab[aria-current="page"] {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
  border-left-color: var(--spark);
}

/* The icon is the second place the brand colour marks the active row, and on
   the Midnight fill it is a shape on a dark ground — where True North measures
   5.56:1 and would be legal even as type. */
.tabs-tab[aria-current="page"] .tabs-ic { color: var(--spark); }

/* The focus ring is 2px Surface Steel, never a glow (§8.7). Steel measures
   7.44:1 on white, which is what an unselected tab sits on.

   The current row is Midnight, and Steel on Midnight is 2.13:1 — v3 writes
   that failure down as a law rather than nudging it. So the ring on the
   current row switches to Paper White at 15.83:1. It is the same 2px ring,
   not a second style: only the ground changed, so only the colour did. */
.tabs-tab:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.tabs-tab[aria-current="page"]:focus-visible { outline-color: var(--paper); }

.tabs-ic {
  width: 16px;
  height: 16px;
  flex: none;
  color: var(--faint);
  transition: color var(--t-hover) var(--ease);
}
.tabs-tab:hover .tabs-ic { color: var(--primary); }

/* A number that says how far down the rail you are. Role-bound colours
   (2026-08-25): Surface Steel at rest, which is exactly what a mono figure
   on a light ground takes, at 7.4:1 full strength rather than dimmed
   through an opacity that quietly broke the ratio. On the current row the
   ground is Midnight, where Steel fails by law, so the numeral goes spark:
   5.6:1 there, legal even as type. */
.tabs-n {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .08em;
  color: var(--chrome);
  display: none;
}
.tabs-tab[aria-current="page"] .tabs-n { color: var(--spark); }
@media (min-width: 768px) { .tabs-n { display: inline; } }

/* ---- the Company OS breadcrumb -------------------------------------------
   One line between the h1 and the lede on all ten routes, naming where the
   page sits inside the Company OS. The one selector in this file not scoped
   under .tabs, because it renders in the page hero above the grid — still
   contained, because this sheet loads only on the ten routes that carry it.
   It sits on the hero's dark ground, so it takes --dim-d (the dark-ground dim
   token the lede already uses there) rather than --muted, which is mixed for
   light grounds. Mono and dimmed on purpose: it is wayfinding, not a second
   subtitle, and it must not compete with the lede below it. */
.tabs-crumb {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .04em;
  line-height: 1.5;
  color: var(--dim-d);
  margin: 10px 0 0;
  max-width: 68ch;
}

/* ---- the panel ----------------------------------------------------------
   One per page now: the route's own content, in the card the tab panels used
   to share. Keeping the class keeps every content rule below working
   unchanged. */
.tabs-panel {
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  padding: clamp(22px, 3.2vw, 40px);
  min-width: 0;
}

.tabs-panel > :first-child { margin-top: 0; }
.tabs-panel h2 { font-size: var(--step-2); letter-spacing: -.018em; margin-top: 2em; }
.tabs-panel h2:first-of-type { margin-top: 0; }
.tabs-panel h3 { margin-top: 1.6em; }
.tabs-panel .card h3 { margin-top: 0; }
.tabs-panel p { max-width: var(--measure); }
.tabs-panel .grid p,
.tabs-panel .note p { max-width: none; }

/* The panel entrance animation left with the client-side switching: a real
   navigation paints a whole new page, and animating one card inside it would
   read as a glitch, not a transition. */
@media (prefers-reduced-motion: reduce) {
  .tabs-tab { transition: none; }
}

/* ============================================================================
   THE AGENT ROSTER — rendered inside the Agents panel.
   ----------------------------------------------------------------------------
   Two rules the markup exists to enforce:

   1. The refusal renders at the same weight as the role. It is the through-line
      of the whole roster, not a footnote, because a refusal is testable and an
      aspiration is not.
   2. No status chip uses the orange accent. Orange is the site's one "look
      here" colour, and if RUNNING wore it then thirty rows would compete with
      every real call to action on the page. v3 turns that judgement into a
      count: "one True North button per view. A second primary means the first
      one was not primary."

   ---- THE v3 REBUILD OF THE FIVE STATUSES -----------------------------------

   Three of the five were carried by tokens v3 deletes. --bronze is gone with
   its whole warm-secondary family (seventh-colour violation) and --flag is
   gone because "there is no red in this palette" — errors and refusals are
   carried by a 2px Midnight Green border, the glyph, and a Plex Mono line,
   never by a hue.

   The five now run on the pattern v3 publishes for status (P02): ON A LIGHT
   GROUND THE DOT CARRIES THE COLOUR AND THE LABEL DOES NOT. That is the rule
   that lets the signal pair appear here at all — status is the one thing
   Landfall and Meridian are FOR — while keeping every label above 6.4:1,
   which neither signal colour manages on white (1.65:1 and 3.01:1).

     status      dot            label       container
     running     Meridian       Midnight    Meridian wash + Meridian hairline
     built       Landfall       Steel       hairline only
     gated       Steel          muted       --band fill, hairline
     buildable   hollow ring    faint       dashed hairline, no fill
     blocked     Midnight       Midnight    2px Midnight border, no fill

   They still separate in greyscale and for anyone who does not distinguish
   these hues, because the container does the work: wash, hairline, band,
   dashed, and a doubled border are five different objects before they are five
   different colours. Blocked is the heaviest thing on the page, which is the
   correct weight for a refusal and the reason it never needed to be red.
   ========================================================================= */

.ledger {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(148px, 100%), 1fr));
  gap: 10px;
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
}

.ledger li {
  border: 1px solid var(--hairline);
  border-radius: var(--r);
  padding: 14px 15px;
  background: var(--card);
}

.ledger .n {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--step-3);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

/* The label is inline-flex so it can carry the dot that now holds the colour.
   --st-dot defaults to nothing visible; the two statuses that get a signal
   colour set it, and the other three separate on the container instead. */
.ledger .k {
  /* flex, not inline-flex: this label used to be display:block and has to keep
     breaking the line after the figure above it. */
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  margin-top: 8px;
}
.ledger .k::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--st-dot, transparent);
  box-shadow: inset 0 0 0 1px var(--st-dot, var(--hairline));
}

.ledger .b { display: block; font-size: 12px; color: var(--muted); margin-top: 6px; }

.ledger li.is-running {
  --st-dot: var(--beacon);
  border-color: color-mix(in srgb, var(--beacon) 40%, transparent);
  background: color-mix(in srgb, var(--beacon) 7%, var(--card));
}
.ledger li.is-running .k   { color: var(--ink); }
.ledger li.is-built        { --st-dot: var(--signal); }
.ledger li.is-built .k     { color: var(--primary); }
.ledger li.is-gated        { --st-dot: var(--chrome); background: var(--band); }
.ledger li.is-gated .k     { color: var(--muted); }
.ledger li.is-buildable    { border-style: dashed; }
.ledger li.is-buildable .k { color: var(--faint); }
/* No red anywhere in v3. A blocked agent is the only cell with a doubled
   Midnight border, which reads heavier than any of the four above it. */
.ledger li.is-blocked      { --st-dot: var(--ink); border: 2px solid var(--ink); padding: 13px 14px; }
.ledger li.is-blocked .k   { color: var(--ink); }

.dept { margin-top: 44px; }
.dept-h { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px; }
.dept-id {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .12em;
  color: var(--faint);
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  padding: 2px 7px;
}
.dept-remit { color: var(--muted); font-size: var(--step--1); }
.dept-drop { font-size: var(--step--1); color: var(--faint); }
.dept-drop b { color: var(--muted); font-weight: 600; }

.ag-list { display: grid; gap: 10px; margin-top: 18px; }

.ag {
  border: 1px solid var(--hairline);
  border-radius: var(--r);
  background: var(--card);
  padding: 16px 18px;
}

.ag-top { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
.ag-top h4 { font-family: var(--font-display); font-size: var(--step-0); font-weight: 700; margin: 0; }

/* One glyph per row. It is a tile rather than a bare icon so that forty-five
   rows read as a list of things rather than a wall of text with decoration
   in the margin. The wash is --primary, never --spark: the status chip to the
   right of it is already carrying meaning, and two coloured objects competing
   in one line is how a row stops being scannable. */
.ag-ic {
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  display: inline-grid;
  place-items: center;
  background: var(--wash-primary);
  border: 1px solid color-mix(in srgb, var(--primary) 18%, transparent);
  color: var(--primary);
}
.ag-ic .ic { width: 17px; height: 17px; }
/* --mist is one of the eleven tints v3 absorbed into --band and --page. This
   is a chip on a card, so it takes --band: 8% Surface Steel on white, with
   Steel type over it at 6.59:1. */
.ag-cmd {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--primary);
  background: var(--band);
  border-radius: var(--r-sm);
  padding: 2px 8px;
}
.ag-cmd.is-quiet { color: var(--faint); background: transparent; border: 1px dashed var(--hairline); }

/* Role and refusal: identical type, identical spacing, one label apiece. The
   only difference between them is which word starts the line. */
.ag-line { display: grid; grid-template-columns: 74px minmax(0, 1fr); gap: 12px; margin-top: 12px; align-items: start; }
.ag-line > span:first-child {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--faint);
  padding-top: 3px;
}
.ag-line > p { margin: 0; font-size: var(--step--1); color: var(--ink); max-width: none; }
/* The REFUSES label was red. There is no red. It goes to full Midnight Green
   at 15.83:1 against the card, which makes it the darkest label in the row —
   the correct emphasis for the line that carries the whole roster's argument,
   and the same "weight, not hue" move v3 makes for every failure state. */
.ag-line.is-no > span:first-child { color: var(--ink); font-weight: 600; }
/* The skill rows use the same two-line anatomy as the agent rows: what it does,
   and the thing it is answerable to. For an agent that is the refusal; for a
   skill it is the reference it adapts, which is the equivalent constraint. */
.ag-line.is-ref > span:first-child { color: var(--primary); }
.ag-line.is-ref > p { color: var(--muted); }
.ag-note { margin: 10px 0 0; font-size: 12px; color: var(--muted); max-width: none; }

/* The chip, rebuilt on P02. The dot is the only thing allowed to be Landfall
   or Meridian here, because the chip sits on a white card and "signal colours
   never set small type on white". */
.ag-st {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  border-radius: var(--pill);
  padding: 3px 10px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.ag-st::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--st-dot, transparent);
  box-shadow: inset 0 0 0 1px var(--st-dot, var(--hairline));
}
.ag-st.is-running   { --st-dot: var(--beacon); color: var(--ink);     background: color-mix(in srgb, var(--beacon) 7%, var(--card)); border-color: color-mix(in srgb, var(--beacon) 34%, transparent); }
.ag-st.is-built     { --st-dot: var(--signal); color: var(--primary); background: var(--card); border-color: var(--hairline); }
.ag-st.is-gated     { --st-dot: var(--chrome); color: var(--muted);   background: var(--band); border-color: var(--hairline); }
.ag-st.is-buildable { color: var(--faint);     background: transparent; border-color: var(--hairline); border-style: dashed; }
/* the heaviest chip in the row, and the only 2px border on the page */
.ag-st.is-blocked   { --st-dot: var(--ink); color: var(--ink); background: transparent; border: 2px solid var(--ink); padding: 2px 9px; }

@media (max-width: 520px) {
  .ag-st { margin-left: 0; }
  .ag-line { grid-template-columns: 1fr; gap: 2px; }
}

/* ============================================================================
   THE REFUSAL DEMO — folded into the Guardrails panel.
   ----------------------------------------------------------------------------
   It used to be its own route with its own nested tab strip. Nested tabs inside
   a tabpanel is a bad experience for keyboard users and a worse one for screen
   readers, and the four answers read better together anyway: two builds beside
   two refusals is the comparison, and hiding three of them behind a control was
   hiding exactly that.
   ========================================================================= */
.rf { margin-top: 22px; }
.rf + .rf { margin-top: 18px; }

.rf-req {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  line-height: 1.6;
  background: var(--band);
  border-radius: var(--r);
  padding: 15px 17px;
  color: var(--ink);
}
/* --faint on --band measures 4.49:1, a hair under AA at 10px. It steps to
   --muted, 5.72:1 on the same fill. */
.rf-req::before {
  content: "THE REQUEST";
  display: block;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .12em;
  color: var(--muted);
  margin-bottom: 8px;
}

.rf-res {
  border-left: 3px solid var(--primary);
  border-radius: 0 var(--r) var(--r) 0;
  background: var(--wash-primary);
  padding: 15px 17px 15px 19px;
  margin-top: 10px;
}
/* A refusal is not an error and it is certainly not red — v3 has neither
   colour available. It is marked by weight: the accepted answer carries a 3px
   Surface Steel rule and a Steel wash, the refused one carries a 3px Midnight
   Green rule and no wash at all. The absence is the point. */
.rf-res.is-no { border-left-color: var(--ink); border-left-width: 4px; background: transparent; }
.rf-res::before {
  content: "THE SYSTEM ANSWERS";
  display: block;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .12em;
  color: var(--faint);
  margin-bottom: 8px;
}
.rf-res p { margin: 0; font-size: var(--step--1); max-width: none; }

.rf-verdict {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: 3px 10px;
  border-radius: var(--pill);
  margin-bottom: 10px;
}
.rf-verdict.is-yes { background: var(--card); color: var(--primary); border: 1px solid color-mix(in srgb, var(--primary) 34%, transparent); }
.rf-verdict.is-no  { background: var(--card); color: var(--ink);     border: 2px solid var(--ink); padding: 2px 9px; }

.rf-why { font-size: var(--step--1); color: var(--muted); margin-top: 10px; max-width: none; }
.rf-why b { color: var(--ink); }

/* ---- the intake form list, folded into The Intake panel ------------------ */
.intake { list-style: none; margin: 0; padding: 0; }
.intake li {
  padding: 8px 0;
  border-top: 1px solid var(--hairline-soft);
  font-size: .9rem;
  color: var(--ink);
}
.intake li:first-child { border-top: 0; }
/* The required-field marker. It was --spark-ink, v2's burnt orange, which
   existed only so that something orange-flavoured could be legal as type on
   light. v3 deletes it and offers no replacement: on light, True North is a
   fill, a rule or a shape, full stop. A required marker is type, so it takes
   the label colour v3 does assign on light — Surface Steel, 7.44:1. */
.req { color: var(--primary); text-decoration: none; cursor: help; font-size: .85em; margin-right: 6px; }
