/* Fonts as separate cacheable files. Subset to the ~185 codepoints this
 * console can render: full ASCII, the punctuation actually used, plus
 * technical symbols and accented Latin-1 as headroom for units and vendor
 * strings that arrive from parsed .cff files. 49.7 KB for four faces. */
@font-face{font-family:"Plex Cond";src:url(../fonts/Plex_Cond-600.woff2) format("woff2");font-weight:600;font-display:swap;font-style:normal;}
@font-face{font-family:"Plex Cond";src:url(../fonts/Plex_Cond-700.woff2) format("woff2");font-weight:700;font-display:swap;font-style:normal;}
@font-face{font-family:"Plex Data";src:url(../fonts/Plex_Data-400.woff2) format("woff2");font-weight:400;font-display:swap;font-style:normal;}
@font-face{font-family:"Plex Data";src:url(../fonts/Plex_Data-500.woff2) format("woff2");font-weight:500;font-display:swap;font-style:normal;}

/* ===== FONTS (inlined; CSP blocks font CDNs) ============================ */


/* ===== TOKENS ==========================================================
 * Palette derived from the gateway's own materials:
 *   accent      #1C5280  YFGW410 splash-page banner blue
 *   ink         #2D4650  AppConst.IndexLineColor
 *   rule        #A0B0BF  AppConst.TargetValueLineColor
 *   ground      #F1F2F4  AppConst.PlotBackgroundColor
 * Semantic status colours are Yokogawa's — Warning #FFCC00 / Error #FF0000 —
 * and are deliberately NOT the accent. Good is the one departure:
 * Yokogawa's #00CCCC is a cyan, which reads as "info" rather than
 * "healthy". Good is green here, and Information in the Log Viewer
 * shares the Good token.
 * ====================================================================== */
:root{
  --bg:#F1F2F4; --surface:#FFFFFF; --surface-2:#F7F8F9; --surface-3:#E7EBEE;
  --sunken:#EDF0F2;
  --border:#D2D9DF; --border-strong:#A0B0BF;
  --ink:#1B2A33; --ink-2:#4A5C67; --ink-3:#7B8C97;
  --accent:#1C5280; --accent-hover:#164267; --accent-ink:#FFFFFF;
  --accent-soft:#1C528014; --accent-line:#1C528040;

  /* Yokogawa semantic status (AppConst) */
  --good:#12A150;   --good-ink:#0A6B36;   --good-soft:#12A1501F;
  --warn:#FFCC00;   --warn-ink:#7A5D00;   --warn-soft:#FFCC001F;
  --crit:#FF0000;   --crit-ink:#B00000;   --crit-soft:#FF00001A;
  --join:#99FFCC;   --join-ink:#00695C;   --join-soft:#99FFCC33;
  --idle:#DFE4E8;   --idle-ink:#6E7C86;   --idle-soft:#DFE4E866;
  --dontcare:#828282;

  --grid:#BEC8D2;
  --shadow-1:0 1px 2px rgba(27,42,51,.06), 0 1px 1px rgba(27,42,51,.04);
  --shadow-2:0 10px 30px -12px rgba(27,42,51,.28), 0 2px 8px -3px rgba(27,42,51,.14);
  --r:4px; --r-lg:6px;

  --font-display:"Plex Cond","Segoe UI Semibold",system-ui,sans-serif;
  --font-body:"Segoe UI",system-ui,-apple-system,Roboto,sans-serif;
  --font-data:"Plex Data",ui-monospace,"Cascadia Mono",Consolas,monospace;

  --rail-w:212px; --topbar-h:52px;
  color-scheme:light;
}
@media (prefers-color-scheme:dark){
  :root{
    --bg:#0E1519; --surface:#151F25; --surface-2:#1A252C; --surface-3:#23303880;
    --sunken:#101A1F;
    --border:#2A3A44; --border-strong:#3E525E;
    --ink:#E4EBEF; --ink-2:#A2B4BF; --ink-3:#6E828E;
    --accent:#5A9CC8; --accent-hover:#7BB3D8; --accent-ink:#08131A;
    --accent-soft:#5A9CC81F; --accent-line:#5A9CC855;
    --good:#3FC97B; --good-ink:#79E3A6; --good-soft:#3FC97B1F;
    --warn:#F0C14B; --warn-ink:#F5D480; --warn-soft:#F0C14B1F;
    --crit:#FF6B60; --crit-ink:#FF9188; --crit-soft:#FF6B601F;
    --join:#6FE0BC; --join-ink:#8FEBCE; --join-soft:#6FE0BC1F;
    --idle:#2E3C45; --idle-ink:#8496A1; --idle-soft:#2E3C4599;
    --dontcare:#7A8A93;
    --grid:#2A3A44;
    --shadow-1:0 1px 2px rgba(0,0,0,.4);
    --shadow-2:0 14px 34px -12px rgba(0,0,0,.7), 0 2px 10px -3px rgba(0,0,0,.5);
    color-scheme:dark;
  }
}
:root[data-theme="dark"]{
  --bg:#0E1519; --surface:#151F25; --surface-2:#1A252C; --surface-3:#23303880;
  --sunken:#101A1F;
  --border:#2A3A44; --border-strong:#3E525E;
  --ink:#E4EBEF; --ink-2:#A2B4BF; --ink-3:#6E828E;
  --accent:#5A9CC8; --accent-hover:#7BB3D8; --accent-ink:#08131A;
  --accent-soft:#5A9CC81F; --accent-line:#5A9CC855;
  --good:#3FC97B; --good-ink:#79E3A6; --good-soft:#3FC97B1F;
  --warn:#F0C14B; --warn-ink:#F5D480; --warn-soft:#F0C14B1F;
  --crit:#FF6B60; --crit-ink:#FF9188; --crit-soft:#FF6B601F;
  --join:#6FE0BC; --join-ink:#8FEBCE; --join-soft:#6FE0BC1F;
  --idle:#2E3C45; --idle-ink:#8496A1; --idle-soft:#2E3C4599;
  --dontcare:#7A8A93; --grid:#2A3A44;
  --shadow-1:0 1px 2px rgba(0,0,0,.4);
  --shadow-2:0 14px 34px -12px rgba(0,0,0,.7), 0 2px 10px -3px rgba(0,0,0,.5);
  color-scheme:dark;
}
:root[data-theme="light"]{
  --bg:#F1F2F4; --surface:#FFFFFF; --surface-2:#F7F8F9; --surface-3:#E7EBEE;
  --sunken:#EDF0F2;
  --border:#D2D9DF; --border-strong:#A0B0BF;
  --ink:#1B2A33; --ink-2:#4A5C67; --ink-3:#7B8C97;
  --accent:#1C5280; --accent-hover:#164267; --accent-ink:#FFFFFF;
  --accent-soft:#1C528014; --accent-line:#1C528040;
  --good:#12A150; --good-ink:#0A6B36; --good-soft:#12A1501F;
  --warn:#FFCC00; --warn-ink:#7A5D00; --warn-soft:#FFCC001F;
  --crit:#FF0000; --crit-ink:#B00000; --crit-soft:#FF00001A;
  --join:#99FFCC; --join-ink:#00695C; --join-soft:#99FFCC33;
  --idle:#DFE4E8; --idle-ink:#6E7C86; --idle-soft:#DFE4E866;
  --dontcare:#828282; --grid:#BEC8D2;
  --shadow-1:0 1px 2px rgba(27,42,51,.06), 0 1px 1px rgba(27,42,51,.04);
  --shadow-2:0 10px 30px -12px rgba(27,42,51,.28), 0 2px 8px -3px rgba(27,42,51,.14);
  color-scheme:light;
}

/* ===== BASE ============================================================ */
*{box-sizing:border-box;}
/* The UA stylesheet's [hidden]{display:none} loses to any author display rule,
 * so elements toggled via .hidden (rails, body row, toolbars) need this to
 * actually disappear. Must come before the component rules below. */
[hidden]{display:none!important;}
html,body{margin:0;padding:0;height:100%;}
body{
  background:var(--bg); color:var(--ink);
  font-family:var(--font-body); font-size:13.5px; line-height:1.45;
  -webkit-font-smoothing:antialiased; overflow-x:hidden;
}
h1,h2,h3,h4{margin:0; font-family:var(--font-display); font-weight:600; text-wrap:balance;}
.mono,.num,td.num,th.num,.tag,.eui,code,pre{
  font-family:var(--font-data); font-variant-numeric:tabular-nums;
}
button,input,select,textarea{font:inherit; color:inherit;}
:focus-visible{outline:2px solid var(--accent); outline-offset:1px;}
::selection{background:var(--accent-soft);}
a{color:var(--accent);}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;}
@media (prefers-reduced-motion:reduce){*{animation-duration:.001ms!important;transition-duration:.001ms!important;}}

/* ===== SHELL =========================================================== */
.shell{display:flex; flex-direction:column; height:100vh; min-height:560px;}
.topbar{
  height:var(--topbar-h); flex:none; display:flex; align-items:center; gap:16px;
  padding:0 14px; background:var(--surface);
  border-bottom:1px solid var(--border); box-shadow:var(--shadow-1); z-index:30;
}
.brand{display:flex; align-items:center; gap:9px; padding-right:14px; border-right:1px solid var(--border);}
.brand-mark{width:28px;height:28px;flex:none;color:var(--accent);}
.brand-name{font-family:var(--font-display); font-weight:700; font-size:14.5px; letter-spacing:.02em; line-height:1.1;}
.brand-sub{font-size:9.5px; color:var(--ink-3); letter-spacing:.09em; text-transform:uppercase; line-height:1.3;}

.gwid{display:flex; align-items:center; gap:9px; min-width:0;}
.gw-tag{font-family:var(--font-data); font-weight:500; font-size:13px;}
.chip{
  display:inline-flex; align-items:center; gap:5px; padding:2px 8px;
  border-radius:99px; font-size:10.5px; font-weight:600;
  letter-spacing:.05em; text-transform:uppercase; white-space:nowrap;
  font-family:var(--font-display);
}
.chip .dot{width:6px;height:6px;border-radius:50%;background:currentColor;flex:none;}
.chip.ok{background:var(--good-soft); color:var(--good-ink);}
.chip.warn{background:var(--warn-soft); color:var(--warn-ink);}
.chip.crit{background:var(--crit-soft); color:var(--crit-ink);}
.chip.idle{background:var(--idle-soft); color:var(--idle-ink);}
.chip.join{background:var(--join-soft); color:var(--join-ink);}
.chip.pulse .dot{animation:blink 1.9s ease-in-out infinite;}
@keyframes blink{0%,100%{opacity:1}50%{opacity:.3}}

.mode-pill{
  display:inline-flex; align-items:center; gap:7px; padding:4px 9px 4px 7px;
  border:1px solid var(--border-strong); border-radius:99px; background:var(--surface-2);
  cursor:pointer; font-size:11.5px; font-weight:600; font-family:var(--font-display);
  letter-spacing:.04em; text-transform:uppercase; color:var(--ink-2);
}
.mode-pill:hover{border-color:var(--accent); color:var(--accent);}
.mode-pill svg{width:13px;height:13px;}
.cfgtools{display:flex; gap:7px; align-items:center;}
.spacer{flex:1;}
.topmeta{display:flex; align-items:center; gap:14px; color:var(--ink-2); font-size:12px;}
.topmeta .clock{font-family:var(--font-data); color:var(--ink);}
.iconbtn{
  width:30px;height:30px;flex:none; display:inline-flex; align-items:center; justify-content:center;
  border:1px solid transparent; border-radius:var(--r); background:transparent;
  color:var(--ink-2); cursor:pointer;
}
.iconbtn:hover{background:var(--surface-3); color:var(--ink);}
.iconbtn svg{width:16px;height:16px;}
.iconbtn[disabled]{opacity:.45; cursor:default;}
.iconbtn.spin svg{animation:spin 900ms linear infinite;}
@keyframes spin{to{transform:rotate(360deg)}}
.userchip{display:flex;align-items:center;gap:7px;padding-left:12px;border-left:1px solid var(--border);cursor:pointer;}
.avatar{
  width:24px;height:24px;border-radius:50%;background:var(--accent);color:var(--accent-ink);
  display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;flex:none;
  font-family:var(--font-display);
}
.userchip .who{font-size:11.5px;line-height:1.2;}
.userchip .role{font-size:9.5px;color:var(--ink-3);letter-spacing:.04em;text-transform:uppercase;}

.bodyrow{flex:1; display:flex; min-height:0;}

/* ===== NAV RAIL ======================================================== */
.rail{
  width:var(--rail-w); flex:none; background:var(--surface); border-right:1px solid var(--border);
  display:flex; flex-direction:column; overflow-y:auto; padding:8px 0 0;
}
.rail-group{
  font-family:var(--font-display); font-size:9.5px; font-weight:600; color:var(--ink-3);
  letter-spacing:.11em; text-transform:uppercase; padding:12px 14px 5px;
}
.navitem{
  display:flex; align-items:center; gap:9px; padding:7px 12px 7px 14px; margin:0 6px 1px;
  border-radius:var(--r); cursor:pointer; color:var(--ink-2); font-size:13px;
  border:1px solid transparent; text-align:left; width:calc(100% - 12px); background:none;
}
.navitem:hover{background:var(--surface-3); color:var(--ink);}
.navitem.sub{padding-left:28px;}
.navitem.active{background:var(--accent-soft); color:var(--accent); border-color:var(--accent-line); font-weight:600;}
.navitem.active .navicon{color:var(--accent);}
.navicon{width:15px;height:15px;flex:none;color:var(--ink-3);}
.navtext{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.navcount{
  font-family:var(--font-data); font-size:10.5px; color:var(--ink-3);
  background:var(--surface-3); border-radius:99px; padding:1px 6px; flex:none;
}
.navitem.active .navcount{background:var(--surface); color:var(--accent);}
.navdot{width:7px;height:7px;border-radius:50%;flex:none;}
.navitem.disabled{opacity:.42; cursor:not-allowed;}
.navitem.disabled:hover{background:none;color:var(--ink-2);}
.rail-foot{margin-top:auto; padding:10px 12px; border-top:1px solid var(--border); display:flex; flex-direction:column; gap:7px;}
.rail-foot .row{display:flex; align-items:center; justify-content:space-between; gap:8px; font-size:11.5px; color:var(--ink-3);}
.seg{display:inline-flex; border:1px solid var(--border); border-radius:var(--r); overflow:hidden;}
.seg button{
  padding:3px 8px; font-size:10.5px; background:var(--surface); border:none; cursor:pointer;
  color:var(--ink-2); font-family:var(--font-display); letter-spacing:.03em;
}
.seg button+button{border-left:1px solid var(--border);}
.seg button[aria-pressed="true"]{background:var(--accent); color:var(--accent-ink); font-weight:600;}

/* ===== MAIN ============================================================ */
.main{flex:1; min-width:0; overflow-y:auto; padding:18px 20px 40px;}
.view{display:none; max-width:1500px;}
.view.active{display:block;}
.viewhead{display:flex; align-items:flex-start; gap:16px; margin-bottom:14px; flex-wrap:wrap;}
.viewhead h2{font-size:20px; letter-spacing:-.01em; line-height:1.2;}
.viewhead p{margin:3px 0 0; color:var(--ink-2); font-size:12.5px; max-width:78ch;}
/* The header actions are a mixed row — labelled selects, checkboxes and
   buttons. Without an explicit cross-axis alignment the flex default stretches
   each child to the tallest, and .checkrow's own flex-start put the label and
   its control on a different baseline from the buttons beside them. */
.viewactions{margin-left:auto; display:flex; align-items:center; gap:7px; flex-wrap:wrap;}
.viewactions>*{align-self:center;}



.btn{
  display:inline-flex; align-items:center; gap:6px; padding:6px 13px; border-radius:var(--r);
  border:1px solid var(--border-strong); background:var(--surface); color:var(--ink);
  font-size:12.5px; cursor:pointer; white-space:nowrap; font-weight:500;
}
.btn:hover{background:var(--surface-3); border-color:var(--ink-3);}
.btn svg{width:14px;height:14px;}
.btn.primary{background:var(--accent); border-color:var(--accent); color:var(--accent-ink); font-weight:600;}
.btn.primary:hover{background:var(--accent-hover); border-color:var(--accent-hover);}
.btn.danger{color:var(--crit-ink); border-color:var(--crit-soft);}
.btn.danger:hover{background:var(--crit-soft);}
.btn[disabled]{opacity:.45; cursor:not-allowed;}
.btn.sm{padding:3px 8px; font-size:11.5px;}
.btn.xs{padding:2px 7px; font-size:11px;}

/* ===== PANEL =========================================================== */
.panel{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg);
  box-shadow:var(--shadow-1); margin-bottom:14px; overflow:hidden;
}
.panel-head{
  display:flex; align-items:center; gap:12px; padding:10px 14px;
  border-bottom:1px solid var(--border); background:var(--surface-2); flex-wrap:wrap;
}
.panel-title{font-family:var(--font-display); font-weight:600; font-size:13px; letter-spacing:.01em;}
.panel-sub{font-size:11.5px; color:var(--ink-3);}
.panel-head .right{margin-left:auto; display:flex; gap:7px; align-items:center; flex-wrap:wrap;}
.panel-body{padding:14px;}
.panel-body.tight{padding:0;}

/* restart annotation — Yokogawa renders these in Color.Red */
.restart-note{
  display:flex; align-items:flex-start; gap:6px; color:var(--crit-ink);
  font-size:11.5px; margin-top:8px; font-weight:500;
}
.restart-note svg{width:13px;height:13px;flex:none;margin-top:1px;}

/* unbacked-by-this-gateway marker */
.unbacked{
  display:inline-flex; align-items:center; gap:4px; font-size:10px; font-weight:600;
  font-family:var(--font-display); letter-spacing:.04em; text-transform:uppercase;
  color:var(--warn-ink); background:var(--warn-soft); border-radius:3px; padding:1px 5px;
  vertical-align:middle;
}

/* ===== KPI ============================================================= */
.kpirow{display:grid; grid-template-columns:repeat(auto-fit,minmax(128px,1fr)); gap:10px; margin-bottom:14px;}
.kpi{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg);
  padding:10px 12px; box-shadow:var(--shadow-1); position:relative; overflow:hidden;
}
.kpi::before{content:""; position:absolute; inset:0 auto 0 0; width:3px; background:var(--border-strong);}
.kpi.good::before{background:var(--good);} .kpi.warn::before{background:var(--warn);}
.kpi.crit::before{background:var(--crit);} .kpi.join::before{background:var(--join);}
.kpi.idle::before{background:var(--idle);}
.kpi-label{font-size:10px; color:var(--ink-3); letter-spacing:.08em; text-transform:uppercase; font-family:var(--font-display); font-weight:600;}
.kpi-value{font-family:var(--font-data); font-size:24px; font-weight:500; line-height:1.15; margin-top:2px;}
.kpi-foot{font-size:11px; color:var(--ink-3); margin-top:1px;}

/* ===== TABLE =========================================================== */
.tscroll{overflow-x:auto; overflow-y:visible;}
table{width:100%; border-collapse:separate; border-spacing:0; font-size:12.5px;}
thead th{
  position:sticky; top:0; z-index:2; background:var(--surface-2);
  font-family:var(--font-display); font-weight:600; font-size:10.5px;
  letter-spacing:.06em; text-transform:uppercase; color:var(--ink-2);
  text-align:left; padding:8px 10px; white-space:nowrap;
  border-bottom:1px solid var(--border-strong);
}
thead th.num{text-align:right;}
tbody td{padding:7px 10px; border-bottom:1px solid var(--border); white-space:nowrap; vertical-align:middle;}
tbody td.num{text-align:right; font-family:var(--font-data);}
tbody td.wrap{white-space:normal; min-width:22ch;}
tbody tr:last-child td{border-bottom:none;}
tbody tr.clickable{cursor:pointer;}
tbody tr.clickable:hover td{background:var(--accent-soft);}
tbody tr.sel td{background:var(--accent-soft);}
tbody tr.zebra td{background:var(--surface-2);}
tbody tr.zebra.clickable:hover td{background:var(--accent-soft);}
/* Fixed-layout tables: a cell must not widen its column, so overlong values are
   clipped with an ellipsis rather than wrapping (which would jump row heights
   on every refresh). The full value is always in the device card. */
table.fixed th,table.fixed td{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
table.fixed td.stat{overflow:visible;}
/* a cell that is meant to wrap keeps wrapping — its column is still fixed */
table.fixed td.wrap{white-space:normal; overflow:visible; text-overflow:clip;}

/* A refresh replaces the rows in place rather than blanking the table, so the
   timestamp flashes to show that something actually happened. */
@keyframes updflash{
  0%{background:var(--accent-soft);color:var(--accent);}
  100%{background:transparent;}
}
.panel-sub.flash{animation:updflash .9s ease-out;border-radius:4px;padding:1px 5px;margin:0 -5px;}
@media (prefers-reduced-motion:reduce){.panel-sub.flash{animation:none;}}

/* Summary row: totals over the rows above it, pinned to the bottom of the table. */
tbody tr.total td{background:var(--surface-2);border-top:2px solid var(--border-strong);
  border-bottom:none;font-weight:600;}
tbody tr.total td.lbl{letter-spacing:.02em;text-transform:uppercase;font-size:11px;
  color:var(--ink-2);}
.dim{color:var(--ink-3);}
/* the "-" sentinel must read differently from a real measurement */
.nil{color:var(--ink-3); font-family:var(--font-data);}
.rangeover{color:var(--warn-ink); font-family:var(--font-data); font-size:11.5px;}
td.stat{width:26px; text-align:center; padding-right:0;}
.empty{padding:34px 14px; text-align:center; color:var(--ink-3); font-size:12.5px;}

/* status dot — Yokogawa DevStatusFlagIconLib: filled ellipse, inset 2.5px */
.sdot{width:11px;height:11px;border-radius:50%;display:inline-block;border:1px solid rgba(0,0,0,.16);}
.sdot.good{background:var(--good);} .sdot.warn{background:var(--warn);}
.sdot.crit{background:var(--crit);} .sdot.join{background:var(--join);}
.sdot.idle{background:var(--idle);}
:root[data-theme="dark"] .sdot{border-color:rgba(255,255,255,.2);}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .sdot{border-color:rgba(255,255,255,.2);}}

/* ===== TABS ============================================================ */
.tabs{display:flex; gap:1px; border-bottom:1px solid var(--border); background:var(--surface-2); padding:0 8px; overflow-x:auto;}
.tab{
  padding:8px 14px; font-size:12.5px; cursor:pointer; color:var(--ink-2); background:none;
  border:none; border-bottom:2px solid transparent; white-space:nowrap;
  font-family:var(--font-display); font-weight:600; letter-spacing:.02em;
}
.tab:hover{color:var(--ink);}
.tab[aria-selected="true"]{color:var(--accent); border-bottom-color:var(--accent);}
.tabpanel{display:none;} .tabpanel.active{display:block;}

/* ===== FORMS =========================================================== */
.fgrid{display:grid; grid-template-columns:repeat(auto-fit,minmax(215px,1fr)); gap:12px 16px;}
.fgrid.c2{grid-template-columns:repeat(2,minmax(0,1fr));}
.fgrid.c3{grid-template-columns:repeat(3,minmax(0,1fr));}
.field{display:flex; flex-direction:column; gap:4px; min-width:0;}
.field.span2{grid-column:span 2;}
label{font-size:11.5px; color:var(--ink-2); font-weight:500;}
.req{color:var(--crit-ink);}
input[type=text],input[type=number],input[type=password],select,textarea{
  padding:6px 9px; border:1px solid var(--border-strong); border-radius:var(--r);
  background:var(--surface); font-size:12.5px; width:100%; min-width:0;
}
input:disabled,select:disabled,textarea:disabled{background:var(--sunken); color:var(--ink-3); cursor:not-allowed;}

/* A control with a caption in front of it, sitting inline in a toolbar. */
.checkrow.inline{align-items:center; padding:0; gap:6px; white-space:nowrap;}
.lbl-sm{
  font-size:10.5px; font-weight:600; letter-spacing:.05em; text-transform:uppercase;
  color:var(--ink-3); font-family:var(--font-display);
}
/* Selects in a toolbar match .btn.sm so the row reads as one control strip:
   same height, border, radius and type size. */
.viewactions select{
  /* width:auto defeats the width:100% the generic rule above gives every
     select — in a flex toolbar that would stretch it across the row. */
  width:auto; padding:3px 8px; font-size:11.5px; border-radius:var(--r);
  border:1px solid var(--border-strong); background:var(--surface); color:var(--ink);
  line-height:1.45; height:auto; cursor:pointer;
}
.viewactions select:hover{border-color:var(--ink-3);}
.viewactions .checkrow.inline input[type=checkbox]{margin:0;}
input.mono,select.mono{font-family:var(--font-data);}
input[aria-invalid="true"]{border-color:var(--crit); background:var(--crit-soft);}
.hint{font-size:11px; color:var(--ink-3);}
.hint.err{color:var(--crit-ink);}
.unit{font-size:11px; color:var(--ink-3); font-family:var(--font-data);}
.checkrow{display:flex; align-items:flex-start; gap:8px; font-size:12.5px; padding:3px 0;}
.checkrow input{margin-top:2px; flex:none;}
.switchrow{display:flex; align-items:center; gap:12px; padding:9px 0; border-bottom:1px solid var(--border);}
.switchrow:last-child{border-bottom:none;}
.switchrow .lbl{font-size:12.5px; font-weight:500;}
.switchrow .sub{font-size:11.5px; color:var(--ink-3); font-family:var(--font-data);}
.switchrow .right{margin-left:auto;}
.sw{width:36px;height:20px;border-radius:99px;background:var(--idle);border:1px solid var(--border-strong);position:relative;cursor:pointer;flex:none;transition:background .14s;}
.sw::after{content:"";position:absolute;top:2px;left:2px;width:14px;height:14px;border-radius:50%;background:var(--surface);box-shadow:var(--shadow-1);transition:transform .14s;}
.sw[aria-checked="true"]{background:var(--accent);border-color:var(--accent);}
.sw[aria-checked="true"]::after{transform:translateX(16px);}

/* ===== DIALOG ========================================================== */
.scrim{
  position:fixed; inset:0; background:rgba(16,26,31,.5); z-index:100;
  display:flex; align-items:center; justify-content:center; padding:22px;
  backdrop-filter:blur(1.5px);
}
.scrim[hidden]{display:none;}
.dlg{
  background:var(--surface); border:1px solid var(--border-strong); border-radius:var(--r-lg);
  box-shadow:var(--shadow-2); width:100%; max-width:780px; max-height:100%;
  display:flex; flex-direction:column; overflow:hidden;
}
.dlg.wide{max-width:1020px;} .dlg.narrow{max-width:440px;}
.dlg-head{
  display:flex; align-items:center; gap:10px; padding:11px 14px;
  border-bottom:1px solid var(--border); background:var(--surface-2); flex:none;
}
.dlg-title{font-family:var(--font-display); font-weight:600; font-size:14px;}
.dlg-body{padding:14px; overflow-y:auto; flex:1; min-height:0;}
.dlg-foot{
  display:flex; gap:8px; padding:11px 14px; border-top:1px solid var(--border);
  background:var(--surface-2); flex:none; align-items:center; flex-wrap:wrap;
}
.dlg-foot .right{margin-left:auto; display:flex; gap:8px;}
.group{border:1px solid var(--border); border-radius:var(--r); padding:11px 12px; margin-bottom:12px;}
.group>legend,.group-title{
  font-family:var(--font-display); font-weight:600; font-size:11px; color:var(--ink-2);
  letter-spacing:.07em; text-transform:uppercase; padding:0 4px; margin-bottom:8px; display:block;
}

/* ===== TRANSFER (Available Parameters <-> selected) ==================== */
.xfer{display:grid; grid-template-columns:1fr auto 1fr; gap:10px; align-items:stretch;}
.xfer-col{display:flex; flex-direction:column; min-width:0;}
.xfer-col>.cap{font-size:11.5px; color:var(--ink-2); margin-bottom:4px; font-weight:500;}
.xfer-list{
  border:1px solid var(--border-strong); border-radius:var(--r); background:var(--surface);
  height:210px; overflow:auto; padding:3px;
}
.xfer-item{
  padding:4px 7px; border-radius:3px; cursor:pointer; font-size:12px;
  display:flex; align-items:baseline; gap:7px;
}
.xfer-item:hover{background:var(--surface-3);}
.xfer-item[aria-selected="true"]{background:var(--accent-soft); color:var(--accent); font-weight:500;}
.xfer-item .pname{font-family:var(--font-data);}
.xfer-item .pobj{font-size:10.5px; color:var(--ink-3); margin-left:auto; font-family:var(--font-data);}
.xfer-item .pk{font-size:9.5px; letter-spacing:.05em; text-transform:uppercase; color:var(--ink-3);}
.xfer-btns{display:flex; flex-direction:column; gap:5px; justify-content:center;}
.xfer-btns button{
  width:34px; padding:5px 0; font-family:var(--font-data); font-size:12px;
  border:1px solid var(--border-strong); border-radius:var(--r); background:var(--surface);
  cursor:pointer; color:var(--ink-2);
}
.xfer-btns button:hover{background:var(--accent-soft); border-color:var(--accent); color:var(--accent);}

/* ===== GENERATED CONFIG (the bridge, made visible) ==================== */
.conf{
  background:var(--sunken); border-top:1px solid var(--border);
  font-family:var(--font-data); font-size:12px; line-height:1.65;
  padding:12px 14px; overflow-x:auto; margin:0; white-space:pre;
  color:var(--ink-2); tab-size:2;
}
.conf .c-sec{color:var(--accent); font-weight:500;}
.conf .c-key{color:var(--ink);}
.conf .c-cmt{color:var(--ink-3); font-style:italic;}
.conf .c-str{color:var(--good-ink);}
.conf .c-num{color:var(--crit-ink);}
:root[data-theme="dark"] .conf .c-num{color:var(--warn-ink);}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .conf .c-num{color:var(--warn-ink);}}

/* ===== LANDING ========================================================= */
.landing{flex:1; display:none; align-items:center; justify-content:center; padding:28px 22px; overflow-y:auto;}
.landing.active{display:flex;}
.landing-in{width:100%; max-width:860px;}
.eyebrow{
  font-family:var(--font-display); font-size:10.5px; font-weight:600; color:var(--ink-3);
  letter-spacing:.14em; text-transform:uppercase; display:flex; align-items:center; gap:8px;
}
.eyebrow::after{content:""; flex:1; height:1px; background:var(--border);}
.landing h1{font-size:30px; letter-spacing:-.02em; margin:12px 0 8px; line-height:1.12;}
.landing .lede{color:var(--ink-2); font-size:14px; max-width:66ch; margin:0 0 22px;}
.modegrid{display:grid; grid-template-columns:repeat(auto-fit,minmax(310px,1fr)); gap:14px;}
.modecard{
  background:var(--surface); border:1px solid var(--border); border-left:3px solid var(--accent);
  border-radius:var(--r-lg); padding:18px; cursor:pointer; text-align:left;
  box-shadow:var(--shadow-1); display:flex; flex-direction:column; gap:9px;
  transition:box-shadow .15s, border-color .15s, transform .15s;
}
.modecard:hover{box-shadow:var(--shadow-2); transform:translateY(-2px);}
.modecard.cfg{border-left-color:var(--ink-2);}
.modecard .mc-ico{width:26px;height:26px;color:var(--accent);}
.modecard.cfg .mc-ico{color:var(--ink-2);}
.modecard h3{font-size:17px;}
.modecard p{margin:0; font-size:12.5px; color:var(--ink-2);}
.modecard ul{margin:2px 0 0; padding:0 0 0 15px; font-size:12px; color:var(--ink-3); display:flex; flex-direction:column; gap:2px;}
.modecard .cta{
  margin-top:auto; padding-top:8px; font-family:var(--font-display); font-weight:600;
  font-size:12px; color:var(--accent); letter-spacing:.03em;
}
.modecard.cfg .cta{color:var(--ink);}
.landing-foot{margin-top:20px; font-size:11.5px; color:var(--ink-3); display:flex; gap:16px; flex-wrap:wrap;}

/* ===== TOAST =========================================================== */
.toasts{position:fixed; right:16px; bottom:16px; z-index:200; display:flex; flex-direction:column; gap:8px; max-width:400px;}
.toast{
  background:var(--surface); border:1px solid var(--border-strong); border-left:3px solid var(--accent);
  border-radius:var(--r); box-shadow:var(--shadow-2); padding:9px 12px; font-size:12.5px;
  animation:tin .2s ease-out;
}
.toast.ok{border-left-color:var(--good);} .toast.warn{border-left-color:var(--warn);} .toast.err{border-left-color:var(--crit);}
.toast .tt{font-weight:600; font-family:var(--font-display); font-size:12px; margin-bottom:1px;}
.toast .tb{color:var(--ink-2); font-size:11.5px;}
@keyframes tin{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* ===== MISC ============================================================ */
.pager{display:flex; align-items:center; gap:7px; padding:9px 14px; border-top:1px solid var(--border); background:var(--surface-2); flex-wrap:wrap;}
.pager .info{font-size:11.5px; color:var(--ink-3); margin-right:auto; font-family:var(--font-data);}
.pgbtn{
  min-width:28px; height:26px; padding:0 7px; border:1px solid var(--border-strong); background:var(--surface);
  border-radius:var(--r); cursor:pointer; font-family:var(--font-data); font-size:12px; color:var(--ink-2);
}
.pgbtn:hover:not([disabled]){background:var(--surface-3); color:var(--ink);}
.pgbtn[disabled]{opacity:.4; cursor:default;}

.chgrid{display:grid; grid-template-columns:repeat(auto-fit,minmax(58px,1fr)); gap:6px;}
.ch{
  border:1px solid var(--border-strong); border-radius:var(--r); padding:7px 4px; text-align:center;
  cursor:pointer; background:var(--surface); user-select:none;
}
.ch .n{font-family:var(--font-data); font-size:14px; font-weight:500;}
.ch .f{font-size:9.5px; color:var(--ink-3); font-family:var(--font-data);}
.ch[aria-pressed="true"]{background:var(--accent-soft); border-color:var(--accent); color:var(--accent);}
.ch.adv{box-shadow:inset 0 -3px 0 var(--warn);}

.bar{height:5px; background:var(--surface-3); border-radius:99px; overflow:hidden; min-width:70px;}
.bar>i{display:block; height:100%; background:var(--accent); border-radius:99px; transition:width .3s;}
.bar.good>i{background:var(--good);} .bar.crit>i{background:var(--crit);}

.minmax{display:flex; align-items:center; gap:6px; min-width:150px;}
.mmtrack{flex:1; height:14px; position:relative; background:var(--surface-3); border-radius:2px; overflow:hidden;}
.mmspan{position:absolute; top:3px; height:8px; background:var(--accent-soft); border-left:2px solid var(--accent); border-right:2px solid var(--accent);}
.mmavg{position:absolute; top:0; width:2px; height:14px; background:var(--accent);}
.mmthresh{position:absolute; top:0; width:0; height:14px; border-left:1px dashed var(--crit);}
.mmval{font-family:var(--font-data); font-size:11px; color:var(--ink-2); min-width:52px; text-align:right;}

.issue{display:flex; gap:9px; padding:7px 0; border-bottom:1px solid var(--border); font-size:12.5px; align-items:flex-start;}
.issue:last-child{border-bottom:none;}
.issue .sev{
  font-family:var(--font-display); font-size:9.5px; font-weight:700; letter-spacing:.06em;
  text-transform:uppercase; padding:2px 6px; border-radius:3px; flex:none; margin-top:1px; min-width:56px; text-align:center;
}
.issue .sev.Error{background:var(--crit-soft); color:var(--crit-ink);}
.issue .sev.Warning{background:var(--warn-soft); color:var(--warn-ink);}
.issue .sev.OK{background:var(--good-soft); color:var(--good-ink);}
.issue .sev.Information{background:var(--accent-soft); color:var(--accent);}
.issue .where{font-family:var(--font-data); font-size:11px; color:var(--ink-3);}

.tree{font-size:12.5px;}
.tree .tnode{display:flex; align-items:center; gap:7px; padding:3px 0;}
.tree .tnode.l1{padding-left:18px;} .tree .tnode.l2{padding-left:36px;}
.tree .tnode .tlabel{font-family:var(--font-data);}
.tree .tnode.locked{color:var(--ink-3);}
.lockmark{font-size:9.5px; letter-spacing:.05em; text-transform:uppercase; color:var(--warn-ink); background:var(--warn-soft); padding:1px 5px; border-radius:3px; font-family:var(--font-display); font-weight:600;}

.stagelist{display:flex; flex-direction:column; gap:5px;}
.stage{display:flex; align-items:center; gap:9px; font-size:12.5px; font-family:var(--font-data);}
.stage .sname{flex:1;}
.stage .sres{font-family:var(--font-display); font-weight:600; font-size:11px; letter-spacing:.04em;}
.stage .sres.ok{color:var(--good-ink);} .stage .sres.fail{color:var(--crit-ink);}

.legend{display:flex; gap:14px; flex-wrap:wrap; font-size:11.5px; color:var(--ink-2); padding:9px 14px; border-bottom:1px solid var(--border); background:var(--surface-2);}
.legend .li{display:flex; align-items:center; gap:5px;}
.lswatch{width:9px;height:9px;border-radius:50%;}
.lline{width:16px;height:0;border-top:2px solid var(--border-strong);}
.lline.dash{border-top-style:dashed;}

.topo{background:var(--surface); overflow:auto; padding:10px;}
/* Centre the drawing in a panel wider than it, instead of pinning it left.
   It still scrolls when the panel is narrower than the diagram. */
.topo svg{display:block; min-width:640px; margin:0 auto;}
.tnodeg{cursor:pointer;}
.tnodeg:hover .thalo{opacity:1;}
.thalo{opacity:0; transition:opacity .12s;}

.kv{display:grid; grid-template-columns:auto 1fr; gap:5px 14px; font-size:12.5px; align-items:baseline;}
.kv dt{color:var(--ink-3); font-size:11.5px;}
.kv dd{margin:0; font-family:var(--font-data);}

.note{
  display:flex; gap:8px; padding:9px 11px; border-radius:var(--r); font-size:12px;
  background:var(--accent-soft); border:1px solid var(--accent-line); color:var(--ink-2);
  margin-bottom:12px; align-items:flex-start;
}
.note svg{width:14px;height:14px;flex:none;margin-top:1px;color:var(--accent);}
.note.warn{background:var(--warn-soft); border-color:var(--warn); }
.note.warn svg{color:var(--warn-ink);}
.note strong{color:var(--ink);}

@media (max-width:960px){
  :root{--rail-w:56px;}
  .rail .navtext,.rail .rail-group,.rail .navcount,.rail-foot .row span{display:none;}
  .navitem{justify-content:center; padding:8px 0;}
  .navitem.sub{padding-left:0;}
  .rail-foot{align-items:center;}
  .brand-name,.brand-sub{display:none;}
  .topmeta .hidesm{display:none;}
  .xfer{grid-template-columns:1fr; }
  .xfer-btns{flex-direction:row; justify-content:center;}
  .fgrid.c2,.fgrid.c3{grid-template-columns:1fr;}
}

/* ===== additions for the live console ================================== */
/* spinner shown while a table waits on the gateway */
.spinner{
  display:inline-block; width:12px; height:12px; vertical-align:-2px;
  border:2px solid var(--border-strong); border-top-color:var(--accent);
  border-radius:50%; animation:sp .7s linear infinite; margin-right:6px;
}
@keyframes sp{to{transform:rotate(360deg)}}
.empty.err{color:var(--crit-ink);}
.err{color:var(--crit-ink);}
.critink{color:var(--crit-ink);}
.warnink{color:var(--warn-ink);}
.dim.sm,.sm{font-size:11px;}

/* inline row of control + button (device picker, CF file picker) */
.row-inline{display:flex; gap:6px; align-items:center; min-width:0;}
.row-inline>select,.row-inline>input{min-width:0; flex:1;}
.row-inline>.btn{flex:none;}

/* tables nested inside dialogs and panels */
table.inner thead th{background:var(--surface-3);}
.panel.flat{box-shadow:none; margin:0;}
.panel-body.bordered{border-top:1px solid var(--border);}
.tabs.inner{margin:-11px -12px 10px;}
input.narrow{width:12ch;} select.mono{min-width:9ch;}
.bar.big{height:8px; margin-top:8px;}
.stage.sub{padding-left:12px;}
.stage.sub .sname{font-size:11.5px;}

/* topology glyph text — set here so the SVG stays free of inline styling */
.glyph-t{font-family:var(--font-display); font-weight:700; fill:var(--ink);}
.glyph-l{font-family:var(--font-data); font-size:11px; fill:var(--ink-2);}

/* login */
.login-wrap{
  flex:1; display:flex; align-items:center; justify-content:center; padding:24px;
}
.login-card{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg);
  box-shadow:var(--shadow-2); padding:22px; width:100%; max-width:380px;
}
.login-card h2{font-size:18px; margin-bottom:4px;}
.login-card p{margin:0 0 16px; color:var(--ink-2); font-size:12.5px;}
.login-card .fgrid{gap:12px;}
.login-foot{margin-top:14px; display:flex; gap:8px; align-items:center;}
.login-foot .right{margin-left:auto;}
.conn-badge{
  font-size:10.5px; font-family:var(--font-display); font-weight:600;
  letter-spacing:.05em; text-transform:uppercase; padding:2px 7px; border-radius:3px;
}
.conn-badge.mock{background:var(--warn-soft); color:var(--warn-ink);}
.conn-badge.gateway{background:var(--good-soft); color:var(--good-ink);}

/* boot splash — occupies the same slot as the login card so there is no jump */
.login-card.boot h2{display:flex; align-items:center; gap:9px;}
.login-card.boot .spinner{width:14px;height:14px;border-width:2px;margin:0;}
.login-card.boot p{margin:6px 0 0;}
