/* ─────────────────────────────────────────────────────────────────
   Architrave × Compliance Viewer — application styles
   Consumes the design tokens from colors_and_type.css.
   Drop-in replacement for viewer/static/style.css.
   ───────────────────────────────────────────────────────────────── */

@import url("colors_and_type.css");

/* ── Reset ────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 20px;
  color: var(--ink);
  background: var(--sky-lighter);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

button { font-family: inherit; }
.hidden { display: none !important; }

/* ── App skeleton ─────────────────────────────────────────── */
.app {
  display: grid;
  grid-template-rows: 48px 1fr;
  /* `minmax(0, 1fr)`, not `1fr`: an `auto` minimum takes the widest thing in
     the column as a floor, and the top bar's row of controls is wider than a
     narrow window. The column would then outgrow the viewport, and the panes
     would never see the width the window actually gives them. */
  grid-template-columns: 236px minmax(0, 1fr);
  height: 100vh;
  overflow: hidden;
  /* the rail peek overlay anchors to this box */
  position: relative;
}
/* The rail runs the full height and carries the brand; the top bar starts to
   the right of it. Both cells are placed by hand: a hover peek takes the rail
   out of the flow, and auto-placement would then slide the workspace into the
   rail's column. */
.topbar { grid-column: 2; grid-row: 1; }
.rail { grid-column: 1; grid-row: 1 / -1; z-index: 40; }
.workspace { grid-column: 2; grid-row: 2; }
.app.rail-collapsed { grid-template-columns: 64px minmax(0, 1fr); }

/* ── Top bar ──────────────────────────────────────────────── */
.topbar {
  background: var(--surface-raised);
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 16px;
  box-shadow: var(--hairline-inset);
  position: relative;
  z-index: 30;
}

/* project switcher (top bar, left of the asset switcher) — shares the asset
   switcher's inner classes so the two read as one control pair. `.static` is the
   single-project case: a label, not a target. */
.project-switcher {
  display: flex; align-items: center; gap: 12px;
  height: 32px;
  background: var(--sky-light);
  border-radius: 4px;
  padding: 0 12px;
  cursor: pointer;
  min-width: 180px;
  max-width: 260px;
  position: relative;
  user-select: none;
  transition: background .15s;
}
.project-switcher:hover { background: var(--surface-hover); }
.project-switcher.static { cursor: default; background: transparent; }
.project-switcher.static:hover { background: transparent; }
.project-switcher .material-icons { font-size: 20px; color: var(--ink-lighter); flex-shrink: 0; }
.project-switcher .as-label {
  font: 400 10px/12px var(--font-sans);
  color: var(--ink-lighter);
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
.project-switcher .as-value {
  font: 500 13px/16px var(--font-sans);
  color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.project-switcher .as-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.project-switcher .as-arrow { color: var(--ink-lighter); flex-shrink: 0; }

/* asset switcher (top bar center) */
.asset-switcher {
  display: flex; align-items: center; gap: 12px;
  height: 32px;
  background: var(--sky-light);
  border-radius: 4px;
  padding: 0 12px;
  cursor: pointer;
  min-width: 320px;
  max-width: 480px;
  position: relative;
  user-select: none;
  transition: background .15s;
}
.asset-switcher:hover { background: var(--surface-hover); }
.asset-switcher .material-icons { font-size: 20px; color: var(--ink-lighter); flex-shrink: 0; }
.asset-switcher .as-label {
  font: 400 10px/12px var(--font-sans);
  color: var(--ink-lighter);
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
.asset-switcher .as-value {
  font: 500 13px/16px var(--font-sans);
  color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.asset-switcher .as-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.asset-switcher .as-arrow { color: var(--ink-lighter); flex-shrink: 0; }

/* asset switcher dropdown */
.as-popover {
  position: absolute;
  top: calc(100% + 6px);
  left: 0; right: 0;
  background: var(--surface-raised);
  border-radius: 8px;
  box-shadow: var(--depth-02);
  border: 1px solid var(--sky);
  padding: 8px 0;
  max-height: 480px;
  overflow-y: auto;
  z-index: 200;
  display: none;
}
.as-popover.open { display: block; }
.as-popover-search {
  padding: 8px 12px;
  border-bottom: 1px solid var(--sky);
  display: flex; align-items: center; gap: 8px;
}
.as-popover-search input {
  flex: 1; border: 0; outline: none;
  font: 400 14px/20px var(--font-sans);
  color: var(--ink);
  background: transparent;
}
.as-popover-search .material-icons { font-size: 18px; color: var(--ink-lighter); }
.as-asset {
  padding: 8px 16px;
  font: 400 14px/20px var(--font-sans);
  color: var(--ink);
  cursor: pointer;
  display: flex; align-items: center; gap: 8px;
}
.as-asset:hover { background: var(--sky-light); }
.as-asset.active { background: var(--blue-tint-bg); color: var(--blue-tint-fg); font-weight: 500; }
.as-asset .as-asset-meta {
  margin-left: auto;
  font: 400 12px/16px var(--font-sans);
  color: var(--ink-lighter);
}

/* topbar right cluster */
.topbar-actions {
  display: flex; align-items: center; gap: 4px;
  margin-left: auto;
}
.icon-btn {
  width: 36px; height: 36px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-lighter);
  background: transparent;
  border: 0; cursor: pointer;
  transition: background .15s, color .15s;
}
.icon-btn:hover { background: var(--sky-light); color: var(--ink); }
.icon-btn .material-icons { font-size: 22px; }

.locale-switcher {
  display: inline-flex;
  border: 1px solid var(--sky);
  border-radius: 4px;
  overflow: hidden;
  background: var(--surface-raised);
  height: 32px;
  margin-right: 8px;
}
.locale-switcher button {
  border: 0; background: transparent;
  padding: 0 12px;
  font: 500 12px/16px var(--font-sans);
  color: var(--ink-lighter);
  letter-spacing: 1.25px;
  cursor: pointer;
  text-transform: uppercase;
}
.locale-switcher button + button { border-left: 1px solid var(--sky); }
.locale-switcher button:hover { background: var(--sky-light); color: var(--ink); }
.locale-switcher button.active { background: var(--blue); color: var(--text-on-accent); }

.avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--blue);
  color: var(--text-on-accent);
  display: flex; align-items: center; justify-content: center;
  font: 500 12px/16px var(--font-sans);
  cursor: pointer;
  margin-left: 8px;
}

/* ── Left rail (domain navigation) ────────────────────────── */
/* Dark in both themes — see the --rail-* tokens in colors_and_type.css. The
   rail is the only surface that steps out of the workspace, so it does not
   follow the theme; nothing but `.rail` reads those tokens. */
.rail {
  background: var(--rail-bg);
  border-right: 0;
  display: flex; flex-direction: column;
  padding: 0;
}
/* The header and the foot keep their height, so only the list scrolls. */
.rail-body {
  flex: 1; min-height: 0;
  overflow-y: auto; overflow-x: hidden;
  padding: 8px 0;
}
.rail-section-label {
  padding: 16px 20px 4px;
  font: 700 10px/16px var(--font-sans);
  color: var(--rail-text-faint);
  letter-spacing: 1.5px;
  text-transform: uppercase;
}
/* The narrow styling hangs off the rail, not off `.app.rail-collapsed`: during a
   hover peek `.app` still holds `rail-collapsed` — the grid column must stay
   64px so the content does not move — while the rail has to look expanded. */
.rail-narrow .rail-section-label { display: none; }

.rail-item {
  display: flex; align-items: center;
  gap: 12px;
  padding: 0 22px;
  height: 40px;
  font: 400 14px/20px var(--font-sans);
  color: var(--rail-text-dim);
  cursor: pointer;
  transition: background .15s, color .15s;
  white-space: nowrap;
  position: relative;
}
.rail-item:hover { background: var(--rail-hover); color: var(--rail-text); }
/* An inset shadow rather than a border: the entry keeps its padding in both
   states, so the icons do not shift by 3px when a page becomes active. */
.rail-item.active {
  background: var(--rail-active);
  color: var(--rail-text);
  box-shadow: inset 3px 0 0 var(--rail-accent);
}
.rail-item .material-icons {
  font-size: 20px; color: inherit; flex-shrink: 0;
}
.rail-item .rail-count {
  margin-left: auto;
  font: 400 12px/16px var(--font-sans);
  color: var(--rail-text-faint);
  background: var(--rail-hover);
  padding: 2px 8px;
  border-radius: 999px;
  min-width: 20px;
  text-align: center;
}
.rail-item.active .rail-count { background: var(--rail-accent); color: var(--rail-text); }
/* A count that says something is LATE. Its own token pair rather than
   `--ink` on `--warning`: the rail keeps one look in both themes, and --ink
   turns light in the dark one, which would put pale grey on yellow. The active
   entry does not override it — which page is open says nothing about whether a
   delivery is overdue. */
.rail-item .rail-count.is-warning,
.rail-item.active .rail-count.is-warning {
  background: var(--rail-warn-bg); color: var(--rail-warn-fg);
}
.rail-narrow .rail-item .rail-label,
.rail-narrow .rail-item .rail-count,
.rail-narrow .rail-item .rail-arrow { display: none; }

.rail-group { }
.rail-group-header {
  display: flex; align-items: center;
  gap: 12px;
  padding: 0 22px;
  height: 40px;
  font: 500 12px/16px var(--font-sans);
  color: var(--rail-text-dim);
  cursor: pointer;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  user-select: none;
}
.rail-group-header:hover { background: var(--rail-hover); color: var(--rail-text); }
.rail-group-header .material-icons { font-size: 18px; }
.rail-group-header .rail-arrow {
  margin-left: auto;
  font-size: 18px;
  transition: transform .2s;
}
.rail-group.expanded .rail-arrow { transform: rotate(180deg); }
.rail-group-children { display: none; padding: 4px 0 8px; }
.rail-group.expanded .rail-group-children { display: block; }
.rail-group-children .rail-item {
  padding-left: 54px;
  height: 36px;
  font-size: 13px;
}
/* The second selector outranks `.rail-group.expanded .rail-group-children`,
   which is equally specific and would otherwise win on order alone. */
.rail-narrow .rail-group-children,
.rail-narrow .rail-group.expanded .rail-group-children { display: none; }
/* A group header is not a `.rail-item`, so the rule above does not reach its
   label or arrow. */
.rail-narrow .rail-group-header .rail-label,
.rail-narrow .rail-group-header .rail-arrow { display: none; }

.rail-divider {
  height: 1px; background: var(--rail-line); margin: 8px 16px;
}

/* 48px, the same height as the top bar beside it: the brand and the asset
   switcher stand on one line. */
.rail-header {
  display: flex; align-items: center; justify-content: space-between;
  height: 48px; flex-shrink: 0;
  padding: 0 14px 0 16px;
  gap: 12px;
  border-bottom: 1px solid var(--rail-line);
}
.rail-brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.rail-glyph {
  width: 30px; height: 30px; border-radius: 8px;
  display: block; flex-shrink: 0;
  cursor: pointer;
}
.rail-brand-text { display: flex; flex-direction: column; min-width: 0; }
.rail-brand-name {
  font: 700 15px/18px var(--font-sans);
  color: var(--rail-text);
  letter-spacing: 0.2px;
  white-space: nowrap;
}
.rail-brand-sub {
  font: 400 12px/15px var(--font-sans);
  color: var(--rail-text-mid);
  white-space: nowrap;
}
/* Narrow, the glyph is the only thing left in the header — and it is the
   control that brings the rail back. */
.rail-narrow .rail-header { justify-content: center; padding: 0; }
.rail-narrow .rail-brand-text { display: none; }
.rail-narrow .rail-toggle { display: none; }
.rail-toggle {
  display: flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  border: 0; border-radius: 4px;
  background: transparent;
  color: var(--rail-text-dim);
  cursor: pointer;
  transition: background .15s, color .15s;
}
.rail-toggle:hover { background: var(--rail-hover); color: var(--rail-text); }
.rail-toggle .material-icons { font-size: 20px; }

/* The foot sits at the bottom even when the list is shorter than the rail, and
   it names what the arrow does. Narrow, only the arrow is left. */
.rail-foot {
  flex-shrink: 0;
  display: flex; align-items: center; gap: 12px;
  height: 48px; width: 100%;
  padding: 0 22px;
  border: 0; border-top: 1px solid var(--rail-line);
  background: transparent;
  color: var(--rail-text-mid);
  font: 400 13px/16px var(--font-sans);
  text-align: left;
  cursor: pointer;
}
.rail-foot:hover { background: var(--rail-hover); color: var(--rail-text); }
.rail-foot .material-icons { font-size: 18px; }
.rail-narrow .rail-foot { justify-content: center; padding: 0; }
.rail-narrow .rail-foot .rail-label { display: none; }

/* The hover peek. The rail has a definite grid position, so an absolute rail is
   positioned against its own grid area — column 1, both rows — not against the
   grid container. The offsets are therefore 0: the grid area is already the full
   height of the app. Only the width grows, and it overflows the 64px column
   because the column itself must not change; that is what holds the content
   still. It keeps the rail's own z-index (40): the peek overflows into the top
   bar's column, and under 30 the bar would cut off its first 64px. */
.rail.rail-peek {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 236px;
  box-shadow: var(--depth-02);
}

/* ── Main workspace ───────────────────────────────────────── */
.workspace {
  display: grid;
  grid-template-columns: 1fr;
  overflow: hidden;
  position: relative;
}
.workspace.with-doc { grid-template-columns: 1fr var(--doc-width, 480px); }
.workspace.with-doc.with-doc-collapsed { grid-template-columns: 1fr 56px; }

/* Subtle separation between rail / workspace / doc viewer.
   The workspace already has --sky-lighter background; rails are white,
   so a 1px sky line is the only chrome they need. */
.workspace { border-left: 1px solid var(--sky); }

.content {
  overflow-y: auto;
  background: var(--sky-lighter);
}
.content-inner {
  padding: 24px 32px 64px;
}

/* v2 page wrapper — symmetric gutters from the rail/doc edges.
   No max-width: workspace is the canvas; padding stays constant whether
   the doc viewer is open or closed. */
.page {
  padding: 24px 32px 64px;
  height: 100%;
  min-height: 0;
  overflow-y: auto;
  background: var(--sky-lighter);
}

/* Table pages: the table pane is the scroll container, not .page.
   A pane with overflow-x:auto nested inside a vertically scrolling .page also
   becomes a vertical scroll container, and a sticky header inside it then
   sticks to nothing. So .page stops scrolling and hands the job down. */
.page.page-table {
  display: flex; flex-direction: column;
  overflow: hidden;
  padding-bottom: 24px;
}
/* Everything above the table: PageHead or the topic band, and the page toolbar. */
.page-table-head { flex: 0 1 auto; overflow-y: auto; }

/* ── Page header pattern ──────────────────────────────────── */
.crumb {
  display: flex; align-items: center; gap: 6px;
  font: 400 12px/16px var(--font-sans);
  color: var(--ink-lighter);
  margin-bottom: 12px;
}
.crumb .material-icons { font-size: 14px; color: var(--ink-lightest); }
.crumb .crumb-current { color: var(--ink); font-weight: 500; }

.page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; flex-wrap: wrap;
  margin-bottom: 24px;
}
.page-title {
  font: 400 28px/36px var(--font-sans);
  color: var(--ink);
  letter-spacing: -0.2px;
  margin: 0 0 4px 0;
}
.page-subtitle {
  font: 400 14px/20px var(--font-sans);
  color: var(--ink-lighter);
  margin: 0;
}
.page-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* Buy/sell switch */
.switch-pill {
  display: inline-flex;
  border: 1px solid var(--sky);
  border-radius: 4px;
  background: var(--surface-raised);
  height: 32px;
  overflow: hidden;
}
.switch-pill .opt {
  font: 500 12px/16px var(--font-sans);
  letter-spacing: 1.25px;
  text-transform: uppercase;
  color: var(--ink-lighter);
  padding: 0 14px;
  display: flex; align-items: center;
  cursor: pointer;
  border: 0;
  background: transparent;
}
.switch-pill .opt.on { background: var(--blue); color: var(--text-on-accent); }

/* ── Buttons ──────────────────────────────────────────────── */
.btn {
  font: var(--t-button-weight) var(--t-button-size)/var(--t-button-lh) var(--font-sans);
  letter-spacing: var(--t-button-tracking);
  text-transform: uppercase;
  border: 0;
  border-radius: 4px;
  padding: 8px 14px;
  height: 36px;
  display: inline-flex; align-items: center; gap: 6px;
  cursor: pointer;
  transition: background .15s, color .15s, box-shadow .15s;
}
.btn .material-icons { font-size: 18px; }
.btn-primary { background: var(--blue-tint-bg); color: var(--blue-tint-fg); }
.btn-primary:hover { background: var(--primary-hover); }
.btn-base { background: var(--surface-raised); color: var(--ink); border: 1px solid var(--sky); }
.btn-base:hover { background: var(--sky-light); }
.btn-text { background: transparent; color: var(--ink-light); }
.btn-text:hover { background: var(--sky-light); color: var(--ink); }
.btn-blue { background: var(--blue); color: var(--text-on-accent); }
.btn-blue:hover { background: var(--blue-dark); }
.btn-success { background: var(--success); color: var(--text-on-accent); }
.btn-success:hover { background: var(--success-dark); }
.btn-critical { background: var(--critical); color: var(--text-on-accent); }
.btn-critical:hover { background: var(--critical-dark); }
.btn-sm { height: 28px; padding: 4px 10px; font-size: 12px; }
.btn-icon { width: 36px; padding: 0; justify-content: center; }
.btn-icon.btn-sm { width: 28px; }

/* ── Cards (universal) ────────────────────────────────────── */
.card {
  background: var(--surface-raised);
  border: 1px solid var(--sky);
  border-radius: 8px;
  overflow: hidden;
  transition: box-shadow .15s, border-color .15s;
}
.card.is-hoverable { cursor: pointer; }
.card.is-hoverable:hover { box-shadow: var(--depth-02); }
.card-section {
  padding: 16px 20px;
}
.card-section + .card-section { border-top: 1px solid var(--sky); }
.card-head {
  padding: 16px 20px;
  display: flex; align-items: center;
  gap: 12px;
  border-bottom: 1px solid var(--sky);
}
.card-title {
  font: 500 16px/24px var(--font-sans);
  color: var(--ink);
  margin: 0;
  letter-spacing: 0.15px;
}
.card-subtitle {
  font: 400 12px/16px var(--font-sans);
  color: var(--ink-lighter);
  margin-top: 2px;
}
.card-actions { margin-left: auto; display: flex; gap: 4px; align-items: center; }

/* Section header for content groups */
.section-overline {
  font: 700 10px/16px var(--font-sans);
  color: var(--ink-lighter);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  margin: 0 0 12px;
}
.section-title-h {
  font: 500 20px/24px var(--font-sans);
  letter-spacing: 0.15px;
  color: var(--ink);
  margin: 0 0 16px;
}

/* ── Stat tiles ───────────────────────────────────────────── */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}
.stat {
  background: var(--surface-raised);
  border: 1px solid var(--sky);
  border-radius: 8px;
  padding: 20px;
  display: flex; flex-direction: column; gap: 4px;
}
.stat-label {
  font: 700 10px/16px var(--font-sans);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ink-lighter);
}
.stat-value {
  font: 300 34px/40px var(--font-sans);
  color: var(--ink);
  letter-spacing: 0.25px;
}
.stat-value.t-num { font-weight: 400; }
.stat-trend {
  font: 400 12px/16px var(--font-sans);
  color: var(--ink-lighter);
  display: flex; align-items: center; gap: 4px;
}
.stat-trend .material-icons { font-size: 14px; }
.stat-trend.up { color: var(--success-dark); }
.stat-trend.down { color: var(--critical-dark); }
.stat-accent { border-left: 4px solid var(--blue); }
.stat-accent.success { border-left-color: var(--success); }
.stat-accent.warning { border-left-color: var(--warning); }
.stat-accent.critical { border-left-color: var(--critical); }

/* ── Filter / toolbar ─────────────────────────────────────── */
.toolbar {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 16px; flex-wrap: wrap;
}
.toolbar .toolbar-spacer { flex: 1; }
.filter-chip {
  display: inline-flex; align-items: center; gap: 6px;
  height: 32px;
  padding: 0 12px;
  border-radius: 4px;
  background: var(--surface-raised);
  border: 1px solid var(--sky);
  font: 400 13px/16px var(--font-sans);
  color: var(--ink-light);
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
}
.filter-chip:hover { background: var(--sky-light); }
.filter-chip.active {
  background: var(--blue-lightest);
  border-color: var(--blue);
  color: var(--blue);
  font-weight: 500;
}
.filter-chip .material-icons { font-size: 16px; }

.search-input {
  display: inline-flex; align-items: center; gap: 8px;
  height: 36px;
  padding: 0 12px;
  background: var(--surface-raised);
  border: 1px solid var(--sky);
  border-radius: 4px;
  min-width: 240px;
}
.search-input input {
  flex: 1; border: 0; outline: none;
  font: 400 14px/20px var(--font-sans);
  color: var(--ink);
  background: transparent;
}
.search-input .material-icons { font-size: 18px; color: var(--ink-lighter); }
.search-input:focus-within { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(0,145,255,0.10); }

.select {
  height: 36px;
  padding: 0 30px 0 12px;
  background: var(--surface-raised) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%23637381' d='M6 7L0 1l1.4-1.4L6 4.2 10.6-.4 12 1z'/%3E%3C/svg%3E") no-repeat right 12px center;
  border: 1px solid var(--sky);
  border-radius: 4px;
  font: 400 14px/20px var(--font-sans);
  color: var(--ink);
  appearance: none;
  cursor: pointer;
  min-width: 140px;
}
.select:hover { border-color: var(--sky-dark); }
.select:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(0,145,255,0.10); }

/* ── Validation dot system (Architrave semantic colors) ─── */
.vdot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  margin-right: 8px;
  vertical-align: middle;
  cursor: pointer;
  flex-shrink: 0;
  transition: transform .15s, box-shadow .15s;
}
.vdot:hover { transform: scale(1.4); }
.vdot.active { transform: scale(1.5); box-shadow: 0 0 0 3px rgba(0,145,255,0.35); }

/* Fixed-position tooltip for .vdot — escapes overflow:hidden ancestors */
.vtip {
  position: fixed;
  transform: translate(-50%, calc(-100% - 8px));
  background: var(--ink);
  color: var(--surface-raised);
  font: 500 11px/14px var(--font-sans);
  letter-spacing: 0.01em;
  padding: 5px 8px;
  border-radius: 6px;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 4px 12px rgba(15,23,42,.18);
  z-index: 9999;
}
/* A dot that carries gate reasons shows them under the status line, so the
   tooltip has to wrap. `nowrap` above keeps the one-line case unchanged. */
.vtip-reasons {
  white-space: normal;
  max-width: 260px;
  text-align: left;
}
.vtip-reason {
  display: block;
  margin-top: 3px;
  font-weight: 400;
  opacity: 0.82;
}
.vtip::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 100%;
  transform: translateX(-50%);
  border: 4px solid transparent;
  border-top-color: var(--ink);
}
/* green = human validated */
.vdot-validated { background: var(--success); box-shadow: 0 0 0 2px rgba(88,188,130,0.20); }
/* blue = AI accepted (high confidence) */
.vdot-ai { background: var(--blue); box-shadow: 0 0 0 2px rgba(0,145,255,0.18); }
/* yellow = needs review */
.vdot-review { background: var(--warning); box-shadow: 0 0 0 2px rgba(255,212,0,0.25); }
/* red = critical / flagged */
.vdot-critical { background: var(--critical); box-shadow: 0 0 0 2px rgba(246,86,86,0.20); }
/* half green = some of the attribute's entries are confirmed, not all. Split
   rather than tinted: this is the one status that reports progress instead of a
   verdict, and a paler green reads as a weaker verdict. */
.vdot-partial {
  background: linear-gradient(90deg, var(--success) 50%, var(--sky-dark) 50%);
  box-shadow: 0 0 0 2px rgba(88,188,130,0.20);
}
/* red with a wider ring = a human rejected one of the entries. Same colour as a
   pipeline conflict, because both say "do not use this value"; the ring is what
   separates a judgement from a detection. */
.vdot-flagged { background: var(--critical); box-shadow: 0 0 0 3px rgba(246,86,86,0.40); }
/* an open ring = a note holds this value and the document is still owed. No
   fill and no halo, because it is not a finding: nothing is wrong with the
   value, a paper is missing behind it. Tokens on both sides, so the ring keeps
   its contrast in the dark theme where a fixed grey would sink into the cell. */
.vdot-note {
  background: var(--surface-raised);
  border: 2px solid var(--ink-light);
  box-sizing: border-box;
  box-shadow: none;
}
/* Inside a table cell the dots are 6px, and a 2px ring on 6px leaves no hole. */
.et .et-cell > .vdot-note { border-width: 1.5px; }

.vdot-legend {
  display: inline-flex; align-items: center; gap: 16px;
  font: 400 12px/16px var(--font-sans);
  color: var(--ink-lighter);
  flex-wrap: wrap;
}
.vdot-legend > span { display: inline-flex; align-items: center; }

/* ── Field rows ───────────────────────────────────────────── */
.field-list { padding: 4px 0; }
.field-row {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 16px;
  padding: 10px 0;
  border-bottom: 1px solid var(--sky-light);
  align-items: baseline;
}
.field-row:last-child { border-bottom: none; }
.field-label {
  font: 400 12px/16px var(--font-sans);
  letter-spacing: 0.4px;
  color: var(--ink-lighter);
}
.field-value {
  font: 400 14px/20px var(--font-sans);
  color: var(--ink);
  display: flex; align-items: center; gap: 4px; flex-wrap: wrap;
}
.field-value.is-mono { font-family: var(--font-mono); font-size: 13px; }
.field-value.is-empty { color: var(--ink-lightest); font-style: italic; }
.field-value-prev {
  margin-left: 6px;
  font-size: 12px;
  color: var(--ink-lightest);
  text-decoration: line-through;
}

.citation-link {
  display: inline-flex; align-items: center; gap: 4px;
  height: 22px;
  padding: 0 8px;
  margin-left: 6px;
  background: var(--sky-light);
  color: var(--ink-lighter);
  border: 1px solid var(--sky);
  border-radius: 4px;
  font: 500 11px/14px var(--font-sans);
  letter-spacing: 0.4px;
  cursor: pointer;
  text-transform: uppercase;
}
.citation-link:hover { background: var(--blue-lightest); color: var(--blue); border-color: var(--blue-lighter); }
.citation-link .material-icons { font-size: 13px; }

/* ── Tables ───────────────────────────────────────────────── */
.data-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface-raised);
  border: 1px solid var(--sky);
  border-radius: 8px;
  overflow: hidden;
}
.data-table thead th {
  background: var(--sky-light);
  text-align: left;
  padding: 10px 16px;
  font: 700 10px/16px var(--font-sans);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ink-lighter);
  border-bottom: 1px solid var(--sky);
  white-space: nowrap;
}
.data-table tbody td {
  padding: 14px 16px;
  font: 400 14px/20px var(--font-sans);
  color: var(--ink);
  border-bottom: 1px solid var(--sky);
  vertical-align: middle;
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr.is-clickable { cursor: pointer; }
.data-table tbody tr:hover { background: var(--sky-lighter); }
.data-table tbody tr.is-selected { background: var(--blue-lightest); }
.data-table tbody tr.is-selected:hover { background: var(--blue-lightest); }
.data-table .num { font-variant-numeric: tabular-nums; text-align: right; }
.data-table .id-cell { font-family: var(--font-mono); font-size: 13px; color: var(--ink-light); }
.data-table .actions-cell { text-align: right; white-space: nowrap; }

/* ── Badges / chips (status, priority, semantic) ──────────── */
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  font: 500 11px/16px var(--font-sans);
  letter-spacing: 0.4px;
  text-transform: uppercase;
  white-space: nowrap;
}
.badge .material-icons { font-size: 13px; }
.badge-success { background: var(--success-lightest); color: var(--success-darker); }
.badge-warning { background: var(--badge-warning-bg); color: var(--badge-warning-fg); }
.badge-critical { background: var(--critical-lightest); color: var(--critical-darker); }
.badge-info { background: var(--blue-lightest); color: var(--blue-darker); }
.badge-neutral { background: var(--sky-light); color: var(--ink-light); }
.badge-purple { background: var(--badge-purple-bg); color: var(--badge-purple-fg); }
/* A note is an open place, not a finding, so it gets the outline the dot gets
   rather than a severity colour: nothing is wrong with the value, a paper is
   missing behind it. Dashed, as the design draws it (line 2105). */
.badge-note {
  background: transparent; color: var(--ink-light);
  border: 1px dashed var(--ink-lighter);
}

.usage-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font: 500 12px/16px var(--font-sans);
  color: var(--text-on-accent);
  white-space: nowrap;
}
.usage-chip-residential { background: #4D7CFF; }
.usage-chip-office      { background: #2196F3; }
.usage-chip-retail      { background: #00897B; }
.usage-chip-industrial  { background: #455A64; }
.usage-chip-mixed       { background: #7B61FF; }
.usage-chip-storage     { background: #607D8B; }

/* ── Empty / loading states ──────────────────────────────── */
.empty {
  text-align: center;
  padding: 64px 24px;
  color: var(--ink-lighter);
}
.empty .material-icons {
  font-size: 48px;
  color: var(--ink-lightest);
  margin-bottom: 12px;
}
.empty-title {
  font: 500 16px/24px var(--font-sans);
  color: var(--ink);
  margin: 0 0 4px;
}
.empty-body { font: 400 14px/20px var(--font-sans); margin: 0 0 16px; }
.loading-row {
  padding: 24px;
  font: 400 13px/16px var(--font-sans);
  color: var(--ink-lighter);
  text-align: center;
}

/* ── Right column: attribute panel over the source view ────
   One column, split horizontally. The upper pane is the attribute source panel,
   the lower one the source view; the handle between them moves the boundary, and
   the handle on the left edge moves the column's own width. Present only while a
   cell is selected — without a selection the source view keeps the column to
   itself and behaves exactly as it did before. */
.rc {
  background: var(--surface-raised);
  padding-left: 6px;
  display: flex; flex-direction: column;
  overflow: hidden;
  position: relative;
  min-width: 56px;
}
.rc-top { flex: 0 0 auto; overflow: hidden; min-height: 120px; }
.rc-hsplit {
  flex: 0 0 auto;
  height: 6px;
  background: var(--sky);
  cursor: row-resize;
}
.rc-hsplit:hover { background: var(--blue-lighter); }
.rc-bottom {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
}
.rc-empty {
  padding: 20px;
  font: 400 13px/20px var(--font-sans);
  color: var(--ink-lighter);
}
/* ── Source view: rule and reference value ────────────────
   The two kinds of evidence that are not a document. Same frame as the document
   viewer above them — a head that names the source and a scrolling body — so
   walking the entry list does not change what the lower pane looks like. */
.sv { display: flex; flex-direction: column; height: 100%; min-height: 0; overflow: hidden; }
.sv-head {
  padding: 10px 16px;
  border-bottom: 1px solid var(--sky);
  background: var(--sky-light);
  flex-shrink: 0;
}
.sv-title { font: 500 14px/18px var(--font-sans); color: var(--ink); margin: 0; }
.sv-tags { display: flex; gap: 6px; margin-top: 4px; flex-wrap: wrap; }
.sv-tag {
  font: 500 10px/14px var(--font-sans);
  letter-spacing: 0.4px;
  text-transform: uppercase;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--sky);
  color: var(--ink-light);
  white-space: nowrap;
}
/* A rule id is a machine identifier: it reads as it is written, not in the small
   caps the word badges beside it use. */
.sv-tag.mono { text-transform: none; letter-spacing: 0; }
.sv-source { font: 400 12px/17px var(--font-sans); color: var(--ink-lighter); margin-top: 4px; }
.sv-body { flex: 1 1 auto; overflow-y: auto; min-height: 0; padding: 12px 16px; }
/* A table brings its own cell padding, and a padded scrollport leaves the sticky
   heading floating a row below the top edge with one row uncovered above it. */
.sv-body.is-table { padding: 0; }
.sv-field { margin-bottom: 14px; }
.sv-field-label {
  font: 700 10px/16px var(--font-sans);
  color: var(--ink-lighter);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  margin-bottom: 4px;
}
.sv-formula {
  font: 400 12px/20px var(--font-mono);
  color: var(--ink-light);
  background: var(--sky-lighter);
  border-radius: 4px;
  padding: 8px 10px;
  white-space: pre-wrap;
  word-wrap: break-word;
}
.sv-result { font: 500 13px/20px var(--font-sans); color: var(--ink); }
.sv-input {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid var(--sky-lighter);
}
.sv-input:last-child { border-bottom: 0; }
.sv-input-body { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.sv-input-label { font: 400 11px/16px var(--font-sans); color: var(--ink-lighter); }
.sv-input-value { font: 500 12px/18px var(--font-sans); color: var(--ink); word-wrap: break-word; }
/* The row that is not evidence reads as a note rather than as a value the
   analyst forgot to check. */
.sv-input.is-not-evidence .sv-input-value { color: var(--ink-lighter); }
.sv-not-evidence {
  flex-shrink: 0;
  font: 400 11px/16px var(--font-sans);
  color: var(--ink-lighter);
  white-space: nowrap;
}
.sv-table { width: 100%; border-collapse: collapse; }
.sv-table th {
  /* z-index, or the rows scroll OVER the heading instead of under it: a
     positioned cell without one loses to the table rows painted after it. */
  position: sticky; top: 0; z-index: 1;
  background: var(--surface-raised);
  text-align: left;
  font: 700 10px/16px var(--font-sans);
  color: var(--ink-lighter);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  padding: 4px 8px;
  border-bottom: 1px solid var(--sky);
}
.sv-table td {
  font: 400 12px/18px var(--font-mono);
  color: var(--ink-light);
  padding: 3px 8px;
  border-bottom: 1px solid var(--sky-lighter);
  white-space: nowrap;
}
.sv-table th:first-child, .sv-table td:first-child { padding-left: 16px; }
.sv-table th:last-child, .sv-table td:last-child { padding-right: 16px; }
/* The used row, marked the way the quote is marked in the document above. */
.sv-table tr.is-used td {
  background: var(--warning);
  color: var(--ink);
  font-weight: 700;
}

/* Inside the column the source view owns neither its width nor its border —
   the column does. */
.doc-pane.is-embedded {
  border-left: 0;
  padding-left: 0;
  flex: 1 1 auto;
  min-height: 0;
  width: auto;
}

/* ── Document viewer (right pane) ─────────────────────────── */
.doc-pane {
  background: var(--surface-raised);
  padding-left: 6px;
  display: flex; flex-direction: column;
  overflow: hidden;
  position: relative;
  min-width: 56px;
}
/* The handle is the band, exactly like .rc-hsplit. It sits in the pane's own
   left padding, so it cannot be clipped by the pane's overflow and the whole
   band answers the pointer. */
.doc-resizer {
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 6px;
  background: var(--sky);
  cursor: col-resize;
  z-index: 10;
}
.doc-resizer:hover { background: var(--blue-lighter); }
/* Collapsed there is nothing to drag, so no handle is rendered. A border keeps
   the band at the same width. */
.doc-pane.collapsed { padding-left: 0; border-left: 6px solid var(--sky); }
.doc-pane.collapsed .doc-head-content,
.doc-pane.collapsed .doc-body { display: none; }
.doc-pane.collapsed .doc-head { justify-content: center; }
.doc-head {
  min-height: 56px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--sky);
  background: var(--sky-light);
  display: flex; align-items: center; gap: 8px;
  flex-shrink: 0;
}
.doc-head .icon-btn { flex-shrink: 0; }
.doc-head-content { flex: 1; min-width: 0; overflow: hidden; }
.doc-head-title {
  font: 500 14px/18px var(--font-sans);
  color: var(--ink);
  margin: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.doc-head-tags {
  display: flex; gap: 6px; margin-top: 4px; flex-wrap: nowrap;
  min-width: 0; overflow: hidden;
}
.doc-head-tags .doc-tag {
  font: 500 10px/14px var(--font-sans);
  letter-spacing: 0.4px;
  text-transform: uppercase;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--sky);
  color: var(--ink-light);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 240px;
  flex-shrink: 1;
}
.doc-head-tags .doc-tag:first-child { flex-shrink: 0; }
.doc-head-tags .doc-tag:nth-child(2) { flex-shrink: 0; }
.doc-head-tags .doc-tag.type { background: var(--blue-lightest); color: var(--blue-darker); }
.doc-head-tags .doc-tag.entity { background: var(--success-lightest); color: var(--success-darker); }

.doc-body {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  font: 400 13px/22px var(--font-mono);
  color: var(--ink-light);
  white-space: pre-wrap;
  word-wrap: break-word;
}
.doc-body mark {
  background: var(--warning);
  color: var(--ink);
  padding: 1px 2px;
  border-radius: 2px;
}

/* ── Full-screen exit (design/chrome.jsx) ─────────────────── */
/* Top centre, just under the top bar and not over it: the centre of the bar is
   the asset switcher, and the asset an analyst is reading must not be covered,
   not even for three seconds. Under the bar the centre is empty on every page —
   a page title stands left, its actions right. Hidden, it is out of the way of
   the pointer as well as of the eye: `pointer-events: none` so it never catches
   a click on the row underneath. */
.fs-exit {
  position: fixed;
  top: 72px; left: 50%;
  transform: translateX(-50%);
  z-index: 500;
  display: flex; align-items: center; gap: 6px;
  background: var(--ink);
  color: var(--surface-raised);
  border: 0; border-radius: 999px;
  padding: 6px 14px 6px 10px;
  font: 500 12px/16px var(--font-sans);
  letter-spacing: 0.5px;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(15,23,42,.28);
  opacity: 0; pointer-events: none;
  transition: opacity .2s;
}
.fs-exit.is-on { opacity: .92; pointer-events: auto; }
.fs-exit.is-on:hover { opacity: 1; }
.fs-exit .material-icons { font-size: 18px; }

/* ── Snackbar ─────────────────────────────────────────────── */
.snack {
  position: fixed; bottom: 24px; left: 50%;
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--surface-raised);
  border-radius: 4px;
  padding: 12px 16px;
  display: flex; align-items: center; gap: 14px;
  font: 400 14px/20px var(--font-sans);
  letter-spacing: 0.25px;
  box-shadow: var(--depth-03);
  z-index: 100;
  min-width: 280px;
}
.snack .material-icons { font-size: 18px; color: var(--success); }
.snack-action {
  font: 500 13px/16px var(--font-sans);
  letter-spacing: 1.25px;
  text-transform: uppercase;
  color: var(--blue-light);
  cursor: pointer;
  margin-left: auto;
}

/* ── Compliance overview helpers ──────────────────────────── */
.cov-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
}

.cov-card {
  background: var(--surface-raised);
  border: 1px solid var(--sky);
  border-radius: 8px;
  padding: 20px;
  display: flex; flex-direction: column; gap: 12px;
}
.cov-card-head {
  display: flex; align-items: center; gap: 12px;
}
.cov-card-icon {
  width: 36px; height: 36px;
  border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  background: var(--blue-lightest); color: var(--blue);
}
.cov-card-icon.success { background: var(--success-lightest); color: var(--success-dark); }
.cov-card-icon.warning { background: var(--badge-warning-bg); color: var(--badge-warning-fg); }
.cov-card-icon.critical { background: var(--critical-lightest); color: var(--critical-darker); }
.cov-card-icon .material-icons { font-size: 20px; }
.cov-card-title {
  font: 500 14px/20px var(--font-sans);
  color: var(--ink);
}
.cov-card-stat {
  font: 300 28px/32px var(--font-sans);
  color: var(--ink);
  letter-spacing: 0.25px;
}

/* compliance status pill */
.compliance-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font: 500 12px/16px var(--font-sans);
}
.compliance-pill.compliant { background: var(--success-lightest); color: var(--success-darker); }
.compliance-pill.noncompliant { background: var(--critical-lightest); color: var(--critical-darker); }
.compliance-pill.warning { background: var(--badge-warning-bg); color: var(--badge-warning-fg); }
.compliance-pill .material-icons { font-size: 16px; }

/* ── Building / floor diagram ─────────────────────────────── */
.building-diagram {
  background: var(--surface-raised);
  border: 1px solid var(--sky);
  border-radius: 8px;
  overflow: hidden;
}
.floor-row {
  display: grid;
  grid-template-columns: 80px 1fr 56px;
  border-bottom: 1px solid var(--sky);
  min-height: 76px;
  position: relative;
}
.floor-row:last-child { border-bottom: none; }
.floor-row::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: 4px; background: var(--ink-lightest);
}
.floor-row.compliant::before { background: var(--success); }
.floor-row.noncompliant::before { background: var(--critical); }
.floor-row.warning::before { background: var(--warning); }
.floor-label {
  background: var(--sky-light);
  border-right: 1px solid var(--sky);
  display: flex; align-items: center; justify-content: center;
  font: 500 16px/24px var(--font-sans);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  padding-left: 4px;
}
.floor-content {
  padding: 14px 16px;
  display: flex; flex-direction: column; gap: 8px;
}
.floor-section { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.floor-section-label {
  font: 700 10px/16px var(--font-sans);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ink-lighter);
  margin-right: 8px;
  min-width: 80px;
}
.floor-status {
  display: flex; align-items: center; justify-content: center;
}
.floor-status .material-icons { font-size: 24px; }
.floor-status .compliant-icon { color: var(--success); }
.floor-status .noncompliant-icon { color: var(--critical); }
.floor-status .warning-icon { color: var(--warning); }

/* ── Ledger (two-sided permits/units matrix) ─────────────── */
.ledger {
  background: var(--surface-raised);
  border: 1px solid var(--sky);
  border-radius: 8px;
  overflow: hidden;
  margin-bottom: 24px;
}
.ledger-title {
  padding: 14px 20px;
  background: var(--blue-lightest);
  border-bottom: 2px solid var(--blue);
  display: flex; align-items: baseline; gap: 12px;
}
.ledger-title-name {
  font: 500 16px/24px var(--font-sans);
  color: var(--ink);
  letter-spacing: 0.15px;
}
.ledger-title-addr {
  font: 400 12px/16px var(--font-sans);
  color: var(--ink-lighter);
}
.ledger-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}
.ledger-table th {
  background: var(--sky-light);
  padding: 10px 16px;
  font: 700 10px/16px var(--font-sans);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ink-lighter);
  text-align: left;
  border-bottom: 1px solid var(--sky);
}
.ledger-table th + th { border-left: 1px solid var(--sky); }
.ledger-th-loc { width: 22%; }
.ledger-th-permits { width: 44%; }
.ledger-th-units { width: 34%; }
.ledger-row { border-bottom: 1px solid var(--sky); }
.ledger-row:last-child { border-bottom: none; }
.ledger-row td { padding: 12px 16px; vertical-align: top; }
.ledger-row td + td { border-left: 1px solid var(--sky); }
.ledger-row.floor-compliant { background: rgba(88,188,130,0.04); }
.ledger-row.floor-noncompliant { background: rgba(246,86,86,0.04); }

.ledger-loc {
  font: 500 14px/20px var(--font-sans);
  color: var(--ink);
}
.ledger-loc-sub {
  font: 400 12px/16px var(--font-sans);
  color: var(--ink-lighter);
  margin-top: 2px;
}
.ledger-permit {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 0;
  font-size: 13px;
}
.ledger-permit + .ledger-permit { border-top: 1px dashed var(--sky); }
.ledger-permit-date {
  font-family: var(--font-mono); font-size: 11px;
  color: var(--ink-lighter);
  width: 84px; flex-shrink: 0;
}
.ledger-unit {
  background: var(--sky-lighter);
  border: 1px solid var(--sky);
  border-radius: 4px;
  padding: 8px 10px;
  margin-bottom: 6px;
  display: flex; flex-direction: column; gap: 4px;
}
.ledger-unit:last-child { margin-bottom: 0; }
.ledger-unit.compliant { border-left: 3px solid var(--success); background: var(--success-lightest); }
.ledger-unit.noncompliant { border-left: 3px solid var(--critical); background: var(--critical-lightest); }
.ledger-unit-head { display: flex; align-items: center; gap: 8px; }
.ledger-unit-name { font: 500 13px/16px var(--font-sans); color: var(--ink); }
.ledger-unit-meta { font: 400 11px/14px var(--font-sans); color: var(--ink-lighter); margin-left: auto; }
.ledger-unit-tenant { font: 400 12px/16px var(--font-sans); color: var(--ink-light); }

/* ── Lease contract family ────────────────────────────────── */
.contract-family { margin-bottom: 32px; }
.contract-family-head {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.contract-family-id {
  font: 700 10px/16px var(--font-sans);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--blue);
  background: var(--blue-lightest);
  padding: 2px 8px;
  border-radius: 4px;
}
.contract-family-name {
  font: 500 18px/24px var(--font-sans);
  color: var(--ink);
}
.amendment-list {
  margin-left: 24px;
  border-left: 2px solid var(--blue-lighter);
  padding: 4px 0 4px 16px;
  margin-top: -4px;
  position: relative;
}
.amendment {
  background: var(--sky-lighter);
  border: 1px solid var(--sky);
  border-radius: 4px;
  padding: 12px 16px;
  margin-bottom: 8px;
  position: relative;
}
.amendment::before {
  content: ""; position: absolute;
  left: -19px; top: 18px;
  width: 14px; height: 2px; background: var(--blue-lighter);
}
.amendment-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 6px;
}
.amendment-num {
  font: 700 11px/16px var(--font-sans);
  letter-spacing: 0.5px;
  color: var(--blue);
  text-transform: uppercase;
}
.amendment-meta {
  font: 400 11px/16px var(--font-mono);
  color: var(--ink-lighter);
}

/* current-state highlight */
.current-state {
  margin: 0;
  padding: 14px 20px;
  background: var(--blue-lightest);
  border-top: 1px solid var(--blue-lighter);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
}
.current-state-item {
  display: flex; flex-direction: column; gap: 2px;
}
.current-state-label {
  font: 700 10px/16px var(--font-sans);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--blue-darker);
}
.current-state-value {
  font: 500 14px/20px var(--font-sans);
  color: var(--ink);
}

/* ── Validation queue ─────────────────────────────────────── */
.vq-row {
  background: var(--surface-raised);
  border: 1px solid var(--sky);
  border-radius: 8px;
  padding: 16px 20px;
  margin-bottom: 8px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 16px;
  align-items: center;
  cursor: pointer;
  transition: box-shadow .15s, border-color .15s;
}
.vq-row:hover { box-shadow: var(--depth-02); border-color: var(--blue-lighter); }
.vq-row.is-active { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(0,145,255,0.10); }
.vq-priority {
  width: 4px; align-self: stretch;
  border-radius: 2px;
}
.vq-priority.critical { background: var(--critical); }
.vq-priority.review { background: var(--warning); }
.vq-priority.ai { background: var(--blue); }
.vq-main { min-width: 0; }
.vq-row-meta {
  display: flex; gap: 8px; align-items: center;
  font: 400 12px/16px var(--font-sans);
  color: var(--ink-lighter);
  margin-bottom: 4px;
  flex-wrap: wrap;
}
.vq-row-id {
  font-family: var(--font-mono); font-size: 11px;
  color: var(--ink-light);
}
.vq-field {
  font: 500 14px/20px var(--font-sans);
  color: var(--ink);
}
.vq-value {
  font: 400 14px/20px var(--font-mono);
  color: var(--ink-light);
  margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.vq-actions { display: flex; gap: 6px; }

/* ── Merge proposals ──────────────────────────────────────── */
.merge-card {
  background: var(--surface-raised);
  border: 1px solid var(--sky);
  border-radius: 8px;
  margin-bottom: 12px;
  overflow: hidden;
}
.merge-head {
  padding: 12px 20px;
  background: var(--sky-light);
  border-bottom: 1px solid var(--sky);
  display: flex; align-items: center; gap: 12px;
  flex-wrap: wrap;
}
.merge-id {
  font-family: var(--font-mono); font-size: 13px; font-weight: 500;
  color: var(--ink);
}
.confidence-bar {
  display: flex; align-items: center; gap: 8px;
  min-width: 160px;
}
.confidence-track {
  flex: 1;
  height: 6px;
  background: var(--sky);
  border-radius: 3px;
  overflow: hidden;
}
.confidence-fill {
  height: 100%; border-radius: 3px;
  transition: width .3s;
}
.confidence-fill.high { background: var(--success); }
.confidence-fill.mid { background: var(--warning); }
.confidence-fill.low { background: var(--critical); }
.confidence-pct {
  font: 500 12px/16px var(--font-mono);
  color: var(--ink-light);
  min-width: 36px; text-align: right;
}
.merge-body {
  padding: 16px 20px;
  display: flex; flex-direction: column; gap: 8px;
}
.merge-ids {
  display: flex; align-items: center; gap: 8px;
  font: 400 14px/20px var(--font-sans);
  color: var(--ink);
  flex-wrap: wrap;
}
.merge-source-id {
  font-family: var(--font-mono); font-size: 13px;
  background: var(--badge-warning-bg);
  color: var(--badge-warning-fg);
  padding: 2px 8px;
  border-radius: 4px;
  font-weight: 500;
}
.merge-canonical-id {
  font-family: var(--font-mono); font-size: 13px;
  background: var(--success-lightest);
  color: var(--success-darker);
  padding: 2px 8px;
  border-radius: 4px;
  font-weight: 500;
}
.merge-arrow { color: var(--ink-lighter); }
.merge-reason {
  background: var(--sky-lighter);
  border-left: 3px solid var(--blue);
  padding: 8px 12px;
  border-radius: 0 4px 4px 0;
  font: 400 13px/20px var(--font-sans);
  color: var(--ink-light);
}
.merge-actions {
  display: flex; gap: 8px;
  padding: 12px 20px;
  border-top: 1px solid var(--sky);
}

/* ── Chat panel (Architrave-styled) ───────────────────────── */
.chat-toggle {
  position: fixed;
  bottom: 24px; right: 24px;
  height: 48px;
  padding: 0 20px 0 16px;
  background: var(--blue);
  color: var(--text-on-accent);
  border: 0;
  border-radius: 24px;
  display: flex; align-items: center; gap: 8px;
  font: 500 14px/16px var(--font-sans);
  letter-spacing: 1.25px;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: var(--depth-02);
  z-index: 50;
}
.chat-toggle:hover { background: var(--blue-dark); }
.chat-toggle .material-icons { font-size: 20px; }

.chat-panel {
  position: fixed;
  bottom: 24px; right: 24px;
  width: 400px; height: 560px;
  background: var(--surface-raised);
  border: 1px solid var(--sky);
  border-radius: 8px;
  box-shadow: var(--depth-03);
  display: none;
  flex-direction: column;
  overflow: hidden;
  z-index: 60;
}
.chat-panel.open { display: flex; }
.chat-head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px;
  background: var(--sky-light);
  border-bottom: 1px solid var(--sky);
}
.chat-head-icon {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--blue);
  color: var(--text-on-accent);
  display: flex; align-items: center; justify-content: center;
}
.chat-head-icon .material-icons { font-size: 18px; }
.chat-head-title { font: 500 14px/20px var(--font-sans); color: var(--ink); margin: 0; }
.chat-head-sub { font: 400 12px/16px var(--font-sans); color: var(--ink-lighter); }
.chat-body {
  flex: 1; overflow-y: auto;
  padding: 16px;
  display: flex; flex-direction: column; gap: 12px;
  background: var(--sky-lighter);
}
.chat-msg {
  max-width: 85%;
  padding: 10px 14px;
  border-radius: 8px;
  font: 400 13px/20px var(--font-sans);
}
.chat-msg.user {
  background: var(--blue);
  color: var(--text-on-accent);
  align-self: flex-end;
  border-bottom-right-radius: 2px;
}
.chat-msg.assistant {
  background: var(--surface-raised);
  color: var(--ink);
  border: 1px solid var(--sky);
  align-self: flex-start;
  border-bottom-left-radius: 2px;
}
.chat-input-wrap {
  display: flex; gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid var(--sky);
  background: var(--surface-raised);
  align-items: flex-end;
}
.chat-input-wrap textarea {
  flex: 1;
  min-height: 36px; max-height: 100px;
  padding: 8px 12px;
  border: 1px solid var(--sky);
  border-radius: 4px;
  font: 400 14px/20px var(--font-sans);
  resize: none;
  outline: none;
}
.chat-input-wrap textarea:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(0,145,255,0.10); }
.chat-send {
  width: 36px; height: 36px;
  background: var(--blue);
  color: var(--text-on-accent);
  border: 0; border-radius: 4px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
}
.chat-send:hover { background: var(--blue-dark); }
.chat-send .material-icons { font-size: 18px; }

/* ── Misc / inline notes ──────────────────────────────────── */
.callout {
  background: var(--blue-lightest);
  border-left: 3px solid var(--blue);
  padding: 12px 16px;
  border-radius: 0 4px 4px 0;
  font: 400 13px/20px var(--font-sans);
  color: var(--ink-light);
  margin-bottom: 16px;
}
.callout.warning {
  background: var(--badge-warning-bg);
  border-left-color: var(--warning);
  color: var(--badge-warning-fg);
}
.callout.critical {
  background: var(--critical-lightest);
  border-left-color: var(--critical);
  color: var(--critical-darker);
}

/* note-text helper */
.muted { color: var(--ink-lighter); }
.mono { font-family: var(--font-mono); }
.numeric { font-variant-numeric: tabular-nums; }
.tag-row { display: flex; gap: 4px; flex-wrap: wrap; }

/* responsive guard
   Below 1100px the navigation FALLS TO THE ICON WIDTH rather than disappearing.
   `display: none` would take the only way between screens off the page: the
   rail has no routable URL, so a user on a narrow window would have nothing
   left to click. 64px is the same column the collapse button gives, so nothing
   here is a second layout — it is the collapsed rail, decided by the window
   instead of by the button.

   The narrow LOOK is written against `.rail` here and not through the
   `.rail-narrow` class, because that class follows the button's state: a user
   whose rail is expanded still gets a 64px column at this width, and the labels
   have to go with it or they run out of the column. The hover peek is the one
   exception — it floats at full width over the content, so its labels stay. */
@media (max-width: 1100px) {
  .app, .app.rail-collapsed { grid-template-columns: 64px minmax(0, 1fr); }
  .rail { grid-column: 1; }
  .workspace { grid-column: 2; }
  .rail:not(.rail-peek) .rail-label,
  .rail:not(.rail-peek) .rail-count,
  .rail:not(.rail-peek) .rail-arrow,
  .rail:not(.rail-peek) .rail-section-label,
  .rail:not(.rail-peek) .rail-group-children { display: none; }
  .rail:not(.rail-peek) .rail-item,
  .rail:not(.rail-peek) .rail-group-header { padding: 0 22px; }
  .rail:not(.rail-peek) .rail-header { justify-content: center; padding: 0; }
  .rail:not(.rail-peek) .rail-brand-text { display: none; }
  .rail:not(.rail-peek) .rail-toggle { display: none; }
  .rail:not(.rail-peek) .rail-foot { justify-content: center; padding: 0; }
}
