/* VCAST Aluminium Casting Set 3 - SCADA
   Dark control room theme, tuned for a wall screen at 2-3 m distance. */

:root {
  --bg:        #0b0f17;
  --bg-2:      #121826;
  --panel:     #151c2b;
  --panel-2:   #1b2436;
  --line:      #26314a;
  --line-2:    #33415f;

  --txt:       #e6ecf7;
  --txt-dim:   #93a1bd;
  --txt-faint: #62708c;

  --accent:    #38bdf8;
  --accent-2:  #2563eb;

  --run:       #22c55e;
  --wait:      #f59e0b;
  --idle:      #475569;
  --alarm:     #ef4444;
  --crit:      #dc2626;
  --warn:      #f59e0b;
  --info:      #38bdf8;
  --part:      #f97316;
  --heat:      #fb7185;
  --cool:      #38bdf8;

  --r:  8px;
  --r2: 5px;
  --mono: "Cascadia Mono", "Consolas", "SF Mono", ui-monospace, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  background: var(--bg);
  color: var(--txt);
  font: 14px/1.45 "Segoe UI", Roboto, system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* ---------------- top bar ---------------- */
.topbar {
  display: flex; align-items: center; gap: 20px;
  padding: 0 16px; height: 54px;
  background: var(--bg-2);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 40;
}
@media (max-width: 1400px) {
  .topbar { gap: 12px; }
  .line-name { display: none; }
  .tab { padding: 8px 10px; font-size: 12.5px; }
}
.brand { display: flex; align-items: center; gap: 9px; }
.logo {
  width: 32px; height: 32px; border-radius: 7px;
  background: linear-gradient(135deg, #22d3ee, #2563eb);
  color: #06121f; font-weight: 800; font-size: 15px;
  display: grid; place-items: center; letter-spacing: -1px;
}
.brand-txt { display: flex; flex-direction: column; line-height: 1.05; }
.brand-txt strong { font-size: 13px; letter-spacing: .5px; }
.brand-txt span { font-size: 8.5px; letter-spacing: 2.6px; color: var(--txt-faint); }

.line-id { display: flex; align-items: center; gap: 9px; }
.chip {
  font-size: 11px; font-weight: 700; padding: 3px 8px;
  border-radius: var(--r2); background: var(--accent-2); color: #fff;
}
.line-name { font-size: 13px; color: var(--txt-dim); white-space: nowrap; }

/* min-width:0 is what lets this shrink at all: a flex item defaults to
   min-width:auto, so eight tabs that need 667 px push the whole bar - and
   the page with it - wider than the screen instead of scrolling.  With this
   the row is identical when there is room and scrolls when there is not, at
   any width, with no breakpoint to guess. */
.tabs {
  display: flex; gap: 2px; margin-left: auto;
  min-width: 0; flex-wrap: nowrap;
  overflow-x: auto; scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  background: transparent; border: 0; color: var(--txt-dim);
  padding: 8px 14px; border-radius: var(--r2); cursor: pointer;
  font-size: 13px; font-family: inherit; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 7px;
}
.tab:hover { background: var(--panel-2); color: var(--txt); }
.tab.active { background: var(--accent-2); color: #fff; font-weight: 600; }
.tab-badge {
  min-width: 18px; padding: 0 5px; height: 17px; border-radius: 9px;
  background: var(--alarm); color: #fff; font-size: 11px; font-weight: 700;
  display: grid; place-items: center;
}
.tab-badge.zero { background: var(--line-2); color: var(--txt-faint); }

.topright { display: flex; align-items: center; gap: 14px; margin-left: 8px; }
.conn { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--txt-dim); }
.conn .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--idle); display: inline-block;
}
.conn.ok  .dot { background: var(--run); box-shadow: 0 0 0 3px rgba(34,197,94,.18); }
.conn.bad .dot { background: var(--alarm); box-shadow: 0 0 0 3px rgba(239,68,68,.18); }
.clock { font-family: var(--mono); font-size: 13px; color: var(--txt-dim); }

/* ---------------- status strip ---------------- */
.statusstrip {
  display: flex; align-items: stretch; gap: 1px; flex-wrap: wrap;
  background: var(--line); border-bottom: 1px solid var(--line);
  position: sticky; top: 54px; z-index: 35;
}
.kpi {
  background: var(--bg-2); padding: 7px 16px; min-width: 118px;
  display: flex; flex-direction: column; justify-content: center;
}
.kpi label { font-size: 10px; text-transform: uppercase; letter-spacing: .8px; color: var(--txt-faint); }
.kpi b { font-size: 19px; font-weight: 650; font-family: var(--mono); line-height: 1.15; }
.kpi small { font-size: 10.5px; color: var(--txt-faint); }
.kpi.alarmkpi b { color: var(--alarm); }
.kpi.alarmkpi.clear b { color: var(--run); }
.statusstrip .spacer { flex: 1; background: var(--bg-2); }
.cmds { background: var(--bg-2); display: flex; align-items: center; gap: 7px; padding: 0 14px; }

.btn {
  background: var(--panel-2); color: var(--txt); border: 1px solid var(--line-2);
  padding: 6px 14px; border-radius: var(--r2); cursor: pointer;
  font: 600 12px/1 inherit; letter-spacing: .4px;
}
.btn:hover { border-color: var(--accent); color: #fff; }
.btn:active { transform: translateY(1px); }
.btn-sm { padding: 5px 10px; font-size: 11.5px; }
.btn-run  { background: #14532d; border-color: #166534; }
.btn-run:hover { background: #166534; border-color: var(--run); }
.btn-stop { background: #4c1d1d; border-color: #7f1d1d; }
.btn-stop:hover { background: #7f1d1d; border-color: var(--alarm); }

/* ---------------- layout ---------------- */
main { padding: 14px; }
.view { display: none; }
.view.active { display: block; }

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  margin-bottom: 14px;
  overflow: hidden;
}
.panel-hd {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 10px 14px; border-bottom: 1px solid var(--line);
  background: var(--panel-2);
}
.panel-hd h2 { margin: 0; font-size: 13px; font-weight: 650; letter-spacing: .3px; }
.hint { font-size: 11.5px; color: var(--txt-faint); font-weight: 400; }

.cols2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 1100px) { .cols2 { grid-template-columns: 1fr; } }

.grid-overview { display: grid; grid-template-columns: minmax(0,1fr) 340px; gap: 14px; }
@media (max-width: 1250px) { .grid-overview { grid-template-columns: 1fr; } }
.side .panel:last-child { margin-bottom: 0; }

/* ---------------- mimic ---------------- */
.mimic-panel { margin-bottom: 0; }
.mimic-wrap { padding: 10px; overflow-x: auto; }
#mimic svg { display: block; width: 100%; height: auto; min-width: 860px; }

.legend {
  display: flex; gap: 18px; flex-wrap: wrap;
  padding: 8px 14px; border-top: 1px solid var(--line);
  font-size: 11.5px; color: var(--txt-dim); background: var(--panel-2);
}
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.lg { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.lg-run { background: var(--run); } .lg-wait { background: var(--wait); }
.lg-idle { background: var(--idle); } .lg-alarm { background: var(--alarm); }
.lg-part { background: var(--part); border-radius: 50%; }

/* mimic svg internals */
.m-area  { fill: var(--panel-2); stroke: var(--line); stroke-width: 1; rx: 8; }
.m-areatxt { fill: var(--txt-faint); font-size: 10.5px; letter-spacing: 1.6px; text-transform: uppercase; }
.m-box   { fill: var(--bg-2); stroke: var(--line-2); stroke-width: 1.2; }
.m-name  { fill: var(--txt); font-size: 11px; font-weight: 600; }
.m-sub   { fill: var(--txt-dim); font-size: 10px; font-family: var(--mono); }
.m-state { font-size: 9.5px; font-weight: 700; letter-spacing: .4px; }
.m-flow  { stroke: var(--line-2); stroke-width: 2; fill: none; }
.m-flow.act { stroke: var(--accent); stroke-dasharray: 6 5; animation: flow 1s linear infinite; }
@keyframes flow { to { stroke-dashoffset: -11; } }
.m-led   { stroke: rgba(0,0,0,.4); stroke-width: .8; }
.m-part  { fill: var(--part); }
.blink   { animation: blink 1s steps(2, start) infinite; }
@keyframes blink { 50% { opacity: .25; } }

/* ---------------- 3D view ---------------- */
.view3d-panel { margin-bottom: 0; }
.ctl3d { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.viewbtns { display: inline-flex; gap: 4px; }

.stage3d { display: grid; grid-template-columns: minmax(0,1fr) 290px; gap: 1px; background: var(--line); }
@media (max-width: 1000px) { .stage3d { grid-template-columns: 1fr; } }

.canvaswrap { position: relative; background: #dce8f5; min-height: 460px; }
#canvas3d { display: block; width: 100%; height: 62vh; min-height: 460px; }
#canvas3d.stale { filter: grayscale(1) brightness(.7); }

.labels3d { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.lbl3d {
  position: absolute; top: 0; left: 0;
  background: rgba(11,15,23,.86); border: 1px solid var(--c, #475569);
  border-radius: 6px; padding: 3px 8px; white-space: nowrap;
  font-size: 11px; line-height: 1.35; color: var(--txt);
  box-shadow: 0 2px 10px rgba(0,0,0,.35);
}
.lbl3d b { display: block; font-size: 11px; font-weight: 650; }
.lbl3d span { display: block; font-family: var(--mono); font-size: 10.5px; color: var(--c, #93a1bd); }
.lbl3d.alarm { animation: devblink 1s steps(2, start) infinite; }
.lbl3d.sel { outline: 2px solid var(--accent); outline-offset: 1px; }

.hint3d {
  position: absolute; left: 12px; bottom: 10px;
  background: rgba(11,15,23,.7); color: var(--txt-dim);
  font-size: 11px; padding: 4px 9px; border-radius: 5px; pointer-events: none;
}

.sel3d { background: var(--panel); padding: 12px; overflow-y: auto; max-height: 62vh; }
.sel3d h3 { margin: 0 0 9px; font-size: 13px; font-weight: 650; color: var(--accent); }
.sel3d .rowset { grid-template-columns: 1fr; }

/* ---------------- plant layout view ---------------- */
.plantpanel { margin-bottom: 0; }
.plantwrap { padding: 10px 12px; overflow-x: auto; background: #0a0e15; }
.plantsvg { display: block; width: 100%; height: auto; min-width: 1000px; }
.plantsvg.stale { opacity: .38; filter: grayscale(1); }

.pv-area      { fill: #101725; stroke: var(--line); stroke-width: 2; }
.pv-arealabel { fill: #55648a; font-size: 26px; letter-spacing: 4px; font-weight: 600; }
.pv-name      { fill: var(--txt); font-size: 25px; font-weight: 600; }
.pv-state     { fill: var(--txt-dim); font-size: 23px; font-weight: 700; letter-spacing: .6px; }
.pv-sub       { fill: var(--txt-dim); font-size: 22px; font-family: var(--mono); }
.pv-big       { fill: var(--txt); font-size: 34px; font-weight: 650; font-family: var(--mono); }

.pv-box       { fill: #172032; stroke: var(--line-2); stroke-width: 2.5; }
.pv-fixture   { fill: #0e1522; stroke: #3a4a6b; stroke-width: 2; }
.pv-barbg     { fill: #070b12; }
.pv-led       { stroke: rgba(0,0,0,.45); stroke-width: 1.5; }

.pv-ctx rect  { fill: #131a28; stroke: #232e45; stroke-width: 2; }
.pv-ctx:hover rect { fill: #1b2436; stroke: var(--line-2); }

.pv-flowarrow { stroke: #33415f; stroke-width: 3; fill: none; stroke-linecap: round; }
.pv-flowtxt   { fill: #55648a; font-size: 22px; letter-spacing: 1.5px; }

/* furnaces */
.pv-shell     { fill: #241a1a; stroke: #7f3d3d; stroke-width: 3; }
.pv-crucible  { fill: #120d0d; stroke: #4a2a2a; stroke-width: 2; }
.pv-heat      { fill: none; stroke: #f97316; stroke-width: 6; }
.pv-heat.pulsing { animation: heatpulse 2.2s ease-in-out infinite; }
@keyframes heatpulse { 50% { stroke-width: 12; opacity: .28; } }
.pv-lid       { fill: none; stroke: #8b98b5; stroke-width: 12; stroke-linecap: round;
                transition: transform .8s ease, opacity .8s ease; }

/* GBF */
.pv-rail      { stroke: #2c3853; stroke-width: 7; stroke-linecap: round; }
.pv-rotor     { fill: #0e1522; stroke: #4a5b80; stroke-width: 2.5; }
.pv-rotorbar  { stroke: #7d8db3; stroke-width: 3.5; stroke-linecap: round; }
.pv-bubble    { fill: #38bdf8; animation: bub 1.1s ease-in-out infinite; }
@keyframes bub { 50% { opacity: .25; r: 6; } }

/* casting machines */
.pv-mould     { fill: #12324a; stroke: #2b6f96; stroke-width: 3; }
.pv-cavity    { fill: #0b1c2b; stroke: #1e5578; stroke-width: 2; }

/* conveyors */
.pv-belt      { fill: #131c2c; stroke: #3a4a6b; stroke-width: 2.5; }
.pv-slat      { stroke: #2b3852; stroke-width: 3; }

/* cooling fans */
.pv-fanring   { fill: rgba(11,15,23,.55); stroke: #3a4a6b; stroke-width: 2.5; }
.pv-blade     { fill: #4a5b80; }
.pv-fan.off .pv-blade { fill: #2a3550; }

.pv-sand      { fill: #b08050; }
.pv-spindle   { fill: #0e1522; stroke: #6b7da3; stroke-width: 2.5; }
.pv-door      { fill: rgba(239,68,68,.10); stroke: var(--alarm); stroke-width: 3;
                stroke-dasharray: 10 7; }
.pv-basket    { fill: #131c2c; stroke: #4a5b80; stroke-width: 2.5; }
.pv-mesh      { stroke: #2b3852; stroke-width: 2; }

/* robots */
.pv-envelope  { fill: rgba(56,189,248,.028); stroke: #253352; stroke-width: 2;
                stroke-dasharray: 12 12; }
.pv-robotbase { fill: #1b2436; stroke: #5b6d94; stroke-width: 3; }
.pv-upperarm  { stroke: #d4a017; stroke-width: 20; stroke-linecap: round; }
.pv-forearm   { stroke: #e5b52c; stroke-width: 15; stroke-linecap: round; }
.pv-joint     { fill: #2a3550; stroke: #8b98b5; stroke-width: 2.5; }
.pv-jaw       { fill: #9aa8c6; transition: y .25s ease; }
.pv-ladle     { fill: #6b7da3; stroke: #9aa8c6; stroke-width: 2; }
.pv-ladlemelt { fill: #f97316; }
.pv-pour      { stroke: #fb923c; stroke-width: 7; fill: none; stroke-linecap: round;
                stroke-dasharray: 14 9; animation: pourflow .5s linear infinite; }
@keyframes pourflow { to { stroke-dashoffset: -23; } }

.pv-dev.alarming { animation: devblink 1s steps(2, start) infinite; }
@keyframes devblink { 50% { opacity: .45; } }

@media (max-width: 900px) {
  .pv-name, .pv-state, .pv-sub, .pv-arealabel { font-size: 30px; }
}

/* ---------------- robot list / cycle bars ---------------- */
.robotlist { padding: 6px; }
.robotrow {
  display: grid; grid-template-columns: 84px 1fr auto;
  align-items: center; gap: 10px;
  padding: 8px 9px; border-radius: var(--r2);
}
.robotrow + .robotrow { margin-top: 3px; }
.robotrow .rname { font-size: 12px; font-weight: 600; color: var(--accent); }
.robotrow .rstep { font-size: 12px; color: var(--txt); font-family: var(--mono); }
.robotrow .rsub  { font-size: 10.5px; color: var(--txt-faint); }
.pill {
  font-size: 10px; font-weight: 700; padding: 3px 8px; border-radius: 20px;
  letter-spacing: .4px; white-space: nowrap;
}
.pill-run   { background: rgba(34,197,94,.16);  color: var(--run); }
.pill-wait  { background: rgba(245,158,11,.16); color: var(--wait); }
.pill-idle  { background: rgba(71,85,105,.35);  color: var(--txt-dim); }
.pill-alarm { background: rgba(239,68,68,.18);  color: var(--alarm); }

.cyclebars { padding: 10px 12px; }
.cbar { margin-bottom: 11px; }
.cbar:last-child { margin-bottom: 2px; }
.cbar-hd { display: flex; justify-content: space-between; font-size: 11.5px; margin-bottom: 4px; }
.cbar-hd b { font-family: var(--mono); font-weight: 600; }
.cbar-hd span { color: var(--txt-dim); }
.cbar-track { height: 7px; border-radius: 4px; background: var(--bg); overflow: hidden; }
.cbar-fill { height: 100%; border-radius: 4px; transition: width .3s linear; }

.statgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line); }
.statgrid .st { background: var(--panel); padding: 9px 12px; }
.statgrid .st label { display: block; font-size: 10px; text-transform: uppercase;
  letter-spacing: .7px; color: var(--txt-faint); }
.statgrid .st b { font-size: 17px; font-family: var(--mono); font-weight: 600; }
.statgrid .st small { font-size: 10.5px; color: var(--txt-faint); }

.ovalarms { padding: 4px 0; }
.ovalarm {
  display: grid; grid-template-columns: 74px 78px 1fr 150px 64px;
  align-items: center; gap: 12px;
  padding: 8px 14px; border-bottom: 1px solid var(--line); font-size: 12.5px;
}
.ovalarm:last-child { border-bottom: 0; }
.ovalarm.acked { opacity: .62; }
.ovalarm .t  { color: var(--txt-dim); font-size: 11.5px; }
.ovalarm .tg { color: var(--txt-faint); font-size: 11.5px; }
.ovalarm .msg { font-weight: 500; }
@media (max-width: 900px) {
  .ovalarm { grid-template-columns: 70px 1fr 60px; }
  .ovalarm .t, .ovalarm .tg { display: none; }
}

/* ---------------- gauges ---------------- */
.gaugerow { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px; }
.gaugegroup {
  flex: 1 1 300px; border: 1px solid var(--line); border-radius: var(--r);
  padding: 9px 10px 4px; background: var(--panel-2);
}
.gaugegroup h4 {
  margin: 0 0 6px; font-size: 11.5px; font-weight: 600; color: var(--accent);
  display: flex; justify-content: space-between;
}
.gaugegroup h4 em { font-style: normal; font-size: 10.5px; color: var(--txt-faint); font-family: var(--mono); }
.gauges { display: flex; gap: 4px; justify-content: space-between; }
.gauge { text-align: center; flex: 1; }
.gauge svg { display: block; margin: 0 auto; }
.gauge .gv { font-family: var(--mono); font-size: 13px; font-weight: 600; }
.gauge .gl { font-size: 9.5px; color: var(--txt-faint); display: block; margin-top: -2px; }

/* ---------------- equipment cards ---------------- */
.cardrow { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line); }
.cardrow > * { background: var(--panel); }
@media (max-width: 700px) { .cardrow { grid-template-columns: 1fr; } }

.eq { padding: 11px 13px; }
.eq-hd { display: flex; align-items: center; justify-content: space-between; margin-bottom: 9px; }
.eq-hd h3 { margin: 0; font-size: 13px; font-weight: 650; }
.eq-state { font-size: 11px; color: var(--txt-dim); font-family: var(--mono); margin-top: 1px; }

.rowset { display: grid; grid-template-columns: 1fr 1fr; gap: 1px 1px; background: var(--line); border-radius: var(--r2); overflow: hidden; }
.rowset .f { background: var(--panel-2); padding: 6px 9px; display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.rowset .f label { font-size: 11px; color: var(--txt-dim); }
.rowset .f b { font-family: var(--mono); font-size: 12.5px; font-weight: 600; white-space: nowrap; }
.rowset .f b u { text-decoration: none; font-size: 10px; color: var(--txt-faint); margin-left: 2px; }
.rowset .f.wide { grid-column: 1 / -1; }
.rowset .f.hi b { color: var(--warn); }
.rowset .f.crit b { color: var(--alarm); }

.bits { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 9px; }
.bit {
  font-size: 10.5px; padding: 3px 8px; border-radius: 20px;
  background: var(--bg); color: var(--txt-faint); border: 1px solid var(--line);
}
.bit.on { background: rgba(34,197,94,.14); color: var(--run); border-color: rgba(34,197,94,.35); }
.bit.warn { background: rgba(245,158,11,.14); color: var(--wait); border-color: rgba(245,158,11,.35); }
.bit.bad { background: rgba(239,68,68,.14); color: var(--alarm); border-color: rgba(239,68,68,.4); }

.progress { margin-top: 10px; }
.progress .cbar-track { height: 9px; }

/* ---------------- tables ---------------- */
.tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.tbl thead th {
  text-align: left; padding: 8px 12px; font-size: 10.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .7px; color: var(--txt-faint);
  background: var(--panel-2); border-bottom: 1px solid var(--line);
  position: sticky; top: 0;
}
.tbl tbody td { padding: 7px 12px; border-bottom: 1px solid var(--line); }
.tbl tbody tr:hover { background: var(--panel-2); }
.tbl .mono { font-family: var(--mono); }
.tbl-tags tbody td:first-child { font-family: var(--mono); color: var(--accent); }
.empty { padding: 22px; text-align: center; color: var(--txt-faint); font-size: 13px; }

.pri { font-weight: 700; font-size: 11px; letter-spacing: .5px; }
.pri-critical { color: var(--crit); } .pri-high { color: var(--alarm); }
.pri-warning  { color: var(--warn); } .pri-info { color: var(--info); }
tr.acked { opacity: .62; }
tr.cleared td:nth-child(4) { text-decoration: line-through; }

#tagSearch, #trendSearch, select {
  background: var(--bg); border: 1px solid var(--line-2); color: var(--txt);
  padding: 6px 10px; border-radius: var(--r2); font: 12.5px inherit; font-family: inherit;
}
#tagSearch { min-width: 300px; }
select:focus, input:focus { outline: 1px solid var(--accent); }

/* ---------------- trends ---------------- */
.trendctl { display: flex; align-items: center; gap: 8px; }
.live { font-size: 11.5px; color: var(--txt-dim); display: flex; align-items: center; gap: 5px; }
.trendlayout { display: grid; grid-template-columns: 250px 1fr; gap: 1px; background: var(--line); }
@media (max-width: 900px) { .trendlayout { grid-template-columns: 1fr; } }
.trendpicker { background: var(--panel); padding: 10px; max-height: 520px; overflow-y: auto; }
.trendpicker input { width: 100%; margin-bottom: 8px; }
.trendpicker .tgroup { font-size: 10px; text-transform: uppercase; letter-spacing: .8px;
  color: var(--txt-faint); margin: 10px 0 4px; }
.trendpicker label {
  display: flex; align-items: center; gap: 7px; padding: 4px 6px;
  border-radius: var(--r2); font-size: 12px; cursor: pointer;
}
.trendpicker label:hover { background: var(--panel-2); }
.trendchart { background: var(--panel); padding: 12px; }
#chart { width: 100%; height: 440px; display: block; }
.chartlegend { display: flex; flex-wrap: wrap; gap: 14px; padding-top: 10px; font-size: 11.5px; }
.chartlegend span { display: inline-flex; align-items: center; gap: 6px; color: var(--txt-dim); }
.chartlegend i { width: 12px; height: 3px; border-radius: 2px; }

/* ---------------- simulator panel ---------------- */
.simpanel { position: fixed; right: 0; bottom: 0; z-index: 50; display: flex; align-items: flex-end; }
.simtoggle {
  background: var(--wait); color: #201400; border: 0; cursor: pointer;
  font: 700 11px/1 inherit; letter-spacing: 1px; padding: 9px 8px;
  border-radius: 6px 0 0 6px; writing-mode: vertical-rl; text-orientation: mixed;
}
.simbody {
  width: 0; overflow: hidden; background: var(--panel);
  border-left: 1px solid var(--line); border-top: 1px solid var(--line);
  transition: width .18s ease;
}
.simpanel.open .simbody { width: 268px; padding: 12px 14px; max-height: 74vh; overflow-y: auto; }
.simbody h3 { margin: 0 0 6px; font-size: 13px; }
.simbody h4 { margin: 12px 0 6px; font-size: 11px; color: var(--txt-faint);
  text-transform: uppercase; letter-spacing: .8px; }
.simnote { font-size: 11px; color: var(--txt-dim); margin: 0 0 10px; line-height: 1.5; }
.simnote code { background: var(--bg); padding: 1px 4px; border-radius: 3px;
  font-family: var(--mono); font-size: 10.5px; color: var(--accent); }
.simrow { display: flex; justify-content: space-between; align-items: center;
  font-size: 12px; color: var(--txt-dim); gap: 8px; }
.simrow select { flex: 1; }
.simfaults { display: flex; flex-direction: column; gap: 4px; }
.simfaults button {
  text-align: left; background: var(--bg); border: 1px solid var(--line);
  color: var(--txt-dim); padding: 6px 9px; border-radius: var(--r2);
  cursor: pointer; font: 11.5px inherit; font-family: inherit;
}
.simfaults button:hover { border-color: var(--line-2); color: var(--txt); }
.simfaults button.on { background: rgba(239,68,68,.16); border-color: var(--alarm); color: #fca5a5; }

/* ---------------- toast ---------------- */
.toast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%) translateY(20px);
  background: var(--panel-2); border: 1px solid var(--line-2); color: var(--txt);
  padding: 10px 18px; border-radius: var(--r); font-size: 12.5px;
  opacity: 0; pointer-events: none; transition: all .2s ease; z-index: 60;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.err { border-color: var(--alarm); color: #fca5a5; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 5px; }
::-webkit-scrollbar-thumb:hover { background: #46567c; }

/* ---- data source switch (SIM / PLC) ----------------------------------- */
.srcswitch {
  display: flex;
  border: 1px solid var(--line, #2c3a4d);
  border-radius: 5px;
  overflow: hidden;
  font: 600 11px/1 system-ui, sans-serif;
  letter-spacing: .06em;
}
.srcswitch button {
  background: transparent;
  color: var(--dim, #7d8ea3);
  border: 0;
  padding: 6px 11px;
  cursor: pointer;
}
.srcswitch button:hover { color: #fff; }
.srcswitch button.on { background: #2c7be5; color: #fff; cursor: default; }
.srcswitch button[data-driver="plc"].on { background: #1f9d55; }

/* ---- read-only lockout on a real PLC ---------------------------------- */
.cmds.locked .btn { opacity: .35; cursor: not-allowed; }
.rolock {
  align-self: center;
  margin-right: 10px;
  padding: 3px 9px;
  border: 1px solid #6b5a1f;
  border-radius: 4px;
  background: #2a2410;
  color: #d7b74a;
  font: 600 11px/1.5 system-ui, sans-serif;
  white-space: nowrap;
}

/* ---- tag list source column ------------------------------------------- */
.srcpill {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 9px;
  font: 600 10px/1.6 system-ui, sans-serif;
  letter-spacing: .04em;
}
.src-plc  { background: #133a22; color: #57c98a; }
.src-calc { background: #16283f; color: #6ea8e0; }
.src-none { background: #3a2313; color: #d99a5b; }
.src-rw   { background: #2a2410; color: #d7b74a; margin-left: 4px; }
.tbl-tags .tagval.badq { color: #6b7a8d; font-style: italic; }

/* ---------------- wide tables ---------------- */
/* .panel is overflow:hidden for its rounded corners, so a table wider than
   the panel is clipped rather than scrolled.  The wrapper gives it its own
   scrollport - on a phone the tag list is 8 columns wide and has to move
   sideways somewhere. */
.tblwrap { overflow-x: auto; }
.tbl { min-width: 560px; }
.tbl-tags { min-width: 760px; }

/* ---------------- narrow: the top bar stops being one row ---------------- */
/* Eight tabs in a flex row are 667 px on their own, and with the brand and
   the status block beside them the bar needs about 1000 px.  A flex row that
   cannot shrink does not scroll, it widens the page: at 375 px the document
   was 1135 px wide, so every view scrolled sideways and the fixed panels sat
   off the edge of the screen.  This is the structural half of the fix, and it
   has to start well above phone width - a tablet in portrait is 768 px and a
   phone in landscape lands here too. */
@media (max-width: 1000px) {
  .topbar {
    flex-wrap: wrap; height: auto; align-items: center;
    gap: 8px 10px; padding: 7px 10px 0;
  }
  .line-id { margin-right: auto; }
  .topright { margin-left: 0; gap: 9px; }

  .tabs {
    order: 9; width: 100%; margin: 0 -10px; padding: 2px 10px 6px;
    flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
  }
  .tabs::-webkit-scrollbar { display: none; }
  .tab {
    flex: 0 0 auto; scroll-snap-align: start;
    padding: 9px 13px; font-size: 13px; min-height: 38px;
  }

  /* the strip was pinned 54 px down, under a bar that is now two rows tall */
  .statusstrip { position: static; }
}

/* ---------------- phones ---------------- */
/* Everything below is about a screen held in one hand rather than a wall
   display read from two metres. */
@media (max-width: 760px) {
  .brand-txt span { display: none; }          /* keep FINEPRO, drop AUTOMATION */
  .clock { display: none; }                   /* the phone has its own */
  .conn span { display: none; }               /* the dot says it */

  /* the 1 px gap is part of the row: a 33.333% basis plus it overflows by a
     pixel and every tile drops onto its own line - 400 px of KPI above the
     first screen */
  .kpi { flex: 1 1 calc(33.333% - 1px); min-width: 0; padding: 6px 9px; }
  /* seven tiles three to a row leave the last one alone next to a grey gap;
     the alarm count is the one worth the whole width anyway */
  .kpi.alarmkpi { flex: 1 1 100%; }
  .kpi b { font-size: 16px; }
  .kpi label { font-size: 9.5px; letter-spacing: .5px; }
  .statusstrip .spacer { display: none; }
  .cmds { flex: 1 1 100%; justify-content: center; padding: 8px 10px; }
  /* a finger is about 9 mm; these were 32 px tall for a mouse pointer */
  .btn { padding: 11px 16px; min-height: 40px; }
  .btn-sm { padding: 9px 12px; min-height: 36px; }
  .srcswitch button { padding: 10px 13px; min-height: 36px; }
  .tab { min-height: 40px; }
  .rolock { margin: 0 0 6px; flex: 1 1 100%; text-align: center; }

  main { padding: 10px; }
  .panel-hd { flex-wrap: wrap; gap: 6px 12px; padding: 9px 12px; }
  .panel-hd .hint { flex-basis: 100%; }
  #tagSearch, #trendSearch { min-width: 0; width: 100%; }

  .gaugegroup { flex: 1 1 100%; }
  .rowset { grid-template-columns: 1fr; }
  .trendpicker { max-height: 240px; }
  #chart { height: 300px; }
  #canvas3d { height: 46vh; min-height: 300px; }
  .canvaswrap { min-height: 300px; }
  .sel3d { max-height: none; }
  .lbl3d { font-size: 10px; padding: 2px 6px; }
  .hint3d { display: none; }

  /* full height sheet rather than a 268 px drawer on a 375 px screen */
  .simpanel.open .simbody { width: min(80vw, 280px); max-height: 70vh; }
  .toast { left: 10px; right: 10px; bottom: 14px; transform: translateY(20px); }
  .toast.show { transform: translateY(0); }
}

@media (max-width: 420px) {
  .kpi { padding: 5px 8px; }
  .kpi b { font-size: 15px; }
  .kpi small { font-size: 9.5px; }
  .brand-txt { display: none; }
  .tab { padding: 9px 11px; }
}
