/* vendored from mycite-core fnd_app/instances/_shared/portal_host/static/portal.css — do not edit here; written and drift-gated by fnd_app/scripts/export_tool_demos.py */
/** MiCyte Portal UI
 * Inspired by the attached reference layout (earthy paper bg + dark nav column),
 * but with fresh naming and separation.
 */

:root{
  --paper: #f0eedc;
  --paper2:#e8e5d0;
  --ink:   #464646;
  --ink2:  #888888;
  --coal:  #2f2f2f;
  --coal2: #3a3a3a;
  --line:  #afafaa;
  --accent:#1e6c93;
  --accent2:#5a9bb5;

  /* Operational accents (theme-aware; base = paper, spore overrides below) */
  --moss:  #1f883d;   /* success / connected */
  /* DECLARED, NOT YET PERMITTED — a port bound and refused, a still held and not
     published, a gadget installed and not allowed. The ramp's oak gall, because this
     is the CORRECT resting state and --danger would teach an operator that the safe
     state is broken and that permitting is how you clear it. Written down, not
     stamped. */
  --held:  #b5762a;
  --danger:#d73a49;   /* error / destructive */
  --accent-fg: #fff;  /* text on accent fills — dark themes override (light accents) */

  --radius: 2px;
  --shadow: 0 2px 10px rgba(0,0,0,0.10);
  --navw: 220px;
  --tabh: 44px;

  /* HERBARIUM PLATE — the categorical ramp for charts.
     Derived from this substrate rather than imported: --viz-1 IS the portal accent, and
     the rest are inks that would have been printed beside it on oat paper — oak gall,
     verdigris, madder, logwood, and a grey for residue (bots, "other", the tail).

     LIGHTNESS varies across the ramp as well as hue, deliberately. A ramp separated only
     by hue collapses in greyscale and for the common colour-blindness types; these stay
     distinguishable by value alone, which is the property a legend cannot supply. */
  --viz-1: #1e6c93;
  --viz-2: #b5762a;
  --viz-3: #4a7c59;
  --viz-4: #a2413c;
  --viz-5: #6b5b8a;
  --viz-6: #8a8578;
}

*{ box-sizing:border-box; }
html,body{ height:100%; }
body{
  margin:0;
  font-family: system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,sans-serif;
  background: var(--paper);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.45;
  overflow:hidden;
}
/* Override the inline critical-CSS fallback (body.v2-native-portal, specificity
   0,1,1) so the ACTIVE theme governs the page canvas/text in every theme. This
   rule loads after the inline <style>, so it wins the source-order tiebreak. */
body.v2-native-portal{
  background: var(--paper);
  color: var(--ink);
}

/* Phantom tokens: previously referenced only through var(--x, fallback) and
   never defined, so the theme could not govern them. Defined here on BODY (the
   same element the theme palette classes body.theme-* set), NOT on :root — a
   var() ref like var(--paper2) resolves against the DEFINING element's cascade,
   and the themed palette lives on body, so :root would lock these to the base
   (paper) palette. On body they re-resolve per theme (paper/ocean/forest/
   midnight/spore). */
body{
  --ide-panel-bg: var(--paper2);
  --ide-border:   var(--line);
  --panel-bg:     var(--paper2);
  --panel:        var(--paper2);
  --panel-border: var(--line);
  --ide-accent:   var(--accent);
  --muted:        var(--ink2);
  --input-bg:     var(--coal);
  --surface:      var(--paper);
  --ink1:         var(--ink);
  --color-border: var(--line);
  --warn:         var(--accent);/* attention (ochre in spore, accent elsewhere) */
}

/* Scrollbars are load-bearing here and nothing had ever themed them. The portal is
   full of regions that legitimately scroll — the datum grid, a tree wider than its
   pane, the tool overlay — and on the spore substrate the UA's dark-grey bar is
   invisible against #16130E. A label clipped at a pane edge with no visible bar does
   not read as "there is more to the right"; it reads as broken, which is precisely
   the complaint. Themed once, on every scrolling surface, in every palette. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
/* Theme standard tokens (cross-portal). portal.js constructs these class
   names dynamically (`theme-${id}`), so no literal `theme-ocean` appears in
   any JS/HTML file — which is how the 2026-08-17 dead-CSS sweep cut the
   palette blocks and left Ocean/Forest rendering as Paper and Midnight as
   dark cards on a cream page. Restored 2026-08-21; a sweep must treat the
   THEME_STANDARD ids in portal.js as live selector roots. */
body.theme-ocean{
  --paper: #e7f3f7;
  --paper2:#d9ebf1;
  --ink:   #1e3b45;
  --ink2:  #4f6f7a;
  --coal:  #17343e;
  --coal2: #1f4753;
  --line:  #8fb5c3;
  --accent:#0b7ea5;
  --accent2:#4aa7c7;
}
body.theme-forest{
  --paper: #e9f0e6;
  --paper2:#dce8d6;
  --ink:   #2b3b2c;
  --ink2:  #5c715c;
  --coal:  #213126;
  --coal2: #2a3f2f;
  --line:  #9fb09f;
  --accent:#2d7a4c;
  --accent2:#57a16f;
}
body.theme-midnight{
  --paper: #202733;
  --paper2:#283141;
  --ink:   #dbe5f5;
  --ink2:  #93a6c3;
  --coal:  #121722;
  --coal2: #1a2231;
  --line:  #41506c;
  --accent:#79a6ff;
  --accent2:#9cc0ff;
  --moss:  #57ab5a;   /* success on a dark substrate */
  --held:  #d49a52;   /* oak gall lifted off a dark substrate */
  --danger:#e5534b;   /* error on a dark substrate */
  --accent-fg: #121722; /* the accent is LIGHT here — dark ink on it, not white */
}
body.theme-midnight .card,
body.theme-midnight .placeholder{
  background: #2b3446;
  color: #dbe5f5;
}
body.theme-midnight .pagehead__sub,
body.theme-midnight .placeholder__text,
body.theme-midnight .card__body{ color: #b7c6df; }

/* Spore — the micyte.com brand as a portal theme: Loam Black substrate, Hypha Gold
   structure, violet network ink, Spore Cream text. Aligns the portal frontend with
   micyte.com's spore-print system. Same override shape as theme-midnight (the dark peer). */
body.theme-spore{
  --paper: #16130e;
  --paper2:#1e1a13;
  --ink:   #ece5d4;
  --ink2:  #a79b84;
  --coal:  #0f0d0b;
  --coal2: #191510;
  --line:  #332b20;
  --accent:#c68a3d;
  --accent2:#9d78b4;
  --moss:  #7f9066;   /* muted lichen green on loam */
  --held:  #c68a3d;   /* on loam the gall IS the substrate accent */
  --danger:#b86b5d;   /* clay red on loam */
  --accent-fg: #16130e; /* loam ink on Hypha Gold — white on gold is ~2.5:1 */
}
body.theme-spore .card,
body.theme-spore .placeholder{
  background: #1e1a13;
  color: #ece5d4;
}
body.theme-spore .pagehead__sub,
body.theme-spore .placeholder__text,
body.theme-spore .card__body{ color: #a79b84; }

/* Left column */
.navcol{
  width: var(--navw);
  min-width: var(--navw);
  background: var(--coal);
  color: #eee;
  border-right: 1px solid var(--line);
  display:flex;
  flex-direction:column;
}

.navcol__brand{
  padding: 14px 14px 10px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
.navcol__brandLink{
  color:#f3f2e5;
  text-decoration:none;
  font-weight: 900;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.navcol__brandSub{
  margin-top: 4px;
  font-size: 11px;
  color: rgba(240,238,220,0.55);
}

.navcol__section{ padding: 12px 0 6px; }
.navcol__sectionTitle{
  padding: 0 14px 8px;
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  color: rgba(240,238,220,0.45);
}

.navcol__search{ padding: 0 14px 10px; }
.navcol__searchInput{
  width:100%;
  padding: 8px 10px;
  border-radius: var(--radius);
  border: 1px solid rgba(255,255,255,0.10);
  outline: none;
  background: rgba(255,255,255,0.06);
  color: #f3f2e5;
}
.navcol__searchInput::placeholder{ color: rgba(240,238,220,0.40); }

.navcol__list{
  list-style:none;
  padding: 0;
  margin: 0;
}
.navcol__item{ margin:0; }
.navcol__link{
  display:block;
  padding: 9px 14px 9px 16px;
  text-decoration:none;
  color: rgba(240,238,220,0.78);
  border-left: 3px solid transparent;
  transition: background 100ms, color 100ms, border-color 100ms;
}
.navcol__link:hover{
  background: rgba(255,255,255,0.06);
  color:#fff;
}
.navcol__link.is-active{
  background: rgba(30,108,147,0.26);
  color:#fff;
  border-left-color: var(--accent);
  font-weight: 650;
}
.navcol__link.is-empty{
  cursor: default;
  opacity: 0.9;
}
.navcol__linkTitle{
  display:block;
  font-size: 13px;
  line-height: 1.3;
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.navcol__linkSub{
  display:block;
  margin-top: 2px;
  font-size: 11px;
  color: rgba(240,238,220,0.45);
}

.navcol__spacer{ flex:1; }

.navcol__footer{
  padding: 10px 14px;
  border-top: 1px solid rgba(255,255,255,0.08);
  font-size: 11px;
  color: rgba(240,238,220,0.40);
}
.navcol__footLine{ margin: 2px 0; }
.navcol__footDim{ color: rgba(240,238,220,0.28); }

.toolshell__item.is-active{
  background: rgba(30,108,147,0.16);
  color: var(--accent);
  font-weight: 700;
}

.toolshell__item.is-empty{
  color: var(--ink2);
  cursor: default;
}

.toolshell__activeTab.is-empty{
  border-color: var(--line);
  color: var(--ink2);
  background: rgba(0,0,0,0.03);
}

.toolshell .themebar{
  padding: 0;
}

.toolshell .themebar__select{
  min-width: 110px;
}

/* Home tabs */
.hometabs{
  display:flex;
  gap:0;
  background: var(--paper2);
  border-bottom: 2px solid var(--line);
  padding: 0 6px;
  height: var(--tabh);
  align-items: end;
}
.hometabs__tab{
  appearance:none;
  border:0;
  background: transparent;
  cursor:pointer;
  height: var(--tabh);
  padding: 0 14px 10px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink2);
  border-bottom: 3px solid transparent;
}
.hometabs__tab:hover{ color: var(--ink); }
.hometabs__tab.is-active{
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.hometabs__spacer{ flex:1; }

.themebar{
  display:flex;
  align-items:center;
  gap:8px;
  padding: 0 10px 8px 0;
}
.themebar__label{
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink2);
}
.themebar__select{
  min-width: 120px;
  height: 28px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  color: var(--ink);
  padding: 0 8px;
  font-size: 12px;
}
body.theme-midnight .themebar__select{
  background: var(--coal);
  color: #dbe5f5;
}

/* Page header */
.pagehead{
  padding: 12px 16px;
  background: var(--coal2);
  color: #f3f2e5;
  border-bottom: 1px solid var(--line);
}
.pagehead--withTools{
  display:flex;
  align-items:flex-start;
  justify-content:space-between;
  gap:12px;
}
.pagehead__meta{
  min-width: 0;
}
.pagehead__title{
  font-size: 12px;
  font-weight: 900;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}
.pagehead__sub{
  margin-top: 4px;
  font-size: 12px;
  color: rgba(240,238,220,0.55);
}
.pagehead .themebar{
  padding: 0;
  margin-left: auto;
}
.pagehead .themebar__label{
  color: rgba(240,238,220,0.72);
}
.pagehead .themebar__select{
  height: 26px;
  min-width: 112px;
}

/* Viewport */
.viewport{
  flex:1;
  overflow:auto;
  padding: 18px 18px 28px;
}

@media (max-width: 860px){
  .pagehead--withTools{
    flex-direction: column;
    align-items: flex-start;
  }
  .pagehead .themebar{
    margin-left: 0;
  }
}
.panel{ display:none; }
.panel.is-active{ display:block; }

.card{
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 14px 14px 12px;
}
.card__kicker{
  font-size: 11px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink2);
}
.card__title{
  margin-top: 6px;
  font-size: 15px;
  font-weight: 800;
  color: var(--ink);
}
.card__body{
  margin-top: 8px;
  color: var(--ink2);
  font-size: 13px;
}
.bullets{ margin: 8px 0 0 18px; padding:0; }
.bullets li{ margin: 6px 0; }

/* Placeholder */
.placeholder{
  border: 2px dashed var(--line);
  border-radius: var(--radius);
  padding: 22px;
  background: rgba(255,255,255,0.35);
  max-width: 860px;
}
.placeholder__title{
  font-size: 14px;
  font-weight: 900;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.placeholder__text{
  margin-top: 10px;
  color: var(--ink2);
  font-size: 13px;
}
.kv{
  display:grid;
  grid-template-columns: 110px 1fr;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid rgba(0,0,0,0.06);
}
.kv:last-child{ border-bottom:0; }
.kv__k{
  font-size: 11px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink2);
}
.kv__v{
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  font-size: 12px;
  color: var(--ink);
  overflow-wrap:anywhere;
}

/* Links */
a{ color: var(--accent); }
code{
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  font-size: 12px;
}

/* NIMM Data Tool */
.data-tool {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
  max-width: none;
  align-self: stretch;
  min-height: 0;
  overflow: hidden;
}

.data-tool--systemWorkbench {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  height: 100%;
  gap: 10px;
}

.data-tool__layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
  width: 100%;
  min-width: 0;
  align-items: stretch;
}

.data-tool__layout--workbench {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  grid-template-columns: minmax(0, 1fr);
  width: 100%;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}

.data-tool__main {
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow: hidden;
}

.data-tool__nimmSummary {
  position: sticky;
  top: 78px;
}

.data-tool__anthologyWorkbench {
  flex: 1 1 auto;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  overflow: hidden;
}

.data-tool__graphToolbar {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 10px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 10px;
}

.data-tool__graphToolbarTitle {
  min-width: 0;
}

.data-tool__paneHead {
  margin-bottom: 8px;
}

.data-tool__workbenchGrid {
  display: grid;
  flex: 1 1 auto;
  grid-template-columns: minmax(0, 1fr);
  grid-auto-rows: minmax(0, 1fr);
  gap: 12px;
  width: 100%;
  align-items: stretch;
  min-height: 0;
  overflow: hidden;
}

.data-tool__graphPane,
.data-tool__tablePane {
  width: 100%;
  flex: 1 1 auto;
  align-self: stretch;
  min-width: 0;
  min-height: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow: hidden;
}

.data-tool__workbenchWithDetail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 380px);
  gap: 12px;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  align-items: stretch;
}

.data-tool__workbenchCenter {
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.data-tool__anthologyDetail {
  min-width: 0;
  min-height: 0;
  max-height: 100%;
  overflow: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
}

.data-tool__anthologyDetailBody {
  min-height: 120px;
}

.data-tool__anthologyInvSection {
  border-top: 1px solid var(--line);
  padding-top: 10px;
  margin-top: 4px;
}

.data-tool__detailSectionTitle {
  margin: 0 0 6px;
  font-size: 13px;
  font-weight: 600;
}

.data-tool__detailHint {
  margin-top: 0;
}

.data-tool__invEmbedMeta {
  font-size: 11px;
  color: var(--ink2);
  margin-bottom: 8px;
}

.data-tool__graphToolSheet {
  margin-bottom: 4px;
}

.data-tool__paneHead--compact .card__title {
  font-size: 15px;
}

@media (max-width: 1100px) {
  .data-tool__workbenchWithDetail {
    grid-template-columns: 1fr;
  }
}

.data-tool__datumEditor {
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.data-tool__editorPairs {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.data-tool__anthologyLayers {
  flex: 1 1 auto;
  height: 100%;
  max-height: 100%;
  min-height: 0;
  overflow: auto;
  overscroll-behavior: contain;
}

.data-tool__editorHeader {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 2px 2px 6px;
}

.data-tool__editorHeadline {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.data-tool__editorChips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.data-tool__editorChip {
  display: inline-flex;
  align-items: center;
  min-height: 20px;
  padding: 0 7px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  font-size: 11px;
  color: var(--ink2);
}

.data-tool__nimmSummary pre {
  margin: 0;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  overflow: auto;
  max-height: 300px;
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 12px;
}

.data-tool__nimmOverlay {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: grid;
  grid-template-columns: 1fr min(860px, 94vw);
}

.data-tool__nimmOverlay[hidden] {
  display: none !important;
  pointer-events: none;
}

.data-tool__nimmBackdrop {
  background: rgba(0, 0, 0, 0.35);
}

.data-tool__nimmPanel {
  margin: 10px 10px 10px 0;
  border-radius: 12px;
  overflow: auto;
  max-height: calc(100vh - 20px);
}

.data-tool__nimmHeader {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

@media (max-width: 1100px) {
  .data-tool__layout {
    grid-template-columns: 1fr;
  }

  .data-tool__graphToolbar {
    flex-direction: column;
    align-items: stretch;
  }

  .data-tool__workbenchGrid {
    grid-template-columns: 1fr;
  }

  .data-tool__samrasGraph {
    min-height: 260px;
  }

  .data-tool__nimmSummary {
    position: static;
  }
}

.data-tool__controls {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.data-tool__controlRow {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: end;
}

.data-tool__controlRow label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 140px;
}

.data-tool__controlRow input,
.data-tool__controlRow select,
.data-tool__controlRow button {
  min-height: 34px;
}

.data-tool__messages {
  display: none;
}

.data-tool__state pre,
.data-tool__pane pre {
  margin: 0;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  overflow: auto;
  max-height: 320px;
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 12px;
}

.data-tool__panes {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

@media (max-width: 900px) {
  .data-tool__panes {
    grid-template-columns: 1fr;
  }
}

.data-tool__paneBody {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.data-tool__paneKind {
  font-size: 12px;
  color: var(--ink2);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.data-tool__datumList {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.data-tool__datumRow {
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 8px;
  background: var(--paper);
}

.data-tool__iconButton {
  width: 38px;
  height: 38px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.data-tool__iconButton:hover {
  border-color: var(--accent);
}

.data-tool__datumText {
  min-width: 0;
  flex: 1;
}

.data-tool__datumTitle {
  font-weight: 700;
  font-size: 13px;
  color: var(--ink);
  margin-bottom: 2px;
  word-break: break-word;
}

.data-tool__datumMeta {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  color: var(--ink2);
  font-size: 12px;
}

.data-tool__datumMeta code {
  font-size: 11px;
}

.data-tool__raw pre {
  margin-top: 8px;
  max-height: 260px;
}

.data-tool__empty {
  margin: 0;
  color: var(--ink2);
  font-size: 13px;
}

.data-tool__legendText {
  margin: 4px 0 0;
  color: var(--ink2);
}

.data-tool__advanced > summary {
  cursor: pointer;
  font-weight: 700;
}

.data-tool__statusText {
  font-size: 12px;
  color: var(--ink2);
}

.data-tool__graphCard {
  margin-top: 10px;
}

.data-tool__graphCanvas {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.data-tool__graphViewport {
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  display: flex;
  justify-content: center;
  overflow: auto;
  max-height: 72vh;
  overscroll-behavior: contain;
}

.data-tool__graphSvg {
  display: block;
  width: max(100%, 920px);
  max-width: none;
  min-width: 920px;
  min-height: 620px;
  flex: 0 0 auto;
  background: linear-gradient(180deg, var(--paper) 0%, var(--paper) 100%);
}

.data-tool__graphLayerLane {
  stroke: var(--line);
  stroke-width: 1;
  stroke-dasharray: 3 5;
}

.data-tool__graphLayerLabel {
  font-size: 12px;
  letter-spacing: 0.03em;
  fill: var(--coal2);
  font-weight: 700;
}

.data-tool__graphEdge {
  fill: none;
  stroke: rgba(100, 108, 120, 0.22);
  stroke-width: 0.85;
}

.data-tool__graphEdge.is-dim {
  stroke: rgba(130, 136, 148, 0.12);
  stroke-width: 0.75;
}

.data-tool__graphEdge.is-unresolved {
  stroke: rgba(180, 38, 52, 0.6);
  stroke-dasharray: 4 3;
}

.data-tool__graphEdge.is-focus {
  stroke: rgba(18, 101, 59, 0.9);
  stroke-width: 2.2;
}

.data-tool__graphEdge.is-path {
  stroke: rgba(29, 78, 216, 0.72);
  stroke-width: 1.45;
}

.data-tool__graphNodeGroup,
.data-tool__graphNode {
  cursor: pointer;
}

.data-tool__graphNodeGroup {
  opacity: 0.95;
}

.data-tool__graphNodeGroup.is-dim {
  opacity: 0.28;
}

.data-tool__graphNode {
  stroke-width: 1.15;
}

.data-tool__graphNode:hover {
  filter: brightness(0.95);
}

.data-tool__graphNodeRect {
  stroke: rgba(20, 26, 36, 0.26);
  stroke-width: 1;
}

.data-tool__graphNodeLabel {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  fill: var(--paper);
  pointer-events: none;
}

.data-tool__graphNodeMeta {
  font-size: 9px;
  letter-spacing: 0.03em;
  fill: rgba(236, 240, 247, 0.92);
  pointer-events: none;
}

.data-tool__graphNodeIconBadge {
  fill: rgba(248, 250, 252, 0.96);
  stroke: rgba(17, 24, 39, 0.32);
  stroke-width: 0.9;
}

.data-tool__graphNodeIcon {
  pointer-events: none;
}

.data-tool__graphNodeIconInitial {
  fill: var(--coal);
  font-size: 7px;
  font-weight: 700;
  letter-spacing: 0.01em;
  pointer-events: none;
}

.data-tool__graphNodeGroup.is-path .data-tool__graphNodeRect {
  stroke: rgba(29, 78, 216, 0.66);
  stroke-width: 1.4;
}

.data-tool__graphNodeGroup.is-context .data-tool__graphNodeRect {
  stroke: rgba(37, 99, 235, 0.45);
  stroke-width: 1.2;
}

.data-tool__graphNode.is-context {
  stroke-width: 1.4;
}

.data-tool__graphNode.is-focus {
  stroke-width: 2.2;
}

.data-tool__graphNodeGroup.is-focus .data-tool__graphNodeRect {
  stroke: var(--moss);
  stroke-width: 2;
}

.data-tool__graphNodeGroup.is-focus .data-tool__graphNodeLabel {
  fill: var(--paper);
}

.data-tool__graphLegend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding-top: 4px;
}

.data-tool__graphLegendChip {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line);
  border-left-width: 4px;
  border-radius: 999px;
  padding: 3px 8px;
  font-size: 11px;
  color: var(--ink);
  background: var(--paper);
}

.data-tool__table tr.is-selected td {
  background: rgba(30, 108, 147, 0.12);
}

.data-tool__table tr.data-tool__row--shade-standard td {
  background: rgba(34, 197, 94, 0.07);
}

.data-tool__table tr.data-tool__row--shade-light td {
  background: rgba(251, 191, 36, 0.12);
}

.data-tool__table tr.data-tool__row--shade-error td {
  background: rgba(239, 68, 68, 0.1);
}

.data-tool__table tr.data-tool__row--shade-neutral td {
  background: rgba(148, 163, 184, 0.12);
}

.data-tool__familyBadge {
  display: inline-block;
  margin-top: 2px;
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink);
  background: var(--paper2);
  max-width: 100%;
}

.data-tool__lensHint {
  font-size: 10px;
  color: var(--ink2);
  margin-top: 2px;
}

.data-tool__ruleMeta {
  margin-top: 6px;
  font-size: 12px;
  color: var(--ink);
}

.data-tool__ruleOverrideRow {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin: 10px 0;
  padding: 8px;
  border: 1px dashed var(--line);
  border-radius: 6px;
  background: var(--paper);
}

.data-tool__ruleOverrideLabel {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--ink);
}

.data-tool__ruleOverrideReason {
  flex: 1;
  min-width: 200px;
  padding: 4px 8px;
  font-size: 12px;
}

.data-tool__anthologyLayers {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 8px;
}

.data-tool__layerGroup > summary,
.data-tool__valueGroup > summary {
  cursor: pointer;
  font-weight: 700;
}

.data-tool__layerGroup {
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  padding: 8px;
}

.data-tool__valueGroups {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 8px;
}

.data-tool__valueGroup {
  border: 1px dashed var(--line);
  border-radius: 6px;
  background: var(--paper);
  padding: 8px;
}

.data-tool__tableWrap {
  max-width: 100%;
  overflow: auto;
}

.data-tool__valueGroupActions {
  margin-top: 8px;
  display: flex;
  justify-content: flex-end;
}

.data-tool__layerActions {
  margin-top: 8px;
  display: flex;
  justify-content: flex-end;
}

.data-tool__table {
  width: 100%;
  border-collapse: collapse;
  min-width: 780px;
  margin-top: 8px;
  background: var(--paper);
}

.data-tool__table th,
.data-tool__table td {
  border: 1px solid var(--line);
  padding: 6px 8px;
  text-align: left;
  vertical-align: top;
}

.data-tool__table th {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink2);
  background: var(--paper);
}

.data-tool__table td code {
  white-space: nowrap;
}

.data-tool__clip {
  display: block;
  max-width: 420px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.data-tool__datumCell {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 220px;
}

.data-tool__datumIcon {
  width: 28px;
  height: 28px;
  border: 1px solid var(--line);
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--paper);
  flex: 0 0 auto;
}

.data-tool__datumMain {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.data-tool__datumName {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
}

.data-tool__datumId {
  font-size: 11px;
  color: var(--ink2);
}

.data-tool__actionBtn {
  min-height: 28px;
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--paper);
  font-size: 12px;
  cursor: pointer;
}

.data-tool__actionBtn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.data-tool__actionBtn--danger {
  border-color: var(--danger);
  color: var(--danger);
}

.data-tool__actionBtn--danger:hover {
  border-color: var(--danger);
  color: var(--danger);
}

.data-tool__tableIconCell {
  width: 52px;
  text-align: center;
}

.data-tool__pairCards {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.data-tool__pairCard {
  min-width: 220px;
  max-width: 100%;
  display: inline-flex;
  align-items: flex-start;
  gap: 8px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  padding: 6px 8px;
}

.data-tool__pairIcon {
  width: 24px;
  height: 24px;
  border: 1px solid var(--line);
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--paper);
  flex: 0 0 auto;
}

.data-tool__pairIcon .datum-icon {
  width: 16px;
  height: 16px;
}

.data-tool__pairIcon .datum-icon--placeholder {
  width: 16px;
  height: 16px;
  font-size: 12px;
  line-height: 16px;
}

.data-tool__pairBody {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.data-tool__pairAddress {
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
  max-width: 360px;
}

.data-tool__pairLabel {
  font-size: 11px;
  color: var(--ink2);
  max-width: 360px;
}

.data-tool__pairMagnitude {
  font-size: 12px;
  color: var(--ink2);
  max-width: 420px;
}

.data-tool__samrasTabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.data-tool__samrasWorkspace {
  min-width: 0;
}

.data-tool__samrasGraph {
  display: block;
  overflow-x: auto;
  padding: 8px 0 4px;
  min-height: 380px;
}

.data-tool__samrasGraph.is-branch-layout {
  display: flex;
  gap: 12px;
}

.data-tool__samrasGraph.is-full-layout {
  display: block;
}

.data-tool__samrasSpanGraph {
  min-width: 1080px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.data-tool__samrasSpanLane {
  display: grid;
  grid-template-columns: 78px minmax(0, 1fr);
  gap: 8px;
  align-items: stretch;
}

.data-tool__samrasSpanLaneHead {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  color: var(--ink2);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  min-height: 56px;
}

.data-tool__samrasSpanLaneBody {
  display: flex;
  gap: 6px;
  min-height: 56px;
}

.data-tool__samrasSpanNode {
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  color: var(--ink);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 2px;
  min-width: 64px;
  padding: 6px 8px;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
}

.data-tool__samrasSpanNode:hover {
  border-color: var(--accent);
}

.data-tool__samrasSpanNode.is-branch {
  background: var(--paper);
}

.data-tool__samrasSpanNode.is-selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px rgba(30, 105, 165, 0.15);
}

.data-tool__samrasSpanNodeTitle {
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.data-tool__samrasSpanNodeAddress {
  font-size: 11px;
  color: var(--ink2);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.data-tool__samrasColumn {
  min-width: 240px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
  padding: 10px;
}

.data-tool__samrasColumnHead {
  font-size: 11px;
  font-weight: 700;
  color: var(--ink2);
  margin-bottom: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.data-tool__samrasNode {
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  padding: 6px 7px;
  margin-bottom: 6px;
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr);
  gap: 8px;
  min-height: 44px;
}

.data-tool__samrasNode:hover {
  border-color: var(--accent);
}

.data-tool__samrasNode.is-branch {
  background: var(--paper);
}

.data-tool__samrasNode.is-expanded {
  border-color: var(--accent);
}

.data-tool__samrasNode.is-selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px rgba(30, 105, 165, 0.15);
}

.data-tool__samrasNodeToggle {
  width: 26px;
  height: 30px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--paper);
  color: var(--ink2);
  cursor: pointer;
  align-self: start;
  margin-top: 2px;
  padding: 0;
}

.data-tool__samrasNodeToggle:disabled {
  opacity: 0.65;
  cursor: default;
}

.data-tool__samrasNodeSelect {
  border: 0;
  padding: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
  min-width: 0;
}

.data-tool__samrasNodeSelect:hover .data-tool__samrasNodeTitle {
  color: var(--accent);
}

.data-tool__samrasNodeSelect:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.data-tool__samrasNodeText {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.data-tool__samrasNodeAddress {
  font-size: 11px;
  color: var(--ink2);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.data-tool__samrasNodeTitle {
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.data-tool__samrasSidebar {
  margin-top: 12px;
}

.data-tool__samrasSummaryDetails {
  margin-top: 10px;
}

.data-tool__samrasSummaryDetails summary {
  cursor: pointer;
  font-weight: 700;
  color: var(--ink2);
  margin-bottom: 8px;
}

.data-tool__samrasSummaryTable tbody tr.is-active {
  background: var(--paper);
}

.data-tool__profileModal {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
}

.data-tool__profileModal[hidden] {
  display: none !important;
  pointer-events: none;
}

.data-tool__profileBackdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
}

.data-tool__profileDialog {
  position: relative;
  z-index: 1;
  width: min(900px, calc(100vw - 24px));
  max-height: calc(100vh - 24px);
  overflow: auto;
}

.data-tool__appendDialog {
  width: min(820px, calc(100vw - 24px));
}

.data-tool__profileHeader {
  display: flex;
  align-items: start;
  justify-content: space-between;
  gap: 8px;
}

.data-tool__profileTarget {
  margin: 6px 0 0;
  color: var(--ink2);
  font-size: 13px;
}

.data-tool__profileTabs {
  margin-top: 12px;
  display: flex;
  gap: 6px;
}

.data-tool__profileTab {
  min-height: 30px;
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--paper);
  font-size: 12px;
  cursor: pointer;
}

.data-tool__profileTab.is-active {
  border-color: var(--accent);
  color: var(--accent);
}

.data-tool__profilePanel {
  display: none;
  margin-top: 12px;
}

.data-tool__profilePanel.is-active {
  display: block;
}

.data-tool__profileMeta {
  display: grid;
  gap: 8px;
  margin-top: 10px;
  font-size: 12px;
}

.data-tool__profileFooter {
  margin-top: 12px;
}

.data-tool__appendPairs {
  margin-top: 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  padding: 10px;
}

.data-tool__appendPairsHeader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.data-tool__appendPairsHeader h3 {
  margin: 0;
  font-size: 13px;
  color: var(--ink);
}

.data-tool__appendPairsList {
  margin-top: 8px;
  display: grid;
  gap: 8px;
}

.data-tool__appendPairRow {
  display: grid;
  grid-template-columns: minmax(220px, 1fr) minmax(220px, 1fr) auto;
  gap: 8px;
  align-items: end;
}

.data-tool__appendPairRow label {
  min-width: 0;
}

.data-tool__appendPairRow input {
  width: 100%;
}

.data-tool__profilePath {
  max-height: 420px;
  overflow: auto;
}

.data-tool__pathList {
  margin: 0;
  padding-left: 20px;
  display: grid;
  gap: 10px;
}

.data-tool__pathItem {
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  padding: 8px;
}

.data-tool__pathRef {
  margin-top: 6px;
  font-size: 12px;
  color: var(--ink2);
}

.data-tool__profileIconCurrent {
  margin-top: 8px;
}

.data-tool__iconControls {
  margin-top: 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: end;
}

.data-tool__iconControls label {
  min-width: 240px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.data-tool__iconControls input {
  min-height: 34px;
}

.data-tool__iconList {
  margin-top: 12px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 8px;
}

.data-tool__iconOption {
  min-height: 40px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  text-align: left;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px;
  font-size: 12px;
  cursor: pointer;
  word-break: break-all;
}

.data-tool__iconOptionText {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.data-tool__iconOptionText strong {
  font-size: 12px;
  color: var(--ink);
  word-break: break-word;
}

.data-tool__iconOptionMeta {
  color: var(--ink2);
  font-size: 11px;
  word-break: break-all;
}

.data-tool__iconOption:hover {
  border-color: var(--accent);
}

.data-tool__iconOption.is-selected {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px rgba(30, 108, 147, 0.18);
}

@media (max-width: 900px) {
  .data-tool__profileDialog {
    width: calc(100vw - 12px);
    max-height: calc(100vh - 12px);
  }

  .data-tool__appendPairRow {
    grid-template-columns: 1fr;
  }
}

.serviceshell__link.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-fg);
}

.serviceshell__item.is-active {
  background: var(--paper2);
  font-weight: 700;
}

.serviceshell__item.is-empty {
  color: var(--ink2);
  cursor: default;
}

.serviceshell__activeTab.is-empty {
  color: var(--ink2);
}

.servicetabs__tab.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-fg);
}

.serviceshell__link.is-active {
  color: var(--accent);
  border-color: var(--accent);
  background: rgba(30, 108, 147, 0.1);
}

.serviceshell .themebar {
  margin-left: auto;
  padding: 0;
}

.serviceshell .themebar__select {
  min-width: 120px;
}

@media (max-width: 860px) {

  .serviceshell .themebar {
    margin-left: 0;
  }
}

/* Sidebar shell updates */
.navcol__homeButton {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 10px;
  border-radius: var(--radius);
  border: 1px solid rgba(255,255,255,0.18);
  text-decoration: none;
  color: #f3f2e5;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: rgba(255,255,255,0.04);
}

.navcol__homeButton:hover {
  background: rgba(255,255,255,0.1);
}

.navcol__homeIcon,
.navcol__sectionIcon {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
}

.navcol__sectionTitle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.card--full {
  grid-column: 1 / -1;
}

.navcol__portalList {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.navcol__portalItem {
  border: 1px solid rgba(255,255,255,0.14);
  border-radius: var(--radius);
  padding: 6px 8px;
  background: rgba(255,255,255,0.05);
}

.navcol__portalItemTop {
  display: flex;
  justify-content: space-between;
  gap: 6px;
  align-items: baseline;
}

.navcol__portalName {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(240,238,220,0.95);
}

.navcol__portalMeta {
  font-size: 10px;
  color: rgba(240,238,220,0.55);
}

.navcol__portalLink {
  margin-top: 4px;
  display: inline-flex;
  font-size: 11px;
  color: var(--accent2);
  text-decoration: none;
}

.navcol__portalLink:hover {
  text-decoration: underline;
}

.navcol__portalItem.is-empty {
  color: rgba(240,238,220,0.55);
  font-size: 11px;
}

/* Locked IDE shell */
:root {
  --ide-menu-h: 38px;
  --ide-activity-w: 60px;
}

.ide-shell {
  /* NO `vh` FLOOR HERE. See the sizing note beside the peer-region rule below: a
     `min-height` clamps a `height`, so a floor in `vh` would put the shell's bottom
     under the phone's browser chrome no matter what the height says. */
  display: flex;
  flex-direction: column;
}

.ide-menubar {
  min-height: var(--ide-menu-h);
  display: grid;
  grid-template-columns: minmax(0, max-content) minmax(0, 1fr) minmax(0, max-content);
  align-items: center;
  gap: 14px;
  padding: 0 10px;
  background: color-mix(in srgb, var(--coal, #2f2f2f) 88%, var(--coal) 12%);
  color: rgba(255, 255, 255, 0.78);
  border-bottom: 1px solid color-mix(in srgb, var(--coal, #2f2f2f) 68%, var(--line) 32%);
  font-size: 12px;
  min-width: 0;
}

.ide-menubar__center {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  min-width: 0;
  width: 100%;
  max-width: none;
  overflow: hidden;
  justify-self: center;
}

.ide-menubar__center > * {
  min-width: 0;
}

.ide-menubar__pageTitle {
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #f1f4f7;
  flex: 0 0 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ide-menubar__pageSub {
  color: rgba(235, 240, 246, 0.64);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  flex: 0 1 auto;
}

.ide-shell--system-workbench .ide-menubar__pageSub {
  max-width: min(44vw, 520px);
}

.ide-shell--system-workbench.ide-shell--workbench-tight .ide-menubar__pageSub {
  display: none;
}

.ide-menubar__right {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-self: end;
  gap: 10px;
  min-width: 0;
  max-width: 100%;
  flex-wrap: nowrap;
  overflow: hidden;
}

.ide-menubar__shellActions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: nowrap;
  min-width: 0;
}

.ide-menubar__shellActions .ide-sessionAction {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  min-width: 28px;
  height: 28px;
  min-height: 28px;
  padding: 0;
}

.ide-sessionAction--icon {
  min-width: 28px;
  padding: 0;
  /* Re-derive the critical-CSS fallback's loam button from the theme. */
  background: var(--coal2);
  border: 1px solid var(--line);
}

.ide-sessionAction__icon {
  display: inline-flex;
  width: 16px;
  height: 16px;
}

.ide-sessionAction__icon svg {
  width: 100%;
  height: 100%;
}

.ide-menubar__theme {
  padding: 0;
  flex-wrap: nowrap;
}

.ide-menubar__theme .themebar__label {
  color: rgba(235, 240, 246, 0.74);
}

.ide-menubar__theme .themebar__select {
  background: rgba(16, 22, 30, 0.8);
  color: #f0f4f8;
  border-color: rgba(235, 240, 246, 0.2);
  min-height: 28px;
  font-size: 11px;
}

.ide-menubar__shellActions [data-shell-lockable="tool-panel"].is-locked {
  border-color: rgba(120, 205, 175, 0.72);
  background: rgba(120, 205, 175, 0.22);
  color: #f7fffb;
}

.ide-body {
  min-height: calc(100vh - var(--ide-menu-h));
  display: grid;
  grid-template-columns: var(--ide-activity-w) minmax(0, 1fr);
  background: var(--paper);
}

/* A tool with no drawn glyph wears its initials. Sized and weighted to read at rail
   scale, where a two-letter mark is the whole affordance. */
.ide-activityicon--mono {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1;
}

.ide-activitybar {
  background: var(--coal);
  color: #ececec;
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;

  /* THE COLUMN'S ONE RULE, as a token (2026-10-26). The group separators below and the
     footer's border-top both read it, because the separator comment has said since
     2026-10-07 that the column has one rule and not two — and that sentence has to stay
     true when the value moves. The operator asked for the lines between instruments, apps
     and pages to be "more contrasting and clear"; this is 0.09 -> 0.26 alpha, which is the
     move, and it happens in one place. */
  --rail-rule: rgba(255, 255, 255, 0.26);
}

/* The rail: the portal's four axes in the nav, the Profile entry in the footer at the
   actual bottom, and — since 2026-09-01, as the GALLERY's tiles since 2026-10-07 — the
   installed apps and the instruments below the axes. The logo anchor, the section
   dividers and the switcher popover left with the launcher rail.

   THE SCROLLING IS `.ide-railBody`'s, NOT THIS ELEMENT'S, and that is why this rule adds
   no overflow of its own. Twenty-one items at ~44px is ~924px, past a laptop's height, so
   a first pass gave the nav `overflow-y: auto; min-height: 0` here — dead CSS, because
   `flex: 0 0 auto` below means the nav never shrinks and so never overflows. The parent
   already carries `flex: 1 1 auto; min-height: 0; overflow-y: auto`; the footer stays put
   because the scroller sits between them. */
.ide-activitynav {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px 6px;
  scrollbar-width: thin;
  /* Inside .ide-railBody (the scroller) the nav keeps its full height: shrinking it
     would hide items instead of scrolling to them. */
  flex: 0 0 auto;
}

.ide-activitylink {
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  color: #c8c8c8;
  border: 1px solid transparent;
  border-radius: 6px;
  padding: 10px 0;
  min-height: 42px;
}

.ide-activityicon {
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.ide-activityicon svg,
.ide-activityicon img {
  width: 22px;
  height: 22px;
  display: block;
}

/* The rail's glyphs are an EXTERNAL <use> into the shared sprite, and an external use
   renders behind a shadow boundary this stylesheet cannot cross. `fill` and `stroke` rules
   here do NOTHING — and fail silently, drawing the icon in the wrong colour with no error
   anywhere. Every symbol in the sprite is `currentColor`, so `color` is the ONE control,
   and it is inherited from .ide-activitylink (#c8c8c8, #fff when active or hovered).
   Do not "fix" this by adding a fill. */
.ide-activityicon svg {
  color: inherit;
}

/* Every rail item CARRIES its label; on a desk nothing draws it. The name arrives on
   hover through `title`, and a column of names would be a sidebar rather than a rail.
   The phone bar keeps them hidden too — five labelled cells do not fit 390px — so the
   label exists for assistive tech and for any future breakpoint that wants it. */
.ide-activitylabel {
  display: none;
}

.ide-activitylink:hover {
  background: rgba(255, 255, 255, 0.07);
  color: #fff;
}

.ide-activitylink.is-active {
  border-color: rgba(30, 108, 147, 0.8);
  background: rgba(30, 108, 147, 0.23);
  color: #fff;
}

/* THE GROUPS READ. The desk rail is axes · installed apps · instruments · Profile — the
   gallery's own bands (2026-10-07) — and a hairline with some air marks each change of
   kind: the same hairline the footer's border-top draws, so the column has one rule, not
   two. Drawn from the DOM's own facts (data-nav-kind, data-nav-group) by sibling
   selectors: no divider ITEM in the payload, which test_activity_rail still refuses. On a
   phone the tool cells are display:none, so these never paint there. */
.ide-activitynav [data-nav-kind="surface"] + [data-nav-kind="tool"],
.ide-activitynav [data-nav-group="app"] + [data-nav-group="instrument"] {
  margin-top: 18px;
  position: relative;
}
.ide-activitynav [data-nav-kind="surface"] + [data-nav-kind="tool"]::before,
.ide-activitynav [data-nav-group="app"] + [data-nav-group="instrument"]::before {
  content: "";
  position: absolute;
  left: 8px;
  right: 8px;
  top: -15px;
  border-top: 1px solid var(--rail-rule, rgba(255, 255, 255, 0.26));
}

/* ===== THREE KINDS THAT READ AS THREE (operator, 2026-10-26) =================
   "Applications should be in rouded corner box oultine containers so visualy distinguish
   them from the rest of the acitivty bar icons. Then instraments like the calendar and
   roladex should be obverses such that there icon is the oberse of the themes color usage
   so they are a contrasting color inside of a rounded corner solid box container."

   So: a PAGE is a bare glyph, an APPLICATION is an outline box, an INSTRUMENT is the
   obverse — a solid box with the glyph in the rail's own GROUND colour. The distinction is
   carried by the CONTAINER and not by hue: it survives greyscale, it survives all five
   themes, and it spends no accent colour, which matters because the lit cell's accent has
   to stay the loudest thing in the column.

   THE OBVERSE IS THE RAIL'S OWN TWO COLOURS, SWAPPED. The fill is the rail's ink
   (#c8c8c8..#fff) and the glyph is `var(--coal)`, the rail's ground — so no theme is named
   and every theme carries it, from paper's #2f2f2f to spore's #0f0d0b. Importing a light
   palette here would have been a sixth theme nobody declared.

   `data-nav-group` already rides the DOM (2026-10-07) and the payload needed no change.
   On a phone `[data-nav-kind="tool"]` is display:none, so none of this paints there. */
.ide-activitynav [data-nav-group="app"] {
  border-color: rgba(255, 255, 255, 0.34);
  border-radius: 8px;
}
.ide-activitynav [data-nav-group="instrument"] {
  background: rgba(236, 236, 236, 0.93);
  color: var(--coal);
  border-color: transparent;
  border-radius: 8px;
}

/* THE THREE BLOCKS ABOVE MUST STAY BELOW `.ide-activitylink:hover` AND `.is-active`, and
   that is a specificity fact, not a preference. `.ide-activitynav [data-nav-group="…"]` is
   two class-level selectors; so are `.ide-activitylink:hover` and
   `.ide-activitylink.is-active` (`:hover` and a second class both count class-level). At
   equal specificity SOURCE ORDER decides, so moving the group block up the file is enough
   for hover's pale wash to erase the obverse — MEASURED 2026-10-26 by doing exactly that,
   which turned `test_the_three_kinds_read_as_three` red on
   `rgba(255,255,255,0.07)`. Deleting the `:hover` restatements below did NOT turn it red,
   because they are higher-specificity belt-and-braces rather than the thing holding the
   obverse up. Both experiments are in that test's evidence; do not reorder this section.

   THE LIT CELL KEEPS ITS ACCENT BORDER. `.is-active` sets `border-color` to the accent and
   the group rules above set it too, at the same specificity and later in the file — so
   without these two restatements a lit APPLICATION cell draws a white outline and only the
   accent WASH survives, which quietly costs the rail its loudest signal. */
.ide-activitynav [data-nav-group="app"]:hover {
  border-color: rgba(255, 255, 255, 0.55);
}
.ide-activitynav [data-nav-group="app"].is-active {
  border-color: rgba(30, 108, 147, 0.9);
}
.ide-activitynav [data-nav-group="instrument"]:hover {
  background: #fff;
  color: var(--coal);
}
.ide-activitynav [data-nav-group="instrument"].is-active {
  background: #fff;
  color: var(--accent, #1e6c93);
  border-color: rgba(30, 108, 147, 0.9);
}

/* DEAD TODAY AND WRITTEN ANYWAY. `activityIconMarkup` emits `<svg><use>` or a monogram
   span and never an `<img>`, so no rail glyph is a raster one. But the live
   `.ide-activityicon img` rules above invert to near-white for every theme, and the day a
   raster glyph does reach the rail it would vanish on the obverse — a solid light box with
   nothing in it, and no error anywhere. */
.ide-activitynav [data-nav-group="instrument"] .ide-activityicon img {
  filter: brightness(0) invert(0.1);
}

/* The Profile slot, pinned to the foot of the activity bar. It renders ONE
   .ide-activitylink (the rail's fifth surface item); the border above it is the
   "actual bottom" statement from the depiction. */
.ide-activityfooter {
  margin-top: auto;
  padding: 6px;
  border-top: 1px solid var(--rail-rule, rgba(255, 255, 255, 0.26));
  position: relative;
}
.ide-activityfooter:empty {
  display: none;
}

.ide-sessionLine {
  color: #d2d2d2;
  font-size: 10px;
  line-height: 1.3;
}

.ide-sessionLine--dim {
  color: #a6a6a6;
}

.ide-sessionAction {
  display: block;
  text-decoration: none;
  color: #f0f0f0;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 6px;
  padding: 6px 6px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-align: center;
}

.ide-sessionAction:hover {
  background: rgba(255, 255, 255, 0.14);
}

.ide-sessionAction:disabled {
  opacity: 0.48;
  cursor: not-allowed;
  background: rgba(255, 255, 255, 0.04);
}

.u-visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.v2-surfaceTabs__tab.is-active {
  border-color: rgba(120, 205, 175, 0.56);
  background: rgba(120, 205, 175, 0.14);
  color: #fff;
}

.data-tool__systemContext {
  margin-top: 10px;
  min-height: 60px;
}

.data-tool__systemContext .data-tool__datumEditor {
  margin: 0;
  padding: 8px 0;
}

.data-tool__systemContext .data-tool__editorHeader,
.data-tool__systemContext .data-tool__controlRow,
.data-tool__systemContext .data-tool__appendPairs {
  margin-bottom: 8px;
}

.data-tool__systemContext .data-tool__appendPairRow {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
}
.data-tool__systemContext .data-tool__appendPairRow label {
  min-width: 0;
}
.data-tool__systemContext .data-tool__appendPairRow .data-tool__actionBtn {
  flex-shrink: 0;
}

.data-tool__systemContext .data-tool__iconBlock {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.data-tool__iconPickerWrap.is-hidden {
  display: none;
}

.data-tool__iconBlockActions {
  display: flex;
  gap: 8px;
  margin-top: 6px;
  margin-bottom: 8px;
}

.data-tool__systemContextInspectWrap {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.data-tool__systemContextInspectHeader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

.data-tool__systemContextInspectTitle {
  font-size: 12px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.9);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.data-tool__systemContextExit {
  flex-shrink: 0;
  min-width: 28px;
  padding: 4px 8px;
  font-size: 18px;
  line-height: 1;
}

.data-tool__selectModeBtn {
  margin-top: 10px;
}

.data-tool__selectModeWrap {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.data-tool__selectModeHint {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.8);
  margin: 0;
}

.data-tool__selectModeListLabel {
  font-size: 12px;
  font-weight: 600;
}

.data-tool__selectModeList {
  margin: 0;
  padding-left: 18px;
  font-size: 12px;
  max-height: 120px;
  overflow-y: auto;
}

.data-tool__selectModeResult {
  margin-top: 8px;
}

.data-tool__mssBitstring {
  font-size: 11px;
  word-break: break-all;
  white-space: pre-wrap;
  max-height: 200px;
  overflow: auto;
  padding: 8px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 6px;
  margin: 0 0 8px 0;
}

.data-tool__mssCopyBtn {
  margin-top: 4px;
}

.js-anthology-row.is-compact-selected {
  background: rgba(30, 108, 147, 0.25);
  outline: 1px solid rgba(30, 108, 147, 0.5);
}

.data-tool__systemContextSearch {
  display: block;
  font-size: 11px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.7);
  margin-bottom: 6px;
}

.data-tool__systemContextSearchInput {
  width: 100%;
  padding: 6px 8px;
  font-size: 12px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.2);
  color: #eee;
}

/* Directive terminal. It shipped with a themed input surface but no layout at all,
so the section ran together as loose text over UA-default buttons {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 10px 0;
}

/* One section header for the whole rail. Both of its two uses — the terminal and a
   tool extension — are the same thing (a named block of controls),
and neither had
   any style {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink2);
}

/* A tool's own controls,
contributed to the rail by whichever tool is open. They
   are a group {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
}

/* The shortcut is a footnote to the verb {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 10px;
  color: var(--ink2);
  border: 0;
  background: none;
  padding: 0;
}

.ide-workbench {
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: auto;
}

.data-tool__main--workspaceOnly {
  min-width: 0;
  min-height: 0;
}

.data-tool__moduleSurface {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px;
  background: var(--paper);
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  flex: 1 1 auto;
}

.data-tool__graphToolbar--compact {
  border-bottom: 1px solid var(--line);
  padding-bottom: 8px;
  margin-bottom: 4px;
}

.data-tool__statusInline {
  font-size: 12px;
  color: var(--ink2);
  margin: 0 0 6px;
  min-height: 1em;
}

.lr-workbench__layout--centerOnly {
  display: grid;
  grid-template-columns: minmax(220px, 340px) minmax(0, 1fr);
  gap: 12px;
  align-items: stretch;
}

.lr-workbench__titleRow--compact {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

.lr-workbench__resourceTitle {
  font-weight: 700;
  font-size: 15px;
}

.inh-workbench__centerHead {
  font-weight: 700;
  margin-bottom: 8px;
}

.viewport--system .system-center-workspace {
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  width: 100%;
  padding: 10px 12px 12px;
  box-sizing: border-box;
  gap: 10px;
}

.viewport--system .system-center-workspace > * {
  min-width: 0;
  width: 100%;
}

.system-mediation-workbench {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.system-mediation-workbench .card__body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

#systemMediationBody {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
  align-content: start;
}

#systemMediationBody > * {
  min-width: 0;
  max-width: none;
  width: 100%;
}

#systemMediationBody .card,
#systemMediationBody .data-tool__advanced {
  width: 100%;
  max-width: none;
}

@media (max-width: 960px) {
  .lr-workbench__layout--centerOnly,
  .inh-workbench__layout.inh-workbench__layout--twoCol {
    grid-template-columns: 1fr;
  }
}

.page-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 10px 12px 0;
}

.page-tab {
  text-decoration: none;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  border-radius: 6px;
  padding: 5px 10px;
  font-size: 12px;
  font-weight: 700;
}

.page-tab.is-active {
  border-color: var(--accent);
  color: var(--accent);
}

.network-workbench {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
}

.network-layout {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.network-layout__columns {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: 12px;
  align-items: start;
}

.network-workbench__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
}

.network-toolbar {
  margin-bottom: 0;
}

.network-channel,
.network-sidecard {
  min-width: 0;
}

.network-thread {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.network-thread__row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  flex-wrap: wrap;
}

.network-thread__row strong {
  color: var(--ink2);
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 0.05em;
}

.network-workbench__actions {
  display: flex;
  gap: 6px;
}

@media (max-width: 1180px) {
  .network-layout__columns {
    grid-template-columns: 1fr;
  }
}

/* Data tool drawers use a right-side drawer posture */
.data-tool__nimmOverlay {
  inset: var(--ide-menu-h) 0 0 auto;
  width: min(820px, 96vw);
  display: none;
  grid-template-columns: 1fr;
  justify-items: end;
  pointer-events: none;
}

.data-tool__nimmOverlay[hidden] {
  display: none !important;
}

.data-tool__nimmOverlay .data-tool__nimmBackdrop {
  display: none;
}

.data-tool__nimmOverlay .data-tool__nimmPanel {
  pointer-events: auto;
  width: 100%;
  max-height: calc(100vh - var(--ide-menu-h));
  margin: 0;
  border-radius: 0;
  border-left: 1px solid var(--line);
}

.data-tool__profileModal {
  inset: var(--ide-menu-h) 0 0 auto;
  width: min(520px, 96vw);
  display: none;
  place-items: stretch end;
  pointer-events: none;
  z-index: 91;
}

.data-tool__profileModal[hidden] {
  display: none !important;
}

.data-tool__profileModal .data-tool__profileBackdrop {
  display: none;
}

.data-tool__profileModal .data-tool__profileDialog {
  pointer-events: auto;
  width: 100%;
  max-height: calc(100vh - var(--ide-menu-h));
  margin: 0;
  border-radius: 0;
  border-left: 1px solid var(--line);
}

/* Portal shell peer-region overrides */
/* THE SHELL IS THE VISIBLE VIEWPORT.                              (2026-08-18)
   `100vh` on a phone browser is the LARGE viewport — the window with the URL bar
   retracted — so a shell sized to it always ends below the screen by the height of
   the browser's own furniture, and everything anchored to its bottom goes with it:
   the network sheet at `bottom: 0`, and the rail's pinned instance switcher. The
   operator could reach neither.

   A `dvh` height was added under `max-width: 700px` on 2026-08-16 and did not fix it,
   for two reasons this rule now settles:

     1. `min-height: 100vh` was still declared, here and on the base rule above, and a
        min-height ALWAYS clamps a height. The shell computed `max(100dvh, 100vh)`,
        which is `100vh` — the floor won every time.
     2. `max-width: 700px` is not "a phone". A phone in LANDSCAPE is 844px wide and
        never entered that query at all, so the one viewport where the loss is worst
        got no `dvh` whatever. The unit belongs here, at every width: on a desk `dvh`
        and `vh` are the same number, so nothing about the desktop changes.

   The `vh` line stays first as the fallback for anything without `dvh`. */
.ide-shell {
  height: 100vh;
  height: 100dvh;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  /* EDGE TO EDGE COSTS THE SIDES BACK (2026-10-31, with `viewport-fit=cover`). In
     landscape the notch is at the side, and these are 0 everywhere else — including
     every desktop — so this is the landscape phone's rule and nobody else's. It sits
     outside the phone query for the reason the `dvh` above does: a phone in landscape
     is 844px wide and enters no phone query at all. */
  padding-left: env(safe-area-inset-left, 0px);
  padding-right: env(safe-area-inset-right, 0px);
}

.ide-menubar {
  flex: 0 0 var(--ide-menu-h);
  min-height: var(--ide-menu-h);
  overflow: hidden;
  min-width: 0;
}

.ide-menubar__menu {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
  flex-wrap: nowrap;
  overflow: hidden;
}

.ide-menubar__menu span {
  white-space: nowrap;
}

.ide-menubar__spacer {
  flex: 1 1 auto;
  min-width: 12px;
}

.ide-menubar__actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.ide-menubar__toggle {
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.08);
  color: #ececec;
  border-radius: 6px;
  min-height: 28px;
  padding: 0 10px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  cursor: pointer;
}

.ide-menubar__toggle:hover {
  background: rgba(255, 255, 255, 0.16);
}

.ide-menubar__toggle.is-active {
  border-color: rgba(120, 205, 175, 0.58);
  background: rgba(120, 205, 175, 0.18);
  color: #fff;
}

.ide-body {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  /* Two columns: the rail you navigate with, and the workbench that answers.
     The control-panel column and its splitter were retired 2026-08-16 — on a
     phone that column became a fixed drawer over the workbench with no reachable
     way to close it, which is why the portal would not load on a phone at all. */
  grid-template-columns: var(--ide-activity-w) minmax(0, 1fr);
  grid-template-areas: "activity workbench";
  overflow: hidden;
  align-items: stretch;
}

/* THE RAIL CANNOT BE TALLER THAN ITS BOX, at any viewport.
   It used to scroll as ONE box, and .ide-activityfooter's `margin-top: auto` then put
   the instance switcher below the fold whenever the items were taller than the screen —
   measured at 844x390 (a phone in landscape, which is a DESKTOP width): scrollHeight 392
   against clientHeight 352, profile button off-screen. Reaching it meant scrolling a
   48px column with a thumb.
   So the rail clips, the NAV is the only scroller, and the foot is pinned. `min-width: 0`
   because a grid item defaults to `min-width: auto` and this one's content measures 56px
   in a 48px track — it was overlapping the workbench by 8px at every phone width. */
.ide-activitybar {
  grid-area: activity;
  min-width: 0;
  overflow: hidden;
}

.ide-railBody {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
}

.ide-activityfooter {
  flex: 0 0 auto;
}

/* The canvas is the theme's paper — no wash. Two hardcoded dark gradients
   used to dim the whole workbench (the heavier one keyed to
   data-active-service="system", which no server ever sets to anything else,
   so it was permanent). Invisible on spore/midnight, they ran the light
   themes ~30% darker than their own palette tokens. The explicit background
   here also overrides the template's critical-CSS fallback (.ide-workbench
   background:#16130e), a duty the deleted gradient shorthand used to carry;
   the border-left re-derives the fallback's loam hairline from the theme. */
.ide-workbench {
  grid-area: workbench;
  min-width: 0;
  min-height: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--paper);
  border-left: 1px solid var(--line);
}

.ide-shell[data-workbench-collapsed="true"] .ide-workbench,
.ide-workbench[data-foreground-visible="false"] {
  display: none;
}

.ide-workbench > * {
  min-width: 0;
  width: 100%;
}

.viewport {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  align-self: stretch;
}

.ide-activitybar,
.ide-workbench {
  height: 100%;
  min-height: 0;
}

.ide-activityicon img {
  filter: brightness(0) invert(0.88);
}

.theme-paper .ide-activityicon img {
  filter: brightness(0) invert(0.9);
}

.theme-midnight .ide-activityicon img,
.theme-ocean .ide-activityicon img,
.theme-forest .ide-activityicon img {
  filter: brightness(0) invert(0.98);
}

.viewport {
  flex: 1 1 auto;
  min-height: 0;
  height: auto;
  overflow: auto;
  overscroll-behavior: contain;
}

.viewport--system {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  width: 100%;
  min-height: 0;
  height: 100%;
  overflow: hidden;
  padding: 0;
  align-items: stretch;
  justify-content: flex-start;
}

.viewport--system > * {
  min-width: 0;
  width: 100%;
}

.viewport--system > .data-tool,
.viewport--system > .lr-workbench,
.viewport--system > .inh-workbench {
  flex: 1 1 auto;
  width: 100%;
  max-width: none;
  align-self: stretch;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.system-sidebar__resourceButton.is-active {
  border-color: rgba(65, 173, 255, 0.8);
  background: rgba(37, 86, 120, 0.42);
  box-shadow: 0 0 0 1px rgba(65, 173, 255, 0.5);
}

.data-tool,
.data-tool__layout,
.data-tool__main,
.data-tool__anthologyWorkbench,
.data-tool__workbenchGrid,
.data-tool__graphPane,
.data-tool__graphCanvas {
  height: 100%;
}

.data-tool__layout--workbench,
.data-tool__workbenchGrid {
  min-height: 0;
}

.data-tool__workbenchGrid[data-layout-mode="table"],
.data-tool__workbenchGrid[data-layout-mode="linear"],
.data-tool__workbenchGrid[data-layout-mode="radial"] {
  grid-template-columns: minmax(0, 1fr);
}

.data-tool__workbenchGrid[data-layout-mode="grouped"] {
  grid-template-columns: 1fr;
  grid-template-rows: minmax(0, 1fr);
  align-items: stretch;
}

.data-tool__workbenchGrid[data-layout-mode="grouped"] .data-tool__anthologyTableHost {
  display: none !important;
}

.data-tool__workbenchGrid[data-layout-mode="grouped"] .data-tool__graphPane {
  display: flex;
  flex-direction: column;
  min-height: 48vh;
}

.data-tool__workbenchGrid[data-layout-mode="table"] {
  align-items: stretch;
}

.data-tool__graphPane {
  min-height: 0;
}

.data-tool__tablePane {
  height: 100%;
  min-height: 0;
}

.data-tool__workbenchGrid[data-layout-mode="table"] .data-tool__graphPane {
  display: none !important;
}

.data-tool__workbenchGrid[data-layout-mode="linear"] .data-tool__tablePane,
.data-tool__workbenchGrid[data-layout-mode="radial"] .data-tool__tablePane {
  display: none;
}

.data-tool__graphCanvas {
  min-height: 58vh;
}

/* TXA sandbox workspace (sandbox SAMRAS resource + title table + branch aside) */
.data-tool__workspaceTabs {
  margin: 0 0 12px;
  flex-wrap: wrap;
}

.data-tool__workspacePanel {
  min-height: 0;
}

.data-tool__workspacePanel[hidden] {
  display: none !important;
}

.data-tool--systemWorkbench .data-tool__workspacePanel {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

.data-tool--systemWorkbench {
  position: relative;
}

.data-tool--systemWorkbench > .data-tool__messages {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 8;
  max-width: min(44ch, 48%);
}

.data-tool--systemWorkbench .data-tool__moduleSurface,
.data-tool--systemWorkbench .data-tool__graphPane,
.data-tool--systemWorkbench .data-tool__tablePane {
  border: 0;
  border-radius: 0;
  background: transparent;
  padding: 0;
  box-shadow: none;
}

.data-tool--systemWorkbench .data-tool__resourcesWorkbench {
  position: relative;
  padding-top: 112px;
  gap: 0;
}

.data-tool--systemWorkbench .data-tool__workbenchGrid {
  gap: 0;
}

.data-tool--systemWorkbench .data-tool__graphPane,
.data-tool--systemWorkbench .data-tool__tablePane {
  overflow: auto;
}

.data-tool__workbenchFloatingControls {
  position: absolute;
  top: 8px;
  right: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 8px;
}

.data-tool__workbenchFloatingControls--right {
  right: 8px;
}

.data-tool__workbenchFloatingControls button,
.data-tool__workbenchFloatingControls select {
  min-height: 34px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: color-mix(in srgb, var(--paper) 92%, var(--paper) 8%);
  color: var(--ink);
  box-shadow: 0 10px 24px color-mix(in srgb, var(--coal) 12%, transparent);
}

.data-tool__workbenchFloatingControls select {
  padding: 0 28px 0 10px;
}

.data-tool__workbenchFloatingControls button:hover,
.data-tool__workbenchFloatingControls select:hover {
  background: color-mix(in srgb, var(--paper2) 86%, var(--paper) 14%);
}

.data-tool__workbenchFloatingControls button:focus-visible,
.data-tool__workbenchFloatingControls select:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--coal2) 48%, var(--line) 52%);
  outline-offset: 2px;
}

.data-tool__layout--txaSandbox {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 34%);
  gap: 14px;
  align-items: start;
  min-height: 0;
}

@media (max-width: 1100px) {
  .data-tool__layout--txaSandbox {
    grid-template-columns: 1fr;
  }
}

.data-tool__txaSandboxCard {
  min-height: 0;
}

.data-tool__resourcesFileTabs {
  display: inline-flex;
  gap: 6px;
  flex-wrap: wrap;
}

.data-tool__resourcesFileTab {
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface, #fff);
  padding: 6px 10px;
  font-size: 0.85rem;
  cursor: pointer;
}

.data-tool__resourcesFileTab.is-active {
  border-color: var(--accent, #2f6fed);
  box-shadow: 0 0 0 1px var(--accent, #2f6fed);
}

.data-tool__resourcesTaskButtons {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}

.data-tool__systemDock {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 5;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: min(720px, calc(100% - 92px));
}

.data-tool__systemNimmButtons {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.data-tool__systemNimmButtons .data-tool__actionBtn {
  min-height: 34px;
  min-width: 120px;
  border-radius: 999px;
  box-shadow: 0 10px 24px color-mix(in srgb, var(--coal) 12%, transparent);
}

.data-tool__systemAitas {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  max-width: 100%;
}

.data-tool__aitasChip {
  width: min(168px, calc(100vw - 180px));
  min-width: 116px;
  padding: 6px 10px;
  border: 1px solid color-mix(in srgb, var(--line) 68%, var(--coal) 32%);
  border-radius: 8px;
  background: linear-gradient(180deg, rgba(248, 248, 248, 0.96), rgba(228, 228, 228, 0.96));
  color: var(--ink);
  box-shadow: 0 8px 18px color-mix(in srgb, var(--coal) 10%, transparent);
}

.data-tool__aitasLabel {
  display: block;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink2);
}

.data-tool__aitasValue {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
  max-width: 100%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.data-tool__resourcesTaskButtons .data-tool__actionBtn.is-active {
  outline: 2px solid var(--accent, #2f6fed);
}

.data-tool__resourcesWorkbench {
  flex: 1 1 auto;
  min-height: 0;
}

.data-tool__resourcesGrid {
  grid-template-columns: minmax(0, 1fr);
}

.data-tool__resourcesPane {
  min-height: 0;
}

.data-tool__floatingMenu {
  position: relative;
}

.data-tool__floatingMenuPanel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 230px;
  display: grid;
  gap: 6px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: color-mix(in srgb, var(--paper) 94%, var(--paper) 6%);
  box-shadow: 0 14px 34px color-mix(in srgb, var(--coal) 18%, transparent);
}

.data-tool__sourceMenuButton {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: color-mix(in srgb, var(--paper) 88%, var(--paper) 12%);
  color: var(--ink);
  text-align: left;
  cursor: pointer;
}

.data-tool__sourceMenuButton span {
  font-weight: 700;
}

.data-tool__sourceMenuButton small {
  color: var(--ink2);
}

.data-tool__sourceMenuButton.is-active {
  border-color: color-mix(in srgb, var(--coal2) 40%, var(--line) 60%);
  background: color-mix(in srgb, var(--paper2) 78%, var(--coal2) 22%);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--coal2) 32%, transparent);
}

.data-tool__resourcesInspectorStack {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  flex: 1 1 auto;
}

.data-tool__resourcesInspectorPanel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
  flex: 1 1 auto;
}

.data-tool__resourcesInspectorBody {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  overscroll-behavior: contain;
  display: grid;
  align-content: start;
  gap: 10px;
  width: 100%;
}

.data-tool__resourcesInspectorBody > * {
  min-width: 0;
  max-width: none;
}

.data-tool__resourcesInspectorHeading {
  font-size: 0.85rem;
  margin: 0 0 6px 0;
}

.data-tool__resourcesDatumProfile {
  margin-top: 6px;
}

.data-tool__resourcesMediateList {
  margin: 8px 0 0;
  padding-left: 1.1rem;
  display: grid;
  gap: 6px;
  overflow-wrap: anywhere;
}

.data-tool__txaSandboxGrid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
  gap: 12px;
  margin-top: 8px;
}

.data-tool__txaWorkspaceStack {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 8px;
  min-height: 0;
  flex: 1 1 auto;
}

.data-tool__txaWorkspacePrimary {
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  flex: 1 1 auto;
}

.data-tool__txaMiniGraph--workspace {
  min-height: 140px;
  max-height: 260px;
  overflow: auto;
}

.data-tool__txaTableWrap {
  flex: 1 1 auto;
  min-height: 220px;
  overflow: auto;
}

.data-tool__txaBranchPathStack {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.data-tool__txaBranchPathRow {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  gap: 8px;
  align-items: center;
}

.data-tool__txaBranchPathDepth {
  font-size: 11px;
  color: var(--ink2);
  text-align: center;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 2px 0;
  background: var(--paper);
}

.data-tool__txaInspectorPathSeg {
  text-align: left;
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  padding: 6px 8px;
  cursor: pointer;
  font: inherit;
}

.data-tool__txaInspectorPathSeg.is-selected {
  border-color: var(--moss);
  box-shadow: 0 0 0 1px rgba(47, 156, 106, 0.35);
}

@media (max-width: 900px) {
  .data-tool__txaSandboxGrid {
    grid-template-columns: 1fr;
  }
}

.data-tool__txaGraphPane {
  min-height: 140px;
}

.data-tool__txaMiniGraph {
  border: 1px solid var(--line, rgba(255, 255, 255, 0.14));
  border-radius: 8px;
  padding: 10px;
  min-height: 120px;
  background: rgba(12, 18, 22, 0.35);
}

.data-tool__txaPathChip {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  margin: 4px 0;
}

.data-tool__txaPathSeg {
  font-family: ui-monospace, monospace;
  font-size: 12px;
  padding: 4px 8px;
  border-radius: 6px;
  border: 1px solid var(--line, rgba(255, 255, 255, 0.18));
  background: rgba(255, 255, 255, 0.06);
  cursor: pointer;
}

.data-tool__txaPathSeg.is-selected {
  outline: 2px solid var(--accent2);
  background: rgba(90, 176, 255, 0.15);
}

.data-tool__txaMiniChildren {
  margin-top: 10px;
  font-size: 13px;
}

.data-tool__txaBranchAside {
  position: sticky;
  top: 8px;
  max-height: calc(100vh - 120px);
  overflow: auto;
}

.data-tool__txaBranchSection {
  margin-top: 12px;
}

.data-tool__txaBranchHeading {
  margin: 0 0 6px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink2, #647076);
}

.data-tool__txaBranchList .data-tool__txaBranchItem {
  display: block;
  width: 100%;
  text-align: left;
  margin: 4px 0;
  padding: 6px 8px;
  border-radius: 6px;
  border: 1px solid var(--line, rgba(255, 255, 255, 0.12));
  background: rgba(255, 255, 255, 0.04);
  cursor: pointer;
  font-family: ui-monospace, monospace;
  font-size: 12px;
}

.data-tool__txaBranchItem.is-selected {
  outline: 2px solid var(--accent2);
}

.data-tool__txaBranchNext code {
  font-size: 13px;
}

.data-tool__samrasBurstColumns {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 6px;
}

.data-tool__samrasBurstCol {
  flex: 1 1 140px;
  min-width: 120px;
  border: 1px solid var(--line, #cfcfcf);
  border-radius: 8px;
  padding: 8px;
  background: rgba(255, 255, 255, 0.35);
}

.data-tool__samrasBurstColTitle {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink2, #647076);
  margin-bottom: 6px;
}

.data-tool__samrasBurstRow {
  display: block;
  width: 100%;
  text-align: left;
  margin: 4px 0;
  padding: 4px 6px;
  border-radius: 6px;
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  font-family: ui-monospace, monospace;
  font-size: 11px;
}

.data-tool__samrasBurstStaged {
  flex: 1 1 100%;
  margin-top: 6px;
  padding-top: 8px;
  border-top: 1px dashed var(--line, #cfcfcf);
}

/* Historical compatibility styles for the former System -> Local Resources workbench. */
.lr-workbench__layout {
  display: grid;
  grid-template-columns: minmax(220px, 280px) minmax(0, 1fr) minmax(240px, 320px);
  gap: 14px;
  align-items: start;
}

@media (max-width: 1180px) {
  .lr-workbench__layout {
    grid-template-columns: 1fr;
  }
}

.lr-workbench__col--inventory .card__body,
.lr-workbench__col--sidebar .lr-workbench__sidebarBody {
  padding-top: 4px;
}

.lr-workbench__searchLabel {
  display: block;
  font-size: 12px;
  margin: 8px 0 4px;
  color: var(--ink2, #647076);
}

.lr-workbench__search {
  width: 100%;
  padding: 6px 8px;
  border-radius: 6px;
  border: 1px solid var(--line, #cfcfcf);
}

.lr-workbench__inventoryList {
  max-height: min(62vh, 640px);
  overflow: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}

.lr-workbench__inventoryItem {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  width: 100%;
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid var(--line, #cfcfcf);
  background: rgba(255, 255, 255, 0.35);
  cursor: pointer;
  font: inherit;
  color: inherit;
}

.lr-workbench__inventoryItem.is-selected {
  outline: 2px solid var(--accent, #1e6c93);
  background: rgba(30, 108, 147, 0.08);
}

.lr-workbench__inventoryId {
  font-weight: 600;
  font-family: ui-monospace, monospace;
  font-size: 12px;
}

.lr-workbench__inventoryMeta {
  font-size: 11px;
  color: var(--ink2, #647076);
}

.lr-workbench__titleRow {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.lr-workbench__stagedBadge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  background: rgba(255, 193, 7, 0.28);
  color: var(--accent);
}

.lr-workbench__status {
  min-height: 1.2em;
  font-size: 13px;
  margin: 0 0 8px;
}

.lr-workbench__status.is-error {
  color: var(--danger);
  font-weight: 600;
}

.lr-workbench__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 8px;
}

.lr-workbench__tab {
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--line, #cfcfcf);
  background: rgba(255, 255, 255, 0.4);
  cursor: pointer;
  font-size: 12px;
}

.lr-workbench__tab.is-active {
  border-color: var(--accent, #1e6c93);
  background: rgba(30, 108, 147, 0.12);
  font-weight: 600;
}

.lr-workbench__tab:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.lr-workbench__panel {
  margin-bottom: 10px;
}

.lr-workbench__editorLabel {
  display: block;
  font-size: 12px;
  margin-bottom: 6px;
  color: var(--ink2, #647076);
}

.lr-workbench__editor {
  width: 100%;
  min-height: 200px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  line-height: 1.35;
}

.lr-workbench__actions {
  margin-top: 8px;
}

.lr-workbench__understanding {
  font-size: 13px;
  margin-bottom: 10px;
}

.lr-workbench__warn {
  color: var(--accent);
}

.lr-workbench__err {
  color: var(--danger);
}

.lr-workbench__subhead {
  margin: 12px 0 6px;
  font-size: 13px;
}

.lr-workbench__layer {
  margin-bottom: 8px;
}

.lr-workbench__table tr.is-selected {
  background: rgba(90, 176, 255, 0.12);
}

.lr-workbench__miniBtn {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 6px;
  border: 1px solid var(--line, #cfcfcf);
  cursor: pointer;
  background: rgba(255, 255, 255, 0.5);
}

.lr-workbench__sidebarSection {
  margin-bottom: 12px;
}

.lr-workbench__sidebarSection h4 {
  margin: 0 0 6px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink2, #647076);
}

.lr-workbench__path {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.lr-workbench__pathSeg {
  font-size: 11px;
  padding: 4px 8px;
  border-radius: 6px;
  border: 1px solid var(--line, #cfcfcf);
  cursor: pointer;
  background: rgba(255, 255, 255, 0.45);
  font-family: ui-monospace, monospace;
}

.lr-workbench__sidebarBtn {
  display: block;
  width: 100%;
  text-align: left;
  margin: 4px 0;
  padding: 6px 8px;
  border-radius: 6px;
  border: 1px solid var(--line, #cfcfcf);
  cursor: pointer;
  background: rgba(255, 255, 255, 0.35);
  font-family: ui-monospace, monospace;
  font-size: 11px;
}

.lr-workbench__advanced {
  margin-top: 16px;
}

.lr-workbench__advancedGrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 12px;
  padding: 8px 0 0;
}

.lr-workbench__advancedCard .card__body {
  padding-top: 8px;
}

.lr-workbench__miniPre {
  max-height: 220px;
  overflow: auto;
  margin-top: 8px;
}

.lr-workbench__workspaceHero {
  border: 1px solid var(--line, #cfcfcf);
  border-radius: 8px;
  padding: 10px;
  background: rgba(255, 255, 255, 0.55);
  margin-bottom: 10px;
}

.lr-workbench__workspaceHero h3 {
  margin: 0 0 6px;
  font-size: 14px;
}

.lr-workbench__workspaceMeta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  font-size: 12px;
  color: var(--ink2, #647076);
}

.lr-workbench__workspaceChip {
  display: inline-flex;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--line, #cfcfcf);
  background: var(--paper);
  font-size: 11px;
}

.lr-workbench__canonicalPath {
  margin: 0 0 4px;
  font-size: 12px;
  color: var(--ink2, #647076);
}

.lr-workbench__kindRow {
  margin: 0 0 6px;
}

.lr-workbench__kindChip {
  display: inline-flex;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px dashed var(--line, #cfcfcf);
  font-size: 11px;
  color: var(--ink2, #647076);
}

.lr-workbench__fileCard {
  border: 1px solid var(--line, #cfcfcf);
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 12px;
  background: rgba(255, 255, 255, 0.55);
}

.lr-workbench__fileCardTitle {
  margin: 0 0 6px;
  font-size: 14px;
}

.lr-workbench__filePath {
  margin: 0 0 8px;
  font-size: 13px;
}

.lr-workbench__fileChips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.lr-workbench__fileSummary {
  margin: 8px 0;
  font-size: 13px;
  color: var(--ink2, #647076);
}

.lr-workbench__samrasMiniGraph {
  margin-top: 10px;
}

.data-tool__advanced--inline {
  display: inline-block;
  margin: 0;
  vertical-align: middle;
}

.data-tool__advanced--inline > summary {
  display: inline-block;
  list-style: none;
  cursor: pointer;
  font-size: 12px;
  padding: 4px 8px;
  border: 1px solid var(--line, #cfcfcf);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.6);
}

.data-tool__advanced--inline > summary::-webkit-details-marker {
  display: none;
}

.data-tool__advanced--inline[open] > summary {
  margin-bottom: 6px;
}

.data-tool__ghostBtn {
  font: inherit;
  font-size: 12px;
  padding: 4px 10px;
  border-radius: 6px;
  border: 1px solid var(--line, #cfcfcf);
  background: rgba(255, 255, 255, 0.65);
  cursor: pointer;
}

.data-tool__samrasQuickRow {
  margin-top: 6px;
}

.inh-workbench__item.is-selected {
  border-color: var(--moss);
  box-shadow: 0 0 0 1px rgba(47, 156, 106, 0.25);
}

.data-tool__controlRow--wrap {
  flex-wrap: wrap;
}

.data-tool__growLabel {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1 1 200px;
}

.data-tool__table--compact td,
.data-tool__table--compact th {
  padding: 6px 8px;
  font-size: 13px;
}

.data-tool__badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
}

.data-tool__badge--staged {
  background: rgba(255, 193, 7, 0.25);
  color: var(--accent);
}

.data-tool__badge--saved {
  background: rgba(76, 175, 80, 0.2);
  color: var(--moss);
}

.data-tool__txaBreadcrumb {
  margin: 0;
  padding-left: 1.25rem;
  font-size: 13px;
}

@media (max-width: 960px) {
  /* The .ide-body grid is already two columns at every width; the override that
     used to live here turned the control panel into a fixed drawer OVER the
     workbench. There is no panel to promote now. */
  .workbench-panels--double{
    grid-template-columns: 1fr;
  }
}

.network-modeTab.is-active {
  border-color: var(--accent);
  color: var(--accent);
  background: rgba(30, 108, 147, 0.12);
}

.fnd-ebi-card .card__body {
  font-size: 0.9rem;
}
body.portal-tool-layer-active .data-tool__workspacePanel[data-workspace-panel="system"] {
  display: none !important;
}
body.portal-tool-layer-active .ide-workbench {
  display: none !important;
}

.system-tool-contextCard.is-active {
  border-color: color-mix(in srgb, var(--accent, #0b6b46) 55%, var(--line, #c8cec8) 45%);
  background: color-mix(in srgb, var(--paper2, #eef1e8) 78%, var(--paper) 22%);
}

/* When both tab panels exist as grid children, the inactive one carries the
   [hidden] attribute and must collapse so the active tab takes the full
   width. Defense-in-depth in case a stylesheet has been loaded that
   overrides the user-agent [hidden] = display:none rule. (A past trim
   mangled this comment into an unterminated one that swallowed every rule
   down to the file's next comment terminator — repaired 2026-08-21.) */
.cts-gis-interface__body > [hidden] {
  display: none !important;
}

.cts-gis-stageColumn.is-active .cts-gis-stageColumn__frame {
  background:
    linear-gradient(
      180deg,
      color-mix(in srgb, var(--paper2, #eef1e8) 68%, var(--paper) 32%) 0%,
      color-mix(in srgb, var(--accent, #0b6b46) 10%, var(--paper2, #eef1e8) 90%) 100%
    );
  border-color: color-mix(in srgb, var(--accent, #0b6b46) 34%, var(--line, #c8cec8) 66%);
}

.cts-gis-stageRow.is-active {
  background: color-mix(in srgb, var(--accent, #0b6b46) 12%, var(--paper2, #eef1e8) 88%);
}

.cts-gis-stageRow.is-active .cts-gis-stageRow__nodeId,
.cts-gis-stageRow.is-active .cts-gis-stageRow__title {
  color: color-mix(in srgb, var(--accent, #0b6b46) 74%, var(--ink, #243026) 26%);
}

.cts-gis-lineageRow.is-active {
  background: color-mix(in srgb, var(--paper2, #eef1e8) 78%, var(--paper) 22%);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent, #0b6b46) 44%, transparent);
}

.cts-gis-orderedPathNode.is-active {
  border-color: color-mix(in srgb, var(--accent, #0b6b46) 56%, var(--line, #c8cec8) 44%);
  background: color-mix(in srgb, var(--paper2, #eef1e8) 72%, var(--paper) 28%);
}

.cts-gis-orderedNode.is-active {
  border-color: color-mix(in srgb, var(--accent, #0b6b46) 58%, var(--line, #c8cec8) 42%);
  background: color-mix(in srgb, var(--paper2, #eef1e8) 74%, var(--paper) 26%);
  opacity: 1;
}

.cts-gis-canvasColumn.is-active {
  border-color: color-mix(in srgb, var(--accent, #0b6b46) 58%, var(--line, #c8cec8) 42%);
  background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--paper2, #eef1e8) 92%, var(--paper) 8%) 0%,
      color-mix(in srgb, var(--paper2, #eef1e8) 70%, var(--paper) 30%) 100%
    );
}

.cts-gis-entryButton.is-active {
  border-color: color-mix(in srgb, var(--accent, #0b6b46) 55%, var(--line, #c8cec8) 45%);
  background: color-mix(in srgb, var(--paper2, #eef1e8) 78%, var(--paper) 22%);
}

.v2-component-frames,
.v2-component-group,
.v2-component-group__children {
  min-width: 0;
  min-height: 0;
}

/* === GARLAND WIREFRAME LAYOUT CONVENTION ===============================
   The wireframe grid is the single source of truth for cell dimensions.
   Every descendant must obey three rules:

     1. NO descendant may set min-height or min-width in pixels / rem /
        vh / vw. Visual hierarchy comes from grid track ratios (fr units),
        not from per-component pixel floors.
     2. Height propagates downward via `height: 100%` from the pane
        through .v2-component-frames → .v2-component-group → grid container.
     3. Components are responsible for their own internal overflow
        (overflow:auto on .v2-component-frame). A component that has too
        much content scrolls inside its cell — it never pushes its parent
        bigger than the cell.

   To add a new component to the Garland tab, declare its grid-column
   and grid-row in the [data-layout-slot="..."] block. Do NOT add
   min-height or min-width to the component's own CSS.
   ====================================================================== */
.cts-gis-pane--garland > .v2-component-frames,
.cts-gis-pane--garland .v2-component-group--garland_wireframe {
  display: block;
  height: 100%;
  min-height: 0;
}

.v2-component-group--garland_wireframe,
.v2-component-group--garland_wireframe * {
  min-width: 0;
  min-height: 0;
}

.v2-component-group--garland_wireframe .v2-component-frame {
  height: 100%;
  /* Frame already declares `overflow: auto` globally — content inside a
     too-small cell scrolls within the frame instead of overflowing it. */
}

/* Inside a profile's subject_slot the geospatial component is a thumbnail
   map only. The full canvas (status badges, projection focus caption,
   collection-bounds meta, feature list, warnings) belongs in a context
   with dedicated room for it (the Diktataograph tab), not in the
   already-cramped Garland wireframe cell. Hiding these descendants
   lets the `1fr` map row claim its parent's full height instead of
   getting squeezed to zero by the surrounding auto rows. */
.v2-component-group--garland_wireframe .v2-component-frame__subjectSlot .cts-gis-mapCanvas__state,
.v2-component-group--garland_wireframe .v2-component-frame__subjectSlot .cts-gis-mapCanvas__meta,
.v2-component-group--garland_wireframe .v2-component-frame__subjectSlot .cts-gis-mapCanvas__featureList,
.v2-component-group--garland_wireframe .v2-component-frame__subjectSlot .cts-gis-mapStage__controls,
.v2-component-group--garland_wireframe .v2-component-frame__subjectSlot .cts-gis-mapStage__caption,
.v2-component-group--garland_wireframe .v2-component-frame__subjectSlot .cts-gis-warningList {
  display: none;
}

.v2-component-group--garland_wireframe .v2-component-frame__subjectSlot .cts-gis-mapStage {
  grid-template-rows: minmax(0, 1fr);
}

.v2-component-group--garland_wireframe .v2-component-frame__subjectSlot .cts-gis-mapCanvas {
  grid-template-rows: minmax(0, 1fr);
  padding: 0;
  border: 0;
  background: transparent;
}

.v2-component-group--garland_wireframe .v2-component-group__children {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 0.95fr);
  grid-template-rows: minmax(0, 1.05fr) minmax(0, 0.8fr) minmax(0, 0.75fr);
  gap: 0.6rem;
  height: 100%;
  min-height: 0;
}

.v2-component-frame {
  display: grid;
  grid-template-rows: auto minmax(0, auto);
  gap: 0.5rem;
  min-width: 0;
  min-height: 0;
  padding: 0.62rem;
  border: 1px solid color-mix(in srgb, var(--line, #c8cec8) 86%, transparent);
  border-radius: 6px;
  background: color-mix(in srgb, var(--paper, #f7f8f3) 90%, var(--paper) 10%);
  overflow: auto;
}

.v2-component-frame__header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.45rem;
  align-items: center;
}

.v2-component-frame__title,
.v2-component-frame__minorTitle {
  margin: 0;
  color: var(--ink, #243026);
  letter-spacing: 0;
  overflow-wrap: anywhere;
}

.v2-component-frame__title {
  font-size: 0.86rem;
  line-height: 1.2;
}

.v2-component-frame__minorTitle {
  font-size: 0.72rem;
  line-height: 1.25;
  text-transform: uppercase;
}

.v2-component-frame__subtitle {
  display: block;
  grid-column: 1;
  color: var(--ink2, #667068);
  font-size: 0.72rem;
  overflow-wrap: anywhere;
}

.v2-component-frame__engageBtn {
  grid-row: 1 / span 2;
  grid-column: 2;
  min-width: 1.8rem;
  min-height: 1.8rem;
  border: 1px solid color-mix(in srgb, var(--line, #c8cec8) 84%, transparent);
  border-radius: 4px;
  background: color-mix(in srgb, var(--paper2, #eef1e8) 72%, var(--paper) 28%);
  color: var(--ink, #243026);
  cursor: pointer;
}

.v2-component-frame__fields,
.v2-component-frame__collectionItems,
.v2-component-frame__charItems {
  display: grid;
  grid-template-columns: minmax(6rem, 0.52fr) minmax(0, 1fr);
  margin: 0;
  border-top: 1px solid color-mix(in srgb, var(--line, #c8cec8) 82%, transparent);
  border-left: 1px solid color-mix(in srgb, var(--line, #c8cec8) 82%, transparent);
}

.v2-component-frame__fields dt,
.v2-component-frame__fields dd,
.v2-component-frame__collectionItems dt,
.v2-component-frame__collectionItems dd,
.v2-component-frame__charItems dt,
.v2-component-frame__charItems dd {
  margin: 0;
  min-width: 0;
  padding: 0.32rem 0.42rem;
  border-right: 1px solid color-mix(in srgb, var(--line, #c8cec8) 82%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--line, #c8cec8) 82%, transparent);
  font-size: 0.74rem;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.v2-component-frame__fields dt,
.v2-component-frame__collectionItems dt,
.v2-component-frame__charItems dt {
  font-weight: 700;
  color: var(--ink2, #667068);
}

.v2-component-frame__subjectSlot {
  min-height: 0;
}

.v2-component-frame__collection,
.v2-component-frame__fieldGroup,
.v2-component-frame__children {
  display: grid;
  gap: 0.4rem;
  min-width: 0;
}

.v2-component-frame__empty {
  margin: 0;
  color: var(--ink2, #667068);
  font-size: 0.78rem;
  line-height: 1.35;
}

.v2-component-listing__table,
.v2-component-chronology__table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  font-size: 0.75rem;
}

.v2-component-listing__table th,
.v2-component-listing__table td,
.v2-component-chronology__table th,
.v2-component-chronology__table td {
  border: 1px solid color-mix(in srgb, var(--line, #c8cec8) 82%, transparent);
  padding: 0.34rem 0.42rem;
  text-align: left;
  overflow-wrap: anywhere;
}

.v2-component-chronology__table td {
  text-align: center;
}

.v2-component-group--garland_wireframe [data-layout-slot="administrative_node_profile"] {
  grid-column: 1;
  grid-row: 1 / span 2;
}

.v2-component-group--garland_wireframe [data-layout-slot="administrative_log_entry_listing"] {
  grid-column: 2;
  grid-row: 1 / span 2;
}

.v2-component-group--garland_wireframe [data-layout-slot="precinct_profile"] {
  grid-column: 3;
  grid-row: 1;
}

.v2-component-group--garland_wireframe [data-layout-slot="log_listing_other_voters"] {
  grid-column: 4;
  grid-row: 1;
}

.v2-component-group--garland_wireframe [data-layout-slot="election_history"] {
  grid-column: 1 / span 2;
  grid-row: 3;
}

.v2-component-group--garland_wireframe [data-layout-slot="voter_profile"] {
  grid-column: 3 / span 2;
  grid-row: 2 / span 2;
}

.v2-component-group--garland_wireframe .v2-component-frame--geospatial {
  padding: 0;
  border: 0;
  background: transparent;
}

.v2-component-group--garland_wireframe .v2-component-frame--geospatial > .v2-component-frame__header {
  padding: 0 0 0.35rem;
}

.v2-component-group--garland_wireframe .cts-gis-mapStage,
.v2-component-group--garland_wireframe .cts-gis-mapStage__frame {
  min-height: 0;
  height: 100%;
}

.cts-gis-mapStage__shape.is-selected {
  fill: rgba(235, 161, 144, 0.58);
  stroke: rgba(133, 67, 55, 0.95);
  stroke-width: 2.8;
}

.cts-gis-mapZoom.is-disabled { opacity: 0.35; pointer-events: none; }

.cts-gis-overlayToggle.is-active {
  border-color: color-mix(in srgb, var(--accent, #0b6b46) 52%, var(--line, #c8cec8) 48%);
  background: color-mix(in srgb, var(--paper2, #eef1e8) 72%, var(--paper) 28%);
}

.cts-gis-collectionCard.is-active {
  border-color: color-mix(in srgb, var(--accent, #0b6b46) 52%, var(--line, #c8cec8) 48%);
  background: color-mix(in srgb, var(--paper2, #eef1e8) 72%, var(--paper) 28%);
}

.cts-gis-profileHierarchy__item.is-active{
  border-color: color-mix(in srgb, var(--accent, #0b6b46) 58%, var(--line, #c8cec8) 42%);
  background: color-mix(in srgb, var(--paper2, #eef1e8) 72%, var(--paper) 28%);
}

@container garlandPane (max-width: 50rem) {
  .v2-component-group--garland_wireframe .v2-component-group__children {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: none;
    min-height: 0;
  }

  .v2-component-group--garland_wireframe [data-layout-slot] {
    grid-column: auto;
    grid-row: auto;
  }

  .v2-component-group--garland_wireframe [data-layout-slot="administrative_node_profile"],
  .v2-component-group--garland_wireframe [data-layout-slot="voter_profile"],
  .v2-component-group--garland_wireframe [data-layout-slot="election_history"] {
    grid-column: 1 / -1;
  }
}

@container garlandPane (max-width: 32rem) {
  .v2-component-group--garland_wireframe .v2-component-group__children {
    grid-template-columns: minmax(0, 1fr);
  }
}

.aws-csm-profileCard.is-active {
  border-color: color-mix(in srgb, var(--accent, #0b6b46) 62%, var(--line, #c8cec8) 38%);
  background: color-mix(in srgb, var(--paper2, #eef1e8) 82%, white 18%);
}

.aws-csm-overviewIntro .card__body p:last-child {
  margin-bottom: 0;
}

.aws-csm-fileEntry.is-active {
  border-color: color-mix(in srgb, var(--accent, #0b6b46) 58%, var(--line, #c8cec8) 42%);
  background: color-mix(in srgb, var(--paper2, #eef1e8) 34%, transparent);
  color: var(--ink, #243026);
}

.aws-csm-fileCard .card__title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.system-tool-mode-controls__btn.is-active {
  background: color-mix(in srgb, var(--accent, #0b6b46) 20%, var(--panel, #eef2ee) 80%);
  border-color: color-mix(in srgb, var(--accent, #0b6b46) 48%, var(--line, #c8cec8) 52%);
}

.v2-networkTable__row.is-selected {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.v2-networkTable__action {
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  border-radius: 8px;
  padding: 0.35rem 0.65rem;
  cursor: pointer;
}

.v2-networkTable__action:hover {
  background: var(--paper);
}

.v2-networkDetail__json {
  margin: 0;
  padding: 0.85rem;
  border-radius: 12px;
  background: var(--coal);
  color: #e5eef6;
  overflow: auto;
  font-size: 12px;
  line-height: 1.45;
  white-space: pre-wrap;
  word-break: break-word;
}

.v2-workbenchUi__layout {
  display: grid;
  grid-template-columns: minmax(280px, 0.95fr) minmax(420px, 1.45fr);
  gap: 12px;
  margin-top: 12px;
}

/* Trifecta workbench layout: sandbox toggle bar / doc column / editor.
   Portal-Workbench-Trifecta-Layout-2026-05-18. */
.v2-workbenchUi__trifecta {
  display: grid;
  grid-template-rows: auto 1fr;
  gap: 0;
  min-height: 70vh;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  background: var(--paper);
}

.v2-workbenchUi__sandboxBar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  background: var(--ide-panel-bg, #f6f8fa);
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}

.v2-workbenchUi__sandboxLabel {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink);
  margin-right: 4px;
}

.v2-workbenchUi__sandboxToggle {
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  border-radius: 999px;
  padding: 0.32rem 0.85rem;
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
}

.v2-workbenchUi__sandboxToggle:hover {
  background: var(--paper);
}

.v2-workbenchUi__sandboxToggle.is-active {
  background: var(--coal2);
  color: #ffffff;
  border-color: var(--line);
  cursor: default;
}

.v2-workbenchUi__columns {
  display: grid;
  grid-template-columns: 260px 1fr;
  min-height: 0;
}

.v2-workbenchUi__docColumn {
  border-right: 1px solid var(--line);
  background: var(--paper);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.v2-workbenchUi__docColumnHeader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
}

.v2-workbenchUi__docColumnHeader h3 {
  margin: 0;
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink);
}

.v2-workbenchUi__addBtn {
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  border-radius: 6px;
  width: 28px;
  height: 28px;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}

.v2-workbenchUi__addBtn:hover:not(:disabled) {
  background: var(--paper);
}

.v2-workbenchUi__addBtn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.v2-workbenchUi__newDocForm {
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
  display: grid;
  gap: 8px;
}

/* The form ships with the `hidden` attribute and is opened by the + button, but an
   author `display: grid` beats the UA stylesheet's `[hidden] { display: none }` —
   so it was never actually hidden, and the column permanently carried a create form
   nobody had asked for. */
.v2-workbenchUi__newDocForm[hidden] {
  display: none;
}

.v2-workbenchUi__newDocForm input[name="document_name"] {
  width: 100%;
  padding: 0.4rem 0.55rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: inherit;
  background: var(--paper2);
  color: var(--ink);
}

.v2-workbenchUi__newDocType {
  display: grid;
  gap: 3px;
}

.v2-workbenchUi__newDocLabel {
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink2);
}

.v2-workbenchUi__newDocType select {
  width: 100%;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: inherit;
  font-size: 12px;
  background: var(--paper2);
  color: var(--ink);
}

.v2-workbenchUi__newDocHint {
  margin: 0;
  font-size: 11px;
  line-height: 1.45;
  color: var(--ink2);
  border-left: 2px solid var(--line);
  padding-left: 8px;
}

.v2-workbenchUi__newDocActions {
  display: flex;
  gap: 6px;
}

.v2-workbenchUi__newDocActions button {
  flex: 1;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  border-radius: 6px;
  padding: 0.35rem 0.65rem;
  cursor: pointer;
  font: inherit;
}

.v2-workbenchUi__primary {
  background: var(--coal2) !important;
  color: #ffffff !important;
  border-color: var(--line) !important;
}

.v2-workbenchUi__primary:hover:not(:disabled) {
  background: var(--coal2) !important;
}

.v2-workbenchUi__formStatus {
  color: var(--danger);
  font-size: 12px;
}

.v2-workbenchUi__docList {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  flex: 1;
}

.v2-workbenchUi__docItem {
  display: grid;
  gap: 2px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
}

/* The filter sets `node.hidden = true` on a non-matching row — and an AUTHOR
   `display: grid` beats the UA `[hidden] { display: none }`, so without this the
   row stays on screen. MEASURED: computed display was still `grid` with the
   attribute set. It looked like it worked only because a needle matching nothing
   in a folder hides the whole <details>, which has no author display rule; a
   needle matching SOME rows left every sibling in place. Same defect the create
   form shipped with. */
.v2-workbenchUi__docItem[hidden] {
  display: none;
}

.v2-workbenchUi__docItem:hover {
  background: var(--paper);
}

.v2-workbenchUi__docItem.is-selected {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border-left: 3px solid var(--line);
  padding-left: 9px;
}

/* Was `.v2-workbenchUi__docItem: focus` — the space made it an invalid selector, so
   keyboard focus in the document list had drawn no ring at all. The list is
   arrow-key navigable, which is only usable if focus is visible. */
.v2-workbenchUi__docItem:focus {
  outline: 2px solid color-mix(in srgb, var(--accent) 50%, transparent);
  outline-offset: -2px;
}

.v2-workbenchUi__docName {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  word-break: break-word;
  display: flex;
  align-items: baseline;
  gap: 6px;
}

/* The anchor marker. An outline chip rather than a filled one: it qualifies the
   name it sits beside, and a filled badge would compete with it. */
.v2-workbenchUi__docTag {
  flex: none;
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink2);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 0 4px;
}

.v2-workbenchUi__docMeta {
  font-size: 11px;
  color: var(--ink2);
}

/* --- F2 rename, in the row ----------------------------------------------------
   The input inherits the row's own type scale so the name does not change size the
   moment it becomes editable — a jump there reads as the row having been replaced
   rather than opened. */
.v2-workbenchUi__docNameInput {
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  background: var(--paper2);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: 1px 5px;
  width: 100%;
  min-width: 8ch;
}

/* A rename apply re-encodes the catalog snapshot and takes seconds. Fading the row
   says "this one, not the list" without moving anything. */
.v2-workbenchUi__docItem.is-busy {
  opacity: 0.55;
  cursor: progress;
}

/* Carries the declared_by warning and its two buttons. Sits under the row inside
   the same grid cell flow, so the list does not reflow around a popover. */
.v2-workbenchUi__rowNote {
  margin-top: 6px;
  font-size: 11px;
  line-height: 1.45;
  color: var(--ink2);
  border-left: 2px solid var(--line);
  padding-left: 8px;
  cursor: default;
  white-space: normal;
}

.v2-workbenchUi__rowNote.is-warn {
  border-left-color: var(--accent);
  color: var(--ink);
}

.v2-workbenchUi__rowNote.is-danger {
  border-left-color: var(--danger);
  color: var(--danger);
}

.v2-workbenchUi__rowNote .v2-displayer__renameActions {
  margin-top: 6px;
}

/* The delete confirm. A dialog rather than a row note, because the row can be
   anywhere in a 510-row scroll container and because the operator has to READ three
   measured facts before deciding. Hairline and paper, like everything else here — the
   weight comes from the words, not from the chrome. */
.v2-workbenchUi__confirmScrim {
  position: fixed;
  inset: 0;
  /* Above the context menu it can be opened from (210) and above the tool overlays,
     matching the scrim language `.v2-modal` already established. */
  z-index: 1300;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(20, 28, 36, 0.55);
  backdrop-filter: blur(2px);
}

.v2-workbenchUi__confirm {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px 20px 16px;
  width: min(480px, 100%);
  max-height: 100%;
  overflow-y: auto;
  font-size: 13px;
  color: var(--ink);
}

.v2-workbenchUi__confirmTitle {
  margin: 0 0 10px;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.v2-workbenchUi__confirmFacts {
  margin: 0 0 10px;
  color: var(--ink2);
  font-size: 12px;
}

.v2-workbenchUi__confirmWarn {
  margin: 0 0 8px;
  line-height: 1.5;
  border-left: 2px solid var(--danger);
  padding-left: 10px;
}

.v2-workbenchUi__confirmStatus {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--ink2);
}

.v2-workbenchUi__confirmStatus.is-danger {
  color: var(--danger);
}

.v2-workbenchUi__confirmActions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 16px;
}

.v2-workbenchUi__confirmActions button {
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  border-radius: 6px;
  padding: 0.4rem 0.9rem;
  cursor: pointer;
  font: inherit;
}

.v2-workbenchUi__confirmActions button:disabled {
  opacity: 0.5;
  cursor: progress;
}

/* The destructive button is marked but not made the loudest thing on screen: it is
   the one the operator must reach for deliberately, never the one they land on. */
.v2-workbenchUi__danger {
  border-color: var(--danger) !important;
  color: var(--danger) !important;
}

.v2-workbenchUi__danger:hover:not(:disabled) {
  background: color-mix(in srgb, var(--danger) 12%, transparent) !important;
}

.v2-workbenchUi__empty {
  padding: 16px;
  color: var(--ink2);
  font-size: 13px;
}

/* --- document column: filter + per-sandbox grouping ---------------------------
   The workbench shows the whole tenant corpus (510 documents, 7 sandboxes, six of
   them holding a document named "anchor"), so the column needs a way in that is
   not scrolling. Filter narrows; the sandbox groups give the name the qualifier it
   was missing. Hairlines and existing tokens throughout — no new hue. */
.v2-workbenchUi__docFilter {
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
}

.v2-workbenchUi__docFilter input {
  width: 100%;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: inherit;
  font-size: 12px;
  background: var(--paper2);
  color: var(--ink);
}

.v2-workbenchUi__docFilter input:focus {
  outline: 2px solid color-mix(in srgb, var(--accent) 45%, transparent);
  outline-offset: -2px;
}

.v2-workbenchUi__docScope {
  margin: 0;
  padding: 6px 12px;
  font-size: 11px;
  color: var(--ink2);
  border-bottom: 1px solid var(--line);
}

.v2-workbenchUi__docGroups {
  overflow-y: auto;
  flex: 1;
}

/* The scroll lives on the groups container. Each group's own list must not become
   a second scroll area, or a long sandbox would trap the wheel inside itself. */
.v2-workbenchUi__docGroups .v2-workbenchUi__docList {
  overflow: visible;
  flex: none;
}

.v2-workbenchUi__docGroupHead {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  background: var(--paper2);
  border-bottom: 1px solid var(--line);
  cursor: pointer;
  list-style: none;
  user-select: none;
}

.v2-workbenchUi__docGroupHead::-webkit-details-marker {
  display: none;
}

/* The heading is a focus stop in the arrow walk — the same ring the rows draw, or
   the tree loses its position the moment the walk steps out of a folder. */
.v2-workbenchUi__docGroupHead:focus {
  outline: 2px solid color-mix(in srgb, var(--accent) 50%, transparent);
  outline-offset: -2px;
}

/* The disclosure triangle, drawn rather than inherited so it rotates with the
   group's state and stays on the palette. */
.v2-workbenchUi__docGroupHead::before {
  content: "";
  flex: none;
  width: 0;
  height: 0;
  border-left: 4px solid var(--ink2);
  border-top: 3.5px solid transparent;
  border-bottom: 3.5px solid transparent;
  transition: transform 120ms ease;
}

.v2-workbenchUi__docGroup[open] > .v2-workbenchUi__docGroupHead::before {
  transform: rotate(90deg);
}

.v2-workbenchUi__docGroupHead:hover {
  background: color-mix(in srgb, var(--accent) 10%, var(--paper2));
}

.v2-workbenchUi__docGroupName {
  flex: 1;
  min-width: 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.v2-workbenchUi__docGroupCount {
  flex: none;
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  color: var(--ink2);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0 6px;
}

.v2-workbenchUi__docFilterEmpty {
  margin: 0;
  padding: 14px 12px;
  font-size: 12px;
  color: var(--ink2);
}

/* --- "Resources used": the sandbox's declared sources ------------------------ */
.v2-workbenchUi__sources {
  flex: none;
  border-bottom: 1px solid var(--line);
  background: var(--paper2);
  /* Viewport-relative, NOT a percentage of the parent. The document column grows
     to its content rather than being height-bounded (measured: a 3,326px aside in
     a 1,100px viewport), so a `%` max-height resolves against no definite height
     and does nothing — trapp's 473 declared sources then added 1,143px to a
     column that was already taller than the screen. Capped here, the list scrolls
     inside itself and the panel stays a panel. */
  max-height: min(40vh, 420px);
  overflow-y: auto;
}

.v2-workbenchUi__sourcesHead {
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 12px;
  background: var(--paper2);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  cursor: pointer;
  list-style: none;
  user-select: none;
}

.v2-workbenchUi__sourcesHead::-webkit-details-marker {
  display: none;
}

.v2-workbenchUi__sourcesCount {
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink2);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0 6px;
}

.v2-workbenchUi__sourceStats {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0 12px 8px;
}

/* The resolver's four verdicts, kept distinct. `stale` and `missing` are the only
   faults; `unverifiable` means "nothing to check it against", which must not read
   as an error. --danger/--moss are the portal's operational tokens — the ochre and
   violet accents stay reserved for place and network. */
.v2-workbenchUi__sourceStat {
  font-size: 10px;
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 0 5px;
  color: var(--ink2);
}
.v2-workbenchUi__sourceStat.is-fresh {
  color: var(--moss);
  border-color: color-mix(in srgb, var(--moss) 45%, transparent);
}
.v2-workbenchUi__sourceStat.is-stale,
.v2-workbenchUi__sourceStat.is-missing {
  color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 55%, transparent);
}

.v2-workbenchUi__sourceList {
  list-style: none;
  margin: 0;
  padding: 0;
}

.v2-workbenchUi__sourceRow {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 12px;
  font-size: 11px;
  border-top: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
}

.v2-workbenchUi__sourceRow.is-stale,
.v2-workbenchUi__sourceRow.is-missing {
  background: color-mix(in srgb, var(--danger) 10%, transparent);
}

.v2-workbenchUi__sourceName {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ink);
}

.v2-workbenchUi__sourceMeta {
  flex: none;
  color: var(--ink2);
  font-size: 10px;
}

.v2-workbenchUi__sourceMore,
.v2-workbenchUi__sourcesEmpty {
  margin: 0;
  padding: 6px 12px;
  font-size: 10.5px;
  line-height: 1.5;
  color: var(--ink2);
}

/* --- publication verdict on the displayer's provenance line ------------------ */
.v2-displayer__pub {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.v2-displayer__pubDot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  border: 1px solid currentColor;
}

.v2-displayer__pub.is-published_current {
  color: var(--moss);
}
.v2-displayer__pub.is-published_current .v2-displayer__pubDot {
  background: currentColor;
}
.v2-displayer__pub.is-published_stale {
  color: var(--danger);
}
.v2-displayer__pub.is-published_stale .v2-displayer__pubDot {
  background: currentColor;
}
/* Held-but-unlisted is CORRECTLY private and unpublished is the ordinary state —
   neither is a problem, so neither gets a colour. A hollow dot says "known, and
   not a fault"; the absence of the whole element says "not computed". */
.v2-displayer__pub.is-held_private,
.v2-displayer__pub.is-unpublished {
  color: var(--ink2);
}

.v2-workbenchUi__editor {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--paper);
}

.v2-workbenchUi__editorHeader {
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}

.v2-workbenchUi__editorHeader h3 {
  margin: 0 0 2px;
  font-size: 16px;
  color: var(--ink);
}

.v2-workbenchUi__editorHeader small {
  color: var(--ink2);
  font-size: 12px;
}

.v2-workbenchUi__editorTable {
  width: 100%;
  border-collapse: collapse;
}

.v2-workbenchUi__editorTable th,
.v2-workbenchUi__editorTable td {
  padding: 8px 12px;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 45%, transparent);
  vertical-align: top;
}

.v2-workbenchUi__editorAddr {
  width: 110px;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 12px;
  color: var(--ink);
  white-space: nowrap;
}

/* A datum value is arbitrary content — a bit string, a hash, a hostname — and none
   of it may be allowed to size the table. Without this the longest single token in
   any row becomes the column's min-content width, and a table cannot shrink below
   min-content: one 52k-character binary payload stretched this table to 366,176px
   inside an 887px pane. Scoped to the value cell ON PURPOSE — `anywhere` affects
   intrinsic sizing, so applying it table-wide would let this column buy its width
   by crushing the address and action columns to one character each. */
.v2-workbenchUi__editorValue {
  min-width: 0;
  overflow-wrap: anywhere;
}

.v2-workbenchUi__editorValue input[type="text"],
.v2-workbenchUi__editorValue textarea {
  width: 100%;
  min-width: 0;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--line);
  border-radius: 5px;
  font: inherit;
  color: var(--ink);
  background: var(--coal);
}

.v2-workbenchUi__editorValue input[type="text"]:focus,
.v2-workbenchUi__editorValue textarea:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
  background: var(--coal);
}

.v2-workbenchUi__editorValue input[readonly],
.v2-workbenchUi__editorValue textarea[readonly] {
  background: var(--paper2);
  color: var(--ink2);
}

.v2-workbenchUi__editorSummary {
  margin-top: 4px;
  font-size: 11px;
  color: var(--ink2);
}

.v2-workbenchUi__editorRow.is-selected {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.v2-workbenchUi__editorFooter {
  padding: 10px 16px;
  border-top: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--paper);
}

.v2-workbenchUi__editorFooter button {
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  border-radius: 6px;
  padding: 0.4rem 0.85rem;
  cursor: pointer;
  font: inherit;
}

.v2-workbenchUi__editorFooter button:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.v2-workbenchUi__editorStatus {
  color: var(--ink2);
  font-size: 12px;
}

/* Datum IDE grid (L3) — Excel-esque cell matrix, themed per layer / value-group */
.v2-ide {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 12px 16px;
}
.v2-ide__layer {
  --ide-layer: #2e74b5;
  border-left: 3px solid var(--ide-layer);
  border-radius: 6px;
  background: var(--paper);
}
.v2-ide__layer[data-layer-id="0"] { --ide-layer: #5b6b7a; }
.v2-ide__layer[data-layer-id="1"] { --ide-layer: #2e74b5; }
.v2-ide__layer[data-layer-id="2"] { --ide-layer: #2f9e7d; }
.v2-ide__layer[data-layer-id="3"] { --ide-layer: #b5772e; }
.v2-ide__layer[data-layer-id="4"] { --ide-layer: #8a4fbf; }
.v2-ide__layer[data-layer-id="5"] { --ide-layer: #b53e63; }
.v2-ide__layer[data-layer-id="6"] { --ide-layer: #3e8fb5; }
.v2-ide__layer[data-layer-id="7"] { --ide-layer: #6b8a2e; }
.v2-ide__layerHeader {
  padding: 6px 12px;
  border-bottom: 2px solid var(--ide-layer);
}
.v2-ide__layerHeader h4 {
  margin: 0;
  font-size: 13px;
  color: var(--ide-layer);
}
/* darker rule divides each value-group section within a layer */
.v2-ide__valueGroup {
  border-top: 2px solid var(--line);
  padding: 8px 12px 12px;
}
.v2-ide__valueGroup:first-of-type {
  border-top: 0;
}
.v2-ide__vgHeader {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 6px;
}
.v2-ide__vgHeader h5 {
  margin: 0;
  font-size: 12px;
  color: var(--ink);
}
.v2-ide__vgHeader small {
  color: var(--ink2);
  font-size: 11px;
}
.v2-ide__table {
  font-size: 12px;
}
/* Color-key box (replaces the per-column label row). Each chip's swatch matches the
   role-shaded cells below, so a value group's columns are read by colour, not header text. */
.v2-ide__keybox {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-left: auto;
}
.v2-ide__keyChip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10px;
  letter-spacing: 0.03em;
  color: var(--ink2, #888);
  text-transform: uppercase;
}
.v2-ide__keySwatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  border: 1px solid var(--line, #afafaa);
}
.v2-ide__cell {
  font-variant-numeric: tabular-nums;
  max-width: 24ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Role-shaded cells: datum address = medium theme accent; reference = darker grey;
   magnitude = lighter grey. Theme tokens keep it correct across paper/forest/ocean/midnight. */
.v2-ide__cell--address,
.v2-ide__cell--record_key {
  background: color-mix(in srgb, var(--accent, #1e6c93) 20%, var(--paper, #f0eedc));
  font-weight: 600;
}
.v2-ide__cell--reference,
.v2-ide__cell--references {
  background: color-mix(in srgb, var(--coal, #2f2f2f) 16%, var(--paper, #f0eedc));
}
.v2-ide__cell--magnitude,
.v2-ide__cell--value {
  background: color-mix(in srgb, var(--coal, #2f2f2f) 7%, var(--paper, #f0eedc));
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.v2-ide__cell--relation {
  background: transparent;
  color: var(--ink2, #888);
  text-align: center;
}
/* The NAME cell. Deliberately the one unshaded, non-monospace cell in the row: every
   other column is a machine token to be matched (an address, a reference, a magnitude)
   and reads as a tinted chip, while this is the only column a person reads as language.
   Giving it a colour of its own would spend an accent on it; leaving it plain is what
   makes it legible against neighbours that are not. */
.v2-ide__cell--label {
  background: transparent;
  color: var(--ink, #1b1b1b);
  max-width: 40ch;
  font-variant-numeric: normal;
  padding-left: 8px;
}
.v2-ide__keyChip--label .v2-ide__keySwatch {
  background: transparent;
  border-style: dashed;
}
.v2-ide__keyChip--address .v2-ide__keySwatch,
.v2-ide__keyChip--record_key .v2-ide__keySwatch {
  background: color-mix(in srgb, var(--accent, #1e6c93) 20%, var(--paper, #f0eedc));
}
.v2-ide__keyChip--reference .v2-ide__keySwatch,
.v2-ide__keyChip--references .v2-ide__keySwatch {
  background: color-mix(in srgb, var(--coal, #2f2f2f) 16%, var(--paper, #f0eedc));
}
.v2-ide__keyChip--magnitude .v2-ide__keySwatch,
.v2-ide__keyChip--value .v2-ide__keySwatch {
  background: color-mix(in srgb, var(--coal, #2f2f2f) 7%, var(--paper, #f0eedc));
}
.v2-ide__keyChip--relation .v2-ide__keySwatch {
  background: transparent;
}
/* Refracted cell: a lens recognized the magnitude, so the reference+magnitude tuple reads as
   one white, human-readable cell prefixed by │ℹ│︙│ controls. Hovering indents it as one button
   (it opens the datum overlay). The │ bars are borders on the control span + its first button. */
/* `--coal` is a SURFACE token (the inset well), not an ink. Using it for text
   assumed paper=light / coal=dark, which holds in four themes and inverts in the
   fifth — and the fifth, spore, is the default: #0F0D0B text on #16130E paper,
   1.05:1. The datum's own value was the least readable thing in the datum grid. */
.v2-ide__cell--refracted {
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
}
.v2-ide__cell--refracted:hover {
  box-shadow: inset 0 0 0 2px var(--accent, #1e6c93);
}
.v2-ide__refractCtl {
  display: inline-flex;
  align-items: center;
  border-left: 1px solid var(--line, #afafaa);
  border-right: 1px solid var(--line, #afafaa);
  margin-right: 6px;
}
.v2-ide__refractBtn {
  color: var(--ink2, #888);
  font-size: 0.82em;
  padding: 0 4px;
}
.v2-ide__refractBtn:hover {
  background: transparent;
  transform: translateY(0.5px);
}
.v2-ide__refractBtn:first-child {
  border-right: 1px solid var(--line, #afafaa);
}
.v2-ide__refractValue {
  font-weight: 500;
}
/* Datum add-rows (per value group + per layer) and the document edit icon — open the datum overlay. */
.v2-ide__addRow td {
  text-align: center;
  padding: 2px;
  background: transparent;
  border-top: 1px dashed var(--line, #afafaa);
}
.v2-ide__addBtn { color: var(--ink2, #888); }
.v2-ide__addLayer { padding: 4px 12px 10px; }
.v2-ide__addLayer .v2-ide__addBtn {
  display: inline-flex;
  gap: 4px;
  font-size: 11px;
  align-items: center;
}
.v2-ide__addLayer .v2-ide__addBtn span { color: var(--ink2, #888); }
.v2-workbenchUi__editDoc {
  color: var(--accent, #1e6c93);
  margin-right: 6px;
  font-size: 1.1em;
}
/* Collapse (layer / value group) */
.v2-ide__collapseBtn { color: var(--ink2, #888); margin-right: 4px; }
.v2-ide__valueGroup.is-collapsed .v2-tableWrap { display: none; }
.v2-ide__layer.is-collapsed .v2-ide__valueGroup,
.v2-ide__layer.is-collapsed .v2-ide__addLayer { display: none; }
/* Context menu (kebab on a refracted cell) */
.v2-ctxMenu {
  position: fixed;
  z-index: 210;
  min-width: 178px;
  background: var(--paper, #fff);
  color: var(--ink, #464646);
  border: 1px solid var(--line, #afafaa);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
  padding: 4px;
}
.v2-ctxMenu__item {
  display: flex;
  align-items: center;
  width: 100%;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  padding: 6px 10px;
  border-radius: 4px;
  cursor: pointer;
}
.v2-ctxMenu__item:hover { background: color-mix(in srgb, var(--accent, #1e6c93) 14%, transparent); }
.v2-ctxMenu__item.is-danger { color: var(--danger); }
.v2-ctxMenu__arrow { margin-left: auto; opacity: 0.6; padding-left: 12px; }
.v2-ctxMenu__sep { height: 1px; background: var(--line, #afafaa); margin: 4px 2px; }
/* Selection-collapse divider — a thick dark theme line, thinner than a row, with light controls */
.v2-ide__row.is-sel-collapsed { display: none; }
.v2-ide__row.is-sel-collapsed.is-revealed { display: table-row; background: rgba(0, 0, 0, 0.05); }
.v2-ide__selDivider td {
  padding: 1px 6px;
  background: color-mix(in srgb, var(--accent, #1e6c93) 45%, var(--coal, #2f2f2f));
  /* Same inversion as the refracted cell: the divider's fill is dark in every
     theme, so its text is the INK, not the page colour. */
  color: var(--ink);
  overflow: hidden;
}
.v2-ide__selExpand { float: left; }
.v2-ide__selClear { float: right; }
.v2-ide__selCount {
  font-size: 10px;
  opacity: 0.85;
  display: block;
  text-align: center;
  line-height: 1.7;
}
.v2-ide__row.is-selected {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}
.v2-ide__blank {
  color: var(--ink2);
}
.v2-ide__rowEditor {
  margin: 10px 16px 16px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
}
.v2-ide__rowEditor > summary {
  cursor: pointer;
  padding: 8px 12px;
  font-size: 12px;
  color: var(--ink2);
}

/* Datum Composer — always-open compose bar in the editor header */
.v2-workbenchUi__composer {
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: stretch;
}
.v2-workbenchUi__composer[data-empty="true"] {
  padding: 8px 14px;
  background: var(--paper);
  color: var(--ink2);
}
.v2-workbenchUi__composerHeader {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  width: 100%;
}
.v2-workbenchUi__composerHeader strong {
  font-size: 13px;
}
.v2-workbenchUi__composerHeader label,
.v2-workbenchUi__composerFooter label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--ink);
}
.v2-workbenchUi__composerHeader input[type="text"],
.v2-workbenchUi__composerHeader select,
.v2-workbenchUi__composerFooter input[type="text"] {
  font: inherit;
  padding: 4px 8px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--paper);
}
.v2-workbenchUi__composerSection {
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 6px 10px;
  margin: 0;
  width: 100%;
  background: var(--paper);
}
.v2-workbenchUi__composerSection legend {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink);
  padding: 0 4px;
}
.v2-workbenchUi__composerSection[hidden] {
  display: none;
}
.v2-workbenchUi__composerTupleRow,
.v2-workbenchUi__composerMagRow {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  margin: 4px 0;
}
.v2-workbenchUi__composerTupleRow label,
.v2-workbenchUi__composerMagRow label {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--ink2);
}
.v2-workbenchUi__composerTupleRow input,
.v2-workbenchUi__composerMagRow input {
  font: inherit;
  padding: 3px 6px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--paper);
}
.v2-workbenchUi__composerTupleRow button,
.v2-workbenchUi__composerMagRow button,
.v2-workbenchUi__composerSection > button {
  font: inherit;
  font-size: 12px;
  padding: 3px 8px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--paper);
  cursor: pointer;
}
.v2-workbenchUi__composerSection > button {
  margin-top: 4px;
}
.v2-workbenchUi__composerFooter {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  width: 100%;
}
.v2-workbenchUi__composerFooter button {
  font: inherit;
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--paper);
  cursor: pointer;
}
.v2-workbenchUi__composerFooter button.v2-workbenchUi__primary {
  background: var(--moss);
  color: #fff;
  border-color: var(--line);
  font-weight: 600;
}
.v2-workbenchUi__composerFooter button.v2-workbenchUi__primary:disabled {
  background: var(--paper2);
  border-color: var(--line);
  cursor: not-allowed;
}
.v2-workbenchUi__composer output[data-composer-status] {
  font-size: 12px;
  padding: 3px 8px;
  border-radius: 4px;
  min-width: 80px;
}
.v2-workbenchUi__composer output[data-composer-status][data-state="error"] {
  background: var(--paper);
  color: var(--danger);
}
.v2-workbenchUi__composer output[data-composer-status][data-state="ok"] {
  background: var(--paper);
  color: var(--moss);
}

/* Per-row editor controls — Raw toggle, Save, Discard, status */
.v2-workbenchUi__editorActions {
  width: 240px;
  white-space: nowrap;
  vertical-align: top;
}
/* `color` is not optional on a themed button. A <button> that sets only its
   background keeps the UA's `buttontext` — black — so Raw/Save/Discard painted
   black-on-#16130E at 1.1:1 on the default theme: present, clickable, invisible. */
.v2-workbenchUi__editorActions button {
  font: inherit;
  font-size: 12px;
  padding: 3px 8px;
  margin-right: 4px;
  border: 1px solid var(--line);
  border-radius: 4px;
  color: var(--ink);
  background: var(--paper2);
  cursor: pointer;
}
.v2-workbenchUi__editorActions button:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}
.v2-workbenchUi__editorActions button:disabled {
  /* State by ink, not by fading a colour that was never legible to begin with. */
  color: var(--ink2);
  opacity: 0.65;
  cursor: not-allowed;
}
.v2-workbenchUi__editorActions button.v2-workbenchUi__primary {
  background: var(--accent);
  color: var(--accent-fg);
  border-color: var(--accent);
  font-weight: 600;
}
.v2-workbenchUi__editorActions button.v2-workbenchUi__primary:disabled {
  background: var(--paper2);
  border-color: var(--line);
}
.v2-workbenchUi__editorRowStatus {
  display: inline-block;
  margin-left: 4px;
  font-size: 12px;
  padding: 2px 6px;
  border-radius: 3px;
}
.v2-workbenchUi__editorRowStatus[data-state="error"] {
  background: var(--paper);
  color: var(--danger);
}
.v2-workbenchUi__editorRowStatus[data-state="ok"] {
  background: var(--paper);
  color: var(--moss);
}
.v2-workbenchUi__editorQuick input[type="text"],
.v2-workbenchUi__editorRaw textarea {
  width: 100%;
  font: inherit;
  padding: 4px 8px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--paper);
}
.v2-workbenchUi__editorRaw textarea {
  font-family: ui-monospace, SFMono-Regular, "Menlo", "Consolas", monospace;
  font-size: 12px;
  resize: vertical;
}
/* A row with no name to edit draws its quick input DISABLED (see _quickField), and it
   has to look it: drawn like the others it read as an empty field waiting for a name,
   the one thing that row cannot take (side-2026-11-03-0093). So it is not a field any
   more: a recessed fill and a dashed edge instead of a box. The reason it gives is the
   one thing in it worth reading, so it keeps the theme's own ink (italic, so it does not
   read as a value), where the UA greyed it to the same #757575 on every theme. */
.v2-workbenchUi__editorQuick input[type="text"]:disabled {
  border-style: dashed;
  background: var(--paper2);
  cursor: not-allowed;
}
.v2-workbenchUi__editorQuick input[type="text"]:disabled::placeholder {
  color: var(--ink);
  font-style: italic;
  opacity: 1;
}

.v2-workbenchUi__pane {
  min-width: 0;
}

.v2-workbenchUi__paneHeader {
  margin-bottom: 12px;
}

.v2-workbenchUi__paneHeader h3 {
  margin: 0 0 4px;
}

.v2-workbenchUi__paneHeader p,
.v2-workbenchUi__groupHeader p {
  margin: 0;
  color: var(--ink);
}

.v2-workbenchUi__tableWrap {
  max-height: 540px;
  overflow: auto;
}

.v2-workbenchUi__stickyHeader th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--ide-panel-bg, #f6f8fa);
}

.v2-workbenchUi__row {
  cursor: pointer;
}

.v2-workbenchUi__row.is-selected {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.v2-workbenchUi__row: focus {
  outline: 2px solid color-mix(in srgb, var(--accent) 44%, transparent);
  outline-offset: -2px;
}

.v2-workbenchUi__primaryCell {
  display: grid;
  gap: 4px;
}

.v2-workbenchUi__subvalue {
  font-size: 12px;
  color: var(--ink);
  word-break: break-word;
}

.v2-workbenchUi__identity {
  display: grid;
  gap: 4px;
}

.v2-workbenchUi__badge {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  padding: 0.18rem 0.5rem;
  border-radius: 999px;
  background: var(--paper2);
  border: 1px solid var(--line);
  color: var(--ink);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.v2-workbenchUi__selectedTag {
  display: inline-flex;
  width: fit-content;
  padding: 0.14rem 0.45rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
}

.v2-workbenchUi__action,
.v2-workbenchUi__navButton {
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  border-radius: 8px;
  padding: 0.35rem 0.65rem;
  cursor: pointer;
}

.v2-workbenchUi__action:hover,
.v2-workbenchUi__navButton:hover {
  background: var(--paper);
}

.v2-workbenchUi__group + .v2-workbenchUi__group {
  margin-top: 12px;
}

.v2-workbenchUi__groupHeader {
  margin-bottom: 8px;
}

.v2-workbenchUi__groupHeader h4 {
  margin: 0 0 4px;
  font-size: 13px;
}

.v2-workbenchUi__navButtons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.v2-workbenchUi__navButton {
  display: grid;
  gap: 2px;
  min-width: 160px;
  text-align: left;
}

.v2-workbenchUi__navButton small {
  color: var(--ink);
}

@media (max-width: 1100px) {
  .v2-workbenchUi__layout {
    grid-template-columns: 1fr;
  }

  .v2-workbenchUi__tableWrap {
    max-height: none;
  }
}

.agro-time__tick.is-active {
  background: color-mix(in srgb, var(--accent, #0b6b46) 40%, var(--coal2) 60%);
  opacity: 1;
}

.agro-time__month.is-active {
  background: rgba(198, 214, 188, 0.92);
  color: var(--ink);
}

.agro-time__dayCell.is-active {
  background: rgba(213, 184, 188, 0.72);
  color: var(--ink);
}

/* V2 native portal shell helpers */
.v2-workbench-body {
  padding: 1rem 1rem 1.5rem;
}
.v2-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
  margin-top: 12px;
}
/* Document card titles can carry long filenames in legacy data; keep
   the card from overflowing horizontally with a tight clamp. The
   renderer already extracts a short label, but the truncation is
   a safety net for any legacy `.fnd.` / `.cts.` filename that the
   short-label regex didn't cover. */
.v2-wb-docCard {
  min-width: 0;
  overflow: hidden;
}
.v2-wb-docCard__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.v2-wb-docCard__header {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  align-items: center;
  min-width: 0;
}
.v2-wb-docCard p small {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}
.v2-card {
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 8px;
  padding: 12px 14px;
  background: var(--ide-panel-bg, #fff);
}
.v2-card h3 {
  margin: 0 0 8px;
  font-size: 14px;
}
.v2-card p {
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
}
/* Phase 12h utilities surface — grantee selector. Sits at the top of
   /portal/utilities/tool-exposure; clicking switches the active grantee
   and repopulates the extension payloads below. Markup + JS in
   v2_portal_workbench_renderers.js (renderGranteeSelector / bindGranteeSelector). */
.v2-granteeSelector {
  margin-top: 0;
}
.v2-granteeSelector__options {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}
.v2-granteeSelector__option {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 8px 12px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 6px;
  background: var(--ide-panel-bg, #fff);
  cursor: pointer;
  font: inherit;
  text-align: left;
  transition: background 120ms, border-color 120ms, color 120ms;
}
.v2-granteeSelector__option:hover {
  background: var(--paper2);
}
.v2-granteeSelector__option.is-active {
  background: var(--ide-accent, #1f883d);
  color: #fff;
  border-color: var(--ide-accent, #1f883d);
}
.v2-granteeSelector__optionLabel {
  font-weight: 600;
}
.v2-granteeSelector__optionDomains {
  font-size: 11px;
  opacity: 0.75;
  margin-top: 2px;
}
.v2-granteeSelector__empty {
  color: var(--ink2);
  font-style: italic;
  margin: 8px 0 0;
}
/* Phase 15a — Extension subtabs rendered below the grantee selector on
   /portal/utilities/extensions. Slimmer pill chips than the grantee
   selector so the two strips read as distinct axes. Markup + JS in
   v2_portal_workbench_renderers.js (renderExtensionTabs /
   bindExtensionTabs). */
.v2-extensionTabs {
  margin-top: 12px;
}
.v2-extensionTabs__options {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}
.v2-extensionTabs__option {
  display: inline-flex;
  align-items: center;
  padding: 6px 14px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 999px;
  background: var(--ide-panel-bg, #fff);
  cursor: pointer;
  font: inherit;
  font-size: 13px;
  transition: background 120ms, border-color 120ms, color 120ms;
}
.v2-extensionTabs__option:hover {
  background: var(--paper2);
}
.v2-extensionTabs__option.is-active {
  background: var(--ide-accent, #1f883d);
  color: #fff;
  border-color: var(--ide-accent, #1f883d);
}
.v2-extensionTabs__optionLabel {
  font-weight: 600;
}

/* ---- Resources type browser: inner subtabs, manifest tree, browse ---- */
.v2-innerSubtabs {
  margin: 8px 0 4px;
}
.v2-innerSubtabs__options {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.v2-innerSubtabs__option {
  display: inline-flex;
  align-items: center;
  padding: 5px 13px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 999px;
  background: var(--ide-panel-bg, #fff);
  cursor: pointer;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  transition: background 120ms, border-color 120ms, color 120ms;
}
.v2-innerSubtabs__option:hover {
  background: var(--paper2);
}
.v2-innerSubtabs__option.is-active {
  background: var(--ide-accent, #1f883d);
  color: #fff;
  border-color: var(--ide-accent, #1f883d);
}
.v2-typeIcon {
  width: 1.15em;
  height: 1.15em;
  flex: 0 0 auto;
  object-fit: contain;
  fill: currentColor;
  color: var(--ide-accent, #1f883d);
}
.v2-typeIcon--none {
  display: inline-block;
  border-radius: 3px;
  background: var(--ide-border, #d8dee4);
  opacity: 0.5;
}
/* Manifest tree */
.v2-typeTree {
  margin-top: 8px;
  font-size: 13px;
}
/* Browse — horizontal cluster tree (dendrogram). SVG draws the links; the nodes
   are absolutely-positioned HTML so the icon/label/buttons reuse existing CSS. */
.v2-dendro__host {
  margin-top: 8px;
  overflow: auto;
  max-height: 70vh;
}
.v2-dendro__toolbar {
  display: flex;
  gap: 6px;
  margin-bottom: 6px;
}
.v2-dendro__all {
  border: 1px solid var(--ide-border, #d8dee4);
  background: var(--ide-panel-bg, #fff);
  border-radius: 6px;
  padding: 2px 10px;
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}
.v2-dendro__all:hover {
  background: var(--paper2);
}
.v2-dendro {
  position: relative;
  font-size: 13px;
}
.v2-dendro__links {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.v2-dendro__link {
  fill: none;
  stroke: var(--ide-border, #d8dee4);
  stroke-width: 1.5;
}
.v2-dendro__node {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 4px;
  transform: translateY(-50%);
  white-space: nowrap;
}
.v2-dendro__toggle {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  line-height: 1;
  padding: 0;
  border: 1px solid var(--ide-border, #d8dee4);
  background: var(--ide-panel-bg, #fff);
  border-radius: 4px;
  font-size: 10px;
  color: var(--ink2);
  cursor: pointer;
}
.v2-dendro__toggle:hover {
  background: var(--paper2);
}
.v2-dendro__toggle--leaf {
  border: none;
  background: none;
  cursor: default;
}
/* Local Domain: a node with a record_view shows a diagonal "expand view" button (⤢)
   in the toggle's place — clicking it opens the node's records as a full-tab table. */
.v2-dendro__expand {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  line-height: 1;
  padding: 0;
  border: 1px solid var(--accent, #1e6c93);
  background: var(--ide-panel-bg, #fff);
  border-radius: 4px;
  font-size: 12px;
  color: var(--accent, #1e6c93);
  cursor: pointer;
}
.v2-dendro__expand:hover {
  background: var(--accent, #1e6c93);
  color: #fff;
}
.v2-dendro__view--static.is-expandable {
  border-color: color-mix(in srgb, var(--accent, #1e6c93) 35%, transparent);
}
.v2-clusterTree__hint {
  color: var(--ink2);
  font-size: 11px;
  margin-left: 6px;
  opacity: 0.85;
}
/* "Showing 53 of 66" — a statement about the structure's coverage, never a control. */
.v2-clusterTree__gap {
  margin: 0 0 6px;
  padding: 5px 8px;
  font-size: 11px;
  line-height: 1.45;
  color: var(--ink2, #57606a);
  border-left: 2px solid color-mix(in srgb, var(--warn, #b8860b) 60%, transparent);
  background: color-mix(in srgb, var(--warn, #b8860b) 7%, transparent);
}
/* Record table back bar (e.g. the agronomics FARM full-tab takeover exit). */
.v2-recordTable__back {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 8px;
  padding: 3px 10px;
  border: 1px solid var(--ide-border, #d8dee4);
  background: var(--ide-panel-bg, #fff);
  border-radius: 6px;
  font: inherit;
  font-size: 12px;
  color: var(--accent, #1e6c93);
  cursor: pointer;
}
.v2-recordTable__back:hover {
  background: var(--paper2);
}

/* The FORWARD counterpart of the back bar: pick a row's subject and open it. Below the
   table rather than above, because it acts on what was just read — the back bar is an
   exit and this is a next step. Laid out as one line so it reads as a single control
   rather than a stray form. */
.v2-recordTable__pick {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--ide-border, #d8dee4);
  font-size: 12px;
  flex-wrap: wrap;
}
.v2-recordTable__pick label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.v2-recordTable__pick select {
  font: inherit;
  font-size: 12px;
  padding: 3px 6px;
  max-width: 22rem;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 6px;
  background: var(--ide-panel-bg, #fff);
  color: inherit;
}
.v2-recordTable__pick button {
  padding: 3px 12px;
  border: 1px solid var(--ide-border, #d8dee4);
  background: var(--ide-panel-bg, #fff);
  border-radius: 6px;
  font: inherit;
  font-size: 12px;
  color: var(--accent, #1e6c93);
  cursor: pointer;
}
.v2-recordTable__pick button:hover {
  background: var(--paper2);
}
/* What the table cannot say about itself in a cell: where the rows came from, or what
   is not being kept current. Muted and above the table, so it reads as a caption on the
   whole rather than as a row. */
.v2-recordTable__notice {
  margin: 0 0 8px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--muted, var(--ink2));
}
/* Synopsis: compact derived-figure widget (PLAN tab far-right inventory). */
.v2-synopsis {
  max-width: 320px;
  font-size: 13px;
}
.v2-synopsis__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  color: var(--ink2);
  font-size: 12px;
  margin-bottom: 6px;
}
.v2-synopsis__edit {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 1px solid var(--ide-border, #d8dee4);
  background: var(--ide-panel-bg, #fff);
  border-radius: 5px;
  font-size: 12px;
  line-height: 1;
  color: var(--accent, #1e6c93);
  cursor: pointer;
}
.v2-synopsis__edit:hover { background: var(--paper2); }
.v2-synopsis__colhead {
  display: flex;
  justify-content: space-between;
  color: var(--ink2);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border-bottom: 1px solid var(--ide-border, #d8dee4);
  padding-bottom: 2px;
}
.v2-synopsis__list {
  list-style: none;
  margin: 0;
  padding: 0;
  /* Self-contained widget: cap the height and scroll internally so a long inventory never
     stretches the PLAN row / forces the whole tab to scroll. */
  max-height: 300px;
  overflow-y: auto;
}
.v2-synopsis__row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 3px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--ide-border, #d8dee4) 50%, transparent);
}
.v2-synopsis__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.v2-synopsis__figure {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--accent, #1e6c93);
}
.v2-synopsis__empty {
  color: var(--ink2);
  font-size: 12px;
}
/* PIM Design > Your site — the client's own website, framed.
   A DEFINITE HEIGHT, deliberately, and not `aspect-ratio`: an aspect-ratio box resolves
   against a width that this pane does not control (it sits inside a tab inside a hub), and
   the frame then draws at whatever height that arithmetic lands on, which for a narrow
   panel is a letterbox nobody can read a page in. A height in px is the one thing that
   cannot be argued with by an ancestor's width. */
.v2-sitePreview { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.v2-sitePreview__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  color: var(--ink2);
  font-size: 12px;
}
.v2-sitePreview__pick { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.v2-sitePreview__open { font-size: 12px; }
.v2-sitePreview__notice { margin: 0; color: var(--ink2); font-size: 12px; }
.v2-sitePreview__frameWrap {
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 6px;
  background: var(--ide-panel-bg, #fff);
  /* The frame is the point of the pane, so it gets the room. */
  height: 620px;
  overflow: hidden;
}
.v2-sitePreview__frame { display: block; width: 100%; height: 100%; border: 0; }
.v2-sitePreview__empty { color: var(--ink2); font-size: 12px; }
/* A phone cannot afford 620px of someone else's page above the controls that change it. */
@media (max-width: 720px) {
  .v2-sitePreview__frameWrap { height: 380px; }
}
/* The notes shelf (Oveure). List beside editor; the editor column owns the height. */
.v2-notes { display: flex; gap: 10px; min-height: 260px; }
.v2-notes__list { flex: 0 0 180px; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.v2-notes__new {
  padding: 4px 10px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 6px;
  background: var(--ide-panel-bg, #fff);
  color: var(--accent, #1e6c93);
  font: inherit;
  cursor: pointer;
  text-align: left;
}
.v2-notes__new:hover { background: var(--paper2); }
.v2-notes__items { list-style: none; margin: 0; padding: 0; overflow-y: auto; max-height: 340px; }
.v2-notes__item {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  padding: 4px 8px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-align: left;
}
.v2-notes__item:hover { background: var(--paper2); }
.v2-notes__item.is-active { background: var(--paper2); color: var(--accent, #1e6c93); font-weight: 600; }
.v2-notes__lines { flex: 0 0 auto; color: var(--ink2); font-size: 11px; font-variant-numeric: tabular-nums; }
.v2-notes__empty { color: var(--ink2); font-size: 12px; padding: 4px 8px; }

/* ---- inbox (Oveure) ---------------------------------------------------- */
/* Same two-column shape as the notes shelf, and deliberately so: a list beside a
   reader is the arrangement an operator already knows from this hub, and inventing a
   second one for the tab next to it would cost them the recognition for nothing.
   Colours are theme variables only -- a literal is wrong in half the themes. */
.v2-inbox { display: flex; gap: 10px; min-height: 260px; }
.v2-inbox__list { flex: 0 0 240px; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.v2-inbox__load {
  padding: 4px 10px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 6px;
  background: var(--ide-panel-bg, #fff);
  color: var(--accent, #1e6c93);
  font: inherit;
  cursor: pointer;
  text-align: left;
}
.v2-inbox__load:hover { background: var(--paper2); }
.v2-inbox__items { list-style: none; margin: 0; padding: 0; overflow-y: auto; max-height: 340px; }
.v2-inbox__item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  padding: 5px 8px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-align: left;
  min-width: 0;
}
.v2-inbox__item:hover { background: var(--paper2); }
.v2-inbox__item.is-active { background: var(--paper2); color: var(--accent, #1e6c93); }
/* Both lines clip rather than wrap: a subject line is unbounded, and one long one
   would otherwise push every other message off the visible list. */
.v2-inbox__from,
.v2-inbox__subj { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-inbox__from { font-weight: 600; font-size: 12px; }
.v2-inbox__subj { color: var(--ink2); font-size: 11px; }
.v2-inbox__empty { color: var(--ink2); font-size: 12px; padding: 4px 8px; line-height: 1.45; }
.v2-inbox__reader { flex: 1 1 auto; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.v2-inbox__bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.v2-inbox__subject { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-inbox__grow { flex: 1 1 auto; }
.v2-inbox__provider {
  padding: 3px 6px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 5px;
  background: var(--ide-panel-bg, #fff);
  color: inherit;
  font: inherit;
}
.v2-inbox__act,
.v2-inbox__send {
  padding: 4px 12px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 6px;
  background: var(--ide-panel-bg, #fff);
  color: var(--accent, #1e6c93);
  font: inherit;
  cursor: pointer;
}
/* Only the button that puts words in front of a stranger is filled. The other three
   read, and they should not look like they do the same thing. */
.v2-inbox__send {
  border-color: var(--accent, #1e6c93);
  background: var(--accent, #1e6c93);
  color: #fff;
}
.v2-inbox__body {
  margin: 0;
  padding: 8px 10px;
  max-height: 260px;
  overflow: auto;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 6px;
  background: var(--paper2);
  font: 12px/1.5 var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  white-space: pre-wrap;
  word-break: break-word;
}
/* Pager under the list, attachments under the body. Both empty until there is
   something to say, so an unloaded pane carries no dead controls. */
.v2-inbox__pager { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.v2-inbox__pager:empty { display: none; }
.v2-inbox__page {
  padding: 2px 10px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 5px;
  background: var(--ide-panel-bg, #fff);
  color: var(--accent, #1e6c93);
  font: inherit;
  cursor: pointer;
}
.v2-inbox__range { color: var(--ink2); flex: 1 1 auto; text-align: center; }
.v2-inbox__attachments { list-style: none; margin: 0; padding: 0; font-size: 12px; }
.v2-inbox__attachments:empty { display: none; }
.v2-inbox__attachments li { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-inbox__attachment { color: var(--accent, #1e6c93); }
.v2-inbox__attmeta { color: var(--ink2); }
.v2-inbox__verdict { color: var(--accent, #1e6c93); font-size: 12px; min-height: 1em; }
.v2-inbox__draft {
  flex: 1 1 auto;
  min-height: 120px;
  padding: 8px 10px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 6px;
  background: var(--ide-panel-bg, #fff);
  color: inherit;
  font: inherit;
  resize: vertical;
}
.v2-inbox__status { color: var(--ink2); font-size: 12px; min-height: 1em; }
.v2-notes__editor { flex: 1 1 auto; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.v2-notes__bar { display: flex; align-items: center; gap: 8px; }
.v2-notes__title { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-notes__titleinput {
  flex: 1 1 auto;
  min-width: 0;
  padding: 3px 8px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 5px;
  background: var(--ide-panel-bg, #fff);
  color: inherit;
  font: inherit;
}
.v2-notes__grow { flex: 1 1 auto; }
.v2-notes__provider {
  padding: 3px 6px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 5px;
  background: var(--ide-panel-bg, #fff);
  color: inherit;
  font: inherit;
}
.v2-notes__ask,
.v2-notes__save {
  padding: 4px 12px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 6px;
  background: var(--ide-panel-bg, #fff);
  color: var(--accent, #1e6c93);
  font: inherit;
  cursor: pointer;
}
.v2-notes__save {
  border-color: var(--accent, #1e6c93);
  background: var(--accent, #1e6c93);
  color: #fff;
}
.v2-notes__ask:hover { background: var(--paper2); }
.v2-notes__text {
  flex: 1 1 auto;
  min-height: 200px;
  padding: 8px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 6px;
  background: var(--ide-panel-bg, #fff);
  color: inherit;
  font: 13px/1.5 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  resize: vertical;
}
.v2-notes__status { color: var(--ink2); font-size: 12px; min-height: 16px; }
/* Composite column direction (PLAN: top widgets over Contract Editor; NETWORK: map+table
   row over the Calendar subtool). Panes take their CONTENT height (flex-basis:auto) so the
   tab renders even when the host panel is content-sized (max-height, no definite height) —
   a basis of 0 collapses ratio panes to 0 there, which blanked PLAN/NETWORK. When a
   definite height IS present, the grow ratios (3:2) still share the extra space; each pane
   scrolls inside its own body. */
.v2-composite--column { flex-direction: column; min-height: 0; }
.v2-composite--column > .v2-composite__pane { flex: 3 1 auto; min-height: 0; overflow: hidden; }
.v2-composite--column > .v2-composite__pane:last-child { flex: 2 1 auto; }
.v2-composite--column > .v2-composite__pane > .v2-composite__paneBody { overflow: auto; min-height: 0; }
.v2-composite__pane--unlabeled { padding-top: 4px; }
/* Independent widgets: each pane keeps its own (content) height — no equal-height stretch. */
.v2-composite--widgets { align-items: flex-start; }
/* Plot Manager: date widget above the map{ display: flex; flex-direction: column; gap: 6px; }
.v2-farm__poly.is-selected { fill: rgba(30,108,147,0.55) !important; stroke: var(--accent) !important; stroke-width: 2 !important; }
.v2-pmModal__mapbox .v2-farm { height: 100%; display: flex; flex-direction: column; }
.v2-pmModal__mapbox .v2-farm__map { flex: 1 1 auto; min-height: 0; position: relative; }
.v2-pmModal__mapbox .v2-farm__svg { width: 100%; height: 100%; }
/* Cluster Editor (redefined Plot Manager) — draw a cluster region, set plot angle/size/spacing. */
.v2-geoedit { display: flex; flex-direction: column; gap: 6px; }
.v2-geoedit__toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.v2-geoedit__btn {
  display: inline-flex; align-items: center; gap: 4px; padding: 4px 12px;
  border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px;
  background: var(--ide-panel-bg, #fff); color: var(--accent, #1e6c93);
  font: inherit; font-size: 13px; cursor: pointer;
}
.v2-geoedit__btn:hover { background: var(--accent, #1e6c93); color: #fff; }
.v2-geoedit__hint { color: var(--ink2); font-size: 12px; }
/* Delegate editor. The map div is the STABLE pan/zoom host (it owns the .v2-mapZoom control); only
   __canvas is rewritten on repaint. */
.v2-geoedit__work { display: flex; gap: 8px; align-items: flex-start; min-height: 0; }
.v2-geoedit__map { position: relative; touch-action: none; outline: none; flex: 1 1 auto; min-width: 0; }
.v2-geoedit__canvas { display: block; }
.v2-geoedit__svg { width: 100%; height: auto; aspect-ratio: 460 / 320; display: block; user-select: none; }
.v2-geoedit__empty { color: var(--ink2); font-size: 12px; padding: 12px; }
/* Context polygons are inert while DRAWING (a click must place a corner, not hit a plot) but are
   the hit targets in Select mode — hence per-mode pointer-events rather than a blanket none. */
.v2-geoedit__ctx { pointer-events: none; }
.v2-geoedit.is-select .v2-geoedit__ctx[data-geo-kind="plot"],
.v2-geoedit.is-select .v2-geoedit__ctx[data-geo-kind="cluster"] { pointer-events: auto; cursor: pointer; }
.v2-geoedit__ctx.is-selected { stroke: var(--accent) !important; stroke-width: 2.5; fill: rgba(31, 111, 235, 0.35) !important; }
.v2-geoedit__ctx.is-moved { stroke-dasharray: 3 2; }
.v2-geoedit__ctx.is-editing { stroke: var(--accent) !important; stroke-width: 2.5; }
.v2-geoedit__modes { display: inline-flex; gap: 2px; }
.v2-geoedit__mode {
  padding: 3px 10px; font: inherit; font-size: 12px; cursor: pointer;
  color: var(--ink); background: var(--paper2);
  border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px;
}
.v2-geoedit__mode.is-active { color: #fff; background: var(--accent, #1e6c93); border-color: var(--accent, #1e6c93); }
.v2-geoedit__btn:disabled { opacity: 0.35; cursor: default; }
.v2-geoedit__btn:disabled:hover { background: var(--ide-panel-bg, #fff); color: var(--accent, #1e6c93); }
.v2-geoedit__sidebar {
  flex: 0 0 190px; max-height: 320px; overflow: auto; font-size: 12px;
  border: 1px solid var(--line); border-radius: 6px;
}
.v2-geoedit__sideEmpty { padding: 8px; color: var(--ink2); font-size: 11px; }
.v2-geoedit__node {
  display: flex; align-items: center; gap: 4px; padding: 2px 6px;
  border-bottom: 1px solid var(--line);
}
.v2-geoedit__node.is-field { font-weight: 600; background: rgba(214, 158, 46, 0.12); }
.v2-geoedit__node.is-cluster { font-weight: 600; background: rgba(137, 87, 229, 0.1); cursor: pointer; }
.v2-geoedit__node.is-plot { padding-left: 16px; cursor: pointer; }
.v2-geoedit__node.is-plot:hover { background: rgba(31, 111, 235, 0.08); }
.v2-geoedit__node.is-selected { background: rgba(31, 111, 235, 0.2); }
.v2-geoedit__node.is-deleted { opacity: 0.45; text-decoration: line-through; }
.v2-geoedit__node.is-moved .v2-geoedit__nodeLbl { font-style: italic; }
.v2-geoedit__nodeLbl { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-geoedit__nodeCount { font-size: 10px; opacity: 0.6; }
.v2-geoedit__del {
  padding: 0 4px; font: inherit; font-size: 11px; line-height: 1.4; cursor: pointer;
  color: var(--ink2); background: transparent; border: 0; border-radius: 4px;
}
.v2-geoedit__del:hover { color: #fff; background: var(--danger); }
.v2-geoedit__pending { font-size: 11px; color: var(--accent, #1e6c93); }
.v2-geoedit__dayLbl { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; color: var(--ink2); }
.v2-geoedit__dayLbl input {
  font: inherit; font-size: 12px; padding: 2px 4px;
  border: 1px solid var(--ide-border, #d8dee4); border-radius: 5px; background: var(--ide-panel-bg, #fff);
}
/* Why the day cannot simply be today — names the contracts that hold the geometry. */
.v2-geoedit__dayNote { font-size: 11px; color: var(--accent); }
.v2-geoedit__cell { fill: rgba(34, 139, 87, 0.28); stroke: rgba(34, 139, 87, 0.8); stroke-width: 0.6; pointer-events: none; }
.v2-geoedit__region { fill: rgba(30, 108, 147, 0.16); stroke: var(--accent, #1e6c93); stroke-width: 1.6; cursor: move; }
.v2-geoedit__vtx { fill: var(--paper); stroke: var(--accent, #1e6c93); stroke-width: 1.5; cursor: grab; }
.v2-geoedit__vtx:hover { fill: var(--accent, #1e6c93); }
.v2-geoedit__rotarm { stroke: var(--accent, #1e6c93); stroke-width: 1; stroke-dasharray: 3 2; pointer-events: none; }
.v2-geoedit__rot { fill: var(--paper); stroke: var(--accent); stroke-width: 1.8; cursor: crosshair; }
.v2-geoedit__cen { fill: var(--accent, #1e6c93); pointer-events: none; }
.v2-geoedit__inspector { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.v2-geoedit__angle { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink2); }
.v2-geoedit__angle input[type="range"] { width: 120px; }
.v2-geoedit__angleNum { width: 4.5em; }
.v2-geoedit__deg { color: var(--ink2); }
.v2-geoedit__grid { display: flex; flex-wrap: wrap; gap: 6px 10px; }
.v2-geoedit__num { display: flex; flex-direction: column; gap: 2px; font-size: 11px; color: var(--ink2); }
.v2-geoedit__num input, .v2-geoedit__angle input[type="number"] {
  font: inherit; font-size: 13px; padding: 3px 6px; width: 5.5em;
  border: 1px solid var(--ide-border, #d8dee4); border-radius: 5px; background: var(--ide-panel-bg, #fff);
}
.v2-geoedit__bar { display: flex; align-items: center; gap: 10px; }
.v2-geoedit__status { flex: 1 1 auto; font-size: 12px; color: var(--ink2); min-height: 1em; }
.v2-geoedit__save {
  padding: 4px 14px; border: 1px solid var(--accent, #1e6c93); border-radius: 6px;
  background: var(--accent, #1e6c93); color: #fff; font: inherit; font-size: 13px; cursor: pointer;
}
.v2-geoedit__save:hover { filter: brightness(1.08); }
/* Farm hub — Overview stat tiles. */
.v2-stats { display: flex; flex-direction: column; gap: 6px; }
.v2-stats__header { font-weight: 600; font-size: 13px; color: var(--ink2); }
.v2-stats__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
.v2-stats__tile { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 8px 10px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 8px; background: var(--ide-panel-bg, #fff); font: inherit; text-align: left; cursor: default; }
.v2-stats__tile--link { cursor: pointer; }
.v2-stats__tile--link:hover { border-color: var(--accent, #1e6c93); box-shadow: inset 0 -2px 0 var(--accent, #1e6c93); }
.v2-stats__val { font-size: 20px; font-weight: 650; font-variant-numeric: tabular-nums; }
.v2-stats__label { font-size: 12px; color: var(--ink2); text-transform: none; letter-spacing: 0; }
.v2-stats__tile:disabled { opacity: 0.8; }
/* Objects panel (Infrastructure & People) + editable object profile page (modal). */
.v2-objects { display: flex; flex-direction: column; gap: 6px; height: 100%; min-height: 0; }
.v2-objects__header { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.v2-objects__title { font-weight: 600; }
.v2-objects__new { display: inline-flex; align-items: center; gap: 6px; }
.v2-objects__kindsel { font: inherit; font-size: 12px; padding: 3px 6px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 5px; background: var(--ide-panel-bg, #fff); }
.v2-objects__add { padding: 4px 10px; border: 1px solid var(--accent, #1e6c93); border-radius: 6px; background: var(--accent, #1e6c93); color: #fff; font: inherit; font-size: 12px; cursor: pointer; }
.v2-objects__add:hover { filter: brightness(1.08); }
.v2-objects__list { list-style: none; margin: 0; padding: 0; overflow: auto; min-height: 0; flex: 1 1 auto; }
.v2-objects__row { display: grid; grid-template-columns: 1fr auto 2fr auto; align-items: center; gap: 10px; padding: 4px 6px; border-bottom: 1px solid var(--ide-border, #eef1f5); }
.v2-objects__row:hover { background: var(--paper); }
.v2-objects__name { font-weight: 500; }
.v2-objects__kind { font-size: 11px; color: var(--ink2); border: 1px solid var(--ide-border, #d8dee4); border-radius: 10px; padding: 0 8px; }
.v2-objects__attrs { font-size: 12px; color: var(--ink2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-objects__acts { display: inline-flex; gap: 6px; }
.v2-objects__edit, .v2-objects__del { border: 1px solid var(--ide-border, #d8dee4); border-radius: 5px; background: var(--ide-panel-bg, #fff); font: inherit; font-size: 12px; padding: 2px 8px; cursor: pointer; }
.v2-objects__edit:hover, .v2-objects__del:hover { background: var(--paper2); }
/* Delete is destructive and sits next to `edit`; styling the two alike is how the wrong one gets
   clicked. Outlined, like .v2-recordForm__submit--danger, so it stays the quieter of the pair. */
.v2-objects__del { border-color: var(--danger); color: var(--danger); }
.v2-objects__del:hover { background: var(--danger); color: #fff; }
.v2-objects__empty { color: var(--ink2); font-size: 12px; padding: 10px 6px; }
.v2-objects__status { font-size: 12px; color: var(--ink2); min-height: 1em; }
.v2-modal, .v2-objModal { position: fixed; inset: 0; z-index: 1000; background: rgba(20, 28, 36, 0.55); backdrop-filter: blur(2px); display: flex; align-items: center; justify-content: center; padding: 24px; }
.v2-modal__panel, .v2-objModal__panel { background: var(--ide-panel-bg, #fff); border-radius: 10px; width: min(520px, 96vw); max-height: 86vh; display: flex; flex-direction: column; overflow: hidden; box-shadow: 0 16px 48px rgba(0, 0, 0, 0.35); }
.v2-modal__head, .v2-objModal__head { display: flex; align-items: center; gap: 14px; padding: 10px 14px; border-bottom: 1px solid var(--ide-border, #d8dee4); }
.v2-modal__title, .v2-objModal__title { font-weight: 600; flex: 1 1 auto; text-transform: capitalize; }
.v2-modal__close, .v2-objModal__close { width: 28px; height: 28px; border: none; background: none; font-size: 16px; color: var(--ink2); cursor: pointer; border-radius: 6px; }
.v2-modal__close:hover, .v2-objModal__close:hover { background: var(--paper2); }
.v2-objForm { padding: 12px 14px; overflow: auto; display: flex; flex-direction: column; gap: 8px; }
.v2-objForm__row { display: flex; flex-direction: column; gap: 3px; font-size: 12px; color: var(--ink2); }
.v2-objForm__row input { font: inherit; font-size: 14px; padding: 5px 8px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px; background: var(--ide-panel-bg, #fff); }
.v2-objForm__attrsHead { font-size: 12px; color: var(--ink2); margin-top: 4px; }
.v2-objForm__attr { display: flex; gap: 6px; align-items: center; }
.v2-objForm__k, .v2-objForm__v { font: inherit; font-size: 13px; padding: 4px 7px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px; background: var(--ide-panel-bg, #fff); }
.v2-objForm__k { flex: 0 0 40%; } .v2-objForm__v { flex: 1 1 auto; }
.v2-objForm__rm { border: none; background: none; color: var(--ink2); cursor: pointer; font-size: 13px; padding: 2px 6px; }
.v2-objForm__rm:hover { color: var(--danger); }
.v2-objForm__addAttr { align-self: flex-start; border: 1px dashed var(--ide-border, #d8dee4); border-radius: 6px; background: none; color: var(--accent, #1e6c93); font: inherit; font-size: 12px; padding: 3px 10px; cursor: pointer; }
.v2-modal__bar, .v2-objModal__bar { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-top: 1px solid var(--ide-border, #d8dee4); }
/* Typed-confirmation dialog — the shared destructive gate. Reuses the modal shell above (the
   .v2-modal aliases exist so a dialog that is not about objects need not borrow their names). */
.v2-modal__body { padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; }
.v2-modal__text { margin: 0; font-size: 13px; color: var(--ink2); }
.v2-modal__field { display: flex; flex-direction: column; gap: 5px; font-size: 12px; color: var(--ink2); }
.v2-modal__field input {
  font: inherit; font-size: 13px; padding: 4px 7px; border-radius: 5px;
  border: 1px solid var(--ide-border, #d8dee4); background: var(--ide-panel-bg, #fff);
}
.v2-modal__status { font-size: 12px; color: var(--ink2); flex: 1 1 auto; }
.v2-modal__cancel, .v2-modal__go {
  padding: 4px 14px; border-radius: 6px; font: inherit; font-size: 13px; cursor: pointer;
  border: 1px solid var(--ide-border, #d8dee4); background: var(--ide-panel-bg, #fff);
}
.v2-modal__go--danger { border-color: var(--danger); color: var(--danger); }
.v2-modal__go--danger:hover:not(:disabled) { background: var(--danger); color: #fff; }
.v2-modal__go:disabled { opacity: 0.45; cursor: not-allowed; }
.v2-objForm__status { flex: 1 1 auto; font-size: 12px; color: var(--ink2); }
.v2-objForm__cancel { padding: 5px 14px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px; background: var(--ide-panel-bg, #fff); font: inherit; font-size: 13px; cursor: pointer; }
.v2-objForm__cancel:hover { background: var(--paper2); }
.v2-objForm__save { padding: 5px 16px; border: 1px solid var(--accent, #1e6c93); border-radius: 6px; background: var(--accent, #1e6c93); color: #fff; font: inherit; font-size: 13px; cursor: pointer; }
.v2-objForm__save:disabled { opacity: 0.45; cursor: default; }
.v2-objForm__save:not(:disabled):hover { filter: brightness(1.08); }
/* Record form (Contract Editor) — inline thin widget for the PLAN bottom bar. */
.v2-recordForm { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 12px; }
.v2-recordForm__header { width: 100%; color: var(--ink2); font-size: 12px; margin-bottom: 2px; }
.v2-recordForm__fields { display: flex; flex-wrap: wrap; gap: 8px 12px; flex: 1 1 auto; }
.v2-recordForm__field { display: flex; flex-direction: column; gap: 2px; font-size: 11px; color: var(--ink2); }
.v2-recordForm__field input, .v2-recordForm__field select, .v2-recordForm__field textarea {
  font: inherit; font-size: 13px; padding: 3px 6px;
  border: 1px solid var(--ide-border, #d8dee4); border-radius: 5px; background: var(--ide-panel-bg, #fff);
}
/* A declared record type's field list is as many lines as the tenant wants, so this one takes
   the full row rather than sitting inline with the single-line inputs beside it. */
.v2-recordForm__field textarea {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace); font-size: 12px;
  min-width: 280px; resize: vertical;
}
.v2-recordForm__field:has(textarea) { flex: 1 1 100%; }
/* A field declared `wide` (a title) takes the row too, and its input fills it. */
.v2-recordForm__field--wide { flex: 1 1 100%; }
.v2-recordForm__field--wide input { width: 100%; box-sizing: border-box; }
/* THE WRITING ITSELF (payload `prose`, 2026-10-07): a reading face at a reading size, the
   page's ink on its paper — not the 12px monospace a record's field list gets. A client
   asked for the Authoring page's font and colours changed; this is the editor's half, and
   `.v2-recordTable__detail--prose` is the version preview's. One serif stack, no webfont. */
.v2-recordForm__field--prose textarea, .v2-recordForm__field--prose input {
  font-family: Georgia, "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Palatino, serif;
  color: var(--ink); background: var(--paper); border-color: var(--line); }
.v2-recordForm__field--prose textarea { font-size: 16px; line-height: 1.55; min-height: 260px; padding: 12px 14px; }
.v2-recordForm__field--prose input { font-size: 18px; padding: 6px 10px; }
.v2-recordForm__field--prose > span { font-size: 12px; }
.v2-recordTable__prose dd {
  font-family: Georgia, "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Palatino, serif;
  font-size: 15px; line-height: 1.55; max-width: 72ch; color: var(--ink); }
/* Several of a known set — the jobs a customer needs, one fieldset per trade, the depth under
   the trade drawn as indentation. Takes the row like a textarea does: a list has no width. */
.v2-recordForm__checks { flex: 1 1 100%; border: 1px solid var(--ide-border, #d8dee4); border-radius: 5px; padding: 6px 10px 8px; margin: 0; }
.v2-recordForm__checks legend { padding: 0 4px; font-size: 11px; color: var(--ink2); }
.v2-recordForm__checkGroup { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 14px; padding: 3px 0; }
.v2-recordForm__checkGroup + .v2-recordForm__checkGroup { border-top: 1px dashed var(--ide-border, #d8dee4); }
.v2-recordForm__checkGroupName { flex: 1 1 100%; font-size: 11px; font-weight: 600; color: var(--ink1, inherit); }
.v2-recordForm__check { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; color: var(--ink1, inherit); padding-left: calc(var(--depth, 0) * 14px); cursor: pointer; }
.v2-recordForm__check input { margin: 0; }
/* "How many" beside a pick (2026-10-15): small, and quiet until its box is ticked. Wide
   enough for a two-digit count beside the number spinner and for its "Qty" placeholder;
   `min-width` so a flex row cannot squeeze it narrower than what it has to show. */
.v2-recordForm__check .v2-recordForm__qty { width: 4.75em; min-width: 4.75em; margin-left: 6px; padding: 2px 6px; font: inherit; font-size: 12px; }
.v2-recordForm__check:not(:has(input[type=checkbox]:checked)) .v2-recordForm__qty { opacity: 0.45; }
.v2-recordForm__submit {
  padding: 4px 14px; border: 1px solid var(--accent, #1e6c93); border-radius: 6px;
  background: var(--accent, #1e6c93); color: #fff; font: inherit; font-size: 13px; cursor: pointer;
}
.v2-recordForm__submit:hover { filter: brightness(1.08); }
/* A destructive submit must not look like a save. Outlined rather than filled, so the danger
   button is also the quieter one until it is deliberately clicked. */
.v2-recordForm__submit--danger {
  border-color: var(--danger, #a3352c); background: transparent; color: var(--danger, #a3352c);
}
.v2-recordForm__submit--danger:hover { background: var(--danger, #a3352c); color: #fff; }
.v2-recordForm__status { font-size: 12px; color: var(--ink2); }
.v2-dendro__view {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 170px;
  border: 1px solid transparent;
  background: var(--ide-panel-bg, #fff);
  border-radius: 6px;
  padding: 2px 8px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.v2-dendro__view:hover {
  border-color: var(--ide-border, #d8dee4);
  background: var(--paper2);
}
.v2-dendro__label {
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 600;
}
.v2-dendro__count {
  flex: 0 0 auto;
  min-width: 1.4em;
  text-align: center;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--ide-border, #eaeef2);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--ink2);
}
/* Node KIND, on the lcl tree only: what a node IS, read from the marker its address
   rides. A type is the default and unlabelled — most of the tree is types, so tagging
   them would be noise. A record and an unclassified node are the ones worth calling out:
   a record is a leaf you edit, and `unclassified` is an honest "the corpus has not said",
   which must not be allowed to look like either of the other two. */
/* LCL Editor: the tree is a SELECTOR here, so a node has to read as pickable and the current
   pick has to be unmistakable. Theme variables only — `--accent` is redeclared per theme, and a
   literal would be wrong in half of them. */
.v2-dendro__view.is-selectable { cursor: pointer; }
.v2-dendro__view.is-selectable:hover { border-color: var(--accent); }
.v2-dendro__view.is-selected {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.v2-dendro__kind {
  flex: 0 0 auto;
  padding: 0 5px;
  border-radius: 3px;
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 600;
}
/* Both tags carry their weight in theme variables only — no literal hex. `--accent` is
   re-declared per theme (it goes light-blue → green → periwinkle across the four), so a
   hardcoded "soft accent" fill would be a light-theme swatch sitting in a dark one. Border
   from currentColor keeps the pair in step with whatever the theme sets. */
.v2-dendro__kind--instance {
  background: transparent;
  color: var(--accent);
  border: 1px solid currentColor;
}
.v2-dendro__kind--unmarked {
  background: transparent;
  color: var(--ink2);
  border: 1px dashed var(--ide-border);
}
/* SAMRAS structure dendrogram: browse-only static nodes (address + label, no
   view/edit button) reusing the .v2-dendro cluster diagram. */
.v2-clusterTree__header { color: var(--ink2); font-size: 12px; margin-bottom: 4px; }
.v2-clusterTree__empty { color: var(--ink2); font-size: 13px; }
/* SAMRAS node: keep the shared .v2-dendro__view chip (white bg, transparent border)
   but non-interactive — the body is a <span> with no drill-in handler, so it must
   NOT take the Resource chip's clickable hover highlight (that reads as a dead click). */
.v2-dendro__view--static {
  cursor: default;
  max-width: 280px;
}
.v2-dendro__view--static:hover {
  border-color: transparent;
  background: var(--ide-panel-bg, #fff);
}
/* Status glyph: the SAMRAS analog of the Resource per-type icon. */
.v2-dendro__status {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  box-sizing: border-box;
}
.v2-dendro__status--defined {
  background: var(--accent, #2f6f3e);
}
.v2-dendro__status--empty {
  background: var(--ide-panel-bg, #fff);
  border: 2px solid var(--line); /* darker + thicker than --ink2 so the hollow ring reads on white */
}
.v2-dendro__addr {
  flex: 0 0 auto;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.v2-dendro__empty { color: var(--ink2); font-style: italic; }
.v2-dendro__view--static.is-empty .v2-dendro__addr { color: var(--ink2); }
/* Empty (undefined) chips dim their address; a child-count pill on such a node
   must follow suit rather than being the one full-strength element. */
.v2-dendro__view--static.is-empty .v2-dendro__count { color: var(--ink2); background: transparent; }

/* Taxonomy Domain node: produce icon + common name, scientific-name subtitle.
   Icons carry baked fills (often #000), so give them a light chip so they read
   in both themes; an inherited (closest-parent) icon is dimmed to signal it. */
.v2-taxo__view { align-items: center; gap: 7px; }
.v2-taxo__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 2px;
  border-radius: 5px;
  background: var(--paper);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}
.v2-taxo__icon .v2-typeIcon { width: 18px; height: 18px; color: inherit; }
.v2-taxo__icon--inherited { opacity: 0.5; }
.v2-taxo__names { display: inline-flex; flex-direction: column; min-width: 0; line-height: 1.15; }
.v2-taxo__names .v2-dendro__label { font-weight: 600; }
/* Vertical (root-on-top) SAMRAS layout: nodes stack their toggle over a centred body. */
.v2-dendro--vertical .v2-dendro__node {
  transform: none;
  width: 132px;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  white-space: normal;
  text-align: center;
}
.v2-dendro--vertical .v2-taxo__view { flex-direction: column; align-items: center; text-align: center; }
.v2-dendro--vertical .v2-taxo__names { align-items: center; }
.v2-dendro--vertical .v2-taxo__sci { white-space: normal; }
.v2-taxo__sci {
  font-size: 10px;
  font-style: italic;
  color: var(--ink2, #57606a);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Taxa Product Table (Taxonomy Domain right pane) — grouped/filterable product list. */
.v2-taxaTable { display: flex; flex-direction: column; min-height: 0; height: 100%; }
.v2-taxaTable__header { font-weight: 600; font-size: 0.82rem; padding: 2px 2px 6px; }
.v2-taxaTable__filters { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.v2-taxaTable__search { flex: 1 1 140px; min-width: 120px; padding: 4px 8px; border: 1px solid var(--line, #d8dee4); border-radius: 6px; font-size: 0.78rem; }
.v2-taxaTable__facet { padding: 3px 6px; border: 1px solid var(--line, #d8dee4); border-radius: 6px; font-size: 0.72rem; background: var(--ide-panel-bg, #fff); }
.v2-taxaTable__toolbar { display: flex; gap: 6px; margin-bottom: 4px; }
.v2-taxaTable__body { flex: 1 1 auto; min-height: 0; overflow: auto; border: 1px solid var(--line, #e6e8eb); border-radius: 8px; }
.v2-taxaTable__count { padding: 6px 10px; font-size: 0.72rem; color: var(--ink2, #57606a); position: sticky; top: 0; background: var(--ide-panel-bg, #fff); border-bottom: 1px solid var(--line, #eee); }
.v2-taxaTable__group { display: flex; align-items: center; gap: 6px; padding: 4px 8px; border-bottom: 1px solid var(--line, #f0f1f3); font-size: 0.78rem; }
.v2-taxaTable__group:hover { background: rgba(31, 111, 235, 0.05); }
.v2-taxaTable__toggle { flex: 0 0 auto; width: 16px; height: 16px; padding: 0; line-height: 1; border: 1px solid var(--line, #d8dee4); background: var(--ide-panel-bg, #fff); border-radius: 4px; font-size: 9px; cursor: pointer; }
.v2-taxaTable__toggle--leaf { border-color: transparent; background: transparent; cursor: default; }
.v2-taxaTable__gico, .v2-taxaTable__pico { flex: 0 0 auto; display: inline-flex; }
.v2-taxaTable__gico .v2-typeIcon, .v2-taxaTable__pico .v2-typeIcon { width: 16px; height: 16px; }
.v2-taxaTable__glabel { font-weight: 600; }
.v2-taxaTable__gsci { font-size: 10px; font-style: italic; color: var(--ink2, #57606a); }
.v2-taxaTable__gcount { margin-left: auto; flex: 0 0 auto; font-size: 0.68rem; color: var(--ink2, #57606a); background: var(--line, #eef0f2); border-radius: 10px; padding: 0 7px; }
.v2-taxaTable__prod { display: flex; align-items: center; gap: 6px; padding: 3px 8px; border-bottom: 1px solid var(--line, #f5f6f7); font-size: 0.74rem; }
.v2-taxaTable__prod:hover { background: rgba(31, 111, 235, 0.04); }
.v2-taxaTable__pname { font-weight: 500; }
.v2-taxaTable__pcommon { font-weight: 400; color: var(--ink2, #57606a); font-style: italic; }
.v2-taxaTable__pmeta { margin-left: auto; display: inline-flex; flex-wrap: wrap; gap: 3px; justify-content: flex-end; }
.v2-taxaTable__chip { font-size: 0.62rem; color: var(--ink2, #57606a); background: var(--line, #eef0f2); border-radius: 4px; padding: 0 5px; white-space: nowrap; }
.v2-taxaTable__empty { padding: 14px; color: var(--ink2, #57606a); font-size: 0.78rem; }
.v2-taxaTable__prod.is-clickable { cursor: pointer; }
.v2-taxaTable__add { flex: 0 0 auto; width: 18px; height: 18px; margin-left: 4px; padding: 0; line-height: 1; border: 1px solid var(--line, #d8dee4); background: var(--ide-panel-bg, #fff); border-radius: 4px; font-size: 12px; color: var(--accent, #1f6feb); cursor: pointer; }
.v2-taxaTable__add:hover { background: var(--accent); color: var(--accent-fg); }
/* Flora & Fauna cluster-graph leaf "add to inventory" affordance (mirrors the product card +). */
.v2-taxo__add { margin-left: 4px; width: 17px; height: 17px; padding: 0; line-height: 1; border: 1px solid var(--line, #d8dee4); background: var(--ide-panel-bg, #fff); border-radius: 4px; font-size: 11px; color: var(--accent, #1f6feb); cursor: pointer; vertical-align: middle; }
.v2-taxo__add:hover { background: var(--accent); color: var(--accent-fg); }

/* Inventory Management — the PLAN tab's writable supply-batch table (inline-edit). */
.v2-invTable { display: flex; flex-direction: column; min-height: 0; font-size: 0.8rem; }
.v2-invTable__header { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.v2-invTable__title { font-weight: 600; color: var(--ink1, #24292f); }
.v2-invTable__add { padding: 4px 12px; border: 1px solid var(--accent, #1f6feb); background: var(--accent, #1f6feb); color: #fff; border-radius: 6px; font-size: 12px; cursor: pointer; }
.v2-invTable__add:hover { filter: brightness(1.08); }
.v2-invTable__wrap { overflow-x: auto; }
.v2-invTable__table { width: 100%; border-collapse: collapse; }
.v2-invTable__table th { text-align: left; font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--ink2, #57606a); border-bottom: 1px solid var(--ide-border, #d8dee4); padding: 4px 8px; white-space: nowrap; }
.v2-invTable__table td { padding: 4px 8px; border-bottom: 1px solid var(--line, #f0f1f3); vertical-align: middle; }
.v2-invTable__act { text-align: right; white-space: nowrap; }
.v2-invTable__edit { width: 22px; height: 22px; padding: 0; border: 1px solid var(--line, #d8dee4); background: var(--ide-panel-bg, #fff); border-radius: 5px; font-size: 12px; color: var(--accent, #1f6feb); cursor: pointer; }
.v2-invTable__edit:hover { background: var(--paper2); }
.v2-invTable__editrow { background: rgba(31, 111, 235, 0.05); }
/* AN ADDRESS CELL: state, city, street — stacked, because they are said in that order
   and because three controls side by side in a table column are three controls nobody
   can hit with a thumb. (2026-08-18)                                                  */
.v2-invTable__addr {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 190px;
}
/* The marker the identity column used to carry, for the tables that no longer have one:
   a row being edited that does not say so is a row an operator saves by accident. */
.v2-invTable__editmark {
  margin-right: 6px;
  color: var(--ink2);
  font-size: 0.72rem;
  white-space: nowrap;
}
.v2-invTable__editrow input, .v2-invTable__editrow select { width: 100%; min-width: 80px; padding: 3px 6px; border: 1px solid var(--line, #d8dee4); border-radius: 5px; font: inherit; font-size: 0.76rem; box-sizing: border-box; }
.v2-invTable__save { padding: 3px 10px; border: 1px solid var(--accent, #1f6feb); background: var(--accent, #1f6feb); color: #fff; border-radius: 5px; font-size: 12px; cursor: pointer; }
.v2-invTable__cancel { padding: 3px 8px; border: 1px solid var(--line, #d8dee4); background: var(--ide-panel-bg, #fff); border-radius: 5px; font-size: 12px; cursor: pointer; }
.v2-invTable__empty { padding: 14px 8px; color: var(--ink2, #57606a); }
.v2-invTable__status { margin-top: 8px; font-size: 12px; color: var(--ink2, #57606a); min-height: 16px; }
/* Server-derived columns (`computed_columns`) — shown, never typed. Set apart from the
   editable cells so the difference is visible before the operator clicks into a row. */
th.v2-invTable__computed { color: var(--ink2, #57606a); font-style: italic; }
td.v2-invTable__computed { color: var(--ink2, #57606a); font-variant-numeric: tabular-nums; }
/* Why a figure is absent. A statement of scope, kept quiet — it is not a warning. */
.v2-invTable__note { margin: 8px 0 0; font-size: 0.72rem; line-height: 1.5; color: var(--ink2, #57606a); }

/* The filter bar. Present exactly when the payload carries `filters`/`export`, so every
   table that declares neither is byte-for-byte what it was. Wraps rather than scrolls: a
   facet select pushed off the right edge is a filter nobody knows is there. */
.v2-invTable__filters { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 8px; }
.v2-invTable__search { flex: 1 1 160px; min-width: 120px; max-width: 280px; padding: 4px 8px; border: 1px solid var(--line, #d8dee4); border-radius: 6px; font: inherit; font-size: 0.76rem; box-sizing: border-box; }
.v2-invTable__facet { padding: 4px 6px; border: 1px solid var(--line, #d8dee4); border-radius: 6px; font: inherit; font-size: 0.76rem; background: var(--ide-panel-bg, #fff); max-width: 190px; }
/* `showing N of M`, and it pushes the actions to the right edge. */
.v2-invTable__showing { margin-left: auto; font-size: 0.72rem; color: var(--ink2, #57606a); font-variant-numeric: tabular-nums; }
.v2-invTable__clear { padding: 4px 10px; border: 1px solid var(--line, #d8dee4); background: var(--ide-panel-bg, #fff); border-radius: 6px; font-size: 12px; cursor: pointer; color: var(--ink2, #57606a); }
.v2-invTable__clear:hover { background: var(--paper2); color: var(--ink1, #24292f); }
/* Export is data LEAVING, so it is an outline button rather than a primary one: it should
   not compete with + Add for the eye, and it should not look like the safe default. */
.v2-invTable__export { padding: 4px 10px; border: 1px solid var(--accent, #1f6feb); border-radius: 6px; font-size: 12px; text-decoration: none; color: var(--accent, #1f6feb); white-space: nowrap; }
.v2-invTable__export:hover { background: rgba(31, 111, 235, 0.08); }
/* A filter matching nothing, said out loud — an empty table under a live filter and an
   empty table are the same picture otherwise, and only one is the operator's own doing. */
.v2-invTable__unmatched { margin: 0 0 8px; font-size: 0.72rem; line-height: 1.5; color: var(--warn-ink, #9a6700); }

/* ── Table / Map switch and the map face ────────────────────────────────────────────────
   The switch LEADS the filter bar, because it says what you are looking at and everything
   after it applies to both faces. Segmented rather than a toggle: two named buttons, one
   pressed, so neither face is the unlabelled other. */
.v2-invTable__views { display: inline-flex; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; }
.v2-invTable__view {
  padding: 4px 12px; border: 0; background: transparent; font: inherit; font-size: 0.76rem;
  color: var(--ink2); cursor: pointer;
}
.v2-invTable__view + .v2-invTable__view { border-left: 1px solid var(--line); }
.v2-invTable__view:hover { background: var(--paper2); color: var(--ink); }
/* Text on an accent fill comes from the token, never from #fff — spore's gold and
   midnight's light blue both fail white at ~2.5:1. */
.v2-invTable__view.is-active { background: var(--accent); color: var(--accent-fg); }

.v2-rowMap { display: flex; flex-direction: column; gap: 10px; margin-bottom: 8px; }
.v2-rowMap__canvas {
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper2);
  padding: 6px; min-height: 0;
}
.v2-rowMap__svg { display: block; width: 100%; height: auto; max-height: 46vh; }
.v2-rowMap__region {
  fill: var(--accent); stroke: var(--line); stroke-width: 1; cursor: pointer;
  transition: fill-opacity 120ms ease;
}
.v2-rowMap__region:hover { stroke: var(--accent2); stroke-width: 1.8; }
.v2-rowMap__region.is-active { stroke: var(--ink); stroke-width: 2.2; }
/* The count sits ON the region, and the region's fill OPACITY varies — so one colour
   cannot be right for both ends of the scale. A heavily shaded region is an accent fill
   and takes `--accent-fg`; a faint one is nearly the canvas and takes ordinary ink. The
   renderer picks by weight; both are tokens, so both follow the theme. */
.v2-rowMap__label { fill: var(--ink); font-size: 12px; font-weight: 600; pointer-events: none; font-variant-numeric: tabular-nums; }
.v2-rowMap__label.is-onfill { fill: var(--accent-fg); }

.v2-rowMap__legend { display: flex; flex-wrap: wrap; gap: 6px; }
.v2-rowMap__row {
  display: inline-flex; align-items: baseline; gap: 8px; padding: 4px 10px;
  border: 1px solid var(--line); border-radius: 6px; background: var(--paper);
  font: inherit; font-size: 0.76rem; color: var(--ink); cursor: pointer;
}
.v2-rowMap__row:hover { background: var(--paper2); }
.v2-rowMap__row.is-active { border-color: var(--accent); background: var(--accent); color: var(--accent-fg); }
/* A place with rows and no polygon is a hole in the picture the picture cannot show, so
   the legend shows it — dashed, present, and clickable like any other. */
.v2-rowMap__row.is-unoutlined { border-style: dashed; color: var(--ink2); }
.v2-rowMap__count { font-variant-numeric: tabular-nums; color: inherit; opacity: 0.8; }
.v2-rowMap__note { margin: 0; font-size: 0.72rem; line-height: 1.5; color: var(--ink2); }

@media (max-width: 700px) {
  .v2-rowMap__svg { max-height: 38vh; }
}

/* THE FACES MUST OBEY `hidden`. `[hidden] { display: none }` comes from the UA
   stylesheet, so ANY explicit `display` on the element beats it — and `.v2-rowMap` sets
   `display: flex`. Measured 2026-09-03 by the three-face e2e: the switch set
   `faces[key].hidden = ...` correctly, the DOM carried the attribute, and the map drew
   underneath the Table button anyway. The renderer and the stylesheet disagreed, and only
   the stylesheet was visible. Every face container gets a rule, not just the one that was
   caught, because the next one added will have the same problem.
   (This repo already spells it this way per component — see `.data-tool__nimmOverlay
   [hidden]` and its neighbours.) */
.v2-rowMap[hidden],
.v2-cardGal[hidden],
.v2-invTable__wrap[hidden],
.v2-invTable__facegap[hidden] { display: none !important; }

/* ── The CARD face ──────────────────────────────────────────────────────────────────────
   The other index over the same rows: a table accounts for every column on every row, a
   gallery is the scannable one. Auto-fill rather than a fixed column count, because the
   panel this draws in is anything from a phone to half a desk — a 3-up grid pinned in CSS
   is a 3-up grid at 390px too.

   NO IMAGE RULE HERE, on purpose. `job_event` has no image field and `save_job` has no
   path that would write one, so there is nothing to size; a frame in the stylesheet would
   be the first half of a feature the corpus cannot supply. */
.v2-cardGal { margin-bottom: 8px; }
.v2-cardGal__grid {
  display: grid; gap: 8px;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}
/* The whole card is the control — a <button> — so opening a job is one target wherever the
   pointer lands, and the keyboard reaches it without a nested tab stop. `text-align: left`
   because a button's default centring turns a record into a poster. */
.v2-cardGal__card {
  display: flex; flex-direction: column; gap: 6px; padding: 10px 12px; text-align: left;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper);
  font: inherit; color: var(--ink); cursor: pointer;
}
.v2-cardGal__card:hover { background: var(--paper2); border-color: var(--accent); }
.v2-cardGal__card:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* A row with no address has nothing to open, so its card is a box and says so by not
   lifting under the pointer. */
.v2-cardGal__card.is-unopenable { cursor: default; opacity: 0.72; }
.v2-cardGal__head { display: flex; align-items: baseline; gap: 8px; }
.v2-cardGal__title { font-weight: 600; font-size: 0.82rem; line-height: 1.3; }
/* What it paid, pushed to the right edge and tabular so a column of cards reads down. */
.v2-cardGal__badge {
  margin-left: auto; font-size: 0.76rem; font-variant-numeric: tabular-nums;
  color: var(--accent); white-space: nowrap;
}
.v2-cardGal__sub { font-size: 0.74rem; line-height: 1.4; color: var(--ink2); }
.v2-cardGal__lines { display: flex; flex-direction: column; gap: 2px; }
/* Label and value on one line, the label fixed so the values align down the card. A blank
   line is never drawn at all — that is the server's rule (`_row_gallery`), not a
   `:empty` selector, because a card is a preview and the TABLE is where a gap is visible. */
.v2-cardGal__line { display: flex; gap: 6px; font-size: 0.72rem; line-height: 1.5; }
.v2-cardGal__label { flex: 0 0 4.4em; color: var(--ink2); }
.v2-cardGal__value { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
/* Written for whoever reaches it: a gallery narrowed to nothing and a book with no work in
   it are the same picture, and only one of them is the operator's own filter. */
.v2-cardGal__empty { margin: 0; padding: 14px 8px; font-size: 0.76rem; color: var(--ink2); }

/* A face the switch offers that the payload did not fill. It is a sentence rather than an
   empty panel: hiding the table for a blank div reads as a broken tool. */
.v2-invTable__facegap {
  margin: 0 0 8px; padding: 14px 8px; font-size: 0.76rem; color: var(--ink2);
}

/* Phase B–D lifecycle: days-until-bad badge, remaining/waste, retire toggle, plan button. */
.v2-invLife { white-space: nowrap; font-size: 0.72rem; line-height: 1.5; }
.v2-invLife__h { font-size: 0.72rem; color: var(--ink2, #57606a); }
.v2-invLife__bad { display: inline-block; padding: 1px 6px; border-radius: 9px; font-weight: 600; }
.v2-invLife__bad.is-ok { background: rgba(31, 136, 61, 0.12); color: var(--moss); }
.v2-invLife__bad.is-soon { background: rgba(191, 135, 0, 0.15); color: var(--accent); }
.v2-invLife__bad.is-bad { background: rgba(207, 34, 46, 0.13); color: var(--danger); }
.v2-invLife__stock { color: var(--ink2, #57606a); }
.v2-invLife__retired { color: var(--danger); font-style: italic; }
/* Declared row actions (`row_actions`): one rule for every record type's buttons, since the
   renderer no longer knows any of them by name. `--plan` keeps the icon-button sizing. */
[class*="v2-invTable__act--"] { margin-left: 4px; padding: 2px 7px; border: 1px solid var(--line, #d8dee4); background: var(--ide-panel-bg, #fff); border-radius: 5px; font-size: 11px; color: var(--ink2, #57606a); cursor: pointer; vertical-align: middle; }
.v2-invTable__act--plan { width: 22px; height: 22px; padding: 0; color: var(--accent, #1f6feb); font-size: 13px; }
[class*="v2-invTable__act--"]:hover { background: var(--paper2); }
.v2-invTable__row--retired td { opacity: 0.55; }
.v2-invTable__row--retired .v2-invLife { opacity: 1; }

/* Agro Calendar (NETWORK tab bottom subtool) — Calendar (month) + Week (day×hour). */
.v2-cal { display: flex; flex-direction: column; min-height: 0; height: 100%; font-size: 0.78rem; }
.v2-cal__filters { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: 6px; }
.v2-cal__tabs { display: inline-flex; border: 1px solid var(--line, #d8dee4); border-radius: 6px; overflow: hidden; }
.v2-cal__tab { padding: 3px 10px; border: 0; background: var(--ide-panel-bg, #fff); cursor: pointer; font-size: 0.74rem; }
.v2-cal__tab.is-active { background: var(--accent); color: var(--accent-fg); }
.v2-cal__sel { padding: 3px 6px; border: 1px solid var(--line, #d8dee4); border-radius: 6px; font-size: 0.72rem; background: var(--ide-panel-bg, #fff); }
/* The coverage note: what the schedule read and what it deliberately excludes. Pushed to the
   end of the filter row and kept quiet — it is a statement of scope, not a control. */
.v2-cal__coverage { margin-left: auto; font-size: 0.66rem; color: var(--ink2, #57606a); }
.v2-cal__body { flex: 1 1 auto; min-height: 0; overflow: auto; }
.v2-cal__nav { display: flex; align-items: center; justify-content: center; gap: 12px; padding: 4px 0; }
.v2-cal__navBtn { width: 22px; height: 22px; border: 1px solid var(--line, #d8dee4); background: var(--ide-panel-bg, #fff); border-radius: 5px; cursor: pointer; }
.v2-cal__title { font-weight: 600; min-width: 150px; text-align: center; }
.v2-cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.v2-cal__dow { text-align: center; font-size: 0.64rem; font-weight: 600; color: var(--ink2, #57606a); padding: 2px 0; }
.v2-cal__cell { min-height: 46px; border: 1px solid var(--line, #eef0f2); border-radius: 4px; padding: 2px 3px; display: flex; flex-direction: column; gap: 2px; }
.v2-cal__cell.is-blank { border: 0; }
.v2-cal__cell.is-today { outline: 2px solid var(--accent); }
.v2-cal__num { font-size: 0.62rem; color: var(--ink2, #57606a); }
.v2-cal__marks { display: flex; flex-wrap: wrap; gap: 2px; }
.v2-cal__mark { width: 9px; height: 9px; border-radius: 50%; border: 0; padding: 0; cursor: pointer; }
.v2-cal__more { font-size: 0.58rem; color: var(--ink2, #57606a); }
.v2-cal__ongoing { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.v2-cal__ongoingLbl { font-size: 0.66rem; font-weight: 600; color: var(--ink2, #57606a); }
.v2-cal__chip { display: inline-flex; align-items: center; gap: 5px; border: 1px solid var(--line, #e6e8eb); border-left-width: 3px; border-radius: 5px; background: var(--ide-panel-bg, #fff); padding: 2px 8px; font-size: 0.7rem; cursor: pointer; }
.v2-cal__chipDot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.v2-cal__chipMeta { color: var(--ink2, #57606a); }
.v2-cal__week { display: flex; flex-direction: column; min-width: 620px; }
.v2-cal__wrow { display: grid; grid-template-columns: 54px repeat(7, 1fr); }
.v2-cal__whrow { position: sticky; top: 0; z-index: 1; background: var(--ide-panel-bg, #fff); }
.v2-cal__wcell { border: 1px solid var(--line, #f0f1f3); padding: 2px 3px; min-height: 20px; }
.v2-cal__whead { text-align: center; font-weight: 600; font-size: 0.66rem; }
.v2-cal__whead.is-today { color: var(--accent); }
.v2-cal__wtime { font-size: 0.6rem; color: var(--ink2, #57606a); text-align: right; }
.v2-cal__wallday { display: flex; flex-wrap: wrap; gap: 3px; min-height: 22px; }
.v2-cal__wslot { position: relative; }
.v2-cal__block { position: absolute; left: 1px; right: 1px; top: 1px; border: 0; border-radius: 3px; color: #fff; font-size: 0.6rem; padding: 1px 3px; text-align: left; cursor: pointer; overflow: hidden; }
.v2-cal__blockTime { opacity: 0.85; }
.v2-cal__back { border: 0; background: none; color: var(--accent); cursor: pointer; font-size: 0.76rem; padding: 4px 2px; }
.v2-cal__detail { border-left: 4px solid var(--danger); padding: 6px 12px; }
.v2-cal__dTitle { margin: 2px 0 8px; font-size: 0.92rem; }
.v2-cal__dRow { display: flex; gap: 8px; padding: 2px 0; font-size: 0.76rem; }
.v2-cal__dRow label { flex: 0 0 74px; color: var(--ink2, #57606a); font-weight: 600; }
.v2-cal__entityLink { border: 0; background: none; color: var(--accent); cursor: pointer; font-size: 0.78rem; padding: 0; }
.v2-cal__empty { padding: 14px; color: var(--ink2, #57606a); }
/* Today chip in the tab strip */
.v2-cal__today { border-left: 1px solid var(--line, #d8dee4); }
/* County pager (◂ label ▸) */
.v2-cal__pager { display: inline-flex; align-items: center; gap: 4px; }
.v2-cal__pagerBtn { width: 22px; height: 22px; border: 1px solid var(--line, #d8dee4); background: var(--ide-panel-bg, #fff); border-radius: 5px; cursor: pointer; font-size: 0.9rem; line-height: 1; }
.v2-cal__pagerLbl { font-size: 0.72rem; min-width: 96px; text-align: center; color: var(--ink, #24292f); font-weight: 600; }
/* clickable month day-cells + day drill-down */
.v2-cal__cell.is-clickable { cursor: pointer; }
.v2-cal__cell.is-clickable:hover { background: rgba(31, 111, 235, 0.06); }
.v2-cal__dayHead { font-weight: 600; font-size: 0.86rem; margin: 4px 0 8px; }
.v2-cal__dayList { display: flex; flex-direction: column; gap: 5px; }
.v2-cal__dActions { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-top: 10px; }
.v2-cal__locateBtn { border: 1px solid var(--line, #d8dee4); background: var(--ide-panel-bg, #fff); color: var(--ink, #24292f); cursor: pointer; font-size: 0.76rem; padding: 3px 10px; border-radius: 6px; }
.v2-cal__locateBtn:hover { border-color: var(--accent); color: var(--accent); }
.v2-dendro__editIcon {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  line-height: 1;
  padding: 0;
  border: 1px solid var(--ide-border, #d8dee4);
  background: var(--ide-panel-bg, #fff);
  border-radius: 4px;
  font-size: 11px;
  color: var(--ink2);
  cursor: pointer;
}
.v2-dendro__editIcon:hover {
  background: var(--paper2);
}
.v2-dendro__picker {
  margin-left: 4px;
  font: inherit;
  font-size: 12px;
  padding: 2px 4px;
}
.v2-dendro__other {
  margin: 8px 2px 0;
  color: var(--ink2);
  font-size: 12px;
}
/* Directory + instance */
.v2-leafletDir__bar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 6px 0;
}
.v2-leafletDir__bar h4 {
  margin: 0;
}
.v2-leafletDir__back {
  border: 1px solid var(--ide-border, #d8dee4);
  background: var(--ide-panel-bg, #fff);
  border-radius: 6px;
  padding: 4px 10px;
  font: inherit;
  cursor: pointer;
}
.v2-leafletDir__back:hover {
  background: var(--paper2);
}
.v2-browseFilters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 6px 0;
}
.v2-browseFilter {
  border: 1px solid var(--ide-border, #d8dee4);
  background: var(--ide-panel-bg, #fff);
  border-radius: 999px;
  padding: 3px 11px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.v2-browseFilter.is-active {
  background: var(--ide-accent, #1f883d);
  color: #fff;
  border-color: var(--ide-accent, #1f883d);
}
.v2-leafletDir__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 6px;
}
.v2-leafletDir__item {
  display: flex;
  align-items: center;
  gap: 8px;
  text-align: left;
  border: 1px solid var(--ide-border, #d8dee4);
  background: var(--ide-panel-bg, #fff);
  border-radius: 6px;
  padding: 6px 8px;
  font: inherit;
  cursor: pointer;
}
.v2-leafletDir__item:hover {
  background: var(--paper2);
}
.v2-leafletDir__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
}
.v2-leafletDir__name {
  font-weight: 600;
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.v2-leafletDir__meta {
  font-size: 11px;
  color: var(--ink2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.v2-leafletDir__count {
  margin-left: auto;
  min-width: 1.6em;
  text-align: center;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--ide-border, #eaeef2);
  font-variant-numeric: tabular-nums;
}
.v2-leafletDir__search {
  width: 100%;
  box-sizing: border-box;
  margin: 6px 0;
  padding: 5px 9px;
  font: inherit;
  font-size: 13px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 6px;
  background: var(--ide-panel-bg, #fff);
}
.v2-leafletDir__empty {
  margin: 8px 2px;
  color: var(--ink2);
  font-size: 13px;
}
.v2-browseEdit {
  margin-top: 12px;
  border-top: 1px solid var(--ide-border, #d8dee4);
  padding-top: 10px;
}
.v2-browseEdit__btn {
  border: 1px solid var(--ide-border, #d8dee4);
  background: var(--ide-panel-bg, #fff);
  border-radius: 6px;
  padding: 4px 12px;
  font: inherit;
  cursor: pointer;
}
.v2-browseEdit__btn:hover {
  background: var(--paper2);
}
.v2-browseEdit__pane {
  margin-top: 10px;
}
/* Field/value → icon links (content representation) */
.v2-fieldLinks {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin: 10px 0;
}
.v2-fieldLink {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
}
.v2-fieldLink__icon {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  object-fit: contain;
}
.v2-fieldLink__icon--none {
  display: inline-block;
  border-radius: 3px;
  background: var(--ide-border, #d8dee4);
  opacity: 0.5;
}
.v2-fieldLink__val {
  color: var(--ide-accent, #1f883d);
  text-decoration: none;
  word-break: break-word;
}
.v2-fieldLink__val:hover {
  text-decoration: underline;
}
/* Grantee-scoped extra fields (scope_fields) */
.v2-scopeBlock {
  margin-top: 12px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 8px;
  padding: 8px 10px;
  background: var(--ide-panel-bg, #fff);
}
.v2-scopeBlock__head {
  margin: 0 0 6px;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink2);
}
.v2-genericLeaflet__fields {
  display: grid;
  gap: 4px;
  margin: 8px 0;
}
.v2-genericLeaflet__raw {
  max-height: 320px;
  overflow: auto;
  background: var(--paper);
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 6px;
  padding: 8px;
  font-size: 12px;
}
/* Phase 16a — inline contact-row edit. The edit row sits below the
   contact row and expands a tiny form in place. The form is hidden
   until the operator clicks Edit. */
.v2-contactEditRow {
  background: var(--paper);
}
.v2-contactEditForm {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: flex-end;
  padding: 8px 4px;
}
.v2-contactEditForm__label {
  display: inline-flex;
  flex-direction: column;
  font-size: 12px;
  gap: 2px;
  min-width: 140px;
}
.v2-contactEditForm__label input {
  padding: 4px 6px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 4px;
  font: inherit;
}
.v2-contactEditForm__actions {
  display: inline-flex;
  gap: 6px;
  margin-left: auto;
}
/* Phase 17b — Connect submissions table message column: wrap long
   bodies + cap width so the table stays readable. */
.v2-extensionCard__connectMessage {
  max-width: 320px;
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 12px;
  color: var(--ink);
}
.v2-activitylink.is-active {
  outline: 2px solid var(--ide-accent, #1f883d);
  outline-offset: -2px;
}
/* The generic table wrapper had no rule, so a wide datum grid (deep node addresses)
   was clipped by the first overflow:hidden ancestor instead of scrolling. Make it a
   horizontal scroll container (mirrors .v2-workbenchUi__tableWrap / .data-tool__tableWrap). */
.v2-tableWrap {
  overflow-x: auto;
}
.v2-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  margin-top: 8px;
}
.v2-table th,
.v2-table td {
  border: 1px solid var(--ide-border, #d8dee4);
  padding: 8px 10px;
  text-align: left;
  vertical-align: top;
}
/* Opt-in, per column, via `{"key": ..., "wrap": true}` in the section spec.
   Long unbreakable identifiers (`save_offering offering in trapp_family_farm`)
   set a column's min-content width, so a table of them pushes past its wrapper —
   which scrolls, but a 35px overhang draws no scrollbar, so the rightmost column
   just looks cut. `anywhere` is the value that lets a cell shrink below its
   longest word; `break-word` does not affect intrinsic sizing and would not fix
   it. It is opt-in rather than blanket because applying it to every cell lets
   the browser squeeze the short columns too — it turned the Tools table's own
   labels into "Workbe/nch UI" and "Calenda/r" to buy width for its neighbours. */
.v2-table td.is-wrap {
  overflow-wrap: anywhere;
}
.v2-table thead th {
  background: var(--ide-panel-bg, #f6f8fa);
  font-weight: 600;
}
.v2-surface-dl {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(120px, 160px) 1fr;
  gap: 6px 12px;
  font-size: 13px;
}
.v2-surface-dl dt {
  margin: 0;
  font-weight: 600;
  opacity: 0.85;
}
.v2-surface-dl dd {
  margin: 0;
  word-break: break-word;
}

/* Wireframe placeholder rendering for empty listings and empty profile collections.
   Used by the CTS-GIS Garland tab so the NIMM-AITAS mockup scaffold remains
   visible before operational data is wired. */
.v2-component-listing__table--placeholder {
  opacity: 0.85;
}
.v2-component-listing__row--placeholder td {
  color: color-mix(in srgb, var(--ink2, #667068) 65%, transparent);
  background: color-mix(in srgb, var(--paper, #f7f8f3) 96%, var(--paper) 4%);
}
.v2-component-listing__cell--placeholderIndex {
  width: 2.4rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink2, #667068);
}
.v2-component-frame__collectionItems--placeholder dt,
.v2-component-frame__collectionItems--placeholder dd {
  color: color-mix(in srgb, var(--ink2, #667068) 65%, transparent);
}

/* Phase 4 — listing rows that carry select_action are clickable. Hover
   + selected affordance + pointer cursor so the admin-log / precinct
   listing rows visibly behave like buttons. */
.v2-component-listing__row--selectable {
  cursor: pointer;
}
.v2-component-listing__row--selectable:hover td {
  background: color-mix(in srgb, var(--accent, #6aa) 12%, transparent);
}
.v2-component-listing__row--selectable:focus {
  outline: 2px solid var(--accent, #6aa);
  outline-offset: -2px;
}
.v2-component-listing__row--selected td,
.v2-component-listing__row--selectable[aria-pressed="true"] td {
  background: color-mix(in srgb, var(--accent, #6aa) 22%, transparent);
  font-weight: 600;
}

/* Three-mode workbench control panel: tabs,
disclosures {
  font-weight: 600;
  color: var(--accent, #6aa);
}

/* The sandbox block — the panel's PRIMARY control,
so it reads as one.
   It sits first,
is never collapsed {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 9px 9px 10px;
  margin-bottom: 10px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--panel-bg, #1a1a1a);
}
/* Stacked,
not side-by-side. Sharing a 280px row with the SANDBOX label truncated
   "Fruitful Network Development LLC" to "Fruitful Network Developm…" — and the instance
   name is the more valuable half {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

/* The terminal is expert tooling and is collapsed by default; its body needs the
   same inset the disclosure body has {
  margin: 0 8px 8px;
}

/* Plan v2 — menubar tool search (replaces the dead File/Edit/... spans). */
.ide-menubar__toolSearch {
  position: relative;
  display: flex;
  align-items: center;
  margin-right: 12px;
  min-width: 240px;
}
.ide-menubar__toolSearchInput {
  width: 100%;
  padding: 4px 8px;
  background: var(--input-bg, #0f0f0f);
  color: inherit;
  border: 1px solid var(--panel-border, #2a2a2a);
  border-radius: 3px;
  font-family: inherit;
  font-size: 0.85em;
}
.ide-menubar__toolSearchInput:focus {
  outline: 2px solid var(--accent, #6aa);
  outline-offset: -2px;
}
.ide-menubar__toolSearchResults {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 60;
  max-height: 320px;
  overflow-y: auto;
  background: var(--panel-bg, #1a1a1a);
  border: 1px solid var(--panel-border, #2a2a2a);
  border-radius: 3px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4);
}
.ide-menubar__toolSearchResults[hidden] {
  display: none;
}
.portal-tool-palette__list {
  list-style: none;
  margin: 0;
  padding: 4px 0;
}
.portal-tool-palette__item {
  padding: 0;
}
.portal-tool-palette__action {
  display: block;
  width: 100%;
  padding: 6px 10px;
  background: transparent;
  border: 0;
  text-align: left;
  cursor: pointer;
  color: inherit;
}
.portal-tool-palette__action:hover {
  background: color-mix(in srgb, var(--accent, #6aa) 18%, transparent);
}
.portal-tool-palette__action strong {
  display: block;
  font-size: 0.9em;
  font-weight: 600;
}
.portal-tool-palette__action small {
  display: block;
  font-size: 0.8em;
  color: var(--muted, #888);
  margin-top: 2px;
}
.portal-tool-palette__empty {
  padding: 10px;
  margin: 0;
  font-size: 0.85em;
  color: var(--muted, #888);
}
.portal-tool-palette__error { color: var(--danger); cursor: pointer; }
/* Interface-panel tool search: results render as an OVERLAY dropdown anchored to the
   search box (hidden until focus/type) so they don't displace the tool boxes below.
   Mirrors .ide-menubar__toolSearchResults. */
.portal-tool-palette { position: relative; }
.portal-tool-palette__results {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 60;
  max-height: 320px;
  overflow-y: auto;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 4px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.25);
}
.portal-tool-palette__results[hidden] { display: none; }

/* portal-tool-overlay-restructure — menubar tool search (right side of the menu bar).
   Selecting a tool from the dropdown opens #portalToolOverlay. The dropdown reuses
   .portal-tool-palette__results (anchored under the input, hidden until focus/type). */
.ide-menubar__toolSearch {
  position: relative;
  width: clamp(160px, 22vw, 260px);
  margin: 0;
  justify-self: end;
}
.ide-menubar__toolSearch .portal-tool-palette__search { margin: 0; }
.ide-menubar__toolSearch input[data-palette-input] {
  width: 100%;
  box-sizing: border-box;
  padding: 4px 9px;
  font: inherit;
  font-size: 12px;
  color: #f1f4f7;
  background: color-mix(in srgb, var(--coal, #2f2f2f) 60%, var(--coal) 40%);
  border: 1px solid color-mix(in srgb, var(--line) 22%, transparent);
  border-radius: 5px;
}
.ide-menubar__toolSearch input[data-palette-input]::placeholder { color: rgba(235, 240, 246, 0.5); }
.ide-menubar__toolSearch input[data-palette-input]:focus { outline: none; border-color: var(--accent, #1e6c93); }
/* The dropdown renders on a light --paper panel, but the menu bar sets white text — force
   dark text so the tool labels (.portal-tool-palette__action strong = color:inherit) read. */
.ide-menubar__toolSearch .portal-tool-palette__results { color: var(--ink, #464646); }
/* The menubar (.ide-menubar / .ide-menubar__right) is overflow:hidden, which CLIPPED the absolutely
   positioned dropdown to zero visible height. Use position:fixed (viewport-relative) so it escapes
   the clip; v2_portal_shell_core.js positionMenubarList() sets top/left/width from the input rect. */
.ide-menubar__toolSearch .portal-tool-palette__results {
  position: fixed;
  left: auto;
  right: auto;
  top: auto;
  z-index: 210;
}

/* Plan v2 — sandbox selector in menubar center. */
.ide-menubar__sandboxLabel {
  display: inline-flex;
  align-items: center;
  margin-left: 12px;
}
.ide-menubar__sandboxSelect {
  padding: 3px 6px;
  background: var(--input-bg, #0f0f0f);
  color: inherit;
  border: 1px solid var(--panel-border, #2a2a2a);
  border-radius: 3px;
  font-family: inherit;
  font-size: 0.85em;
  cursor: pointer;
}

.ide-visualizationPanel {
  display: flex;
  flex-direction: column;
  min-width: 320px;
  max-width: 50vw;
  background: var(--panel-bg, #1a1a1a);
  border-left: 1px solid var(--panel-border, #2a2a2a);
}
.ide-visualizationPanel[hidden],
.ide-visualizationPanel.is-collapsed {
  display: none;
}
.ide-visualizationPanel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  border-bottom: 1px solid var(--panel-border, #2a2a2a);
}
.ide-visualizationPanel__kicker {
  font-size: 0.7em;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted, #888);
}
.ide-visualizationPanel__title {
  font-size: 0.95em;
  font-weight: 600;
}
.ide-visualizationPanel__close {
  background: transparent;
  color: inherit;
  border: 0;
  font-size: 1.3em;
  cursor: pointer;
  padding: 2px 8px;
  border-radius: 3px;
}
.ide-visualizationPanel__close:hover {
  background: color-mix(in srgb, var(--accent, #6aa) 20%, transparent);
}
.ide-visualizationPanel__content {
  flex: 1;
  overflow: auto;
  padding: 12px;
}
.ide-visualizationPanel__error,
.ide-visualizationPanel__empty {
  font-size: 0.85em;
  color: var(--muted, #888);
}
.ide-visualizationPanel__error {
  color: var(--danger, #d66);
}

/* Multi-tool visualization panel: each selected tool renders in a uniform,
   removable container box (stacked vertically inside the panel aside). */
#portalVisualizationPanelContent {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.ide-visualizationPanel__empty,
.ide-visualizationPanel__error { color: var(--ink2); font-size: 13px; }
.ide-visualizationPanel__error { color: var(--danger, #c0392b); }

/* TXA node-address tree (nested <details>) — indented, navigable, light text. */
/* Composite tool: N sub-tool panes laid out side by side (e.g. agronomics =
   farm_profile | LCL). Fills the vizBox height; each pane scrolls independently.
   On a narrow interface panel the row scrolls horizontally — widen the panel
   (splitter) or collapse the workbench for a roomier side-by-side. */
.v2-composite {
  display: flex;
  gap: 12px;
  align-items: stretch;
  min-height: 0;
  height: 100%;
  overflow-x: auto;
}
.v2-composite__pane {
  flex: 1 1 0;
  min-width: 240px;
  display: flex;
  flex-direction: column;
  min-height: 0;
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
  background: var(--paper2);
}
.v2-composite__paneHeader {
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none; /* a heading is a sentence — see .v2-chart__title */
  color: var(--ink2);
  padding: 4px 8px;
  border-bottom: 1px solid var(--line);
}
.v2-composite__paneBody { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 6px 8px; }
/* A row that may FOLD (payload.wrap): block buttons under a piece of writing. Each pane keeps
   a readable width and the row grows downward instead of scrolling sideways on a phone. */
.v2-composite--wrap { flex-wrap: wrap; height: auto; overflow-x: visible; }
.v2-composite--wrap > .v2-composite__pane { flex: 1 1 240px; }

/* Planting Calendar (PLAN > Planting) — plots (rows) x days (columns) swimlanes.
   ONE grid holds header + gutter + cells + bars, so the columns can never desynchronise; the body
   scrolls on BOTH axes and the gutter/header stick to its edges. z-order: corner > header >
   gutter > bars > cells. */
.v2-pcal { display: flex; flex-direction: column; min-height: 0; height: 100%; }
.v2-pcal__toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 4px 8px;
  border-bottom: 1px solid var(--line);
}
.v2-pcal__nav { display: flex; align-items: center; gap: 2px; }
.v2-pcal__navBtn {
  padding: 1px 8px;
  font-size: 0.8rem;
  color: var(--ink);
  background: var(--paper2);
  border: 1px solid var(--line);
  border-radius: 5px;
  cursor: pointer;
}
.v2-pcal__navBtn:hover { border-color: var(--ink); }
.v2-pcal__today { font-size: 0.72rem; }
.v2-pcal__date, .v2-pcal__sel {
  padding: 1px 4px;
  font-size: 0.76rem;
  color: var(--ink);
  background: var(--paper2);
  border: 1px solid var(--line);
  border-radius: 5px;
}
.v2-pcal__chip, .v2-pcal__jump {
  padding: 1px 8px;
  font-size: 0.74rem;
  color: var(--ink);
  background: var(--paper2);
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
}
.v2-pcal__jump:hover, .v2-pcal__chip:hover { border-color: var(--ink); }
.v2-pcal__counts { margin-left: auto; font-size: 0.72rem; opacity: 0.7; }
.v2-pcal__body { flex: 1 1 auto; min-height: 0; overflow: auto; }
.v2-pcal__grid { display: grid; position: relative; width: max-content; min-width: 100%; }
.v2-pcal__corner {
  position: sticky;
  top: 0;
  left: 0;
  z-index: 4;
  grid-column: 1;
  grid-row: 1;
  padding: 0 6px;
  font-size: 0.68rem;
  line-height: 26px;
  opacity: 0.6;
  background: var(--paper);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.v2-pcal__day {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: 0.6rem;
  line-height: 1.05;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}
.v2-pcal__day.is-weekend { background: var(--paper2); }
.v2-pcal__day.is-today { color: var(--accent); font-weight: 700; }
.v2-pcal__day.is-viewing { box-shadow: inset 0 -2px 0 var(--accent); }
.v2-pcal__dayMon { opacity: 0.45; }
.v2-pcal__gutter {
  position: sticky;
  left: 0;
  z-index: 2;
  grid-column: 1;
  padding: 0 6px;
  overflow: hidden;
  font-size: 0.7rem;
  line-height: 22px;
  text-overflow: ellipsis;
  white-space: nowrap;
  background: var(--paper);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.v2-pcal__gutter.is-occupied { font-weight: 600; }
.v2-pcal__cell { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); cursor: pointer; }
.v2-pcal__cell.is-weekend { background: var(--paper2); }
.v2-pcal__cell.is-viewing { box-shadow: inset 0 0 0 1px rgba(31, 111, 235, 0.35); }
.v2-pcal__cell:hover { background: rgba(31, 111, 235, 0.08); }
.v2-pcal__barItem {
  z-index: 1;
  align-self: center;
  overflow: hidden;
  height: 16px;
  padding: 0 5px;
  font-size: 0.64rem;
  line-height: 16px;
  color: #fff;
  text-overflow: ellipsis;
  white-space: nowrap;
  border-radius: 3px;
  cursor: pointer;
}
/* A planting that starts before / ends after the window squares off that edge, so a clipped bar
   never reads as one that begins or ends here. */
.v2-pcal__barItem.is-clipStart { border-top-left-radius: 0; border-bottom-left-radius: 0; }
.v2-pcal__barItem.is-clipEnd { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.v2-pcal__empty { padding: 14px; font-size: 0.8rem; opacity: 0.65; }

/* farm_profile drill-down map — overall ⇄ field view. The map host is the positioning context for the
   top-left back arrow and the top-right plot-label popup; hovering a polygon "indents" it (thicker
   stroke); faint plots in the overall view are texture only (non-interactive). */
.v2-farm__map { position: relative; }
/* Only the canvas is rewritten on repaint; the map host is stable so the pan/zoom control it owns
   survives. Deliberately UNpositioned so __back / __plotLabel still resolve against __map. */
.v2-farm__canvas { display: block; }
.v2-farm__svg { display: block; cursor: grab; }
.v2-farm__map.is-panning, .v2-farm__map.is-panning .v2-farm__svg { cursor: grabbing; }
.v2-farm__svg polygon { transition: stroke-width 80ms ease; }
.v2-farm__svg polygon.is-hover { stroke-width: 2.5; }
.v2-farm__svg polygon.is-faint { opacity: 0.22; pointer-events: none; }
/* A plot mid-planting on the viewing day (Planting map): hatched so "busy" reads at a glance and
   stays distinct from selection (solid blue). */
.v2-farm__svg polygon.is-occupied { fill: rgba(188, 76, 0, 0.4) !important; stroke: var(--accent) !important; }
.v2-farm__svg polygon[data-fp-cluster] { cursor: pointer; }
.v2-farm__svg polygon[data-fp-role="field"] { cursor: pointer; }
.v2-farm__svg polygon[data-fp-plot] { cursor: pointer; }
.v2-farm__back {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 2;
  padding: 2px 10px;
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper2);
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: pointer;
}
.v2-farm__back:hover { border-color: var(--ink); }
.v2-farm__plotLabel {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 2;
  padding: 2px 8px;
  font-size: 0.8rem;
  color: var(--ink);
  background: var(--paper2);
  border: 1px solid var(--line);
  border-radius: 6px;
  pointer-events: none;
}
.v2-farm__plotLabel[hidden] { display: none; }

/* The network map (`renderNetworkMap`): the county-first ATLAS (`.v2-netmap__map--atlas`,
   `v2_portal_network_atlas.js`) with the chips, type filter, legend, events list and CSA
   strip around it — in a bottom sheet on the Network page, beside it when embedded. */
.v2-netmap { display: flex; flex-direction: column; gap: 8px; min-height: 0; }
.v2-netmap__header { font-size: 0.8rem; color: var(--ink2); }
.v2-netmap__filters { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.v2-netmap__chips { display: flex; flex-wrap: wrap; gap: 4px; }
.v2-netmap__chip {
  padding: 2px 9px;
  font-size: 0.74rem;
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper2);
  border: 1px solid var(--line);
  border-left: 3px solid var(--chip, var(--line));
  border-radius: 999px;
  cursor: pointer;
}
.v2-netmap__chip.is-active { background: var(--ink); color: var(--paper); }
.v2-netmap__count { opacity: 0.65; font-size: 0.68rem; }
/* The farm-type dropdown: a pill button + a checkbox popover. */
.v2-netmap__multi { position: relative; margin-left: auto; }
.v2-netmap__multiBtn {
  padding: 2px 9px;
  font-size: 0.76rem;
  color: var(--ink);
  background: var(--paper2);
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.v2-netmap__multiBtn.is-active { border-color: var(--ink); background: var(--paper); font-weight: 600; }
.v2-netmap__multiN { color: var(--ink2); font-size: 0.7rem; }
.v2-netmap__multiCaret { font-size: 0.6rem; opacity: 0.6; }
.v2-netmap__pop {
  position: absolute;
  z-index: 30;
  top: calc(100% + 4px);
  right: 0;
  min-width: 190px;
  max-height: 260px;
  overflow: auto;
  padding: 6px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
}
.v2-netmap__pop[hidden] { display: none; }
.v2-netmap__popHead { display: flex; gap: 6px; padding: 0 2px 6px; border-bottom: 1px solid var(--line); margin-bottom: 4px; }
.v2-netmap__popHead button {
  flex: 1 1 0; font-size: 0.7rem; padding: 2px 4px; cursor: pointer;
  color: var(--ink); background: var(--paper2); border: 1px solid var(--line); border-radius: 5px;
}
.v2-netmap__mopt {
  display: flex; align-items: center; gap: 6px; padding: 3px 4px; font-size: 0.76rem;
  color: var(--ink); cursor: pointer; border-radius: 5px;
}
.v2-netmap__mopt:hover { background: var(--paper2); }
.v2-netmap__mopt span:first-of-type { flex: 1 1 auto; }
.v2-netmap__popEmpty { font-size: 0.72rem; color: var(--ink2); padding: 4px; }
.v2-netmap__layout { display: flex; gap: 10px; min-height: 0; align-items: stretch; }
.v2-netmap__map { flex: 1 1 62%; min-width: 0; position: relative; }
/* EMBEDDED (the registrar portal's pane, the agronomics NETWORK tab): the atlas fills its
   host, so a figure in a document gives it a height here; the index of places sits under it. */
.v2-netmap__figure { flex: 1 1 62%; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.v2-netmap__figure > .v2-netmap__map--atlas {
  flex: 0 0 auto; height: clamp(320px, 58vh, 560px);
  border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
}
.v2-netmap__defs { position: absolute; }
.v2-netmap__groundNote { margin: 0; padding: 12px; }

/* Zoom controls overlaid on any map div (which is position: relative). */
.v2-mapZoom { position: absolute; top: 8px; right: 8px; display: flex; flex-direction: column; gap: 4px; z-index: 3; }
.v2-mapZoom__btn { width: 26px; height: 26px; display: flex; align-items: center; justify-content: center; padding: 0; font: inherit; font-size: 16px; line-height: 1; border: 1px solid var(--line, #d8dee4); border-radius: 6px; background: var(--ide-panel-bg, #fff); color: var(--ink2); cursor: pointer; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.14); }
.v2-mapZoom__btn:hover { background: var(--paper2); color: var(--ink); }
.v2-netmap__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  font-size: 0.7rem;
  color: var(--ink2);
}
.v2-netmap__legendItem { display: inline-flex; gap: 3px; align-items: center; }
.v2-netmap__legendSep { width: 1px; height: 12px; background: var(--line); }
.v2-netmap__legendLabel { font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; font-size: 0.62rem; opacity: 0.75; }
.v2-netmap__swatch { width: 11px; height: 11px; border-radius: 3px; flex: 0 0 auto; }
.v2-netmap__eventDot {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  margin-top: 4px;
  border: 1px solid var(--line);
  border-radius: 2px;
  transform: rotate(45deg);
}
.v2-netmap__events { flex: 1 1 38%; min-width: 200px; max-height: 380px; overflow: auto; }
.v2-netmap__eventsTitle {
  margin: 0 0 4px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink2);
}
.v2-netmap__hostFilter {
  font-size: 0.74rem;
  color: var(--ink2);
  padding: 2px 6px;
  margin-bottom: 4px;
  background: var(--paper2);
  border: 1px solid var(--line);
  border-radius: 6px;
}
.v2-netmap__hostFilter button { border: 0; background: none; cursor: pointer; color: var(--ink); }
.v2-netmap__eventList { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; }
.v2-netmap__eventList[hidden], .v2-netmap__cal[hidden] { display: none; }
.v2-netmap__event {
  display: flex;
  gap: 7px;
  align-items: flex-start;
  padding: 5px 7px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--line);
  border-radius: 7px;
}
.v2-netmap__event.is-hidden { display: none; }
.v2-netmap__eventGlyph { flex: 0 0 auto; margin-top: 2px; }
.v2-netmap__evToggles { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 6px; }
.v2-netmap__evToggle {
  display: inline-flex;
  gap: 4px;
  align-items: center;
  padding: 2px 8px;
  font-size: 0.72rem;
  color: var(--ink);
  background: var(--paper2);
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
}
.v2-netmap__evToggle.is-active { background: var(--ink); color: var(--paper); }
.v2-netmap__eventsHead { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.v2-netmap__viewSwitch { display: inline-flex; border: 1px solid var(--line); border-radius: 7px; overflow: hidden; }
.v2-netmap__viewBtn {
  padding: 1px 9px;
  font-size: 0.72rem;
  color: var(--ink);
  background: var(--paper2);
  border: 0;
  cursor: pointer;
}
.v2-netmap__viewBtn + .v2-netmap__viewBtn { border-left: 1px solid var(--line); }
.v2-netmap__viewBtn.is-active { background: var(--ink); color: var(--paper); }
.v2-netmap__calHead { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 5px; }
.v2-netmap__calTitle { font-size: 0.82rem; font-weight: 700; min-width: 120px; text-align: center; }
.v2-netmap__calNav {
  padding: 0 9px;
  font-size: 0.9rem;
  color: var(--ink);
  background: var(--paper2);
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: pointer;
}
.v2-netmap__calGrid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.v2-netmap__calDow { font-size: 0.66rem; text-align: center; color: var(--ink2); padding: 1px 0; }
.v2-netmap__calCell {
  min-height: 34px;
  padding: 2px 3px;
  background: var(--paper2);
  border: 1px solid var(--line);
  border-radius: 5px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.v2-netmap__calCell.is-blank { background: transparent; border-color: transparent; cursor: default; }
.v2-netmap__calCell.is-today { border-color: var(--ink); }
.v2-netmap__calCell.is-selected { outline: 2px solid var(--ink); outline-offset: -1px; }
.v2-netmap__calCell.has-events:hover { border-color: var(--ink2); }
.v2-netmap__calNum { font-size: 0.68rem; color: var(--ink2); line-height: 1; }
.v2-netmap__calMarks { display: flex; flex-wrap: wrap; gap: 2px; align-items: center; }
.v2-netmap__calMark {
  width: 8px;
  height: 8px;
  border: 1px solid var(--line);
  border-radius: 2px;
}
.v2-netmap__calMore { font-size: 0.62rem; color: var(--ink2); }
.v2-netmap__calOngoing {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
  margin-top: 6px;
  font-size: 0.74rem;
}
.v2-netmap__calChip {
  padding: 1px 7px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--line);
  border-radius: 6px;
  font-size: 0.72rem;
}
.v2-netmap__calDetail { margin-top: 7px; }
.v2-netmap__eventDate { flex: 0 0 auto; font-size: 0.74rem; font-variant-numeric: tabular-nums; color: var(--ink2); min-width: 78px; }
.v2-netmap__eventBody { display: flex; flex-direction: column; font-size: 0.8rem; min-width: 0; }
.v2-netmap__eventMeta { font-size: 0.72rem; color: var(--ink2); }
.v2-netmap__empty { font-size: 0.8rem; color: var(--ink2); }
.v2-netmap__csas { margin-top: 4px; }
.v2-netmap__csaGrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 8px;
}
.v2-netmap__csaCard {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 7px 9px;
  font-size: 0.8rem;
  background: var(--paper2);
  border: 1px solid var(--line);
  border-left: 3px solid var(--line);
  border-radius: 8px;
}
.v2-netmap__csaCard.is-hidden { display: none; }
.v2-netmap__csaPickup { display: flex; gap: 6px; align-items: flex-start; }
.v2-netmap__csaPickup .v2-netmap__eventDot { margin-top: 3px; }
.v2-netmap__csaPickup .v2-netmap__eventMeta { display: block; }
.v2-netmap__csaLink { font-size: 0.72rem; color: var(--ink2); text-decoration: none; }
.v2-netmap__csaLink:hover { text-decoration: underline; }
@media (max-width: 860px) {
  .v2-netmap__layout { flex-direction: column; }
  .v2-netmap__events { max-height: 240px; }
}

/* Control-panel Sources section — the per-sandbox pins { margin: 10px 0; font-size: 12px; }

/* The Compendium folder UI (2026-08-16): breadcrumb bar, sandbox-folder shelf,
   document gallery/list, and the open document's face. Tiles speak file-manager:
   selected state on aria-selected, focus visible, double-click opens. */
.v2-compendium { display: flex; flex-direction: column; min-height: 100%; }
.v2-compendium__bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  background: var(--paper2, #e8e5d0);
  border-bottom: 1px solid var(--line, #afafaa);
}
.v2-compendium__crumbs { display: flex; align-items: center; gap: 6px; min-width: 0; flex-wrap: wrap; }
.v2-compendium__crumb {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink2, #888);
  text-decoration: none;
  padding: 2px 6px;
  border-radius: 4px;
  white-space: nowrap;
}
.v2-compendium__crumb:hover { color: var(--ink, #464646); background: rgba(0, 0, 0, 0.06); }
.v2-compendium__crumb.is-current { color: var(--ink, #464646); cursor: default; }
.v2-compendium__sep { color: var(--ink2, #888); }
.v2-compendium__toggles { display: inline-flex; border: 1px solid var(--line, #afafaa); border-radius: 6px; overflow: hidden; }
.v2-compendium__toggle {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--ink2, #888);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 4px 12px;
  cursor: pointer;
}
.v2-compendium__toggle + .v2-compendium__toggle { border-left: 1px solid var(--line, #afafaa); }
.v2-compendium__toggle.is-active { background: var(--paper, #f0eedc); color: var(--ink, #464646); }
.v2-compendium__toggle[disabled],
.v2-compendium__toggle[aria-disabled="true"] { opacity: 0.45; cursor: default; }
.v2-compendium__note { font-size: 12px; color: var(--ink2, #888); max-width: 46ch; text-align: right; }
.v2-compendium__toolbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px 0;
}
.v2-compendium__toolbar [data-role="doc-filter"] {
  flex: 0 1 320px;
  padding: 5px 10px;
  border: 1px solid var(--line, #afafaa);
  border-radius: 6px;
  background: var(--paper, #f0eedc);
  color: inherit;
  font: inherit;
  font-size: 13px;
}
.v2-compendium__glyph { width: 40px; height: 40px; color: var(--accent, #1e6c93); }
.v2-compendium__glyph--folder { color: var(--ink2, #888); }
.v2-compendium__name { font-size: 13px; font-weight: 600; word-break: break-word; }
.v2-compendium__meta { font-size: 11px; color: var(--ink2, #888); }
.v2-compendium__anchorTag {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--accent, #1e6c93);
  border: 1px solid currentColor;
  border-radius: 4px;
  padding: 0 4px;
  vertical-align: middle;
}
.v2-compendium__list { width: 100%; border-collapse: collapse; margin: 12px 0; font-size: 13px; }
.v2-compendium__list th {
  text-align: left;
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink2, #888);
  padding: 6px 14px;
  border-bottom: 1px solid var(--line, #afafaa);
}
.v2-compendium__row td { padding: 7px 14px; border-bottom: 1px solid rgba(0, 0, 0, 0.06); }
.v2-compendium__row:hover { background: rgba(0, 0, 0, 0.04); }
.v2-compendium__row[aria-selected="true"] { background: rgba(30, 108, 147, 0.12); }
.v2-compendium__row:focus-visible { outline: 2px solid var(--accent, #1e6c93); outline-offset: -2px; }
.v2-compendium__row .v2-compendium__glyph { width: 16px; height: 16px; vertical-align: -3px; margin-right: 8px; }
.v2-compendium__empty,
.v2-compendium__filterEmpty { color: var(--ink2, #888); padding: 20px 14px; }
.v2-compendium__face { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 12px 14px; }

/* The SANDBOX VIEW's domain face is full bleed (operator, 2026-08-20: "the entire
   surface of tab given area"). No padding and no scroll: the plane pans, and a
   scrolling ancestor would clip the pan rather than move it -- the same lesson the
   full-bleed tree learned on 2026-08-19. */
.v2-compendium__face--plane { padding: 0; overflow: hidden; }

/* ── THE INSTANCE TREE (2026-10-18) ─────────────────────────────────────────────
   The landing draws the shape a sandbox opens into, one level up: the instance is the
   root, each sandbox a branch wearing the database-server glyph. The connectors are the
   domain plane's own hairlines, and a branch's lit spine means what a lit spine means on
   the plane — something is behind it (here: a local domain to open into). A sandbox with
   none wears a dashed spine and says so in words. */
.v2-compendium__tree {
  display: grid;
  grid-template-columns: max-content minmax(0, 40rem);
  align-items: center;
  padding: 18px 14px 32px;
}
.v2-compendium__treeRoot {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  margin-right: 28px;
  padding: 10px 14px 10px 12px;
  border: 1px solid var(--line, #afafaa);
  border-radius: 5px;
  background: var(--paper2, #e8e5d0);
  color: var(--ink, #464646);
}
/* The root's own connector, out to the spine. */
.v2-compendium__treeRoot::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -29px;
  width: 28px;
  border-top: 1px solid var(--line, #afafaa);
}
.v2-compendium__treeRoot .v2-compendium__glyph { width: 26px; height: 26px; color: var(--ink2, #888); }
.v2-compendium__treeRootText { display: flex; flex-direction: column; gap: 1px; }
.v2-compendium__treeRootName { font-size: 13px; font-weight: 600; }
.v2-compendium__treeRootMsn {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 10.5px;
  color: var(--ink2, #888);
}
.v2-compendium__treeRootCount { font-size: 12px; color: var(--ink2, #888); }
.v2-compendium__branches { list-style: none; margin: 0; padding: 0; }
.v2-compendium__branch { position: relative; padding: 4px 0 4px 24px; }
/* The spine runs from the first branch's middle to the last one's; each branch takes a
   tick off it. */
.v2-compendium__branch::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-left: 1px solid var(--line, #afafaa);
}
.v2-compendium__branch:first-child::before { top: 50%; }
.v2-compendium__branch:last-child::before { bottom: 50%; }
.v2-compendium__branch:only-child::before { display: none; }
.v2-compendium__branch::after {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 24px;
  border-top: 1px solid var(--line, #afafaa);
}
.v2-compendium__sandbox {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 10px 14px 10px 15px;
  border: 1px solid var(--line, #afafaa);
  border-radius: 5px;
  background: var(--paper, #f0eedc);
  color: var(--ink, #464646);
  text-decoration: none;
  overflow: hidden;
}
.v2-compendium__sandbox::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--accent, #1e6c93);
}
.v2-compendium__sandbox.is-flat::before {
  background: repeating-linear-gradient(
    to bottom, var(--ink2, #888) 0 4px, transparent 4px 8px);
  opacity: 0.6;
}
.v2-compendium__sandbox:hover,
.v2-compendium__sandbox[aria-selected="true"] { border-color: var(--accent2, var(--accent, #1e6c93)); }
.v2-compendium__sandbox:focus-visible {
  outline: 2px solid var(--accent2, var(--accent, #1e6c93));
  outline-offset: 2px;
}
.v2-compendium__sandbox .v2-compendium__glyph {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  margin-top: 1px;
  color: var(--accent, #1e6c93);
}
.v2-compendium__sandbox.is-flat .v2-compendium__glyph { color: var(--ink2, #888); }
.v2-compendium__sandboxBody { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 auto; }
.v2-compendium__sandboxHead { display: flex; align-items: baseline; gap: 12px; }
.v2-compendium__sandbox .v2-compendium__name { font-size: 14px; font-weight: 600; }
.v2-compendium__sandboxCount {
  margin-left: auto;
  flex: 0 0 auto;
  font-size: 12px;
  color: var(--ink2, #888);
  font-variant-numeric: tabular-nums;
}
.v2-compendium__purpose,
.v2-compendium__flatNote { font-size: 12.5px; line-height: 1.4; color: var(--ink2, #888); max-width: 62ch; }
.v2-compendium__flatNote { font-style: italic; }

@media (max-width: 700px) {
  /* The root sits on top and the spine runs down the left gutter. */
  .v2-compendium__tree { grid-template-columns: minmax(0, 1fr); padding: 12px 10px 24px; }
  .v2-compendium__treeRoot { margin: 0 0 12px; justify-self: start; }
  .v2-compendium__treeRoot::after {
    top: 100%;
    right: auto;
    left: 18px;
    width: 0;
    height: 13px;
    border-top: 0;
    border-left: 1px solid var(--line, #afafaa);
  }
  .v2-compendium__branches { margin-left: 18px; }
  .v2-compendium__branch { padding-left: 16px; }
  .v2-compendium__branch::after { width: 16px; }
  .v2-compendium__branch:first-child::before { top: 0; }
  .v2-compendium__branch:only-child::before { display: block; bottom: 50%; }
  .v2-compendium__sandbox { padding: 10px 12px 10px 14px; gap: 10px; }
  .v2-compendium__sandbox .v2-compendium__glyph { width: 24px; height: 24px; }
}

/* ── WHAT THE TREE DOES NOT REACH (level 1, domain face) ──────────────────────
   A closed tray between the bar and the plane. Its body floats OVER the plane: the plane
   measures its own height once, and a tray that pushed it down would cut off its foot. */
.v2-compendium__unfiled {
  position: relative;
  flex: 0 0 auto;
  z-index: 6;
  border-bottom: 1px solid var(--line, #afafaa);
  background: var(--paper2, #e8e5d0);
}
.v2-compendium__unfiled > summary {
  padding: 7px 14px;
  font-size: 12.5px;
  color: var(--ink2, #888);
  cursor: pointer;
}
.v2-compendium__unfiled > summary:hover,
.v2-compendium__unfiled[open] > summary { color: var(--ink, #464646); }
.v2-compendium__unfiled > summary:focus-visible { outline: 2px solid var(--accent2, var(--accent, #1e6c93)); outline-offset: -2px; }
.v2-compendium__unfiledBody {
  position: absolute;
  top: 100%;
  left: 10px;
  right: 10px;
  max-height: min(60vh, 32rem);
  overflow: auto;
  padding: 10px 12px 12px;
  border: 1px solid var(--line, #afafaa);
  border-top: 0;
  border-radius: 0 0 6px 6px;
  background: var(--paper, #f0eedc);
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.22);
}
.v2-compendium__unfiledWhy,
.v2-compendium__unfiledMore { margin: 0 0 8px; font-size: 12px; color: var(--ink2, #888); max-width: 70ch; }
.v2-compendium__unfiledMore { margin: 8px 0 0; }
.v2-compendium__unfiledMore a { color: var(--accent, #1e6c93); }
.v2-compendium__unfiledList {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 2px 12px;
}
.v2-compendium__unfiledDoc {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 36px;
  padding: 4px 8px;
  border-radius: 4px;
  color: var(--ink, #464646);
  text-decoration: none;
}
.v2-compendium__unfiledDoc:hover { background: rgba(0, 0, 0, 0.06); }
.v2-compendium__unfiledDoc:focus-visible { outline: 2px solid var(--accent2, var(--accent, #1e6c93)); outline-offset: -2px; }
.v2-compendium__unfiledDoc .v2-compendium__glyph { flex: 0 0 auto; width: 16px; height: 16px; }
.v2-compendium__unfiledTitle { font-size: 13px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-compendium__unfiledKind { margin-left: auto; flex: 0 0 auto; font-size: 11.5px; color: var(--ink2, #888); }
/* The list face standing in for a domain the sandbox does not have. */
.v2-compendium__domainNote {
  margin: 10px 14px 0;
  padding: 8px 12px;
  border-left: 3px solid var(--ink2, #888);
  font-size: 12.5px;
  color: var(--ink2, #888);
  max-width: 72ch;
}

/* ── INSTRUMENTS: the shelf's second band ──────────────────────────────────────
   An instrument is a peer of a sandbox, not a promotion of one, so its label is set
   at the folder tile's own size and weight. What differs is the SHAPE: a folder is a
   closed box, an instrument is a card that spans -- it draws the sandboxes it reads
   along its foot, so an instrument over three and an instrument over one cannot look
   alike. Violet is the shelf's only one, which is what says "not a sandbox" before
   the label is read. */
.v2-compendium__bandHead {
  margin: 18px 14px 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink2, #888);
}
.v2-compendium__band {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
  gap: 10px;
  padding: 8px 14px 16px;
}
.v2-compendium__instrument {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px;
  border: 1px solid var(--line, #afafaa);
  border-left: 3px solid var(--v2-instrument, #6f5bd6);
  border-radius: 8px;
  background: var(--paper, #f0eedc);
  color: inherit;
  text-decoration: none;
}
.v2-compendium__instrument:hover { background: rgba(111, 91, 214, 0.08); }
.v2-compendium__instrument:focus-visible {
  outline: 2px solid var(--v2-instrument, #6f5bd6);
  outline-offset: 2px;
}
.v2-compendium__instrumentHead { display: flex; align-items: center; gap: 8px; }
.v2-compendium__instrumentHead .v2-compendium__glyph {
  width: 22px;
  height: 22px;
  color: var(--v2-instrument, #6f5bd6);
}
.v2-compendium__instrumentWhy { font-size: 12px; color: var(--ink2, #888); }

/* ===== The Gadgets gallery (2026-08-21) ====================================
   The launcher page apps and instruments moved to. Cards reuse the Compendium
   band vocabulary above; only the page's own frame is new. The divider is the
   depiction's "thin floating divider": a hairline that stops short of the
   edges, floating between the two groups rather than ruling the page. */
.v2-gadgets { padding: 16px 8px 32px; }
.v2-gadgets__groupHead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 0 10px;
}
.v2-gadgets__groupHead .v2-compendium__bandHead { margin: 0; }
.v2-gadgets__manage { font-size: 12px; white-space: nowrap; }
.v2-gadgets__divider {
  border: 0;
  height: 1px;
  margin: 20px 28px;
  background: var(--line);
  opacity: 0.8;
}

/* --- The gallery is a TILE GRID (operator, 2026-08-28) ---------------------
   "It should be a simple design with icons as the gallery items with perhaps
   minimal labels below each icon, and headers for Applications and Instruments."

   So the gallery stops using the Compendium band's card vocabulary. A card is
   for reading — icon, name, a sentence of summary, a row of sandbox chips — and
   at eight apps and six instruments that is fourteen paragraphs on a page whose
   only job is "open one of these". A tile is for aiming at.

   The label stays. An icon grid with no words is a memory test, and these icons
   are not yet conventional enough for one. It sits UNDER the icon, small, and
   wraps rather than truncating: a name clipped to "Boutique Hom..." is the same
   problem the summary was. */
.v2-gadgets__tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 8px;
  padding: 8px 14px 16px;
}

/* THE PIN SITS BESIDE THE TILE, NOT INSIDE IT (2026-10-26). A <button> nested in an
   <a> is invalid markup and swallows the Enter key the tile itself answers, so the grid
   item is now this cell and the tile fills it; the pin is positioned over its corner.
   The cell carries `role="listitem"` because the tile stopped being the list's child. */
.v2-gadgets__cell {
  position: relative;
  display: flex;
}
.v2-gadgets__cell > .v2-gadgets__tile {
  flex: 1 1 auto;
  width: 100%;
}
.v2-gadgets__tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  padding: 16px 8px 12px;
  border: 1px solid var(--line, #afafaa);
  border-radius: 10px;
  background: var(--paper, #f0eedc);
  color: inherit;
  text-decoration: none;
  text-align: center;
  min-height: 96px;
}
.v2-gadgets__tile:hover { background: rgba(111, 91, 214, 0.08); }
.v2-gadgets__tile:focus-visible {
  outline: 2px solid var(--v2-instrument, #6f5bd6);
  outline-offset: 2px;
}
.v2-gadgets__tile .v2-compendium__glyph {
  width: 34px;
  height: 34px;
  color: var(--v2-instrument, #6f5bd6);
}
.v2-gadgets__tileLabel {
  font-size: 12px;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

/* The pin: a star in the tile's top-right. A star rather than a word because the label
   underneath is already the only text a tile carries and the operator called reading matter
   on this page "way too much information and text". Hollow = not pinned, filled = pinned,
   and `aria-pressed` carries the state for anyone who cannot see the difference.

   28px square: smaller than the 44px a touch target wants, and deliberately — the TILE is
   the touch target, and a 44px control over a 96px tile would be a quarter of it. On a
   phone it grows (below), where there is no hover to reveal anything and a thumb is the
   only pointer. */
.v2-gadgets__pin {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  color: var(--ink2, #888888);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}
.v2-gadgets__pin:hover {
  background: var(--paper2, #e8e5d0);
  color: var(--ink, #464646);
}
.v2-gadgets__pin.is-pinned { color: var(--accent, #1e6c93); }
.v2-gadgets__pin:focus-visible {
  outline: 2px solid var(--v2-instrument, #6f5bd6);
  outline-offset: 1px;
}
.v2-gadgets__pin[disabled] { opacity: 0.5; cursor: default; }
/* The one gadget that cannot be pinned says so on hover rather than looking broken: the
   rail's footer already draws Profile at the column's actual bottom. */
.v2-gadgets__pinFixed {
  position: absolute;
  top: 8px;
  right: 10px;
  color: var(--ink2, #888888);
  font-size: 13px;
  line-height: 1;
}

/* What the bar holds, and the pins the page cannot draw. Both are statements with a
   remedy in them, set small and above the shelf so neither becomes the page's subject. */
.v2-gadgets__pinState,
.v2-gadgets__pinNote {
  margin: 4px 12px 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--ink2, #888888);
}
.v2-gadgets__pinNote {
  color: var(--held, #b5762a);
}
.v2-gadgets__pinNote strong { color: inherit; }

/* A phone fits three across at this size; the tile is already the shape a touch
   target wants, so only the column floor moves. */
@media (max-width: 720px) {
  .v2-gadgets__tiles { grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); gap: 6px; }
  .v2-gadgets__tile { min-height: 84px; padding: 12px 6px 10px; }
  /* No hover on a thumb, so the control has to be reachable at rest. */
  .v2-gadgets__pin { width: 34px; height: 34px; font-size: 17px; }
}

/* ===== The marketplace: Utilities > Find gadgets (2026-10-18) ==============
   Operator: "the place I'd want people to find gadgets … making it clear what is
   what". Portal tokens only, so every theme carries it. The one bold move is the
   KIND KEY — the glossary and the filter are the same buttons; everything around
   it stays quiet. Installed state is a moss rule on the card's edge, not a badge.
   No motion: nothing animates, so there is nothing to reduce. */
.v2-market { padding: 14px 14px 40px; max-width: 1180px; color: var(--ink); }
.v2-market__source { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; }
.v2-market__sourceLine { margin: 0; font-size: 13px; font-weight: 600; }
.v2-market__sourceDot {
  display: inline-block; width: 8px; height: 8px; margin-right: 8px;
  border-radius: 50%; background: var(--line); vertical-align: 1px;
}
.v2-market__sourceDot--published { background: var(--moss); }
.v2-market__sourceNote { flex-basis: 100%; margin: 0; font-size: 12.5px; color: var(--ink2, var(--ink)); max-width: 72ch; }
.v2-market__sourceNote:empty { display: none; }
.v2-market__sourceRepo { flex-basis: 100%; margin: 0; font-size: 12.5px; }
.v2-market__check,
.v2-market__reset,
.v2-market__overlayClose {
  min-height: 36px; padding: 0 14px; border: 1px solid var(--line); border-radius: 999px;
  background: transparent; color: var(--ink); font: inherit; font-size: 13px; cursor: pointer;
}
.v2-market__check:disabled { opacity: 0.6; cursor: progress; }
.v2-market__promise { margin: 10px 0 18px; font-size: 13px; line-height: 1.5; color: var(--ink2, var(--ink)); max-width: 78ch; }

.v2-market__key {
  display: grid; grid-template-columns: minmax(110px, 0.6fr) repeat(5, minmax(0, 1fr));
  gap: 8px; margin: 0 0 10px;
}
.v2-market__keyItem {
  display: grid; grid-template-columns: 1fr auto; align-content: start; gap: 4px 10px;
  padding: 11px 13px 12px; border: 1px solid var(--line); border-radius: 10px;
  background: transparent; color: var(--ink); font: inherit; text-align: left; cursor: pointer;
}
.v2-market__keyItem:hover { background: color-mix(in srgb, var(--accent) 6%, transparent); }
.v2-market__keyItem[aria-pressed="true"] {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
  background: color-mix(in srgb, var(--accent) 9%, transparent);
}
.v2-market__keyName { font-size: 15px; font-weight: 600; }
.v2-market__keyCount { font-size: 13px; font-variant-numeric: tabular-nums; color: var(--ink2, var(--ink)); }
.v2-market__keyDef { grid-column: 1 / -1; font-size: 12.5px; line-height: 1.4; color: var(--ink2, var(--ink)); }

.v2-market__show { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 16px; }
.v2-market__showItem {
  min-height: 36px; padding: 0 13px; border: 1px solid var(--line); border-radius: 999px;
  background: transparent; color: var(--ink); font: inherit; font-size: 13px; cursor: pointer;
}
.v2-market__showItem[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); font-weight: 600; }
.v2-market__empty[hidden],
.v2-market__card[hidden] { display: none; }
.v2-market__empty { font-size: 13px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.v2-market__shelf {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 12px;
}
.v2-market__card {
  display: flex; flex-direction: column; gap: 8px;
  padding: 14px 16px 14px 15px; border: 1px solid var(--line); border-left: 3px solid var(--line);
  border-radius: 10px; background: var(--paper);
}
.v2-market__card[data-market-installed="yes"] { border-left-color: var(--moss); }
/* lineage (2026-10-19): a descendant sits under its core app, stepped in, its left rule
   dashed; the line under the name says which way the relationship runs */
.v2-market__card--descendant { margin-left: 1.25rem; border-left-style: dashed; }
.v2-market__lineage { margin: -4px 0 0; font-size: 12px; color: var(--ink2, var(--ink)); }
@media (max-width: 40rem) { .v2-market__card--descendant { margin-left: 0.6rem; } }
.v2-market__card[data-market-status="update"] { border-left-color: var(--accent); }
.v2-market__cardHead { display: flex; align-items: center; gap: 10px; }
.v2-market__cardHead .v2-compendium__glyph { width: 28px; height: 28px; flex: none; color: var(--v2-instrument, var(--accent)); }
.v2-market__name { margin: 0; font-size: 16px; font-weight: 600; line-height: 1.25; }
.v2-market__kind { margin-left: auto; font-size: 12px; color: var(--ink2, var(--ink)); }
.v2-market__status { margin: 0; font-size: 12.5px; font-weight: 600; color: var(--ink2, var(--ink)); }
.v2-market__card[data-market-installed="yes"] .v2-market__status { color: var(--moss); }
.v2-market__card[data-market-status="update"] .v2-market__status { color: var(--accent); }
.v2-market__does { margin: 0; font-size: 13.5px; line-height: 1.5; }
.v2-market__more { font-size: 12.5px; line-height: 1.5; color: var(--ink2, var(--ink)); }
.v2-market__more summary { cursor: pointer; color: var(--accent); }
.v2-market__more p { margin: 6px 0 0; }
.v2-market__facts { margin: 2px 0 0; display: grid; gap: 6px; }
.v2-market__fact { display: grid; grid-template-columns: 74px 1fr; gap: 10px; font-size: 12.5px; line-height: 1.45; }
.v2-market__fact dt { color: var(--ink2, var(--ink)); }
.v2-market__fact dd { margin: 0; overflow-wrap: anywhere; }
.v2-market__needs { margin: 0; padding: 0; list-style: none; display: grid; gap: 3px; }
.v2-market__actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: auto; padding-top: 4px; }
.v2-market__action {
  display: inline-flex; align-items: center; min-height: 36px; padding: 0 16px;
  border: 1px solid var(--line); border-radius: 999px; font-size: 13px;
  color: var(--ink); text-decoration: none;
}
.v2-market__action--primary { background: var(--accent); border-color: var(--accent); color: var(--accent-fg, #fff); font-weight: 600; }
/* The card's own Install (an extension: nothing to choose) is a BUTTON wearing the action's
   look; a button carries the browser's font and cursor unless told otherwise. */
button.v2-market__action { font: inherit; font-size: 13px; cursor: pointer; }
/* `font: inherit` above resets the weight a primary action carries, so a button wearing the
   primary look restates it. */
button.v2-market__action--primary { font-weight: 600; }
button.v2-market__action:disabled { opacity: 0.6; cursor: default; }
/* What installing creates — one line, before the button that does it. */
.v2-market__creates { margin: 0; font-size: 12.5px; line-height: 1.45; color: var(--ink2, var(--ink)); }
.v2-market__installStatus { flex-basis: 100%; margin: 0; font-size: 12.5px; color: var(--ink2, var(--ink)); }
.v2-market__installStatus[hidden] { display: none; }

.v2-market__rest { margin-top: 36px; padding-top: 18px; border-top: 1px solid var(--line); }
.v2-market__restHead { margin: 0 0 12px; font-size: 15px; font-weight: 600; }
.v2-market__rest > .v2-market__restGroup { margin-bottom: 14px; }
.v2-market__rest { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 0 28px; }
.v2-market__restHead { grid-column: 1 / -1; }
.v2-market__restGroupName { margin: 0 0 6px; font-size: 13px; font-weight: 600; color: var(--ink2, var(--ink)); }
.v2-market__restGroup ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
.v2-market__restGroup li { display: grid; gap: 2px; font-size: 13px; }
.v2-market__restJob { font-size: 12.5px; line-height: 1.4; color: var(--ink2, var(--ink)); }

.v2-market__keyItem:focus-visible,
.v2-market__showItem:focus-visible,
.v2-market__check:focus-visible,
.v2-market__reset:focus-visible,
.v2-market__action:focus-visible,
.v2-market__more summary:focus-visible,
.v2-market__fact a:focus-visible,
.v2-market__sourceRepo a:focus-visible,
.v2-market__overlayOut:focus-visible,
.v2-market__overlayClose:focus-visible,
.v2-market__rest a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The overlay (2026-11-08): one <dialog> for every preview and every web tool that can be
   framed. The frame fills the dialog under a bar naming what is shown. The dialog has no
   padding, so a click outside the bar and frame lands on the backdrop — which is how a click
   there closes it. */
.v2-market__overlay {
  width: min(1180px, calc(100vw - 32px)); height: min(880px, calc(100vh - 32px));
  max-width: none; max-height: none; padding: 0;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--paper); color: var(--ink); overflow: hidden;
}
.v2-market__overlay[open] { display: flex; flex-direction: column; }
.v2-market__overlay::backdrop { background: rgba(0, 0, 0, 0.45); }
.v2-market__overlayBar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px;
  padding: 10px 14px; border-bottom: 1px solid var(--line);
}
.v2-market__overlayHead { flex: 1 1 260px; min-width: 0; }
.v2-market__overlayTitle { margin: 0; font-size: 15px; font-weight: 600; line-height: 1.3; }
.v2-market__overlayShows { margin: 2px 0 0; font-size: 12.5px; line-height: 1.4; color: var(--ink2, var(--ink)); max-width: 90ch; }
.v2-market__overlayShows:empty { display: none; }
.v2-market__overlayOut { font-size: 13px; color: var(--accent); }
.v2-market__overlayFrame { flex: 1; width: 100%; min-height: 0; border: 0; background: var(--paper); }

@media (max-width: 900px) {
  .v2-market__key { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .v2-market__keyItem--all { grid-column: 1 / -1; }
}
/* The Utilities nav opens a gap where a group of tabs starts (get gadgets, connect
   services, work with others). Entries without a group draw as before. */
.v2-sectionNav__item--groupStart { margin-left: 12px; }
.v2-market__keyNow { display: none; }
/* On a phone the key folds into a row of names you can swipe, and the definition of
   the kind you picked sits under it — the glossary still answers, one kind at a time,
   instead of pushing the shelf five screens down. */
@media (max-width: 520px) {
  .v2-market { padding: 10px 10px 32px; }
  .v2-market__key {
    display: flex; gap: 6px; overflow-x: auto; margin: 0 -10px 6px; padding: 2px 10px 6px;
    scrollbar-width: thin;
  }
  .v2-market__keyItem { flex: none; grid-template-columns: auto auto; padding: 8px 12px; border-radius: 999px; }
  .v2-market__keyName { font-size: 14px; }
  .v2-market__keyDef { display: none; }
  .v2-market__keyNow { display: block; margin: 0 0 12px; font-size: 12.5px; line-height: 1.45; color: var(--ink2, var(--ink)); }
  .v2-market__shelf { grid-template-columns: 1fr; }
  .v2-sectionNav__item--groupStart { margin-left: 0; }
  .v2-market__overlay { width: 100vw; height: 100vh; border: 0; border-radius: 0; }
}


/* ===== The instance, drawn: Utilities > Instance (2026-11-08) ================
   The operator's drawing of 2026-11-05. Portal tokens only, so every theme carries it.
   The figure scrolls inside itself on a phone instead of shrinking its words to nothing;
   the page never scrolls sideways. A socket's state is its stroke: working is moss,
   waiting to be allowed is a dashed ink line (the correct resting state, not a fault),
   open is a plain rule. STATIC is the same figure unlit, with nothing to hover. */
.v2-diagram { margin: 0 0 22px; }
.v2-diagram__scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: 12px; background: var(--paper); }
.v2-diagram__svg { display: block; width: 100%; min-width: 720px; height: auto; color: var(--ink); }
.v2-diagram__caption { margin: 8px 2px 0; font-size: 12.5px; line-height: 1.45; color: var(--ink2, var(--ink)); }
.v2-diagram__instance { stroke: var(--ink2, var(--ink)); stroke-width: 1.5; fill: color-mix(in srgb, var(--accent) 3%, transparent); }
.v2-diagram__wave { stroke: var(--ink2, var(--ink)); stroke-width: 1.2; stroke-dasharray: 1 0; }
.v2-diagram__head { fill: var(--ink2, var(--ink)); font-size: 12px; font-weight: 600; }
.v2-diagram__note { fill: var(--ink2, var(--ink)); font-size: 12px; }
.v2-diagram__label { fill: var(--ink); font-size: 13px; font-weight: 600; }
.v2-diagram__state { fill: var(--ink2, var(--ink)); font-size: 11.5px; }
.v2-diagram__app,
.v2-diagram__sandbox,
.v2-diagram__provider { fill: var(--paper); stroke: var(--line); stroke-width: 1.2; }
.v2-diagram__glyph { color: var(--v2-instrument, var(--accent)); }
.v2-diagram__tie { stroke: var(--line); stroke-width: 1; }
.v2-diagram__employs { stroke: var(--ink2, var(--ink)); stroke-width: 1; opacity: 0.55; }
.v2-diagram__band { fill: var(--paper); stroke: var(--line); stroke-width: 1; }
.v2-diagram__plug { fill: var(--paper); stroke: var(--ink2, var(--ink)); stroke-width: 1.4; }
.v2-diagram__pin { fill: var(--ink2, var(--ink)); }
.v2-diagram__badge { stroke: var(--accent); stroke-width: 1.5; }
.v2-diagram__socket--working .v2-diagram__plug,
.v2-diagram__socket--working .v2-diagram__band { stroke: var(--moss); }
.v2-diagram__socket--refused .v2-diagram__band { stroke-dasharray: 4 3; }
.v2-diagram__fills { stroke-width: 1.6; }
.v2-diagram__fills--working { stroke: var(--moss); }
.v2-diagram__fills--refused { stroke: var(--ink2, var(--ink)); stroke-dasharray: 5 4; }
.v2-diagram__fills--open { stroke: var(--line); }
.v2-diagram__profile { stroke: var(--ink2, var(--ink)); stroke-width: 1.5; fill: color-mix(in srgb, var(--accent) 10%, transparent); }
.v2-diagram__link { cursor: pointer; }
.v2-diagram__link:hover .v2-diagram__app,
.v2-diagram__link:hover .v2-diagram__sandbox,
.v2-diagram__link:hover .v2-diagram__provider,
.v2-diagram__link:hover .v2-diagram__band { stroke: var(--accent); }
.v2-diagram__link:focus-visible { outline: none; }
.v2-diagram__link:focus-visible .v2-diagram__app,
.v2-diagram__link:focus-visible .v2-diagram__sandbox,
.v2-diagram__link:focus-visible .v2-diagram__provider,
.v2-diagram__link:focus-visible .v2-diagram__band { stroke: var(--accent); stroke-width: 3; }
.v2-diagram--static .v2-diagram__svg { filter: grayscale(1); opacity: 0.72; }
.v2-diagram--static .v2-diagram__svg * { pointer-events: none; }


/* ===== The profile interface (2026-08-21) ==================================
   Identity, channel accounts, session — three sections, the gadgets' thin
   floating divider between them. Cards reuse the Compendium band vocabulary;
   the switcher rows are the rail footer's old popover items, laid flat. */
.v2-profile { padding: 16px 8px 32px; }
/* The registrar's panel, folded away (operator, 2026-08-28). It is the page's largest
   block and its secondary reading; closed by default so the page opens on what the
   instance says of ITSELF. */
.v2-profile__registrar { margin-top: 14px; }
.v2-profile__registrar > summary {
  cursor: pointer;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink2, #888);
  padding: 6px 0;
}
.v2-profile__registrar > summary:focus-visible {
  outline: 2px solid var(--v2-instrument, #6f5bd6);
  outline-offset: 2px;
}
.v2-profile__section { padding: 0 10px; }
.v2-profile__msn {
  margin: 2px 0 10px;
  color: var(--ink2);
  font-family: ui-monospace, monospace;
  font-size: 11px;
  /* An msn is an ADDRESS and its meaning is positional — a segment read in isolation
     tells you nothing — so the groups have to be countable at a glance. Tabular figures
     make the segments line up; the tracking keeps the hyphens from binding the whole
     thing into one run. */
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}
.v2-profile__dl { max-width: 560px; }

/* THE SHARED STATE CELL. One vocabulary for every table that reports whether a thing is
   working, waiting on permission, or wrong — the holdings table, the stills table and
   whatever asks next. `is-held` is deliberately not a warning colour: see --held. */
.v2-state { white-space: nowrap; }
.v2-state.is-live  { color: var(--moss); }
.v2-state.is-held  { color: var(--held); }
.v2-state.is-fault { color: var(--danger); }
/* NOTHING HERE YET, which on an unused seam is not a fault and not a success. Grey,
   so the two states that mean something keep their colour meaning something. */
.v2-state.is-idle  { color: var(--ink2); }

/* THE PORT LADDER (operator, 2026-10-24: "organize the other aspect like ports, etc.
   visually and conceptually to make more sense"). One card per seam; four rungs down
   the gutter, joined by a hairline, each rung's number carrying its own state colour.
   The join IS the design: the three tables this replaced described the same six seams
   and left the reader to match them on a key none of them printed. */
.v2-ladder {
  display: grid;
  /* 340px, not 290: at 290 a 1440px workbench fits four columns and every rung lead
     breaks after three or four words. Three columns is the widest that still reads. */
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: 12px;
  padding: 8px 0 4px;
}
.v2-ladder__port {
  min-width: 0;
  border: 1px solid var(--line);
  border-left: 3px solid var(--ink2);
  border-radius: var(--radius);
  /* NO background of its own: the card sits on `.v2-card`'s panel, and a token that
     happened to match it in one theme would be a stripe in the other two. */
  padding: 10px 12px 8px;
}
/* The card's left edge is where it stands, readable before any text is. */
.v2-ladder__port.is-live { border-left-color: var(--moss); }
.v2-ladder__port.is-held { border-left-color: var(--held); }
.v2-ladder__port.is-idle { border-left-color: var(--line); }
.v2-ladder__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.v2-ladder__names { min-width: 0; }
.v2-ladder__name { margin: 0; font-size: 13.5px; }
.v2-ladder__id {
  margin: 1px 0 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10.5px;
  color: var(--ink2);
  overflow-wrap: anywhere;
}
.v2-ladder__pill { margin: 0; flex: 0 0 auto; font-size: 11px; }
.v2-ladder__rungs {
  position: relative;
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
}
/* The ladder's stile, behind the rung numbers. 7.5px is half the 15px gutter. */
.v2-ladder__rungs::before {
  content: "";
  position: absolute;
  left: 7.5px;
  top: 6px;
  bottom: 8px;
  width: 1px;
  background: var(--line);
}
.v2-ladder__rung {
  position: relative;
  display: grid;
  grid-template-columns: 15px minmax(0, 1fr);
  gap: 8px;
  padding: 5px 0;
}
.v2-ladder__layer {
  position: relative;
  z-index: 1;
  /* Punches the stile so the number reads as a rung on it rather than over it, in
     whatever the surrounding panel is -- the same token `.v2-card` fills with. */
  background: var(--ide-panel-bg, #fff);
  padding: 1px 0;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  text-align: center;
  color: var(--ink2);
}
.v2-ladder__rung.is-live .v2-ladder__layer { color: var(--moss); }
.v2-ladder__rung.is-held .v2-ladder__layer { color: var(--held); }
.v2-ladder__body { min-width: 0; }
.v2-ladder__lead { margin: 0; font-size: 12px; }
.v2-ladder__layerName { font-weight: 600; }
.v2-ladder__rung.is-idle .v2-ladder__lead { color: var(--ink2); }
.v2-ladder__items {
  margin: 3px 0 0;
  padding-left: 14px;
  font-size: 11.5px;
  color: var(--ink2);
}
.v2-ladder__items li { overflow-wrap: anywhere; }
.v2-ladder__next {
  margin: 8px 0 0;
  padding-top: 7px;
  border-top: 1px solid var(--line);
  font-size: 11.5px;
}
.v2-ladder__nextLayer { font-weight: 600; }

/* THE PROFILE HEADER (operator, 2026-10-24 and 2026-11-09: "still didn't look like a
   profile page"). What reads as a profile is a face beside a name, an address under it,
   a row of counts and the actions, then tabs. `.v2-profile__specimen` is the identity
   section's old name, kept as the header's selector. */
/* One column on one axis, as a profile is read: header, tabs and grid share a centre. */
.v2-profile { max-width: 980px; margin: 0 auto; }
.v2-profile__specimen {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 24px;
  align-items: center;
  padding: 10px 10px 22px;
}
.v2-profile__specimenMain { min-width: 0; }
/* A monogram in a ring: the instance's own letters, in the theme's accent, so the face
   is never a stock silhouette and never a colour one palette lacks. */
.v2-profile__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  border: 2px solid var(--accent);
  box-shadow: inset 0 0 0 4px var(--paper);
  background: color-mix(in srgb, var(--accent) 14%, var(--paper));
  color: var(--accent);
  font-size: 34px;
  font-weight: 600;
  letter-spacing: 0.02em;
  user-select: none;
}
.v2-profile__name {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.v2-profile__specimen .v2-profile__msn { margin: 4px 0 0; font-size: 12px; }
[data-profile-visit] .v2-profile__specimen .v2-profile__dl { margin: 10px 0 6px; }
.v2-profile__counts {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 20px;
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
}
.v2-profile__count {
  padding: 2px 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 13px;
  color: var(--ink2);
  cursor: pointer;
}
.v2-profile__count strong {
  margin-right: 5px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.v2-profile__count:hover strong { color: var(--accent); }
.v2-profile__count:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* The rail is now the header's meta row: the signature fact, then the one action. It
   wraps as a whole rather than squeezing its value: "published" must never break into
   "publish / ed" (2026-10-31), so the value cell does not wrap at all. */
.v2-profile__rail {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  min-width: 0;
  margin-top: 14px;
}
.v2-profile__rail .v2-profile__dl { max-width: none; margin: 0; }
.v2-profile__rail .v2-surface-dl {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 12.5px;
}
.v2-profile__rail .v2-surface-dl dt { font-weight: 400; color: var(--ink2); opacity: 1; }
.v2-profile__rail .v2-surface-dl dd { white-space: nowrap; word-break: normal; }
.v2-profile__railLink {
  display: inline-block;
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
}
.v2-profile__railLink:hover { border-color: var(--accent); color: var(--accent); }
.v2-profile__railLink:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* THE TABS. A rule across the page with the open tab marked ON it, as a profile's tabs
   are; centred while they fit, and scrolling inside their own strip when they do not
   (`safe` keeps the first tab reachable instead of clipped). */
.v2-profile__tabs {
  display: flex;
  justify-content: safe center;
  gap: 4px;
  margin: 0 10px;
  border-top: 1px solid var(--line);
  overflow-x: auto;
  scrollbar-width: none;
}
.v2-profile__tab {
  flex: 0 0 auto;
  margin-top: -1px;
  padding: 11px 14px 10px;
  border: 0;
  border-top: 2px solid transparent;
  background: none;
  font: inherit;
  font-size: 13px;
  color: var(--ink2);
  white-space: nowrap;
  cursor: pointer;
}
.v2-profile__tab:hover { color: var(--ink); }
.v2-profile__tab[aria-selected="true"] {
  border-top-color: var(--ink);
  color: var(--ink);
  font-weight: 600;
}
.v2-profile__tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.v2-profile__tabCount {
  margin-left: 6px;
  font-size: 11px;
  font-weight: 400;
  color: var(--ink2);
  font-variant-numeric: tabular-nums;
}
.v2-profile__panel { padding: 12px 0 6px; }
.v2-profile__panel[hidden] { display: none; }

/* ALIASES as icon cards (operator, 2026-10-24) — smaller than an instrument card and
   denser, because an alias has a mark and two words rather than a summary to read. */
.v2-profile__aliasGrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 12px;
  padding: 4px 0 10px;
}
/* An alias is a TILE under the profile's tabs: the mark first and large, the name, then
   at most three lines of why. A longer summary is the interface's own to say. */
.v2-profile__aliasGrid .v2-profile__card { min-height: 150px; }
.v2-profile__aliasGrid .v2-compendium__glyph,
.v2-profile__aliasGrid .v2-profile__cardBrand { width: 44px; height: 44px; }
.v2-profile__aliasGrid .v2-compendium__instrumentWhy {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* The head wraps: mark and access on the first line, the name on its own line below
   (2026-10-26). An alias card is now named for its host — "Fruitful Network
   Development account" — and beside a mark in a 150px card the one-line head broke that
   mid-word ("Fruit / ful / Netw / ork"), as it already did "Registr / ar". Words break
   only where they cannot fit alone. */
.v2-profile__aliasGrid .v2-compendium__instrumentHead { flex-wrap: wrap; }
.v2-profile__aliasGrid .v2-compendium__name {
  flex: 1 1 100%;
  order: 2;
  word-break: normal;
  overflow-wrap: anywhere;
}
.v2-profile__aliasGrid .v2-profile__cardAccess { order: 1; }
.v2-profile__note { color: var(--ink2); font-size: 12px; margin: 6px 0; }
.v2-profile__stills { font-size: 12px; margin: 8px 0; }
.v2-profile__docLine { font-size: 12px; margin: 8px 0 2px; }
.v2-profile__card.is-disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.v2-profile__card.is-open { border-color: rgba(30, 108, 147, 0.8); }
/* A VISITED profile's channel cards (client door, 2026-11-09). One that cannot be pressed
   says why in its note, so it stays readable rather than fading to a ghost; the action a
   pressable one takes is a filled label at its foot. */
.v2-profile__card.is-disabled[data-profile-kind="visit"] { opacity: 0.8; }
.v2-profile__cardAction {
  align-self: flex-start;
  margin-top: auto;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-fg);
  font-size: 12px;
  font-weight: 600;
}
.v2-profile__card:hover .v2-profile__cardAction,
.v2-profile__card:focus-visible .v2-profile__cardAction { filter: brightness(1.1); }
/* The form that takes a place in a channel, on the visitor's own profile. */
.v2-profile__establish { display: flex; flex-direction: column; gap: 14px; max-width: 32rem; margin-top: 12px; }
.v2-profile__establishField { display: flex; flex-direction: column; gap: 4px; }
.v2-profile__establishField label { font-weight: 600; font-size: 13px; }
.v2-profile__establishField input {
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
}
.v2-profile__establishField input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.v2-profile__establishHint { margin: 0; font-size: 12px; color: var(--ink2); }
.v2-profile__establishError { margin: 0; font-size: 12px; color: #b3261e; }
.v2-profile__establishActions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.v2-profile__establishSubmit {
  display: inline-block;
  padding: 8px 18px;
  border: 0;
  border-radius: 6px;
  background: var(--accent);
  color: var(--accent-fg);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.v2-profile__establishSubmit:disabled { opacity: 0.6; cursor: progress; }
.v2-profile__establishSubmit:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.v2-profile__member { margin: 4px 0 10px; font-size: 13px; }
.v2-profile__cardAccess {
  flex: 0 0 auto;
  margin-left: auto;
  padding: 1px 7px;
  border: 1px solid currentColor;
  border-radius: 8px;
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.8;
}
.v2-profile__cardHost,
.v2-profile__cardNote {
  font-size: 11px;
  color: var(--ink2);
}
/* A TEXT brand line in the glyph's place (2026-10-26): the host's letters, boxed at the
   glyph's size so the card grid keeps one rhythm. */
.v2-profile__cardBrand {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  border: 1.5px solid currentColor;
  border-radius: 9px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
}
.v2-profile__sessionMount { margin-top: 10px; }
/* The embedded msn_profile face is the registrar detail panel, whose tables want
   ~740px. Wide content scrolls INSIDE its own container (the standing phone rule)
   — measured before this: the page stayed 390px wide and the detail was silently
   CLIPPED at the mount's width, which is worse than scrolling. */
.v2-profile__faceMount { margin-top: 12px; overflow-x: auto; }
.v2-profile__switcher {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 560px;
}
.v2-profile__switch {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  margin: 2px 0;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 12.5px;
  text-align: left;
  cursor: pointer;
}
.v2-profile__switch:hover { background: rgba(127, 127, 127, 0.12); }
.v2-profile__switch.is-active {
  border-color: rgba(30, 108, 147, 0.8);
  background: rgba(30, 108, 147, 0.18);
  cursor: default;
}
.v2-profile__switchMsn {
  display: block;
  margin-top: 2px;
  color: var(--ink2);
  font-family: ui-monospace, monospace;
  font-size: 10px;
}
.v2-profile__switchKind {
  color: var(--ink2);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
/* The vault and manage links share this look deliberately; each has its OWN class so a
   selector reaching for the sign-out cannot land on the credential store instead. */
.v2-profile__signOut,
.v2-profile__manageLink,
.v2-profile__vaultLink {
  display: inline-block;
  margin-top: 14px;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 6px;
  text-decoration: none;
}
.v2-profile__signOut:hover,
.v2-profile__manageLink:hover,
.v2-profile__vaultLink:hover { background: rgba(127, 127, 127, 0.12); }
/* The ACTION is the primary of the two, so it reads as one. The vault beside it is
   where a recorded value is read; this is where one is set. */
.v2-profile__manageLink { border-color: var(--ink2); margin-right: 8px; }

/* ===== The board session (2026-10-18) ====================================== */
/* A member's seat and the statement their office may read; the host's roster. One
   grammar with the grantor session beside it: the same tables, the same notes, so two
   channels on one profile page read as one surface. */
.v2-board { display: grid; gap: 18px; }
.v2-board__board { display: grid; gap: 10px; }
.v2-board__head .v2-profile__msn { margin: 2px 0 0; }
.v2-board__seat { margin: 4px 0 0; color: var(--ink2); font-size: 13px; }
.v2-board__sectionHead {
  margin: 10px 0 2px;
  color: var(--ink2);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.v2-board__periodRow { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.v2-board__periodLabel { color: var(--ink2); font-size: 12px; }
.v2-board__period {
  margin-left: 8px;
  padding: 5px 10px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 12.5px;
}
.v2-board__tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
  margin: 8px 0 4px;
}
.v2-board__tile {
  display: grid;
  gap: 2px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--paper);
}
.v2-board__tileLabel { color: var(--ink2); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; }
.v2-board__tileValue { font-size: 20px; font-variant-numeric: tabular-nums; }
.v2-board__tileNote { color: var(--ink2); font-size: 11.5px; }
.v2-board__table {
  width: 100%;
  max-width: 760px;
  border-collapse: collapse;
  font-size: 12.5px;
  margin: 4px 0;
}
.v2-board__table th,
.v2-board__table td {
  padding: 7px 10px;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}
.v2-board__table th {
  color: var(--ink2);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.v2-board__amount { font-variant-numeric: tabular-nums; white-space: nowrap; }
.v2-board__note { margin: 4px 0; color: var(--ink2); font-size: 12.5px; max-width: 760px; }
.v2-board__source { margin: 0; color: var(--ink2); font-size: 11px; max-width: 760px; }

/* ===== The grantor session (2026-08-21) ==================================== */
.v2-grantor__tabs { display: flex; gap: 6px; margin: 4px 0 12px; }
.v2-grantor__tab {
  padding: 7px 14px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  text-transform: capitalize;
  cursor: pointer;
}
.v2-grantor__tab.is-active {
  border-color: rgba(30, 108, 147, 0.8);
  background: rgba(30, 108, 147, 0.18);
}
.v2-grantor__card { text-align: left; font: inherit; cursor: pointer; }
/* The alias's own tabs (2026-11-12): their labels are written as shown ("API keys"), and
   the bar wraps rather than scrolling the page sideways on a phone. */
.v2-grantor__viewerTabs { flex-wrap: wrap; }
.v2-grantor__viewerTabs .v2-grantor__tab { text-transform: none; }
.v2-grantor__viewerPanel { max-width: 760px; }
.v2-grantor__lede { margin: 2px 0 6px; color: var(--ink2); font-size: 12.5px; max-width: 640px; }
/* The rate wraps: "$1.00 per mailbox after the first 2" held on one line pushed the state
   column out of a phone-width window. */
.v2-grantor__rate { font-variant-numeric: tabular-nums; }
.v2-grantor__rate.is-unpriced { color: var(--ink2); font-style: italic; }

/* ===== The Channel tab: a member's interface in a window (2026-11-12) ======= */
.v2-channelPreview__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.v2-channelPreview__chip {
  padding: 1px 9px;
  border: 1px solid rgba(30, 108, 147, 0.6);
  border-radius: 9px;
  font-size: 11px;
}
.v2-channelPreview__chip.is-quiet { border-color: var(--line); color: var(--ink2); }
.v2-channelPreview__picks { display: flex; flex-wrap: wrap; gap: 12px; margin: 8px 0 12px; }
.v2-channelPreview__pick { display: flex; align-items: center; gap: 6px; font-size: 12.5px; }
.v2-channelPreview__pick select { max-width: 100%; font: inherit; }
.v2-channelPreview__window {
  margin: 0;
  max-width: 900px;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  background: var(--paper);
  box-shadow: var(--shadow);
}
.v2-channelPreview__bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 12px;
  border-bottom: 1px solid var(--line);
  background: var(--paper2);
  font-size: 12px;
  color: var(--ink2);
}
.v2-channelPreview__dots { display: inline-flex; gap: 5px; }
.v2-channelPreview__dots i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 1px solid var(--line);
}
.v2-channelPreview__title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-channelPreview__body { padding: 14px 16px; overflow-x: auto; }
.v2-grantor__services,
.v2-grantor__tolling {
  width: 100%;
  max-width: 720px;
  border-collapse: collapse;
  font-size: 12.5px;
  margin: 10px 0;
}
.v2-grantor__services th,
.v2-grantor__services td,
.v2-grantor__tolling th,
.v2-grantor__tolling td {
  padding: 7px 10px;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}
.v2-grantor__services th,
.v2-grantor__tolling th {
  color: var(--ink2);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.v2-grantor__state {
  padding: 1px 8px;
  border: 1px solid var(--line);
  border-radius: 9px;
  font-size: 11px;
}
.v2-grantor__state.is-on {
  border-color: rgba(64, 160, 90, 0.7);
  background: rgba(64, 160, 90, 0.14);
}
.v2-grantor__lock {
  margin-left: 6px;
  color: var(--ink2);
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.v2-grantor__key { margin: 12px 0; }
.v2-grantor__keyValue {
  display: inline-block;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  font-family: ui-monospace, monospace;
  font-size: 12px;
  user-select: all;
}
.v2-grantor__copy,
.v2-grantor__mint {
  margin-left: 8px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.v2-grantor__copy:hover,
.v2-grantor__mint:hover { background: rgba(127, 127, 127, 0.12); }
.v2-grantor__tollingLine { font-size: 12.5px; }
/* THREE STATES (2026-10-26): on, off, and undeclared — a row the client's document has
   never spoken of — drawn apart, because billing keys on the difference. */
.v2-grantor__state.is-off {
  border-color: rgba(200, 86, 60, 0.7);
  background: rgba(200, 86, 60, 0.12);
}
.v2-grantor__state.is-undeclared {
  border-style: dashed;
  color: var(--ink2);
}
.v2-grantor__rowNote { display: block; color: var(--ink2); font-size: 11.5px; }
.v2-grantor__toggle,
.v2-grantor__reveal,
.v2-grantor__confirm,
.v2-grantor__cancel {
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.v2-grantor__toggle:hover,
.v2-grantor__reveal:hover,
.v2-grantor__confirm:hover,
.v2-grantor__cancel:hover { background: rgba(127, 127, 127, 0.12); }
.v2-grantor__reveal { margin-left: 8px; }
.v2-grantor__confirm {
  border-color: rgba(30, 108, 147, 0.8);
  background: rgba(30, 108, 147, 0.18);
}
.v2-grantor__toggle[disabled],
.v2-grantor__reveal[disabled],
.v2-grantor__copy[disabled],
.v2-grantor__mint[disabled],
.v2-grantor__confirm[disabled] { opacity: 0.5; cursor: not-allowed; }
.v2-grantor__toggle:focus-visible,
.v2-grantor__reveal:focus-visible,
.v2-grantor__copy:focus-visible,
.v2-grantor__mint:focus-visible,
.v2-grantor__confirm:focus-visible,
.v2-grantor__cancel:focus-visible,
.v2-grantor__paymentLink:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.v2-grantor__report { margin-top: 6px; }
/* The door's step report: one line per step, status apart from reason. */
.v2-grantor__steps { list-style: none; margin: 6px 0; padding: 0; font-size: 12px; }
.v2-grantor__step {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  padding: 3px 0;
  border-bottom: 1px dotted var(--line);
}
.v2-grantor__stepName { min-width: 88px; font-weight: 600; }
.v2-grantor__stepStatus {
  min-width: 64px;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink2);
}
.v2-grantor__step.is-refused .v2-grantor__stepStatus { color: rgba(200, 86, 60, 1); }
.v2-grantor__step.is-done .v2-grantor__stepStatus { color: rgba(64, 160, 90, 1); }
.v2-grantor__stepWhy { flex: 1 1 240px; color: var(--ink2); }
/* The key, masked: the prefix and the last four until Reveal. */
.v2-grantor__keyValue.is-masked { letter-spacing: 0.04em; }
.v2-grantor__keyStatus { display: inline-block; margin-left: 8px; color: var(--ink2); font-size: 12px; }
/* A date is one word: "minted 2026-10-26" must not break at its hyphens on a phone. */
.v2-grantor__keyMinted { white-space: nowrap; }
@media (max-width: 520px) {
  /* On its own line under the buttons, flush with them, rather than indented after them. */
  .v2-grantor__keyStatus { display: block; margin: 6px 0 0; }
}
/* Payment information: the card as recorded, and the door a card is entered through. */
.v2-grantor__payment { margin: 14px 0 6px; max-width: 720px; }
.v2-grantor__instrument { margin: 4px 0 8px; font-size: 12.5px; }
.v2-grantor__paymentLink {
  display: inline-block;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  font-size: 12px;
  text-decoration: none;
  color: var(--ink);
}
.v2-grantor__paymentLink:hover { background: rgba(127, 127, 127, 0.12); }
/* The services agreement: where it stands, the copy to download, the signed copy to upload. */
.v2-grantor__agreement { margin: 14px 0 6px; max-width: 720px; }
.v2-grantor__agreementState { margin: 4px 0 8px; font-size: 12.5px; }
.v2-grantor__agreementUpload {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin-top: 10px;
  font-size: 12px;
}
.v2-grantor__agreementPick { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.v2-grantor__agreementPick input[type="file"] { max-width: 100%; font-size: 12px; }
.v2-grantor__agreementPick input[type="file"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* The client's data: their whole instance as one zip, and what the download is doing. */
.v2-grantor__export { margin: 14px 0 6px; max-width: 720px; }
.v2-grantor__exportNote { margin: 4px 0 8px; font-size: 12.5px; }
.v2-grantor__exportAct { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; font-size: 12px; }
.v2-grantor__exportAct [aria-disabled="true"] { opacity: 0.6; cursor: progress; }
.v2-profile__delete { margin-top: 20px; }
/* The buttons' own display would otherwise beat `hidden`: the two presses showed at once. */
.v2-profile__delete [hidden] { display: none; }
.v2-profile__deleteHead { margin: 0 0 6px; font-size: 0.95rem; font-weight: 600; }
.v2-profile__danger { color: var(--danger); border-color: var(--danger); }
/* The card page's address, named in full on the operator's reading: one unbreakable
   token wider than a phone, so it breaks anywhere rather than scrolling the page
   sideways (measured 31px over at 390px, 2026-10-27). */
.v2-grantor__payment code[data-grantor-card-page] {
  font-family: ui-monospace, monospace;
  font-size: 11.5px;
  overflow-wrap: anywhere;
  word-break: break-all;
}
.v2-grantor__viewer h4.v2-compendium__bandHead { margin: 16px 0 4px; font-size: 13px; }
/* The span ticks. Wrapping, never scrolling: a hidden tick is a sandbox the operator
   would not know the instrument reads, which is the one thing this row is for. */
.v2-compendium__spans { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 2px; }
.v2-compendium__span {
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 10px;
  letter-spacing: 0.02em;
  color: var(--v2-instrument, #6f5bd6);
  border: 1px solid currentColor;
  border-radius: 3px;
  padding: 0 4px;
}

/* The list face's tally. Exact counts, never a rounded one: "12 filed - 3 unfiled"
   is a claim an operator can check against the rows below it. */
.v2-compendium__tally {
  margin-left: auto;
  font-size: 12px;
  color: var(--ink2, #888);
  white-space: nowrap;
}
.v2-compendium__tallyUnfiled { color: var(--v2-source-external, #b4791f); font-weight: 600; }
.v2-compendium__slot { font-size: 11.5px; color: var(--ink2, #888); }
.v2-compendium__row.is-unfiled .v2-compendium__slot { color: var(--v2-source-external, #b4791f); }
.v2-compendium__unfiledTag,
.v2-compendium__reservedTag {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  border: 1px solid currentColor;
  border-radius: 4px;
  padding: 0 4px;
  vertical-align: middle;
}
.v2-compendium__unfiledTag { color: var(--v2-source-external, #b4791f); }
.v2-compendium__reservedTag { color: var(--v2-domain-slot, #8a94a6); }
.v2-compendium--open .v2-workbenchUi__trifecta { flex: 1 1 auto; min-height: 0; }

/* A page's own nav, at the top of the page (the control panel that used to hold it
   was retired 2026-08-16). Wraps rather than clips: on a phone the six Utilities
   sections become three rows, not a row with three sections missing. */
.v2-sectionNav {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 10px 14px 0;
}
.v2-sectionNav__item {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 12px;
  border: 1px solid var(--line, #afafaa);
  border-radius: 999px;
  font-size: 13px;
  text-decoration: none;
  color: var(--ink, #464646);
  background: color-mix(in srgb, var(--panel, #eef2ee) 45%, transparent);
}
.v2-sectionNav__item:hover { background: rgba(0, 0, 0, 0.06); }
.v2-sectionNav__item.is-active {
  border-color: var(--accent, #1e6c93);
  color: var(--accent, #1e6c93);
  font-weight: 600;
}
.v2-sectionNav__item:focus-visible { outline: 2px solid var(--accent, #1e6c93); outline-offset: 2px; }

/* The install TARGET: which sandbox an app would land in. */
.v2-installTarget {
  display: grid;
  gap: 6px;
  margin: 10px 14px 0;
  padding: 10px 12px;
  border: 1px solid var(--line, #afafaa);
  border-radius: 8px;
  background: color-mix(in srgb, var(--panel, #eef2ee) 45%, transparent);
}
.v2-installTarget__label {
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink2, #888);
}
.v2-installTarget__options { display: flex; flex-wrap: wrap; gap: 6px; }
.v2-installTarget__option {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 0 11px;
  border: 1px solid var(--line, #afafaa);
  border-radius: 999px;
  font-size: 13px;
  text-decoration: none;
  color: var(--ink, #464646);
}
.v2-installTarget__option.is-active {
  border-color: var(--accent, #1e6c93);
  background: color-mix(in srgb, var(--accent, #1e6c93) 12%, transparent);
  color: var(--accent, #1e6c93);
  font-weight: 600;
}
.v2-installTarget__option:focus-visible { outline: 2px solid var(--accent, #1e6c93); outline-offset: 2px; }
.v2-installTarget__note { margin: 0; font-size: 12px; color: var(--ink2, #888); }

/* Which contract / event type the log table is filtered to, beside the table. */
.v2-selectionStrip {
  display: grid;
  gap: 8px;
  margin: 10px 14px 0;
  padding: 10px 12px;
  border: 1px solid var(--line, #afafaa);
  border-radius: 8px;
  background: color-mix(in srgb, var(--panel, #eef2ee) 45%, transparent);
}
.v2-selectionStrip__facts { display: flex; flex-wrap: wrap; gap: 10px; font-size: 12px; color: var(--ink2, #888); }
.v2-selectionStrip__fact b { font-weight: 600; }
.v2-selectionStrip__group { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.v2-selectionStrip__groupTitle {
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink2, #888);
  margin-right: 2px;
}
.v2-selectionStrip__item {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  max-width: 100%;
  padding: 0 10px;
  border: 1px solid var(--line, #afafaa);
  border-radius: 6px;
  font-size: 12px;
  text-decoration: none;
  color: var(--ink, #464646);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.v2-selectionStrip__item.is-active {
  border-color: var(--accent, #1e6c93);
  color: var(--accent, #1e6c93);
  font-weight: 600;
}
.v2-selectionStrip__item:focus-visible { outline: 2px solid var(--accent, #1e6c93); outline-offset: 2px; }

/* Sources: what this sandbox reads from elsewhere, and what it declares of its own.
   A section of the SANDBOX, so it sits under the sandbox's own document shelf. */
.v2-compendium__sources {
  margin: 8px 14px 20px;
  padding: 10px 12px 12px;
  border: 1px solid var(--line, #afafaa);
  border-radius: 8px;
  background: color-mix(in srgb, var(--panel, #eef2ee) 55%, transparent);
}
.v2-compendium__sourcesHeader { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.v2-compendium__sourcesHeader h3 {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink2, #888);
}
.v2-compendium__sourcesCount {
  font-size: 11px;
  color: var(--ink2, #888);
  border: 1px solid var(--line, #afafaa);
  border-radius: 999px;
  padding: 0 7px;
}
.v2-compendium__sourcesManage { margin-left: auto; font-size: 12px; color: var(--accent, #1e6c93); }
.v2-compendium__sourcesHead {
  margin: 10px 0 4px;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink2, #888);
}
.v2-compendium__sourceList { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.v2-compendium__sourceRow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, auto) minmax(0, auto);
  gap: 8px;
  align-items: baseline;
  font-size: 12px;
  padding: 3px 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}
.v2-compendium__sourceName { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-compendium__sourceFrom { font-size: 11px; color: var(--ink2, #888); }
.v2-compendium__sourceStatus { font-size: 11px; color: var(--ink2, #888); }
.v2-compendium__sourceStatus[data-status="found"] { color: var(--accent, #1e6c93); }
.v2-compendium__sourcesEmpty { margin: 8px 0 0; font-size: 12px; color: var(--ink2, #888); }
@media (max-width: 700px) {
  .v2-compendium__bar { flex-wrap: wrap; }
}

/* Workbench tool host — a tool rendered in the center pane (?tool=<id> on the system
   root; the modal tool overlay was retired 2026-08-16). Chrome row: title left,
   See-source + Close right. The body scrolls; the chrome stays. */
.v2-toolHost {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}
.v2-toolHost__chrome {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 14px;
  background: var(--paper2, #e8e5d0);
  border-bottom: 1px solid var(--line, #afafaa);
}
.v2-toolHost__title { margin: 0; font-size: 1rem; font-weight: 600; }
.v2-toolHost__actions { display: flex; align-items: center; gap: 12px; }
.v2-toolHost__back,
.v2-toolHost__seeSource {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink2, #888);
  text-decoration: none;
  padding: 4px 8px;
  border-radius: 4px;
}
.v2-toolHost__back:hover,
.v2-toolHost__seeSource:hover { color: var(--ink, #464646); background: rgba(0, 0, 0, 0.06); }
.v2-toolHost__seeSource svg { width: 16px; height: 16px; }
.v2-toolHost__body { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 12px; }
.v2-toolHost__panel + .v2-toolHost__panel { margin-top: 12px; }
.ide-visualizationPanel__error { color: var(--danger); padding: 12px 16px; }

/* Portal icon-leaflet registry (portal.js iconImg) — CSS-mask spans so leaflets inherit
   currentColor (themeable). Served from /assets/icons/ (nginx in prod; app.py on :6101). */
.mc-icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -0.14em;
  background-color: currentColor;
  -webkit-mask: var(--mc-icon-url) no-repeat center / contain;
  mask: var(--mc-icon-url) no-repeat center / contain;
}
.mc-iconBtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  padding: 2px;
  border-radius: 4px;
  line-height: 0;
  transition: background 0.12s ease, transform 0.06s ease;
}
.mc-iconBtn:hover { background: rgba(0, 0, 0, 0.08); }
.mc-iconBtn:active { transform: translateY(0.5px); }
.mc-iconBtn--sm { font-size: 0.85em; }
.mc-iconBtn--light { color: var(--paper, #f0eedc); }

/* Datum-editing pane — inline in the workbench (the modal cell-editor overlay was
   retired 2026-08-16). Docks as a third column beside the datum grid when the
   two-column workbench is on screen; the accent border says "editing here". Not
   modal: no backdrop, the grid stays clickable, Escape or × closes. */
.ide-datumOverlay {
  display: flex;
  flex-direction: column;
  min-height: 0;
  max-height: 100%;
  align-self: start;
  background: var(--paper, #f0eedc);
  color: var(--ink, #464646);
  border: 1px solid var(--line, #afafaa);
  border-top: 4px solid var(--accent, #1e6c93);
  border-radius: 10px;
  overflow: hidden;
}
.v2-workbenchUi__columns:has(> .ide-datumOverlay) {
  grid-template-columns: 260px 1fr minmax(300px, 380px);
}
@media (max-width: 1100px) {
  .v2-workbenchUi__columns:has(> .ide-datumOverlay) { grid-template-columns: 260px 1fr; }
  .v2-workbenchUi__columns > .ide-datumOverlay { grid-column: 1 / -1; }
}
.ide-datumOverlay__chrome {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: var(--paper2, #e8e5d0);
  border-bottom: 1px solid var(--line, #afafaa);
}
.ide-datumOverlay__close {
  order: 0;
  border: 0;
  background: transparent;
  color: var(--ink2, #888);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 6px;
  border-radius: 4px;
}
.ide-datumOverlay__close:hover { color: var(--danger); background: rgba(0, 0, 0, 0.06); }
.ide-datumOverlay__title { font-weight: 600; font-size: 0.95rem; }
.ide-datumOverlay__tabs {
  display: flex;
  gap: 2px;
  flex: 0 0 auto;
  padding: 0 12px;
  background: var(--paper2, #e8e5d0);
  border-bottom: 1px solid var(--line, #afafaa);
}
.ide-datumOverlay__tab {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--ink2, #888);
  font: inherit;
  font-weight: 600;
  letter-spacing: 0.06em;
  font-size: 11px;
  padding: 8px 14px;
  cursor: pointer;
  border-bottom: 2px solid transparent;
}
.ide-datumOverlay__tab:hover:not([disabled]) { color: var(--ink, #464646); }
.ide-datumOverlay__tab.is-active {
  color: var(--ink, #464646);
  border-bottom-color: var(--accent, #1e6c93);
}
.ide-datumOverlay__tab[disabled] { opacity: 0.4; cursor: default; }
.ide-datumOverlay__content { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 14px; }
/* DENOTATION form */
.v2-denote__field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
.v2-denote__field > label {
  font-size: 11px;
  color: var(--ink2, #888);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.v2-denote__field input,
.v2-denote__row input {
  padding: 6px 8px;
  border: 1px solid var(--line, #afafaa);
  border-radius: 4px;
  background: var(--paper, #fff);
  color: var(--ink);
  font: inherit;
}
.v2-denote__row { display: flex; gap: 6px; align-items: center; margin-bottom: 6px; }
.v2-denote__row input { flex: 1 1 auto; }
.v2-denote__sectionLabel { font-size: 11px; color: var(--ink2); text-transform: uppercase; letter-spacing: 0.04em; margin: 12px 0 6px; }
.v2-denote__actions { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
.v2-denote__status { margin-top: 10px; font-size: 12px; min-height: 1em; }
.v2-denote__status[data-state="error"] { color: var(--danger); }
.v2-denote__status[data-state="ok"] { color: var(--moss); }
.v2-btn {
  border: 1px solid var(--line);
  background: var(--paper2);
  color: var(--ink);
  padding: 6px 12px;
  border-radius: 4px;
  cursor: pointer;
  font: inherit;
}
.v2-btn:disabled { opacity: 0.5; cursor: default; }
.v2-btn--primary { background: var(--accent, #1e6c93); color: #fff; border-color: var(--accent, #1e6c93); }
.v2-btn--danger { color: var(--danger); }
/* INFORMATION abstraction path graph */
.v2-info__meta { font-size: 11px; color: var(--ink2); margin-bottom: 12px; }
.v2-info__hyphae { font-family: ui-monospace, monospace; font-size: 11px; word-break: break-all; }
.v2-info__path { display: flex; flex-direction: column; gap: 0; }
.v2-info__node {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--paper2);
}
.v2-info__node.is-target { border-color: var(--accent); border-width: 2px; font-weight: 600; }
.v2-info__arrow { text-align: center; color: var(--ink2); font-size: 12px; line-height: 1.4; }
.v2-info__hash { font-family: ui-monospace, monospace; font-size: 10px; color: var(--ink2); margin-left: auto; }
.v2-mediation { color: var(--ink2); padding: 24px; text-align: center; font-style: italic; }
/* Profile-card base (visual + title + SAMRAS chip) — its own tool, and composed atop farm_profile. */
.v2-profile { padding: 4px; }
.v2-profileCard {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  margin-bottom: 10px;
  border: 1px solid var(--line, #afafaa);
  border-radius: 8px;
  background: var(--paper2, #e8e5d0);
}
.v2-profileCard__visual {
  width: 52px;
  height: 52px;
  flex: 0 0 auto;
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--paper, #fff);
  border: 1px solid var(--line, #afafaa);
}
.v2-profileCard__visual img { width: 100%; height: 100%; object-fit: cover; }
.v2-profileCard__visual--placeholder {
  font-weight: 700;
  font-size: 22px;
  color: var(--accent, #1e6c93);
  background: color-mix(in srgb, var(--accent, #1e6c93) 14%, var(--paper, #fff));
}
.v2-profileCard__title { font-weight: 600; font-size: 14px; }
.v2-profileCard__samras {
  font-size: 11px;
  color: var(--ink2, #888);
  margin-top: 2px;
  font-family: ui-monospace, monospace;
}
.v2-profileCard__chip {
  display: inline-block;
  font-size: 9px;
  letter-spacing: 0.06em;
  background: var(--accent, #1e6c93);
  color: #fff;
  padding: 1px 5px;
  border-radius: 3px;
  vertical-align: 1px;
}

/* Registrar Portal — standalone registrar entity-profile tool (browse + detail). */
.v2-registrar { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.v2-registrar__toolbar { display: flex; align-items: center; gap: 12px; padding: 8px 12px; border-bottom: 1px solid var(--ide-border, #d8dee4); }
.v2-registrar__count { font-size: 12px; color: var(--ink2); flex: 1 1 auto; }
.v2-registrar__new { padding: 5px 14px; border: 1px solid var(--accent, #1e6c93); border-radius: 6px; background: var(--accent, #1e6c93); color: #fff; font: inherit; font-size: 13px; cursor: pointer; }
.v2-registrar__new:hover { filter: brightness(1.08); }
.v2-registrar__browse { flex: 1 1 auto; min-height: 0; display: flex; }
.v2-registrar__browse > .v2-composite { flex: 1 1 auto; min-height: 0; }
.v2-registrar__empty { padding: 20px; color: var(--ink2); font-size: 13px; }
.v2-registrar--detail { padding: 10px 14px; overflow: auto; gap: 10px; }
.v2-registrar__back { align-self: flex-start; display: inline-flex; align-items: center; gap: 6px; margin-bottom: 6px; padding: 4px 12px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px; background: var(--ide-panel-bg, #fff); font: inherit; font-size: 13px; color: var(--accent, #1e6c93); cursor: pointer; }
.v2-registrar__back:hover { background: var(--paper2); }
.v2-registrar__cols { display: grid; grid-template-columns: minmax(220px, 1fr) minmax(240px, 1.2fr); gap: 18px; margin-top: 10px; align-items: start; }
.v2-registrar__edit { margin-top: 10px; padding: 5px 14px; border: 1px solid var(--accent, #1e6c93); border-radius: 6px; background: var(--ide-panel-bg, #fff); color: var(--accent, #1e6c93); font: inherit; font-size: 13px; cursor: pointer; }
.v2-registrar__edit:hover { background: var(--paper2); }
.v2-registrar__eventsTitle { margin: 0 0 8px; font-size: 12px; font-weight: 600; color: var(--ink2); text-transform: uppercase; letter-spacing: 0.04em; }
.v2-registrar__eventsEmpty { font-size: 13px; color: var(--ink2); }
.v2-registrar__events { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.v2-registrar__event { display: flex; align-items: center; gap: 8px; padding: 7px 9px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 8px; background: var(--ide-panel-bg, #fff); }
.v2-registrar__eventGlyph { flex: 0 0 auto; color: var(--accent, #1e6c93); }
.v2-registrar__eventType { flex: 0 0 auto; font-size: 11px; font-weight: 600; color: var(--ink2); text-transform: capitalize; }
.v2-registrar__eventBody { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.v2-registrar__eventBody strong { font-size: 13px; }
.v2-registrar__eventMeta, .v2-registrar__eventNext { font-size: 11px; color: var(--ink2); }
.v2-profile__fields { width: 100%; border-collapse: collapse; margin-top: 8px; }
.v2-profile__fields td { padding: 4px 8px; border-bottom: 1px solid var(--ide-border, #d8dee4); font-size: 13px; vertical-align: top; }
.v2-profile__fields td:first-child { color: var(--ink2); font-size: 12px; white-space: nowrap; width: 34%; }

/* profile_admin_edit — registry browse + entry/event curation. Deliberately a list, not a
   map: 58 of the 235 nodes have no coordinate and a map cannot draw the thing you came to fix. */
.v2-pae { display: flex; flex-direction: column; gap: 10px; padding: 10px 12px; overflow: auto; }
.v2-pae__bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.v2-pae__q { flex: 1 1 220px; min-width: 160px; font: inherit; font-size: 13px; padding: 5px 8px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px; background: var(--ide-panel-bg, #fff); }
.v2-pae__region { font: inherit; font-size: 13px; padding: 5px 8px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px; background: var(--ide-panel-bg, #fff); }
.v2-pae__count { font-size: 12px; color: var(--ink2); }
.v2-pae__table { width: 100%; border-collapse: collapse; font-size: 13px; }
.v2-pae__table th { text-align: left; padding: 4px 8px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink2); border-bottom: 1px solid var(--ide-border, #d8dee4); }
.v2-pae__table td { padding: 5px 8px; border-bottom: 1px solid var(--ide-border, #d8dee4); vertical-align: top; }
.v2-pae__row { cursor: pointer; }
.v2-pae__row:hover { background: var(--paper2); }
.v2-pae__gap { color: var(--ink2); font-size: 12px; }
.v2-pae__empty { padding: 14px 4px; color: var(--ink2); font-size: 13px; }
.v2-pae__note { margin: 6px 0 0; font-size: 11px; color: var(--ink2); }
.v2-pae__title { margin: 4px 0 0; font-size: 16px; }
.v2-pae__section { margin: 14px 0 4px; font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink2); }
.v2-pae__entry { border: 1px solid var(--ide-border, #d8dee4); border-radius: 8px; padding: 8px 10px; margin-bottom: 8px; }
.v2-pae__entryTitle { margin: 0; font-size: 13px; }
.v2-pae__entryBar { display: flex; align-items: center; justify-content: flex-end; gap: 10px; padding: 6px 0 0; }
.v2-pae__mini { font: inherit; font-size: 12px; padding: 2px 8px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px; background: var(--ide-panel-bg, #fff); color: var(--accent, #1e6c93); cursor: pointer; }
.v2-pae__mini:hover { background: var(--paper2); }
/* The detail's three parts (2026-11-10): the contact card and the profile side by side, each
   saying which document keeps it and which archetype it is written to; everything else folded
   below. The card's rule is the accent, the profile's the ink, so the two never read as one. */
.v2-pae__parts { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 12px; align-items: start; }
.v2-pae__part { min-width: 0; }
.v2-pae__partTitle { margin: 8px 0 2px; font-size: 14px; }
.v2-pae__partDoc { margin: 0 0 6px; font-size: 12px; color: var(--ink2); overflow-wrap: anywhere; }
.v2-pae__partDoc code, .v2-ptypes code { font-size: 12px; overflow-wrap: anywhere; }
.v2-pae__part--card .v2-pae__entry { border-left: 3px solid var(--accent, #1e6c93); }
.v2-pae__part--profile .v2-pae__entry { border-left: 3px solid var(--ink2); }
.v2-pae__part .v2-profile__fields td { overflow-wrap: anywhere; }
.v2-pae__addr { margin-left: 4px; font-weight: normal; font-size: 11px; color: var(--ink2); }
.v2-pae__notes { margin: 4px 0; padding: 8px 12px; font-size: 13px; border-left: 3px solid var(--warn, #b8860b); background: color-mix(in srgb, var(--warn, #b8860b) 8%, transparent); border-radius: 0 6px 6px 0; }
.v2-pae__notesHead { margin: 0 0 4px; font-weight: 600; }
.v2-pae__notes ul { margin: 0; padding-left: 18px; }
.v2-pae__notes li + li { margin-top: 3px; }
.v2-pae__also > summary { margin: 12px 0 6px; font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink2); cursor: pointer; }
.v2-ptypes__lede { max-width: 72ch; font-size: 13px; }
.v2-ptypes__table td { vertical-align: top; }
.v2-ptypes__kind td { padding-top: 9px; border-top: 1px solid var(--ink2); font-weight: 600; }
.v2-ptypes__kind .v2-place__link { font-size: 13px; font-weight: 600; }
.v2-ptypes__subRow td { border-bottom: 0; padding-top: 2px; padding-bottom: 2px; }
.v2-ptypes__table .v2-ptypes__sub { display: inline-block; max-width: calc(100% - 16px); margin-left: 16px; }
.v2-ptypes__gap { display: block; font-size: 11px; font-weight: normal; color: var(--ink2); }
.v2-ptypes__none { font-size: 12px; color: var(--ink2); }
.v2-ptypes__of { font-weight: normal; font-size: 13px; color: var(--ink2); }
.v2-ptypes__doc .v2-pae__note { overflow-wrap: anywhere; }
/* On a phone each kind is a short block: its name and two counts on one line, where it is kept
   on the next, every cell labelled because the header row is gone. */
@media (max-width: 600px) {
  .v2-ptypes__table thead { display: none; }
  .v2-ptypes__table tr { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr); column-gap: 8px; }
  .v2-ptypes__table td { padding: 3px 4px; border: 0; }
  .v2-ptypes__table td:empty { display: none; }
  .v2-ptypes__table td[data-label]::before { content: attr(data-label); display: block; font-size: 10px; font-weight: normal; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink2); }
  .v2-ptypes__kind { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--ink2); }
  .v2-ptypes__kind td[data-label="Kept in"] { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; }
  .v2-ptypes__kind td[data-label="Kept in"]::before { display: inline; }
  .v2-ptypes__kind td[data-label="Kept in"] .v2-ptypes__gap { display: inline; }
}

/* Registrar profile editor modal (reuses the .v2-objModal shell). */
.v2-profForm { padding: 12px 14px; overflow: auto; display: flex; flex-direction: column; gap: 8px; }
.v2-profForm__row { display: flex; flex-direction: column; gap: 3px; font-size: 12px; color: var(--ink2); }
.v2-profForm__row input, .v2-profForm__row select { font: inherit; font-size: 14px; padding: 5px 8px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px; background: var(--ide-panel-bg, #fff); }
.v2-profForm__row input:disabled { opacity: 0.6; }
.v2-profForm__coord { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.v2-profForm__note { margin: 0; font-size: 11px; color: var(--ink2); line-height: 1.5; }
.v2-profForm__status { flex: 1 1 auto; font-size: 12px; color: var(--ink2); }
.v2-profForm__cancel { padding: 5px 14px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px; background: var(--ide-panel-bg, #fff); font: inherit; font-size: 13px; cursor: pointer; }
.v2-profForm__cancel:hover { background: var(--paper2); }
.v2-profForm__save { padding: 5px 16px; border: 1px solid var(--accent, #1e6c93); border-radius: 6px; background: var(--accent, #1e6c93); color: #fff; font: inherit; font-size: 13px; cursor: pointer; }
.v2-profForm__save:disabled { opacity: 0.45; cursor: default; }
.v2-profForm__save:not(:disabled):hover { filter: brightness(1.08); }

/* portal-tool-overlay-restructure — tabbed container (agronomics FARM/PLAN/NETWORK).
   Client-side tab switching (no shell reload); sibling of .v2-composite. */
.v2-tabbed { display: flex; flex-direction: column; min-height: 0; }
.v2-tabbed__strip {
  display: flex;
  gap: 4px;
  flex: 0 0 auto;
  border-bottom: 1px solid var(--line, #afafaa);
  margin-bottom: 8px;
}
.v2-tabbed__farm {
  margin-left: auto;
  align-self: center;
  max-width: 220px;
  padding: 3px 8px;
  border: 1px solid var(--line, #d8dee4);
  border-radius: 6px;
  background: var(--ide-panel-bg, #fff);
  color: var(--ink, #24292f);
  font: inherit;
  font-size: 0.78rem;
  cursor: pointer;
}
.v2-tabbed__farm + .v2-tabbed__expand { margin-left: 6px; }

/* THE APPLICATION SWITCH (2026-10-27) — `Director ~ Registrar` with a down arrow.
   The operator's spec, verbatim: "a drop down eligible button box, no rounded corners
   just that text and then a down arrow expand icon." So: square corners (0, explicitly —
   this file's controls are 6px by default and the shell converges on 2px, so the zero is
   a decision and not an omission), the name at the strip's weight, and one chevron.
   The chevron is the WRAPPER's `::after` because a <select>'s own arrow cannot be styled
   across browsers; `appearance: none` removes the native one and `padding-right` leaves
   the room. */
.v2-tabbed__app {
  position: relative;
  align-self: flex-start;
  margin-bottom: 8px;
}
.v2-tabbed__app::after {
  content: "";
  position: absolute;
  right: 10px;
  top: 50%;
  width: 7px;
  height: 7px;
  margin-top: -5px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  pointer-events: none;
  opacity: 0.7;
}
.v2-tabbed__appSelect {
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid var(--line, #d8dee4);
  border-radius: 0;
  background: var(--ide-panel-bg, #fff);
  color: var(--ink, #24292f);
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  padding: 6px 30px 6px 12px;
  cursor: pointer;
}
.v2-tabbed__appSelect:hover { background: var(--paper2, #f6f8fa); }
.v2-tabbed__appSelect:focus-visible { outline: 2px solid var(--accent, #1e6c93); outline-offset: 1px; }
.v2-tabbed__expand {
  margin-left: auto;
  align-self: center;
  border: 1px solid var(--line, #d8dee4);
  background: var(--ide-panel-bg, #fff);
  border-radius: 6px;
  width: 26px;
  height: 24px;
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  color: var(--ink2, #57606a);
}
.v2-tabbed__expand.is-active { background: var(--accent); color: var(--accent-fg); border-color: var(--accent); }
.v2-tabbed__tab {
  appearance: none;
  border: 1px solid transparent;
  border-bottom: 0;
  background: transparent;
  color: var(--ink2, #888);
  font: inherit;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 6px 14px;
  cursor: pointer;
  border-radius: 6px 6px 0 0;
}
.v2-tabbed__tab:hover { color: var(--ink, #464646); }
.v2-tabbed__tab.is-active {
  color: var(--ink, #464646);
  background: var(--paper2, #e8e5d0);
  border-color: var(--line, #afafaa);
}
.v2-tabbed__body { flex: 1 1 auto; min-height: 0; overflow: auto; }
.v2-tabbed__placeholder {
  color: var(--ink2, #888);
  padding: 28px 16px;
  text-align: center;
  font-style: italic;
}
/* A deferred tab that could not be fetched: the reason, and the way to ask again. */
.v2-tabbed__retry {
  font: inherit; font-size: 12px; padding: 4px 12px; margin-top: 6px; border-radius: 5px;
  border: 1px solid var(--line, #afafaa); background: var(--paper2, #e8e5d0);
  color: var(--ink, #464646); cursor: pointer;
}
/* SAMRAS structure tool: the txa/msn/lcl selector bar above the node tree. */
.v2-samras__bar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.v2-samras__label { font-size: 12px; color: var(--ink2); display: inline-flex; align-items: center; gap: 6px; }
.v2-samras__select {
  font: inherit; font-size: 12px; padding: 2px 6px; border-radius: 5px;
  border: 1px solid var(--line); background: var(--paper2); color: var(--ink); cursor: pointer;
}
.v2-samras__note { font-size: 11px; font-style: italic; color: var(--ink2); }
.v2-txatree__node.is-empty > summary .v2-txatree__label,
.v2-txatree__leaf.is-empty { color: var(--ink2); font-style: italic; }

/* ext_resources — the shared site-core asset library (profiles contact-app,
   galleries, upload, icon dedup). Rendered inside its extension card. */
.v2-resourcesApp { display: flex; flex-direction: column; gap: 12px; }
.v2-resourcesApp h4 { margin: 4px 0; font-size: 13px; }
.v2-resourcesThumb {
  width: 36px; height: 36px; border-radius: 50%;
  object-fit: cover; flex: 0 0 36px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(127,127,127,0.18); color: #9aa;
}
.v2-resourcesThumb--lg { width: 64px; height: 64px; flex-basis: 64px; }
.v2-resourcesThumb--xl { width: 120px; height: 120px; flex-basis: 120px; border-radius: 8px; object-fit: contain; }
.v2-resourcesThumb svg { width: 60%; height: 60%; }
.v2-resourcesApp__detail {
  border: 1px solid var(--accent, #1e6c93); border-radius: 8px; padding: 12px;
}
.v2-resourcesDetail__head { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.v2-resourcesDetail__head h4 { flex: 1; margin: 0; }
/* Layered profile detail — header band: base fields (left) beside an enlarged logo. */
.v2-resourcesDetail__head--band { align-items: flex-start; gap: 16px; }
.v2-resourcesDetail__headText { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.v2-resourcesDetail__headText h4 { margin: 0; }
.v2-resourcesDetail__head--band .v2-resourcesThumb--xl { flex: 0 0 auto; }
.v2-resourcesDetail__meta--inline { margin-top: 0; }
/* Typed section block (mirrors .v2-scopeBlock): the "section break" between
   base / legal-entity / agricultural / additional field groups. */
.v2-typedBlock {
  border: 1px solid rgba(127,127,127,0.28); border-radius: 8px;
  padding: 10px 12px; margin-top: 12px;
}
.v2-typedBlock__head {
  margin: 0 0 6px; font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.05em; opacity: 0.85;
}
.v2-resourcesField { display: flex; flex-direction: column; gap: 2px; margin-bottom: 8px; }
.v2-resourcesField input, .v2-resourcesField textarea, .v2-resourcesField select,
.v2-resourcesUploadForm input, .v2-resourcesUploadForm select,
.v2-resourcesApp input[type="text"], .v2-resourcesApp input[type="email"],
.v2-resourcesApp input[type="url"], .v2-resourcesApp input[type="search"],
.v2-resourcesApp input[type="password"], .v2-resourcesApp textarea, .v2-resourcesApp select {
  width: 100%; padding: 5px 7px; font: inherit; box-sizing: border-box;
  border: 1px solid var(--line); border-radius: 5px;
  background: var(--paper); color: var(--ink);
}
.v2-resourcesField--ro { flex-direction: row; gap: 8px; font-size: 12px; }
.v2-resourcesField__label { opacity: 0.65; min-width: 140px; }
.v2-resourcesDetail__actions { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.v2-resourcesDetail__result { font-size: 12px; opacity: 0.85; }
.v2-resourcesUpload, .v2-resourcesDedup { font-size: 12px; }
.v2-resourcesUploadForm { display: flex; flex-direction: column; gap: 6px; padding: 8px 0; }
.v2-resourcesUploadForm label { display: flex; flex-direction: column; gap: 2px; }
.v2-resourcesDedup__locked { opacity: 0.6; font-style: italic; }
/* Delete-protected "where used" detail + allocation In-use/Available split.
   Theme-aware: only defined vars (--ink/--line/--accent), no --surface/#fff. */
.v2-resourcesDetail__protected { margin-top: 8px; font-size: 12px; }
.v2-resourcesDetail__usedList { margin: 6px 0; padding-left: 18px; }
.v2-resourcesDetail__usedList li { margin: 2px 0; }
.v2-resourcesDetail__hint { margin: 4px 0 0; opacity: 0.7; }
.v2-resourcesManaged__subhead {
  margin: 8px 0 4px; font-size: 11px; font-weight: 600; letter-spacing: 0.02em;
  text-transform: uppercase; opacity: 0.7; color: var(--ink);
}
.v2-resourcesManaged__divider { border: 0; border-top: 1px solid var(--line); margin: 10px 0; }
/* Unified, theme-aware resource controls — one convention for every button.
   Uses ONLY defined theme vars (--paper/--paper2/--ink/--line/--accent), so it
   reads correctly on light (Paper/Ocean/Forest) AND dark (Midnight) themes.
   NEVER use --surface/--border (undefined → black box) or hardcoded #fff/#222. */
.v2-resourcesApp button.v2-rowAction,
.v2-resourcesApp button.v2-rowAction--primary,
.v2-resourcesApp button.v2-rowAction--secondary,
.v2-resourcesApp button.v2-rowAction--danger,
.v2-resourcesUploadForm button {
  padding: 4px 11px; border-radius: 5px; cursor: pointer; font: inherit;
  border: 1px solid var(--line); background: var(--paper2); color: var(--ink);
}
.v2-resourcesApp button.v2-rowAction:hover,
.v2-resourcesApp button.v2-rowAction--primary:hover,
.v2-resourcesApp button.v2-rowAction--secondary:hover,
.v2-resourcesApp button.v2-rowAction--danger:hover,
.v2-resourcesUploadForm button:hover { background: var(--paper); }
.v2-resourcesApp button.v2-rowAction--primary,
.v2-resourcesUploadForm button { border-color: var(--accent); color: var(--accent); font-weight: 600; }
/* The shared component-library form's submit button (the profile editor's
   "Save & publish") renders unstyled by default — unify it with the primary
   resource button so it matches the rest and is theme-aware (not browser gray). */
.v2-resourcesApp .v2-form__submit {
  padding: 5px 14px; border-radius: 5px; cursor: pointer; font: inherit; font-weight: 600;
  border: 1px solid var(--accent); background: var(--paper2); color: var(--accent);
}
.v2-resourcesApp .v2-form__submit:hover { background: var(--paper); }
.v2-resourcesApp button.v2-rowAction--danger { border-color: var(--danger); color: var(--danger); }

/* Refactor: GLOBAL "Overall" grantee-selector entry + collective gallery mgmt. */
.v2-granteeSelector__option.is-overall {
  font-weight: 600;
  border-style: dashed;
}
.v2-resourcesSearch {
  width: 100%; box-sizing: border-box; margin: 6px 0 10px;
  padding: 7px 10px; border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--paper); color: var(--ink); font: inherit;
}
.v2-resourcesManaged { font-size: 12px; margin: 4px 0; }
.v2-resourcesManaged > summary { cursor: pointer; font-weight: 600; padding: 4px 0; }
.v2-resourcesManaged__groups {
  display: flex; flex-direction: column; gap: 8px;
  margin-top: 6px; max-height: 460px; overflow-y: auto;
}
.v2-resourcesGroup {
  border: 1px solid var(--line, #afafaa); border-radius: 6px;
  padding: 6px 8px; background: var(--paper2, #e8e5d0);
}
.v2-resourcesGroup__head {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-bottom: 4px;
}
.v2-resourcesGroup__slug { font-weight: 600; color: var(--ink, #464646); }
.v2-resourcesGroup__count { color: var(--ink2, #888888); }
.v2-resourcesMember {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: 3px 0;
}
.v2-resourcesMember__file { font-size: 11px; word-break: break-all; flex: 1 1 auto; }
.v2-resourcesMember__actions { display: flex; gap: 4px; flex-shrink: 0; }
.v2-resourcesMember__badge {
  font-size: 10px; padding: 1px 6px; border-radius: 8px;
  border: 1px solid var(--line, #afafaa); color: var(--ink2, #888888);
}
.v2-resourcesThumb--sm { width: 22px; height: 22px; flex-basis: 22px; }
.v2-resourcesMember.is-allocated { background: rgba(30,108,147,0.08); border-radius: 4px; }

/* Two-pane master/detail Resource library (faceted search + list on the left,
   view/edit on the right). Theme-aware throughout. */
.v2-resourcesTwoPane { display: flex; gap: 12px; align-items: flex-start; margin-top: 6px; }
.v2-resourcesPane { min-width: 0; }
.v2-resourcesPane--list { flex: 0 0 44%; max-width: 44%; }
.v2-resourcesPane--detail {
  flex: 1 1 56%; min-width: 0; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--paper2);
}
@media (max-width: 860px) {
  .v2-resourcesTwoPane { flex-direction: column; }
  .v2-resourcesPane--list, .v2-resourcesPane--detail { flex-basis: auto; max-width: none; width: 100%; }
}
.v2-facetBar { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.v2-facetRow { display: flex; flex-wrap: wrap; gap: 6px; align-items: flex-end; }
.v2-facet { display: flex; flex-direction: column; gap: 2px; font-size: 10px; color: var(--ink2); }
.v2-facet select {
  font: inherit; font-size: 12px; padding: 3px 6px; border-radius: 5px;
  border: 1px solid var(--line); background: var(--paper); color: var(--ink);
}
.v2-facet__sort { align-self: flex-end; }
.v2-leafletList { max-height: 520px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.v2-leafletList__count { font-size: 10px; color: var(--ink2); padding: 2px 4px; }
.v2-leafletItem {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  padding: 5px 8px; border: 1px solid transparent; border-radius: 6px;
  background: none; color: var(--ink); cursor: pointer; font: inherit;
}
.v2-leafletItem:hover { background: var(--paper2); }
.v2-leafletItem.is-active { background: var(--paper2); border-color: var(--accent); }
.v2-leafletItem__text { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.v2-leafletItem__title { font-weight: 600; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.v2-leafletItem__sub { font-size: 10px; color: var(--ink2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.v2-resourcesThumb--dot { border: 1px dashed var(--line); border-radius: 4px; background: var(--paper); }
.v2-resourcesDetail__placeholder { color: var(--ink2); font-size: 12px; }
.v2-resourcesDetail__result { font-size: 12px; color: var(--ink2); margin-top: 6px; display: block; }
.v2-resourcesDetail__meta { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.v2-resourcesDetail__meta .v2-resourcesField label {
  font-size: 11px; font-weight: 600; color: var(--ink2, #888888);
}
.v2-resourcesDetail__meta .v2-resourcesField > div { word-break: break-all; }

/* ============================================================================
 * Datum-displayer frame (Stream C) — standardized PRESENTATIONAL wrapper for
 * every datum displayer: identity · address · body · actions · provenance.
 * Purely visual; does NOT touch the load→edit→apply mechanism. All colours are
 * spore-print tokens (theme-aware): --paper2 card surface, --coal address well,
 * 1px --line hairlines, --accent (ochre in spore) identity spine, --radius 2px.
 * Text on the dark --coal well uses fixed light values, matching the existing
 * on-coal convention (see .navcol). Appended section — no existing rules changed.
 * ==========================================================================*/
.v2-displayer {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--paper);
}

/* 1. identity header — accent left-spine + glyph tile + name/kind + lifecycle */
.v2-displayer__identity {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px 14px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--paper2);
}
.v2-displayer__spine {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--accent);
}
.v2-displayer__glyph {
  flex: none;
  width: 2.3rem;
  height: 2.3rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
  color: var(--accent);
  font-size: 1.05rem;
  line-height: 1;
}
.v2-displayer__ident {
  min-width: 0;
  flex: 1;
}
.v2-displayer__identLine {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.v2-displayer__name {
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.01em;
  word-break: break-word;
}
/* Rename in place. The name is only editable where the server would accept the
   write (never an anchor), so the affordance appears exactly where it works. A
   dotted underline on hover rather than a visible field: the identity line is a
   heading first, and dressing it as an input permanently would say otherwise. */
.v2-displayer__name[data-rename-target] {
  cursor: text;
  border-bottom: 1px dashed transparent;
}
.v2-displayer__name[data-rename-target]:hover,
.v2-displayer__name[data-rename-target]:focus-visible {
  border-bottom-color: var(--ink2);
  outline: none;
}
.v2-displayer__name.is-busy {
  opacity: 0.5;
}
.v2-displayer__nameInput {
  font: inherit;
  color: var(--ink);
  background: var(--paper2);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: 1px 6px;
  min-width: 14ch;
}
.v2-displayer__renameNote {
  margin-top: 6px;
  font-size: 0.72rem;
  line-height: 1.45;
  color: var(--ink2);
  border-left: 2px solid var(--line);
  padding-left: 8px;
}
/* `--moss`/`--danger` are the portal's existing operational tokens, not new hues —
   the two-accent rule governs ochre and violet, and an operational warning is
   neither place nor network. */
.v2-displayer__renameNote.is-warn {
  border-left-color: var(--accent);
  color: var(--ink);
}
.v2-displayer__renameNote.is-danger {
  border-left-color: var(--danger);
  color: var(--danger);
}
.v2-displayer__renameActions {
  display: flex;
  gap: 6px;
  margin-top: 6px;
}
.v2-displayer__renameActions button {
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  border-radius: 6px;
  padding: 0.2rem 0.6rem;
  font: inherit;
  font-size: 0.72rem;
  cursor: pointer;
}
.v2-displayer__kind {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.56rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 2px 6px;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  color: var(--accent);
}
.v2-displayer__subtitle {
  margin-top: 2px;
  font-size: 0.72rem;
  color: var(--ink2);
}
.v2-displayer__identActions {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
}
.v2-displayer__lifecycle {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.62rem;
  padding: 3px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink2);
  white-space: nowrap;
}
.v2-displayer__lifeMark {
  font-size: 0.7rem;
  line-height: 1;
}
.v2-displayer__lifecycle[data-state="loaded"] {
  color: var(--ink2);
  border-color: var(--line);
}
.v2-displayer__lifecycle[data-state="editing"] {
  color: var(--accent);
  border-color: var(--accent);
}
.v2-displayer__lifecycle[data-state="applied"] {
  color: var(--moss);
  border-color: var(--moss);
}

/* 2. address strip — --coal well, version(=hash) segment accented */
.v2-displayer__address {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 10px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--coal);
}
.v2-displayer__addr {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.82rem;
  color: #f3f2e5; /* light ink on the dark --coal well (theme-invariant) */
  word-break: break-all;
}
.v2-displayer__sep {
  color: rgba(243, 242, 229, 0.5);
}
.v2-displayer__version {
  color: var(--accent);
}
.v2-displayer__addrNote {
  flex: none;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.6rem;
  letter-spacing: 0.05em;
  color: rgba(243, 242, 229, 0.55);
}

/* 3. body — renderer output verbatim; inner grid/row-editor keep their spacing */
.v2-displayer__body {
  flex: 1 1 auto;
  min-height: 0;
}

/* Datum-KIND summary: a derived, read-only kind body the document editor
   prepends ABOVE the authoritative datum grid (card/record today). Additive —
   the grid + row-editor render verbatim below; this only sets it apart. */
.v2-displayer__kindSummary {
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px dashed var(--line);
}

/* 4. actions bar + load→edit→apply stepper (visual only) */
.v2-displayer__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 16px;
  border-top: 1px solid var(--line);
  background: var(--paper2);
}
.v2-displayer__stepper {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.64rem;
  color: var(--ink2);
}
.v2-displayer__step {
  display: inline-flex;
  align-items: center;
}
.v2-displayer__step + .v2-displayer__step::before {
  content: "\2192"; /* → */
  margin-right: 8px;
  color: var(--ink2);
  opacity: 0.6;
}
.v2-displayer__step.is-active {
  color: var(--accent);
  font-weight: 600;
}
.v2-displayer__step.is-done {
  color: var(--moss);
}
.v2-displayer__controls {
  display: flex;
  gap: 8px;
}

/* 5. provenance — muted mono footer row */
.v2-displayer__provenance {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 24px;
  padding: 9px 16px;
  border-top: 1px solid var(--line);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.62rem;
  color: var(--ink2);
}

/* ============================================================================
 * Datum-displayer BODY library — composable kind bodies (Stream C).
 * One body per datum KIND, produced by renderDisplayerBody(kind, payload) and
 * dropped into renderDisplayerFrame's .v2-displayer__body slot. Recreates the
 * delivered design bodies (contact card · profile · record/table · geo map ·
 * tree) in the portal's spore-print tokens. Theme-aware: every colour flows
 * through --accent (Hypha Gold in spore) / --accent2 (violet network ink) /
 * --line / --ink / --ink2 / --coal, so paper/ocean/forest/midnight/spore all
 * inherit. ADDITIVE — no existing renderer's markup/classes are touched.
 * ==========================================================================*/
.v2-displayer__body--card,
.v2-displayer__body--profile,
.v2-displayer__body--record,
.v2-displayer__body--map,
.v2-displayer__body--tree,
.v2-displayer__body--unknown {
  padding: 16px;
}
.v2-displayer__body--unknown {
  color: var(--ink2);
  font-size: 0.82rem;
}
/* Trailing caption under a body ("Contact card — the minimal artifact …"). */
.v2-dispNote {
  margin: 14px 0 0;
  font-size: 0.66rem;
  line-height: 1.45;
  color: var(--ink2);
  opacity: 0.85;
}

/* Shared key/value grid — contact card, map coordinates, profile attributes. */
.v2-dispKv {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--line);
}
.v2-dispKv__row {
  display: grid;
  grid-template-columns: minmax(0, 12rem) 1fr;
  gap: 16px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
  font-size: 0.86rem;
  align-items: start;
}
.v2-dispKv__row:last-child {
  border-bottom: 0;
}
.v2-dispKv__key {
  font-size: 0.64rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink2);
  overflow-wrap: anywhere;
  min-width: 0;
}
.v2-dispKv__val {
  color: var(--ink);
  word-break: break-word;
}
.v2-dispKv__val--mono {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
}
.v2-dispKv__val--accent {
  color: var(--accent);
}

/* card — flat contact artifact the registry publishes. */
.v2-displayer__body--card .v2-dispKv {
  border-top: 1px solid var(--line);
}

/* profile — prose + tag chips (left) beside an attribute list (right). */
.v2-dispProfile {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}
.v2-dispProfile__prose {
  flex: 1 1 15rem;
  min-width: 15rem;
}
.v2-dispProfile__text {
  margin: 0 0 12px;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--ink);
}
.v2-dispProfile__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.v2-dispChip {
  font-size: 0.6rem;
  line-height: 1;
  padding: 4px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--accent);
}
.v2-dispProfile__attrs {
  flex: 1 1 14rem;
  min-width: 14rem;
}
.v2-dispProfile__attrs .v2-dispKv__row {
  grid-template-columns: 7rem 1fr;
  gap: 12px;
  font-size: 0.82rem;
}

/* record / table — operational ledger: meta header · columnar table · total. */
.v2-dispRecord__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 32px;
  margin-bottom: 12px;
}
.v2-dispRecord__metaItem {
  font-size: 0.78rem;
}
.v2-dispRecord__metaKey {
  display: block;
  font-size: 0.6rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink2);
}
.v2-dispRecord__metaVal {
  color: var(--ink);
}
.v2-dispRecord__wrap {
  border: 1px solid var(--line);
  overflow-x: auto;
}
.v2-dispRecord__table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.76rem;
}
.v2-dispRecord__table th {
  text-align: left;
  padding: 9px 10px;
  border-bottom: 1px solid var(--line);
  font-size: 0.58rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink2);
}
.v2-dispRecord__table td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
}
.v2-dispRecord__table tbody tr:last-child td {
  border-bottom: 0;
}
.v2-dispRecord__table th.is-num,
.v2-dispRecord__table td.is-num {
  text-align: right;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-variant-numeric: tabular-nums;
}
.v2-dispRecord__table tr.is-flagged td {
  color: var(--accent);
}
.v2-dispRecord__total td {
  border-top: 1px solid var(--line);
  padding: 10px;
}
.v2-dispRecord__totalLabel {
  text-align: right;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink2);
}
.v2-dispRecord__totalVal {
  text-align: right;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.9rem;
  color: var(--accent);
}
.v2-dispRecord__empty {
  padding: 8px 0;
  color: var(--ink2);
  font-size: 0.82rem;
}

/* geo map — hand-authored SVG geometry beside a coordinate field list. */
.v2-dispMap {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}
.v2-dispMap__canvas {
  position: relative;
  overflow: hidden;
  aspect-ratio: 16 / 10;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--coal);
}
.v2-dispMap__canvas svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.v2-dispMap__parcel {
  fill: color-mix(in srgb, var(--paper2) 65%, var(--coal));
  stroke: var(--line);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.v2-dispMap__field {
  fill: color-mix(in srgb, var(--accent) 20%, var(--coal));
  stroke: var(--accent);
  stroke-width: 1.2;
  vector-effect: non-scaling-stroke;
}
.v2-dispMap__link {
  fill: none;
  stroke: var(--line);
  stroke-width: 1.2;
  vector-effect: non-scaling-stroke;
}
.v2-dispMap__pt {
  fill: var(--ink2);
  opacity: 0.6;
}
.v2-dispMap__node {
  fill: var(--accent);
  stroke: var(--paper);
  stroke-width: 1.5;
}
.v2-dispMap__nodeLabel {
  fill: var(--ink);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 4.5px;
}
.v2-dispMap__fields .v2-dispKv__row {
  grid-template-columns: 5.5rem 1fr;
  gap: 12px;
  font-size: 0.8rem;
}
@media (max-width: 34rem) {
  .v2-dispMap {
    grid-template-columns: 1fr;
  }
}

/* tree — nested txa nodes; mycelial indent spine; violet leaf border. */
.v2-dispTree {
  border: 1px solid var(--line);
}
.v2-dispTree__row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
}
.v2-dispTree__node:last-child > .v2-dispTree__row {
  border-bottom: 0;
}
.v2-dispTree__caret {
  flex: none;
  width: 0.8rem;
  text-align: center;
  color: var(--accent);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.7rem;
  line-height: 1;
}
.v2-dispTree__label {
  color: var(--ink);
}
.v2-dispTree__label i {
  font-style: italic;
}
.v2-dispTree__addr {
  margin-left: auto;
  padding-left: 10px;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.64rem;
  color: var(--ink2);
}
.v2-dispTree__children {
  margin-left: 0.85rem;
  padding-left: 0.85rem;
  border-left: 1px solid var(--line);
}
.v2-dispTree__row--leaf {
  border-left: 2px solid var(--accent2);
}

/* ------------------------------------------------------------------------- */
/* Network > Browser — the msn_id browser (v2_portal_network_browser.js).     */
/* Three panes: regions to navigate, nodes to select, and the selected node's */
/* msn_profile. The panes collapse to one column below 1100px rather than     */
/* scrolling the page sideways.                                              */
/* ------------------------------------------------------------------------- */
.v2-browser {
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}
.v2-browser__modebar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 8px 10px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 8px;
  background: var(--ide-panel-bg, #fff);
}
.v2-browser__modelabel {
  font: 600 11px/1 system-ui, sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  opacity: 0.7;
}
.v2-browser__mode {
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 999px;
  background: transparent;
  padding: 3px 12px;
  font-size: 12px;
  cursor: pointer;
}
.v2-browser__mode.is-active {
  background: var(--ide-accent, #115f45);
  border-color: var(--ide-accent, #115f45);
  color: #fff;
}
.v2-browser__why {
  font-size: 12px;
  opacity: 0.75;
  flex: 1 1 260px;
  min-width: 0;
}
.v2-browser__panes {
  display: grid;
  grid-template-columns: minmax(200px, 240px) minmax(240px, 320px) minmax(0, 1fr);
  gap: 12px;
  align-items: start;
  min-width: 0;
}
.v2-browser__regions,
.v2-browser__nodes,
.v2-browser__profile {
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 8px;
  background: var(--ide-panel-bg, #fff);
  padding: 10px 12px;
  min-width: 0;
}
.v2-browser__regions h3,
.v2-browser__nodes h3,
.v2-browser__profile h3 {
  margin: 0 0 8px;
  font-size: 13px;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}
.v2-browser__nodes h3 small,
.v2-browser__profileSection h4 small {
  font-weight: 400;
  opacity: 0.6;
  font-size: 11px;
}
.v2-browser__regionList,
.v2-browser__nodeList {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 62vh;
  overflow-y: auto;
}
.v2-browser__region button,
.v2-browser__node button {
  width: 100%;
  text-align: left;
  background: transparent;
  border: 0;
  border-radius: 6px;
  padding: 5px 7px;
  cursor: pointer;
  font-size: 12px;
  display: flex;
  gap: 6px;
  align-items: baseline;
}
.v2-browser__region button:hover,
.v2-browser__node button:hover {
  background: rgba(127, 127, 127, 0.12);
}
.v2-browser__region.is-child button {
  padding-left: 20px;
  font-size: 11.5px;
  opacity: 0.85;
}
.v2-browser__region.is-active > button,
.v2-browser__node.is-active > button {
  background: rgba(17, 95, 69, 0.14);
  font-weight: 600;
}
.v2-browser__regionName {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.v2-browser__regionKind {
  font-size: 10px;
  opacity: 0.55;
}
.v2-browser__regionCount {
  font-variant-numeric: tabular-nums;
  opacity: 0.6;
  font-size: 11px;
}
.v2-browser__clear {
  background: transparent;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 6px;
  font-size: 11px;
  padding: 3px 8px;
  margin-bottom: 6px;
  cursor: pointer;
}
.v2-browser__filter {
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 6px;
  padding: 5px 8px;
  font-size: 12px;
  border: 1px solid var(--ide-border, #d8dee4);
  border-radius: 6px;
}
.v2-browser__node button {
  flex-direction: column;
  gap: 2px;
}
.v2-browser__nodeTitle {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.v2-browser__nodeMeta {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 10.5px;
  opacity: 0.7;
}
/* Entity class colours are the operator's mark: colour encodes WHO, not what. */
.v2-browser__kind {
  font-style: normal;
  border-radius: 999px;
  padding: 0 6px;
  color: #fff;
  background: #6b7280;
}
.v2-browser__kind--legal { background: #a32023; }
.v2-browser__kind--administrative { background: #d89c1f; }
.v2-browser__kind--informal { background: #3f1f4a; }
.v2-browser__kind--natural { background: #115f45; }
.v2-browser__empty {
  font-size: 12px;
  opacity: 0.65;
  padding: 6px 7px;
}
.v2-browser__profile {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 72vh;
  overflow-y: auto;
}
.v2-browser__profileSection h4 {
  margin: 0 0 8px;
  font-size: 12.5px;
  display: flex;
  justify-content: space-between;
  gap: 8px;
  align-items: baseline;
}
.v2-browser__profileRow {
  border-top: 1px solid var(--ide-border, #d8dee4);
  padding-top: 6px;
  margin-top: 6px;
}
.v2-browser__profileRow:first-of-type {
  border-top: 0;
  margin-top: 0;
}
.v2-browser__profileRow h5 {
  margin: 0 0 4px;
  font-size: 12px;
  display: flex;
  gap: 8px;
  align-items: baseline;
}
.v2-browser__profileRow h5 small {
  font-weight: 400;
  opacity: 0.55;
  font-variant-numeric: tabular-nums;
}
.v2-browser__visit {
  margin-top: 10px;
  border: 1px solid var(--ide-accent, #115f45);
  color: var(--ide-accent, #115f45);
  background: transparent;
  border-radius: 6px;
  padding: 4px 12px;
  font-size: 12px;
  cursor: pointer;
}
.v2-browser__visit:hover {
  background: var(--ide-accent, #115f45);
  color: #fff;
}
@media (max-width: 1100px) {
  .v2-browser__panes { grid-template-columns: minmax(0, 1fr); }
  .v2-browser__regionList,
  .v2-browser__nodeList { max-height: 34vh; }
}

/* The no-URL site overlay. There is deliberately no address bar: navigation is
   msn_id-based, and a URL is a dead end that exits back to the browser. */
.v2-browserOverlay {
  position: fixed;
  inset: 0;
  background: rgba(12, 14, 16, 0.62);
  z-index: 1200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.v2-browserOverlay__frame {
  background: var(--ide-panel-bg, #fff);
  border-radius: 10px;
  width: min(1180px, 100%);
  height: min(88vh, 100%);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.35);
}
.v2-browserOverlay__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--ide-border, #d8dee4);
}
.v2-browserOverlay__title {
  font-weight: 600;
  font-size: 13px;
}
.v2-browserOverlay__exit {
  border: 1px solid var(--ide-border, #d8dee4);
  background: transparent;
  border-radius: 6px;
  padding: 4px 12px;
  font-size: 12px;
  cursor: pointer;
}
.v2-browserOverlay__body {
  flex: 1 1 auto;
  position: relative;
  min-height: 0;
}
.v2-browserOverlay__site {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
.v2-browserOverlay__refused {
  margin: 0;
  padding: 24px;
  font-size: 13px;
  line-height: 1.5;
}

/* ── Place: the geospatial profile shown as an aspect of an entity profile ─── */
.v2-place__table { width: 100%; border-collapse: collapse; font-size: 12px; }
.v2-place__table td { padding: 3px 8px; border-bottom: 1px solid var(--ide-border, #d8dee4); }
.v2-place__band { color: var(--ink2); text-transform: lowercase; white-space: nowrap; }
.v2-place__node { font-family: var(--mono, monospace); font-size: 11px; color: var(--ink2); }
.v2-place__outline { text-align: right; color: var(--ink2); font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; }
.v2-place__list { list-style: none; margin: 0; padding: 0; }
.v2-place__list li { display: flex; justify-content: space-between; gap: 8px; padding: 2px 0; border-bottom: 1px solid var(--ide-border, #d8dee4); }
.v2-place__link { border: 0; background: none; padding: 0; color: var(--ink); font-size: 12px; text-align: left; cursor: pointer; }
.v2-place__link:hover { text-decoration: underline; }
.v2-place__kind { color: var(--ink2); font-size: 11px; }

/* ===== Hosted channels (convention 2026-08-02) ============================
   The interface search badges channels; a channel session renders in the
   workbench (and, since 2026-08-21, inside the profile page's channel
   cards). */
.portal-tool-palette__kind {
  display: inline-block;
  margin-left: 6px;
  padding: 0 5px;
  border: 1px solid currentColor;
  border-radius: 8px;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.75;
  vertical-align: 1px;
}
.channel-session { display: flex; flex-direction: column; gap: 10px; font-size: 13px; }
.channel-session__head { margin: 0; }
.channel-session__title { margin: 0; font-size: 16px; display: flex; align-items: center; gap: 8px; }
.channel-session__access {
  font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
  padding: 1px 6px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 8px;
  color: var(--ink2);
}
.channel-session__summary { margin: 2px 0 0; color: var(--ink2); font-size: 12px; }
.channel-session__tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--ide-border, #d8dee4); }
.channel-session__tab {
  border: 0; background: none; padding: 5px 12px; cursor: pointer; font-size: 12px;
  text-transform: capitalize; color: var(--ink2); border-bottom: 2px solid transparent;
}
.channel-session__tab.is-active { color: var(--ink); border-bottom-color: currentColor; font-weight: 600; }
.channel-session__pane { display: flex; flex-direction: column; gap: 12px; }
/* display:flex beats the [hidden] UA default, so say it explicitly — the
   renderer hides inactive tab panes with the attribute. */
.channel-session__pane[hidden] { display: none; }
.channel-session__empty { color: var(--ink2); font-size: 12px; margin: 8px 0; }
.channel-session__coverage { color: var(--ink2); font-size: 11px; margin: 4px 0 0; border-top: 1px solid var(--ide-border, #d8dee4); padding-top: 6px; }
.channel-session__note { color: var(--ink2); font-size: 11px; margin: 2px 0 0; font-style: italic; }
.channel-demand__controls { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 8px; }
.channel-demand__control { display: flex; flex-direction: column; gap: 2px; font-size: 11px; color: var(--ink2); min-width: 0; max-width: 100%; }
.channel-demand__control select { font-size: 12px; padding: 2px 4px; max-width: 100%; }
.channel-demand__product { border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px; padding: 8px 10px; }
.channel-demand__productHead { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.channel-demand__productHead small { color: var(--ink2); }
.channel-demand__taxon { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; color: var(--ink2); opacity: .75; }
.channel-demand__tag { font-size: 11px; letter-spacing: .04em; text-transform: uppercase; border: 1px solid currentColor; border-radius: 999px; padding: 0 6px; opacity: .7; }
.channel-demand__chart { width: 100%; height: auto; display: block; margin-top: 4px; }
.channel-demand__bar { fill: var(--accent, #4a7c59); opacity: 0.85; }
.channel-demand__whisker { stroke: var(--ink2, #667); stroke-width: 2; opacity: 0.5; }
.channel-demand__axis { stroke: var(--ide-border, #d8dee4); stroke-width: 1; }
.channel-demand__axisLabel { font-size: 9px; fill: var(--ink2, #667); }
.channel-demand__lots { width: 100%; border-collapse: collapse; font-size: 11px; margin-top: 6px; }
.channel-demand__lots th { text-align: left; color: var(--ink2); font-weight: 500; padding: 2px 6px; border-bottom: 1px solid var(--ide-border, #d8dee4); }
.channel-demand__lots td { padding: 2px 6px; border-bottom: 1px solid var(--ide-border, #d8dee4); }

/* Sources panel (sources resolver 2026-08-02). The verdict is the point of the
   surface, so a stale row must not look like a current one — the chip carries
   the colour and the row tints behind it. */
.v2-sources { display: flex; flex-direction: column; gap: 10px; }
.v2-sources__title { margin: 0; font-size: 15px; }
.v2-sources__summary { margin: 2px 0 0; color: var(--ink2); font-size: 12px; }
.v2-sources__coverage { margin: 0; color: var(--ink2); font-size: 12px; }
.v2-sources__warn { margin: 0; color: var(--warn); font-size: 12px; }
.v2-sources__empty { color: var(--ink2); font-size: 12px; margin: 8px 0; }
.v2-sources__detail { color: var(--ink2); font-size: 11px; margin: 2px 0 0; }
.v2-sources__table { width: 100%; border-collapse: collapse; font-size: 12px; }
.v2-sources__table th { text-align: left; color: var(--ink2); font-weight: 500;
  padding: 3px 8px; border-bottom: 1px solid var(--ide-border, #d8dee4); }
.v2-sources__table td { padding: 4px 8px; border-bottom: 1px solid var(--ide-border, #d8dee4);
  vertical-align: top; }
.v2-sources__row.is-stale { background: color-mix(in srgb, var(--danger) 8%, transparent); }
.v2-sources__row.is-missing { background: color-mix(in srgb, var(--warn) 8%, transparent); }
.v2-sources__chip { font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em;
  border: 1px solid currentColor; border-radius: 999px; padding: 1px 7px; white-space: nowrap; }
.v2-sources__chip--fresh { color: var(--moss); }
.v2-sources__chip--stale { color: var(--danger); }
.v2-sources__chip--missing { color: var(--warn); }
.v2-sources__chip--unverifiable { color: var(--ink2); }
.v2-sources__actions { display: flex; gap: 6px; white-space: nowrap; }
.v2-sources__undeclared { font-size: 12px; color: var(--ink2); }
.v2-sources__addList { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }

/* Channel profiles tab — AGNET's producers, hubs and consumers (2026-11-12). One colour per
   type group, the same on the map and on the cards; a live profile's dot is larger and
   ringed. The viewer emits this class contract; the site carries its own copy. */
.channel-profiles__totals { margin: 4px 0 0; color: var(--ink2); font-size: 12px; }
.channel-profiles__controls { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.channel-profiles__search { flex: 1 1 220px; min-width: 0; font: inherit; font-size: 13px; padding: 5px 8px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px; background: transparent; color: inherit; }
.channel-profiles__select { flex: 0 1 auto; max-width: 100%; font: inherit; font-size: 13px; padding: 4px 6px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px; background: transparent; color: inherit; }
.channel-profiles__chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.channel-profiles__chip { display: inline-flex; align-items: center; gap: 6px; font: inherit; font-size: 12px; padding: 3px 9px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 999px; background: transparent; color: inherit; cursor: pointer; }
.channel-profiles__chip[aria-pressed="true"] { border-color: currentColor; font-weight: 600; }
.channel-profiles__chip:focus-visible { outline: 2px solid var(--moss, #4f8a3c); outline-offset: 2px; }
.channel-profiles__swatch { display: inline-block; width: 10px; height: 10px; border-radius: 50%; flex: none; background: var(--agnet-swatch); }
.channel-profiles__swatch--producer { --agnet-swatch: #4f8a3c; }
.channel-profiles__swatch--hub { --agnet-swatch: #c98a1b; }
.channel-profiles__swatch--consumer { --agnet-swatch: #2f73b8; }
.channel-profiles__swatch--seed_supplier { --agnet-swatch: #8a5cb8; }
.channel-profiles__swatch--organization { --agnet-swatch: #7d7d7d; }
.channel-profiles__swatch--administrative_sponsor { --agnet-swatch: #5b7088; }
.channel-profiles__swatch--other { --agnet-swatch: #9a9a9a; }
.channel-profiles__map { margin: 10px 0 0; }
.channel-profiles__mapSvg { display: block; width: 100%; height: auto; max-height: min(600px, 70vh); }
.channel-profiles__mapGround { fill: transparent; stroke: var(--ide-border, #d8dee4); stroke-width: 2; }
.channel-profiles__dot { fill: var(--agnet-swatch); fill-opacity: 0.9; stroke: var(--ide-surface, #fff); stroke-width: 2px; vector-effect: non-scaling-stroke; cursor: pointer; outline: none; }
.channel-profiles__dot.is-live { fill-opacity: 1; stroke: var(--ide-text, #1f2328); stroke-width: 3px; }
.channel-profiles__dot:hover, .channel-profiles__dot:focus-visible { stroke: var(--moss, #4f8a3c); stroke-width: 4px; }
.channel-profiles__place { fill: var(--ide-text, #1f2328); fill-opacity: 0.8; font-weight: 600; stroke: var(--ide-surface, #fff); stroke-width: 3px; stroke-opacity: 0.85; paint-order: stroke; vector-effect: non-scaling-stroke; pointer-events: none; }
.channel-profiles__shown { margin: 6px 0 0; color: var(--ink2); font-size: 12px; }
.channel-profiles__cards { list-style: none; margin: 6px 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 8px; max-height: 520px; overflow-y: auto; }
.channel-profiles__card { min-width: 0; padding: 7px 9px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px; font-size: 12px; }
.channel-profiles__card.is-picked { border-color: currentColor; }
.channel-profiles__cardHead { display: flex; align-items: baseline; gap: 6px; }
.channel-profiles__name { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.channel-profiles__live { margin-left: auto; font-size: 11px; font-weight: 600; color: var(--moss, #4f8a3c); }
.channel-profiles__type, .channel-profiles__where, .channel-profiles__owners, .channel-profiles__note { margin: 2px 0 0; color: var(--ink2); font-size: 11px; }
.channel-profiles__type::first-letter { text-transform: uppercase; }
.channel-profiles__site { display: inline-block; margin-top: 2px; font-size: 11px; overflow-wrap: anywhere; }

/* Channel session — TAXONOMY tab (the txa tree absorbed from taxonomy_domain).
   The viewer emits this class contract and no styles; these are the portal's
   tokens for it. The site carries its own copy of the same contract. */
.channel-taxonomy__controls { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; margin-top: 6px; }
.channel-taxonomy__search { font: inherit; font-size: 12px; padding: 3px 6px; min-width: 18rem; background: var(--ide-surface, #fff); color: inherit; border: 1px solid var(--ide-border, #d8dee4); border-radius: 4px; }
.channel-taxonomy__all { font: inherit; font-size: 11px; padding: 3px 8px; color: var(--ink2); background: none; border: 1px solid var(--ide-border, #d8dee4); border-radius: 4px; cursor: pointer; }
.channel-taxonomy__all:hover { color: inherit; }
.channel-taxonomy__totals { margin: 4px 0 0; color: var(--ink2); font-size: 11px; }
.channel-taxonomy__host { max-height: 560px; overflow: auto; border: 1px solid var(--ide-border, #d8dee4); border-radius: 6px; padding: 6px 8px; }
.channel-taxonomy__level { list-style: none; margin: 0; padding: 0 0 0 14px; }
/* The root level carries no indent; every level below it steps once. A rule that
   indented the root would push the whole tree off its own gutter. */
.channel-taxonomy__host > .channel-taxonomy__level { padding-left: 0; }
.channel-taxonomy__level--flat { padding-left: 0; }
.channel-taxonomy__node { margin: 0; }
.channel-taxonomy__head { display: flex; align-items: baseline; gap: 6px; padding: 1px 0; font-size: 12px; }
.channel-taxonomy__toggle { width: 16px; flex: 0 0 16px; font: inherit; font-size: 10px; line-height: 1; padding: 0; color: var(--ink2); background: none; border: none; cursor: pointer; text-align: left; }
.channel-taxonomy__toggle--leaf { cursor: default; }
.channel-taxonomy__icon { width: 16px; height: 16px; flex: 0 0 16px; align-self: center; }
.channel-taxonomy__icon--inherited { opacity: 0.5; }
.channel-taxonomy__names { display: inline-flex; align-items: baseline; gap: 6px; min-width: 0; }
.channel-taxonomy__label { font-weight: 500; }
.channel-taxonomy__sci { color: var(--ink2); font-size: 11px; }
.channel-taxonomy__addr { color: var(--ink2); font-size: 10px; opacity: 0.75; }
.channel-taxonomy__count { color: var(--ink2); font-size: 10px; border: 1px solid var(--ide-border, #d8dee4); border-radius: 999px; padding: 0 5px; }
.channel-taxonomy__tag { font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--accent, #b0762f); border: 1px solid currentColor; border-radius: 999px; padding: 0 5px; }
.channel-taxonomy__node.is-traded > .channel-taxonomy__head .channel-taxonomy__label { color: var(--accent, #b0762f); }
.channel-taxonomy__products { list-style: none; margin: 0 0 2px; padding: 0 0 0 36px; }
.channel-taxonomy__product { display: flex; gap: 8px; align-items: baseline; font-size: 11px; color: var(--ink2); }
.channel-taxonomy__productName { color: inherit; }
.channel-taxonomy__productCount { opacity: 0.8; }

/* ===== Viewscopes (v2_portal_viewscope.js) ===================================== */
/* A viewscope draws a document as the thing it is. It renders into the visualization
   panel and draws no chrome of its own — the viewer owns its mount, chrome goes beside it.
   Everything here is ink on paper except the spine, which is the one coloured element. */

.v2-viewscope { display: flex; gap: 12px; align-items: stretch; padding: 4px 0; }
.v2-viewscope__body { flex: 1 1 auto; min-width: 0; }

/* The signature: a filament down the left edge, tinted by ABSTRACTION LAYER. A row is
   literally a filament here — one row of (rf.<babelette>, value) cells — and the layer is
   real information otherwise readable only by parsing the address. Also the way in: it
   opens the datum overlay at the address it names. */
.v2-viewscope__spine {
  flex: 0 0 auto; width: 3px; min-height: 100%; padding: 0; border: 0; border-radius: 2px;
  background: var(--ink2); opacity: 0.55; cursor: pointer; align-self: stretch;
}
.v2-viewscope__spine:hover, .v2-viewscope__spine:focus-visible { opacity: 1; }
.v2-viewscope__spine:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.v2-viewscope__spine[data-layer="0"] { background: var(--ink2); }
.v2-viewscope__spine[data-layer="1"] { background: var(--accent2); }
.v2-viewscope__spine[data-layer="2"] { background: var(--accent2); }
.v2-viewscope__spine[data-layer="3"] { background: var(--accent); }
.v2-viewscope__spine[data-layer="4"] { background: var(--accent); }
.v2-viewscope__spine[data-layer="5"] { background: var(--accent); opacity: 0.8; }
.v2-viewscope__spine[data-layer="6"] { background: var(--accent); opacity: 0.7; }
.v2-viewscope__spine[data-layer="7"] { background: var(--ink); }

.v2-viewscope__head {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline;
  padding-bottom: 8px; margin-bottom: 12px; border-bottom: 1px solid var(--panel-border, #d8d4bc);
}
.v2-viewscope__archetype {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
  color: var(--accent); letter-spacing: 0.02em;
}
.v2-viewscope__doc { font-size: 13px; font-weight: 600; color: var(--ink); }
.v2-viewscope__count { font-size: 11px; color: var(--ink2); margin-left: auto; }
.v2-viewscope__note { flex: 1 0 100%; margin: 4px 0 0; font-size: 11px; color: var(--ink2); }

.v2-viewscope__group { margin-bottom: 16px; }
.v2-viewscope__groupName {
  margin: 0 0 6px; font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--ink2);
}
.v2-viewscope__slots { display: grid; gap: 8px 20px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.v2-viewscope__slot { min-width: 0; }
.v2-viewscope__pair { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* Editing a datum row through its viewscope. The bar sits under the header so the archetype
   and the row count are read BEFORE the affordance to change them. */
.v2-viewscope__editbar { display: flex; gap: 6px; margin: 8px 0 4px; }
.v2-viewscope__edit,
.v2-viewscope__save,
.v2-viewscope__cancel {
  padding: 3px 10px;
  font-size: 0.82em;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--panel-bg, #1a1a1a);
  color: inherit;
  cursor: pointer;
}
.v2-viewscope__save { border-color: var(--accent, #c8873f); }
/* An ACT on the subject (viewscope `acts`): the same bar shape as editing, drawn beside
   it, because both are things a person does to this one row. */
.v2-viewscope__acts { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 4px; }
.v2-viewscope__act {
  padding: 3px 10px;
  font-size: 0.82em;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--panel-bg, #1a1a1a);
  color: inherit;
  cursor: pointer;
}
.v2-viewscope__act:disabled { opacity: 0.6; cursor: progress; }
.v2-viewscope__act .mc-icon { margin-right: 5px; }
.v2-viewscope__input {
  width: 100%;
  padding: 3px 6px;
  background: var(--input-bg);
  color: inherit;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
/* A locked value states WHY it is locked. The reason is the point of the treatment — a
   read-only cell with no explanation is indistinguishable from an input that failed to
   render, which is the confusion this whole distinction exists to prevent. */
.v2-viewscope__pair--locked { opacity: 0.72; }
.v2-viewscope__locked { margin: 1px 0 0; font-size: 0.72em; font-style: italic; opacity: 0.8; }
.v2-viewscope__saveNote { margin: 6px 0 0; font-size: 0.78em; opacity: 0.85; }
.v2-viewscope__saveNote:empty { display: none; }

/* The one added type role: a logical field NAME is an address into a shared vocabulary,
   a value is contingent data. Setting them in different faces states that. */
.v2-viewscope__field {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px; color: var(--ink2); letter-spacing: 0.01em;
}
.v2-viewscope__value { font-size: 13px; color: var(--ink); overflow-wrap: anywhere; }
.v2-viewscope__text { font-size: 15px; line-height: 1.35; color: var(--ink); overflow-wrap: anywhere; }
.v2-viewscope__empty { font-size: 12px; color: var(--ink2); font-style: italic; opacity: 0.75; }
/* An icon_ref DRAWN rather than printed. These are whole leaflet files from the shared
   pool, so unlike the rail's sprite they are not `currentColor` and not themeable — sized
   and aligned only. */
.v2-viewscope__symbol {
  width: 22px; height: 22px; vertical-align: -5px; margin-right: 4px; display: inline-block;
}
.v2-viewscope__chip, .v2-viewscope__coord {
  display: inline-block; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px; padding: 1px 5px; margin: 1px 3px 1px 0;
  background: var(--paper2); border-radius: 3px; color: var(--ink);
}

.v2-viewscope__geometry { display: flex; flex-direction: column; gap: 4px; }
.v2-viewscope__geometryCount { margin: 0; font-size: 15px; color: var(--ink); }
.v2-viewscope__coords { display: flex; flex-wrap: wrap; align-items: baseline; }
.v2-viewscope__more { font-size: 11px; color: var(--ink2); }

/* A slot whose value names another document draws THAT document's viewscope inline —
   the box the brief asks for. Inset so the nesting is visible without a second frame. */
.v2-viewscope__referenceBox {
  border-left: 2px solid var(--panel-border, #d8d4bc); padding-left: 10px;
}
.v2-viewscope__referenceBody { margin-top: 6px; }

.v2-viewscope__tableWrap { overflow-x: auto; }
.v2-viewscope__table { width: 100%; border-collapse: collapse; font-size: 12px; }
.v2-viewscope__table th, .v2-viewscope__table td {
  text-align: left; padding: 4px 8px; border-bottom: 1px solid var(--panel-border, #d8d4bc);
  vertical-align: baseline;
}
.v2-viewscope__table thead th { position: sticky; top: 0; background: var(--paper); }
.v2-viewscope__lineSpine { width: 3px; padding: 4px 0 4px 2px; }
.v2-viewscope__lineSpine .v2-viewscope__spine { min-height: 14px; }
.v2-viewscope--lines .v2-viewscope__body { width: 100%; }
.v2-viewscope--empty { display: block; }

@media (prefers-reduced-motion: reduce) {
  .v2-viewscope__spine { transition: none; }
}
/* A resolved node name, with the address it names kept beside it. */
.v2-viewscope__named { display: inline-flex; align-items: baseline; gap: 6px; margin: 1px 6px 1px 0; }
.v2-viewscope__chipAddr {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10px;
  color: var(--ink2); opacity: 0.7;
}
/* Geometry drawn from its own bounding box — no projection, no map library. */
.v2-viewscope__map {
  display: block; width: 100%; max-width: 460px; height: auto; max-height: 320px;
  margin: 6px 0 4px; overflow: visible;
}
.v2-viewscope__ring {
  fill: var(--accent); fill-opacity: 0.16;
  /* With non-scaling-stroke the width is SCREEN pixels, not user units — a value in
     degrees (0.0004) would be invisible at every zoom. */
  stroke: var(--accent); stroke-width: 1.25px; stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.v2-viewscope__ring:hover { fill-opacity: 0.3; }
/* A tree nested by the address its key field holds. Every node is in the DOM; depth beyond
   the open depth is hidden by class, so the browser's own find still reaches it. */
.v2-viewscope__tree th, .v2-viewscope__tree td { padding: 2px 8px; }
.v2-viewscope__node.is-hidden { display: none; }
.v2-viewscope__nodeHead { display: flex; align-items: baseline; gap: 6px; font-weight: 400; }
.v2-viewscope__indent { flex: 0 0 auto; display: inline-block; }
.v2-viewscope__twist {
  flex: 0 0 auto; width: 13px; height: 13px; padding: 0; border: 0; background: none;
  cursor: pointer; position: relative;
}
.v2-viewscope__twist.is-leaf { cursor: default; opacity: 0.25; }
.v2-viewscope__twist::before {
  content: ""; position: absolute; left: 3px; top: 3px;
  border-left: 5px solid var(--ink2); border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
}
.v2-viewscope__twist.is-leaf::before { border-left-color: transparent; }
.v2-viewscope__twist[aria-expanded="true"]::before {
  left: 1px; top: 5px; border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 5px solid var(--ink2); border-bottom: 0;
}
.v2-viewscope__twist:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.v2-viewscope__nodeLabel { color: var(--ink); }
.v2-viewscope__kids {
  font-size: 10px; color: var(--ink2); background: var(--paper2);
  border-radius: 8px; padding: 0 5px;
}

/* Address space: a tree fetched a level at a time. `is-lazy` is a twist whose children
   have not been asked for yet — hollow rather than solid, because "there is more here"
   and "here is more" are different promises and the operator pays a request for one. */
.v2-viewscope__twist.is-lazy::before {
  border-left-color: transparent;
  border: 4px solid var(--ink2); border-radius: 50%;
  left: 2px; top: 2px; width: 0; height: 0; opacity: 0.55;
}
.v2-viewscope__twist.is-loading { opacity: 0.4; cursor: progress; }
.v2-viewscope__twist.is-error::before { border-color: var(--danger); opacity: 1; }
.v2-viewscope__node.is-unnamed .v2-viewscope__nodeLabel {
  color: var(--ink2); font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.v2-viewscope__trail {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px;
  margin: 4px 0 2px; font-size: 11px;
}
.v2-viewscope__crumb {
  border: 0; background: none; padding: 1px 4px; cursor: pointer;
  color: var(--accent); font: inherit;
}
.v2-viewscope__crumb + .v2-viewscope__crumb::before {
  content: "/"; color: var(--ink2); opacity: 0.5; margin-right: 5px;
}
.v2-viewscope__crumb[aria-current="location"] { color: var(--ink); cursor: default; }
.v2-viewscope--export .v2-viewscope__table td { padding: 2px 8px; }
.v2-viewscope__take {
  display: inline-block; margin-top: 4px; color: var(--accent);
  text-decoration: underline; font-size: 11px;
}
.v2-viewscope__take:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.v2-viewscope__crumb:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
@media (prefers-reduced-motion: reduce) {
  .v2-viewscope__twist.is-loading { cursor: wait; }
}

/* glyph_canvas — the document IS the drawing.

   Two things are on screen and the second is the point. The CANVAS shows the glyph at the
   size it is authored; the LADDER shows the same glyph at 16, 24 and 48, because the only
   question anyone actually has about an icon is whether it still reads small, and a 512px
   preview cannot answer it.

   The canvas carries a faint eighth-grid. Not decoration: a coordinate here is a position
   in a 512 x 512 space, the eighths are at 64, and seeing where a stroke lands relative to
   them is how you tell a deliberate edge from a near-miss. Everything draws in
   currentColor, so the glyph is themed by whatever colour its host sets. */
.v2-viewscope.v2-glyph { display: block; }
.v2-glyph__stage {
  display: flex; flex-wrap: wrap; gap: 20px; align-items: flex-end; margin-bottom: 14px;
}
.v2-glyph__canvas {
  position: relative; flex: 0 0 auto;
  width: min(260px, 60vw); aspect-ratio: 1 / 1;
  border: 1px solid var(--line); border-radius: 3px;
  background-color: var(--panel);
  background-image:
    repeating-linear-gradient(to right, var(--line) 0 1px, transparent 1px 12.5%),
    repeating-linear-gradient(to bottom, var(--line) 0 1px, transparent 1px 12.5%);
  color: var(--ink);
}
/* The grid is a reference, not a subject: strong enough to read against, never to compete. */
.v2-glyph__canvas::after {
  content: ""; position: absolute; inset: 0; background: var(--panel); opacity: 0.86;
  pointer-events: none;
}
.v2-glyph__canvas > .v2-glyph__svg {
  position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; overflow: visible;
}
.v2-glyph__ladder { display: flex; gap: 14px; align-items: flex-end; }
.v2-glyph__step { display: flex; flex-direction: column; align-items: center; gap: 5px; }
.v2-glyph__step .v2-glyph__svg { display: block; color: var(--ink); overflow: visible; }
.v2-glyph__stepSize {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px; color: var(--ink2);
}
.v2-glyph__paths { list-style: none; margin: 0 0 4px; padding: 0; }
.v2-glyph__pathRow {
  display: flex; gap: 8px; align-items: baseline; padding: 3px 0;
  border-top: 1px solid var(--line);
}
/* Filled or stroked, said once and shown as what it means: a solid pip or a ring. */
.v2-glyph__pathFill {
  flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%;
  border: 1px solid var(--ink2); background: transparent;
}
.v2-glyph__pathFill.is-filled { background: var(--ink2); }
/* A node's GLYPH, on the chip and in the picker. Everything is currentColor: a tree draws
   its icons in the ink it draws its names in, so an icon is never a second palette. */
.v2-domain__icon { flex: 0 0 auto; display: block; overflow: visible; }
.v2-domain__chip .v2-domain__icon { margin-right: 5px; opacity: 0.85; }
.v2-domain__chip.is-selected .v2-domain__icon { opacity: 1; }

/* Picked by LOOKING, never from a list of titles. The whole reason a glyph is a document
   is that it can be drawn; a dropdown reading "circle / disc / dot" hands that back as
   three words. Wraps and scrolls rather than growing the card. */
.v2-domain__icons {
  display: flex; flex-wrap: wrap; gap: 4px; align-items: center;
  margin: 8px 0 4px; padding: 6px; max-height: 96px; overflow-y: auto;
  border: 1px solid var(--line); border-radius: 4px;
}
.v2-domain__iconsLabel {
  flex: 0 0 auto; margin-right: 4px; font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink2);
}
.v2-domain__iconPick {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0; border-radius: 4px;
  border: 1px solid transparent; background: transparent; color: var(--ink2);
  cursor: pointer; font-size: 13px; line-height: 1;
}
.v2-domain__iconPick:hover { color: var(--ink); border-color: var(--line); }
.v2-domain__iconPick.is-on {
  color: var(--ink); border-color: var(--accent); background: var(--panel);
}
.v2-domain__iconPick:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.v2-glyph__d {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px;
  color: var(--ink2); word-break: break-all; min-width: 0;
}

/* The general calendar (container "calendar"). A MONTH GRID, a week and a day drill-down,
   drawn with .v2-cal's own grid classes — the geometry is shared with the network's calendar
   through __MYCITE_V2_CALENDAR_GRID, so this needs no second set of cells. What is not
   shared is the event model: those events RECUR, these HAPPEN. The .v2-cal2__* rules below
   are only the parts that are this calendar's own — the legend, the event lines, coverage.
   The section carries BOTH classes, so .v2-cal's grid/nav/filters rules apply. */
.v2-cal2 { padding: 10px 12px; }
.v2-cal2__header { display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: 10px; }
.v2-cal2__title-main { font-weight: 600; color: var(--ink); }
.v2-cal2__count { font-size: 12px; color: var(--ink2); }
.v2-cal2__day { margin-bottom: 12px; }
.v2-cal2__day h4 { margin: 0 0 4px; font-size: 12px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink2); }
.v2-cal2__day ul { list-style: none; margin: 0; padding: 0; }
.v2-cal2__event { display: grid; align-items: baseline; gap: 10px;
  grid-template-columns: 4.5em 10em 1fr 10em auto; padding: 4px 0;
  border-top: 1px solid var(--rule, rgba(255,255,255,.08)); font-size: 13px; }
.v2-cal2__time { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--ink2); }
.v2-cal2__kind { color: var(--ink2); }
.v2-cal2__title { color: var(--ink); overflow-wrap: anywhere; }
.v2-cal2__where { color: var(--ink2); font-size: 12px; }
.v2-cal2__add { font-size: 12px; white-space: nowrap; }
.v2-cal2__foot { margin-top: 10px; font-size: 11px; color: var(--ink2); }
.v2-cal2__excl { display: block; margin-top: 2px; font-style: italic; }
/* One colour per SOURCE DOCUMENT, named. A colour nobody can decode is decoration, so the
   legend is not optional chrome — it is what makes the dots in the month cells readable. */
.v2-cal2__legend { display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
  margin-left: auto; font-size: 11px; color: var(--ink2); }
.v2-cal2__legendItem { display: inline-flex; align-items: center; gap: 4px; }
.v2-cal2__legendItem i { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }
.v2-cal2__list { list-style: none; margin: 0; padding: 0; }
/* An event line carries its source's colour on the left edge, so the day view and the month
   dots agree without the reader holding the legend in their head. */
.v2-cal2__event { border-left: 3px solid transparent; padding-left: 8px; }
.v2-cal2__who { color: var(--ink2); font-size: 12px; }
/* Six columns now (time · kind · title · who · where · add), where the list had five. */
.v2-cal2 .v2-cal2__event { grid-template-columns: 4.5em 8em 1fr 9em 9em auto; }
@media (max-width: 760px) {
  .v2-cal2 .v2-cal2__event { grid-template-columns: 4.5em 1fr auto; }
  .v2-cal2__kind, .v2-cal2__who { display: none; }
}

/* ===========================================================================
   THE PORTAL ON A PHONE                                        (2026-08-16)
   ===========================================================================
   The operator could not load the portal on their phone. Two causes, both
   measured at 390x844 against the deployed build rather than inferred:

     1. the control panel became a fixed drawer over the workbench with its
        only handle clipped off-screen — fixed by retiring the region;
     2. what remained was still laid out for a desk. The menubar's right column
        collapsed to 0px under `overflow: hidden`, so the theme selector and the
        tool search were present in the DOM and invisible; the folder shelf drew
        one 233px column where two fit; and the document LIST table wanted
        425px, which scrolled the whole page sideways.

   Everything below is inside this query. The desktop layout is untouched.
   ========================================================================= */
@media (max-width: 700px) {
  /* The shell's own sizing moved OUT of this query on 2026-08-18 — a phone in
     landscape is 844px wide and never reaches it. See `.ide-shell` above. */

  /* TWO ROWS, on purpose (2026-08-21). The drawer that used to swallow the tool
     search and theme selector is gone — the rail is a bottom bar now — so the
     menubar holds the page's name on its first row and the shell's two controls
     on a second. That is the 2026-08-16 layout back, minus the hamburger. */
  .ide-menubar {
    flex: 0 0 auto;
    min-height: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: 10px;
    row-gap: 6px;
    /* The status-bar band, for the standalone case. Safari's own chrome covers it and
       the inset is 0 there; installed to the home screen it is not. Safe to put the
       inset in the padding here and nowhere else: this rule's box is content-sized
       (`flex: 0 0 auto; min-height: 0`), so it GROWS by the band instead of clipping
       a row into it the way the base rule's fixed `--ide-menu-h` basis would. */
    padding: calc(7px + env(safe-area-inset-top, 0px)) 10px 7px;
    overflow: visible;
  }
  .ide-menubar__center { flex: 1 1 auto; min-width: 0; }
  .ide-menubar__pageTitle {
    font-size: 15px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* An ellipsised sentence is not information. It survives on a desk, where it
     has the width to finish. */
  .ide-menubar__pageSub { display: none; }
  .ide-menubar__right {
    flex: 1 1 100%;
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    overflow: visible;
  }
  .ide-menubar__toolSearch { flex: 1 1 auto; min-width: 0; margin-right: 0; }
  .ide-menubar__right .portal-tool-palette input { width: 100%; box-sizing: border-box; min-height: 38px; }
  .ide-menubar__right .themebar { flex: 0 0 auto; padding: 0; }
  .ide-menubar__right .themebar__select { min-height: 38px; }

  /* ===== THE RAIL AS A BOTTOM BAR =========================================
     The depiction (2026-08-21): "Mobile puts the activity bar at the bottom" —
     five equal cells, left to right Utilities · Gadgets · Network · Compendium ·
     Profile. IN FLOW, not fixed: the shell is 100dvh, so the bar rides above the
     keyboard and shrinks with the visual viewport for free, and nothing overlays
     the workbench. The off-canvas drawer, its scrim, its hamburger and the chrome
     slot that drawer carried are gone. */
  .ide-body {
    position: relative;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) auto;
    grid-template-areas: "workbench" "activity";
  }
  /* THE PHONE BAR CARRIES THE AXES ONLY. The rail is a horizontal strip at the foot
     here, so the gallery's tiles the desk rail carries (2026-09-01; the gallery's own
     set since 2026-10-07) would turn four reachable cells into a dozen unreachable
     ones. The operator's depiction said "on desktop" for exactly this reason; the
     menubar search still reaches every tool by name on a phone. */
  .ide-activitynav [data-nav-kind="tool"] { display: none; }
  .ide-activitynav { overflow-y: visible; }

  .ide-activitybar {
    grid-area: activity;
    /* The template's critical-CSS fallback sizes the DESKTOP column (width: 56px)
       with no media query of its own; the row has to take the whole bar back. */
    width: auto;
    flex-direction: row;
    align-items: stretch;
    height: auto;
    min-height: 0;
    border-right: 0;
    border-top: 1px solid var(--line);
    /* The home-indicator band: a 52px target whose bottom sits under the device's
       own furniture is a smaller target than it draws. */
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .ide-railBody {
    flex: 4 1 0;
    min-width: 0;
    overflow: visible;
    display: flex;
  }
  .ide-activitynav {
    flex: 1 1 auto;
    flex-direction: row;
    align-items: stretch;
    gap: 0;
    padding: 4px 2px;
  }
  .ide-activitylink {
    flex: 1 1 0;
    min-width: 0;
    min-height: 52px;
    padding: 6px 0;
    border-radius: 8px;
  }
  /* The depiction's left-to-right order differs from the desk's top-to-bottom
     reading. ONE DOM, ordered here from the item id the renderer stamps — a
     second server ordering would be a second rail to keep in step. */
  .ide-activitylink[data-item-id="utilities.root"] { order: 1; }
  .ide-activitylink[data-item-id="gadgets.root"] { order: 2; }
  .ide-activitylink[data-item-id="network.root"] { order: 3; }
  .ide-activitylink[data-item-id="system.root"] { order: 4; }
  /* Profile is the bar's fifth cell: the footer joins the row instead of
     closing a column. */
  .ide-activityfooter {
    margin-top: 0;
    border-top: 0;
    padding: 4px 2px;
    flex: 1 1 0;
    min-width: 0;
    display: flex;
  }
  .ide-activityfooter .ide-activitylink { flex: 1 1 auto; }

  /* ===== TOOLS IN THE WORKBENCH ==========================================
     Measured at 390px on the Oveure hub, which is the shape every app hub
     shares: a tab strip and a label/value shelf, both laid out for a desk.

     THE TABS SCROLL rather than clip. `nowrap` with no scroller put the fourth
     tab's right edge at 417px on a 390px screen — present, half-drawn, and
     unreachable. Scrolling is the phone answer; wrapping would push the panel
     body below the fold on a hub with five tabs. */
  .v2-tabbed__strip {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
  }
  .v2-tabbed__strip::-webkit-scrollbar { display: none; }
  .v2-tabbed__tab {
    flex: 0 0 auto;
    scroll-snap-align: start;
    padding: 8px 12px;
    min-height: 40px;
  }

  /* A LABEL/VALUE ROW STACKS. Held side by side in 310px the label was clipped
     to "Domain — the sandbox's own shee…", which is a sentence that has been
     charged for and not delivered. */
  .v2-synopsis__row {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    padding: 6px 0;
  }
  .v2-synopsis__label {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
  }

  /* The notes shelf is a list BESIDE an editor. At 390px the fixed 180px list
     left ~190px of editor, which is not a place to write. */
  .v2-notes { flex-direction: column; }
  .v2-notes__list { flex: 0 0 auto; max-height: 40vh; }
  .v2-inbox { flex-direction: column; }
  .v2-inbox__list { flex: 0 0 auto; max-height: 32vh; }
  /* The action bar is four controls; on a phone they wrap rather than squeeze, and
     Send stays last so the destructive-ish one is not what a thumb lands on first. */
  .v2-inbox__bar { gap: 6px; }
  .v2-inbox__body { max-height: 34vh; }

  /* Reclaim the desk-sized gutters. */
  .v2-workbench-body { padding: 0.6rem 0.6rem 1.2rem; }
  .v2-compendium__bar,
  .v2-compendium__toolbar { padding-left: 10px; padding-right: 10px; }
  /* One instrument card across on a phone: the span ticks are the point of the
     card and two columns cut them to one line. */
  .v2-compendium__band { grid-template-columns: minmax(0, 1fr); padding: 8px 10px 14px; }
  /* The face stays beside the name on a phone, smaller, as a profile's does. */
  .v2-profile__specimen { gap: 14px; align-items: start; padding-bottom: 16px; }
  .v2-profile__avatar { width: 64px; height: 64px; font-size: 23px; box-shadow: inset 0 0 0 3px var(--paper); }
  .v2-profile__name { font-size: 19px; }
  .v2-profile__tab { padding: 10px 11px 9px; }
  /* Two across on a phone rather than one: an alias card is a mark and a label, and one
     per row turns four aliases into a scroll. */
  .v2-profile__aliasGrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* One seam per row on a phone: a port card is four rungs of prose, and two across at
     390px breaks every lead mid-word. */
  .v2-ladder { grid-template-columns: minmax(0, 1fr); }
  .v2-compendium__bandHead { margin-left: 10px; margin-right: 10px; }
  .v2-compendium__glyph { width: 34px; height: 34px; }
  .v2-compendium__name { font-size: 12px; }

  /* Tap targets. A crumb, a view toggle and a source link are all things a
     thumb has to hit. */
  .v2-compendium__crumb,
  .v2-compendium__toggle { min-height: 40px; display: inline-flex; align-items: center; }
  .v2-compendium__sources { margin: 8px 10px 16px; }
  .v2-sectionNav { padding: 8px 10px 0; }
  .v2-selectionStrip,
  .v2-installTarget { margin: 8px 10px 0; }

  /* Cards stack rather than forcing a 220px minimum the screen cannot give. */
  .v2-card-grid { grid-template-columns: 1fr; }

  /* A label/value pair stacks. Held to two columns on a 390px screen, a 160px
     label column left ~150px for the value, which set "Every tool this instance
     holds" one word to a line. */
  .v2-surface-dl { grid-template-columns: 1fr; gap: 2px; }
  .v2-surface-dl dt { margin-top: 8px; }
  .v2-surface-dl dt:first-child { margin-top: 0; }
}

/* A wide table scrolls inside ITSELF at every width. The page must never scroll
   sideways: a horizontal page scroll on a phone moves the rail and the menubar
   off-screen along with the table that caused it. */
.v2-compendium__listWrap {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.v2-compendium__listWrap > .v2-compendium__list { min-width: 24rem; }

/* Type does not inflate on rotation, and taps do not wait 300ms to see whether
   they were a double-tap. */
html { -webkit-text-size-adjust: 100%; }
button,
a,
select,
input,
.v2-compendium__row { touch-action: manipulation; }

/* "showing 20 of 473" — the section states its own cut, beside the heading it
   cuts. A list truncated without saying so reads as a complete list. */
.v2-compendium__sourcesCut {
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  opacity: 0.8;
}

/* ===========================================================================
   THE NETWORK MODULE: A MAP, AND THREE ICONS                    (2026-08-17)
   ===========================================================================
   Operator: orient the map like Apple Maps on a phone or Google Maps in a
   browser — the difference being that the polygons built from the FND resource
   are what give the map its sense of context. So the canvas is edge to edge,
   the search comes up from a bottom sheet, and only minimal buttons sit on top.

   The ground is a REGISTER, not a tile service, and the styling says so: the
   outlines stay line-drawn, the palette stays the portal's own, and nothing
   here imitates cartography the registry does not contain.
   ========================================================================= */
/* A percentage height needs a definite one to resolve against, and the chain from
   .ide-workbench down to the surface has none: `.viewport` is a flex item that
   sizes itself, and `.v2-workbench-body` is a padded document box. So the map
   asks for the frame explicitly — `data-fullbleed` is set by the renderer and
   cleared by every other surface — rather than every surface paying for a height
   only this one wants. Measured before this existed: the canvas came out 334x0. */
.viewport { display: flex; flex-direction: column; }
/* The inset the map has to shed is `.viewport`'s `18px 18px 28px`, one level ABOVE
   the node the renderer owns — clearing the body's padding alone left the canvas
   at x=19 in a 390px viewport, measured. `:has()` lets the parent answer for its
   child without the renderer reaching upward and having to remember to clear it
   again; the stylesheet already relies on `color-mix` and `dvh`, both younger. */
.viewport:has(> #v2-workbench-body[data-fullbleed]) { padding: 0; }
#v2-workbench-body[data-fullbleed="map"] {
  flex: 1 1 auto;
  min-height: 0;
  height: 100%;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.v2-netshell {
  position: relative;
  flex: 1 1 auto;
  height: 100%;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.v2-netshell__map {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
}
/* A DESTINATION page is a page, and the chrome does not FLOAT on one. Floating is
   right over a map, where the ground below is the content and the controls are
   meant to sit on it; over a document it lands on the first paragraph. Measured on
   the inbox: the three circles covered the contract card's top-right corner. So on
   a page the chrome is a row at the top, in flow, and the page starts under it. */
.v2-netshell--page { display: flex; flex-direction: column; }
.v2-netshell--page .v2-netchrome {
  position: static;
  flex: 0 0 auto;
  flex-direction: row;
  justify-content: flex-end;
  gap: 8px;
  padding: 10px 14px 0;
}
.v2-netshell--page .v2-netshell__page {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 6px 16px 32px;
}

/* The three controls. Circular, translucent, and stacked at the top-right the way
   a maps app puts its account button — near the thumb on a phone, out of the way
   of the ground everywhere. */
.v2-netchrome {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 8;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.v2-netchrome__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: color-mix(in srgb, var(--coal) 82%, transparent);
  color: var(--ink);
  text-decoration: none;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(6px);
}
.v2-netchrome__btn:hover { color: var(--accent2); border-color: var(--accent2); }
.v2-netchrome__btn:focus-visible { outline: 2px solid var(--accent2); outline-offset: 2px; }
.v2-netchrome__btn.is-active { border-color: var(--accent); color: var(--accent); }
.v2-netchrome__icon { width: 20px; height: 20px; display: block; }

/* ── The map, edge to edge ────────────────────────────────────────────────── */
.v2-netmap--shell {
  position: absolute;
  inset: 0;
  display: block;
  margin: 0;
  padding: 0;
}
/* ── The atlas: counties first (2026-10-18) ──────────────────────────────────
   `v2_portal_network_atlas.js` draws the Network page's map and carries its own
   structure; it takes every colour from these, so it reads in every theme. The count
   circle is the mark's own node — an ink disc ringed in the accent (in Spore: an ivory
   disc on hypha gold, the logo's ivory nodes on ochre). */
.v2-netmap__map--atlas {
  /* Substrate and ground from PAPER, not coal: every theme's text tokens are written to
     read on its paper, and on the light themes coal is a dark grey that ink vanishes on. */
  --atlas-sea: var(--paper);
  --atlas-ground: color-mix(in srgb, var(--paper2) 86%, var(--ink));
  --atlas-ground-quiet: color-mix(in srgb, var(--paper2) 55%, var(--paper));
  --atlas-ground-sel: color-mix(in srgb, var(--accent) 14%, transparent);
  --atlas-edge: var(--line);
  --atlas-muni-edge: color-mix(in srgb, var(--accent) 50%, transparent);
  --atlas-structure: var(--accent);
  --atlas-count: var(--ink);
  --atlas-count-ink: var(--paper);
  --atlas-dot-edge: var(--paper);
  --atlas-ink: var(--ink);
  --atlas-ink-quiet: var(--ink2);
  --atlas-focus: var(--accent2);
  background: var(--paper);
}
/* The crumbs float over the ground, so they get the page's own paper behind them. */
.v2-netmap__map--atlas .atlas__head {
  padding: 8px 12px 9px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(8px);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
  max-width: min(30rem, calc(100% - 80px));
}
/* The index of places is the first thing in the sheet: a list a keyboard and a screen
   reader can walk, in the same order the circles count. */
.v2-netmap__atlasIndex { margin: 2px 0 14px; }
.v2-netmap__atlasIndex .atlas__index {
  --atlas-ink: var(--ink);
  --atlas-ink-quiet: var(--ink2);
  --atlas-edge: color-mix(in srgb, var(--line) 60%, transparent);
  --atlas-count: var(--ink);
  --atlas-count-ink: var(--paper);
  --atlas-structure: var(--accent);
  --atlas-ground-sel: rgba(255, 255, 255, 0.05);
  --atlas-focus: var(--accent2);
}
.v2-netmap__atlasIndex .atlas__item { min-height: 44px; }
@media (max-width: 640px) {
  .v2-netmap__map--atlas .atlas__head { max-width: calc(100% - 64px); }
  .v2-netmap__map--atlas .atlas__sum { font-size: 12px; }
}
.v2-netmap--shell .v2-netmap__canvas { position: absolute; inset: 0; }
.v2-netmap--shell .v2-netmap__map { position: absolute; inset: 0; margin: 0; }

/* ── The bottom sheet ─────────────────────────────────────────────────────── */
/* Three detents. PEEK is the search field and nothing else; HALF is a screenful
   of results; FULL is the whole panel — the counts, the filters, the legend, the
   events. The sheet is where every one of those lives now, because the operator
   asked for the map's top to stay clear. */
.v2-netmap__sheet {
  position: absolute;
  left: 0;
  right: 0;
  /* ABOVE THE KEYBOARD.                                            (2026-08-18)
     `--kb-inset` is what the visual viewport lost and the layout viewport kept — a soft
     keyboard, which `dvh` does not see. Zero at every other moment, so this reads as
     `bottom: 0` unless someone is typing in the search field one line down from here.
     `max-height` subtracts it too, or the FULL detent would grow past the top of the map
     by exactly the height of the keys. */
  bottom: var(--kb-inset, 0px);
  /* ABOVE the module chrome (z-index 8), which is what a sheet sliding over a map does.
     Underneath it, the three icons floated on top of the panel's own search field and
     first rows at the FULL detent — measured. Covered is not the same as vanished: the
     controls come straight back as the sheet comes down. */
  z-index: 12;
  display: flex;
  flex-direction: column;
  max-height: calc(92% - var(--kb-inset, 0px));
  border-top: 1px solid var(--line);
  border-radius: 14px 14px 0 0;
  background: color-mix(in srgb, var(--coal) 94%, transparent);
  box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(10px);
  transition: height 200ms ease;
}
.v2-netmap__sheet[data-detent="peek"] { height: 108px; }
.v2-netmap__sheet[data-detent="half"] { height: 52%; }
.v2-netmap__sheet[data-detent="full"] { height: 92%; }
.v2-netmap__grip {
  flex: 0 0 auto;
  display: block;
  width: 100%;
  /* 44px of thumb, not 4px of bar. The visible handle stays small; what a finger has
     to hit is the whole strip above the search field. */
  min-height: 30px;
  padding: 12px 0 8px;
  border: 0;
  background: none;
  cursor: grab;
  /* The one place in the sheet that takes a gesture instead of a scroll. */
  touch-action: none;
}
.v2-netmap__sheet[data-dragging] .v2-netmap__grip { cursor: grabbing; }
/* While a thumb is on it the sheet tracks the thumb; the eased detent transition
   would otherwise fight every frame of the drag. */
.v2-netmap__sheet[data-dragging] { transition: none; }
.v2-netmap__grip:focus-visible { outline: 2px solid var(--accent2); outline-offset: -2px; }
.v2-netmap__gripBar {
  display: block;
  width: 40px;
  height: 4px;
  margin: 0 auto;
  border-radius: 2px;
  background: var(--ink2);
  opacity: 0.6;
}
.v2-netmap__search { flex: 0 0 auto; padding: 4px 12px 10px; }
.v2-netmap__searchInput {
  width: 100%;
  box-sizing: border-box;
  min-height: 40px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
}
.v2-netmap__searchInput:focus-visible { outline: 2px solid var(--accent2); outline-offset: 1px; }
.v2-netmap__sheetBody {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 12px 16px;
  /* The operator's own division: the map is an app surface and this is a page. A
     finger here scrolls, selects and taps exactly as it would anywhere else on the
     web. `pan-y` says so out loud rather than leaving it to the default, because the
     map one layer down has taken every gesture and the difference has to be
     deliberate on both sides of the line. */
  touch-action: pan-y;
}
/* At PEEK the body is not merely short — it is not there. A half-cut filter row
   under a search field reads as a rendering fault. */
.v2-netmap__sheet[data-detent="peek"] .v2-netmap__sheetBody { display: none; }
.v2-netmap__resultList { list-style: none; margin: 0 0 12px; padding: 0; }
.v2-netmap__result {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 8px 10px;
  border: 0;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 60%, transparent);
  background: none;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.v2-netmap__result:hover { background: rgba(255, 255, 255, 0.05); }
.v2-netmap__resultKind { color: var(--ink2); font-size: 12px; }
/* Inside the sheet the map's own chrome is a stack, not a row beside a map. */
.v2-netmap--shell .v2-netmap__layout { display: block; }
/* ONE SCROLLER PER SURFACE. Beside a map the events aside is a column with its own
   scrollbar, and that is right there. Stacked inside the sheet it became a 240px
   window onto a 4,175px list inside a 300px panel inside a full-bleed map — three
   nested scroll regions under one thumb. Measured: a drag in the sheet moved the
   events list and left the sheet where it was, which is the "regular site mechanics"
   the operator asked for failing in the least visible way possible. In the sheet the
   sheet scrolls, and nothing inside it does. */
.v2-netmap--shell .v2-netmap__events {
  width: auto;
  margin-top: 12px;
  max-height: none;
  overflow: visible;
}

@media (prefers-reduced-motion: reduce) {
  .v2-netmap__sheet { transition: none; }
}

/* ── A map that keeps the browser's gestures ──────────────────────────────── */
/* The operator, 2026-08-18: the greatest failure of a map like this is one that
   zooms the PAGE instead of the map. A full-bleed canvas has nothing to scroll, so
   a magnified page is a room with no door. `touch-action: none` is the line that
   keeps the browser out; the class is added by `attachMapPanZoom` itself, under
   `opts.touch`, so the rule and the handlers that depend on it arrive together and
   an embedded map — one that must go on scrolling its document — never gets it. */
.is-touchmap {
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.is-touchmap:focus-visible { outline: 2px solid var(--accent2); outline-offset: -2px; }
/* What floats OVER a touch map is still a page. The region card has its own scrollbar,
   and inheriting `touch-action: none` from the map would leave a card taller than its
   box with no way to read the rest of it. */

/* THE WAY BACK. Prevention covers the map; it cannot cover an OS accessibility zoom,
   a pinch that began off the map, or a browser that ignores touch-action. If the page
   does end up scaled, two things happen at once: the map gives the browser its
   gestures back, so the reader can drag the magnified page around instead of being
   pinned to one corner of it, and a control appears that puts the scale back to 1. */
.ide-shell[data-page-zoomed] .is-touchmap { touch-action: auto; }
.v2-zoomEscape {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 60;
  display: none;
  align-items: center;
  gap: 10px;
  margin: 10px;
  padding: 8px 12px;
  border: 1px solid var(--accent);
  border-radius: 10px;
  background: var(--coal, #14181d);
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.5);
  /* Pinned to the VISIBLE viewport and held at its drawn size while the page is
     magnified — the transform is written by the shell from `visualViewport`. Without
     it the one control that undoes the zoom is itself off the zoomed screen. */
  transform-origin: 0 0;
}
.ide-shell[data-page-zoomed] .v2-zoomEscape { display: flex; }
.v2-zoomEscape__btn {
  min-height: 32px;
  padding: 0 12px;
  border: 1px solid var(--accent);
  border-radius: 8px;
  background: var(--accent);
  color: var(--accent-fg);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.v2-zoomEscape__btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* ── The two destination pages ────────────────────────────────────────────── */
.v2-netprofile__sub { color: var(--ink2); margin: 2px 0 0; }
.v2-netprofile__node {
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 12px;
  color: var(--ink2);
  margin: 2px 0 14px;
}
.v2-netprofile__sourceGroup { margin: 10px 0; }
.v2-netprofile__sourceGroup ul { margin: 4px 0 0; padding-left: 18px; }
.v2-netprofile__count { color: var(--ink2); font-weight: 400; }
.v2-netprofile__empty, .v2-netinbox__empty { color: var(--ink2); }
.v2-netprofile__warn { color: var(--danger, #d1242f); }
.v2-netprofile__link { color: var(--accent2); }
.v2-netprofile__row h5 { margin: 10px 0 2px; }

.v2-netinbox {
  display: grid;
  grid-template-columns: minmax(200px, 260px) minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}
.v2-netinbox__panel ul { list-style: none; margin: 6px 0 0; padding: 0; }
.v2-netinbox__item {
  display: grid;
  gap: 2px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  margin-bottom: 6px;
  color: var(--ink);
  text-decoration: none;
}
.v2-netinbox__item.is-active { border-color: var(--accent); background: rgba(30, 108, 147, 0.14); }
.v2-netinbox__who { overflow-wrap: anywhere; font-weight: 600; }
.v2-netinbox__state { color: var(--ink2); font-size: 12px; }
.v2-netinbox__tag {
  justify-self: start;
  padding: 1px 6px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  color: var(--accent);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.v2-netinbox__id {
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 12px;
  color: var(--ink2);
  overflow-wrap: anywhere;
}
.v2-netinbox__note, .v2-netinbox__purpose { color: var(--ink2); }
.v2-netinbox__histFilters { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; }
.v2-netinbox__histChip {
  min-height: 32px;
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: none;
  color: var(--ink2);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.v2-netinbox__histChip.is-active { border-color: var(--accent); color: var(--accent); }
.v2-netinbox__histList { list-style: none; margin: 6px 0 0; padding: 0; }
.v2-netinbox__histList li {
  display: grid;
  grid-template-columns: minmax(0, 10em) minmax(0, 1fr) minmax(0, 10em);
  gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
}
.v2-netinbox__histWhen, .v2-netinbox__histWho { color: var(--ink2); font-size: 12px; }
@media (max-width: 700px) {
  /* Three columns in 358px gives each about a hundred pixels, which is not a
     column, it is a place words go to be cut in half. */
  .v2-netinbox__histList li { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}
.v2-netinbox__reach ul { margin: 6px 0 0; padding-left: 18px; }

/* FIND A PROFILE, on a Lite account's Network page. Top-right over the map, the corner a
   Lite page leaves free (it draws no chrome stack; the map's own hint card is top-left and
   its search sheet is at the bottom). The page's own surface, slightly translucent so the
   ground still reads as the page beneath it. */
.v2-netshell__finder {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 8;
  width: min(300px, calc(100% - 20px));
  max-height: calc(100% - 20px);
  display: flex;
  flex-direction: column;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: color-mix(in srgb, var(--surface) 94%, transparent);
  color: var(--ink);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(6px);
}
.v2-netshell__finderBody {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
  margin-top: 8px;
}
.v2-netshell__finderHead:focus-visible { outline: 2px solid var(--accent2); outline-offset: 2px; }
.v2-netshell__finderHead { margin: 0; font-size: 1rem; font-weight: 600; cursor: pointer; }
.v2-netshell__finderLabel { display: flex; flex-direction: column; gap: 4px; font-size: 0.85rem; }
.v2-netshell__finderInput {
  width: 100%;
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
}
.v2-netshell__finderInput:focus-visible { outline: 2px solid var(--accent2); outline-offset: 1px; }
.v2-netshell__finderList { list-style: none; margin: 0; padding: 0; overflow-y: auto; min-height: 0; }
.v2-netshell__finderLink {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 6px;
  border-radius: 6px;
  color: var(--ink);
  text-decoration: none;
}
.v2-netshell__finderLink:hover { background: color-mix(in srgb, var(--accent) 14%, transparent); }
.v2-netshell__finderLink:focus-visible { outline: 2px solid var(--accent2); outline-offset: 1px; }
.v2-netshell__finderName { font-weight: 600; }
.v2-netshell__finderMeta { font-size: 0.8rem; color: var(--muted); }
.v2-netshell__finderNone { margin: 0; font-size: 0.85rem; color: var(--muted); }
@media (max-width: 700px) {
  /* A bar ABOVE the map, in flow, closed: a card over a 390px map covers the map's own
     hint card or its search sheet, whichever corner it takes. Opened, the list drops over
     the map rather than pushing it, so the map keeps the size it was drawn at. */
  .v2-netshell__finder {
    position: relative;
    top: auto;
    right: auto;
    flex: none;
    width: auto;
    max-height: none;
    margin: 8px 8px 0;
  }
  .v2-netshell__finderBody {
    position: absolute;
    top: 100%;
    left: -1px;
    right: -1px;
    max-height: 55vh;
    margin-top: 0;
    padding: 10px 12px 12px;
    border: 1px solid var(--line);
    border-top: 0;
    border-radius: 0 0 10px 10px;
    background: var(--surface);
    box-shadow: 0 6px 10px rgba(0, 0, 0, 0.3);
  }
}

@media (max-width: 700px) {
  /* One column, list then detail — a 260px panel beside a detail pane is two
     unusable columns on a 390px screen. */
  .v2-netinbox { grid-template-columns: minmax(0, 1fr); }
  .v2-netchrome { top: 8px; right: 8px; }
  .v2-netshell--page .v2-netshell__page { padding: 12px 12px 28px; }
  /* Clear of the chrome stack, which is 3 x 40px + gaps. */
  .v2-netshell--page .v2-netshell__page > * { padding-top: 0; }
  .v2-netprofile > h2, .v2-netinbox__panel > h2 { margin-right: 56px; }
}

/* The system-log document the Network table is reading. */
.v2-networkPath {
  margin: 6px 14px 0;
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 11px;
  color: var(--ink2, #888);
  overflow-wrap: anywhere;
}

/* ═══ THE DOMAIN SURFACE (Oveure) ═══════════════════════════════════════════ */
/* The tree is the surface: it fills the tab, it takes the gestures, and a node's
   WRITING is drawn on the node. Everything here is a token — the portal ships a
   light and a dark theme and a literal hex would be wrong in one of them.

   The type is ADDRESS-FIRST. The address is set in mono at full contrast on the top
   line and the human label sits under it in the muted ink. That inverts the usual
   arrangement on purpose: in SAMRAS the address is the denotation and the label is a
   gloss, which is why a restructure is a re-key of addresses and why a writing is
   NAMED by one.

   The one loud thing is the SPINE — the filled bar down the left edge of a node that
   holds a writing. Before anything is clicked, the tree shows where the policy lives
   and which nodes are only scaffolding, which is the question this surface exists to
   answer. Everything else is a hairline. */
.v2-domain {
  /* The ONE colour this surface adds: the ledger ink, used only on the document branch so
     a filed thing reads apart from a claim about the world. Everything else is the
     portal's own palette — a tab inside a live product earns no second identity. */
  --v2-domain-slot: #8a94a6;
  /* The shelf's only violet: an INSTRUMENT is not a sandbox, and the card has to say
     so before its label is read. */
  --v2-instrument: #6f5bd6;
  /* Amber, the slot stamp's family, reused for "this came from outside this instance"
     -- and for a document the sandbox holds that its log does not know about. */
  --v2-source-external: #b4791f;
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  min-height: 320px;
  overflow: hidden;
  background: var(--panel, #f6f5f1);
  border: 1px solid var(--line, #d8dee4);
  border-radius: 8px;
}
/* THE FILTER BAR is where the documents gallery went. A slot is a node, so the tree is
   already the gallery; what the gallery had that the tree did not was search and a way to
   see the unassigned. 44px so a thumb can reach it, and it takes its own gestures back
   from the plane below. */
.v2-domain__filter {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 44px;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 10px;
  background: color-mix(in srgb, var(--panel, #f6f5f1) 88%, transparent);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--line, #d8dee4);
  touch-action: pan-y;
}
.v2-domain__search {
  flex: 1 1 auto;
  min-width: 0;
  height: 28px;
  font: inherit;
  font-size: 12px;
  padding: 0 9px;
  color: var(--ink);
  background: var(--paper, #fff);
  border: 1px solid var(--line, #d8dee4);
  border-radius: 5px;
}
.v2-domain__search:focus { border-color: var(--accent); outline: none; }
.v2-domain__toggleBtn {
  flex: 0 0 auto;
  height: 28px;
  font: inherit;
  font-size: 11px;
  padding: 0 10px;
  color: var(--ink2);
  background: var(--paper, #fff);
  border: 1px solid var(--line, #d8dee4);
  border-radius: 999px;
  cursor: pointer;
}
.v2-domain__toggleBtn em {
  font-style: normal;
  font-weight: 600;
  color: var(--accent);
}
.v2-domain__toggleBtn.is-on {
  color: var(--accent);
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--paper, #fff));
}
.v2-domain__toggleBtn:focus-visible { outline: 2px solid var(--accent2); outline-offset: 2px; }
.v2-domain__found {
  flex: 0 0 auto;
  font-size: 10.5px;
  color: var(--ink2);
  min-width: 0;
  white-space: nowrap;
}
.v2-domain__plane {
  position: absolute;
  inset: 44px 0 0;
  overflow: hidden;
  cursor: grab;
}
.v2-domain__plane.is-panning { cursor: grabbing; }
.v2-domain__world {
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: 0 0;
  will-change: transform;
}
.v2-domain__empty {
  padding: 24px;
  color: var(--ink2);
  font-size: 13px;
}

/* ── a node ─────────────────────────────────────────────────────────────── */
.v2-domain__node {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 4px;
  transform: translateY(-50%);
  white-space: nowrap;
}
.v2-domain__toggle {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  padding: 0;
  line-height: 1;
  font-size: 11px;
  border: 1px solid var(--line, #d8dee4);
  border-radius: 4px;
  background: var(--panel, #fff);
  color: var(--ink2);
  cursor: pointer;
}
.v2-domain__toggle:hover { color: var(--accent); border-color: var(--accent); }
.v2-domain__toggle--leaf { border: 0; background: none; cursor: default; }
.v2-domain__chip {
  position: relative;
  box-sizing: border-box;
  width: 214px;
  min-height: 38px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1px;
  padding: 5px 8px 5px 12px;
  text-align: left;
  font: inherit;
  border: 1px solid var(--line, #d8dee4);
  border-radius: 5px;
  background: var(--paper, #fff);
  color: var(--ink);
  cursor: pointer;
  overflow: hidden;
}
.v2-domain__chip:hover { border-color: var(--accent2); }
.v2-domain__chip:focus-visible { outline: 2px solid var(--accent2); outline-offset: 2px; }
.v2-domain__chip.is-selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent) inset, 0 2px 10px rgba(0, 0, 0, 0.16);
}
/* THE SPINE. Absent unless the node holds a writing, so its presence is the fact. */
.v2-domain__spine {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: transparent;
}
.v2-domain__chip.has-doc .v2-domain__spine { background: var(--accent); }
.v2-domain__chip.is-decision .v2-domain__spine { background: var(--accent2); }
/* THE HIERARCHY INVERTS (2026-08-19). The chip led with its address in 12.5px mono and
   dropped the label underneath — right while an address was the only durable thing a
   document had, and wrong now that the log carries a title beside it. The TITLE leads;
   the address becomes a tick in the chip's footer, like a page number in a margin. Both
   are still there. What changed is which one the eye lands on first. */
.v2-domain__label {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2-domain__preview {
  font-size: 10.5px;
  line-height: 1.3;
  color: var(--ink2);
  opacity: 0.8;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2-domain__foot {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 1px;
}
.v2-domain__addr {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 10.5px;
  letter-spacing: 0.02em;
  color: var(--ink2);
  flex: 0 0 auto;
}
/* THE SLOT STAMP — the signature. The tree's shape cannot show a pointer, which is the
   one fact the local domain log adds, so the pointer is drawn at BOTH ends: the node
   carries the slot it denotes, the slot carries the node that denotes it. An arc across
   the plane was the obvious answer and was cut — at 390px and k=0.62 it crosses six chips
   and points at nothing readable. This survives clipping and costs no layout pass. */
.v2-domain__stamp {
  margin-left: auto;
  flex: 0 0 auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 10px;
  line-height: 1.5;
  padding: 0 5px;
  border-radius: 3px;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.v2-domain__stamp.is-loose {
  color: var(--ink2);
  background: transparent;
  border: 1px dashed var(--line, #d8dee4);
  font-family: inherit;
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.v2-domain__count {
  flex: 0 0 auto;
  font-size: 10px;
  color: var(--ink2);
  border: 1px solid var(--line, #d8dee4);
  border-radius: 999px;
  padding: 0 5px;
}
/* WHAT IS BENEATH (2026-10-26). Beside the child count, how many of the nodes under
   this one denote a document — accent, like the spine, because it is the same fact one
   level up: a `contacts` type whose children carry profiles says so before it is opened.
   The kind rides in mono, the way a slot address does. On the foot's one line, so the
   chip keeps its height (DOMAIN_DIMS.NODE_H is what the layout reserves). */
.v2-domain__below {
  flex: 0 0 auto;
  font-size: 10px;
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 999px;
  padding: 0 5px;
  white-space: nowrap;
}
.v2-domain__below i {
  font-style: normal;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* THE LEDGER RAIL. A document slot is a different KIND of thing from a domain node — a
   filed thing rather than a claim about the world — so the meta branch reads quieter and
   squarer, and its spine is the ledger ink rather than the accent. */
.v2-domain__chip.is-slot {
  border-radius: 2px;
  border-left-width: 3px;
  border-left-color: var(--v2-domain-slot, #8a94a6);
  background: color-mix(in srgb, var(--panel, #f6f5f1) 55%, var(--paper, #fff));
}
.v2-domain__chip.is-slot .v2-domain__spine { background: var(--v2-domain-slot, #8a94a6); }
/* Filtering DIMS rather than removes: the tree an operator is navigating must not move
   under them on every keystroke. */
.v2-domain__node.is-dim { opacity: 0.22; }
.v2-domain__node.is-dim .v2-domain__chip { border-style: dotted; }
/* An ACTION is vocabulary, not policy: drawn quieter and rounder than the nodes that
   reference it, so a tree reads as "these are the words" at a glance. */
.v2-domain__chip.is-action {
  width: 150px;
  min-height: 28px;
  border-radius: 999px;
  border-style: dashed;
  background: transparent;
}
.v2-domain__chip.is-empty .v2-domain__label { font-style: italic; opacity: 0.7; }

/* Option stubs hang to the RIGHT of a decision. A node holding a writing takes no
   children (the leaf rule), so a decision is always a leaf and the space is free. */
.v2-domain__stubs { display: flex; align-items: center; gap: 4px; margin-left: 6px; }
.v2-domain__stub {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  padding: 2px 7px;
  font-size: 10.5px;
  color: var(--accent2);
  border: 1px solid var(--accent2);
  border-radius: 999px;
  background: var(--panel);
}
.v2-domain__stub.is-resolved { border-style: solid; }
.v2-domain__stubTo {
  font-style: normal;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 9.5px;
  color: var(--ink2);
}

/* ── floating chrome ────────────────────────────────────────────────────── */
/* BELOW the filter bar, not over it. The chrome was pinned at `top: 8px` when the plane
   started at the surface's top edge; the filter bar took that band and the chrome went on
   floating in it — covering the unassigned toggle so completely that a real click landed
   on an SVG instead. Measured in the browser: "…v2-domain__glyph… from
   <div class="v2-domain__chrome"> subtree intercepts pointer events", 60 retries. */
.v2-domain__chrome {
  position: absolute;
  top: 52px;
  right: 8px;
  z-index: 4;
  display: flex;
  gap: 6px;
}
.v2-domain__ctl {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--line, #d8dee4);
  border-radius: 8px;
  background: var(--paper, #fff);
  color: var(--ink2);
  cursor: pointer;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.16);
}
.v2-domain__ctl:hover { color: var(--accent); border-color: var(--accent); }
.v2-domain__ctl:focus-visible { outline: 2px solid var(--accent2); outline-offset: 2px; }
.v2-domain__glyph { width: 17px; height: 17px; display: block; }
/* The plane's own zoom stack sits bottom-right, clear of the chrome above and next to
   the hand that is already down there — the placement the network map settled on. */
.v2-domain .v2-mapZoom { top: auto; bottom: 10px; right: 10px; }

/* ── the selection card ─────────────────────────────────────────────────── */
.v2-domain__card {
  position: absolute;
  z-index: 6;
  top: 8px;
  right: 8px;
  bottom: 8px;
  width: 340px;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line, #d8dee4);
  border-radius: 10px;
  background: var(--paper, #fff);
  box-shadow: 0 6px 28px rgba(0, 0, 0, 0.24);
  overflow: hidden;
  animation: v2DomainCardIn 140ms ease-out;
}
@keyframes v2DomainCardIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .v2-domain__card { animation: none; }
}
.v2-domain__card[hidden] { display: none; }
/* The card and the controls float OVER a surface that refuses the browser's gestures, so
   they take their own back explicitly. Stated on the elements rather than as
   `.is-touchmap *`: they are SIBLINGS of the plane, not children of it, so an inheritance
   rule keyed on the plane's class matches nothing — measured, after asserting it did. */
.v2-domain__card,
.v2-domain__filter,
.v2-domain__chrome { touch-action: pan-y; }
.v2-domain__cardHead {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 8px 8px 12px;
  border-bottom: 1px solid var(--line, #d8dee4);
  background: var(--panel);
}
.v2-domain__cardAddr {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
  letter-spacing: 0.02em;
}
.v2-domain__title {
  flex: 1 1 auto;
  min-width: 0;
  font: inherit;
  font-size: 13px;
  padding: 4px 6px;
  border: 1px solid transparent;
  border-radius: 5px;
  background: transparent;
  color: var(--ink);
}
.v2-domain__title:hover { border-color: var(--line, #d8dee4); }
.v2-domain__title:focus { border-color: var(--accent); background: var(--paper); outline: none; }
.v2-domain__ctl--close { width: 28px; height: 28px; box-shadow: none; }
.v2-domain__cardBody { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 10px 12px 16px; }
.v2-domain__meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.v2-domain__parent { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--ink2); }
.v2-domain__parent select,
.v2-domain__action {
  font: inherit;
  font-size: 11px;
  padding: 3px 6px;
  border: 1px solid var(--line, #d8dee4);
  border-radius: 5px;
  background: var(--paper);
  color: var(--ink);
  max-width: 190px;
}
.v2-domain__kind { font-size: 10.5px; color: var(--ink2); text-transform: lowercase; }
.v2-domain__acts { display: flex; gap: 6px; margin: 10px 0 4px; flex-wrap: wrap; }
.v2-domain__acts--docs { align-items: center; }
.v2-domain__denotes {
  font-size: 10.5px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--ink2);
}
.v2-domain__kindTag {
  flex: 0 0 auto;
  font-size: 10px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--ink2);
  border: 1px solid var(--line, #d8dee4);
  border-radius: 3px;
  padding: 0 5px;
}
.v2-domain__act {
  flex: 1 1 62px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  min-height: 46px;
  padding: 6px 4px;
  font: inherit;
  font-size: 10px;
  border: 1px solid var(--line, #d8dee4);
  border-radius: 7px;
  background: var(--panel);
  color: var(--ink2);
  cursor: pointer;
}
.v2-domain__act em { font-style: normal; }
.v2-domain__act:hover { color: var(--accent); border-color: var(--accent); }
.v2-domain__act.is-danger:hover { color: var(--danger); border-color: var(--danger); }
.v2-domain__act:focus-visible { outline: 2px solid var(--accent2); outline-offset: 2px; }
.v2-domain__decision {
  margin: 10px 0 0;
  padding: 6px 8px;
  font-size: 11px;
  color: var(--accent2);
  border-left: 3px solid var(--accent2);
  background: var(--panel);
}
.v2-domain__writing { margin-top: 12px; }
.v2-domain__writingHead {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink2);
}
.v2-domain__writingHead > span:first-child { flex: 1 1 auto; }
.v2-domain__text {
  width: 100%;
  box-sizing: border-box;
  margin-top: 5px;
  padding: 7px 8px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  line-height: 1.45;
  resize: vertical;
  border: 1px solid var(--line, #d8dee4);
  border-radius: 6px;
  background: var(--paper);
  color: var(--ink);
}
.v2-domain__text:focus { border-color: var(--accent); outline: none; }
.v2-domain__writingBar { display: flex; align-items: center; gap: 8px; margin-top: 5px; }
.v2-domain__save {
  font: inherit;
  font-size: 11px;
  padding: 4px 12px;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: var(--accent);
  color: var(--accent-fg);
  cursor: pointer;
}
.v2-domain__save:hover { filter: brightness(1.08); }
.v2-domain__hint { font-size: 10px; color: var(--ink2); }
.v2-domain__mini {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font: inherit;
  font-size: 10.5px;
  padding: 3px 8px;
  border: 1px solid var(--line, #d8dee4);
  border-radius: 6px;
  background: transparent;
  color: var(--ink2);
  cursor: pointer;
}
.v2-domain__mini:hover { color: var(--accent); border-color: var(--accent); }
.v2-domain__mini.is-danger:hover { color: var(--danger); border-color: var(--danger); }
.v2-domain__mini .v2-domain__glyph { width: 13px; height: 13px; }
.v2-domain__opts { margin-top: 12px; }
.v2-domain__opts .v2-domain__writing {
  padding-left: 9px;
  border-left: 3px solid var(--accent2);
}
.v2-domain__panes > .v2-domain__pane { margin-top: 14px; }
/* THE VIEW PANE (2026-10-26): a document's face, drawn in the card by the shell's own
   dispatcher. A viewscope article paints at the width it is given; in a 340px aside
   that is a column, and anything wider scrolls within the pane rather than widening
   the card over the tree. */
.v2-domain__view { overflow-x: auto; }
.v2-domain__status { margin: 10px 0 0; font-size: 11px; color: var(--ink2); min-height: 1em; }
.v2-domain__why { font-size: 12px; color: var(--ink2); }

/* ── the branch question, inside the shared confirmation ────────────────── */
.v2-modal__choices { margin: 10px 0 0; padding: 0; border: 0; }
.v2-modal__choices legend {
  padding: 0;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink2);
}
.v2-modal__choice {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: 7px;
  padding: 7px 9px;
  font-size: 12px;
  border: 1px solid var(--line, #d8dee4);
  border-radius: 6px;
  cursor: pointer;
}
.v2-modal__choice:has(input:checked) { border-color: var(--accent); }
.v2-modal__choice input { margin-top: 2px; }
.v2-modal__choiceHelp { display: block; margin-top: 2px; font-size: 11px; font-style: normal; color: var(--ink2); }

/* ── the phone ──────────────────────────────────────────────────────────── */
/* The card becomes a bottom sheet: a 340px panel pinned to the right edge of a 390px
   screen IS the screen, and the tree it is about would be entirely behind it. */
@media (max-width: 720px) {
  /* FULL BLEED, by clearing the insets rather than escaping them. Three ancestors each
     take their own padding — `.viewport` 18px, `#v2-workbench-body` 9.6px and
     `.v2-toolHost__body` 12px, measured — which is a fifth of a 390px screen spent on
     nothing. A `width: 100vw` + negative-margin bleed was tried first and is WRONG here:
     `.v2-tabbed__body` scrolls, so it clips the escaped child, and the card's own text
     came out cut off at x=41 while every rectangle measured correct. `:has()` lets each
     parent answer for its child, the same idiom the map shell's `data-fullbleed` uses
     one level up. */
  .viewport:has(.v2-domain),
  #v2-workbench-body:has(.v2-domain),
  .v2-toolHost__body:has(.v2-domain) { padding-left: 0; padding-right: 0; }
  .v2-domain { border-radius: 0; border-left: 0; border-right: 0; }
  .v2-domain__card {
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    max-height: 66%;
    border-radius: 12px 12px 0 0;
  }
  .v2-domain__cardBody { padding: 10px 12px calc(16px + env(safe-area-inset-bottom, 0px)); }
  .v2-domain__act { flex: 1 1 0; min-height: 52px; font-size: 10px; }
  .v2-domain__parent select { max-width: 150px; }
  /* The zoom stack rides above the sheet rather than under it. */
  .v2-domain:has(.v2-domain__card:not([hidden])) .v2-mapZoom { display: none; }
  /* The filter bar keeps its search and its toggle and drops the count — a phone has no
     room for a figure that repeats what the dimming already shows. */
  .v2-domain__found { display: none; }
  .v2-domain__filter { padding: 0 8px; gap: 6px; }
  .v2-domain__toggleBtn { padding: 0 9px; }
}

/* ── SOURCES: three buckets, and a page for the instance ────────────────────────
   The ORIGIN is the question these sections exist to answer, so it leads: a row that
   led with the document name made the reader work out where it came from from the
   sandbox column. `is-delivered` marks a source that ARRIVED as a contract payload
   rather than one this instance reached for. */
.v2-compendium__barLink {
  flex: 0 0 auto;
  margin-left: auto;
  font-size: 12px;
  color: var(--accent, #1e6c93);
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: 5px;
  padding: 2px 8px;
}
.v2-compendium__barLink:hover { border-color: var(--line, #afafaa); }
.v2-compendium__barLink.is-open {
  border-color: var(--accent, #1e6c93);
  background: rgba(30, 108, 147, 0.1);
}
.v2-compendium__barLink:focus-visible {
  outline: 2px solid var(--accent, #1e6c93);
  outline-offset: 2px;
}
.v2-compendium__sources--instance { margin-top: 4px; }
.v2-compendium__sourceRow.is-delivered .v2-compendium__sourceName { font-weight: 600; }
.v2-compendium__sourceDelivered {
  color: var(--v2-source-external, #b4791f);
  font-size: 12px;
  margin-right: 4px;
}
.v2-compendium__sourceStatus[data-status="stale"] { color: var(--v2-source-external, #b4791f); }
.v2-compendium__sourcesUpdate {
  margin: 6px 14px;
  padding: 6px 10px;
  font-size: 12px;
  border-left: 3px solid var(--v2-source-external, #b4791f);
  background: rgba(180, 121, 31, 0.1);
}

/* A sandbox's SETTINGS, over the plane. Not beside it: the domain face is full bleed,
   and a panel under it is a panel nobody reaches. */
.v2-compendium__settings { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 0 20px; }
.v2-compendium__settingsHead {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line, #afafaa);
}
.v2-compendium__settingsTabs { display: flex; gap: 4px; }
.v2-compendium__settingsTab {
  font-size: 12.5px;
  padding: 4px 10px;
  border: 1px solid transparent;
  border-radius: 6px;
  color: inherit;
  text-decoration: none;
}
.v2-compendium__settingsTab:hover { border-color: var(--line, #afafaa); }
.v2-compendium__settingsTab.is-active {
  border-color: var(--accent, #1e6c93);
  color: var(--accent, #1e6c93);
  font-weight: 600;
}
.v2-compendium__settingsTab:focus-visible {
  outline: 2px solid var(--accent, #1e6c93);
  outline-offset: 2px;
}
.v2-compendium__settings .v2-compendium__sourcesManage { margin-left: auto; }

/* ============================================================ chart
   Four modes, one visual grammar. Figures are ALWAYS mono with tabular numerals — a
   number that shifts width as it changes is a number you cannot compare down a column,
   and comparison is the only reason these panes exist. */
.v2-chart {
  padding: 12px 14px 14px;
  background: var(--ide-panel-bg, var(--paper2));
  border: 1px solid var(--ide-border, var(--line));
  border-radius: var(--radius);
}
.v2-chart__header {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin-bottom: 10px;
}
/* A HEADING IS A SENTENCE (2026-10-16, TASK-2026-10-16-002). This was the tracked-out
   monospace eyebrow — 11px, uppercase — so every Analytics pane read "PEOPLE, MONTH BY
   MONTH" beside tables titled in sentence case. Written in sentence case by the panes, and
   drawn as written here, so every chart (and every pane that draws one) follows. */
.v2-chart__title {
  font-family: inherit; font-size: 13px; font-weight: 600; letter-spacing: 0;
  text-transform: none; color: var(--ink, inherit);
}
.v2-chart__count {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px; font-variant-numeric: tabular-nums; color: var(--ink2, #888);
}
.v2-chart__empty, .v2-chart__note {
  margin: 6px 0 0; font-size: 12px; color: var(--ink2, #888);
}

/* -- rank: a ranked list read as bars off a shared baseline. */
.v2-chart__rank { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; }
.v2-chart__rank li {
  display: grid; grid-template-columns: minmax(0, 11rem) 1fr auto;
  align-items: center; gap: 10px;
}
.v2-chart__rankKey {
  font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.v2-chart__rankTrack {
  height: 9px; background: color-mix(in srgb, var(--ink2, #888) 18%, transparent);
  border-radius: 1px; overflow: hidden;
}
.v2-chart__rankBar { display: block; height: 100%; border-radius: 1px; }
.v2-chart__rankVal {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px; font-variant-numeric: tabular-nums; color: var(--ink, #464646);
}

/* -- split: one stacked proportion bar. */
.v2-chart__split {
  display: flex; height: 22px; border-radius: 2px; overflow: hidden;
  background: color-mix(in srgb, var(--ink2, #888) 15%, transparent);
}
.v2-chart__splitPart { display: block; height: 100%; }

/* -- meter: what is USED against what is INCLUDED, one track per row (Home's storage,
      2026-10-26). The split's track — the same tokens, so every theme restates it the
      way it restates the split — laid out like a rank row so the two read as one
      grammar: label · "used of included" · track · share. The fill's colour is the
      ramp's, set per row by the renderer; it never exceeds the track (the renderer caps
      the share) and keeps a 1px floor while anything is used, because a 0.1% that
      vanished would read as nothing kept.
      THE COLUMNS ARE THE LIST'S (side-2026-11-03-0064). Each row was a grid of its own,
      so its figure column was as wide as ITS figure and its track began after it: at
      1280px a base account's website files drew from 281.6px, 932px long, and its
      records from 303.3px, 910.3px long, two scales in one meter. The list holds the four
      columns and each row takes them as a subgrid, so the figure column is the widest
      figure's, the share column the widest share's, and every track of a meter starts at
      one edge and is one width. The row's own template is declared before `subgrid`: an
      engine without subgrid drops that line and draws each row as it did before. */
.v2-chart__meter {
  list-style: none; margin: 0; padding: 0; display: grid; gap: 7px 10px;
  grid-template-columns: minmax(0, 8rem) auto 1fr auto;
}
.v2-chart__meter li {
  display: grid; grid-column: 1 / -1; align-items: center; gap: 10px;
  grid-template-columns: minmax(0, 8rem) auto 1fr auto;
  grid-template-columns: subgrid;
}
.v2-chart__meterKey {
  font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.v2-chart__meterVal, .v2-chart__meterPct {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.v2-chart__meterVal { color: var(--ink); }
.v2-chart__meterPct { color: var(--ink2); min-width: 3.2em; text-align: right; }
.v2-chart__meterTrack {
  display: block; height: 9px; border-radius: 1px; overflow: hidden;
  background: color-mix(in srgb, var(--ink2) 15%, transparent);
}
.v2-chart__meterFill { display: block; height: 100%; max-width: 100%; border-radius: 1px; }
.v2-chart__meterFill.is-used { min-width: 1px; }

/* -- legend, shared by split and donut. */
.v2-chart__legend { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 4px; }
.v2-chart__legend--inline {
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 4px 14px;
}
.v2-chart__legend li { display: flex; align-items: center; gap: 7px; font-size: 12px; }
.v2-chart__legend i {
  width: 9px; height: 9px; border-radius: 1px; flex: none;
}
.v2-chart__legendKey { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-chart__legendVal, .v2-chart__legendPct {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px; font-variant-numeric: tabular-nums;
}
.v2-chart__legendPct { color: var(--ink2, #888); min-width: 2.6em; text-align: right; }

/* -- donut. */
.v2-chart__donutRow { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.v2-chart__donut { width: 128px; height: 128px; flex: none; }
.v2-chart__donutRow .v2-chart__legend { margin: 0; flex: 1 1 11rem; min-width: 0; }
.v2-chart__donutTotal {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 21px; font-variant-numeric: tabular-nums;
  fill: var(--ink, #464646);
}

/* -- series: THE MONTH STRIP. The signature of the Analytics tab: a run of months as
      columns, the active one lifted, every one a control. Columns share one scale, so a
      quiet month reads as quiet — normalising each to its own height would draw every
      month identically and answer nothing. */
.v2-chart__strip {
  /* A DEFINITE height on the strip is what makes the columns drawable: the bars are
     positioned inside a track below, and a track with no resolved height gives a
     percentage nothing to resolve against. */
  display: flex; align-items: stretch; gap: 6px;
  height: 136px; overflow-x: auto; padding-bottom: 2px;
}
.v2-chart__month {
  flex: 1 1 0; min-width: 34px; max-width: 96px;
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  background: none; border: 0; padding: 4px 2px 0; cursor: pointer;
  font: inherit; color: inherit; border-radius: 2px;
}
.v2-chart__monthTrack {
  position: relative; width: 100%; flex: 1 1 auto; min-height: 0;
}
.v2-chart__month:hover { background: color-mix(in srgb, var(--ink2, #888) 10%, transparent); }
.v2-chart__month:focus-visible { outline: 2px solid var(--accent, #1e6c93); outline-offset: 1px; }
.v2-chart__monthBar {
  position: absolute; left: 0; right: 0; bottom: 0; min-height: 2px;
  background: color-mix(in srgb, var(--viz-1) 42%, transparent);
  border-radius: 1px 1px 0 0;
  display: flex; align-items: flex-end;
  transition: background 120ms ease;
}
/* The bot share, drawn INSIDE the column rather than beside it: it is part of the same
   traffic, and a second column would double-count the month at a glance. */
.v2-chart__monthSub {
  width: 100%; display: block;
  background: color-mix(in srgb, var(--viz-6) 70%, transparent);
  border-radius: 0 0 1px 1px;
}
.v2-chart__month.is-active .v2-chart__monthBar { background: var(--viz-1); }
.v2-chart__monthVal {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px; font-variant-numeric: tabular-nums; color: var(--ink, #464646);
}
.v2-chart__month.is-active .v2-chart__monthVal { font-weight: 600; }
.v2-chart__monthKey {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 10px; letter-spacing: 0.04em; color: var(--ink2, #888);
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  .v2-chart__monthBar { transition: none; }
}
@media (max-width: 640px) {
  .v2-chart__rank li { grid-template-columns: minmax(0, 7rem) 1fr auto; }
  .v2-chart__donutRow { gap: 12px; }
  /* A meter row at phone width: the label and the share on one line, the figure under
     them, the track full width — four cells side by side would leave the track no room.
     Each row is a grid of its own here, as every row was before the list held the
     columns, so the phone rows do not lean on the desk's: a track that spans its whole
     row already starts at the meter's one edge and is its one width. */
  .v2-chart__meter { grid-template-columns: none; }
  .v2-chart__meter li {
    grid-column: auto; grid-template-columns: 1fr auto; gap: 3px 10px;
    grid-template-areas: "key pct" "val val" "track track";
  }
  .v2-chart__meterKey { grid-area: key; }
  .v2-chart__meterPct { grid-area: pct; }
  .v2-chart__meterVal { grid-area: val; }
  .v2-chart__meterTrack { grid-area: track; }
}

/* ============================================================ record_table
   The most-used container in the portal had NO base styling: no frame, no header
   treatment, no cell rhythm — every table rendered as naked HTML beside panes that were
   framed, which is most of why the application read as unfinished.

   Deliberately the SAME frame, eyebrow and figure treatment as .v2-chart, so a tab
   holding a chart and a table reads as one surface rather than two. */
.v2-recordTable {
  padding: 12px 14px 14px;
  background: var(--ide-panel-bg, var(--paper2));
  border: 1px solid var(--ide-border, var(--line));
  border-radius: var(--radius);
}
/* Sentence case, as .v2-chart__title above: the eyebrow's capitals were the same drift. */
.v2-recordTable__header {
  font-family: inherit; font-size: 13px; font-weight: 600; letter-spacing: 0;
  text-transform: none; color: var(--ink, inherit); margin-bottom: 10px;
}
/* Wide content scrolls INSIDE its own box. A table that widens the page pushes every
   other pane off-screen, and on a phone that is the whole application. */
.v2-recordTable__wrap { overflow-x: auto; }
.v2-recordTable__table {
  width: 100%; border-collapse: collapse;
  font-size: 13px; font-variant-numeric: tabular-nums;
}
.v2-recordTable__table th {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 10px; letter-spacing: 0.07em; text-transform: uppercase;
  font-weight: 500; color: var(--ink2, #888);
  text-align: left; padding: 0 12px 6px 0; white-space: nowrap;
  border-bottom: 1px solid var(--ide-border, var(--line));
}
.v2-recordTable__table td {
  padding: 7px 12px 7px 0; vertical-align: top;
  border-bottom: 1px solid color-mix(in srgb, var(--ink2, #888) 16%, transparent);
}
.v2-recordTable__table tr:last-child td { border-bottom: 0; }
.v2-recordTable__table th:last-child,
.v2-recordTable__table td:last-child { padding-right: 0; }
/* A cell holding a long address must not set the table's width. */
.v2-recordTable__table td { max-width: 28rem; overflow-wrap: anywhere; }
.v2-recordTable__table tr.is-flagged td {
  background: color-mix(in srgb, var(--warn, var(--accent)) 9%, transparent);
}
.v2-recordTable__empty {
  margin: 4px 0 0; font-size: 12px; color: var(--ink2, #888);
}
/* PER-ROW REVEAL (2026-10-05): a trailing Show/Hide toggle and the hidden row it opens.
   Opt-in through payload.detail_key — see renderRecordTable. The detail row is a two-
   column definition list so a label and its value read as one line each. */
.v2-recordTable__toggle {
  font: inherit; font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 2px 9px; border-radius: 999px; cursor: pointer; white-space: nowrap;
  color: var(--ink2, #888); background: transparent;
  border: 1px solid var(--ide-border, var(--line));
}
.v2-recordTable__toggle:hover,
.v2-recordTable__toggle[aria-expanded="true"] {
  color: var(--ink, inherit); border-color: var(--ink2, #888);
}
.v2-recordTable__detail[hidden] { display: none; }
.v2-recordTable__detail td {
  padding: 0 0 10px;
  background: color-mix(in srgb, var(--ink2, #888) 5%, transparent);
}
.v2-recordTable__detail dl {
  display: grid; grid-template-columns: max-content 1fr; gap: 3px 14px;
  margin: 0; padding: 8px 12px; font-size: 12px;
}
.v2-recordTable__detail dt {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 10px; letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--ink2, #888); align-self: baseline;
}
.v2-recordTable__detail dd { margin: 0; overflow-wrap: anywhere; white-space: pre-wrap; }

/* ==== Enchir — a gallery of projects, and one project's page (2026-09-10) =============
   The photograph is the interface: tiles are the pictures the site shows, edge to edge,
   with a hairline and no shadow; the chrome takes the portal's own tokens; the ONE accent
   is the primary save. Numbers on the tiles are a sequence, which is what an order is.
   Buttons are the first way to reorder (a phone has no hover and no reliable drag);
   drag is the second. Hidden tiles fade rather than vanish — kept, not shown. */
.v2-projects { padding: 12px 14px 16px; background: var(--ide-panel-bg, var(--paper2));
  border: 1px solid var(--ide-border, var(--line)); border-radius: var(--radius); }
.v2-projects__header { display: flex; align-items: baseline; gap: 12px; margin: 0 0 12px; }
.v2-projects__header h3 { margin: 0; font-size: 16px; font-weight: 600; color: var(--ink); }
.v2-projects__count { font-size: 12px; color: var(--ink2); }
.v2-projects__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px; }
.v2-projects__tile { display: flex; flex-direction: column; text-align: left; padding: 0;
  font: inherit; color: var(--ink); background: var(--surface, var(--paper));
  border: 1px solid var(--ide-border, var(--line)); border-radius: 3px; cursor: pointer; overflow: hidden; }
.v2-projects__tile:hover .v2-projects__name, .v2-projects__tile:focus-visible .v2-projects__name { text-decoration: underline; }
.v2-projects__tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.v2-projects__picture { display: block; aspect-ratio: 4 / 3; background: var(--coal2); overflow: hidden; }
/* Where the "picture" is the writing's first line, a shallower box: words are not a photograph.
   INK on PAPER inverted, not coal: `--coal2` is near-black in every palette while `--paper` is
   light in one and dark in the rest, so on Spore (the default) the words vanished into the box.
   `--ink` is the one colour guaranteed to contrast with `--paper` in all five themes. */
.v2-projects__picture:has(.v2-projects__excerpt) { aspect-ratio: 2 / 1; background: var(--ink); }
.v2-projects__picture img { width: 100%; height: 100%; object-fit: cover; display: block; }
.v2-projects__noPicture { display: flex; align-items: center; justify-content: center; height: 100%;
  color: var(--paper); font-size: 12px; text-align: center; padding: 8px; }
.v2-projects__name { padding: 10px 12px 2px; font-size: 15px; font-weight: 600; line-height: 1.25; }
/* A writing card: the first line stands where a photograph would (2026-10-05). */
.v2-projects__excerpt { height: 100%; padding: 12px; box-sizing: border-box;
  color: var(--paper); font-size: 13px; line-height: 1.35; overflow: hidden; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; }
/* The "+" card — a plus inside a circle, first in the grid. */
.v2-projects__tile--new { align-items: center; justify-content: center; min-height: 100%;
  border-style: dashed; background: transparent; }
.v2-projects__tile--new .v2-projects__name { padding: 6px 12px 14px; font-weight: 500; color: var(--ink2); }
.v2-projects__plus { display: flex; align-items: center; justify-content: center; width: 56px; height: 56px;
  margin-top: 28px; border: 2px solid var(--ink2); border-radius: 50%; font-size: 34px; line-height: 1;
  color: var(--ink2); }
.v2-projects__tile--new:hover .v2-projects__plus, .v2-projects__tile--new:focus-visible .v2-projects__plus {
  border-color: var(--accent); color: var(--accent); }
.v2-projects__meta { padding: 0 12px 12px; font-size: 12px; color: var(--ink2); }
.v2-projects__empty { margin: 0; font-size: 13px; color: var(--ink2); max-width: 60ch; }

.v2-project { padding: 12px 14px 16px; background: var(--ide-panel-bg, var(--paper2));
  border: 1px solid var(--ide-border, var(--line)); border-radius: var(--radius); }
.v2-project__nav { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 12px; }
.v2-project__back { font: inherit; font-size: 13px; color: var(--ink); background: transparent;
  border: 1px solid var(--ide-border, var(--line)); border-radius: 3px; padding: 6px 12px; cursor: pointer; }
.v2-project__back:hover { background: var(--surface, var(--paper)); }
.v2-project__site { font-size: 13px; color: var(--accent); }
.v2-project__top { display: grid; grid-template-columns: minmax(280px, 5fr) minmax(280px, 6fr); gap: 18px; align-items: start; }
.v2-project__cover { margin: 0; aspect-ratio: 16 / 10; background: var(--coal2); border-radius: 3px; overflow: hidden; }
.v2-project__cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.v2-project__facts { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.v2-project__field { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--ink2); }
.v2-project__field input, .v2-project__field textarea { font: inherit; font-size: 14px; color: var(--ink);
  padding: 7px 9px; border: 1px solid var(--ide-border, var(--line)); border-radius: 4px;
  background: var(--surface, var(--paper)); width: 100%; box-sizing: border-box; }
.v2-project__field--title input { font-size: 20px; font-weight: 600; line-height: 1.2; }
.v2-project__field textarea { resize: vertical; line-height: 1.45; }
.v2-project__field input:focus-visible, .v2-project__field textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.v2-project__line { margin: -4px 0 0; font-size: 13px; color: var(--ink2); }
.v2-project__photosHeader { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; margin: 18px 0 10px; }
.v2-project__photosHeader h3 { margin: 0; font-size: 16px; font-weight: 600; color: var(--ink); }
.v2-project__photosHeader [data-summary] { font-size: 12px; color: var(--ink2); }
.v2-project__hint { flex-basis: 100%; font-size: 12px; color: var(--ink2); max-width: 70ch; }
.v2-project__grid { list-style: none; margin: 0; padding: 0; display: grid;
  grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); gap: 12px; }
.v2-project__tile { position: relative; display: flex; flex-direction: column; background: var(--surface, var(--paper));
  border: 1px solid var(--ide-border, var(--line)); border-radius: 3px; overflow: hidden; }
.v2-project__tile.is-feature { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.v2-project__tile.is-hidden .v2-project__picture { opacity: 0.45; filter: saturate(0.2); }
.v2-project__tile.is-dragging { opacity: 0.5; }
.v2-project__order { position: absolute; top: 6px; left: 6px; z-index: 1; min-width: 22px; height: 22px; padding: 0 6px;
  display: inline-flex; align-items: center; justify-content: center; font-size: 12px; font-variant-numeric: tabular-nums;
  color: var(--paper); background: rgba(0,0,0,0.62); border-radius: 11px; }
.v2-project__featureMark { position: absolute; top: 6px; right: 6px; z-index: 1; padding: 2px 8px;
  font-size: 11px; font-weight: 600; color: var(--paper); background: var(--ink); border-radius: 3px; }
.v2-project__picture { display: block; aspect-ratio: 4 / 3; background: var(--coal2); overflow: hidden; }
.v2-project__picture img { width: 100%; height: 100%; object-fit: cover; display: block; }
.v2-project__play { display: flex; align-items: center; justify-content: center; height: 100%; font-size: 28px; color: var(--paper); }
.v2-project__caption { padding: 8px 10px 4px; font-size: 12px; color: var(--ink); line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-project__controls { display: grid; grid-template-columns: 1fr auto auto 1fr; gap: 4px; padding: 0 8px 8px; }
.v2-project__controls button { min-height: 34px; padding: 0 8px; font: inherit; font-size: 12px; color: var(--ink);
  background: transparent; border: 1px solid var(--ide-border, var(--line)); border-radius: 3px; cursor: pointer; }
.v2-project__controls button:hover:not(:disabled) { background: var(--paper2); }
.v2-project__controls button:disabled { opacity: 0.35; cursor: default; }
.v2-project__controls button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.v2-project__tile--video .v2-project__caption { color: var(--ink2); }
.v2-project__tile--add { border-style: dashed; background: transparent; }
.v2-project__add { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  height: 100%; min-height: 100%; padding: 18px 12px; box-sizing: border-box; text-align: center; cursor: pointer; }
.v2-project__add input { position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden; }
.v2-project__addMark { font-size: 30px; line-height: 1; color: var(--ink2); }
.v2-project__addWord { font-size: 13px; font-weight: 600; color: var(--ink); }
.v2-project__addHint { font-size: 11px; line-height: 1.35; color: var(--ink2); max-width: 22ch; }
.v2-project__tile--add:hover { background: var(--paper2); }
.v2-project__tile--add:focus-within { outline: 2px solid var(--accent); outline-offset: 1px; }
.v2-project__add input:disabled ~ .v2-project__addWord { opacity: 0.5; }
.v2-project__save { position: sticky; bottom: 0; display: flex; justify-content: flex-end; align-items: center; gap: 14px;
  margin: 14px -14px -16px; padding: 10px 14px; background: var(--ide-panel-bg, var(--paper2));
  border-top: 1px solid var(--ide-border, var(--line)); }
.v2-project__status { font-size: 12px; color: var(--ink2); }
.v2-project__saveBtn { font: inherit; font-size: 14px; padding: 8px 18px; color: var(--accent-fg, #fff);
  background: var(--accent); border: 1px solid var(--accent); border-radius: 4px; cursor: pointer; }
.v2-project__saveBtn:hover { filter: brightness(1.08); }
.v2-project__saveBtn:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
@media (max-width: 720px) {
  .v2-project__top { grid-template-columns: 1fr; }
  .v2-project__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .v2-project__controls { grid-template-columns: 1fr 1fr; }
  .v2-project__controls button { min-height: 40px; }
  .v2-projects__grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 10px; }
  .v2-projects__picture:has(.v2-projects__excerpt) { aspect-ratio: 5 / 2; }
  .v2-projects__plus { margin-top: 18px; }
}
@media (prefers-reduced-motion: no-preference) {
  .v2-project__tile { transition: opacity 120ms ease; }
}

/* ===================================================================================
   THE CLIENT DASHBOARD'S GRAMMAR (2026-10-07, TASK-2026-10-07-003) — body.v2-client-shell
   only; the operator console is untouched.

   Three kinds of surface, three borders, so a person can tell at a glance what a thing
   IS before reading it:
     FACTS  (tables, tiles, charts)      — no frame: hairlines between rows, nothing around
     SHEET  (anything you fill in)       — one ink frame on paper: "you can write here"
     ACTION (a form with no fields)      — the button is the object: large, icon + verb
   The renderers derive the kind from what the pane is (`v2-surface--*`); a payload may
   say otherwise. Operator asked: "differently bordered items … less form fields initially
   … more icon representing buttons, like add or send."
   =================================================================================== */
body.v2-client-shell .v2-recordTable.v2-surface--facts,
body.v2-client-shell .v2-chart.v2-surface--facts,
body.v2-client-shell .v2-stats.v2-surface--facts {
  border: 0; background: transparent; border-radius: 0; padding: 6px 2px 10px;
}
/* The summary strip (Home): a figure such as "233.69 MB" stays on one line, so a tile is as
   wide as its figure needs; at phone width two tiles share a row. */
body.v2-client-shell .v2-stats__grid { grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); }
body.v2-client-shell .v2-stats__val { white-space: nowrap; }
/* A table's title: a sentence, not a tracked-out label. The count stays quiet beside it. */
body.v2-client-shell .v2-recordTable__header {
  font-family: inherit; font-size: 15px; font-weight: 600; letter-spacing: 0; text-transform: none;
  color: var(--ink); margin-bottom: 8px;
}
body.v2-client-shell .v2-recordTable__header .v2-recordTable__count { font-weight: 400; font-size: 12px; color: var(--ink2); }
/* A chart's title is the same heading as a table's, so Analytics reads as one surface. */
body.v2-client-shell .v2-chart__title { font-size: 15px; color: var(--ink); }
body.v2-client-shell .v2-recordTable__table th {
  font-family: inherit; font-size: 12px; letter-spacing: 0; text-transform: none; font-weight: 500;
  color: var(--ink2); border-bottom: 1px solid var(--ink2);
}
body.v2-client-shell .v2-recordTable__table td { padding: 9px 12px 9px 0; }
body.v2-client-shell .v2-recordTable__notice { font-size: 13px; color: var(--ink2); max-width: 72ch; }

/* The search that narrows a long table as you type. */
body.v2-client-shell .v2-recordTable__filter { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; }
body.v2-client-shell .v2-recordTable__filter input {
  font: inherit; font-size: 14px; padding: 7px 10px 7px 34px; min-width: 260px; max-width: 100%;
  border: 1px solid var(--ink); border-radius: 8px; background: var(--paper); color: var(--ink);
  background-image: none;
}
body.v2-client-shell .v2-recordTable__filter .mc-icon { position: absolute; margin-left: 10px; width: 16px; height: 16px; opacity: 0.7; pointer-events: none; }
body.v2-client-shell .v2-recordTable__filter label { position: relative; display: inline-flex; align-items: center; }
body.v2-client-shell .v2-recordTable__filterCount { font-size: 12px; color: var(--ink2); }

/* A SHEET: one ink frame on paper. The frame means "you can write here". */
body.v2-client-shell .v2-recordForm.v2-surface--sheet {
  border: 1px solid var(--ink); border-radius: 8px; background: var(--paper); padding: 14px 16px 16px;
  align-items: flex-end;
}
body.v2-client-shell .v2-recordForm.v2-surface--sheet .v2-recordForm__header { font-size: 15px; font-weight: 600; color: var(--ink); margin-bottom: 6px; }
body.v2-client-shell .v2-recordForm__field { font-size: 12px; color: var(--ink2); }
body.v2-client-shell .v2-recordForm__field input, body.v2-client-shell .v2-recordForm__field select, body.v2-client-shell .v2-recordForm__field textarea {
  font-size: 14px; padding: 6px 9px; border-radius: 6px; border-color: var(--line); background: var(--paper);
}
/* "More": the fields a form can wait to ask for. */
body.v2-client-shell .v2-recordForm__more { flex: 1 1 100%; }
body.v2-client-shell .v2-recordForm__more > summary { cursor: pointer; font-size: 13px; color: var(--accent); list-style: none; padding: 2px 0; }
body.v2-client-shell .v2-recordForm__more > summary::-webkit-details-marker { display: none; }
body.v2-client-shell .v2-recordForm__more > summary::before { content: "+ "; }
body.v2-client-shell .v2-recordForm__more[open] > summary::before { content: "− "; }
body.v2-client-shell .v2-recordForm__more > .v2-recordForm__fields { margin-top: 8px; }
/* A file field reads as a button, not a path box. */
body.v2-client-shell .v2-recordForm__field input[type="file"] { padding: 6px 4px; border: 1px dashed var(--ink2); }

/* An ACTION: a form with nothing to fill in is its button — no frame, no title (the button's
   verb is the title). Since 2026-10-16 the button is the same icon button as every other
   act (below), not a full-width banner: one action style. */
body.v2-client-shell .v2-recordForm.v2-surface--action { border: 0; background: transparent; padding: 0; flex-direction: column; align-items: flex-start; gap: 4px; }
body.v2-client-shell .v2-recordForm.v2-surface--action .v2-recordForm__header { display: none; }
body.v2-client-shell .v2-recordForm.v2-surface--action .v2-recordForm__fields { display: none; }
/* THE WRAPPERS ARE INVISIBLE. Every surface now carries the frame its kind earns, so the
   composite panes that arrange them must not add a second one — the first render showed a
   sheet inside a box and three buttons inside a box. The composite still lays out (column,
   row, wrap); it no longer draws. */
body.v2-client-shell .v2-composite__pane { border: 0; background: transparent; overflow: visible; min-width: 0; }
body.v2-client-shell .v2-composite__pane > .v2-composite__paneBody { padding: 0; overflow: visible; }
body.v2-client-shell .v2-composite__paneHeader { border: 0; padding: 0 0 6px; font-family: inherit; font-size: 15px; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--ink); }
body.v2-client-shell .v2-composite { gap: 22px; height: auto; overflow-x: visible; }
body.v2-client-shell .v2-composite--wrap > .v2-composite__pane { flex: 1 1 240px; }
@media (prefers-reduced-motion: no-preference) {
  body.v2-client-shell .v2-recordForm__more > .v2-recordForm__fields { animation: v2-more-in 140ms ease-out; }
  @keyframes v2-more-in { from { opacity: 0; transform: translateY(-2px); } to { opacity: 1; transform: none; } }
}
/* A picker's select must not set the page's width: the composite no longer clips, so a long
   option label would otherwise scroll the whole dashboard sideways on a phone. */
body.v2-client-shell .v2-recordTable__pick { flex-wrap: wrap; row-gap: 6px; }
body.v2-client-shell .v2-recordTable__pick select { max-width: min(100%, 60vw); min-width: 0; }
body.v2-client-shell .v2-recordTable__pick label { max-width: 100%; }
/* No tracked-out capitals on the client's dashboard: the reveal toggle and the revealed
   text's label read as words. */
body.v2-client-shell .v2-recordTable__toggle { font-family: inherit; font-size: 12px; letter-spacing: 0; text-transform: none; }
body.v2-client-shell .v2-recordTable__detail dt { font-family: inherit; font-size: 12px; letter-spacing: 0; text-transform: none; }

/* ---- settings_list (TASK-2026-10-16-002) ----------------------------------------------
   Rows of a settings document: label, what it stops, what it risks, and its control —
   one Save for the list. A reusable kind; PIM's Email › Spam is its first user. Text on the
   left, the control on the right; at phone width the control drops under its text so a
   long label never squeezes the switch off the screen. */
.v2-settingsList { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.v2-settingsList__header { font-size: 15px; font-weight: 600; color: var(--ink); }
.v2-settingsList__notice, .v2-settingsList__note, .v2-settingsList__empty {
  margin: 0; font-size: 13px; color: var(--ink2); max-width: 46rem;
}
.v2-settingsList__rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.v2-settingsList__row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 16px; align-items: start;
  padding: 12px 0; border-top: 1px solid var(--line);
}
.v2-settingsList__row:first-child { border-top: 0; padding-top: 4px; }
.v2-settingsList__text { min-width: 0; }
.v2-settingsList__label { display: block; font-size: 14px; font-weight: 600; color: var(--ink); cursor: pointer; }
.v2-settingsList__line { margin: 3px 0 0; font-size: 13px; line-height: 1.4; color: var(--ink2); overflow-wrap: anywhere; }
.v2-settingsList__term { font-weight: 600; color: var(--ink); }
/* What the setting DID ("Held this month: 3."). Quiet at zero; inked when it counted
   something, because that is the line a client looks for after a missing email. */
.v2-settingsList__tally { margin: 6px 0 0; font-size: 12px; color: var(--ink2); }
.v2-settingsList__tally.is-counted { color: var(--ink); font-weight: 600; }
.v2-settingsList__control { display: flex; align-items: center; justify-content: flex-end; padding-top: 2px; }
.v2-settingsList__control select {
  font: inherit; font-size: 14px; padding: 5px 8px; border: 1px solid var(--line);
  border-radius: 6px; background: var(--paper); color: var(--ink); max-width: 100%;
}
/* A real checkbox drawn as a switch: the keyboard, the <label> and a screen reader keep
   working because it is still the native control. */
.v2-settingsList__switch {
  -webkit-appearance: none; appearance: none; margin: 0; cursor: pointer; flex: none;
  width: 40px; height: 22px; border-radius: 11px; position: relative;
  background: var(--line); border: 1px solid var(--line); transition: background .15s;
}
.v2-settingsList__switch::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px;
  border-radius: 50%; background: var(--paper, #fff); transition: transform .15s;
}
.v2-settingsList__switch:checked { background: var(--accent, #1e6c93); border-color: var(--accent, #1e6c93); }
.v2-settingsList__switch:checked::after { transform: translateX(18px); background: var(--accent-fg, #fff); }
.v2-settingsList__switch:disabled, .v2-settingsList__control select:disabled { opacity: .55; cursor: not-allowed; }
.v2-settingsList__switch:focus-visible, .v2-settingsList__control select:focus-visible,
.v2-settingsList__save:focus-visible, .v2-recordTable__open:focus-visible {
  outline: 2px solid var(--accent, #1e6c93); outline-offset: 2px;
}
.v2-settingsList__bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding-top: 6px; }
/* The ONE action of the list is a `.v2-iconButton` (below); it turns primary while
   something is unsaved, because then saving is the consequential act. */
.v2-settingsList__status { font-size: 12px; color: var(--ink2); }
body.v2-client-shell .v2-settingsList.v2-surface--sheet {
  border: 1px solid var(--ink); border-radius: 8px; background: var(--paper); padding: 14px 16px 16px;
}
@media (max-width: 520px) {
  .v2-settingsList__row { grid-template-columns: minmax(0, 1fr); }
  .v2-settingsList__control { justify-content: flex-start; }
  .v2-settingsList__control select { width: 100%; }
}

/* ---- ONE ACTION STYLE (2026-10-16, TASK-2026-10-16-002) ---------------------------------
   Every act a client can take is ONE kind of button: an icon beside its verb, an optional
   consequence line under the verb, outlined on paper. Exactly one act in a pane — the
   consequential one, the act that reaches past the dashboard (requests a plan change,
   posts to the site, mails people) — is declared `primary` by its payload and is filled.
   Danger is outlined in the danger colour; quiet is outlined in ink.

   Before this, one job wore three looks: a full-width banner ("Request the upgrade"), a
   filled pill ("Save connection") and an icon button ("Add grouping"). The renderers put
   this class on record_form submits (client shell) and on settings_list's Save; nothing is
   patched per button. */
.v2-iconButton {
  display: inline-flex; align-items: center; gap: 8px; min-height: 36px; padding: 6px 14px;
  border: 1px solid var(--accent, #1e6c93); border-radius: 8px; cursor: pointer;
  background: var(--paper, #fff); color: var(--accent, #1e6c93);
  font: inherit; font-size: 14px; font-weight: 600; text-align: left; filter: none;
}
.v2-iconButton:hover { background: color-mix(in srgb, var(--accent, #1e6c93) 9%, var(--paper, #fff)); filter: none; }
.v2-iconButton:focus-visible { outline: 2px solid var(--accent, #1e6c93); outline-offset: 2px; }
.v2-iconButton:disabled { opacity: .6; cursor: progress; }
.v2-iconButton .mc-icon { width: 17px; height: 17px; flex: 0 0 auto; }
.v2-iconButton .v2-recordForm__verb, .v2-iconButton .v2-settingsList__verb {
  display: flex; flex-direction: column; align-items: flex-start; line-height: 1.2;
}
.v2-iconButton .v2-recordForm__note { font-size: 12px; font-weight: 400; opacity: 0.85; }
.v2-iconButton.v2-iconButton--primary,
.v2-settingsList.is-dirty .v2-iconButton {
  background: var(--accent, #1e6c93); border-color: var(--accent, #1e6c93); color: var(--accent-fg, #fff);
}
.v2-iconButton.v2-iconButton--primary:hover,
.v2-settingsList.is-dirty .v2-iconButton:hover { background: var(--accent, #1e6c93); filter: brightness(1.08); }
.v2-iconButton.v2-iconButton--danger { border-color: var(--danger, #a3352c); color: var(--danger, #a3352c); background: var(--paper, #fff); }
.v2-iconButton.v2-iconButton--danger:hover { background: var(--danger, #a3352c); color: #fff; }
.v2-iconButton.v2-iconButton--quiet { border-color: var(--ink, #333); color: var(--ink, #333); background: var(--paper, #fff); }
.v2-iconButton.v2-iconButton--quiet:hover { background: var(--paper2, #eee); }

/* A record_table row that OPENS (`row_open`): its first cell is the way in. Drawn as the
   cell's own text with the link colour, so the table still reads as a table. */
.v2-recordTable__open {
  font: inherit; color: var(--accent, #1e6c93); background: none; border: 0; padding: 0;
  cursor: pointer; text-align: left; text-decoration: underline; text-underline-offset: 2px;
  overflow-wrap: anywhere;
}
/* A record_table cell that is a LINK (`{text, href}`): a remedy the reader can take from
   the row, drawn in the same voice as an opening cell. */
.v2-recordTable__link {
  color: var(--accent, #1e6c93); text-decoration: underline; text-underline-offset: 2px;
  overflow-wrap: anywhere;
}

/* ===========================================================================
   THE CLIENT DASHBOARD ON A PHONE                               (2026-11-13)
   ===========================================================================
   The MiCyte app (MiCyte/Mobile) is this page in a native shell, and on the
   operator's iPhone it read as a desk made small: two menubar rows (a tool
   search a client has nothing to search with, and the theme picker under its
   caption), a tool window's own title, source link and Close above the one tool
   there is, and a bottom bar of unlabelled cells, blank on micyte.com, where the
   sprite's address was a 404 (`CLIENT_ICON_BASE`).

   A client's phone shell is one title row, the page, and a tab bar whose cells
   say what they open. A client has two to three cells, not the operator's five,
   so the labels fit. The desktop client shell is unchanged. */

/* Close and See source open the operator's Compendium, which no client door serves. */
body.v2-client-shell .v2-toolHost__back,
body.v2-client-shell .v2-toolHost__seeSource { display: none; }

@media (max-width: 700px) {
  body.v2-client-shell .ide-menubar {
    flex-wrap: nowrap;
    padding: calc(10px + env(safe-area-inset-top, 0px)) 16px 10px;
  }
  body.v2-client-shell .ide-menubar__pageTitle { font-size: 17px; }
  body.v2-client-shell .ide-menubar__right { flex: 0 0 auto; }
  body.v2-client-shell .ide-menubar__toolSearch { display: none; }
  body.v2-client-shell .ide-menubar__right .themebar__label { display: none; }
  body.v2-client-shell .ide-menubar__right .themebar__select {
    min-height: 32px;
    padding: 4px 8px;
    font-size: 13px;
  }

  /* The title row already names the page. */
  body.v2-client-shell .v2-toolHost__chrome { display: none; }

  /* Every cell the same width, however many the door gives: the nav holds one
     to two, the footer holds Profile. */
  body.v2-client-shell .ide-railBody { flex: 1 1 0; }
  body.v2-client-shell .ide-railBody:has(.ide-activitylink + .ide-activitylink) { flex: 2 1 0; }
  body.v2-client-shell .ide-railBody:has(.ide-activitylink + .ide-activitylink + .ide-activitylink) { flex: 3 1 0; }
  body.v2-client-shell .ide-activitynav,
  body.v2-client-shell .ide-activityfooter { padding: 6px 0 4px; }

  body.v2-client-shell .ide-activitylink {
    flex-direction: column;
    gap: 4px;
    min-height: 52px;
    padding: 2px 0;
    border: 0;
    border-radius: 0;
    color: #b9b4a8;
  }
  body.v2-client-shell .ide-activitylink:hover { background: transparent; }
  body.v2-client-shell .ide-activitylabel {
    display: block;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: 0.01em;
  }
  /* The active cell: a pill behind its icon and a brighter label, the way a
     phone's own tab bars mark where you are. */
  body.v2-client-shell .ide-activitylink .ide-activityicon {
    width: 56px;
    height: 30px;
    border-radius: 15px;
  }
  body.v2-client-shell .ide-activitylink.is-active {
    background: transparent;
    border-color: transparent;
    color: #fff;
  }
  body.v2-client-shell .ide-activitylink.is-active .ide-activityicon {
    background: rgba(30, 108, 147, 0.42);
  }
}
