/* badger-ui.css — the shared BadgerRig / Walk'n'Chalk shell token + component layer.
   Source: docs/prototype-brig-cool.html (the agreed "-cool" direction), with the
   deviations locked in docs/ui-shell-plan.md §2. Owned by js/shell.js.

   NAMING RULE (holds for the whole ui-shell transition):
     every custom property is  --bui-*    every class is  .bui-*
   index.html's own <style> already defines :root{--tx,--txd,--sans,--bdr,--s1,…} — the
   aliases library.js renders against — so an unprefixed token layer would silently
   restyle the live UI the moment this file is linked. Prefixing makes that impossible
   by construction, and makes the shell greppable while both layers coexist.
   Bare modifier tokens (.on, .ok, .pri, .k, .v …) appear ONLY compounded with, or
   descended from, a .bui-* class — never as a standalone selector.

   GLOBALS: none. The reset is scoped to .bui-root, and the UI-size multiplier only
   applies once shell.js stamps html[data-bui-scale]. This file is inert until the
   shell mounts. */

/* ══ tokens ═══════════════════════════════════════════════════════ */
:root{
  /* base — lifted a touch off the palette's #12161c so edges read softer */
  --bui-bg:#141a21; --bui-panel:#1b232c; --bui-panel2:#212b35; --bui-panel3:#283440;
  --bui-plot-bg:#10161d;
  --bui-line:#2a3643; --bui-line-soft:#222d38;
  --bui-tx:#e8eef4; --bui-txd:#9aa9b8; --bui-txm:#647485;

  /* cold spectrum, from the BadgerWorks palette */
  --bui-teal:#2fd6c3; --bui-teal-d:rgba(47,214,195,.12); --bui-teal-b:rgba(47,214,195,.4);
  --bui-cyan:#54b9ff; --bui-cyan-d:rgba(84,185,255,.12);
  --bui-blue:#7f9dff; --bui-blue-d:rgba(127,157,255,.12);
  --bui-violet:#b18cf2; --bui-violet-d:rgba(177,140,242,.12);
  --bui-green:#43d98b; --bui-green-d:rgba(67,217,139,.12);
  --bui-amb:#f0a72e; --bui-amb-d:rgba(240,167,46,.11);   /* the only warm note — warnings, measure, view-only */
  --bui-amb-b:rgba(240,167,46,.3);
  --bui-red:#ff7b72; --bui-red-d:rgba(255,123,114,.11);
  --bui-on-teal:#04211d;

  /* DM Sans / DM Mono — already loaded by index.html. NOT the palette's
     Segoe UI Variable / Cascadia Mono: those do not exist on a phone, and the
     palette look is carried by colour and layout, not the typeface. (plan §2) */
  --bui-sans:'DM Sans',system-ui,-apple-system,sans-serif;
  --bui-mono:'DM Mono','Consolas',ui-monospace,monospace;

  --bui-r:6px; --bui-r-sm:4px;
  --bui-tap:2.75rem;                      /* 44px at 100% — rem so it scales with UI size */
  --bui-safe-b:env(safe-area-inset-bottom,0px);
  --bui-safe-t:env(safe-area-inset-top,0px);
  --bui-ui:1;
  --bui-lift:inset 0 1px 0 rgba(255,255,255,.045);
}

/* UI size: a type-scale multiplier on the root, NEVER CSS zoom — zoom is what
   breaks canvas tap decoding at 80% / 160% (documented in W'n'C's CLAUDE.md).
   Opt-in attribute so this file changes nothing until the shell mounts. */
html[data-bui-scale]{ font-size:calc(16px * var(--bui-ui)); -webkit-text-size-adjust:100%; }

/* ══ shell root ═══════════════════════════════════════════════════ */
.bui-root{
  font-family:var(--bui-sans); background:var(--bui-bg); color:var(--bui-tx);
  display:flex; flex-direction:column; min-height:0;
  font-size:.875rem; line-height:1.45; font-variant-numeric:tabular-nums;
  overscroll-behavior:none;
}
.bui-root.bui-fill{ position:absolute; inset:0; }
.bui-root *{ margin:0; padding:0; box-sizing:border-box; -webkit-tap-highlight-color:transparent }
.bui-root button,.bui-root input{ font-family:inherit; color:inherit }
.bui-root button{ cursor:pointer; border-radius:var(--bui-r-sm) }
.bui-root svg{ display:block }
.bui-mono{ font-family:var(--bui-mono) }

/* ══ header ═══════════════════════════════════════════════════════ */
.bui-hdr{ flex:0 0 auto; display:flex; align-items:center; gap:.6rem;
  background:linear-gradient(180deg,var(--bui-panel2),var(--bui-panel)); box-shadow:var(--bui-lift);
  padding:.5rem .6rem; border-bottom:1px solid var(--bui-line);
  padding-top:calc(.5rem + var(--bui-safe-t)) }
.bui-badge{ width:1.95rem; height:1.95rem; flex:0 0 auto; border-radius:var(--bui-r-sm);
  background:var(--bui-teal-d); border:1px solid rgba(47,214,195,.45); color:var(--bui-teal);
  font:700 .625rem/1 var(--bui-mono); display:flex; align-items:center; justify-content:center }
.bui-title{ flex:1; min-width:0; background:none; border:none; text-align:left;
  padding:.1rem .2rem; border-radius:var(--bui-r-sm) }
.bui-title:active{ background:var(--bui-panel3) }
.bui-title .t1{ font-size:.875rem; font-weight:600; white-space:nowrap; overflow:hidden;
  text-overflow:ellipsis; display:flex; align-items:center; gap:.3rem }
.bui-title .t1 svg{ opacity:.45; flex:0 0 auto }
.bui-title .t2{ display:flex; align-items:center; gap:.4rem; margin-top:.05rem;
  font-size:.625rem; color:var(--bui-txm) }
.bui-tag{ font-size:.5625rem; font-weight:600; letter-spacing:.04em; padding:.08rem .35rem;
  border-radius:99px; white-space:nowrap; line-height:1.6 }
.bui-tag.ok{ background:var(--bui-green-d); color:var(--bui-green) }
.bui-tag.vwx{ background:var(--bui-violet-d); color:var(--bui-violet) }
.bui-tag.ro{ background:var(--bui-amb-d); color:var(--bui-amb) }
.bui-tag.info{ background:var(--bui-cyan-d); color:var(--bui-cyan) }
.bui-tag.off{ background:#64748515; color:var(--bui-txm) }
.bui-hbtn{ width:2.15rem; height:2.15rem; flex:0 0 auto; border-radius:var(--bui-r-sm);
  border:1px solid var(--bui-line); background:var(--bui-panel2); color:var(--bui-txd);
  display:flex; align-items:center; justify-content:center }
.bui-hbtn:active,.bui-hbtn.on{ border-color:var(--bui-teal); color:var(--bui-teal); background:var(--bui-teal-d) }

/* view-only strip — amber, the one warm note. Both escapes live here. */
.bui-ro{ flex:0 0 auto; display:none; align-items:center; gap:.5rem; flex-wrap:wrap;
  background:var(--bui-amb-d); border-bottom:1px solid rgba(240,167,46,.28);
  padding:.4rem .6rem; font-size:.6875rem }
.bui-ro.on{ display:flex }
.bui-ro .k{ color:var(--bui-amb); font-weight:700 }
.bui-ro .d{ color:var(--bui-txd); font-family:var(--bui-mono); font-size:.625rem }
.bui-ro .r{ margin-left:auto; display:flex; gap:.3rem }

/* ══ views ════════════════════════════════════════════════════════ */
.bui-body{ flex:1 1 auto; position:relative; min-height:0 }
.bui-view{ position:absolute; inset:0; display:none; flex-direction:column; min-height:0 }
.bui-view.on{ display:flex }
.bui-scroll{ flex:1 1 auto; overflow:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch }
.bui-scroll::-webkit-scrollbar{ width:.35rem; height:.35rem }
.bui-scroll::-webkit-scrollbar-thumb{ background:var(--bui-panel3); border-radius:99px }
.bui-scroll::-webkit-scrollbar-track{ background:transparent }
/* A view that owns its own sizing (a canvas container that measures itself) gets this
   instead of .bui-scroll — a scrolling parent would fight the measurement. */
.bui-plain{ flex:1 1 auto; min-height:0; position:relative; display:flex; flex-direction:column }
.bui-canvaswrap{ flex:1 1 auto; position:relative; min-height:0;
  background:var(--bui-plot-bg); touch-action:none }
.bui-canvaswrap>canvas{ display:block; width:100%; height:100% }

.bui-orient{ position:absolute; font-size:.5625rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--bui-txm); pointer-events:none }
.bui-orient.t{ top:.45rem; left:50%; transform:translateX(-50%) }
.bui-orient.b{ bottom:.45rem; left:50%; transform:translateX(-50%) }
.bui-orient.l{ left:.4rem; top:50%; transform:translate(-50%,-50%) rotate(-90deg) }
.bui-orient.r{ right:.4rem; top:50%; transform:translate(50%,-50%) rotate(90deg) }
.bui-flag{ position:absolute; top:.45rem; right:.5rem; font-size:.5625rem; color:var(--bui-amb);
  background:var(--bui-amb-d); border:1px solid var(--bui-amb-b); padding:.12rem .4rem;
  border-radius:99px; pointer-events:none; display:none }
.bui-flag.on{ display:block }

/* ══ status bar ═══════════════════════════════════════════════════ */
.bui-status{ flex:0 0 auto; display:flex; align-items:center; gap:.85rem; background:var(--bui-panel);
  border-top:1px solid var(--bui-line); padding:.32rem .6rem; font-size:.5625rem;
  overflow-x:auto; scrollbar-width:none; color:var(--bui-txm) }
.bui-status::-webkit-scrollbar{ display:none }
.bui-status span{ white-space:nowrap }
.bui-status b{ color:var(--bui-tx); font-family:var(--bui-mono); font-weight:500; font-size:.625rem }
.bui-status .t b{ color:var(--bui-teal) }

/* ══ tool rail — docked under the plot, never floating over it ════ */
.bui-rail{ flex:0 0 auto; display:flex; gap:.25rem; padding:.3rem .35rem;
  background:linear-gradient(180deg,var(--bui-panel),var(--bui-bg));
  border-top:1px solid var(--bui-line); overflow-x:auto; scrollbar-width:none }
.bui-rail::-webkit-scrollbar{ display:none }
.bui-rail button{ flex:1 0 auto; min-width:3rem; height:2.5rem; border-radius:var(--bui-r);
  border:1px solid transparent; background:transparent; color:var(--bui-txd);
  font-size:.5625rem; font-weight:600;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:.12rem }
.bui-rail button:active{ background:var(--bui-panel2) }
.bui-rail button.on{ background:var(--bui-teal-d); border-color:var(--bui-teal-b); color:var(--bui-teal) }
.bui-rail button[disabled]{ opacity:.35; cursor:default }

/* ══ inspector ════════════════════════════════════════════════════ */
/* max-height is a PERCENTAGE of the view, not of the viewport, and the panel
   scrolls past it. Without this a tall inspector starves the canvas: at
   740 × 360 (landscape phone) header + status + rail + nav already take 186 px,
   and a six-cell inspector took the remaining 172 — the plot collapsed to 3 px.
   Capping at 40 % of the view keeps the plot alive and the rail on screen, and
   is inert in portrait, where the natural height is well under the cap. */
.bui-insp{ flex:0 1 auto; display:none; max-height:40%; overflow:auto;
  overscroll-behavior:contain;
  background:linear-gradient(180deg,var(--bui-panel2),var(--bui-panel));
  border-top:1px solid var(--bui-line); box-shadow:var(--bui-lift); padding:.5rem .6rem .55rem }
.bui-insp.on{ display:block }
.bui-insp::-webkit-scrollbar{ width:.35rem }
.bui-insp::-webkit-scrollbar-thumb{ background:var(--bui-panel3); border-radius:99px }
.bui-insp::-webkit-scrollbar-track{ background:transparent }
/* The plot must never be squeezed out entirely by the chrome below it. */
.bui-canvaswrap{ min-height:4rem }
.bui-insp .ih{ display:flex; align-items:baseline; gap:.5rem; margin-bottom:.4rem }
.bui-insp .ih .n{ font:600 .9375rem var(--bui-mono); color:var(--bui-teal) }
.bui-insp .ih .t{ font-size:.6875rem; color:var(--bui-txd) }
.bui-insp .ih .x{ margin-left:auto; color:var(--bui-txm); padding:0 .2rem;
  background:none; border:none; font-size:.8125rem }
.bui-ig{ display:grid; grid-template-columns:repeat(auto-fit,minmax(4.8rem,1fr)); gap:.15rem }
.bui-ig div{ background:var(--bui-bg); border-radius:var(--bui-r-sm); padding:.28rem .4rem }
.bui-ig .k{ font-size:.5rem; color:var(--bui-txm); letter-spacing:.06em; text-transform:uppercase }
.bui-ig .v{ font:500 .8125rem var(--bui-mono); color:var(--bui-tx); margin-top:.05rem }
.bui-ig .v.neg{ color:var(--bui-red) }
.bui-ig .v.pos{ color:var(--bui-green) }
.bui-ig .v.acc{ color:var(--bui-teal) }
.bui-ig .v.cy{ color:var(--bui-cyan) }
.bui-ibtns{ display:flex; gap:.35rem; margin-top:.45rem; flex-wrap:wrap }

/* ══ tables — horizontal rules only, no card soup ═════════════════ */
table.bui-dt{ border-collapse:collapse; min-width:100%; white-space:nowrap }
table.bui-dt th{ position:sticky; top:0; z-index:2; background:var(--bui-panel2);
  font-size:.5625rem; font-weight:600; letter-spacing:.05em; color:var(--bui-txm);
  padding:.5rem .55rem; border-bottom:1px solid var(--bui-line); text-align:right }
table.bui-dt th.l{ text-align:left }
table.bui-dt th.on{ color:var(--bui-teal) }
table.bui-dt td{ padding:.48rem .55rem; border-bottom:1px solid var(--bui-line-soft);
  font:400 .75rem var(--bui-mono); text-align:right; color:var(--bui-txd) }
table.bui-dt td.l{ text-align:left }
table.bui-dt td.id{ color:var(--bui-tx); font-weight:600; font-family:var(--bui-sans); font-size:.8125rem }
table.bui-dt td.sym{ text-align:center; padding:.15rem .35rem; width:2rem }
table.bui-dt tr.org td{ background:var(--bui-teal-d) }
table.bui-dt tr.org td.yv{ color:var(--bui-teal); font-weight:600 }
table.bui-dt td.yv{ color:var(--bui-tx) }
table.bui-dt td.neg{ color:var(--bui-red) }
table.bui-dt td.pos{ color:var(--bui-green) }
table.bui-dt td.mut{ color:var(--bui-txm) }
.bui-cls{ display:inline-block; width:.45rem; height:.45rem; border-radius:99px;
  margin-right:.35rem; vertical-align:.02rem }
/* Two DIFFERENT row states, and they can both be on at once:
   .selrow = ticked for a bulk edit (many rows)   .sel = the one row highlighted in the plot. */
table.bui-dt tbody tr.selrow td{ background:var(--bui-teal-d) }
table.bui-dt tbody tr.sel td{ box-shadow:inset 0 0 0 1px var(--bui-teal-b) }
/* An editable table: the controls have to sit inside the cell without inflating the row. */
table.bui-dt td input[type=text],
table.bui-dt td input[type=number],
table.bui-dt td select{ width:100%; min-width:3.5rem; background:var(--bui-bg);
  border:1px solid var(--bui-line); border-radius:var(--bui-r-sm); padding:.15rem .3rem;
  font:400 .75rem var(--bui-mono); color:var(--bui-tx) }
table.bui-dt td select{ font-family:var(--bui-sans) }
table.bui-dt td input:focus,
table.bui-dt td select:focus{ outline:none; border-color:var(--bui-teal) }
table.bui-dt td input[type=number]{ text-align:right }
table.bui-dt td input[type=checkbox]{ accent-color:var(--bui-teal); width:1.1rem; height:1.1rem }
/* Row handle — the # you click to select. Its own hit area, mono, dim until selected. */
/* touch-action:none so a press-and-drag down the # column paints a selection instead of
   being claimed by the browser as a scroll. Deliberately ONLY this narrow column — the rest
   of the row stays a normal scroll surface, so the table can still be panned by touch. */
table.bui-dt td.rh{ cursor:pointer; color:var(--bui-txm); text-align:center; user-select:none;
  touch-action:none }
table.bui-dt tr.selrow td.rh{ color:var(--bui-teal); font-weight:600 }
table.bui-dt th.rh{ cursor:pointer; text-align:center }

/* ══ blocks ═══════════════════════════════════════════════════════ */
.bui-pad{ padding:.65rem }
.bui-sec{ display:flex; align-items:center; gap:.45rem; margin:1rem 0 .4rem;
  font-size:.6875rem; font-weight:600; color:var(--bui-txd) }
.bui-sec:first-child{ margin-top:0 }
.bui-sec::before{ content:''; width:.75rem; height:2px; border-radius:2px;
  background:var(--bui-teal); flex:0 0 auto }
.bui-sec em{ font-style:normal; color:var(--bui-txm); font-weight:400; font-size:.625rem;
  margin-left:auto; font-family:var(--bui-mono) }
.bui-card{ background:linear-gradient(180deg,var(--bui-panel2),var(--bui-panel));
  border:1px solid var(--bui-line); border-radius:var(--bui-r); box-shadow:var(--bui-lift);
  padding:.6rem .7rem; margin-bottom:.4rem }
.bui-list{ background:var(--bui-panel); border:1px solid var(--bui-line);
  border-radius:var(--bui-r); overflow:hidden }
.bui-item{ display:flex; align-items:center; gap:.55rem; padding:.5rem .6rem;
  border-bottom:1px solid var(--bui-line-soft); min-height:var(--bui-tap) }
.bui-list .bui-item:last-child{ border-bottom:none }
.bui-item .nm{ flex:1; min-width:0; font-size:.8125rem; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap }
.bui-item .nm i{ display:block; font-style:normal; font-size:.625rem;
  color:var(--bui-txm); margin-top:.05rem }
.bui-item .rt{ font:500 .6875rem var(--bui-mono); color:var(--bui-txd); white-space:nowrap }
.bui-item.on{ background:var(--bui-teal-d) }
.bui-item.on .nm{ color:var(--bui-teal) }
.bui-prop{ display:flex; align-items:baseline; gap:.6rem; padding:.42rem .6rem;
  border-bottom:1px solid var(--bui-line-soft) }
.bui-list .bui-prop:last-child{ border-bottom:none }
.bui-prop .k{ flex:0 0 7.5rem; font-size:.6875rem; color:var(--bui-txm) }
.bui-prop .v{ flex:1; text-align:right; font:500 .8125rem var(--bui-mono); color:var(--bui-tx) }
.bui-prop .v.acc{ color:var(--bui-teal) }
.bui-prop .v.cy{ color:var(--bui-cyan) }
.bui-prop .v.warn{ color:var(--bui-amb) }
.bui-prop .v.bad{ color:var(--bui-red) }
.bui-prop .v.gn{ color:var(--bui-green) }
.bui-prop .v input{ width:100%; text-align:right; background:transparent; border:none;
  font:500 .8125rem var(--bui-mono); color:var(--bui-tx) }
.bui-prop .v input:focus{ outline:none; color:var(--bui-teal) }
/* A settings row whose value IS a choice — the select has to read like the mono values
   above and below it, not like a browser default control. */
.bui-prop .v select{ width:100%; text-align:right; background:var(--bui-bg);
  border:1px solid var(--bui-line); border-radius:var(--bui-r-sm); padding:.2rem .35rem;
  font:500 .75rem var(--bui-sans); color:var(--bui-tx) }
.bui-prop .v select:focus{ outline:none; border-color:var(--bui-teal) }
.bui-sw{ width:1.25rem; height:1.25rem; flex:0 0 auto; border-radius:var(--bui-r-sm);
  border:1px solid var(--bui-line); background:var(--bui-panel2); color:var(--bui-txm);
  font-size:.625rem; display:flex; align-items:center; justify-content:center }
.bui-sw.on{ border-color:var(--bui-teal); color:var(--bui-on-teal); background:var(--bui-teal) }
/* The switch is 1.25rem so it reads as a checkbox, but 20px is well under --bui-tap and this
   is a control riggers hit repeatedly with gloves on. Expand the HIT area only — the pseudo
   element is invisible and does not affect layout, so the row still looks the same. */
.bui-item > .bui-sw{ position:relative }
.bui-item > .bui-sw::after{ content:''; position:absolute; inset:-0.75rem }
.bui-dot{ width:.5rem; height:.5rem; border-radius:99px; flex:0 0 auto }

.bui-btn{ height:2.15rem; padding:0 .8rem; border-radius:var(--bui-r-sm);
  border:1px solid var(--bui-line); background:var(--bui-panel2); color:var(--bui-tx);
  font-size:.75rem; font-weight:600; display:inline-flex; align-items:center; gap:.3rem;
  white-space:nowrap; box-shadow:var(--bui-lift) }
.bui-btn:active{ border-color:var(--bui-teal); color:var(--bui-teal) }
.bui-btn.pri{ background:var(--bui-teal); border-color:var(--bui-teal); color:var(--bui-on-teal) }
.bui-btn.pri:active{ color:var(--bui-on-teal) }
.bui-btn.gh{ background:transparent; color:var(--bui-txd); box-shadow:none }
.bui-btn.warn{ border-color:var(--bui-amb-b); color:var(--bui-amb); background:var(--bui-amb-d) }
/* A disabled button has to READ disabled — the column mapper greys Import until every
   required role is assigned, and without this the only cue is that tapping does nothing. */
.bui-btn:disabled{ opacity:.4; cursor:default; box-shadow:none }
.bui-btn:disabled:active{ border-color:var(--bui-line); color:var(--bui-tx) }
.bui-btn.pri:disabled:active{ color:var(--bui-on-teal) }
.bui-btn.sm{ height:1.8rem; padding:0 .55rem; font-size:.6875rem }
.bui-btn.wide{ flex:1; justify-content:center }
.bui-btn[disabled]{ opacity:.4; cursor:default }
.bui-btns{ display:flex; gap:.4rem; flex-wrap:wrap; margin-top:.5rem }
.bui-note{ font-size:.6875rem; color:var(--bui-txm); line-height:1.6; margin-top:.55rem }
.bui-msg{ font-size:.6875rem; padding:.4rem .55rem; border-radius:var(--bui-r-sm);
  margin-bottom:.3rem; line-height:1.5 }
.bui-msg.bad{ background:var(--bui-red-d); color:var(--bui-red) }
.bui-msg.mid{ background:var(--bui-amb-d); color:var(--bui-amb) }
.bui-msg.ok{ background:var(--bui-green-d); color:var(--bui-green) }
.bui-msg.info{ background:var(--bui-cyan-d); color:var(--bui-cyan) }

/* ══ apex stepper + elevation diagram (Bridles) ═══════════════════ */
.bui-stepwrap{ background:linear-gradient(180deg,var(--bui-panel2),var(--bui-panel));
  border:1px solid var(--bui-line); border-radius:var(--bui-r); box-shadow:var(--bui-lift);
  padding:.55rem .6rem; margin-bottom:.45rem }
.bui-ticks{ display:flex; gap:3px; margin-bottom:.5rem }
.bui-ticks span{ flex:1; height:.4rem; border-radius:99px; background:var(--bui-line) }
.bui-ticks span.fit{ background:var(--bui-green) }
.bui-ticks span.on{ background:var(--bui-teal); box-shadow:0 0 0 2px var(--bui-teal-d) }
.bui-step{ display:flex; align-items:stretch; gap:.4rem }
.bui-step button{ width:2.9rem; border-radius:var(--bui-r-sm); border:1px solid var(--bui-line);
  background:var(--bui-panel3); color:var(--bui-tx); font-size:1.15rem; line-height:1 }
.bui-step button:active{ background:var(--bui-teal); color:var(--bui-on-teal); border-color:var(--bui-teal) }
.bui-step .val{ flex:1; text-align:center; padding:.15rem 0 }
.bui-step .val b{ display:block; font:600 1.05rem var(--bui-mono); color:var(--bui-teal) }
.bui-step .val i{ display:block; font-style:normal; font-size:.5625rem;
  color:var(--bui-txm); margin-top:.1rem }
.bui-dia{ background:var(--bui-plot-bg); border:1px solid var(--bui-line);
  border-radius:var(--bui-r); overflow:hidden; margin-bottom:.45rem }
.bui-dia svg{ width:100%; height:auto; display:block }

/* ══ bottom nav ═══════════════════════════════════════════════════ */
.bui-nav{ flex:0 0 auto; display:flex; gap:.2rem; padding:.25rem .3rem;
  background:linear-gradient(180deg,var(--bui-panel),var(--bui-bg));
  border-top:1px solid var(--bui-line); padding-bottom:calc(.25rem + var(--bui-safe-b)) }
.bui-nav button{ flex:1; min-height:var(--bui-tap); border-radius:var(--bui-r);
  border:1px solid transparent; background:none; color:var(--bui-txm);
  font-size:.5625rem; font-weight:600;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:.15rem }
.bui-nav button.on{ color:var(--bui-teal); background:var(--bui-teal-d);
  border-color:rgba(47,214,195,.28) }

/* ══ sheets — Project / Transfer / Settings ═══════════════════════ */
.bui-sheet{ position:fixed; inset:0; z-index:60; background:var(--bui-bg);
  display:none; flex-direction:column;
  font-family:var(--bui-sans); color:var(--bui-tx); font-size:.875rem; line-height:1.45;
  font-variant-numeric:tabular-nums }
.bui-sheet *{ margin:0; padding:0; box-sizing:border-box; -webkit-tap-highlight-color:transparent }
.bui-sheet button,.bui-sheet input{ font-family:inherit; color:inherit }
.bui-sheet button{ cursor:pointer; border-radius:var(--bui-r-sm) }
.bui-sheet svg{ display:block }
.bui-sheet.on{ display:flex; animation:bui-up .16s ease }
@keyframes bui-up{ from{ opacity:0; transform:translateY(.8rem) } to{ opacity:1; transform:none } }
.bui-sh-hd{ flex:0 0 auto; display:flex; align-items:center; gap:.5rem;
  background:linear-gradient(180deg,var(--bui-panel2),var(--bui-panel)); box-shadow:var(--bui-lift);
  padding:.6rem; border-bottom:1px solid var(--bui-line);
  padding-top:calc(.6rem + var(--bui-safe-t)) }
.bui-sh-hd .t{ font-size:.9375rem; font-weight:600; color:var(--bui-teal) }
.bui-sh-hd .x{ margin-left:auto; width:2.1rem; height:2.1rem; border-radius:var(--bui-r-sm);
  border:1px solid var(--bui-line); background:var(--bui-panel2); color:var(--bui-txd);
  display:flex; align-items:center; justify-content:center }
.bui-sh-tabs{ flex:0 0 auto; display:flex; gap:.2rem; padding:.35rem .4rem;
  background:var(--bui-panel); border-bottom:1px solid var(--bui-line);
  overflow-x:auto; scrollbar-width:none }
.bui-sh-tabs::-webkit-scrollbar{ display:none }
.bui-sh-tabs button{ flex:0 0 auto; border-radius:99px; border:1px solid transparent;
  background:transparent; color:var(--bui-txd); font-size:.6875rem; font-weight:600;
  padding:.35rem .7rem; min-height:1.95rem }
.bui-sh-tabs button.on{ background:var(--bui-teal-d); border-color:rgba(47,214,195,.35);
  color:var(--bui-teal) }
.bui-sh-body{ flex:1 1 auto; overflow:auto; padding:.7rem .65rem calc(1.3rem + var(--bui-safe-b)) }
.bui-pane{ display:none }
.bui-pane.on{ display:block }

/* ══ modal ════════════════════════════════════════════════════════
      A centred panel over everything, for a task that must finish before the
      app continues — the CSV column mapper is the one that matters. Distinct
      from .bui-sheet: a sheet is a place you visit and leave, a modal is a
      question you answer.
      z-index 100 sits above the sheets (60) because the mapper can be raised
      FROM a sheet — Project ▸ Sources owns the drop zone — and below the toast
      (200), which still has to be readable over it.
      Carries its own reset and font like .bui-sheet, for the same reason: it
      lives outside .bui-root, so it inherits none of that scope. ═══════ */
.bui-modal{ position:fixed; inset:0; z-index:100; display:none;
  align-items:center; justify-content:center; padding:.7rem;
  background:rgba(6,10,14,.72);
  font-family:var(--bui-sans); color:var(--bui-tx); font-size:.875rem; line-height:1.45;
  font-variant-numeric:tabular-nums }
.bui-modal *{ margin:0; padding:0; box-sizing:border-box; -webkit-tap-highlight-color:transparent }
.bui-modal button,.bui-modal input,.bui-modal select{ font-family:inherit; color:inherit }
.bui-modal button{ cursor:pointer; border-radius:var(--bui-r-sm) }
/* `.show` as well as the shell's usual `.on`: import-csv.js toggles `.show`, and that
   file is a diff-and-copy twin of Walk'n'Chalk's. Accepting both keeps the JS identical
   in both apps and lets W'n'C adopt this component with a markup-only change. */
.bui-modal.on,.bui-modal.show{ display:flex; animation:bui-fade .14s ease }
@keyframes bui-fade{ from{ opacity:0 } to{ opacity:1 } }
/* Sized off the overlay (100%), NEVER vw/vh: UI size is CSS `zoom` on <body>, and
   viewport units do not account for it — 96vw resolved against the unzoomed width and
   was then multiplied by the zoom, so at 160% on a 360px phone the panel came out
   553px wide and ran off both edges. The overlay is position:fixed inset:0, so its
   own box is already the viewport in layout px, which is the frame that scales right. */
.bui-modal-panel{ display:flex; flex-direction:column; gap:.55rem;
  width:min(100%,60rem); max-height:min(100%,44rem);
  background:var(--bui-panel); border:1px solid var(--bui-line);
  border-radius:var(--bui-r); box-shadow:0 1.2rem 3rem rgba(0,0,0,.55);
  padding:.75rem .7rem; animation:bui-up .16s ease }
.bui-modal-hd{ display:flex; align-items:baseline; gap:.5rem; flex-wrap:wrap }
.bui-modal-hd .t{ font-size:.9375rem; font-weight:600; color:var(--bui-teal) }
.bui-modal-hd .s{ font-size:.6875rem; color:var(--bui-txm) }
/* The scroll lives here, not on the panel: a sticky table header inside needs a
   scroll ancestor that is not the flex column itself. */
.bui-modal-scroll{ flex:1 1 auto; min-height:0; overflow:auto;
  border:1px solid var(--bui-line); border-radius:var(--bui-r-sm) }
.bui-modal-actions{ display:flex; align-items:center; gap:.5rem; flex-wrap:wrap }
.bui-modal-actions .grow{ flex:1 1 auto; min-width:0 }

/* ══ inputs ═══════════════════════════════════════════════════════ */
.bui-drop{ border:1px dashed var(--bui-line); border-radius:var(--bui-r); padding:1.2rem .7rem;
  text-align:center; color:var(--bui-txm); font-size:.6875rem; line-height:1.65;
  background:var(--bui-panel) }
.bui-drop b{ display:block; color:var(--bui-txd); font-size:.8125rem; margin-bottom:.2rem }
.bui-drop.over{ border-color:var(--bui-teal); background:var(--bui-teal-d) }
.bui-field{ display:flex; gap:.4rem; margin-top:.45rem }
.bui-field input{ flex:1; min-width:0; height:2.15rem; background:var(--bui-bg);
  border:1px solid var(--bui-line); border-radius:var(--bui-r-sm); padding:0 .55rem;
  font:400 .8125rem var(--bui-mono); color:var(--bui-tx) }
.bui-field input:focus{ outline:none; border-color:var(--bui-teal) }
.bui-field select{ flex:1; min-width:0; height:2.15rem; background:var(--bui-bg);
  border:1px solid var(--bui-line); border-radius:var(--bui-r-sm); padding:0 .4rem;
  font:400 .75rem var(--bui-sans); color:var(--bui-tx) }
.bui-field select:focus{ outline:none; border-color:var(--bui-teal) }
.bui-code{ font:600 1.4rem var(--bui-mono); letter-spacing:.26em; color:var(--bui-teal);
  text-align:center; background:var(--bui-teal-d); border:1px solid rgba(47,214,195,.32);
  border-radius:var(--bui-r); padding:.75rem .2rem .75rem .5rem }
.bui-seg{ display:flex; gap:.25rem; background:var(--bui-panel); border:1px solid var(--bui-line);
  border-radius:var(--bui-r); padding:.22rem }
.bui-seg button{ flex:1; height:2rem; border-radius:var(--bui-r-sm); border:none;
  background:transparent; color:var(--bui-txd); font-size:.75rem; font-weight:600 }
.bui-seg button.on{ background:var(--bui-teal); color:var(--bui-on-teal) }
.bui-slider{ display:flex; align-items:center; gap:.7rem; padding:.3rem .6rem }
.bui-slider input{ flex:1; accent-color:var(--bui-teal); height:1.5rem }
.bui-slider b{ font:600 .875rem var(--bui-mono); color:var(--bui-teal);
  min-width:3rem; text-align:right }

/* ══ toast — fallback only. core.js's showToast owns the real one; the
      shell delegates to it whenever it exists (see js/shell.js). ════ */
.bui-toast{ position:fixed; left:.5rem; right:.5rem; bottom:calc(.5rem + var(--bui-safe-b));
  background:var(--bui-panel3); border:1px solid var(--bui-line);
  border-left:3px solid var(--bui-teal); border-radius:var(--bui-r); color:var(--bui-tx);
  font-family:var(--bui-sans); font-size:.6875rem; padding:.5rem .65rem; z-index:200;
  opacity:0; transform:translateY(.5rem); transition:opacity .15s, transform .15s;
  pointer-events:none; box-shadow:0 .5rem 1.4rem rgba(0,0,0,.45); line-height:1.5 }
.bui-toast.on{ opacity:1; transform:none }
