/* The three Binnacle faces, served from here rather than fetched. A page that
   is meant to be static should not need a third party to render its own type,
   and an offline shop should not get fallback metrics. */
@font-face{
  font-family:'Inter'; font-style:normal; font-weight:400 700; font-display:swap;
  src:url('vendor/fonts/Inter-VariableFont_opsz,wght.ttf') format('truetype');
}
@font-face{
  font-family:'Space Grotesk'; font-style:normal; font-weight:400 700; font-display:swap;
  src:url('vendor/fonts/SpaceGrotesk-VariableFont_wght.ttf') format('truetype');
}
@font-face{
  font-family:'IBM Plex Mono'; font-style:normal; font-weight:400; font-display:swap;
  src:url('vendor/fonts/IBMPlexMono-Regular.ttf') format('truetype');
}
@font-face{
  font-family:'IBM Plex Mono'; font-style:normal; font-weight:500; font-display:swap;
  src:url('vendor/fonts/IBMPlexMono-Medium.ttf') format('truetype');
}

/* Joiner · browser front end — the Binnacle port that needs no porting.
   The desktop app translates these tokens into QSS by hand, which is where the
   one contrast defect in this project's history came from. Here they are the
   tokens themselves. */

:root{
  /* What is genuinely Joiner's, and no house token covers.

     Everything else — the surfaces, the accent contract, the text ramp, the
     type roles — comes from binnacle-tokens.css, which is generated from the
     standard's own file. This page used to carry its own copy of all of it,
     and the copy had drifted: --text read #E6EDF3 against the house #E7EEF4,
     and --muted #9FB0BE against #93A4B2. Nobody could have seen that by eye,
     which is the argument for not keeping a second copy. */
  --hair:rgba(143,160,174,.18);   /* a translucent rule; the house line is solid */
}


*{box-sizing:border-box}
/* An explicit display beats the hidden attribute, which is how the boot screen
   once stayed on top of a perfectly good window. */
[hidden]{display:none !important}
html,body{height:100%}
body{
  margin:0; background:var(--ink); color:var(--text);
  font-family:var(--font-ui); font-size:13.5px; line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
.mono{font-family:var(--font-mono)}

/* ---- boot ---------------------------------------------------------------- */
#boot{position:fixed; inset:0; display:grid; place-items:center; background:var(--ink); z-index:50}
.boot-inner{text-align:center; width:min(360px,80vw)}
.boot-mark{font-family:var(--font-disp); font-size:44px; font-weight:600; letter-spacing:-.02em}
.boot-mark span{color:var(--amber)}
.boot-note{font-family:var(--font-mono); font-size:11px; letter-spacing:.18em;
  text-transform:uppercase; color:var(--muted-2); margin:14px 0 18px}
.boot-bar{height:2px; background:var(--hair); border-radius:2px; overflow:hidden}
.boot-bar span{display:block; height:100%; width:0; background:var(--amber);
  transition:width var(--dur) var(--ease)}

/* ---- frame --------------------------------------------------------------- */
#app{height:100%; display:flex; flex-direction:column}

/* the menu bar: a classic bar, in the house language rather than in 1995 */
.menubar{
  display:flex; align-items:stretch; gap:2px; padding:0 12px; flex:0 0 auto;
  background:var(--ink); border-bottom:1px solid var(--hair);
}
/* The wordmark, set by the house rule rather than by eye: the name in caps at
   19px, the display face's heavy weight, tracked *in* by a hundredth rather
   than out, and the full stop in amber. */
.menubar .brand{
  display:flex; align-items:center; margin-right:14px;
  font-family:var(--font-disp); font-weight:700; font-size:19px;
  text-transform:uppercase; letter-spacing:-.01em;
}
/* the version, at the far end of the bar: there to answer one question —
   "am I running the thing we just changed?" — so it is quiet and stays out
   of the way of the menus it shares the bar with */
.menubar .version{
  margin-left:auto; display:flex; align-items:center;
  font-size:11.5px; color:var(--muted); user-select:text;
}
/* what a command will do beyond what its label says — a warning, not a
   refusal, so it sits quietly after the label rather than greying it */
.menu .row .note, .drop .row .note{
  margin-left:auto; padding-left:14px; font-size:11px; color:var(--muted);
  font-style:italic;
}
.menus{display:flex; align-items:stretch}
.menus > .top{
  position:relative; display:flex; align-items:center; padding:7px 11px;
  font-size:12.5px; color:var(--muted); cursor:default; border-radius:6px 6px 0 0;
  user-select:none;
}
.menus > .top:hover{color:var(--text); background:var(--panel)}
.menus > .top[data-open="1"]{color:var(--text); background:var(--panel)}
.menus > .top > .drop{
  position:absolute; top:100%; left:0; z-index:30; min-width:236px; padding:5px;
  background:var(--panel); border:1px solid var(--hair); border-radius:0 9px 9px 9px;
  box-shadow:0 14px 36px rgba(0,0,0,.55);
}
.brand{font-family:var(--font-disp); font-weight:600; font-size:15px; margin-right:8px}
.brand .dot{color:var(--amber)}
.bar-gap{flex:1}

/* ---- the bottom rail ------------------------------------------------------ */
.rail{
  display:flex; align-items:center; gap:14px; padding:4px 14px; flex:0 0 auto;
  background:var(--panel); border-top:1px solid var(--hair);
  font-size:11.5px; color:var(--muted-2);
}
.rail-cell{white-space:nowrap}
/* What the pointer is over. It takes what room is going and gives it back the
   moment the pointer leaves, so the rail does not jump about as a hand crosses
   a menu. Quiet, because it is there to be ignored as often as it is read. */
.rail-about{
  min-width:0; overflow:hidden; text-overflow:ellipsis; color:var(--muted);
  border-left:1px solid var(--hair); padding-left:14px;
}
.rail-about:empty{border-left:0; padding-left:0}
#rail-selection{overflow:hidden; text-overflow:ellipsis}

/* ---- panes --------------------------------------------------------------- */
/* Three columns of panes with a draggable gutter between each, and each column
   splitting its own two panes: the structure tree and the preview want the
   room at different moments, and one shared row made every drag move both.
   Every size is a variable, so a drag moves the layout without rewriting it. */
.grid{
  --col-left:250px; --col-right:290px; --row-left:1.35fr; --row-mid:1.35fr; --gut:5px;
  flex:1; min-height:0; display:grid; gap:0; padding:1px;
  grid-template-columns:var(--col-left) var(--gut) minmax(0,1fr) var(--gut) var(--col-right);
  grid-template-rows:minmax(0,1fr);
  background:var(--hair);
}
.stack{
  min-height:0; min-width:0; display:grid;
  grid-template-rows:minmax(0,var(--row-left)) var(--gut) minmax(0,1fr);
}
.stack-mid{grid-template-rows:minmax(0,var(--row-mid)) var(--gut) minmax(0,1fr)}
.pane{background:var(--panel); min-height:0; display:flex; flex-direction:column; overflow:hidden}
.pane-view{background:var(--well)}

/* A gutter is mostly empty space around a hairline: the line is the join the
   panes already showed, and the space is what makes it possible to grab. */
.gutter{background:var(--panel); position:relative; z-index:2}
.gutter::after{content:''; position:absolute; background:var(--hair)}
.gutter:hover::after,.gutter[data-dragging="1"]::after{background:var(--amber)}
.gutter-v{cursor:col-resize}
.gutter-v::after{top:0; bottom:0; left:50%; width:1px; margin-left:-.5px}
.gutter-h{cursor:row-resize}
.gutter-h::after{left:0; right:0; top:50%; height:1px; margin-top:-.5px}

.pane-head{
  font-family:var(--font-mono); font-size:10px; letter-spacing:.2em; text-transform:uppercase;
  color:var(--muted-2); padding:9px 12px 7px; border-bottom:1px solid var(--hair);
  flex:0 0 auto;
}
.pane-head .idx{color:var(--amber); margin-right:7px}
/* The panel's head (UI spec §21). At the top, where a heading belongs: ours
   was at the foot under a caption, saying "—" when nothing was selected, which
   is a heading in the place a summary goes. The kind is a caption, the name is
   the biggest thing in the pane because it is the answer to "what am I looking
   at", and the note is the way back in words. */
.head{
  padding:12px 12px 10px; border-bottom:1px solid var(--hair);
}
.head[hidden]{display:none}
.head-kind{
  font-family:var(--font-mono); font-size:10px; letter-spacing:.2em;
  text-transform:uppercase; color:var(--amber);
}
.head-name{
  font-family:var(--font-disp); font-size:16px; font-weight:600;
  color:var(--text); margin-top:3px; line-height:1.25;
}
/* A name with somewhere to go is a control; one without is text. The chevron
   is the difference, and it is the same one the tree folds with. */
button.head-name{
  display:flex; align-items:center; gap:6px; width:100%;
  background:none; border:0; padding:0; cursor:pointer; text-align:left;
}
button.head-name:hover{color:var(--amber)}
/* A click leaves the focus ring behind, which reads as a text box around the
   name. Kept for the keyboard, where it is the only thing saying where you
   are, and dropped for the mouse, which does not need telling. */
button.head-name:focus:not(:focus-visible){outline:none}
button.head-name:focus-visible{outline:1px solid var(--amber); outline-offset:2px}
.head-mark{width:12px; height:12px; flex:none; color:var(--muted)}
button.head-name:hover .head-mark{color:var(--amber)}
.head-note{
  font-size:11.5px; color:var(--muted); margin-top:3px; line-height:1.4;
}

.pane-sub{
  font-family:var(--font-mono); font-size:10px; letter-spacing:.2em; text-transform:uppercase;
  color:var(--muted-2); padding:12px 12px 4px;
}

/* A position typed straight at the preview, where the drag was. */
input.typed{
  position:fixed; z-index:40; width:120px; font-family:var(--font-mono); font-size:12.5px;
  color:var(--text); background:var(--panel); border:1px solid var(--amber);
  border-radius:7px; padding:5px 8px; box-shadow:0 10px 26px rgba(0,0,0,.5);
}
input.typed:focus{outline:none}

/* ---- tree ---------------------------------------------------------------- */
.tree,.parts{list-style:none; margin:0; padding:5px 0; overflow:auto; flex:1; min-height:0}
.tree li,.parts li{
  padding:4px 12px; cursor:default; display:flex; gap:8px; align-items:baseline;
  border-left:2px solid transparent; white-space:nowrap;
}
.parts li{display:grid; grid-template-columns:minmax(0,1fr) auto; row-gap:0}
.parts li > span{overflow:hidden; text-overflow:ellipsis}
.tree li:hover,.parts li:hover{background:var(--panel-2)}
.tree li[data-selected="1"],.parts li[data-selected="1"]{
  background:var(--panel-2); border-left-color:var(--amber);
}
/* selected as well, but not the one in hand: about to be edited, not inspected */
.tree li[data-also="1"]{background:var(--panel-2); border-left-color:var(--cyan)}
.tree .det{margin-left:auto; font-family:var(--font-mono); font-size:11.5px; color:var(--muted-2)}
.parts .size{font-family:var(--font-mono); font-size:11.5px; color:var(--muted-2); text-align:right}
.parts .role{grid-column:1; font-size:10.5px}
.tree .kind-division{color:var(--muted)}
/* The disclosure arrow. Always the same width, present or not, so labels line
   up down the column rather than shifting as zones gain and lose children. */
.tree .twist{
  flex:0 0 11px; width:11px; font-family:var(--font-mono); font-size:9px;
  color:var(--muted-2); cursor:pointer; user-select:none; text-align:center;
}
.tree .twist:hover{color:var(--amber)}
/* Renaming happens on the row, so the row must not move while it does. */
.tree input.rename{
  font:inherit; font-size:12.5px; color:var(--text); background:var(--panel-2);
  border:1px solid var(--amber); border-radius:5px; padding:0 5px; margin:-1px 0;
  min-width:0; flex:1 1 auto;
}
.tree input.rename:focus{outline:none}
.tree li[data-collapsed="1"] > span:not(.twist){color:var(--muted)}
.tree .front{
  font-family:var(--font-mono); font-size:10px; letter-spacing:.12em; text-transform:uppercase;
  color:var(--cyan);
}
/* a row that names a front nothing will cut says so, in the colour that means
   stop — and in words too, never colour alone */
.tree li[data-hidden="1"] .name{color:var(--muted-2)}
.tree li[data-tone="bad"] .front{color:var(--danger)}
.tree li[data-tone="bad"]{border-left-color:var(--danger)}
.parts .role{font-family:var(--font-mono); color:var(--muted-2)}

/* ---- preview ------------------------------------------------------------- */
#scene{flex:1; min-height:0; width:100%; display:block}

/* ---- properties ---------------------------------------------------------- */
/* The properties column fills its height, and the history takes whatever is
   left rather than a fixed 180px strip with empty space under it. The panel
   above scrolls on its own when the selection is a long one, so the list of
   steps never gets pushed off the bottom. */
.pane-props{display:flex; flex-direction:column; min-height:0; overflow:hidden}
.props-top{flex:1 1 auto; min-height:0; overflow:auto}
.fields{padding:12px 12px 4px; display:grid; gap:9px}
/* One vertical split, in the same place every time (UI spec §21). Labels left
   of it, values right of it, and it does not move when the selection changes —
   that one line is doing most of the work of making the panel scannable. 82px
   rather than 74: a nested row spends part of the column on its indent, and at
   74 the deeper labels wrapped. */
.field{display:grid; grid-template-columns:82px 1fr; align-items:center; gap:10px}
.field label{color:var(--muted); font-size:12.5px}
.field input[type=text],.field select{
  font-family:var(--font-mono); font-size:12.5px; color:var(--text);
  background:var(--panel-2); border:1px solid var(--hair); border-radius:7px;
  padding:5px 9px; width:100%;
}
.field input[data-invalid="1"]{border-color:var(--danger)}
.field input:focus,.field select:focus{outline:none; border-color:var(--amber)}
.field.toggle-row{grid-template-columns:1fr}
/* A value that has parts. The row keeps its value — the word it used to
   flatten to — and the chevron opens it where it stands. A nest is a row with
   a value; a group is a band without one, which is the whole difference. */
.field.nest > .fold{
  display:flex; align-items:center; gap:6px; padding:0;
  background:none; border:0; cursor:pointer; color:var(--muted);
  font-family:var(--font-ui); font-size:12.5px; text-align:left;
}
.field.nest > .fold:hover{color:var(--text)}
.field.nest > .fold svg{width:11px; height:11px; flex:none}
.field.nest > .fold:focus:not(:focus-visible){outline:none}
/* A fact is a value with no control, drawn as what it is: text beside its
   label, in the figure face, with no box promising an edit nobody can make. */
.field .said{
  font-size:12.5px; color:var(--text); padding:5px 0; min-width:0;
  overflow-wrap:anywhere;
}
/* How far in a row sits. One step per level, off the label column, so the
   nesting reads without the value column moving — the split between label and
   value stays in the same place, which is most of what makes a panel
   scannable. */
.field.nested{grid-template-columns:calc(82px - var(--step)) 1fr}
.field.nested{--step:calc(var(--depth, 1) * 11px); padding-left:var(--step)}
.field.toggle-row label{display:flex; gap:7px; align-items:center; cursor:pointer}

/* ---- the timeline -------------------------------------------------------- */
/* Along the bottom of the *viewport*, not of the window: it describes the
   thing above it, and stretched across the whole program it read as a
   property of the program. The canvas is a flex child beside it, so the two
   share the pane and the drawing gives up exactly the strip's height. */
.timeline{
  display:flex; align-items:center; gap:12px; padding:3px 10px; flex:0 0 auto;
  background:var(--well); border-top:1px solid var(--hair);
}
.history{
  list-style:none; margin:0; padding:0; display:flex; align-items:center; gap:3px;
  overflow-x:auto; overflow-y:hidden; min-width:0; flex:1 1 auto;
}
.history .step{
  flex:0 0 auto; width:22px; height:22px; display:grid; place-items:center;
  font-family:var(--font-mono); font-size:13px; line-height:1; cursor:pointer;
  color:var(--muted-2); border:1px solid transparent; border-radius:6px;
  background:var(--panel-2); user-select:none;
}
.history .step:hover{color:var(--text); border-color:var(--muted-2)}
.history .step[data-current="1"]{color:var(--amber); border-color:var(--amber)}
.history .step[data-undone="1"]{opacity:.4}
.timeline-now{
  font-size:11.5px; color:var(--muted-2); white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis; max-width:38%;
}

.detail{padding:2px 12px 8px; font-size:12px; color:var(--muted); white-space:pre-wrap}
#inspector{padding:0 12px 10px}
.detail b{color:var(--text); font-weight:500}

.status{
  margin:4px 12px 14px; padding:8px 10px; border-radius:7px; font-size:12px;
  border-left:2px solid var(--neutral); background:var(--well); color:var(--muted);
  min-height:0;
}
.status[hidden]{display:none}
.status[data-tone="bad"]{border-left-color:var(--danger); color:var(--text)}
.status[data-tone="now"]{border-left-color:var(--amber)}
.status[data-tone="good"]{border-left-color:var(--cyan)}
.status .glyph{font-family:var(--font-mono); margin-right:7px; color:inherit}
.status .fix{display:block; color:var(--muted-2); margin-top:3px}

/* ---- cut list ------------------------------------------------------------ */
.table-wrap{overflow:auto; flex:1; min-height:0}
table{border-collapse:collapse; width:100%; font-size:12.5px}
th{
  position:sticky; top:0; background:var(--panel); text-align:left;
  font-family:var(--font-mono); font-size:10px; letter-spacing:.16em; text-transform:uppercase;
  color:var(--muted-2); font-weight:500; padding:8px 10px; border-bottom:1px solid var(--hair);
}
td{padding:5px 10px; border-bottom:1px solid var(--hair); color:var(--muted)}
td:first-child{font-family:var(--font-mono); color:var(--text)}
td:nth-child(n+4):nth-child(-n+6){font-family:var(--font-mono); color:var(--text)}
tbody tr:hover td{background:var(--panel-2)}

/* ---- menus: the same rows at the cursor and along the top ---------------- */
.menu{
  position:fixed; z-index:40; min-width:230px; padding:5px;
  background:var(--panel); border:1px solid var(--hair); border-radius:9px;
  box-shadow:0 12px 34px rgba(0,0,0,.5);
}
.menu .row,.drop .row{
  padding:6px 10px; border-radius:6px; cursor:default; display:flex;
  align-items:center; gap:9px; font-size:12.5px; white-space:nowrap;
}
.menu .row.item:hover,.drop .row.item:hover{background:var(--panel-2)}
.menu .row.heading,.drop .row.heading{
  font-family:var(--font-mono); font-size:10px; letter-spacing:.16em; text-transform:uppercase;
  color:var(--muted-2); cursor:default;
}
.menu .row.disabled,.drop .row.disabled{color:var(--muted-2); opacity:.6}
.menu .sep,.drop .sep{height:1px; background:var(--hair); margin:5px 8px}
.menu .tick,.drop .tick{font-family:var(--font-mono); width:1em; color:var(--cyan)}
.menu .arrow,.drop .arrow{margin-left:auto; color:var(--muted-2); padding-left:14px}
.menu .row,.drop .row{position:relative}
.menu .sub,.drop .sub{
  display:none; position:absolute; left:calc(100% - 6px); top:-5px; z-index:35;
  min-width:170px; padding:5px; background:var(--panel);
  border:1px solid var(--hair); border-radius:9px; box-shadow:0 14px 36px rgba(0,0,0,.55);
}
.menu .row:hover > .sub,.drop .row:hover > .sub{display:block}
/* a submenu that would run off the right edge opens to the left instead */
.menu .sub.flip,.drop .sub.flip{left:auto; right:calc(100% - 6px)}

/* ---- a notice: About, the licence — read once, then dismissed ------------- */
.notice{
  position:fixed; inset:0; z-index:60; display:flex; align-items:center;
  justify-content:center; background:rgba(5,8,11,.62); padding:24px;
}
.notice-card{
  max-width:min(560px,92vw); background:var(--panel); color:var(--text);
  border:1px solid var(--hair); border-radius:12px; padding:22px 24px;
  box-shadow:0 24px 60px rgba(0,0,0,.6);
}
.notice-card h2{
  font-family:var(--font-disp); font-size:20px; font-weight:600; margin:0 0 10px;
}
.notice-card p{margin:0 0 10px; color:var(--muted); font-size:13px}
.notice-card .notice-lead{color:var(--text); margin-bottom:14px}
.notice-facts{
  display:grid; grid-template-columns:auto 1fr; gap:5px 16px;
  margin:0 0 14px; font-size:12.5px; align-items:baseline;
}
.notice-facts dt{font-family:var(--font-mono); color:var(--muted-2); white-space:nowrap}
.notice-facts dd{margin:0; color:var(--text)}
.notice-card button{margin-top:8px}

/* The padlock on a field that can be held against a drag. Quiet until it is
   shut: a control that shouts while doing nothing teaches people to stop
   reading it. */
/* the row grows a third column only when there is a padlock to put in it */
.field:has(.lock){grid-template-columns:82px 1fr auto}
.field .lock{background:none; border:1px solid transparent; border-radius:6px;
  color:var(--muted); cursor:pointer; font-size:13px; line-height:1;
  padding:3px 5px}
.field .lock:hover{border-color:var(--line-2); color:var(--text)}
.field .lock[data-on="1"]{color:var(--amber); border-color:var(--line-2)}

/* ---- the house glyphs ------------------------------------------------------
   Sized in ems so a mark scales with the words beside it, and coloured by
   currentColor so a theme or a vision profile reaches it without a redraw. */
svg.gl{width:1em; height:1em; display:inline-block; vertical-align:-0.14em;
  fill:none; color:inherit}
svg.gl.twist-mark{width:.72em; height:.72em}
svg.gl.front-mark{width:.9em; height:.9em; cursor:pointer; color:var(--muted);
  margin-left:auto; flex:0 0 auto; padding:0 1px}
svg.gl.front-mark:hover{color:var(--amber)}
/* two shapes and two colours: the struck-through eye is the channel that does
   not depend on seeing colour, and the amber says *you did this* */
.tree li[data-hidden="1"] svg.gl.front-mark{color:var(--amber)}
.field .lock svg.gl{width:.95em; height:.95em}
svg.gl.step-mark{width:11px; height:11px}
svg.gl.tick-mark{width:.8em; height:.8em}

/* ---- scrollbars ------------------------------------------------------------
   The page was leaving these to the browser, which draws the platform's own —
   a white bar with arrows on it, down the side of a dark instrument panel. The
   same rule the desktop follows: a thin handle in the line colour, no arrows,
   no trough. `scrollbar-*` covers Firefox; the `::-webkit-` block covers the
   rest, and neither is a fallback for the other. */
*{scrollbar-width:thin; scrollbar-color:var(--line-2) transparent}
::-webkit-scrollbar{width:11px; height:11px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-corner{background:transparent}
::-webkit-scrollbar-thumb{
  background:var(--line-2); border-radius:5px; border:2px solid transparent;
  background-clip:padding-box;
}
::-webkit-scrollbar-thumb:hover{background:var(--muted-2); background-clip:padding-box}
::-webkit-scrollbar-button{display:none; width:0; height:0}

/* a locked field: still readable, plainly not typeable */
.field input[data-held="1"]{color:var(--muted); background:var(--well); border-color:var(--line)}

/* What presses a menu row, at the far end of it. Dim and monospaced, because
   it is a reminder rather than the name of the thing. */
.menu .row .chord,.drop .row .chord{
  margin-left:auto; padding-left:24px; color:var(--muted-2);
  font-family:var(--font-mono); font-size:11.5px;
}

/* A label you can drag to nudge the value beside it. */
.field label.scrub{cursor:ew-resize; user-select:none}
/* A group heading: the same fold the tree uses, at the width of the panel. */
.field.group{padding:10px 0 2px}
.field.group .fold{
  display:flex; align-items:center; gap:6px; width:100%; padding:2px 0;
  background:none; border:0; cursor:pointer; color:var(--muted);
  font-family:var(--font-ui); font-size:10.5px; letter-spacing:.09em;
}
.field.group .fold:hover{color:var(--text)}
.field.group .fold svg{width:12px; height:12px}

/* The palette. Over the window rather than in it: it is a way of reaching
   things, not a pane, and it goes away the moment it has been used. */
.palette{
  position:fixed; inset:0; z-index:60; background:rgba(0,0,0,.38);
  display:flex; justify-content:center; align-items:flex-start; padding-top:12vh;
}
.palette-card{
  width:min(560px, 92vw); background:var(--panel); border:1px solid var(--line);
  border-radius:10px; box-shadow:0 18px 50px rgba(0,0,0,.45); padding:10px;
}
.palette-card input{
  width:100%; padding:9px 10px; border-radius:7px; border:1px solid var(--line-2);
  background:var(--panel-2); color:var(--text); font-family:var(--font-ui);
  font-size:13.5px;
}
.found-list{max-height:46vh; overflow-y:auto; margin-top:8px}
.found{
  display:flex; align-items:center; gap:10px; padding:7px 9px; border-radius:6px;
  font-size:12.5px; cursor:default;
}
.found[data-on="1"]{background:var(--panel-2)}
.found-label{flex:0 1 auto}
.found-hint{color:var(--muted-2); font-size:11px; margin-left:auto}
.found .chord{margin-left:10px}
.found.disabled{color:var(--muted-2); opacity:.6}
.found.more{color:var(--muted-2); font-style:italic}

/* The settings window: the palette's card, taller, holding rows.

   It is a *document* more than a panel — a person reads it once, decides, and
   leaves — so it is set for reading rather than for density. The properties
   panel's 74px label column is right for `Width` beside a viewport and wrong
   for `Carcass thickness` in a card twice as wide: at 74px every name in the
   sheet wrapped onto two lines and the column of controls went ragged. */
.settings-card{width:min(680px, 94vw); padding:14px}
.settings-list{max-height:66vh; overflow-y:auto; margin:8px 0 12px; padding-right:4px}
.settings-list .field{grid-template-columns:150px 1fr; gap:12px; padding:3px 0}
.settings-list .field label{color:var(--text); font-size:13px; line-height:1.35}
.settings-list .field input[type=text],
.settings-list .field select{font-size:13px; padding:6px 10px}
.settings-note{
  margin:0 0 8px; color:var(--muted-2); font-size:12px; line-height:1.55;
}
/* A section heading, in the accent that means *this is the structure*, with a
   hairline above it so the eye finds the joins without reading the words. */
.settings-list .field.group{
  padding:16px 0 4px; margin-top:6px; border-top:1px solid var(--hair);
}
.settings-list .field.group:first-child{border-top:0; margin-top:0; padding-top:2px}
.settings-list .field.group .fold{
  color:var(--amber); font-size:11px; letter-spacing:.14em;
}
.settings-list .field.group .fold:hover{color:var(--text)}
/* `.palette-card input{width:100%}` was written for the one line the palette
   holds and then reached every control in this card: a checkbox stretched to
   the width of the list, pushing its own label off the edge. A tick is the
   size a tick is. */
.palette-card input[type=checkbox],
.field input[type=checkbox]{width:auto; flex:none; padding:0; margin:0}
.field input[type=checkbox]{accent-color:var(--amber)}

/* A line to narrow a list by, in the pane's own head. Quiet: it is a way of
   looking at the list rather than part of it. */
.pane-head .filter{
  margin-left:auto; width:110px; padding:2px 7px; border-radius:5px;
  border:1px solid var(--line); background:var(--panel-2); color:var(--text);
  font-family:var(--font-ui); font-size:11px; letter-spacing:0;
  text-transform:none;
}
.pane-head .filter:focus{outline:none; border-color:var(--line-2)}
.pane-head .hidden-count{
  margin-left:8px; color:var(--muted-2); font-size:10.5px; letter-spacing:.04em;
}

/* ── The command bar ────────────────────────────────────────────────────────
   Assembled in the view layer out of the menus' own marked rows, so nothing
   here decides what is on it. Every mark carries its word: a row of pictures
   nobody can name is a row nobody finds twice. */
/* The bar row: what kind of work this is, then what can be done within it.
   The mode does not scroll away with the marks, because it is the one thing on
   the row that is not a command. */
.bar-row{
  display:flex; align-items:stretch; min-width:0;
  background:var(--well); border-bottom:1px solid var(--hair);
}
.mode-now{
  display:flex; align-items:center; flex:none; padding:0 12px;
  border-right:1px solid var(--hair);
  font-family:var(--font-ui); font-size:10.5px; font-weight:600;
  letter-spacing:.16em; text-transform:uppercase; color:var(--amber);
  cursor:default;
}
.bar{
  display:flex; align-items:stretch; gap:1px; padding:2px 10px;
  min-width:0; flex:1 1 auto;
  overflow-x:auto; scrollbar-width:none;
}
.bar::-webkit-scrollbar{display:none}
.bar-sep{width:1px; margin:4px 7px; background:var(--hair); flex:none}
/* The mark sits BESIDE its word, not over it. Stacked, every button stood
   twice the height of the menu bar it hangs under — a lot of window spent on a
   strip that is only glanced at. The word stays; it just stops taking a line of
   its own. */
.bar-item{
  display:flex; align-items:center; gap:5px;
  padding:2px 7px 2px 5px; flex:none;
  background:transparent; border:1px solid transparent; border-radius:5px;
  color:var(--muted); font:inherit; font-size:11px; line-height:1.5;
  cursor:pointer;
}
.bar-item:hover:not(.disabled){color:var(--text); border-color:var(--line-2)}
.bar-item:focus-visible{outline:2px solid var(--amber); outline-offset:1px}
/* A refusal keeps its place and its reason, the way the menus do. */
.bar-item.disabled{color:var(--muted-2); opacity:.55; cursor:default}
/* The bar carries state as well as commands: a command that is currently ON
   is drawn pressed, because after ten minutes away the question is *where am
   I* rather than *what may I do*. */
.bar-item[data-on="1"]{
  color:var(--text); border-color:var(--amber); background:var(--panel-2);
}
.bar-mark{width:13px; height:13px; flex:none}
.bar-word{letter-spacing:.01em}
/* The same mark, on the menu row that names it. */
.row-mark{width:13px; height:13px; margin-right:6px; opacity:.8}
