/* ==========================================================
   PMSLens — dense ERP UI. Black / white / grey only.
   Colour is reserved for status: green, amber, red.
   ========================================================== */
:root{
  --bg:#f5f5f5;
  --card:#ffffff;
  --dark:#1a1a1a;
  --border:#e0e0e0;
  --muted:#999999;
  --text:#1a1a1a;
  --text-2:#666666;
  --green:#1b8a2a;  --green-bg:#e9f4ea;
  --amber:#c77d00;  --amber-bg:#fdf5e6;
  --red:#c62828;    --red-bg:#fbeaea;
  --mono:'JetBrains Mono','Consolas',monospace;
  --sans:'IBM Plex Sans',-apple-system,Segoe UI,Arial,sans-serif;
  --r:2px;
}
*{margin:0;padding:0;box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{font-family:var(--sans);font-size:13px;line-height:1.45;color:var(--text);background:var(--bg)}
a{color:inherit;text-decoration:none}
::selection{background:#1a1a1a;color:#fff}

/* ---------- shell ---------- */
.shell{display:flex;min-height:100vh}
.sidebar{width:200px;flex:0 0 200px;background:#fff;border-right:1px solid var(--border);
  position:fixed;top:0;left:0;bottom:0;display:flex;flex-direction:column;z-index:100}
/* brand block is exactly the height of the top bar so the two rules line up */
.brand{height:64px;flex:0 0 64px;padding:0 14px;border-bottom:1px solid var(--border);
  display:flex;align-items:center;justify-content:space-between;gap:6px;
  font-family:var(--mono);font-size:12px;letter-spacing:2.5px;text-transform:uppercase;
  overflow:hidden;white-space:nowrap}
.brand small{font-size:9px;color:var(--muted);letter-spacing:.5px;flex:0 0 auto}
.nav{flex:1;overflow-y:auto;overflow-x:hidden;padding:6px 0}
.nav-sec{padding:14px 14px 4px;font-size:9px;letter-spacing:2px;text-transform:uppercase;color:var(--muted)}
.nav a{display:block;padding:6px 14px;font-size:12px;color:var(--text-2);border-left:2px solid transparent;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.nav a:hover{background:#fafafa;color:var(--text)}
.nav a.active{background:#f0f0f0;color:var(--text);border-left-color:var(--dark);font-weight:600}
.side-foot{border-top:1px solid var(--border);padding:8px 14px;font-size:10px;color:var(--muted);overflow:hidden}
.side-foot strong{display:block;color:var(--text);font-size:11px;font-weight:600;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.side-foot a{color:var(--text-2);font-size:10px;text-transform:uppercase;letter-spacing:.5px;flex:0 0 auto}
.side-foot a:hover{color:var(--red)}
.side-foot .between{gap:6px;min-width:0}
.side-foot .between>span:first-child{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

.main{flex:1;margin-left:200px;min-width:0;max-width:calc(100% - 200px)}
.topbar{height:64px;background:#fff;border-bottom:1px solid var(--border);
  display:flex;align-items:center;justify-content:space-between;gap:12px;padding:0 18px;
  position:sticky;top:0;z-index:60}
.topbar h1{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  min-width:0;flex:1 1 auto}
.topbar .right{display:flex;align-items:center;gap:10px;font-family:var(--mono);font-size:11px;
  color:var(--text-2);flex:0 0 auto;min-width:0}
.topbar .right>span{white-space:nowrap}
.topbar select.co-switch{font-family:var(--mono);font-size:11px;border:1px solid var(--border);
  border-radius:var(--r);padding:3px 22px 3px 6px;background:#fff;
  max-width:180px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}
.topbar select.co-switch:focus{outline:none;border-color:var(--dark)}
.page{padding:14px 18px 40px;min-width:0;overflow-x:hidden}

/* ---------- cards ---------- */
.card{background:var(--card);border:1px solid var(--border);border-radius:var(--r);margin-bottom:12px}
.card-head{padding:9px 14px;border-bottom:1px solid var(--border);font-size:11px;font-weight:600;
  letter-spacing:1px;text-transform:uppercase;display:flex;align-items:center;justify-content:space-between;gap:10px}
.card-head .tools{display:flex;gap:6px;align-items:center}
.card-body{padding:14px}
.card-body.tight{padding:9px 14px}
.card.s-green{border-left:3px solid var(--green)}
.card.s-amber{border-left:3px solid var(--amber)}
.card.s-red{border-left:3px solid var(--red)}

/* ---------- tables ---------- */
.tbl{width:100%;border-collapse:collapse;font-size:12px;table-layout:auto}
.tbl th{background:var(--dark);color:#fff;text-align:left;padding:7px 9px;font-size:10px;
  font-weight:600;letter-spacing:.5px;text-transform:uppercase;white-space:nowrap}
.tbl th.n,.tbl td.n{text-align:right;font-family:var(--mono)}
.tbl th.c,.tbl td.c{text-align:center}
.tbl td{padding:6px 9px;border-bottom:1px solid var(--border);vertical-align:middle}
.tbl tbody tr:hover td{background:#fafafa}
.tbl tfoot td{background:#f5f5f5;font-weight:700;border-top:2px solid var(--dark);border-bottom:none}
.tbl .neg{color:var(--red)}
.tbl-wrap{overflow-x:auto;max-width:100%;min-width:0}
.tbl input.form-control,.tbl select.form-control{padding:4px 6px;font-size:12px}
.tbl-sm td{padding:4px 8px}
.empty{padding:22px 14px;text-align:center;color:var(--muted);font-size:12px}

/* ---------- dense grid: register-style reports ---------- */
.tbl-dense{font-size:11px;border-collapse:collapse}
.tbl-dense th{padding:4px 6px;font-size:9px;letter-spacing:.3px;
  border-right:1px solid #333;border-bottom:1px solid #333;line-height:1.2}
.tbl-dense th:last-child{border-right:none}
.tbl-dense td{padding:2px 6px;line-height:1.35;border-right:1px solid #ececec;
  border-bottom:1px solid #ececec;vertical-align:middle;white-space:nowrap;height:22px}
.tbl-dense td:last-child{border-right:none}
.tbl-dense tbody tr:hover td{background:#fafafa}
.tbl-dense .grp td{border-top:2px solid #bdbdbd}
.tbl-dense .sub-td{background:#fcfcfc}
.tbl-dense tfoot td{padding:4px 6px;border-right:1px solid #d0d0d0}
.tbl-dense .badge{padding:1px 5px;font-size:9px}
/* long free text stays on one line and reveals in full on hover */
.tbl-dense .clip{max-width:230px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}
.tbl-dense .zero{color:#d0d0d0}
/* header sticks under the 64px top bar while scrolling */
/* The header row stays put while the rows scroll under it. The wrapper does the
   scrolling rather than the page, because .tbl-wrap already establishes an
   overflow context and a sticky header cannot escape one. */
.tbl-wrap.sticky{max-height:calc(100vh - 230px);overflow:auto}
.tbl-wrap.sticky thead th{position:sticky;top:0;z-index:3;
  box-shadow:inset 0 -1px 0 var(--border)}
/* a footer of totals is as worth keeping in view as the header */
.tbl-wrap.sticky tfoot td{position:sticky;bottom:0;z-index:3;background:#fff;
  box-shadow:inset 0 1px 0 var(--border)}
.tbl-wrap.sticky thead tr:nth-child(2) th{top:22px}
.tbl-dense .stick-l{position:sticky;left:0;background:#fff;z-index:2;border-right:1px solid #d8d8d8}
.tbl-dense tbody tr:hover .stick-l{background:#fafafa}
.tbl-dense thead .stick-l{background:var(--dark);z-index:4}

/* ---------- badges ---------- */
.badge{display:inline-block;font-family:var(--mono);font-size:10px;font-weight:700;
  letter-spacing:.5px;padding:2px 7px;border-radius:1px;white-space:nowrap}
.badge-green{background:var(--green-bg);color:var(--green)}
.badge-amber{background:var(--amber-bg);color:var(--amber)}
.badge-red{background:var(--red-bg);color:var(--red)}
.badge-dark{background:#efefef;color:var(--text-2)}

/* ---------- forms ---------- */
.form-group{margin-bottom:10px}
.form-group>label{display:block;font-size:10px;font-weight:600;letter-spacing:.5px;
  text-transform:uppercase;color:var(--text-2);margin-bottom:3px}
.form-control{width:100%;padding:6px 9px;font-family:var(--sans);font-size:13px;color:var(--text);
  background:#fff;border:1px solid var(--border);border-radius:var(--r)}
.form-control:focus{outline:none;border-color:var(--dark);box-shadow:none}
.form-control[readonly]{background:#fafafa;color:var(--text-2)}
textarea.form-control{min-height:56px;resize:vertical}
input[type=number].form-control,input[type=date].form-control,input[type=month].form-control,
input[type=time].form-control{font-family:var(--mono);font-size:12px}

/* Numeric inputs must sit right, like every other number in a table. Without
   this the digits inside the box aligned left while the column header and the
   footer total aligned right, so the totals never lined up with the figures
   above them. */
.form-control.n,.tbl td.n input.form-control{text-align:right}
.form-row{display:flex;gap:10px;flex-wrap:wrap}
.form-row>.form-group{flex:1 1 150px;min-width:120px}
.form-row.end{align-items:flex-end}
.chk{display:flex;align-items:center;gap:6px;font-size:12px}
.chk-group{display:flex;flex-wrap:wrap;gap:6px 18px;padding:7px 9px;border:1px solid var(--border);
  border-radius:var(--r);background:#fff}
.chk-group .chk{flex:0 0 auto;white-space:nowrap}
.chk input{width:14px;height:14px;accent-color:#1a1a1a}
.hint{font-size:10px;color:var(--muted);margin-top:3px}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;gap:5px;padding:6px 14px;font-family:var(--sans);
  font-size:11px;font-weight:600;letter-spacing:1px;text-transform:uppercase;cursor:pointer;
  border:1px solid transparent;border-radius:var(--r);background:none;white-space:nowrap}
.btn-primary{background:var(--dark);color:#fff;border-color:var(--dark)}
.btn-primary:hover{background:#000}
.btn-secondary{background:#fff;color:var(--text);border-color:var(--border)}
.btn-secondary:hover{background:#fafafa;border-color:#c8c8c8}
.btn-danger{background:var(--red);color:#fff;border-color:var(--red)}
.btn-danger:hover{background:#a81f1f}
.btn-confirm{background:var(--green);color:#fff;border-color:var(--green)}
.btn-confirm:hover{background:#146d21}
.btn-sm{padding:3px 9px;font-size:10px;letter-spacing:.5px}
.btn:disabled{opacity:.45;cursor:not-allowed}
.btn-group{display:flex;gap:6px;flex-wrap:wrap}

/* ---------- KPI ---------- */
.kpi{background:#fff;border:1px solid var(--border);border-left:3px solid var(--border);
  border-radius:var(--r);padding:10px 12px}
.kpi.green{border-left-color:var(--green)}
.kpi.amber{border-left-color:var(--amber)}
.kpi.red{border-left-color:var(--red)}
.kpi .lbl{font-size:9px;letter-spacing:1px;text-transform:uppercase;color:var(--muted)}
.kpi .val{font-family:var(--mono);font-size:22px;font-weight:700;line-height:1.15;margin:3px 0 1px}
.kpi .val.green{color:var(--green)} .kpi .val.amber{color:var(--amber)} .kpi .val.red{color:var(--red)}
.kpi .sub{font-size:10px;color:var(--text-2);font-family:var(--mono)}

/* ---------- grid ---------- */
.grid{display:grid;gap:12px}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
.g5{grid-template-columns:repeat(5,1fr)}
.g6{grid-template-columns:repeat(6,1fr)}
.g-2-1{grid-template-columns:2fr 1fr}
.g-1-2{grid-template-columns:1fr 2fr}

/* ---------- charts ---------- */
.chart{position:relative;width:100%;height:260px;overflow:hidden;min-width:0}
.chart.tall{height:330px}
.chart.short{height:190px}
.chart canvas{max-width:100%!important;display:block}
.card-body{min-width:0}
.grid{min-width:0}
.grid>*{min-width:0}

/* ---------- column grouping: makes wide entry grids readable ----------
   Groups are separated by a heavier rule. Derived columns sit on a grey
   band so they read as read-only; the one column that matters most gets
   the strongest treatment. Colour stays reserved for status. */
.tbl-grid{border-collapse:collapse}
.tbl-grid th,.tbl-grid td{border-right:1px solid #ededed}
.tbl-grid th{border-right-color:#3d3d3d}
.tbl-grid th:last-child,.tbl-grid td:last-child{border-right:none}
.tbl-grid .g0{border-left:2px solid #c9c9c9}
.tbl-grid thead .g0{border-left:2px solid #545454}
.tbl-grid tfoot .g0{border-left:2px solid #c9c9c9}
/* derived / calculated cells */
.tbl-grid .calc{background:#fafafa;color:var(--text-2)}
.tbl-grid thead .calc{background:#2a2a2a;color:#cfcfcf}
.tbl-grid tbody tr:hover .calc{background:#f3f3f3}
/* the primary input column */
.tbl-grid .key{background:#f1f1f1}
.tbl-grid .key .form-control{background:#fff;border-color:#b8b8b8;font-weight:700}
.tbl-grid thead .key{background:#000;color:#fff}
.tbl-grid tbody tr:hover .key{background:#eaeaea}
.tbl-grid tfoot td{background:#f0f0f0;border-top:2px solid var(--dark);font-weight:700}
.tbl-grid tfoot .key{background:#e4e4e4}
/* free-text block sits flush white so it reads as a separate zone */
.tbl-grid td.txt{background:#fff}
.tbl-grid tbody tr:hover td.txt{background:#fcfcfc}

/* icon-only actions: keeps dense rows narrow and the action column tidy */
.btn-icon{padding:3px 6px;line-height:1;min-width:26px;justify-content:center}
/* A row needing attention — a slab crossing a shift change, say. Amber is a
   status colour here, not decoration. */
tr.row-warn>td{background:#fdf8ee}
tr.row-warn:hover>td{background:#fbf3e2}
tr.row-warn>td:first-child{box-shadow:inset 2px 0 0 var(--amber)}

/* First row of a group: a heavier rule above, matching the column grouping. */
tr.row-grp>td{border-top:2px solid #d0d0d0}
tr.row-grp:first-child>td{border-top:0}
td.grp-name{font-weight:600}

td.actions,th.actions{white-space:nowrap;text-align:right}
td.actions form{display:inline}
td.actions>*{margin-left:3px}
.btn-icon svg{width:13px;height:13px;display:block;fill:none;stroke:currentColor;
  stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}

/* an hour block groups several module lines; the first line carries the time */
.hour-start td{border-top:2px solid #c9c9c9}
.sub-line td:first-child{color:var(--muted)}

/* value chips — used for difference columns */
.chip{display:inline-block;min-width:36px;text-align:center;font-family:var(--mono);
  font-size:10px;font-weight:700;padding:1px 6px;border-radius:1px;letter-spacing:.3px}
.chip-flat{background:#efefef;color:var(--text-2)}
.chip-red{background:var(--red-bg);color:var(--red)}
.chip-green{background:var(--green-bg);color:var(--green)}
.chip-solid-red{background:var(--red);color:#fff}
.chip-solid-green{background:var(--green);color:#fff}

/* Totals under a column of <input> cells.
   An input insets its digits by its own padding (6px) plus border (1px), so a
   plain-text total in the footer would sit 7px to the right of the numbers it
   is summing. Add that 7px back so the column reads as one straight edge. */
.tbl-inputs tfoot td.n{padding-right:16px}          /* 9px cell + 7px input */
.tbl-dense.tbl-inputs tfoot td.n{padding-right:13px} /* 6px cell + 7px input */
.tbl-inputs tfoot td.n.no-inset{padding-right:9px}



/* Inputs inside dense tables were being squeezed until digits were clipped.
   A minimum width keeps them typeable however tight the column is. */
.tbl-dense td input.form-control{min-width:54px}
.tbl-dense td input[type=number].form-control{min-width:62px}
.tbl-dense td input[type=time].form-control{min-width:104px}
.tbl-dense td .form-control{padding:4px 6px}

/* ---------- searchable select ----------
   The native <select> stays in the DOM carrying the value; it is moved out of
   sight rather than display:none so form validation still behaves. */
.ss-wrap{position:relative;width:100%}
.ss-native{position:absolute;opacity:0;pointer-events:none;height:1px;width:1px;overflow:hidden}
.ss-field{display:block;width:100%;text-align:left;cursor:pointer;background:#fff;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-family:var(--sans);font-size:13px;
  padding:6px 22px 6px 9px;position:relative}
.ss-field::after{content:'';position:absolute;right:9px;top:50%;margin-top:-2px;
  border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid var(--muted)}
.ss-field:focus{outline:none;border-color:var(--dark)}
.ss-field.ss-empty{color:var(--muted)}
.tbl .ss-field{padding:4px 20px 4px 6px;font-size:12px}

/* Fixed, not absolute. Ancestors clip in ways that are hard to predict — a
   card with overflow:hidden, a scrolling table, and .page which sets
   overflow-x:hidden and so clips vertically too. Fixed positioning escapes all
   of them; the coordinates are set from the field's rect when it opens. */
.ss-panel{position:fixed;z-index:200;background:#fff;
  border:1px solid var(--dark);border-radius:var(--r);min-width:220px}
.ss-panel.hidden{display:none}
.ss-input{width:100%;border:0;border-bottom:1px solid var(--border);padding:7px 9px;
  font-family:var(--sans);font-size:12px;color:var(--text)}
.ss-input:focus{outline:none}
.ss-list{max-height:260px;overflow-y:auto}
.ss-opt{padding:6px 9px;font-size:12px;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ss-opt.cur{background:#f0f0f0}
.ss-opt.sel{font-weight:600}
.ss-opt:hover{background:#fafafa}
.ss-group{padding:5px 9px;font-size:10px;letter-spacing:.5px;text-transform:uppercase;
  color:var(--muted);background:#fafafa;border-top:1px solid var(--border)}
.ss-list .ss-group:first-child{border-top:0}
.ss-none{padding:8px 9px;font-size:12px;color:var(--muted)}

/* Nothing to un-clip any more — the panel is positioned against the viewport. */

/* ---------- overflow guards ---------- */
.card{overflow:hidden}
.card-head{min-width:0}
.card-head>span:first-child,.card-head>a:first-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kpi{overflow:hidden}
.kpi .val{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.kpi .sub,.kpi .lbl{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.filters{overflow:hidden}
/* Table cells size to their content and never wrap. Anything too long is
   clipped with .clip; the .tbl-wrap scrolls horizontally instead. */
.tbl td,.tbl th{white-space:nowrap}
.tbl td.wrap,.tbl th.wrap{white-space:normal}
.tbl{width:auto;min-width:100%}


/* A row that runs through a break: tinted, not blocked. Lines do work through
   lunch, so the sheet must be able to record it — this only makes it visible. */
tr.row-break>td{background:#f2f2f2}
tr.row-break>td:first-child{box-shadow:inset 3px 0 0 var(--muted)}
tr.row-break:hover>td{background:#ececec}



/* ---------- OEE lot screen ----------
   One screen: the lot strip, every section behind tabs beneath it, then the
   buttons, then the day's other lots. Full width — the entry needs the room and
   the history is only for glancing at. */
.oee-b{display:flex;flex-direction:column;gap:10px}
.oee-strip{flex:0 0 auto}
.oee-strip .card{margin-bottom:0}
.oee-body{min-height:0}

.oee-tabs{display:flex;flex-direction:column;min-height:0;margin-bottom:0}
.oee-tabs .tabs{display:flex;border-bottom:1px solid var(--border);flex:0 0 auto;flex-wrap:wrap}
.oee-tabs .tabs button{border:0;border-right:1px solid var(--border);background:#fafafa;
  padding:7px 14px;font-family:var(--sans);font-size:10px;font-weight:600;letter-spacing:.6px;
  text-transform:uppercase;color:var(--text-2);cursor:pointer}
.oee-tabs .tabs button.on{background:#fff;color:var(--text);box-shadow:inset 0 -2px 0 var(--dark)}
.oee-tabs .pane{display:none;padding:10px}
.oee-tabs .pane.on{display:block}
/* the captured blocks brought their own card frames; inside a pane they are
   content, so drop the doubled border */
.oee-tabs .pane>.card{border:0;margin:0}
.oee-tabs .pane>.card>.card-head{padding-left:0;padding-right:0;border-top:0}
.oee-tabs .pane>.grid{margin:0}

.oee-daylots{margin-bottom:0}
.oee-daylots .tbl-wrap{max-height:38vh;overflow:auto}


/* a break drawn into the advanced plan: a gap, not a slab */
tr.adv-break-row>td{background:#f2f2f2;color:var(--text-2);border-top:1px dashed var(--border);
  border-bottom:1px dashed var(--border);padding-top:4px;padding-bottom:4px}

/* ---------- process roll-up on the overview ---------- */
.btn-twist{width:20px;height:20px;line-height:1;padding:0;border:1px solid var(--border);
  background:#fff;border-radius:var(--r);font-family:var(--mono);font-size:13px;
  color:var(--text);cursor:pointer}
.btn-twist:hover{border-color:var(--dark)}
tr.row-proc{cursor:pointer}
tr.row-proc>td{border-top:2px solid var(--border);background:#fcfcfc}
tr.row-proc:hover>td{background:#f4f4f4}
tr.row-line>td{background:#fff}
td.sub-line{padding-left:20px;color:var(--text-2)}
tr.row-line.hidden{display:none}

/* ---------- master record form ----------
   A twelve-column grid instead of a flex row of pixel widths: fields line up
   on the same left edges and their labels share a baseline, whatever mix of
   widths a particular master happens to declare. */
.form-grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:12px 14px;align-items:start}
.form-grid .fg{min-width:0;display:flex;flex-direction:column}
.form-grid .fg>label{margin-bottom:3px}
.form-grid .fg .form-control{width:100%}
.fg.s2{grid-column:span 2}.fg.s3{grid-column:span 3}.fg.s4{grid-column:span 4}
.fg.s6{grid-column:span 6}.fg.s12{grid-column:span 12}
.form-grid .hint{margin-top:3px}
label .req{color:var(--red)}

/* Checkboxes get their own band so they never sit mid-row among text inputs. */
.form-ticks{display:flex;flex-wrap:wrap;gap:8px 22px;margin-top:14px;padding:10px 12px;
  border:1px solid var(--border);border-radius:var(--r);background:#fafafa}
.form-ticks .fg-tick label{display:flex;align-items:center;gap:6px;font-size:12px;
  text-transform:none;letter-spacing:0;color:var(--text)}

/* A long list of lines or shifts is a picker, not a field: its own block with a
   count, a filter and select-all, and a fixed height that scrolls. */
.pick{margin-top:14px;border:1px solid var(--border);border-radius:var(--r)}
.pick-head{display:flex;justify-content:space-between;align-items:center;gap:10px;
  padding:8px 12px;border-bottom:1px solid var(--border);background:#fafafa;
  font-size:10px;font-weight:600;letter-spacing:1px;text-transform:uppercase}
.pick-tools{display:flex;align-items:center;gap:8px}
.pick-tools .form-control.xs{padding:4px 7px;font-size:11px}
.pick-body{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));
  gap:2px 14px;padding:10px 12px;max-height:210px;overflow-y:auto}
.pick-body .chk{display:flex;align-items:center;gap:6px;font-size:12px;cursor:pointer;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:2px 0}
.pick-body .chk input{margin:0;flex:0 0 auto}
.pick .hint{padding:8px 12px;border-top:1px solid var(--border);margin:0}

.form-actions{display:flex;gap:8px;margin-top:16px;padding-top:14px;border-top:1px solid var(--border)}

@media (max-width:900px){
  .fg.s2,.fg.s3,.fg.s4{grid-column:span 6}
  .fg.s6{grid-column:span 12}
}

/* ---------- misc ---------- */
.mono{font-family:var(--mono)}
.muted{color:var(--muted)}
.small{font-size:11px}
.xs{font-size:10px}
.right{text-align:right}.center{text-align:center}
.green{color:var(--green)}.amber{color:var(--amber)}.red{color:var(--red)}
.mb0{margin-bottom:0}.mb1{margin-bottom:8px}.mb2{margin-bottom:16px}
.mt1{margin-top:8px}.mt2{margin-top:16px}
.flex{display:flex;gap:8px;align-items:center}
.between{display:flex;justify-content:space-between;align-items:center;gap:10px}
.wrap{flex-wrap:wrap}
.nowrap{white-space:nowrap}
.hidden{display:none!important}
.bar{height:5px;background:var(--border);border-radius:1px;overflow:hidden}
.bar>i{display:block;height:100%}
.bar>i.green{background:var(--green)}.bar>i.amber{background:var(--amber)}.bar>i.red{background:var(--red)}

.flash{padding:8px 12px;font-size:12px;border:1px solid var(--border);border-left-width:3px;
  border-radius:var(--r);margin-bottom:10px;background:#fff}
.flash.ok{border-left-color:var(--green);color:var(--green)}
.flash.warn{border-left-color:var(--amber);color:var(--amber)}
.flash.err{border-left-color:var(--red);color:var(--red)}

.filters{background:#fff;border:1px solid var(--border);border-radius:var(--r);padding:9px 12px;margin-bottom:12px}
/* Controls dropped straight into a .filters form — without the usual .form-row
   wrapper — would each become a block and take a whole line. Lay them out the
   same way either way, so a row carries several filters rather than one. */
.filters>.form-group,.filters>select,.filters>input{display:inline-block;vertical-align:bottom;
  margin-right:10px}
.filters .form-row{align-items:flex-end}
.filters .form-group{margin-bottom:0}

.tabs{display:flex;gap:0;border-bottom:1px solid var(--border);margin-bottom:12px;overflow-x:auto}
.tabs a{padding:7px 14px;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;
  color:var(--muted);border-bottom:2px solid transparent;white-space:nowrap}
.tabs a:hover{color:var(--text)}
.tabs a.active{color:var(--text);border-bottom-color:var(--dark)}

/* ---------- login ---------- */
.login-page{min-height:100vh;display:flex;align-items:center;justify-content:center;background:#1a1a1a;padding:20px}
.login-box{width:340px;background:#fff;border-radius:var(--r);overflow:hidden}
.login-head{background:#1a1a1a;color:#fff;padding:22px;text-align:center;font-family:var(--mono);
  font-size:13px;letter-spacing:4px;text-transform:uppercase}
.login-head small{display:block;font-size:9px;letter-spacing:1px;color:#8a8a8a;margin-top:5px}
.login-body{padding:22px}
.login-body .btn{width:100%;justify-content:center;padding:9px}
.login-foot{border-top:1px solid var(--border);padding:10px;text-align:center;font-size:9px;
  color:var(--muted);font-family:var(--mono);letter-spacing:1px}
.login-demo{border-top:1px solid var(--border);padding:10px 22px;font-size:10px;color:var(--muted);font-family:var(--mono)}

/* ---------- floor display ---------- */
.floor{background:#fff;min-height:100vh}
.floor-head{height:44px;display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:0 16px;border-bottom:1px solid var(--border);background:#fff;white-space:nowrap;overflow:hidden}
.floor-head > .flex{flex:0 0 auto;min-width:0}
.floor-head .dots{max-width:420px;flex-wrap:wrap;row-gap:3px}
.floor-head h1{font-family:var(--mono);font-size:13px;letter-spacing:2px;text-transform:uppercase;white-space:nowrap}
.floor-head .clock{font-family:var(--mono);font-size:16px;font-weight:700;line-height:1.1}
.floor-head .sub{font-family:var(--mono);font-size:10px;color:var(--muted);line-height:1.1;white-space:nowrap}
/* header 44 + ticker 30: the slide is everything in between, no spare band below */
.slide{display:none;padding:8px 14px 0;height:calc(100vh - 44px - 30px);box-sizing:border-box}
.slide > .card{height:100%;display:flex;flex-direction:column;margin:0}
.slide > .card > .card-body{flex:1 1 auto;min-height:0;padding:8px 10px 6px}
.slide.on{display:block}
.ticker{position:fixed;left:0;right:320px;bottom:0;height:30px;background:#1a1a1a;overflow:hidden}
/* duration is set in JS from the content width so the speed stays readable
   however much news there is; this is only the fallback */
.ticker .run{display:inline-flex;white-space:nowrap;padding-top:7px;animation:tick 90s linear infinite}
.ticker span{font-family:var(--mono);font-size:11px;color:#bbb;padding:0 22px}
.ticker span.green{color:#5fd070}.ticker span.amber{color:#e5a63a}.ticker span.red{color:#f06a6a}
@keyframes tick{from{transform:translateX(0)}to{transform:translateX(-50%)}}
.dots{display:flex;gap:5px}
.dots i{width:6px;height:6px;border-radius:50%;background:var(--border);display:block}
.dots i.on{background:var(--dark)}

/* ---------- print ---------- */
@media print{
  .sidebar,.topbar,.btn,.filters,.no-print{display:none!important}
  .main{margin-left:0}
  .page{padding:0}
  .card{border:1px solid #999;break-inside:avoid}
}

/* ---------- responsive ---------- */
@media (max-width:768px){
  .sidebar{display:none}
  .main{margin-left:0}
  .g4,.g5,.g6{grid-template-columns:repeat(2,1fr)}
  .g3,.g-2-1,.g-1-2{grid-template-columns:1fr}
  .g2{grid-template-columns:1fr}
  .page{padding:12px}
  .topbar{padding:0 12px}
}

/* adv planning: rows that cross into the next production day */
tr.row-over .a-to, tr.row-over .a-from { color: var(--red); font-weight: 600; }

/* adv actuals: the outcome column and its follow-up fields */
#advActTbl td.av-outcome { min-width: 180px; text-align: left; }
#advActTbl .av-status { width: 100%; min-width: 165px; }
#advActTbl .av-status-remark, #advActTbl .av-moved { display: block; width: 100%; min-width: 165px; }
#advActTbl tr.av-skip .av-from, #advActTbl tr.av-skip .av-to,
#advActTbl tr.av-skip .av-mins { opacity: .5; }
#advActTbl tr.av-alt .av-from, #advActTbl tr.av-alt .av-to { border-color: var(--dark); }
/* ran at another time and not yet recorded: lit until its quantity is in */
#advActTbl tr.av-alt-open td { background: #fff6e5; box-shadow: inset 3px 0 0 var(--amber); }
#advActTbl tr.av-alt-open:hover td { background: #fdefd0; }
#advActTbl tr.av-alt-open .av-outcome select { border-color: var(--amber); }

/* adv actuals: two slabs claiming the same minutes on one machine */
#advActTbl tr.av-clash .av-from, #advActTbl tr.av-clash .av-to { border-color: var(--amber); background: #fff8ec; }

/* oee lot: reason and defect pickers hold their column, remarks take the room */
#oeeLosses select, #oeeDefects select { width: 100%; max-width: 300px; }
#oeeLosses input[name="l_remarks[]"], #oeeDefects input[name="d_remarks[]"] { width: 100%; }

/* client branding: the logo heads the menu inside a fixed box */
/* The client logo is centred in the rail and the block is exactly as tall as
   the top bar, so the sidebar rule and the top-bar rule continue each other
   across the edge — that alignment is why .brand carries a fixed height. */
.brand-client{align-items:center;justify-content:center;height:64px;flex:0 0 64px;padding:8px 14px}
/* any shape fits: a tall mark runs out of height first, a wide wordmark of
   width, and contain scales whichever comes first — never cropped or stretched */
.brand-client img{display:block;max-width:172px;max-height:48px;width:auto;height:auto;object-fit:contain}
/* the maker's mark: present, never loud */
.kredo-foot{padding:18px 0 10px;text-align:center;font-size:10px;letter-spacing:.4px;color:var(--muted);opacity:.75}

/* floor display: the OEE screen's headline figures */
.floor-kpis{display:grid;grid-template-columns:repeat(6,1fr);gap:10px;margin-bottom:14px}
.floor-kpis .fkpi{background:#fff;border:1px solid var(--border);border-left:3px solid var(--dark);padding:10px 14px}
.floor-kpis .fkpi.green{border-left-color:var(--green)}
.floor-kpis .fkpi.amber{border-left-color:var(--amber)}
.floor-kpis .fkpi.red{border-left-color:var(--red)}
.floor-kpis .fkpi .lbl{font-size:9px;letter-spacing:.6px;color:var(--muted);text-transform:uppercase}
.floor-kpis .fkpi .val{font-family:var(--mono);font-size:26px;line-height:1.2}
@media (max-width:1200px){.floor-kpis{grid-template-columns:repeat(3,1fr)}}

/* KPI strip: as many equal columns as there are cards, always one row */
.kpi-row{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:10px}
.kpi-row .kpi{min-width:0}
.kpi-row .kpi .val{font-size:20px}
.kpi-row .kpi .sub{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@media (max-width:1400px){.kpi-row .kpi .val{font-size:18px}.kpi-row .kpi .sub{font-size:9px}}
@media (max-width:1100px){.kpi-row{grid-auto-flow:row;grid-template-columns:repeat(3,1fr)}}
@media (max-width:768px){.kpi-row{grid-template-columns:repeat(2,1fr)}}

/* floor display: client mark in the header, maker's mark by the ticker */
.floor-logo{height:30px;max-width:160px;object-fit:contain;display:block}
/* the maker's mark keeps its own strip at the end of the ticker bar, so the
   scrolling text can never run over it */
.floor-kredo{position:fixed;right:0;bottom:0;width:320px;height:30px;line-height:30px;background:#1a1a1a;color:#bbb;
  font-family:var(--mono);font-size:11px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-left:1px solid #333;z-index:5}

/* floor display: charts fill the wall, labels stay legible from a distance */
.floor .chart.tall{height:calc(100vh - 320px);min-height:320px}
.floor .chart.xtall{height:100%;min-height:0}
.floor .card-head{font-size:13px;padding:7px 12px;flex:0 0 auto}
.floor .tbl td,.floor .tbl th{font-size:14px}
.floor .dots i.hidden{display:none}

/* the sheet's own Excel controls */
.xl-tools{display:inline-flex;align-items:center;gap:6px}
.xl-menu{position:relative;display:inline-block}
/* The card clips its own overflow, so an absolutely positioned menu inside a
   card header is cut off. Fixed positioning escapes that; the script places it
   under its button. */
.xl-drop{position:fixed;background:#fff;border:1px solid var(--border);box-shadow:0 2px 6px rgba(0,0,0,.14);
  min-width:230px;z-index:900;display:flex;flex-direction:column}
.xl-drop a{padding:7px 10px;font-size:11px;color:var(--dark);text-decoration:none;border-bottom:1px solid var(--border)}
.xl-drop a:last-child{border-bottom:0}
.xl-drop a:hover{background:#f0f0f0}

/* a slab carried in from a day that could not finish it */
#advPlanTbl tr.row-carried td, tr.row-carried td{background:#fffdf5}
tr.row-carried input[readonly]{background:#f7f7f7;color:#555}

/* floor display: a banner that explains a stall without hiding the figures */
.floor-note{position:fixed;left:0;right:320px;bottom:30px;padding:7px 18px;background:#fff6e5;
  border-top:1px solid #e2c98d;font-size:14px;letter-spacing:.3px;color:#7a5a12;z-index:40}
.floor-note.bad{background:#fdecec;border-top-color:#e6a9a9;color:#8c2f2f}

/* floor: per-process slides and honest empty states */
.floor .proc-slide{grid-template-columns:1.3fr 1fr 1fr}
.floor .slide.hidden-slide{display:none!important}
.floor .faded{opacity:.25}
.floor-empty{position:absolute;left:0;right:0;top:40%;text-align:center;font-family:'JetBrains Mono',monospace;
  font-size:30px;letter-spacing:1px;color:var(--muted)}
.floor-none{display:flex;align-items:center;justify-content:center;height:100%;color:var(--muted);
  font-family:'JetBrains Mono',monospace;font-size:20px}
.floor .slide{position:relative}

/* floor: the totals that belong beside a chart title, and verdict colours */
.floor .card-head .floor-kpis{display:inline-flex;gap:22px;margin-left:auto;text-transform:none;letter-spacing:0}
.floor-kpi{font-family:'JetBrains Mono',monospace;font-size:22px;font-weight:700;color:var(--dark)}
.floor-kpi em{display:block;font-style:normal;font-size:10px;letter-spacing:1px;text-transform:uppercase;color:var(--muted);font-weight:500}
.floor-kpi.g{color:var(--green)}.floor-kpi.a{color:var(--amber)}.floor-kpi.r{color:var(--red)}

.floor .card-head .floor-headnote{margin-left:14px;text-transform:none;letter-spacing:0;font-weight:500;color:var(--muted)}

/* floor: a line's own screen — four small charts under one heading */
.line-slide{height:100%;display:flex;flex-direction:column}
.line-head{display:flex;align-items:center;justify-content:space-between;padding:4px 12px 8px;font-family:'JetBrains Mono',monospace;
  font-size:15px;font-weight:700;letter-spacing:1px;text-transform:uppercase;color:var(--dark)}
.line-head .floor-kpis{display:inline-flex;gap:18px}
.line-head .floor-kpi{font-size:18px}
.line-grid{flex:1 1 auto;min-height:0;display:grid;grid-template-columns:1fr 1fr 1fr;grid-template-rows:1.15fr 1fr;gap:10px}
.line-grid .card.span3{grid-column:1 / -1}
.line-grid .card-head{font-size:11px;padding:5px 10px}
.line-grid .floor-none{font-size:14px}
.line-grid .card{display:flex;flex-direction:column;min-height:0;margin:0}
.line-grid .card-body{flex:1 1 auto;min-height:0;padding:6px 8px}
.line-grid .chart{height:100%;min-height:0}

/* floor: where the rotation is, when there are too many screens for dots */
.floor-pos{display:inline-flex;align-items:center;gap:8px;font-size:11px;color:var(--muted);white-space:nowrap}
.floor-pos-bar{display:inline-block;width:120px;height:4px;background:#e0e0e0;position:relative}
.floor-pos-bar i{position:absolute;left:0;top:0;bottom:0;background:var(--dark);width:0;transition:width .3s}

/* floor: the headline strip across a screen's heading */
.line-head{align-items:flex-end;gap:16px}
.line-title{flex:0 0 auto;white-space:nowrap;padding-bottom:6px}
.floor-tiles{display:flex;gap:8px;margin-left:auto;flex-wrap:nowrap}
.floor-tile{display:flex;flex-direction:column;min-width:128px;padding:5px 10px;background:#fff;border:1px solid var(--border);
  border-left:3px solid var(--border);text-transform:none;letter-spacing:0;font-weight:500}
.floor-tile em{font-style:normal;font-size:9px;letter-spacing:1px;text-transform:uppercase;color:var(--muted)}
.floor-tile b{font-family:'JetBrains Mono',monospace;font-size:20px;line-height:1.15;color:var(--dark)}
.floor-tile i{font-style:normal;font-size:10px;color:var(--muted);letter-spacing:.2px}
.floor-tile.g{border-left-color:var(--green)}.floor-tile.g b{color:var(--green)}
.floor-tile.a{border-left-color:var(--amber)}.floor-tile.a b{color:var(--amber)}
.floor-tile.r{border-left-color:var(--red)}.floor-tile.r b{color:var(--red)}
.line-grid.shift-grid{grid-template-rows:1fr}

/* actuals sheet: a slab whose actual duration differs from its plan */
.tbl tr.row-timeoff td{background:#fff6e5}
.tbl tr.row-timeoff:hover td{background:#fdefd0}
.tbl td.av-mins.timeoff-over{color:var(--red);font-weight:600}
.tbl td.av-mins.timeoff-under{color:var(--amber);font-weight:600}

/* SPC data grid: the subgroup number sits over its own column of boxes, and
   the SL NO. column stays put while a wide study scrolls sideways */
.spc-grid th.c, .spc-grid td.c { text-align:center }
.spc-grid th:first-child, .spc-grid td:first-child { position:sticky; left:0; z-index:2; background:#fff }
.spc-grid thead th:first-child { background:#1a1a1a }
