/* TrustGenAI production-console Phase 0 shell */
:root {
  color-scheme: light;
  --bg: #f4f6f9;
  --panel: #ffffff;
  --ink: #14171c;
  --muted: #5c646f;
  --line: #e3e6ec;
  --soft: #f8f9fb;
  --accent: #1f4fd8;
  --accent-soft: #eaf0ff;
  --warn: #8a5a00;
  --warn-soft: #fff5e3;
  --stop: #a32f2f;
  --stop-soft: #fdeded;
  --ok: #1c6b46;
  --ok-soft: #e9f6ef;
  --shadow: 0 1px 2px rgba(18, 22, 28, .05), 0 8px 24px rgba(18, 22, 28, .06);
  --focus: #9a5200;
  --header-height: 52px;
  /* THE COLUMNS ARE A SHARE OF THE WINDOW, WITH A LEGIBLE FLOOR AND A SANE CEILING.
     These were flat pixel counts - 210px of navigation, 360px of assistant - so the
     same layout was a quarter of a laptop and a sixth of an ultrawide, and neither
     followed a resize. A pixel is only honest here as the FLOOR, because "190px of
     navigation is readable and 140px is not" is a fact about text rather than about
     the screen; the preferred size and the ceiling are proportions.
     These two are the no-JavaScript fallback and the starting point; once the layout
     script runs it sets --left and --right as percentages of the shell. */
  --sidebar-width: clamp(190px, 15vw, 320px);
  --assistant-width: clamp(300px, 21vw, 520px);
  --divider: 5px;
  /* One inset for anything that floats against an edge, so the breathing room grows
     with the display instead of being a number chosen on one laptop. */
  --edge-inset: clamp(12px, 1.2vw, 28px);
}

*, *::before, *::after { box-sizing: border-box; }
html { min-width: 320px; min-height: 100%; background: var(--bg); }
/* A COLUMN, so the shell takes whatever the header leaves and no arithmetic is
   involved. The shell used to be `calc(100dvh - var(--header-height))` against a
   header declared as 52px that actually rendered at 53, so every page overflowed
   the window by a pixel and the bottom of the assistant was clipped. A measured
   constant that has to agree with a rendered element is a constant that will
   eventually disagree with it. */
body { min-width: 320px; height: 100vh; height: 100dvh; margin: 0; display: flex; flex-direction: column; overflow: hidden; background: var(--bg); color: var(--ink); font: 15px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif; }
[hidden] { display: none !important; }
button, input, select, textarea { font: inherit; }
button, summary { cursor: pointer; }
button:disabled { cursor: not-allowed; opacity: .55; }
a { color: inherit; }
svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
h1, h2, p { margin-top: 0; }
/* 23px at 800. The console's tables and secondary text were ALREADY at .82rem (13.1px),
   which is the density the Snowflake study asked for — the gap that study found was on
   the public site, where the largest type was 17px. So the only change the console
   needed was the page title carrying more weight against the denser body around it. */
h1 { margin-bottom: 4px; font-size: 1.44rem; font-weight: 800; line-height: 1.22; letter-spacing: -.02em; }
h2 { margin-bottom: 7px; font-size: 1.05rem; line-height: 1.3; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }

.skip-link { position: fixed; z-index: 200; top: 7px; left: 10px; min-height: 44px; padding: 8px 12px; visibility: hidden; transform: translateY(-140%); border-radius: 8px; background: var(--panel); color: var(--ink); font-weight: 700; box-shadow: var(--shadow); }
.skip-link:focus { visibility: visible; transform: none; }

/* The estate-provenance markers were REMOVED BY DECISION on 23 September 2026, not
   because the estate stopped being simulated. `console/demonstration.py` and its
   adapter still resolve the fact and are still tested; only the rendering went. If the
   claim is ever to be drawn again, the rules that were here are in the history of this
   file and the view model is waiting for them. */

.topbar { position: sticky; z-index: 40; top: 0; flex: 0 0 auto; min-height: var(--header-height); display: flex; align-items: center; gap: 10px; padding: 4px 18px; border-bottom: 1px solid var(--line); background: var(--panel); }
.brand { display: inline-flex; align-items: center; gap: 9px; color: var(--ink); font-weight: 750; letter-spacing: -.2px; text-decoration: none; }
.brand-mark { width: 32px; height: 32px; display: grid; place-items: center; border-radius: 8px; background: #173b67; color: #fff; font-size: .82rem; }
.header-spacer { flex: 1; }
.scope-indicator { min-width: 150px; padding-right: 7px; text-align: right; }
.scope-indicator span, .scope-indicator strong { display: block; line-height: 1.2; }
.scope-indicator span { color: var(--muted); font-size: .68rem; }
.scope-indicator strong { margin-top: 2px; font-size: .78rem; }
.header-icon, .mobile-menu-button { width: 44px; height: 44px; position: relative; display: grid; flex: 0 0 44px; place-items: center; padding: 0; border: 1px solid var(--line); border-radius: 50%; background: var(--panel); color: var(--muted); text-decoration: none; transition: border-color 180ms ease, color 180ms ease, background 180ms ease; }
.header-icon:hover, .mobile-menu-button:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.notification-dot { position: absolute; top: -2px; right: -2px; width: 8px; height: 8px; border: 2px solid var(--panel); border-radius: 50%; background: var(--stop); }
.mobile-menu-button { display: none; border-radius: 8px; }

.profile-menu { position: relative; }
.profile-menu summary { width: 44px; min-height: 44px; display: grid; place-items: center; list-style: none; }
.profile-menu summary::-webkit-details-marker { display: none; }
.profile-menu summary > span { width: 34px; height: 34px; display: grid; place-items: center; border: 1px solid #cbd7f8; border-radius: 50%; background: var(--accent-soft); color: var(--accent); font-size: .76rem; font-weight: 700; }
.profile-panel, .notification-panel { position: absolute; z-index: 70; top: 44px; right: 14px; width: min(320px, calc(100vw - 28px)); padding: 15px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel); box-shadow: var(--shadow); }
.profile-panel { right: 0; }
.profile-panel > strong, .profile-panel > span { display: block; }
.profile-panel > span { color: var(--muted); font-size: .8rem; }
.profile-panel dl { display: grid; gap: 9px; margin: 14px 0 0; }
.profile-panel dl div { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 8px; }
.profile-panel dt { color: var(--muted); font-size: .76rem; }
.profile-panel dd { margin: 0; font-size: .76rem; }
.notification-panel p { margin: 8px 0 0; color: var(--muted); font-size: .8rem; }

/* FIVE COLUMNS: navigation, splitter, page, splitter, assistant. --left and --right
   are set by platform-console-layout.js and by nothing else; a closed pane is 0px, so
   the width IS the state and there is no second flag to fall out of step with it. The
   fallbacks here are what a reader gets with JavaScript off: both panes open, fixed. */
.console-shell { flex: 1 1 auto; min-height: 0; overflow: hidden; display: grid; grid-template-columns: var(--left, var(--sidebar-width)) var(--divider) minmax(0, 1fr) var(--divider) var(--right, var(--assistant-width)); }
.console-shell[data-dragging="true"] { cursor: col-resize; user-select: none; }
.console-shell[data-left-open="false"] .sidebar, .console-shell[data-right-open="false"] .ally-panel { display: none; }

/* EVERY CHILD IS PLACED EXPLICITLY, and it has to be.
   A collapsed pane is `display: none`, and a display:none child leaves the grid flow
   altogether. Under automatic placement the remaining children then slide one column
   left: close the navigation and `main` lands in column 1, which is `var(--left)` and
   therefore nought pixels wide. On dev that showed as the assistant panel filling the
   window and the page itself disappearing - and only when the LEFT pane was closed,
   which is why collapsing the right on its own looked perfectly correct and the fault
   survived a review. Measured: both open 731px of main, right closed 1011px, left
   closed 44px.
   With each child pinned to its own column, hiding any of them moves nothing. */
.console-shell > .sidebar { grid-column: 1; }
.console-shell > [data-splitter="left"] { grid-column: 2; }
.console-shell > main { grid-column: 3; }
.console-shell > [data-splitter="right"] { grid-column: 4; }
.console-shell > .ally-panel { grid-column: 5; }

/* The splitters. Five pixels of hit area, invisible until wanted, and a visible bar on
   hover or focus so a keyboard reader can see which one they are moving.

   THE DIVIDER IS NEVER HIDDEN, and that is the whole reason this works. It used to be
   `hidden` whenever its pane was shut. The control that reopens a pane now lives ON the
   divider, so hiding it would have made a closed pane permanent — the only way back
   would have been clearing browser storage. A closed pane is a five-pixel strip with a
   chevron sitting on it, not nothing. */
.split { position: relative; border: 0; padding: 0; background: transparent; cursor: col-resize; }
/* ALWAYS DRAWN. This was transparent until hover, which made an open divider
   invisible: there was nothing on screen to tell anybody a column could be
   dragged or folded, and the reasonable conclusion was that the feature did not
   work. A control nobody can find is a control that does not exist. */
.split::after { content: ""; position: absolute; inset: 0 2px; background: var(--line); transition: background 120ms ease; }
.split:hover::after, .split:focus-visible::after { background: var(--accent); }
.split:focus-visible { outline: none; }
/* Shut: there is no width left to drag, so the resize affordance goes and the line is
   drawn permanently rather than on hover, so the strip reads as a thing to click. */
.split[data-collapsed="true"] { cursor: default; }
.split[data-collapsed="true"]::after { background: var(--line); }

/* The control sits ON the line. It is absolutely positioned so it can overflow a
   five-pixel grid track without widening it — the track stays five pixels whether the
   pane beside it is open or shut, so nothing moves when one closes. */
.split-toggle { position: absolute; z-index: 3; top: 12px; left: 50%; width: 20px; height: 26px; display: grid; place-items: center; padding: 0; transform: translateX(-50%); border: 1px solid var(--line); border-radius: 6px; background: var(--panel); color: var(--muted); cursor: pointer; opacity: 1; transition: opacity 120ms ease, color 120ms ease, border-color 120ms ease; }
.split-toggle svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.8; }
/* Shown on hover or focus while the pane is open, and ALWAYS while it is shut, because
   a control you cannot see is a pane you cannot reopen. */
.split:hover .split-toggle, .split-toggle:focus-visible, .split[data-collapsed="true"] .split-toggle { opacity: 1; }
/* A chevron drawn pointing the way the pane closes points the WRONG way once it is
   shut, when the only thing it can do is open it. The arrow is mirrored rather than
   drawn twice, so the template keeps one icon per side and cannot describe two. */
.split[data-collapsed="true"] .split-toggle svg { transform: scaleX(-1); }
/* THE ASSISTANT IS A CHAT PANEL, so when it is shut its way back belongs at the bottom
   of the line, which is where every chat product puts one - not level with the
   navigation's control at the top. Reported 23 Sep 2026 as "the ask button is on the
   top!!, it should be at thebuttom". While the pane is OPEN the control stays at the
   top, beside the navigation's, because then it is a hide button and not a launcher. */
/* PINNED TO THE WINDOW, not to the divider, and this is not decoration.
   A shut assistant is 0px wide, so its divider collapses to the right-hand edge of the
   window - a 5px strip at x 1915 of 1920. The launcher is centred on that strip, so at
   36px it spanned 1900 to 1936 and SIXTEEN PIXELS OF IT SAT OUTSIDE THE WINDOW, leaving
   a sliver jammed in the very corner. Reported 24 Sep 2026: "the bot folded and I cannot
   unfold it!!" - the control was there, and all but unreachable.
   `position: fixed` takes it off the divider and puts it where a chat launcher belongs,
   inset from the corner, which cannot be pushed off an edge by a collapsing column. */
.split[data-splitter="right"][data-collapsed="true"] .split-toggle { position: fixed; z-index: 61; top: auto; right: var(--edge-inset); bottom: var(--edge-inset); left: auto; width: 44px; height: 44px; transform: none; border-radius: 50%; border-color: var(--accent); background: var(--accent); color: #fff; box-shadow: 0 6px 18px rgba(15, 23, 42, .28); }
.split[data-splitter="right"][data-collapsed="true"] .split-toggle:hover { border-color: var(--accent); color: #fff; }
.split[data-splitter="right"][data-collapsed="true"] .split-toggle svg { width: 18px; height: 18px; }
.split-toggle:hover { border-color: var(--accent); color: var(--accent); }
.split-toggle:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.sidebar { height: 100%; min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; overscroll-behavior: contain; padding: 14px 10px 10px; border-right: 1px solid var(--line); background: var(--panel); }
.sidebar nav { display: grid; gap: 2px; }
.nav-group { margin: 13px 10px 4px; color: #7a828d; font-size: .66rem; font-weight: 750; letter-spacing: .07em; text-transform: uppercase; }
.nav-group:first-child { margin-top: 2px; }
.nav-link, .settings-link { min-height: 44px; display: flex; align-items: center; gap: 9px; padding: 8px 11px; border-radius: 8px; color: var(--ink); text-decoration: none; transition: background 180ms ease, color 180ms ease; }
.nav-link:hover, .settings-link:hover { background: #f1f3f7; }
.nav-link.is-current, .settings-link.is-current { background: var(--accent-soft); color: var(--accent); font-weight: 650; }
.nav-count { min-width: 25px; margin-left: auto; padding: 1px 7px; border-radius: 999px; background: #eef1f6; color: var(--muted); font-size: .72rem; font-weight: 600; text-align: center; }
.nav-link.is-current .nav-count { background: var(--panel); color: var(--accent); }
.sidebar-footer { margin-top: auto; padding-top: 10px; border-top: 1px solid var(--line); }
.seat-card { display: flex; align-items: center; gap: 9px; padding: 7px 9px 10px; }
.seat-card > span { width: 31px; height: 31px; display: grid; flex: 0 0 31px; place-items: center; border-radius: 50%; background: var(--accent-soft); color: var(--accent); font-size: .7rem; font-weight: 700; }
.seat-card small, .seat-card strong { display: block; line-height: 1.2; }
.seat-card small { color: var(--muted); font-size: .65rem; }
.seat-card strong { margin-top: 2px; font-size: .72rem; }
.settings-link svg { width: 18px; height: 18px; }
.sidebar-scrim { position: fixed; z-index: 44; inset: var(--header-height) 0 0 0; border: 0; background: rgba(20, 23, 28, .4); }

/* THE PAGE SCROLLS ITSELF. `min-height: 0` is not decoration: a grid child defaults
   to `min-height: auto`, which means it grows to fit its content instead of scrolling,
   and the overflow then lands on the body as one outer scrollbar dragging all three
   columns together. That is the complaint this rule answers. */
/* FULL WIDTH OF ITS TRACK. This carried `width: min(100%, 1180px)`, a readable-measure
   cap that belongs on the public site - where `app.css` still uses it, correctly, on
   centred prose - and not on a console of tables between two fixed columns. Here the
   track is already bounded by the navigation and the assistant, and the cap simply left
   the remainder empty: measured on dev at 1920 wide, the track was 1318px, main was
   1180px, and 138px of nothing sat between main's scrollbar and the assistant. Reported
   24 Sep 2026 - "now I can see space after the vertical scroll", and "the menu on the
   left end, the bot at the right end, the rest will fit the middile page with no space".
   Nothing centres it either, so the gap was all on one side. */
main { width: 100%; min-width: 0; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 18px 22px 116px; }
.breadcrumb { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 7px; color: var(--muted); font-size: .78rem; }
.breadcrumb a { color: var(--accent); }
.page-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; margin-bottom: 14px; }
.page-heading p { max-width: 760px; margin: 0; color: var(--muted); }
.page-title-row { display: flex; align-items: center; gap: 8px; }
.page-info { width: 22px; height: 22px; display: inline-grid; place-items: center; border: 1px solid var(--line); border-radius: 50%; color: var(--muted); font-size: .72rem; font-weight: 750; text-decoration: none; cursor: help; }

.page-heading .keyboard-hint { margin-top: 4px; font-size: .7rem; }
.primary-action { min-height: 44px; flex: 0 0 auto; padding: 8px 14px; border: 0; border-radius: 8px; background: var(--accent); color: #fff; font-weight: 650; }
/* A form inside a table cell: the archive, reopen and erase actions on the platform
   area. Stacked rather than inline, because the erase form carries a label and a text
   box as well as its button and those must not end up side by side on a phone. */
.seat-inline-form { display: flex; flex-direction: column; gap: 5px; align-items: flex-start; }
.seat-inline-form button { min-height: 38px; padding: 6px 11px; border: 1px solid var(--line); border-radius: 8px; background: var(--soft); font-weight: 600; }
.seat-inline-form label { font-size: .72rem; }
.seat-inline-form input[type="text"] { min-height: 38px; width: 100%; max-width: 15rem; padding: 5px 9px; border: 1px solid var(--line); border-radius: 8px; }
/* The one control on this console with no undo. Bordered, filled AND worded, so it is
   not colour alone that says so - the button's own text reads "Erase permanently". */
.destructive-action { border: 1px solid var(--stop) !important; background: var(--stop-soft) !important; color: var(--stop); font-weight: 750; }
.boundary-line { display: flex; align-items: center; gap: 11px; margin-bottom: 14px; padding: 10px 13px; border: 1px solid #cbd7f8; border-radius: 9px; background: var(--accent-soft); color: #203d89; }
.boundary-line svg { flex: 0 0 21px; }
.boundary-line strong, .boundary-line span { display: block; }
.boundary-line strong { margin-right: 7px; }
.boundary-line span { font-size: .78rem; }
.boundary-line span strong { display: inline; }
/* The About list on Help. Two facts, each selectable, because the whole point of them
   is being copied into a bug report. */
.about-list { display: grid; gap: 9px; margin: 12px 0 0; }
.about-list div { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 10px; align-items: baseline; }
.about-list dt { color: var(--muted); font-size: .76rem; }
.about-list dd { margin: 0; }
.about-list code { font-size: .78rem; overflow-wrap: anywhere; user-select: all; }
.status-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin-bottom: 14px; }
.status-grid article, .empty-card { border: 1px solid var(--line); border-radius: 10px; background: var(--panel); box-shadow: var(--shadow); }
.status-grid article { min-height: 118px; padding: 14px; }
.status-grid article > span, .status-grid article > strong, .status-grid article > small { display: block; }
.status-label { color: var(--muted); font-size: .68rem; font-weight: 750; letter-spacing: .055em; text-transform: uppercase; }
.status-grid article > strong { margin: 12px 0 4px; font-size: 1.02rem; }
.status-grid article > small { color: var(--muted); font-size: .74rem; }
.empty-card { min-height: 260px; display: grid; grid-template-columns: auto minmax(0, 620px); align-content: center; justify-content: center; gap: 18px; padding: clamp(26px, 5vw, 58px); }
.empty-icon { width: 56px; height: 56px; display: grid; place-items: center; border-radius: 14px; background: var(--accent-soft); color: var(--accent); }
.empty-icon svg { width: 28px; height: 28px; }
.eyebrow { margin-bottom: 4px; color: var(--accent); font-size: .69rem; font-weight: 750; letter-spacing: .065em; text-transform: uppercase; }
.empty-card p:not(.eyebrow) { margin-bottom: 15px; color: var(--muted); }
.source-chips { display: flex; flex-wrap: wrap; gap: 7px; }
.source-chips span { min-height: 29px; display: inline-flex; align-items: center; gap: 6px; padding: 4px 9px; border: 1px solid #c8e6d6; border-radius: 999px; background: var(--ok-soft); color: var(--ok); font-size: .7rem; font-weight: 650; }
.source-chips span.missing { border-color: #f4d2d2; background: var(--stop-soft); color: var(--stop); }
.source-chips i { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }

/* DOCKED, as the right column of the shell. It was a floating window pinned to the
   bottom-right that folded itself; it is now a pane the reader sizes, and the column
   being open or closed is the only thing that decides whether it shows. */
.ally-panel { height: 100%; min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden; border-left: 1px solid var(--line); background: var(--panel); }
/* The heading bar and its "A" mark were DELETED on 24 September 2026. Whatever that bar
   was worded to say, it put the assistant's identity at the top of the column and so
   read as the bot sitting above its own conversation. It was reported three times in two
   days and reworded twice before the answer turned out to be that it should not be
   there. The panel's accessible name is the `aria-label` on the <aside>. */

.ally-log article.opening { color: var(--muted); }
.ally-log article.opening p { margin: 0; }
/* THE CONVERSATION STARTS AT THE TOP AND THE BODY FILLS THE COLUMN.
   It used to be bottom-anchored with `margin-top: auto` on the first child, so a short
   conversation was pressed against the composer and everything above it was blank. In a
   full-height column that is most of the panel: measured on dev at 1280x720, the first
   words appeared at y=600 of a 667px column, leaving about 550px of empty white beside
   the page. Reported 24 Sep 2026 - "now I can see space after the vertical scroll" and
   "it should fill all the page".
   Reading order wins over hugging the box: the greeting and the suggested questions sit
   at the top where they are read first, the composer stays pinned at the bottom because
   it is a flex sibling and not part of this scroller, and the room between them is where
   the conversation grows. Once it is taller than the panel the script scrolls this box
   to its end, so the newest exchange still sits directly above the composer. */
.ally-body { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; }
.ally-log { padding: 12px; background: var(--soft); }
.ally-log article { padding: 11px; border: 1px solid var(--line); border-radius: 9px; background: var(--panel); }
.ally-log article + article { margin-top: 8px; }
.ally-log article.question { border-color: #cbd7f8; background: var(--accent-soft); }
.ally-log article.refused { border-color: #e7c98a; background: var(--warn-soft); }
.ally-log article.refused strong { color: var(--warn); }
.ally-log article.pending { border-style: dashed; }
.ally-log article.pending p { color: var(--muted); }
.ally-log strong { color: var(--accent); font-size: .72rem; }
.ally-log p { margin: 4px 0 0; font-size: .78rem; }
.ally-log small { display: block; margin-top: 7px; color: var(--muted); font-size: .68rem; }
.ally-log small a { color: var(--accent); }
.ally-questions { display: grid; gap: 6px; padding: 10px 12px; }
.ally-questions button { min-height: 44px; padding: 7px 9px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); color: var(--accent); font-size: .74rem; text-align: left; }
.ally-questions button:hover { border-color: var(--accent); background: var(--accent-soft); }
/* The composer is pinned: it sits outside .ally-body, which is the only thing that
   scrolls, so the box you type in never moves while the conversation does. */
.ally-composer { flex: 0 0 auto; padding: 10px 12px; border-top: 1px solid var(--line); background: var(--panel); }
.ally-composer-row { display: flex; align-items: center; gap: 8px; }
.ally-composer input { flex: 1; min-width: 0; min-height: 40px; padding: 8px 11px; border: 1px solid var(--line); border-radius: 9px; background: var(--panel); color: var(--ink); font: inherit; font-size: .78rem; }
.ally-composer input:focus-visible { border-color: var(--accent); outline: 2px solid var(--accent); outline-offset: 1px; }
.ally-send { display: flex; align-items: center; justify-content: center; width: 34px; height: 34px; flex: 0 0 auto; padding: 0; border: 0; border-radius: 50%; background: var(--accent); color: #fff; }
.ally-send svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.ally-send:disabled { background: var(--line); color: var(--muted); }
.ally-boundary-info { flex: 0 0 auto; width: 26px; height: 26px; font-size: .66rem; }

/* A label that a screen reader announces and nobody sees. The placeholder is not a
   label: it disappears the moment somebody types. */
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.noscript { margin: 20px; padding: 14px; border: 1px solid var(--line); background: var(--panel); }

.seat-card.is-preview { border: 1px solid #e7c98a; border-radius: 9px; background: var(--warn-soft); }
.seat-card.is-preview > span { background: #f6e6c6; color: var(--warn); }
.preview-note { margin: 8px 2px 0; color: var(--warn); font-size: .68rem; }
.preview-revert { margin: 8px 0 0; }
.preview-revert-button { width: 100%; min-height: 44px; padding: 8px 12px; border: 1px solid #e7c98a; border-radius: 8px; background: var(--panel); color: var(--warn); font-size: .76rem; font-weight: 650; }
.preview-revert-button:hover { background: var(--warn-soft); }

.preview-banner { display: flex; align-items: center; gap: 11px; margin-bottom: 14px; padding: 10px 13px; border: 1px solid #e7c98a; border-radius: 9px; background: var(--warn-soft); color: var(--warn); }
.preview-banner svg { flex: 0 0 21px; }
.preview-banner > span { display: block; font-size: .78rem; }
.preview-banner strong { margin-right: 7px; }
.preview-banner .preview-revert { flex: 0 0 auto; margin: 0; }
.preview-banner .preview-revert-button { width: auto; white-space: nowrap; }

.seat-error, .seat-notice { margin: 0 0 14px; padding: 11px 13px; border: 1px solid #f4d2d2; border-radius: 9px; background: var(--stop-soft); color: var(--stop); font-size: .82rem; }
.seat-notice { border-color: #c8e6d6; background: var(--ok-soft); color: var(--ok); }

.seat-panel { margin-bottom: 14px; padding: 18px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); box-shadow: var(--shadow); }
.seat-panel > p { max-width: 760px; color: var(--muted); font-size: .84rem; }
.seat-note { margin: 0; color: var(--muted); font-size: .76rem; }
.seat-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; margin: 0; }
.seat-field { display: grid; gap: 5px; }
.seat-field label { font-size: .8rem; font-weight: 650; }
.seat-form select, .seat-form input[type="text"] { min-height: 44px; padding: 9px 11px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); color: var(--ink); }
.seat-form.is-inline input[type="text"] { min-width: 180px; flex: 1 1 180px; }
.seat-submit { min-height: 44px; padding: 8px 14px; border: 0; border-radius: 8px; background: var(--accent); color: #fff; font-size: .8rem; font-weight: 650; }

.seat-table { width: 100%; border-collapse: collapse; font-size: .82rem; }
.seat-table caption { padding-bottom: 8px; color: var(--muted); font-size: .72rem; text-align: left; }
.seat-table th, .seat-table td { padding: 9px 10px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: middle; }
.seat-table thead th { color: var(--muted); font-size: .68rem; font-weight: 750; letter-spacing: .055em; text-transform: uppercase; }
.seat-table tbody th { font-weight: 650; }

.signout-form { margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--line); }
.signout-button { width: 100%; min-height: 44px; padding: 8px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); color: var(--ink); font-size: .8rem; font-weight: 650; }
.signout-button:hover { border-color: var(--stop); background: var(--stop-soft); color: var(--stop); }

.signin-page main { width: min(100%, 520px); margin: 0 auto; padding: 34px 18px 72px; }
.signin-card { padding: clamp(20px, 4vw, 32px); border: 1px solid var(--line); border-radius: 12px; background: var(--panel); box-shadow: var(--shadow); }
.signin-intro { color: var(--muted); }
.signin-error, .signin-notice { margin: 0 0 14px; padding: 11px 13px; border: 1px solid #f4d2d2; border-radius: 9px; background: var(--stop-soft); color: var(--stop); font-size: .82rem; }
.signin-notice { border-color: #c8e6d6; background: var(--ok-soft); color: var(--ok); }
.signin-form { display: grid; gap: 14px; margin-bottom: 18px; }
.signin-field { display: grid; gap: 5px; }
.signin-field label { font-size: .8rem; font-weight: 650; }
.signin-field input { min-height: 44px; padding: 9px 11px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); color: var(--ink); }
.signin-field input:hover { border-color: #b9c2d2; }
.signin-submit { width: 100%; margin-top: 2px; }
.signin-alt { margin: 14px 0 0; color: var(--muted); font-size: .8rem; }
.signin-alt a { color: var(--accent); }

.signin-providers { display: grid; gap: 9px; margin: 0 0 18px; padding-top: 16px; border-top: 1px solid var(--line); }
.signin-providers-label { margin: 0 0 2px; color: var(--muted); font-size: .78rem; font-weight: 650; }
.signin-provider { display: flex; align-items: center; justify-content: center; min-height: 44px; padding: 9px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); color: var(--ink); font-size: .84rem; font-weight: 650; text-decoration: none; }
.signin-provider:hover { border-color: var(--accent); color: var(--accent); }
.signin-provider:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (max-width: 1050px) {
  .console-shell { grid-template-columns: 1fr; }
  /* One track now, so the explicit placements above must go with it. Leaving
     `main` on column 3 against a single-track grid conjures two implicit
     columns and pushes the page off the side of a phone. Both panes are
     overlays at this width and the splitters have nothing to split. */
  .console-shell > .sidebar,
  .console-shell > main { grid-column: 1; }
  .console-shell > [data-splitter="left"] { display: none; }
  /* THE NAVIGATION'S collapse must not apply here. Its control is the divider, there is
     no divider at this width, and the off-canvas drawer has its own way in via the
     mobile menu button - so honouring `data-left-open="false"` would leave a phone with
     a pane it could never bring back. */
  .console-shell[data-left-open="false"] .sidebar { display: flex; }

  /* THE ASSISTANT IS A CHAT PANEL HERE, NOT A ROW.
     It used to be given `right/bottom/left: 0` while still statically positioned, so
     those three offsets did nothing at all and it stayed in the grid as a full-width
     band. The band took a row of a shell that is `overflow: hidden`, which left the
     conversation about forty pixels to live in: measured on dev at 1000x600, the log
     was clipped by 360px, so the answers could not be read and the input sat jammed
     against the bottom edge of the window. Reported twice, as "the AI Bot ... is in the
     Top (should be at buttom) and no text bar to type the prompt".
     It is now what it always said it was - docked bottom-right, above a launcher, with
     the conversation above the box you type in, which is the shape of every chat
     product and the shape that was asked for. */
  .ally-panel { position: fixed; z-index: 60; right: var(--edge-inset); bottom: calc(var(--edge-inset) * 2 + 44px); left: auto; width: min(clamp(300px, 88vw, 420px), calc(100vw - var(--edge-inset) * 2)); height: min(62dvh, 30rem); border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 12px 34px rgba(15, 23, 42, .26); }
  .console-shell[data-right-open="false"] > .ally-panel { display: none; }
  /* A sheet that cannot be shut would cover the page, so unlike the navigation the
     assistant's collapse DOES apply at this width. What made that unsafe before was
     that its only control lived on a hidden divider; the divider is now reduced to that
     control alone, floating, so there is always a way back. */
  .console-shell > [data-splitter="right"] { display: block; position: fixed; z-index: 61; right: var(--edge-inset); bottom: var(--edge-inset); width: 52px; height: 52px; background: none; }
  .console-shell > [data-splitter="right"]::after { display: none; }
  /* `.split` is named as well as the attribute so this ties with the desktop rule for a
     SHUT right-hand divider and, coming later, wins. Without it the launcher was 52px
     while open and 36px once shut - the desktop rule is a column affordance and has no
     business resizing a floating button. */
  .console-shell > .split[data-splitter="right"] .split-toggle { top: 0; bottom: auto; left: 0; width: 52px; height: 52px; border-radius: 50%; transform: none; border-color: var(--accent); background: var(--accent); color: #fff; box-shadow: 0 6px 18px rgba(15, 23, 42, .28); }
  .console-shell > .split[data-splitter="right"] .split-toggle:hover { border-color: var(--accent); color: #fff; }
  .console-shell > .split[data-splitter="right"] .split-toggle svg { width: 20px; height: 20px; }
  .sidebar { position: fixed; z-index: 45; top: var(--header-height); bottom: 0; left: 0; width: min(290px, 84vw); height: auto; transform: translateX(-102%); box-shadow: var(--shadow); transition: transform 200ms ease; }
  .sidebar.is-open { transform: none; }
  .mobile-menu-button { display: grid; }
  main { width: 100%; }
  .status-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .status-grid article:last-child { grid-column: 1 / -1; }
}

@media (max-width: 650px) {
  body { font-size: 16px; }
  .topbar { padding: 4px 12px; }
  .brand > span:last-child { display: none; }
  .scope-indicator { min-width: 0; max-width: 145px; }
  .scope-indicator span { display: none; }
  .scope-indicator strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .header-icon:not(.help-link) { display: none; }
  .page-heading { align-items: stretch; flex-direction: column; }
  .primary-action { align-self: flex-start; }
  main { padding: 18px 14px 112px; }
  .status-grid { grid-template-columns: 1fr; }
  .status-grid article:last-child { grid-column: auto; }
  .empty-card { grid-template-columns: 1fr; justify-items: start; }
  .boundary-line { align-items: flex-start; }
  .preview-banner { align-items: flex-start; flex-wrap: wrap; }
  .preview-banner .preview-revert-button { width: 100%; }
  .seat-form.is-inline { flex-direction: column; align-items: stretch; }
  .seat-table, .seat-table tbody, .seat-table tr, .seat-table th, .seat-table td { display: block; }
  .seat-table thead { display: none; }
  .seat-table tr { margin-bottom: 12px; border-bottom: 1px solid var(--line); }
  .seat-table th, .seat-table td { border-bottom: 0; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; transition-duration: .01ms !important; }
}

/* Phase 1: the agent register, the gate queue and the candidate portfolio. */
.record-panel { margin-bottom: 14px; padding: 18px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); box-shadow: var(--shadow); }
.record-panel > p { max-width: 820px; color: var(--muted); font-size: .84rem; }
.record-panel h3 { margin: 18px 0 6px; font-size: .92rem; }
.scope-note { margin: 0 0 10px; color: var(--muted); font-size: .78rem; }
.empty-note { margin: 0; max-width: 820px; color: var(--muted); font-size: .82rem; }
.absent { color: var(--muted); font-size: .78rem; font-style: italic; }
/* A plan judged on spend to date: allowed, but not a forecast pass, so neither the
   plain text of "Fits the forecast" nor the grey of "No budget set". */
.plan-on-spend { color: var(--warn); font-weight: 600; }
/* A level nobody could judge, let through by the organisation's budget policy: not a
   fit, not a refusal, and not the grey of an absence. */
.budget-unknown-allowed { color: var(--warn); font-style: italic; font-weight: 600; border-bottom: 1px dashed var(--warn); }

.record-table { width: 100%; border-collapse: collapse; font-size: .82rem; }
.record-table caption { padding-bottom: 8px; color: var(--muted); font-size: .72rem; text-align: left; }
.record-table th, .record-table td { padding: 9px 10px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.record-table thead th { color: var(--muted); font-size: .68rem; font-weight: 750; letter-spacing: .055em; text-transform: uppercase; }
.record-table tbody th { font-weight: 650; }
.record-table a { font-weight: 650; text-decoration-thickness: 1px; text-underline-offset: 2px; }

.record-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); gap: 10px; margin: 0; }
.record-facts div { min-width: 0; }
.record-facts dt { color: var(--muted); font-size: .68rem; font-weight: 750; letter-spacing: .055em; text-transform: uppercase; }
.record-facts dd { margin: 3px 0 0; font-size: .85rem; }

.stage-chip { display: inline-block; padding: 2px 8px; border-radius: 999px; background: var(--soft); border: 1px solid var(--line); font-size: .72rem; }
.stage-track { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 14px; padding: 0; list-style: none; }
.stage-step { padding: 4px 10px; border: 1px solid var(--line); border-radius: 999px; background: var(--soft); color: var(--muted); font-size: .74rem; }
.stage-step.is-current { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 700; }

.verdict { display: inline-block; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--line); background: var(--soft); font-size: .72rem; font-weight: 650; }
.verdict.is-pass, .verdict.is-allow { border-color: #bfe3d0; background: var(--ok-soft); color: var(--ok); }
.verdict.is-fail, .verdict.is-refuse { border-color: #f4d2d2; background: var(--stop-soft); color: var(--stop); }
.verdict.is-unread, .verdict.is-human { border-color: #f0dcb4; background: var(--warn-soft); color: var(--warn); }

/* The settings tabs, in five groups. The label is text and carries no hover, no
   pointer and no focus ring, because it is not a control and must not look like one. */
.section-tabs { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-bottom: 14px; }
.section-tab-group { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.section-tab-label { color: #7a828d; font-size: .64rem; font-weight: 750; letter-spacing: .07em; text-transform: uppercase; user-select: none; }
.section-tab-group + .section-tab-group { padding-left: 18px; border-left: 1px solid var(--line); }
.section-tab { min-height: 36px; display: inline-flex; align-items: center; padding: 6px 12px; border: 1px solid var(--line); border-radius: 999px; background: var(--panel); color: var(--muted); font-size: .8rem; text-decoration: none; }
.section-tab.is-current { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 700; }

.record-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); align-items: start; gap: 12px; margin: 0; }
.record-form.is-inline { display: block; margin-top: 12px; }
.record-form .field { display: flex; flex-direction: column; gap: 5px; min-width: 0; margin: 0; padding: 0; border: 0; }
.record-form label, .record-form legend { color: var(--muted); font-size: .72rem; font-weight: 750; letter-spacing: .04em; text-transform: uppercase; }
.record-form label.check { display: flex; flex-direction: row; align-items: center; gap: 6px; font-size: .82rem; font-weight: 500; letter-spacing: 0; text-transform: none; }
.record-form small { color: var(--muted); font-size: .72rem; }
.record-form input[type="text"], .record-form input[type="date"], .record-form select, .record-form textarea { min-height: 44px; padding: 9px 11px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); color: var(--ink); }
.record-form textarea { min-height: 72px; resize: vertical; }
.record-form button { grid-column: 1 / -1; justify-self: start; }

.lens-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 12px; }
.lens-card { min-width: 0; padding: 14px; border: 1px solid var(--line); border-radius: 9px; background: var(--soft); }
.lens-card h3 { margin: 0 0 6px; font-size: .88rem; }
.lens-card p { margin: 0 0 6px; font-size: .82rem; }
.lens-band { display: inline-block; padding: 2px 10px; border: 1px solid var(--line); border-radius: 999px; background: var(--panel); font-weight: 700; text-transform: capitalize; }

/* The four domain layers connected to the console: reports, review, risk,
   configuration and invitations. Every class below is used by a section in
   platform-console.html and by nothing else. */
.measure-code { display: inline-block; padding: 1px 6px; border: 1px solid var(--line); border-radius: 999px; background: var(--soft); color: var(--muted); font-size: .68rem; font-weight: 650; letter-spacing: .04em; }
/* R15: standard codes wrap as chips; where they came from sits on its own line beneath. */
.taxonomy-codes .measure-code { margin: 0 2px 4px 0; }
.taxonomy-source { display: block; margin-top: 2px; }
.taxonomy-reference summary { cursor: pointer; font-weight: 650; margin: 12px 0; }

/* A band is a colour with a word in it. The word is there because a colour alone
   is not readable to everybody, and grey says grey rather than saying nothing. */
.band { display: inline-block; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--line); background: var(--soft); color: var(--muted); font-size: .72rem; font-weight: 650; text-transform: capitalize; }
.band.is-green { border-color: #bfe3d0; background: var(--ok-soft); color: var(--ok); }
.band.is-amber { border-color: #f0dcb4; background: var(--warn-soft); color: var(--warn); }
.band.is-red { border-color: #f4d2d2; background: var(--stop-soft); color: var(--stop); }
.band.is-grey { border-color: var(--line); background: var(--soft); color: var(--muted); }

.heat-map { table-layout: auto; }
.heat-cell { font-size: .76rem; }
.heat-cell.is-green { background: var(--ok-soft); }
.heat-cell.is-amber { background: var(--warn-soft); }
.heat-cell.is-red { background: var(--stop-soft); }
.heat-cell.is-grey { background: var(--soft); color: var(--muted); }

.severity { display: inline-block; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--line); background: var(--soft); font-size: .72rem; font-weight: 650; text-transform: capitalize; }
.severity.is-critical, .severity.is-high { border-color: #f4d2d2; background: var(--stop-soft); color: var(--stop); }
.severity.is-medium { border-color: #f0dcb4; background: var(--warn-soft); color: var(--warn); }
.severity.is-low { border-color: var(--line); background: var(--soft); color: var(--muted); }

.missing-list { margin: 0; padding-left: 18px; color: var(--muted); font-size: .82rem; }
.missing-list li { margin-bottom: 4px; }

.builder-options { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 10px; }
.builder-option { min-width: 0; min-height: 44px; display: flex; flex-direction: column; gap: 4px; padding: 12px 14px; border: 1px solid var(--line); border-radius: 9px; background: var(--soft); text-decoration: none; }
.builder-option strong { font-size: .88rem; }
.builder-option span { color: var(--muted); font-size: .78rem; }
.builder-option:hover { border-color: var(--accent); background: var(--accent-soft); }

.stage-step.is-next { border-color: var(--warn); background: var(--warn-soft); color: var(--warn); font-weight: 700; }

/* The one response that carries a clear invitation link. It is marked so nobody
   mistakes it for something they can come back to: there is no second copy. */
.record-panel.is-once { border-color: var(--warn); background: var(--warn-soft); }
.invitation-token { overflow-wrap: anywhere; margin: 0 0 12px; font-size: .84rem; }
.invitation-token code { padding: 6px 9px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); }

/* THE STATUS BAR. What the page is standing on — release, tenant, seat — plus the two
   panel toggles, which is where a workbench keeps them. It is the last line of the
   document and it does not scroll away. */
