/* ============================================================================
   PANTEREX — THE INSTRUMENT
   "PANTEREX is an intelligence instrument built to hunt in darkness."

   WHY THIS FILE EXISTS RATHER THAN A PATCH TO px-nocturnal.css
     The previous surface failed visual acceptance on COMPOSITION, not palette.
     It was a vertical document: sections divided by full-width rules, labels
     stacked above values, every region wrapped in a rectangle. Retuning colours
     inside that structure would not have changed what it is. This layer defines
     a different spatial language and the Decision Room is rebuilt on it, so the
     old report-era classes simply stop being used rather than being fought.

   THE SPATIAL RULES, WHICH ARE THE ACTUAL SUBJECT
     1. GROUP IN CELLS, DO NOT SEPARATE WITH RULES. Related facts sit together in
        a bounded region; unrelated ones sit in a different one. A horizontal rule
        across the full width is a paragraph break in a document, and this is not
        a document.
     2. DIVIDE WITH THIN VERTICALS. A row of figures is separated by hairline
        verticals, never by boxing each figure.
     3. TYPOGRAPHY CARRIES HIERARCHY. The decision is large because it is the
        most important thing on screen, not because it has a coloured background.
     4. NEGATIVE SPACE IS STRUCTURAL. Space between groups does the work that
        borders were doing.
     5. THE CANVAS IS THE STAGE. The graph is a primary product object and fills
        its region edge to edge.

   COLOUR DISCIPLINE (unchanged semantics, stricter application)
     cyan = OBSERVED · ultraviolet = INFERRED · tungsten = FOCUS
     orange = ANOMALY · red = DANGER · emerald = HEALTHY · ash = context/unknown
     Tungsten is an OPTICAL event — an iris ring, a focus edge, one primary
     action — never a filled background behind a row or a panel. The surface
     stays ~85-90% neutral.
   ============================================================================ */

/* ── ground ───────────────────────────────────────────────────────────────── */
.px-i {
  --i-rail: 232px;
  --i-hair: rgba(255,255,255,.055);
  --i-hair-hi: rgba(255,255,255,.10);
  --i-cell: rgba(255,255,255,.014);
  --i-gap: 14px;

  background: var(--nx-obsidian);
  color: var(--nx-bone);
  font-family: var(--nx-sans);
  display: grid;
  grid-template-columns: var(--i-rail) minmax(0, 1fr);

  /* THE INSTRUMENT OCCUPIES THE VIEWPORT AND DOES NOT SCROLL AS A PAGE.
     Left to grow, the field took 895px of a 908px viewport and pushed the lenses, the decision tape and
     the actions entirely below the fold — the screen became a long document again, which is the exact
     failure this pass exists to correct. The frame is fixed; the decision panel scrolls inside it. */
  /* dvh, not vh: on a phone the URL bar makes 100vh TALLER than what you can see, so the
     last rows of a fixed frame sit permanently under the browser chrome. */
  height: 100vh; height: 100dvh; overflow: hidden;
}
:root[data-px-theme="field"] .px-i { --i-hair: rgba(0,0,0,.085); --i-hair-hi: rgba(0,0,0,.14); --i-cell: rgba(0,0,0,.016); }

/* A cell is the unit of grouping. Its border is close to invisible — present
   enough to bound a region, never enough to read as a card. */
.px-cell { border: 1px solid var(--i-hair); background: var(--i-cell); border-radius: 2px; }
.px-cell-h { display: flex; align-items: center; gap: 10px; padding: 9px 13px; border-bottom: 1px solid var(--i-hair); }
.px-cell-b { padding: 13px; }

/* ── type ─────────────────────────────────────────────────────────────────── */
/* DISPLAY is used sparingly and only for identity and the decision itself. */
.px-display {
  font-family: var(--nx-sans); font-weight: 600;
  letter-spacing: .10em; text-transform: uppercase;
  color: var(--nx-bone-hi); line-height: .95;
  font-stretch: condensed;
}
.px-label {
  font-family: var(--nx-mono); font-size: 9.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--nx-ash); white-space: nowrap;
}
.px-tele { font-family: var(--nx-mono); font-size: 11px; color: var(--nx-ash-2); }
.px-body { font-size: 13px; line-height: 1.72; color: var(--nx-bone); }
.px-num  { font-family: var(--nx-mono); font-variant-numeric: tabular-nums; color: var(--nx-bone-hi); }

/* ── the instrument spine ─────────────────────────────────────────────────── */
.px-rail {
  border-right: 1px solid var(--i-hair);
  background: var(--nx-carbon);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; height: 100dvh; overflow-y: auto;
  overscroll-behavior: contain;
}
.px-rail-brand { padding: 30px 20px 24px; text-align: center; }
/* The eye is the brand's primary object and must actually read at rail size. The asset is a fine
   outline drawn for large use, so it is given size and full luminance rather than being tucked in. */
.px-rail-eye { width: 96px; height: auto; margin: 0 auto 16px; display: block; opacity: 1;
  filter: brightness(1.35) contrast(1.1); }
:root[data-px-theme="field"] .px-rail-eye { filter: invert(1) contrast(1.15) brightness(.9); }
.px-rail-word { font-size: 21px; letter-spacing: .30em; text-indent: .30em; }
.px-rail-chain {
  margin-top: 9px; font-family: var(--nx-mono); font-size: 9px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--nx-ash);
}
.px-rail-chain i { font-style: normal; color: var(--nx-healthy); margin-left: 5px; }

.px-nav { padding: 6px 0; }
/* ACTIVE IS A THIN TUNGSTEN EDGE, NOT A FILLED STRIP. A filled row reads as a
   selected item in a chat app; an edge marker reads as an instrument setting. */
.px-nav a {
  display: flex; align-items: center; gap: 11px;
  padding: 11px 20px 11px 19px;
  border-left: 1px solid transparent;
  color: var(--nx-ash-2); text-decoration: none;
  font-size: 12.5px; letter-spacing: .085em; text-transform: uppercase;
  transition: color .16s ease, border-color .16s ease;
}
.px-nav a + a { border-top: 1px solid var(--i-hair); }
.px-nav a:hover { color: var(--nx-bone); }
.px-nav a[aria-current="page"] { color: var(--nx-bone-hi); border-left-color: var(--nx-tungsten); }
.px-nav a:focus-visible { outline: 1px solid var(--nx-tungsten); outline-offset: -2px; color: var(--nx-bone-hi); }
/* No bullet before a destination. A dot in front of every item reads as a list, and §12 asks for
   minimal or no icons on primary navigation — the active marker alone carries the state. */
.px-nav-dot { display: none; }
.px-nav-n { margin-left: auto; font-family: var(--nx-mono); font-size: 10.5px; color: var(--nx-ash); }

.px-rail-foot { margin-top: auto; padding: 16px 18px 18px; border-top: 1px solid var(--i-hair); }
.px-rail-meta { margin-top: 12px; font-family: var(--nx-mono); font-size: 9px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--nx-ash); line-height: 1.7; }
.px-rail-state {
  display: flex; align-items: center; gap: 7px;
  font-family: var(--nx-mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--nx-ash);
}
.px-rail-state b { font-weight: 400; color: var(--nx-bone); }
.px-pulse { width: 5px; height: 5px; border-radius: 50%; flex: none; background: var(--nx-ash); }
.px-pulse[data-on="1"] { background: var(--nx-healthy); box-shadow: 0 0 0 3px color-mix(in srgb, var(--nx-healthy) 18%, transparent); }
.px-pulse[data-on="0"] { background: var(--nx-danger); }
.px-pulse[data-on="?"] { background: var(--nx-gunmetal-2); }

/* ── main ─────────────────────────────────────────────────────────────────── */
/* ── THE DESTINATION SCROLLING CONTRACT ───────────────────────────────────────
   The instrument frame is fixed at one viewport (.px-i above). That is correct for
   a decision room and WRONG for everything else, and for a while it was applied to
   everything: WHALES, POSITIONS, ACCOUNT, PACK, BETA and INTELLIGENCE all render
   content taller than the screen into a container with `overflow: hidden`, inside a
   page that cannot scroll either. The content below the fold was unreachable, and
   the browser answered a wheel event it could not consume by bouncing the whole
   document. That is the trap.

   The fix is not `overflow: auto` on one surface. It is an explicit contract, set
   per destination by the router:

     data-mode="stage"  a genuine viewport-oriented environment — the decision room.
                        The frame holds; specific regions scroll INSIDE it.

     data-mode="flow"   content whose natural height exceeds the viewport. The
                        destination itself is the single vertical scroll owner.

   ONE primary vertical scroll owner per destination. A flow destination must not
   contain another full-height same-axis scroller, or the wheel gets swallowed by
   whichever one the pointer happens to be over. */
.px-main { min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }

.px-main[data-mode="flow"] {
  display: block;                     /* natural document flow — children size to content */
  overflow-y: auto; overflow-x: hidden;
  /* The home indicator overlaps the last row of a scrolling destination. The scroller ends above it,
     and scroll-padding keeps a focused control clear of it too. 0px where there is no indicator. */
  padding-bottom: var(--px-safe-bottom);
  scroll-padding-bottom: var(--px-safe-bottom);
  /* The scroll chain stops here. Without this, reaching the end of the destination
     hands the remaining delta to the document, which cannot move — and the browser
     renders that refusal as a rubber-band. */
  overscroll-behavior-y: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-gutter: stable;
  scrollbar-width: thin;
}
/* In FLOW the destination is the scroller, so an inner .px-scroll must NOT also be
   one — two nested same-axis scrollers is precisely the trap being removed. */
.px-main[data-mode="flow"] .px-scroll {
  overflow: visible; flex: none; min-height: 0; max-height: none;
}
.px-main[data-mode="stage"] { display: flex; overflow: hidden; }
.px-readout .px-label b { color: var(--nx-bone); font-weight: 400; }

.px-topbar {
  display: flex; align-items: center; gap: 16px;
  padding: 0 24px; height: 46px; flex: none;
  border-bottom: 1px solid var(--i-hair);
}
.px-back {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--nx-ash-2); text-decoration: none;
  font-family: var(--nx-mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
}
.px-back:hover { color: var(--nx-bone-hi); }
/* A run of readings separated by hairline verticals — never boxed individually. */
.px-readout { margin-left: auto; display: flex; align-items: center; }
.px-readout > * { padding: 0 16px; border-left: 1px solid var(--i-hair); }
.px-readout > *:first-child { border-left: 0; }

.px-head { padding: 18px 24px 16px; border-bottom: 1px solid var(--i-hair); flex: none; }
/* .px-label sets white-space: nowrap so a figure never breaks mid-row. A page SUBTITLE is
   prose and must wrap — HUNT's ran 126px past a 390 viewport because it inherited the rule. */
.px-head-sub { margin-top: 7px; white-space: normal; max-width: 62ch; }
.px-head-row { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.px-head-id { font-size: 38px; letter-spacing: .07em; }
.px-head-meta { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.px-head-right { margin-left: auto; text-align: right; }

/* State reads as a word with a dot, not as a filled badge. */
.px-state { display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--nx-mono); font-size: 11px; letter-spacing: .13em; text-transform: uppercase; }
.px-state::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.px-state[data-s="watching"]             { color: var(--px-observed); }
.px-state[data-s="investigating"]        { color: var(--px-observed); }
.px-state[data-s="rejected"]             { color: var(--nx-danger); }
.px-state[data-s="qualified_for_review"] { color: var(--nx-healthy); }
.px-state[data-s="qualified"]            { color: var(--nx-healthy); }
.px-state[data-s="expired"]              { color: var(--nx-ash); }
.px-state[data-s="discovered"]           { color: var(--nx-ash-2); }

/* ── the stage ────────────────────────────────────────────────────────────── */
.px-stage {
  flex: 1; min-height: 0; overflow: hidden;
  display: grid; grid-template-columns: minmax(0, 58fr) minmax(400px, 42fr);
}
.px-stage-l { min-width: 0; min-height: 0; display: flex; flex-direction: column; border-right: 1px solid var(--i-hair); overflow: hidden; }
.px-stage-r { min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }

/* THE CANVAS IS THE STAGE. No card, no padding ring, no inner border — the
   field runs to the edges of its region and the chrome floats on top of it. */
.px-field { position: relative; flex: 1; min-height: 0; background: var(--nx-obsidian); overflow: hidden; }
.px-field canvas { display: block; }
.px-field-tl { position: absolute; left: 16px; top: 14px; display: flex; align-items: center; gap: 16px; pointer-events: none; }
.px-field-bl { position: absolute; left: 16px; bottom: 14px; display: flex; gap: 6px; }
.px-field-br { position: absolute; right: 16px; bottom: 14px; }
.px-legend { display: flex; gap: 14px; }
.px-legend span { display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--nx-mono); font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--nx-ash); }
.px-legend i { width: 5px; height: 5px; border-radius: 50%; font-style: normal; }

.px-tool {
  appearance: none; cursor: pointer; width: 27px; height: 27px;
  display: inline-flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--nx-carbon) 86%, transparent);
  border: 1px solid var(--i-hair-hi); border-radius: 2px;
  color: var(--nx-ash-2); font-family: var(--nx-mono); font-size: 12px; line-height: 1;
}
.px-tool:hover { color: var(--nx-bone-hi); border-color: var(--nx-tungsten-dim); }
.px-tool:focus-visible { outline: 1px solid var(--nx-tungsten); outline-offset: 1px; }

/* THE SPARSE STATE. A lone token in an empty rectangle reads as a broken
   component. Unresolved regions are indicated instead, so an empty field says
   "the environment has not resolved yet" rather than "nothing rendered". */
.px-unresolved {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(closest-side at 50% 50%, transparent 26%, color-mix(in srgb, var(--nx-ash) 5%, transparent) 78%, transparent 100%);
  opacity: .55;
}
.px-unresolved::after {
  content: ''; position: absolute; inset: 12%;
  border: 1px dashed var(--i-hair); border-radius: 50%;
}
.px-field-note {
  position: absolute; left: 50%; bottom: 58px; transform: translateX(-50%);
  text-align: center; max-width: 380px; pointer-events: none;
}

/* ── tabs: cyan underline, never a pill ──────────────────────────────────── */
.px-tabs { display: flex; gap: 0; border-top: 1px solid var(--i-hair); flex: none; }
.px-tabs button {
  appearance: none; cursor: pointer; background: none;
  border: 0; border-bottom: 2px solid transparent;
  padding: 13px 18px; color: var(--nx-ash);
  font-family: var(--nx-mono); font-size: 10px; letter-spacing: .15em; text-transform: uppercase;
}
.px-tabs button:hover { color: var(--nx-bone); }
.px-tabs button[aria-selected="true"] { color: var(--nx-bone-hi); border-bottom-color: var(--px-observed); }
.px-tabs button:focus-visible { outline: 1px solid var(--nx-tungsten); outline-offset: -3px; }
.px-tabpanel { padding: 16px 20px 22px; overflow-y: auto; max-height: 34vh; flex: none; }

/* ── the decision ─────────────────────────────────────────────────────────── */
.px-decision { overflow-y: auto; flex: 1; min-height: 0; scrollbar-width: thin; }
.px-decision::-webkit-scrollbar { width: 7px; }
.px-decision::-webkit-scrollbar-thumb { background: var(--nx-gunmetal); border-radius: 4px; }

.px-verdict { padding: 20px 22px 18px; border-bottom: 1px solid var(--i-hair); }
.px-verdict-word { font-size: 33px; letter-spacing: .07em; margin: 9px 0 0; }
.px-verdict-word[data-s="watching"]             { color: var(--px-observed); }
.px-verdict-word[data-s="investigating"]        { color: var(--px-observed); }
.px-verdict-word[data-s="rejected"]             { color: var(--nx-danger); }
.px-verdict-word[data-s="qualified_for_review"] { color: var(--nx-healthy); }
.px-verdict-word[data-s="qualified"]            { color: var(--nx-healthy); }
.px-verdict-word[data-s="expired"]              { color: var(--nx-ash-2); }

/* Segmented quality bars. Discrete because the underlying value is a count or a
   share of a small set — a smooth bar would imply a precision we do not have. */
.px-seg { display: flex; gap: 3px; margin-top: 7px; }
.px-seg i { flex: 1; height: 3px; border-radius: 1px; background: var(--nx-gunmetal); font-style: normal; }
.px-seg i[data-on="1"] { background: var(--px-observed); }
.px-seg[data-tone="healthy"] i[data-on="1"] { background: var(--nx-healthy); }
.px-seg[data-tone="anomaly"] i[data-on="1"] { background: var(--nx-anomaly); }
.px-seg[data-tone="unknown"] i[data-on="1"] { background: var(--px-unknown); }

.px-quals { display: flex; gap: 26px; margin-top: 16px; }
.px-quals > div { flex: 1; min-width: 0; }

/* WHY — prose, with the facts beside it rather than beneath it. */
.px-why { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 24px;
  padding: 18px 22px; border-bottom: 1px solid var(--i-hair); }
/* A sparse candidate has almost nothing to tabulate. Reserving a column for two rows leaves a dead
   region that reads as a rendering fault, so the prose simply takes the full width instead. */
.px-why[data-sparse="1"] { grid-template-columns: 1fr; }
.px-facts { display: grid; grid-template-columns: auto auto; gap: 5px 18px; align-content: start; }
.px-facts dt { font-family: var(--nx-mono); font-size: 9.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--nx-ash); }
.px-facts dd { margin: 0; font-family: var(--nx-mono); font-size: 11.5px; color: var(--nx-bone-hi);
  text-align: right; font-variant-numeric: tabular-nums; }

/* KNOWN / INFERRED / UNKNOWN / WAITING FOR — the reasoning model as four
   parallel columns. This is the replacement for the six stacked question
   fields: same underlying evidence, read as a picture instead of a form. */
.px-quad { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  border-bottom: 1px solid var(--i-hair); }
.px-quad > div { padding: 15px 14px; border-left: 1px solid var(--i-hair); min-width: 0; }
.px-quad > div:first-child { border-left: 0; }
.px-quad ul { margin: 10px 0 0; padding: 0; list-style: none; }
.px-quad li { position: relative; padding-left: 13px; margin-bottom: 8px;
  font-size: 11.5px; line-height: 1.5; color: var(--nx-bone); overflow-wrap: anywhere; }
.px-quad li::before { content: ''; position: absolute; left: 0; top: 6px;
  width: 4px; height: 4px; border-radius: 50%; background: currentColor; }
.px-quad [data-k="known"]    li { color: var(--nx-bone); }
.px-quad [data-k="known"]    li::before { background: var(--nx-healthy); }
.px-quad [data-k="inferred"] li::before { background: var(--px-inferred); }
.px-quad [data-k="unknown"]  li { color: var(--nx-ash-2); }
.px-quad [data-k="unknown"]  li::before { background: var(--px-unknown); }
.px-quad [data-k="waiting"]  li { color: var(--nx-ash-2); }
.px-quad [data-k="waiting"]  li::before { background: var(--nx-tungsten); }
.px-quad-empty { margin-top: 10px; font-size: 11.5px; color: var(--nx-ash); font-style: italic; }

/* Metric cells — a 2x2 of small instruments, divided, not boxed. */
.px-metrics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  border-bottom: 1px solid var(--i-hair); }
.px-metrics > div { padding: 14px; border-left: 1px solid var(--i-hair); border-top: 1px solid var(--i-hair); min-width: 0; }
.px-metrics > div:nth-child(odd) { border-left: 0; }
.px-metrics > div:nth-child(-n+2) { border-top: 0; }
.px-metric-v { font-family: var(--nx-mono); font-size: 15px; color: var(--nx-bone-hi); margin-top: 6px;
  font-variant-numeric: tabular-nums; }
.px-metric-row { display: flex; align-items: center; gap: 10px; margin-top: 9px; }
.px-metric-kv { display: flex; justify-content: space-between; gap: 10px; margin-top: 5px;
  font-family: var(--nx-mono); font-size: 10.5px; color: var(--nx-ash-2); }
.px-metric-kv b { font-weight: 400; color: var(--nx-bone-hi); }

/* ── decision tape ────────────────────────────────────────────────────────── */
.px-tape { padding: 4px 0 0; }
.px-tape-row { display: grid; grid-template-columns: 62px 1fr auto; gap: 12px; align-items: baseline;
  padding: 9px 22px; border-top: 1px solid var(--i-hair); }
.px-tape-row:first-child { border-top: 0; }
.px-tape-t { font-family: var(--nx-mono); font-size: 10px; color: var(--nx-ash); }
.px-tape-e { font-family: var(--nx-mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--px-observed); }
.px-tape-e[data-p="INFERRED"] { color: var(--px-inferred); }
.px-tape-e[data-p="UNKNOWN"]  { color: var(--nx-ash); }
.px-tape-d { font-size: 11.5px; color: var(--nx-ash-2); margin-top: 3px; line-height: 1.5; }
.px-tape-src { font-family: var(--nx-mono); font-size: 9px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--nx-ash); }

/* ── actions ──────────────────────────────────────────────────────────────── */
.px-actions { display: flex; align-items: stretch; border-top: 1px solid var(--i-hair); flex: none; }
.px-act {
  appearance: none; cursor: pointer; background: none; border: 0;
  border-left: 1px solid var(--i-hair);
  padding: 15px 18px; color: var(--nx-ash-2);
  font-family: var(--nx-mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
}
.px-act:first-child { border-left: 0; }
a.px-act { text-decoration: none; display: inline-flex; align-items: center; }
.px-act:hover { color: var(--nx-bone-hi); }
/* Exactly one tungsten action per screen. It is the primary thing you can do. */
.px-act[data-primary] { margin-left: auto; color: var(--nx-tungsten); border-left: 1px solid var(--nx-tungsten-dim); }
.px-act[data-primary]:hover { background: var(--nx-tungsten-veil); color: var(--nx-tungsten); }
.px-act:focus-visible { outline: 1px solid var(--nx-tungsten); outline-offset: -3px; }
.px-act[disabled] { opacity: .4; cursor: not-allowed; }

/* ── the lens ─────────────────────────────────────────────────────────────── */
.px-lens {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 10px 22px; border-bottom: 1px solid var(--nx-tungsten-dim);
  background: var(--nx-tungsten-veil);
}
.px-lens-w { font-size: 12.5px; color: var(--nx-bone-hi); }
.px-lens-n { font-size: 11px; color: var(--nx-ash-2); margin-right: auto; }
.px-lensed [data-lens="out"] { opacity: .26; transition: opacity .18s ease; }
.px-lensed [data-lens="in"]  { opacity: 1; }

/* MOTION VOCABULARY: focus, resolve, trace, fade, heat. Nothing else. */
@keyframes px-resolve { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
.px-resolve { animation: px-resolve .26s ease both; }
@media (prefers-reduced-motion: reduce) {
  .px-resolve { animation: none; }
  .px-lensed [data-lens="out"] { transition: none; }
  .px-pulse[data-on="1"] { box-shadow: none; }
}

/* ── provenance, correctly positioned ─────────────────────────────────────── */
/* Nothing is hidden. Customer-level attribution reads in the flow; the exact
   provider path, implementation source, timestamp, confidence and basis sit one
   deliberate disclosure away. */
.px-prov { margin-top: 12px; }
.px-prov > summary { cursor: pointer; list-style: none;
  font-family: var(--nx-mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--nx-ash); padding: 6px 0; }
.px-prov > summary::-webkit-details-marker { display: none; }
.px-prov > summary::before { content: '+ '; color: var(--nx-tungsten); }
.px-prov[open] > summary::before { content: '– '; }
.px-prov > summary:hover { color: var(--nx-bone); }
.px-prov-body { border-top: 1px solid var(--i-hair); padding-top: 10px; }
.px-prov-row { display: grid; grid-template-columns: minmax(0,1fr) auto; gap: 10px;
  padding: 7px 0; border-top: 1px solid var(--i-hair); }
.px-prov-row:first-child { border-top: 0; }
.px-src { font-family: var(--nx-mono); font-size: 10px; color: var(--nx-ash); overflow-wrap: anywhere; }

/* ── appearance control ───────────────────────────────────────────────────── */
/* Deliberate control, not three developer buttons bolted to the navigation. */
.px-appearance { position: relative; }
.px-appearance > summary { cursor: pointer; list-style: none; }
.px-appearance > summary::-webkit-details-marker { display: none; }
.px-appearance > summary:focus-visible { outline: 1px solid var(--nx-tungsten); outline-offset: 2px; }
.px-appearance-menu button:focus-visible { outline: 1px solid var(--nx-tungsten); outline-offset: -2px; }
.px-back:focus-visible { outline: 1px solid var(--nx-tungsten); outline-offset: 2px; }
.px-appearance-menu {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 40; min-width: 226px;
  background: var(--nx-carbon); border: 1px solid var(--i-hair-hi); border-radius: 2px;
  box-shadow: 0 12px 34px rgba(0,0,0,.5); padding: 5px;
}
.px-appearance-menu button {
  display: block; width: 100%; text-align: left; appearance: none; cursor: pointer;
  background: none; border: 0; border-left: 1px solid transparent; padding: 9px 11px; color: var(--nx-ash-2);
}
.px-appearance-menu button:hover { color: var(--nx-bone-hi); }
.px-appearance-menu button[aria-pressed="true"] { color: var(--nx-bone-hi); border-left-color: var(--nx-tungsten); }
.px-appearance-menu b { display: block; font-weight: 500; font-size: 12.5px; letter-spacing: .09em; text-transform: uppercase; }
.px-appearance-menu span { display: block; font-size: 11px; color: var(--nx-ash); margin-top: 3px; line-height: 1.45; }

/* ── responsive ───────────────────────────────────────────────────────────── */
/* The desktop art direction is not shrunk proportionally. Below the stage
   breakpoint the composition re-forms: the decision comes first because on a
   phone the answer is what you came for, and the field becomes a full-width
   stage of its own rather than a squeezed column. */
@media (max-width: 1180px) {
  .px-stage { grid-template-columns: 1fr; }
  .px-stage-l { border-right: 0; border-top: 1px solid var(--i-hair); order: 2; }
  .px-stage-r { order: 1; }
  .px-decision { overflow: visible; }
  .px-field { min-height: 380px; }
}
@media (max-width: 900px) {
  /* The rail becomes a horizontally scrolling strip, and its own scroll content was widening the page
     by ~13px. The rail keeps its internal scroll — nothing becomes unreachable — but the page itself
     must never move sideways. */
  .px-i { grid-template-columns: 1fr; grid-template-rows: auto auto auto 1fr; overflow-x: hidden; }
  /* THE RAIL ITSELF DOES NOT SCROLL. Only the destinations do.
     When the whole strip was the scroller, revealCurrentDest() centred the current destination and
     dragged the identity and the capital readout off the left edge — so the two things that must
     always be visible were the two things that disappeared first. */
  /* THE RAIL CLEARS THE STATUS BAR.
     A customer's screenshot showed TODAY / HUNT / WHALES sitting underneath the iOS clock and
     battery, and the PANTEREX mark behind the time. hunt.html declares viewport-fit=cover — correct,
     it is how the instrument reaches the edges of the device — but nothing compensated for the area
     the OS owns.
     Padding on the RAIL rather than the frame, so the rail's own background fills the status area
     (it must not be a transparent gap) while its contents begin below it. --px-safe-top is 0px on a
     device without an inset, so this changes nothing on a laptop or an ordinary Android. */
  .px-rail { position: static; height: auto; flex-direction: row; align-items: center;
    overflow: visible; border-right: 0; border-bottom: 1px solid var(--i-hair);
    padding-top: var(--px-safe-top);
    /* Landscape moves the cutout to a side: the identity and the first destination must clear it. */
    padding-left: var(--px-safe-left); padding-right: var(--px-safe-right);
    background: var(--nx-carbon); }
  /* Identity stays put while the destinations scroll under it. A trading app whose name disappears
     the moment you move sideways reads as a page you have been redirected to, not the product. */
  .px-rail-brand { padding: 10px 14px; display: flex; align-items: center; gap: 10px; text-align: left; flex: none;
    background: var(--nx-carbon); border-right: 1px solid var(--i-hair); }
  .px-rail-eye { width: 24px; margin: 0; }
  .px-rail-word { font-size: 14px; letter-spacing: .22em; }
  .px-rail-chain { display: none; }
  /* The rail foot is hidden on a phone EXCEPT the capital readout, which is exactly what somebody
     opens the app on a phone to check. It moves to the front of the strip, before the destinations. */
  .px-rail-foot { display: contents; }
  .px-rail-foot .px-rail-state, .px-rail-foot .px-rail-meta { display: none; }
  /* Order matters here: the brand is sticky at left:0, so anything given a LOWER order than it ends
     up underneath it and invisible. Capital sits immediately AFTER the identity and before the
     destinations — the first thing read on a phone, and never covered. */
  /* Capital moves to its own row on a phone — see the capital-bar block at the end of this file,
     which must come AFTER the base .px-capbar rule to win at equal specificity. */
  /* The rail is a flex ROW here, so every child must be told not to shrink. Without flex:none the
     nav and each destination were compressed below their own text width and the labels drew on top
     of one another — six destinations overlapping in a single illegible line on a phone. */
  /* The destinations are the scroller now, and they take whatever width is left after the identity
     and the capital readout have had theirs. */
  .px-nav { display: flex; padding: 0; flex: 1 1 auto; min-width: 0;
    overflow-x: auto; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; }
  .px-nav a { flex: none; border-left: 0; border-top: 0; border-bottom: 2px solid transparent; white-space: nowrap; padding: 15px 14px; }
  .px-nav a + a { border-top: 0; }
  /* The strip scrolls, so it must LOOK like it scrolls: the right edge fades instead of ending on a
     hard cut that reads as "this is all of it". */
  .px-nav { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent 100%);
            mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent 100%); }
  .px-nav::-webkit-scrollbar { height: 0; }
  .px-nav a[aria-current="page"] { border-left-color: transparent; border-bottom-color: var(--nx-tungsten); }
  .px-nav-dot { display: none; }
  .px-head-id { font-size: 28px; }
  .px-why { grid-template-columns: 1fr; gap: 14px; }
  .px-quad { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .px-quad > div:nth-child(3) { border-left: 0; }
  .px-quad > div:nth-child(n+3) { border-top: 1px solid var(--i-hair); }
}
@media (max-width: 560px) {
  /* No microscopic telemetry on a phone. The desktop label size is legible at reading distance on a
     large display and is not on a handset, so the smallest type steps up rather than being scaled down
     with everything else. */
  .px-label { font-size: 10.5px; letter-spacing: .11em; }
  .px-tele { font-size: 12px; }
  .px-quad li { font-size: 12.5px; }
  .px-tape-t, .px-tape-src { font-size: 11px; }
  .px-quad, .px-metrics { grid-template-columns: 1fr; }
  .px-quad > div, .px-metrics > div { border-left: 0; border-top: 1px solid var(--i-hair); }
  .px-quad > div:first-child, .px-metrics > div:first-child { border-top: 0; }
  .px-readout > * { padding: 0 10px; }
  .px-verdict-word { font-size: 27px; }
  .px-tape-row { grid-template-columns: 54px 1fr; }
  .px-tape-src { grid-column: 2; }
  .px-actions { flex-wrap: wrap; }
  .px-act[data-primary] { margin-left: 0; width: 100%; border-left: 0; border-top: 1px solid var(--nx-tungsten-dim); }
}

/* Nothing may push the page sideways. */
.px-i, .px-main, .px-stage, .px-stage-l, .px-stage-r { max-width: 100%; }
.px-i * { min-width: 0; }

/* ============================================================================
   SHARED DESTINATION PRIMITIVES
   Added when TODAY was migrated. These are the same spatial rules the approved
   Decision Room established, factored out so every destination composes from
   one vocabulary rather than growing its own — that is what makes the product
   feel like one application rather than a set of screens.
   ============================================================================ */

/* A destination that scrolls its own content inside the fixed instrument frame.
   The Decision Room uses .px-stage instead, which manages its own regions. */
.px-scroll { flex: 1; min-height: 0; overflow-y: auto; scrollbar-width: thin;
  display: flex; flex-direction: column; }
.px-scroll::-webkit-scrollbar { width: 7px; }
.px-scroll::-webkit-scrollbar-thumb { background: var(--nx-gunmetal); border-radius: 4px; }

/* A STRIP OF READINGS. Divided by hairline verticals, never boxed individually —
   boxing each figure is what turned the old surface into a grid of cards. */
.px-strip { display: flex; flex-wrap: wrap; border-bottom: 1px solid var(--i-hair); }
.px-strip > div { flex: 1 1 0; min-width: 150px; padding: 15px 20px; border-left: 1px solid var(--i-hair); }
.px-strip > div:first-child { border-left: 0; }
.px-strip-v { font-family: var(--nx-mono); font-size: 21px; line-height: 1.1; margin-top: 7px;
  color: var(--nx-bone-hi); font-variant-numeric: tabular-nums; }
.px-strip-v[data-tone="healthy"] { color: var(--nx-healthy); }
.px-strip-v[data-tone="danger"]  { color: var(--nx-danger); }
.px-strip-v[data-tone="anomaly"] { color: var(--nx-anomaly); }
.px-strip-v[data-tone="ash"]     { color: var(--nx-ash); }
.px-strip-s { font-size: 11.5px; color: var(--nx-ash-2); margin-top: 5px; line-height: 1.45; }

/* Two regions side by side. Not a card grid — a wide primary and a narrower
   secondary, separated by one hairline. */
.px-two { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(340px, 1fr); }
.px-two > section { min-width: 0; border-left: 1px solid var(--i-hair); }
.px-two > section:first-child { border-left: 0; }
.px-region { padding: 16px 20px 20px; }
.px-region-h { display: flex; align-items: baseline; gap: 12px; margin-bottom: 12px; }
.px-region-h a { margin-left: auto; text-decoration: none; }

/* A row in a list of real things. Hairline between, nothing around. */
.px-row { display: block; text-decoration: none; padding: 12px 0; border-top: 1px solid var(--i-hair); }
.px-row:first-of-type { border-top: 0; }
.px-row:hover { background: rgba(255,255,255,.014); }
.px-row-top { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.px-row-id { font-size: 14.5px; color: var(--nx-bone-hi); font-weight: 500; }
.px-row-d { font-size: 12px; color: var(--nx-ash-2); line-height: 1.55; margin-top: 5px; }
.px-row-r { margin-left: auto; text-align: right; flex: none; }

/* An honest empty state. It states which of the two indistinguishable cases it
   is — nothing happening, or nothing running — and never looks like a result. */
.px-empty { padding: 26px 0; }
.px-empty b { display: block; font-weight: 500; font-size: 14px; color: var(--nx-bone); margin-bottom: 6px; }
.px-empty span { display: block; font-size: 12.5px; color: var(--nx-ash); line-height: 1.65; max-width: 52ch; }

/* The funnel. Refusal carries the same weight as everything else: a hunter that
   refuses ninety-nine things is doing its job, and hiding that makes the one it
   kept look unearned. */
.px-funnel a { display: flex; align-items: center; gap: 14px; text-decoration: none;
  padding: 9px 0; border-top: 1px solid var(--i-hair); }
.px-funnel a:first-child { border-top: 0; }
.px-funnel-n { font-family: var(--nx-mono); font-size: 17px; min-width: 46px; color: var(--nx-bone-hi);
  font-variant-numeric: tabular-nums; }
.px-funnel-n[data-zero="1"] { color: var(--nx-ash); }
.px-funnel-l { font-family: var(--nx-mono); font-size: 9.5px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--nx-ash); min-width: 128px; }

@media (max-width: 1020px) {
  .px-two { grid-template-columns: 1fr; }
  .px-two > section { border-left: 0; border-top: 1px solid var(--i-hair); }
  .px-two > section:first-child { border-top: 0; }
}
@media (max-width: 560px) {
  .px-strip > div { flex: 1 1 100%; border-left: 0; border-top: 1px solid var(--i-hair); }
  .px-strip > div:first-child { border-top: 0; }
}

/* An input in the instrument. No filled control anywhere — the field is a bounded region and the
   action beside it is the only tungsten on the row. */
.px-input {
  flex: 1; min-width: 0; appearance: none;
  background: transparent; border: 0; outline: 0;
  padding: 13px 14px; color: var(--nx-bone-hi);
  font-family: var(--nx-mono); font-size: 12.5px;
}
.px-input::placeholder { color: var(--nx-ash); }
.px-input:focus-visible { outline: 1px solid var(--nx-tungsten); outline-offset: -1px; }
.px-input[aria-invalid="true"] { color: var(--nx-danger); }

/* ============================================================================
   INSTRUMENT ACTION + TYPOGRAPHY ROLES
   (visual correction — affordance was over-restrained)

   THE FAILURE
     Restraint had gone past precision into faintness. Destination actions read
     as metadata: mono, ~10px, ash, letter-spaced, hard against the right edge.
     A control a user must hover to discover is not a control.

   PREMIUM IS NOT FAINT. The fix adds hierarchy, not chrome — typography,
   contrast, spacing, a hairline and an arrow. No pills, no filled buttons, no
   glow, no shadow, no scale animation.

   THE TYPOGRAPHY ROLES ARE NOW LOCKED PRODUCT-WIDE
     DISPLAY     condensed PANTEREX type — identity and headline moments only
     INTERFACE   DM Sans — navigation, actions, explanation, prose
     TELEMETRY   JetBrains Mono — addresses, times, states, raw evidence
   Mono is NOT the default UI font. A reader must be able to tell DATA from
   CONTROLS from HEADINGS without thinking about it.
   ============================================================================ */

/* ── the canonical action ─────────────────────────────────────────────────── */
.px-action {
  display: inline-flex; align-items: baseline; gap: 8px;
  font-family: var(--nx-sans);
  font-size: 12.5px; font-weight: 500; letter-spacing: .012em;
  color: var(--nx-bone); text-decoration: none;
  padding: 4px 0; border: 0; background: none; cursor: pointer;
  border-bottom: 1px solid transparent;
  transition: color .15s ease, border-color .15s ease;
}
/* The arrow is the interactive indicator and the only tungsten at rest. The
   label stays bone: making the whole label tungsten would turn every action
   into an alarm. */
.px-action::after {
  content: '→';
  font-family: var(--nx-sans); font-size: 12.5px; line-height: 1;
  color: var(--nx-tungsten);
  transition: color .15s ease;
}
.px-action:hover,
.px-action:focus-visible {
  color: var(--nx-bone-hi);
  border-bottom-color: var(--nx-tungsten);
}
.px-action:focus-visible { outline: 0; }
.px-action:focus-visible::after { color: var(--nx-tungsten); }

/* A row whose whole surface is the target. The explicit action remains, because
   a clickable row with no visible action is still a guess. */
.px-actionable { cursor: pointer; transition: background-color .15s ease; }
.px-actionable:hover { background: rgba(255,255,255,.018); }
:root[data-px-theme="field"] .px-actionable:hover { background: rgba(0,0,0,.022); }
.px-actionable:hover .px-action { color: var(--nx-bone-hi); border-bottom-color: var(--nx-tungsten); }
.px-actionable:focus-within { background: rgba(255,255,255,.022); }

/* Deliberate right-side breathing room — an action hard against the viewport
   edge reads as a stray label rather than a control. */
.px-action-slot { padding-right: 6px; flex: none; }

@media (max-width: 700px) {
  /* Touch targets get more size, not less. */
  .px-action { font-size: 13.5px; padding: 8px 0; }
  .px-action::after { font-size: 13.5px; }
}

/* ── readability corrections ──────────────────────────────────────────────── */
/* Labels are still mono and still small, but no longer at the edge of legibility
   and no longer competing with controls for the same visual weight.
   Measured at 4.20 contrast on obsidian — below WCAG AA's 4.5 for text this size —
   so the token steps up. Metadata may be quiet; it may not be unreadable. */
.px-label { font-size: 10.5px; letter-spacing: .12em; color: var(--nx-ash-2); }
@media (max-width: 700px) { .px-label { font-size: 11px; } }

.px-tele { font-size: 11.5px; }
@media (max-width: 700px) { .px-tele { font-size: 12.5px; } }

/* Prose is DM Sans and readable, not decorative. */
.px-body { font-size: 13.5px; line-height: 1.68; color: var(--nx-bone); }

/* A destination name is a heading, not telemetry — sans, with real authority. */
.px-entry-title {
  font-family: var(--nx-sans); font-size: 14.5px; font-weight: 600;
  letter-spacing: .01em; color: var(--nx-bone-hi);
}
/* State chips stay mono: they are data about the thing, not the thing. */
.px-entry-state { font-family: var(--nx-mono); font-size: 10px; letter-spacing: .13em; text-transform: uppercase; }

/* A row that pairs a title, a state and an action. */
.px-entry { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.px-entry .px-action-slot { margin-left: auto; }

/* Row link surfaces must never inherit link underlines. */
.px-actionable a { text-decoration: none; }

/* ============================================================================
   CONFIGURATION — a control surface, not a preferences page.

   The failure to avoid is the one this file was written against: heading, rule,
   label, input, rule, label, toggle. Settings are grouped in CELLS by concept,
   values lead, and controls are precise rather than decorative. Requested and
   Effective appear TOGETHER only when a higher-order rule actually changed the
   value — showing both on every row would make the exception invisible.
   ============================================================================ */

/* Capital leads: readings before controls. */
.px-cfg-lede { padding: 20px 22px 18px; border-bottom: 1px solid var(--i-hair); }
.px-cfg-lede-row { display: flex; gap: 0; margin-top: 12px; }
.px-cfg-reading { flex: 1 1 0; min-width: 0; padding-left: 18px; border-left: 1px solid var(--i-hair); }
.px-cfg-reading:first-child { padding-left: 0; border-left: 0; }
.px-cfg-reading-v {
  display: block; font-family: var(--nx-sans); font-weight: 300; font-size: 30px;
  line-height: 1.05; letter-spacing: -.015em; color: var(--nx-bone-hi);
  font-variant-numeric: tabular-nums;
}
.px-cfg-reading-k {
  display: block; margin-top: 6px; font-family: var(--nx-mono); font-size: 9.5px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--nx-ash);
}

.px-cfg-sec { padding: 18px 22px 20px; border-top: 1px solid var(--i-hair); }
.px-cfg-sec-h { display: flex; align-items: baseline; gap: 10px; }
.px-cfg-sec-h .px-tele { margin-left: auto; }
.px-cfg-hint { font-size: 12.5px; color: var(--nx-ash-2); margin: 6px 0 14px; max-width: 62ch; line-height: 1.55; }

/* A setting is a row in a cell, not a form field under a rule. */
.px-cfg-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 24px;
  align-items: start; padding: 13px 0; border-top: 1px solid var(--i-hair);
}
.px-cfg-row:first-of-type { border-top: 0; }
.px-cfg-dirty { box-shadow: inset 2px 0 0 var(--nx-tungsten); padding-left: 12px; margin-left: -12px; }
.px-cfg-label { font-size: 14px; color: var(--nx-bone-hi); font-weight: 500; }
.px-cfg-unit {
  margin-left: 8px; font-family: var(--nx-mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--nx-ash);
}
.px-cfg-note { font-size: 12px; color: var(--nx-ash-2); margin-top: 5px; max-width: 58ch; line-height: 1.5; }
.px-cfg-bounds {
  margin-top: 7px; font-family: var(--nx-mono); font-size: 10px; color: var(--nx-ash); text-align: right;
}
/* The constraint is a STATEMENT, not an error. Tungsten because it is a focus event. */
.px-cfg-constraint {
  margin-top: 9px; padding: 9px 11px; border-left: 2px solid var(--nx-tungsten);
  background: var(--nx-tungsten-veil); border-radius: 2px;
}
.px-cfg-why { font-size: 12px; color: var(--nx-bone); margin-top: 5px; line-height: 1.5; }

/* ── controls ─────────────────────────────────────────────────────────────── */
.px-stepper { display: inline-flex; align-items: stretch; border: 1px solid var(--i-hair-hi); border-radius: 2px; }
.px-stepper button {
  appearance: none; background: none; border: 0; cursor: pointer; width: 34px; min-height: 34px;
  color: var(--nx-ash-2); font-family: var(--nx-sans); font-size: 15px; line-height: 1;
  transition: color .15s ease, background-color .15s ease;
}
.px-stepper button:hover, .px-stepper button:focus-visible { color: var(--nx-bone-hi); background: rgba(255,255,255,.03); outline: 0; }
.px-stepper input {
  appearance: none; border: 0; border-left: 1px solid var(--i-hair); border-right: 1px solid var(--i-hair);
  background: none; color: var(--nx-bone-hi); width: 86px; text-align: center;
  font-family: var(--nx-mono); font-size: 13px; font-variant-numeric: tabular-nums; padding: 7px 4px;
}
.px-stepper input:focus { outline: 0; background: var(--nx-tungsten-veil); }

.px-switch {
  appearance: none; cursor: pointer; display: inline-flex; align-items: center; gap: 9px;
  border: 1px solid var(--i-hair-hi); border-radius: 2px; background: none; padding: 7px 12px 7px 9px;
  min-height: 34px; color: var(--nx-ash-2);
  font-family: var(--nx-sans); font-size: 13px; font-weight: 500;
  transition: color .15s ease, border-color .15s ease;
}
.px-switch span { width: 26px; height: 14px; border-radius: 2px; border: 1px solid var(--i-hair-hi); position: relative; flex: none; }
.px-switch span::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 8px; height: 8px;
  background: var(--nx-ash); transition: transform .15s ease, background-color .15s ease;
}
.px-switch[aria-checked="true"] { color: var(--nx-bone-hi); border-color: rgba(63,212,232,.45); }
.px-switch[aria-checked="true"] span { border-color: var(--px-observed); }
.px-switch[aria-checked="true"] span::after { transform: translateX(12px); background: var(--px-observed); }
.px-switch:focus-visible { outline: 0; border-color: var(--nx-tungsten); }

/* ── the review / apply bar ───────────────────────────────────────────────── */
.px-cfg-bar {
  position: sticky; bottom: 0; z-index: 5;
  padding: 15px 22px; border-top: 1px solid var(--i-hair-hi);
  background: var(--nx-graphite); display: grid; gap: 8px;
}
.px-cfg-bar[data-t="review"] { border-top-color: var(--nx-tungsten); }
.px-cfg-bar[data-t="ok"]     { border-top-color: var(--nx-healthy); }
.px-cfg-bar[data-t="warn"]   { border-top-color: var(--nx-anomaly); }
.px-cfg-bar[data-t="err"]    { border-top-color: var(--nx-danger); }
.px-cfg-bar-t { font-size: 14px; font-weight: 600; color: var(--nx-bone-hi); }
.px-cfg-bar-d { font-size: 12.5px; color: var(--nx-ash-2); line-height: 1.55; max-width: 78ch; }
.px-cfg-bar-a { display: flex; gap: 20px; align-items: center; margin-top: 4px; }
.px-action-primary {
  border: 1px solid rgba(232,163,61,.55); border-radius: 2px; padding: 9px 15px;
  color: var(--nx-tungsten); background: var(--nx-tungsten-veil);
}
.px-action-primary:hover, .px-action-primary:focus-visible { border-color: var(--nx-tungsten); background: rgba(232,163,61,.16); }
.px-action[disabled] { opacity: .45; cursor: default; }

@media (max-width: 720px) {
  .px-cfg-row { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .px-cfg-ctl { justify-self: start; }
  .px-cfg-bounds { text-align: left; }
  .px-cfg-lede-row { flex-wrap: wrap; gap: 14px 0; }
  .px-cfg-reading { flex: 1 1 45%; }
}

/* ── controlled choices ───────────────────────────────────────────────────── */
.px-choice { display: inline-flex; border: 1px solid var(--i-hair-hi); border-radius: 2px; overflow: hidden; }
.px-choice button {
  appearance: none; background: none; border: 0; border-left: 1px solid var(--i-hair); cursor: pointer;
  padding: 9px 13px; min-height: 34px; color: var(--nx-ash-2);
  font-family: var(--nx-sans); font-size: 12.5px; font-weight: 500; white-space: nowrap;
  transition: color .15s ease, background-color .15s ease;
}
.px-choice button:first-child { border-left: 0; }
.px-choice button[aria-checked="true"] { color: var(--nx-bone-hi); background: rgba(63,212,232,.10); box-shadow: inset 0 -2px 0 var(--px-observed); }
.px-choice button:hover, .px-choice button:focus-visible { color: var(--nx-bone-hi); outline: 0; }

.px-select {
  appearance: none; background: none; border: 1px solid var(--i-hair-hi); border-radius: 2px;
  color: var(--nx-bone-hi); font-family: var(--nx-mono); font-size: 12.5px;
  padding: 8px 11px; min-height: 34px; cursor: pointer;
}
.px-select:focus { outline: 0; border-color: var(--nx-tungsten); }
.px-select option { background: var(--nx-graphite); color: var(--nx-bone-hi); }

/* A setting whose safe domain is not established stays visible but not editable. */
.px-cfg-ro { display: inline-flex; flex-direction: column; align-items: flex-end; gap: 5px; }
.px-cfg-ro-w { font-family: var(--nx-mono); font-size: 9.5px; letter-spacing: .04em; color: var(--nx-ash); max-width: 26ch; text-align: right; line-height: 1.45; }

/* ── whale exit: a policy choice, not a settings row ──────────────────────── */
.px-wx-opts { display: grid; gap: 0; border: 1px solid var(--i-hair); border-radius: 2px; background: var(--i-cell); }
.px-wx-opt {
  appearance: none; background: none; border: 0; border-top: 1px solid var(--i-hair); cursor: pointer;
  display: flex; align-items: flex-start; gap: 12px; padding: 14px 15px; text-align: left; width: 100%;
  transition: background-color .15s ease;
}
.px-wx-opt:first-child { border-top: 0; }
.px-wx-opt:hover { background: rgba(255,255,255,.018); }
.px-wx-opt:focus-visible { outline: 1px solid var(--nx-tungsten); outline-offset: -2px; }
.px-wx-mark { width: 14px; height: 14px; border-radius: 50%; border: 1px solid var(--i-hair-hi); flex: none; margin-top: 2px; position: relative; }
.px-wx-opt[aria-checked="true"] .px-wx-mark { border-color: var(--nx-tungsten); }
.px-wx-opt[aria-checked="true"] .px-wx-mark::after {
  content: ''; position: absolute; inset: 3px; border-radius: 50%; background: var(--nx-tungsten);
}
.px-wx-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1 1 auto; }
.px-wx-label { font-size: 14px; font-weight: 500; color: var(--nx-bone-hi); }
.px-wx-desc { font-size: 12.5px; color: var(--nx-ash-2); line-height: 1.5; }
.px-wx-cur { font-family: var(--nx-mono); font-size: 9.5px; letter-spacing: .13em; text-transform: uppercase; color: var(--px-observed); flex: none; margin-top: 3px; }
/* The acknowledgement is a deliberate act. It is never pre-checked. */
.px-wx-ack {
  display: flex; align-items: flex-start; gap: 13px; margin-top: 14px; padding: 13px 15px;
  border: 1px solid rgba(232,163,61,.40); border-left-width: 2px; border-radius: 2px;
  background: var(--nx-tungsten-veil);
}
.px-wx-ack-t { font-size: 12.5px; color: var(--nx-bone); line-height: 1.55; }

/* ── THE PERSISTENT CAPITAL READOUT ───────────────────────────────────────────
   Present on every authenticated destination. A customer looking at wallet
   intelligence still has money in the machine, and a platform that hides their
   position from them because the current screen is "about something else" is
   asking them to trust it with less information than it has.

   Three readings, restrained. This is a status line, not a scoreboard: no
   casino green, no animated counters, no size that competes with the work. */
.px-capbar { display: none; }
.px-cap { display: grid; gap: 10px 0; padding: 0 0 14px; margin-bottom: 12px;
  border-bottom: 1px solid var(--i-hair); }
.px-cap-cell { display: grid; gap: 2px; }
.px-cap-k { font-family: var(--nx-mono); font-size: 9px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--nx-ash); }
.px-cap-v { font-family: var(--nx-mono); font-size: 16px; color: var(--nx-bone-hi);
  line-height: 1.1; font-variant-numeric: tabular-nums; }
.px-cap-v i { font-style: normal; font-size: 10px; color: var(--nx-ash); letter-spacing: .08em; }
.px-cap-unk { font-family: var(--nx-sans); font-size: 12px; color: var(--nx-ash);
  letter-spacing: 0; text-transform: none; }
/* P&L: a controlled reading of a fact, not a celebration. */
.px-cap-v[data-pnl="up"]      { color: var(--nx-healthy); }
.px-cap-v[data-pnl="down"]    { color: var(--nx-danger); }
.px-cap-v[data-pnl="flat"]    { color: var(--nx-bone); }
.px-cap-v[data-pnl="unknown"] { color: var(--nx-ash); }
.px-cap-eng[data-on="1"] { color: var(--nx-healthy); font-size: 13px; }
.px-cap-eng[data-on="0"] { color: var(--nx-anomaly); font-size: 13px; }
.px-cap-dim { color: var(--nx-ash); font-size: 12px; font-family: var(--nx-sans); }
.px-cap-flag { justify-self: start; font-family: var(--nx-mono); font-size: 9px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--nx-anomaly);
  border: 1px solid rgba(217,138,58,.4); padding: 2px 6px; }
.px-cap[data-state="unavailable"] { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.px-cap[data-state="reading"]     { display: flex; align-items: baseline; gap: 8px; }

@media (max-width: 900px) {
  /* In the horizontal rail the readout becomes a row of cells, still visible — it is not dropped
     on a phone, because that is exactly where a customer checks a balance. */
  .px-cap { display: flex; align-items: center; gap: 18px; padding: 0 14px; margin: 0;
    border-bottom: 0; border-right: 1px solid var(--i-hair); flex: none; }
  .px-cap-v { font-size: 13px; }
}


/* ── THE MOBILE CAPITAL BAR ───────────────────────────────────────────────────
   Declared here, at the end, deliberately: the base `.px-capbar { display: none }`
   sits with the rest of the capital styles further up, and a media query earlier
   in the file loses to it at equal specificity. Order is the mechanism.

   On a phone the rail strip carries identity and destinations, and the
   destinations scroll. Anything sharing that strip eventually scrolls out of it —
   which is exactly what happened to the balance. It gets its own full-width row
   instead, so the customer's capital cannot be pushed off screen by navigating. */
@media (max-width: 900px) {
  .px-rail-foot .px-cap-slot-rail { display: none; }
  .px-capbar { display: block; grid-column: 1 / -1;
    padding-left: var(--px-safe-left); padding-right: var(--px-safe-right);
    border-bottom: 1px solid var(--i-hair); background: var(--nx-carbon); }
  .px-capbar .px-cap { display: flex; align-items: center; gap: 20px; flex-wrap: nowrap;
    overflow-x: auto; overscroll-behavior-x: contain;
    padding: 9px 14px; margin: 0; border-bottom: 0; }
  .px-capbar .px-cap::-webkit-scrollbar { height: 0; }
  .px-capbar .px-cap-cell { flex: none; }
  .px-capbar .px-cap-v { font-size: 14px; }
  .px-capbar .px-cap[data-state="unavailable"],
  .px-capbar .px-cap[data-state="reading"] { padding: 11px 14px; }
}

/* ── HOME ─────────────────────────────────────────────────────────────────────
   Two different places, and the product must not blur them:
     HOME  — the public PANTEREX site. Leaves the instrument.
     TODAY — the operational home of the application.

   The logo is an anchor to /, so it works by click, by keyboard, by middle-click
   and without JavaScript. HOME also appears as an explicit destination, because
   nobody should have to guess that a logo is clickable. */
.px-rail-brand { text-decoration: none; color: inherit; display: block; }
.px-rail-brand:hover .px-rail-word { color: var(--nx-bone-hi); }
.px-rail-brand:focus-visible { outline: 1px solid var(--nx-tungsten); outline-offset: -2px; }

.px-nav-home { position: relative; }
.px-nav-home .px-nav-out {
  margin-left: auto; font-family: var(--nx-mono); font-size: 10px;
  color: var(--nx-ash); flex: none;
}
.px-nav-home:hover .px-nav-out { color: var(--nx-tungsten); }
/* It never takes the current-destination mark: you are never "on" Home while inside the app. */
.px-nav-home[aria-current] { border-left-color: transparent; }

@media (max-width: 900px) {
  /* HOME must exist on a phone too — the desktop logo is not a substitute, and a customer must be
     able to go public → app → public without browser gymnastics. */
  .px-nav-home { order: -1; }
  .px-nav-home .px-nav-out { margin-left: 6px; }
}

/* ── ENGINE AUTHORITY ─────────────────────────────────────────────────────────
   Whether PANTEREX is hunting is not a detail of the TODAY page. It is one of the
   two things a customer opens the app to check, the other being their capital, so
   the two sit together.

   STOP IS DELIBERATELY NOT HERE. A full stop ends stop-loss, take-profit and
   trailing protection for open positions; that consequence must never be one
   thumb-slip away on a persistent bar. It lives in TODAY and ACCOUNT behind the
   two-step confirmation that says what it costs.

   Restrained on purpose: no sticky footer, no glowing pill, no giant green START.
   An instrument, not a games console. */
.px-eng { display: grid; gap: 10px 0; padding: 0 0 14px; margin-bottom: 12px;
  border-bottom: 1px solid var(--i-hair); }
.px-eng-cell { display: grid; gap: 2px; }
.px-eng-k { font-family: var(--nx-mono); font-size: 9px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--nx-ash); }
.px-eng-v { font-family: var(--nx-mono); font-size: 15px; line-height: 1.1; color: var(--nx-bone-hi); }
.px-eng-v[data-on="on"]      { color: var(--nx-healthy); }
.px-eng-v[data-on="paused"]  { color: var(--nx-anomaly); }
.px-eng-v[data-on="off"]     { color: var(--nx-ash); }
.px-eng-v[data-on="unknown"] { color: var(--nx-ash); }
.px-eng-dim { color: var(--nx-ash); font-size: 12px; font-family: var(--nx-sans); }
.px-eng-note { font-size: 11px; line-height: 1.45; color: var(--nx-ash); }
.px-eng .px-o-act { justify-self: start; }
.px-eng [data-busy="1"] { opacity: .6; pointer-events: none; }
.px-engbar { display: none; }

@media (max-width: 900px) {
  /* On a phone the engine control gets its own row beside capital — always visible, on every
     destination, reachable without scrolling. A customer looking at WHALES still knows whether
     PANTEREX is hunting, and can pause it there. */
  .px-eng-slot-rail { display: none; }
  .px-engbar { display: block; grid-column: 1 / -1;
    border-bottom: 1px solid var(--i-hair); background: var(--nx-carbon);
    /* In landscape the island sits on one side; the engine control must not slide under it. */
    padding-left: var(--px-safe-left); padding-right: var(--px-safe-right); }
  .px-engbar .px-eng { display: flex; align-items: center; gap: 14px; flex-wrap: nowrap;
    overflow-x: auto; overscroll-behavior-x: contain;
    padding: 5px 14px; margin: 0; border-bottom: 0; }
  .px-engbar .px-eng::-webkit-scrollbar { height: 0; }
  .px-engbar .px-eng-cell { flex: none; }
  .px-engbar .px-eng-v { font-size: 14px; }
  /* A PERSISTENT control is pressed with a thumb, in motion, one-handed. 28px of target was a
     mis-tap waiting to happen next to a scrolling list, so the hit area is a full 44px regardless
     of how small the label gets. The bar is padded DOWN to absorb it rather than growing taller. */
  .px-engbar .px-o-act { flex: none; white-space: nowrap;
    min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
  /* The explanatory line is the first thing to go when space is tight — the STATE and the ACTION
     are what must survive. */
  .px-engbar .px-eng-note { display: none; }
}
@media (max-width: 380px) {
  .px-engbar .px-eng { gap: 10px; padding: 5px 12px; }
  .px-engbar .px-eng-v { font-size: 13px; }
  /* The LABEL may shrink on a narrow phone. The TARGET may not. */
  .px-engbar .px-o-act { font-size: 11.5px; padding: 6px 11px; min-height: 44px; }
}

/* ── STRATEGY ───────────────────────────────────────────────────────────────────────────────────
   The instrument vocabulary already in this file, extended for the three things Strategy adds:
   a set-valued control, a live statement of what is feeding the engine, and the difference between
   a rule that is requested and one that is actually enforced.

   No new colour system, no cards, no shadows. Typography and a hairline carry the hierarchy, as
   everywhere else here. */

/* The letter that fixes a concept's place in the sequence. Metadata, so telemetry type. */
.px-cfg-kick {
  font-family: var(--nx-mono); font-size: 10px; letter-spacing: .16em;
  color: var(--nx-ash-2); opacity: .55; min-width: 1.1em;
}

/* WHAT IS FEEDING PANTEREX — the first answer on the screen, before any control. */
.px-src-state { margin: 0 0 18px; padding: 14px 0 16px; border-top: 1px solid var(--i-hair); border-bottom: 1px solid var(--i-hair); }
.px-src-live { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.px-src-chip {
  font-family: var(--nx-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  padding: 5px 10px; border: 1px solid var(--i-hair-hi); border-radius: 2px;
  color: var(--nx-ash-2); white-space: nowrap;
}
.px-src-chip[data-on="true"] {
  color: var(--nx-bone-hi); border-color: rgba(63,212,232,.42);
  background: rgba(63,212,232,.09);
}
.px-src-say { font-size: 13px; line-height: 1.55; color: var(--nx-bone); max-width: 66ch; }
.px-src-state[data-tone="danger"] .px-src-say { color: var(--px-danger, #ff6b5e); }

/* A SET, not a scalar. Each option is its own switch; the group reads as one control. */
.px-multi { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; max-width: 30ch; }
.px-multi button {
  appearance: none; background: none; cursor: pointer;
  border: 1px solid var(--i-hair-hi); border-radius: 2px;
  padding: 6px 10px; min-height: 30px;
  color: var(--nx-ash-2); font-family: var(--nx-sans); font-size: 12px; font-weight: 500;
  white-space: nowrap; transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
.px-multi button[aria-checked="true"] {
  color: var(--nx-bone-hi); border-color: rgba(63,212,232,.42); background: rgba(63,212,232,.09);
}
.px-multi button:hover, .px-multi button:focus-visible { color: var(--nx-bone-hi); outline: 0; }

/* REQUESTED IS NOT ENFORCED. A threshold whose gate is off is a number the engine never reads, and
   a screen that does not say so has told the customer something untrue about their own strategy. */
.px-cfg-on, .px-cfg-off {
  font-family: var(--nx-mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase;
  margin-left: 9px; vertical-align: 1px;
}
.px-cfg-on  { color: var(--nx-ash-2); opacity: .6; }
.px-cfg-off { color: var(--nx-tungsten); }
.px-cfg-row.px-cfg-inactive .px-cfg-label,
.px-cfg-row.px-cfg-inactive .px-cfg-unit { opacity: .5; }
.px-cfg-row.px-cfg-inactive .px-stepper input { opacity: .55; }

@media (max-width: 720px) {
  .px-multi { justify-content: flex-start; max-width: none; }
}

/* ── ENGINE TELEMETRY ───────────────────────────────────────────────────────────────────────────
   Is it running · what did it last look at · why didn't it buy.

   Every value here is measured by the engine. There is deliberately no pulse, no shimmer and no
   "scanning…" — decorative movement unsupported by engine state is the thing this replaces. A source
   that has done nothing says what it is waiting for, and that reads as calm rather than as broken. */
.px-tel-box { margin: 18px 0 0; padding: 16px 0 4px; border-top: 1px solid var(--i-hair); }
.px-tel-h { margin-bottom: 12px; }

.px-tel {
  display: grid; grid-template-columns: 8.5rem 1fr; gap: 2px 16px;
  padding: 10px 0; border-top: 1px solid var(--i-hair);
}
.px-tel:first-of-type { border-top: 0; }
.px-tel-k {
  grid-row: span 2; align-self: start; padding-top: 1px;
  font-family: var(--nx-mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--nx-ash-2);
}
.px-tel-v { font-size: 13.5px; color: var(--nx-bone-hi); line-height: 1.4; }
.px-tel-d { font-size: 12px; color: var(--nx-ash-2); line-height: 1.5; max-width: 64ch; }

/* State is carried by the label's colour alone — one thin signal, not a badge. */
.px-tel[data-tone="live"]     .px-tel-k { color: var(--px-observed, #3fd4e8); }
.px-tel[data-tone="idle"]     .px-tel-k { color: var(--nx-ash-2); }
.px-tel[data-tone="off"]      .px-tel-k { color: var(--nx-ash-2); opacity: .6; }
.px-tel[data-tone="off"]      .px-tel-v { color: var(--nx-ash-2); }
.px-tel[data-tone="inactive"] .px-tel-k { color: var(--nx-tungsten); }
.px-tel[data-tone="inactive"] .px-tel-v { color: var(--nx-tungsten); }
.px-tel[data-tone="anomaly"]  .px-tel-k,
.px-tel[data-tone="anomaly"]  .px-tel-v { color: var(--nx-tungsten); }

@media (max-width: 720px) {
  .px-tel { grid-template-columns: 1fr; gap: 3px; }
  .px-tel-k { grid-row: auto; }
}

/* CONFIGURED BUT INACTIVE. A contradiction the customer can see and resolve in one deliberate press —
   never a silent mode change, because switching also moves the score floor. */
.px-src-warn { margin: 12px 0 4px; padding: 12px 0 0; border-top: 1px solid var(--i-hair); }
.px-src-warn-t { font-size: 13px; color: var(--nx-tungsten); margin-bottom: 5px; }
.px-src-warn-b { font-size: 12px; color: var(--nx-ash-2); line-height: 1.55; max-width: 64ch; margin-bottom: 10px; }

/* ── CAPABILITY STATUS (px-state.js) ────────────────────────────────────────────────────────────
   Nine words, one meaning each, one appearance everywhere. A status that looks different on RADAR
   than it does on TODAY is a status the user has to re-learn per screen. */
.px-st { display: grid; grid-template-columns: 11rem 1fr; gap: 2px 16px; padding: 11px 0; border-top: 1px solid var(--i-hair); }
.px-st:first-of-type { border-top: 0; }
.px-st-k { grid-row: span 3; align-self: start; padding-top: 1px;
  font-family: var(--nx-mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--nx-ash-2); }
.px-st-s { font-family: var(--nx-mono); font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase; }
.px-st-w { font-size: 12.5px; color: var(--nx-bone); line-height: 1.5; max-width: 64ch; }
.px-st-a { font-size: 12px; color: var(--nx-ash-2); line-height: 1.5; max-width: 64ch; }
.px-st[data-tone="ok"]   .px-st-s { color: var(--px-healthy, #4ade80); }
.px-st[data-tone="live"] .px-st-s { color: var(--px-observed, #3fd4e8); }
.px-st[data-tone="warn"] .px-st-s { color: var(--nx-tungsten); }
.px-st[data-tone="bad"]  .px-st-s { color: var(--px-danger, #ff6b5e); }
.px-st[data-tone="off"]  .px-st-s { color: var(--nx-ash-2); }
@media (max-width: 720px) { .px-st { grid-template-columns: 1fr; gap: 3px; } .px-st-k { grid-row: auto; } }
