/* ===========================================================================
   FINOpti V12 — design system
   ---------------------------------------------------------------------------
   Fluent-flavoured, border-driven, low-shadow, 4–6px radii, tabular numerals
   on every measurement. Ported from design_handoff_v12_web (v11.css tokens +
   v12.css chrome/density) against the specs in README §1.

   EVERYTHING IS SCOPED TO [data-ui="v12"].

   The live app and this system share 29 class names (.btn .tbl .tag .warn .on
   .sm .page .mono .num …) with different meanings, and 4 token names
   (--bg --err --ok --r-xs). Unscoped, this file would silently restyle every
   screen that has not been migrated yet. So V12 screens render inside a
   [data-ui="v12"] container and get this system; everything else is untouched.
   When the last screen has moved over, the scope can be dropped and this
   becomes the app's only stylesheet.

   data-theme (light|dark) and data-density (comfortable|compact) already live
   on <html> — set by store.jsx — so this file reads them from :root.
   =========================================================================== */

/* ---------------------------------------------------------------- tokens -- */
[data-ui="v12"] {
  --win: #f3f3f3;
  --srf: #ffffff;
  --srf-2: #fafafa;
  --srf-3: #f5f5f5;

  --bd: #e5e5e5;
  --bd-2: #d6d4d2;
  --bd-3: #b3b0ad;

  --ink: #1b1a19;
  --ink-2: #484644;
  --ink-3: #605e5c;
  --ink-4: #8a8886;

  --acc: #0f6cbd;
  --acc-2: #115ea3;
  --acc-3: #0c5391;
  --acc-soft: #eff6fc;
  --acc-line: #a9d3f2;

  --ok: #0f7b0f;
  --err: #c50f1f;
  --amb: #9d5d00;
  --vio: #5c2e91;

  /* The sheet stays light paper in BOTH themes; only the well around it goes
     dark. Ink painted ON the board follows --board-ink, never --ink, or the
     drawing inverts and becomes unreadable. (README §1, critical rule.) */
  --board: #ffffff;
  --paper: #ffffff;
  --board-ink: #3b3a39;
  --board-tx: #14171b;

  --sh-1: none;
  --sh: 0 1px 2px rgba(0, 0, 0, .06);
  --sh-2: 0 2px 6px rgba(0, 0, 0, .1);
  --sh-3: 0 8px 24px rgba(0, 0, 0, .18);
  --ring: 0 0 0 2px #fff, 0 0 0 3.5px var(--acc);

  --f: "Segoe UI Variable Text", "Segoe UI", system-ui, sans-serif;
  --d: "Segoe UI Variable Display", "Segoe UI", system-ui, sans-serif;
  --m: "Cascadia Mono", "Consolas", ui-monospace, monospace;

  --r: 6px;
  --r-s: 4px;
  --r-xs: 3px;

  color: var(--ink);
  font-family: var(--f);
  font-size: 14.5px;
  line-height: 1.5;
}

:root[data-theme="dark"] [data-ui="v12"],
[data-ui="v12"][data-theme="dark"] {
  --win: #202020;
  --srf: #2b2b2b;
  --srf-2: #272727;
  --srf-3: #323232;

  --bd: #3d3d3d;
  --bd-2: #4a4a4a;
  --bd-3: #6b6b6b;

  --ink: #ffffff;
  --ink-2: #e0e0e0;
  --ink-3: #c8c6c4;
  --ink-4: #9d9d9d;

  --acc: #4cc2ff;
  --acc-2: #66cbff;
  --acc-soft: #173a4d;
  --acc-line: #2f6f8f;

  /* paper stays readable: the WELL darkens, the board ink lightens */
  --board: #211f1e;
  --paper: #211f1e;
  --board-ink: #d6d4d2;
  /* Ink painted ON the board must flip with it. The handoff's dark block sets
     --board/--paper dark and lightens --board-ink, but leaves --board-tx at the
     near-black #14171b — and part id / size labels are drawn in --board-tx, so
     they came out black-on-near-black. Unreadable is worse than ugly on a
     shop-floor screen, so --board-tx flips too. */
  --board-tx: #e8e6e3;
  --ring: 0 0 0 2px #2b2b2b, 0 0 0 3.5px var(--acc);
}

/* Every measurement lines up. */
[data-ui="v12"] { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------ typography -- */
[data-ui="v12"] h2 {
  font-family: var(--d);
  font-weight: 600;
  font-size: 26px;
  line-height: 34px;
  letter-spacing: 0;
  margin: 0;
}
[data-ui="v12"] h3 {
  font-family: var(--d);
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0;
  margin: 0;
}
/* SENTENCE CASE, not small caps. v11.css:124 sets text-transform:none and
   letter-spacing:.02em — the label reads as quiet text beside the value, not
   as a heading shouting over it. This was the single biggest visual departure
   in the build: uppercasing .lab put every KPI label, breadcrumb, field label
   and section header in caps on every screen. */
[data-ui="v12"] .lab {
  font-family: var(--f);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: none;
  color: var(--ink-3);
}
[data-ui="v12"] .jsub { font-size: 12px; color: var(--ink-3); }
[data-ui="v12"] .mono,
[data-ui="v12"] .num { font-family: var(--m); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------ page -- */
/* v11.css:120. The v7 sheet says 30/34/52; README §1 says the V11 values win
   where the two disagree, and this one is very visible — v7 pads a document a
   third wider on every side. */
[data-ui="v12"] .page { padding: 20px 22px 32px; max-width: 1640px; }
[data-ui="v12"] .phead {
  display: flex;
  align-items: flex-end;
  gap: 16px;
  margin-bottom: 18px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--bd);
}
[data-ui="v12"] .phead p { font-size: 14px; color: var(--ink-3); margin: 6px 0 0; max-width: 62ch; }
[data-ui="v12"] .grow { flex: 1; min-width: 0; }

/* ----------------------------------------------------------------- plate -- */
[data-ui="v12"] .plate {
  background: var(--srf);
  border: 1px solid var(--bd);
  border-radius: var(--r);
  box-shadow: none;
}
[data-ui="v12"] .plate-hd {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 40px;
  padding: 8px 12px;
  background: var(--srf-2);
  border-bottom: 1px solid var(--bd);
}
[data-ui="v12"] .plate-hd.hatch {
  background: linear-gradient(var(--srf-2), var(--srf));
}
[data-ui="v12"] .plate-bd { padding: 12px; }

/* --------------------------------------------------------------- buttons -- */
[data-ui="v12"] .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 32px;
  padding: 0 12px;
  border: 1px solid var(--bd-2);
  border-radius: var(--r-s);
  background: var(--srf);
  color: var(--ink);
  font-family: var(--f);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  box-shadow: none;
  cursor: pointer;
}
[data-ui="v12"] .btn:hover { background: var(--srf-3); border-color: var(--bd-2); color: var(--ink); transform: none; box-shadow: none; }
[data-ui="v12"] .btn:active { background: var(--bd); }
[data-ui="v12"] .btn:focus-visible { outline: none; box-shadow: var(--ring); }
[data-ui="v12"] .btn[disabled] { cursor: default; }
[data-ui="v12"] .btn.pri { background: var(--acc); border-color: var(--acc); color: var(--ac-ink); box-shadow: none; }
[data-ui="v12"] .btn.pri:hover { background: var(--acc-2); border-color: var(--acc-2); }
[data-ui="v12"] .btn.pri:active { background: var(--acc-3); border-color: var(--acc-3); }
[data-ui="v12"] .btn.gho { background: transparent; border-color: transparent; color: var(--ink-2); }
[data-ui="v12"] .btn.gho:hover { background: var(--srf-3); }
[data-ui="v12"] .btn.on { background: var(--acc-soft); border-color: var(--acc-line); color: var(--acc-2); }
[data-ui="v12"] .btn.sm { min-height: 26px; font-size: 12.5px; padding: 0 9px; }
[data-ui="v12"] .btn.ico { width: 32px; padding: 0; }
[data-ui="v12"] .btn.ico.sm { width: 26px; }
/* the web build's command bar runs 36px */
[data-ui="v12"] .cmdbar .btn { min-height: 32px; }

/* ---------------------------------------------------------------- inputs -- */
[data-ui="v12"] .inp {
  min-height: 32px;
  padding: 0 10px;
  border: 1px solid var(--bd-2);
  border-bottom: 1px solid var(--ink-4);
  border-radius: var(--r-s);
  background: var(--srf);
  color: var(--ink);
  font-family: var(--f);
  font-weight: 400;
  box-shadow: none;
  font-size: 14px;
}
[data-ui="v12"] .inp:hover { border-color: var(--bd-3); }
[data-ui="v12"] .inp:focus {
  outline: none;
  border-color: var(--bd-2);
  border-bottom: 2px solid var(--acc);
}
[data-ui="v12"] .inp.mono { font-family: var(--m); }
[data-ui="v12"] .inp.mono[type="number"], [data-ui="v12"] .inp.mono.num { text-align: right; }
[data-ui="v12"] select.inp { padding-right: 6px; }

/* ---------------------------------------------------------------- tables -- */
[data-ui="v12"] .tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
/* Sentence case here too (v11.css:166). A cut list is read at speed and often
   at arm's length; uppercase column heads lose the word-shapes that make
   "Length"/"Width" distinguishable at a glance. */
[data-ui="v12"] .tbl th {
  height: 32px;
  padding: 0 10px;
  text-align: left;
  font-family: var(--f);
  font-size: 12px;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
  color: var(--ink-3);
  background: var(--srf-2);
  border-bottom: 1px solid var(--bd);
  white-space: nowrap;
}
[data-ui="v12"] .tbl td { padding: 5px 10px; border-bottom: 1px solid var(--bd); }
/* Alignment deliberately absent: the design's .tbl td.n sets family, tabular
   figures, colour and tracking only, and left-aligns like every other cell. */
[data-ui="v12"] .tbl td.n {
  font-family: var(--m);
  font-variant-numeric: tabular-nums;
}
[data-ui="v12"] .tbl td.id { font-weight: 600; }
[data-ui="v12"] .tbl tbody tr:hover { background: var(--acc-soft); }
[data-ui="v12"] .tbl tbody tr.sel { background: var(--acc-soft); }

/* ------------------------------------------------------------- KPI  deck -- */
[data-ui="v12"] .deck {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}
[data-ui="v12"] .cell {
  box-shadow: none;
  position: relative;
  background: var(--srf);
  border: 1px solid var(--bd);
  border-radius: var(--r);
  padding: 14px 16px 38px;
}
[data-ui="v12"] .cell .v {
  display: block;
  font-family: var(--d);
  letter-spacing: 0;
  font-size: 32px;
  font-weight: 600;
  line-height: 1.1;
  margin-top: 6px;
}
/* The KPI cell's unit and caption are .u and .sub (the design's own names),
   styled by the ported sheet — see v2_console.jsx V2Cell. */

/* ------------------------------------------------------------------ tags -- */
[data-ui="v12"] .tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 20px;
  padding: 0 7px;
  border: 1px solid var(--bd);
  border-radius: 4px;
  font-family: var(--f);
  letter-spacing: 0;
  text-transform: none;
  background: var(--srf-3);
  color: var(--ink-2);
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
}
[data-ui="v12"] .tag.ok { background: #f1faf1; border-color: #9fd89f; color: #0e700e; }
[data-ui="v12"] .tag.ac { background: var(--acc-soft); border-color: var(--acc-line); color: var(--acc-2); }
[data-ui="v12"] .tag.mute { background: var(--srf-2); border-color: var(--bd); color: var(--ink-4); }
[data-ui="v12"] .tag.err { background: #fdf3f4; border-color: #eeacb2; color: var(--err); }
:root[data-theme="dark"] [data-ui="v12"] .tag.ok { background: #0d2a0d; border-color: #2c6e2c; color: #6ccb6c; }
:root[data-theme="dark"] [data-ui="v12"] .tag.err { background: #3a1417; border-color: #7d2b33; color: #ff99a1; }

/* -------------------------------------------------------- property  grid -- */
[data-ui="v12"] .pgrid { font-size: 13px; }
[data-ui="v12"] .pgsec {
  padding: 6px 10px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--ink-3);
  background: var(--srf-2);
  border-top: 1px solid var(--bd);
  border-bottom: 1px solid var(--bd);
}
[data-ui="v12"] .pgrow {
  display: grid;
  grid-template-columns: 44% 56%;
  min-height: 28px;
  align-items: center;
  border-bottom: 1px solid var(--bd);
}
[data-ui="v12"] .pgrow > span {
  padding: 4px 10px;
  color: var(--ink-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
[data-ui="v12"] .pgrow > b {
  padding: 4px 10px;
  border-left: 1px solid var(--bd);
  font-family: var(--m);
  font-size: 12px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
[data-ui="v12"] .pgrow:hover { background: var(--srf-2); }

/* --------------------------------------------------------- inline notice -- */
/* The design's .warn is a flat full-bleed row divided by a hairline — the
   ported sheet supplies its layout, padding and colour. All that is added here
   is the accent bar's fill, which the design leaves to the caller. Boxing the
   notice (background + amber border + radius) made every routine message read
   as an alert. */
[data-ui="v12"] .warn .wb { align-self: stretch; background: var(--amb); }
[data-ui="v12"] .warn.err .wb { background: var(--err); }
[data-ui="v12"] .warn.ok .wb { background: var(--ok); }

/* ------------------------------------------------------ modal / popover -- */
[data-ui="v12"] .palwrap,
.palwrap[data-ui="v12"] {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .35);
  display: grid;
  place-items: start center;
  z-index: 200;
}
[data-ui="v12"] .palwrap > .plate,
.palwrap[data-ui="v12"] > .plate {
  max-height: 80vh;
  width: min(680px, calc(100vw - 32px));
  display: flex;
  flex-direction: column;
  box-shadow: var(--sh-3);
}
[data-ui="v12"] .palwrap .plate-bd,
.palwrap[data-ui="v12"] .plate-bd { overflow: auto; }
[data-ui="v12"] .palwrap .plate-ft,
.palwrap[data-ui="v12"] .plate-ft {
  display: flex;
  align-items: center;
  gap: 8px;
  justify-content: flex-end;
  padding: 10px 12px;
  border-top: 1px solid var(--bd);
  background: var(--srf-2);
}

[data-ui="v12"] .menupop {
  position: absolute;
  min-width: 236px;
  padding: 4px;
  background: var(--srf);
  border: 1px solid var(--bd-2);
  border-radius: var(--r);
  box-shadow: var(--sh-3);
  z-index: 210;
}
[data-ui="v12"] .mrow {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  height: 30px;
  padding: 0 10px 0 8px;
  border-radius: var(--r-s);
  font-size: 13px;
  color: var(--ink);
  text-align: left;
  background: none;
  border: 0;
  cursor: pointer;
}
[data-ui="v12"] .mrow:hover:not([disabled]) { background: var(--srf-3); }
[data-ui="v12"] .mrow[disabled] { color: var(--ink-4); cursor: default; }
[data-ui="v12"] .mrow .chk { width: 14px; flex: none; color: var(--acc); }
[data-ui="v12"] .mrow .k { margin-left: auto; font-family: var(--m); font-size: 11.5px; color: var(--ink-4); }
[data-ui="v12"] .msep { height: 1px; background: var(--bd); margin: 4px 6px; }
/* a row with a subtitle can't sit in the fixed 30px track or line two clips */
[data-ui="v12"] .wsmenu .mrow { height: auto; min-height: 30px; padding: 6px 10px 6px 8px; align-items: flex-start; }
[data-ui="v12"] .wsmenu .mrow .chk { margin-top: 1px; }
[data-ui="v12"] .wsmenu .mrow .jsub { margin-top: 1px; white-space: normal; }
[data-ui="v12"] .wsmenu .pgsec { background: transparent; border: none; padding: 7px 10px 3px; }

/* ----------------------------------------------------- status / stepper -- */
[data-ui="v12"] .led { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--ink-3); }
[data-ui="v12"] .sdot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); flex: none; }
[data-ui="v12"] .sdot.err { background: var(--err); }
[data-ui="v12"] .sdot.amb { background: var(--amb); }
[data-ui="v12"] .sdot.mute { background: var(--ink-4); }
[data-ui="v12"] .stepno {
  width: 20px;
  height: 20px;
  border-radius: 3px;
  font-family: var(--f);
  background: var(--acc);
  /* --ac-ink, not #fff: the dark theme's accent is LIGHT, so white on it is
     the 2:1 Send-to-saw bug again in miniature. */
  color: var(--ac-ink);
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 600;
  flex: none;
}

/* ----------------------------------------------------------------- toast -- */
[data-ui="v12"] .toast,
.toast[data-ui="v12"] {
  position: fixed;
  left: 50%;
  bottom: 40px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 16px;
  background: var(--srf);
  color: var(--ink);
  border: 1px solid var(--bd-2);
  border-radius: var(--r);
  box-shadow: var(--sh-3);
  font-size: 13.5px;
  z-index: 300;
}

/* -------------------------------------------------------------- timeline -- */
[data-ui="v12"] .fitem { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; }
[data-ui="v12"] .fbar { width: 3px; align-self: stretch; border-radius: 2px; background: var(--acc); flex: none; }
[data-ui="v12"] .fitem b { font-weight: 600; }
[data-ui="v12"] .ftime { font-family: var(--m); font-size: 11.5px; color: var(--ink-4); white-space: nowrap; }

/* --------------------------------------------------------------- density -- */
:root[data-density="compact"] [data-ui="v12"] .page { padding: 14px 16px 24px; }
:root[data-density="compact"] [data-ui="v12"] .phead { margin-bottom: 12px; padding-bottom: 10px; }
:root[data-density="compact"] [data-ui="v12"] h2 { font-size: 23px; line-height: 30px; }
:root[data-density="compact"] [data-ui="v12"] .plate-hd { min-height: 34px; padding: 5px 10px; }
:root[data-density="compact"] [data-ui="v12"] .tbl td { padding: 2px 8px; }
:root[data-density="compact"] [data-ui="v12"] .tbl th { height: 28px; padding: 0 8px; }
:root[data-density="compact"] [data-ui="v12"] .inp { min-height: 28px; font-size: 13px; }
:root[data-density="compact"] [data-ui="v12"] .btn { min-height: 28px; font-size: 12.5px; }
:root[data-density="compact"] [data-ui="v12"] .cell { padding: 10px 12px 30px; }
:root[data-density="compact"] [data-ui="v12"] .pgrow { min-height: 24px; }
:root[data-density="compact"] [data-ui="v12"] .deck { gap: 8px; }

/* ===========================================================================
   MOTION — ported verbatim from the handoff's own timings (design/v7/v7.css
   :107-109, :254-267, :308). The design specifies exactly five movements and
   nothing else; a system this dense reads as unstable if things slide about,
   so this is deliberately the whole set.

     fade    .14s   overlay scrims
     pop     .18s   cubic-bezier(.2,.9,.3,1)  dialogs and popovers entering
     fadein  .32s   cubic-bezier(.2,.9,.3,1)  a document arriving
     fadein  .22s   toasts
     slidein .28s   a line appearing in a running log
     sweep  1.15s   the optimize scanline, looping

   The status LED is explicitly NOT animated (v7.css:103 `animation:none
   !important`) — a blinking dot next to a saw is an alarm, and this one is
   not reporting an alarm.
   =========================================================================== */
@keyframes v12fade   { from { opacity: 0 } to { opacity: 1 } }
@keyframes v12pop    { from { opacity: 0; transform: translateY(-8px) scale(.985) } to { opacity: 1; transform: none } }
@keyframes v12fadein { from { opacity: 0; transform: translateY(8px) } to { opacity: 1; transform: none } }
@keyframes v12slide  { from { opacity: 0; transform: translateX(-6px) } to { opacity: 1; transform: none } }
@keyframes v12sweep  { 0% { top: 0 } 100% { top: 100% } }

[data-ui="v12"] .palwrap { animation: v12fade .14s; }
[data-ui="v12"] .palwrap > .plate { animation: v12pop .18s cubic-bezier(.2, .9, .3, 1); }
[data-ui="v12"] .menupop { animation: v12pop .18s cubic-bezier(.2, .9, .3, 1); }
/* BACKWARDS, NOT BOTH — this one matters far beyond the animation.
   v12fadein animates `transform`, and `both` keeps the animation in effect
   forever after it ends. A finished, filling transform animation still counts
   as a transform (Chrome reports the end state as matrix(1,0,0,1,0,0), not
   `none`), and an element with a transform is the CONTAINING BLOCK for every
   position:fixed descendant inside it. So every V12 page permanently
   re-anchored its fixed children to itself instead of the viewport: the edge
   modal's scrim came out at top 140px and 1764px tall — the page's scroll
   height — putting the dialog about 1000px below the fold, and EdgeMini's
   hover panel, which positions itself from getBoundingClientRect (viewport
   coordinates), landed in the wrong corner.
   `backwards` keeps the part that is actually wanted — the from-state applied
   before the animation starts, so there is no flash of the un-faded page — and
   drops the forwards fill, which bought nothing: the end keyframe is the
   element's natural state anyway (opacity 1, no transform). */
[data-ui="v12"] .page { animation: v12fadein .32s cubic-bezier(.2, .9, .3, 1) backwards; }
[data-ui="v12"] .toast { animation: v12fadein .22s; }
[data-ui="v12"] .v12log span { display: block; animation: v12slide .28s; }

/* the optimize overlay: a scanline crossing the plate while the engine runs */
[data-ui="v12"] .v12opt {
  position: absolute; inset: 0; z-index: 20; display: grid; place-items: center;
  background: color-mix(in srgb, var(--win) 72%, transparent);
  backdrop-filter: blur(8px); animation: v12fade .18s; overflow: hidden;
}
[data-ui="v12"] .v12opt .sweep {
  position: absolute; left: 0; right: 0; height: 1.5px;
  background: linear-gradient(90deg, transparent, var(--acc), transparent);
  animation: v12sweep 1.15s cubic-bezier(.4, 0, .2, 1) infinite;
}

/* Interactive feedback. The design gives .wbtn `transition:.1s` and nothing
   else; the same 100ms is applied to every control that changes on hover so
   the chrome feels consistent rather than half-animated. Colour and shadow
   only — never size or position, which would shift the layout under a cursor
   or a fingertip on the floor tablet. */
[data-ui="v12"] .btn,
[data-ui="v12"] .hbtn,
[data-ui="v12"] .cmd,
[data-ui="v12"] .dtab,
[data-ui="v12"] .tnode,
[data-ui="v12"] .mrow,
[data-ui="v12"] .v2setnav,
[data-ui="v12"] .v2ordrow,
[data-ui="v12"] .v2prow,
[data-ui="v12"] .v2pick,
[data-ui="v12"] .inp {
  transition: background-color .1s, border-color .1s, color .1s, box-shadow .1s;
}

/* Respect the system setting. A shop-floor tablet is often set to reduced
   motion, and the sweep in particular is a large moving element. */
@media (prefers-reduced-motion: reduce) {
  [data-ui="v12"] .palwrap,
  [data-ui="v12"] .palwrap > .plate,
  [data-ui="v12"] .menupop,
  [data-ui="v12"] .page,
  [data-ui="v12"] .toast,
  [data-ui="v12"] .v12log span,
  [data-ui="v12"] .v12opt,
  [data-ui="v12"] .v12opt .sweep { animation: none !important; }
  [data-ui="v12"] * { transition: none !important; }
}

/* ===========================================================================
   CLASSIC-PAGE SKIN
   ---------------------------------------------------------------------------
   /v2 renders several screens that have not been rebuilt yet — the job editor,
   quick job, materials, batch, production, the tablet, admin and the portal.
   They carry the classic class vocabulary, so inside the V12 shell they kept
   the old look: different radii, different type, different surfaces, sitting
   next to rebuilt screens that do not.

   The shared names (.btn .tbl .tag .inp .plate .page …) already resolve to V12
   because every V12 rule is scoped to [data-ui="v12"] and therefore outranks
   the unscoped classic rule. What was left was the classic-ONLY vocabulary.
   This maps each of those onto the V12 token set.

   It changes no markup and no behaviour — it is a stylesheet, scoped to the
   V12 shell. The classic app at / never sees any of it, so this cannot alter
   the cockpit rendering that GOLDEN RULE 5 protects.

   Screens rebuilt natively do not need this; it is scaffolding that shrinks
   as each one comes across.
   =========================================================================== */

/* page head ------------------------------------------------------------- */
[data-ui="v12"] .page-head {
  display: flex; align-items: flex-start; gap: 14px; margin-bottom: 18px;
}
[data-ui="v12"] .page-title {
  font-family: var(--f); font-size: 26px; font-weight: 600; letter-spacing: -.02em;
  margin: 0 0 4px; color: var(--ink);
}
[data-ui="v12"] .page-sub { font-size: 13.5px; color: var(--ink-3); margin: 0; max-width: 70ch; }
[data-ui="v12"] .page-head .spacer,
[data-ui="v12"] .card-head .spacer { flex: 1 1 auto; }
[data-ui="v12"] .section-label {
  font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-3);
}

/* cards become plates ---------------------------------------------------- */
[data-ui="v12"] .card {
  background: var(--srf); border: 1px solid var(--bd); border-radius: var(--r-s);
  box-shadow: none;
}
[data-ui="v12"] .card-head {
  display: flex; align-items: center; gap: 9px;
  min-height: 40px; padding: 0 13px;
  border-bottom: 1px solid var(--bd); background: var(--srf-2);
}
[data-ui="v12"] .card-head h3 {
  margin: 0; font-size: 13.5px; font-weight: 600; letter-spacing: -.01em; color: var(--ink);
}
[data-ui="v12"] .card-pad { padding: 13px; }

/* form controls ---------------------------------------------------------- */
[data-ui="v12"] .input,
[data-ui="v12"] .select,
[data-ui="v12"] .textarea,
[data-ui="v12"] .input-cell {
  font-family: var(--f); font-size: 13.5px; color: var(--ink);
  background: var(--srf); border: 1px solid var(--bd-2); border-radius: var(--r-xs);
  padding: 5px 8px; min-height: 30px; box-shadow: none;
}
[data-ui="v12"] .input:focus,
[data-ui="v12"] .select:focus,
[data-ui="v12"] .textarea:focus,
[data-ui="v12"] .input-cell:focus {
  outline: none; border-color: var(--acc); box-shadow: 0 0 0 1px var(--acc);
}
[data-ui="v12"] .input.sm, [data-ui="v12"] .select.sm { min-height: 26px; padding: 3px 6px; font-size: 12.5px; }

/* A cell input is the design's .cellinp (v7.css + v11.css): FULL WIDTH of its
   table cell, chrome-free until touched, mono, and on focus the flat surface
   with an inset hairline and the accent underline. The skinned version used to
   keep its intrinsic width, so a 2245mm length sat in a stub of an input with
   dead cell space either side of it — the "fields aren't full width" of it. */
[data-ui="v12"] .input-cell {
  width: 100%; min-width: 0; display: block;
  border: none; border-radius: 3px;
  background: transparent;
  padding: 7px 9px; min-height: 34px;
  font-family: var(--m); font-size: 12.5px; letter-spacing: -.02em;
}
[data-ui="v12"] .input-cell:hover { background: var(--srf-3); }
[data-ui="v12"] .input-cell:focus {
  background: var(--srf);
  box-shadow: inset 0 0 0 1px var(--bd-2);
  border-bottom: 2px solid var(--acc);
}
/* the parts-table cell padding lives in v2_overrides.css — it must beat the
   ported design's generic .tbl td padding, which loads after this file */

/* segmented + chips ------------------------------------------------------ */
[data-ui="v12"] .seg, [data-ui="v12"] .grain-seg {
  display: inline-flex; border: 1px solid var(--bd-2); border-radius: var(--r-s); overflow: hidden;
}
[data-ui="v12"] .seg > button, [data-ui="v12"] .grain-seg > button {
  border: 0; border-radius: 0; background: transparent; color: var(--ink-2);
  font-family: var(--f); font-size: 12.5px; padding: 5px 10px; cursor: pointer;
}
[data-ui="v12"] .seg > button + button, [data-ui="v12"] .grain-seg > button + button {
  border-left: 1px solid var(--bd-2);
}
[data-ui="v12"] .seg > button.on, [data-ui="v12"] .grain-seg > button.on {
  background: var(--acc-soft); color: var(--acc-2);
  box-shadow: inset 0 0 0 1px var(--acc-line);
}
/* WHY NOT A SOLID FILL. A block of flat accent inside a bordered, rounded
   segmented control has square corners where the control's are round, so two
   of them side by side read as a rendering fault rather than a selection. The
   soft wash + accent hairline says "this one" without fighting the container's
   shape — the same treatment .v2seg carries, so the two segmented controls in
   the app finally agree.

   THE GRAIN CONTROL ALSO NEEDED ITS BOX BACK. The rule above sets
   `padding: 5px 10px` and a font size, which are right for a TEXT segment and
   wrong for this one: GrainToggle's buttons are a fixed 26x24 holding a 16px
   glyph, so 10px of side padding left a 6px content box and the icon only
   looked centred because `place-items: center` re-centred it in the padding
   box. Hover and focus rings were computed off that squeezed box. State the
   icon-button geometry instead of inheriting text geometry. */
[data-ui="v12"] .grain-seg > button {
  width: 26px; height: 24px; padding: 0;
  display: grid; place-items: center;
}
[data-ui="v12"] .grain-seg > button:hover:not(.on) { background: var(--srf-3); color: var(--ink); }

/* The sequence tick. Under V12 this control was invisible in BOTH states and
   nearly identical between them, for two separate reasons:

     the ported reset's `button { border: none }` is (0,1,1) and beats
     `.seq-check { border: 1px solid ... }` at (0,1,0), so the box had no
     border at all — and `.seq-check.on { border-color: var(--accent) }` then
     had no border to colour;

     and `.seq-check { color: transparent }`, which is what HIDES the tick when
     the box is unticked, was overridden too — so an unticked box drew a full
     dark checkmark. Ticked drew the same checkmark in blue on a very pale
     blue. In a table of nineteen rows those two read as the same thing.

   So: an empty bordered box when off with NO tick in it, and a filled accent
   box with a white tick when on. That is the checkbox idiom, and it is
   deliberately not the soft wash used for the segmented controls above — a
   wash is how you show which of several joined buttons is active; a lone
   checkbox in a dense grid has to be legible at a glance from across the
   row. */
[data-ui="v12"] .seq-check {
  width: 22px; height: 22px; padding: 0; border-radius: var(--r-xs);
  border: 1px solid var(--bd-3); background: var(--srf);
  display: grid; place-items: center; cursor: pointer;
  color: transparent;                       /* the tick, hidden until ticked */
  transition: background .12s, border-color .12s, color .12s;
}
[data-ui="v12"] .seq-check:hover { border-color: var(--acc); background: var(--acc-soft); }
[data-ui="v12"] .seq-check.on {
  border-color: var(--acc); background: var(--acc); color: var(--ac-ink);
}
[data-ui="v12"] .seq-check:focus-visible { outline: 2px solid var(--acc); outline-offset: 1px; }
[data-ui="v12"] .chip {
  display: inline-flex; align-items: center; gap: 5px;
  height: 20px; padding: 0 7px; border-radius: var(--r-xs);
  border: 1px solid var(--bd-2); background: var(--srf-2);
  font-size: 11.5px; font-weight: 500; color: var(--ink-2);
}

/* text + numbers --------------------------------------------------------- */
[data-ui="v12"] .muted { color: var(--ink-3); }
[data-ui="v12"] .num, [data-ui="v12"] .tnum, [data-ui="v12"] td.num, [data-ui="v12"] th.num {
  font-family: var(--m); font-variant-numeric: tabular-nums; text-align: right;
}
[data-ui="v12"] .err { color: var(--err); }

/* tables ----------------------------------------------------------------- */
[data-ui="v12"] .table-wrap { overflow: auto; border-radius: var(--r-s); }

/* notices ---------------------------------------------------------------- */
[data-ui="v12"] .banner {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 12px; border: 1px solid var(--bd); border-left: 3px solid var(--acc);
  border-radius: var(--r-xs); background: var(--srf-2);
  font-size: 13px; color: var(--ink-2);
}
[data-ui="v12"] .banner.err { border-left-color: var(--err); }
[data-ui="v12"] .banner.ok  { border-left-color: var(--ok); }

/* empty states ----------------------------------------------------------- */
[data-ui="v12"] .empty { text-align: center; color: var(--ink-3); font-size: 13.5px; padding: 30px 20px; }
[data-ui="v12"] .empty h3 { font-size: 15px; font-weight: 600; color: var(--ink); margin: 0 0 6px; }
[data-ui="v12"] .empty-ico {
  width: 42px; height: 42px; border-radius: var(--r-s); margin: 0 auto 12px;
  background: var(--srf-3, var(--srf-2)); color: var(--ink-3);
  display: grid; place-items: center;
}

/* job-editor step cards -------------------------------------------------- */
/* The classic AI-scan HERO — 46px accent tile, accent text, lift-on-hover —
   shouts over the design's quiet plates. Same control, presented as one more
   plate row: the feature keeps its place in the flow without dressing itself
   as the most important thing on a screen whose job is the parts table. */
[data-ui="v12"] .je-ai {
  background: var(--srf);
  /* --bd-2, same as the sibling panels since the canvas change — the hero is
     a panel on the grey document canvas like the sections beside it. */
  border: 1px solid var(--bd-2);
  border-radius: var(--r);
  box-shadow: none;
  padding: 10px 12px;
  gap: 12px;
}
[data-ui="v12"] .je-ai:hover {
  border-color: var(--bd-2); background: var(--srf-3);
  box-shadow: none; transform: none;
}
[data-ui="v12"] .je-ai-ic {
  width: 32px; height: 32px; border-radius: var(--r-s);
  background: var(--acc-soft); color: var(--acc-2); box-shadow: none;
}
[data-ui="v12"] .je-ai-t { font-size: 13.5px; font-weight: 600; color: var(--ink); }
[data-ui="v12"] .je-ai-s { font-size: 12px; color: var(--ink-3); opacity: 1; }

/* ---- editor layout in the docked pane ------------------------------------
   Three fixes the classic editor needs when it renders inside /v2:

   1. FULL WIDTH. The classic centres itself at max-width 1240px, which is
      right for a standalone browser tab and wrong inside a document pane —
      it left dead gutters both sides while the fields sat cramped.
   2. RESPONSIVE. The classic collapse (styles.css @media 1280px) is a
      VIEWPORT query; in a docked pane it fires at the wrong moment or never
      — the same trap the cockpit's column steps had. The pane (.docbody) is
      a container, so these are container queries on the pane's real width.
   3. FULL-WIDTH FIELDS. Every input inside a .field label-column stretches
      to its cell. A date input at intrinsic width beside a stretched text
      input is what made the forms read ragged. */
/* The editor is a classic screen hosted in the V12 pane, so it does not render
   the design's `.page` wrapper and never picked up the page gutter every other
   route gets (.docbody > .page → 20px 22px 32px). Give it the same one, stated
   here rather than inherited from classic's `0 var(--pad) 90px`, so the editor
   sits on the pane exactly like Jobs, Free Mode and Settings do. */
[data-ui="v12"] .je { max-width: none; padding: 20px 22px 32px; }
[data-ui="v12"] .field > .input,
[data-ui="v12"] .field > .select,
[data-ui="v12"] .field > .textarea,
[data-ui="v12"] .field > input.input,
[data-ui="v12"] .field > select.select { width: 100%; min-width: 0; }
@container (max-width: 1060px) {
  [data-ui="v12"] .je-grid { grid-template-columns: minmax(0, 1fr); }
  [data-ui="v12"] .je-rail { position: static; }
}
@container (max-width: 700px) {
  /* the docket's four-across field grid folds to two, then the paste/import
     toolbar wraps instead of pushing the table wider than the pane */
  [data-ui="v12"] .je .card-head { flex-wrap: wrap; row-gap: 6px; }
}

[data-ui="v12"] .je-card {
  background: var(--srf); border: 1px solid var(--bd); border-radius: var(--r-s);
}
[data-ui="v12"] .je-card-h {
  display: flex; align-items: center; gap: 9px;
  min-height: 40px; padding: 0 13px;
  border-bottom: 1px solid var(--bd); background: var(--srf-2);
  font-size: 13.5px; font-weight: 600;
}
[data-ui="v12"] .je-card-b { padding: 13px; }
[data-ui="v12"] .je-step {
  width: 20px; height: 20px; border-radius: var(--r-xs); flex: none;
  background: var(--acc); color: var(--ac-ink);
  display: grid; place-items: center;
  font-family: var(--m); font-size: 11px; font-weight: 700;
}
[data-ui="v12"] .je-stat { font-size: 12.5px; color: var(--ink-3); }
[data-ui="v12"] .menu-sep { height: 1px; background: var(--bd); margin: 4px 0; }

/* The editor's SECTIONS, dressed as the design's plates. Classic renders
   .je-sec-h as a roomy 16px/750 heading floating over 20px padding; the
   design's card header is a compact 40px strip on srf-2 with a 14px title
   (v11.css .plate-hd). Same markup, design metrics. */
[data-ui="v12"] .je-sec { border-radius: var(--r); box-shadow: none; }
[data-ui="v12"] .je-sec-h {
  min-height: 40px; padding: 6px 12px; gap: 9px;
  background: var(--srf-2); border-bottom: 1px solid var(--bd);
}
[data-ui="v12"] .je-sec-h h2,
[data-ui="v12"] .je-head2 h2 {
  font-family: var(--d); font-size: 14px; font-weight: 600; letter-spacing: 0;
}
[data-ui="v12"] .je-sec-b { padding: 14px; }
[data-ui="v12"] .je-order { gap: 12px; }
[data-ui="v12"] .je-order .full { gap: 12px; }
[data-ui="v12"] .je-head2 { margin: 4px 2px 0; min-height: 32px; }
[data-ui="v12"] .je-tabs { margin: 10px 0 12px; }
/* Order ref: classic gives it a 46px/19px hero input INLINE; in the design
   every control is 34-38px. !important is the only way past an inline style —
   scoped here so classic "/" keeps its hero. The dashed add-customer button
   shares the row and must match the new height. */
[data-ui="v12"] .je-order .input.mono { height: 38px !important; font-size: 15px !important; }
[data-ui="v12"] .je-order .field .btn { height: 38px !important; border-radius: var(--r-s) !important; }

/* remaining classic-only names -------------------------------------------- */
/* The V12 document pane already constrains width and scrolls; a page-level
   max-width fights it and leaves the content floating off-centre in a wide
   pane. Let the pane decide. */
[data-ui="v12"] .page.wide { max-width: none; }
[data-ui="v12"] .je-sec-c { margin-left: auto; font-size: 12px; font-weight: 600; color: var(--ink-3); }
[data-ui="v12"] .pcell { font-size: 13px; color: var(--ink); }
[data-ui="v12"] .sel-cell { text-align: center; }

/* job-editor header ------------------------------------------------------- */
/* The editor keeps its own je-* header vocabulary. Rather than restructure
   1,600 lines where every field feeds the engine, the header is mapped onto
   the V12 page head: eyebrow as .lab, the ref at V12's h2 size and weight,
   the sticky bar on V12 surfaces. */
[data-ui="v12"] .je-top {
  background: var(--win); border-bottom: 1px solid var(--bd);
  padding: 14px 0 12px; gap: 14px;
}
[data-ui="v12"] .je-eyebrow {
  font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-3);
}
[data-ui="v12"] .je-title {
  font-family: var(--f); font-size: 26px; font-weight: 600; letter-spacing: -.02em;
  margin: 2px 0 0; color: var(--ink);
}
[data-ui="v12"] .je-title .cust { color: var(--ink-3); font-weight: 400; }
[data-ui="v12"] .je-back {
  font-size: 12.5px; font-weight: 500; color: var(--ink-3);
  border-radius: var(--r-xs); padding: 5px 9px 5px 5px;
}
[data-ui="v12"] .je-back:hover { color: var(--ink); background: var(--srf-3, var(--srf-2)); }
[data-ui="v12"] .je-head2 { margin: 8px 0 0; }

/* ===========================================================================
   CLASSIC TOKEN ALIASES — the deep half of the skin.
   ---------------------------------------------------------------------------
   The class skin above restyles classic CLASS names, but a lot of the classic
   markup is inline-styled with the classic CUSTOM PROPERTIES — the saw tablet's
   header, the production cards, the editor's chips. CSS cannot outrank an
   inline style, so those kept the old palette inside /v2.

   Re-pointing the classic token NAMES at the V12 values fixes all of it at
   once, because an inline `background: var(--surface)` then resolves to the
   V12 surface. Scoped to [data-ui="v12"], so the classic app at / is
   completely unaffected.

   Only colour/surface tokens are aliased. Sizing tokens (--pad, radii) are
   left alone: the floor screens set deliberate 44-52px touch targets inline,
   and shrinking those would make the tablet worse on the machine, not better.
   =========================================================================== */
[data-ui="v12"] {
  --bg:             var(--win);
  --surface:        var(--srf);
  --surface-2:      var(--srf-2);
  --surface-3:      var(--srf-3, var(--srf-2));
  --border:         var(--bd);
  --border-2:       var(--bd-2);
  --border-strong:  var(--bd-2);
  --text:           var(--ink);
  --text-2:         var(--ink-2);
  --text-3:         var(--ink-3);
  --accent:         var(--acc);
  --accent-2:       var(--acc-2);
  --accent-soft:    var(--acc-soft);
  --accent-text:    var(--acc);
  --ok:             var(--ok);
  --ok-text:        var(--ok);
  --err:            var(--err);
  --err-text:       var(--err);
  --warn-text:      var(--ink-2);
  --shadow-lg:      none;
  --shadow-pop:     none;

  /* The tokens above were the first pass; these are the ones a dark-mode
     audit found still falling through to the CLASSIC dark palette — which is
     where "v1 colours in dark mode" came from. Any classic token not aliased
     here resolves from styles.css's own :root[data-theme=dark] block, so a
     hosted screen wore v1's accent states, v1's tone chips and v1's FONTS
     inside the V12 shell.

     The soft tones are mixed from the V12 palette rather than hardcoded, so
     they flip with the theme by construction. --on-accent maps to --ac-ink —
     the design's own "ink on accent" token, which is dark in dark mode
     because the accent there is light. Fonts were the most visible leak of
     all: hosted panels rendered in v1's Inter next to V12's Segoe. */
  --accent-hover:   var(--acc-2);
  --accent-press:   var(--acc-3);
  --accent-soft-2:  var(--acc-soft);
  --on-accent:      var(--ac-ink);
  --muted-text:     var(--ink-3);
  --muted-soft:     var(--srf-3);
  --ok-soft:        color-mix(in srgb, var(--ok) 14%, var(--srf));
  --err-soft:       color-mix(in srgb, var(--err) 14%, var(--srf));
  --warn-soft:      color-mix(in srgb, var(--amb) 16%, var(--srf));
  --overlay:        rgba(0, 0, 0, .45);
  --shadow-sm:      var(--sh);
  --shadow-md:      var(--sh-2);
  --font:           var(--f);
  --font-head:      var(--d);
  --mono:           var(--m);
  /* radii follow the design; the SIZING tokens (--pad, --control-h, --row-h,
     --cell-py) stay classic on purpose — the floor screens set deliberate
     44-52px touch targets with them, per the note above. */
  --r-sm:           var(--r-xs);
  --r-md:           var(--r-s);
  --r-lg:           var(--r);
  --r-xl:           var(--r);
}

/* The classic rules that paint LITERAL white on an accent background — the
   token aliases can't reach these because #fff is written into the rule, not
   into a token. In dark, the accent is light, so each was white-on-light at
   the same 2.01 ratio the Send button had. Found by contrast probe, not by
   reading: .chip.solid, the checkbox tick, and the checked ack box. */
[data-ui="v12"] .chip.solid { color: var(--ac-ink); }
[data-ui="v12"] .cbx svg { color: var(--ac-ink); }

/* ------------------------------------------------- the editor is a FORM --- */
/* Removing classic's max-width let the editor fill the document pane. At
   1264px that was right; at 1920 it is a mess — measured: the form column
   runs 1516px, so a ten-character order reference gets a 418px box and the
   Notes field stretches to 948px. Nothing about a form improves past a
   comfortable measure; only the parts table earns extra width, and it does
   not need 1500px for eleven columns either.

   So the editor caps at a measure and stays put. The cap is on the GRID, so
   the totals rail travels with the form instead of drifting to the far edge
   of a widescreen. Below the cap nothing changes at all. */
@container (min-width: 1500px) {
  [data-ui="v12"] .je-grid { max-width: 1460px; }
}
