/* ===========================================================================
   CoolSim Operations Console -- design system
   2026-07-25 refresh.

   This is a STANDALONE stylesheet, not an override layer. Redesigned pages
   load only this file; the 2013 stack (style.css, menu.css, jquery-ui*.css,
   ui.jqgrid.css) is loaded only for the two legacy fallback routes that still
   run on jqGrid. See view/index.php.
   =========================================================================== */

/* --- tokens --------------------------------------------------------------- */
:root {
    /* Palette sampled from the CoolSim logo. The mark is a thermal scale -- hot
       red-orange sweeping through amber and green to cold blue -- which is both
       the brand and, conveniently, the semantic scale a CFD console needs:
         #e03000 hot red   -> --bad
         #f08010 amber     -> --warn
         #60a0e0 cold blue -> --accent
       The literals below are those hues darkened where they carry text, so they
       clear 4.5:1 on white; the raw logo tints are kept for backgrounds. */
    --brand-900:#0b1524; --brand-800:#101d31; --brand-700:#17293f;
    --brand-600:#1e3a52;
    --accent:#1a6fb5;      /* logo blue, deepened for contrast with white text */
    --accent-hi:#70b0f0;   /* the logo blue itself -- used on the dark sidebar */
    --accent-dim:rgba(112,176,240,.16);

    --bg:#f4f6f9;  --surface:#ffffff; --surface-2:#f9fafb; --surface-3:#eef1f5;
    --line:#dfe4ea; --line-soft:#eaeef3;
    --ink:#16202e; --ink-2:#4a5768; --ink-3:#79879a; --ink-inv:#ffffff;

    --ok:#0f7b4f;   --ok-bg:#e6f5ee;
    --bad:#c22a08;  --bad-bg:#fdeae5;      /* logo #e03000 */
    --warn:#a85f00; --warn-bg:#fdf2e0;     /* logo #f08010 */
    --info:#1a6fb5; --info-bg:#e8f1fb;

    /* The logo ring, as a gradient. Used as a hairline accent so the brand is
       present on every page without pasting the logo everywhere. */
    --thermal:linear-gradient(90deg,#e03000 0%,#f08010 22%,#c8c832 44%,#5ab0a0 64%,#60a0e0 82%,#70b0f0 100%);

    --r-sm:4px; --r:7px; --r-lg:11px;
    --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:22px; --sp-6:30px;
    --shadow:0 1px 2px rgba(16,29,49,.05), 0 2px 8px rgba(16,29,49,.05);
    --shadow-lg:0 10px 34px rgba(11,21,36,.16);
    --sidebar-w:230px;
    --font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
    --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;
}

html[data-theme="dark"] {
    --bg:#0d1521; --surface:#141f2e; --surface-2:#182534; --surface-3:#1e2c3d;
    --line:#25384d; --line-soft:#1d2c3d;
    --ink:#e6edf5; --ink-2:#a9b8c9; --ink-3:#7288a0;
    --accent:#70b0f0;      /* the logo blue reads correctly on dark */
    --accent-hi:#9ccbf7;
    --accent-dim:rgba(112,176,240,.18);
    --ok:#41c98a; --ok-bg:rgba(65,201,138,.13);
    --bad:#f4795c; --bad-bg:rgba(224,48,0,.16);
    --warn:#eda93f; --warn-bg:rgba(240,128,16,.15);
    --info:#70b0f0; --info-bg:rgba(112,176,240,.14);
    --shadow:0 1px 2px rgba(0,0,0,.3), 0 2px 8px rgba(0,0,0,.24);
    --shadow-lg:0 10px 34px rgba(0,0,0,.5);
}

/* --- reset ---------------------------------------------------------------- */
*,*::before,*::after { box-sizing:border-box; }
html,body { margin:0; padding:0; }
body {
    background:var(--bg); color:var(--ink);
    font:14px/1.5 var(--font);
    -webkit-font-smoothing:antialiased;
}
a { color:var(--info); text-decoration:none; }
a:hover { text-decoration:underline; }
h1,h2,h3,h4 { margin:0; font-weight:600; letter-spacing:-.011em; }
img { max-width:100%; border:0; }
p { margin:0 0 var(--sp-3); }
ul { margin:0; padding:0; }

/* ===========================================================================
   Application shell
   =========================================================================== */
.app { display:flex; min-height:100vh; }

/* --- sidebar -------------------------------------------------------------- */
.sidebar {
    width:var(--sidebar-w); flex:0 0 var(--sidebar-w);
    background:var(--brand-900); color:#c6d3e2;
    display:flex; flex-direction:column;
    position:sticky; top:0; height:100vh; overflow-y:auto;
}
.sidebar-brand {
    padding:18px 18px 15px; border-bottom:1px solid rgba(255,255,255,.07);
    position:relative;
}
/* The logo ring as a hairline along the bottom of the brand block. */
.sidebar-brand::after {
    content:""; position:absolute; left:0; right:0; bottom:-1px;
    height:2px; background:var(--thermal); opacity:.85;
}
.sidebar-brand .logo { display:block; width:148px; max-width:100%; height:auto; }
.sidebar-brand .logo-mark { display:none; width:34px; height:34px; }
.sidebar-brand .sub {
    color:#7f93ab; font-size:10px; text-transform:uppercase;
    letter-spacing:.13em; margin-top:7px; padding-left:2px;
}

.nav { padding:12px 10px; flex:1; }
.nav-sec {
    font-size:10px; text-transform:uppercase; letter-spacing:.1em;
    color:#5f748d; padding:14px 10px 6px; font-weight:600;
}
.nav a {
    display:flex; align-items:center; gap:10px;
    padding:8px 10px; margin:1px 0; border-radius:var(--r);
    color:#c0cddc; font-size:13.5px; text-decoration:none; line-height:1.2;
}
.nav a:hover { background:rgba(255,255,255,.06); color:#fff; text-decoration:none; }
.nav a.current { background:var(--accent-dim); color:#fff; box-shadow:inset 2px 0 0 var(--accent); }
.nav a.current .ico { color:var(--accent-hi); }
.nav .ico { width:17px; height:17px; flex:0 0 17px; color:#7d92aa; }
.nav a .tag {
    margin-left:auto; font-size:10.5px; font-weight:600;
    background:var(--bad); color:#fff; border-radius:9px; padding:1px 6px;
}
.sidebar-foot {
    padding:12px 16px; border-top:1px solid rgba(255,255,255,.07);
    font-size:11px; color:#5f748d;
}

/* --- topbar --------------------------------------------------------------- */
.main { flex:1; min-width:0; display:flex; flex-direction:column; }
.topbar {
    display:flex; align-items:center; gap:var(--sp-4);
    padding:0 var(--sp-6); height:58px;
    background:var(--surface); border-bottom:1px solid var(--line);
    position:sticky; top:0; z-index:20;
}
.topbar h1 { font-size:16px; font-weight:600; white-space:nowrap; }
.topbar .crumb { color:var(--ink-3); font-size:12.5px; }
.topbar-spacer { flex:1; }

.search {
    position:relative; width:290px; max-width:34vw;
}
/* Scoped to .topbar deliberately: the generic input[type=text] rule further
   down this file has equal specificity, so an unscoped ".search input" LOSES
   the padding-left and the text runs under the magnifier glyph. */
.topbar .search input[type=text] {
    width:100%; height:34px; padding:0 12px 0 32px;
    border:1px solid var(--line); border-radius:var(--r);
    background:var(--surface-2); color:var(--ink); font:inherit; font-size:13px;
}
.topbar .search input[type=text]:focus {
    outline:none; border-color:var(--accent); background:var(--surface);
}
.search .ico {
    position:absolute; left:9px; top:9px; width:15px; height:15px; color:var(--ink-3);
}
/* Typeahead dropdown (built by CS.typeahead). Wider than the box itself --
   290px is enough to type in but not enough to read a job name, a customer
   and an outcome pill side by side -- and right-aligned so it grows leftward
   into the topbar's spare width, not off-screen. */
.search-drop {
    position:absolute; top:calc(100% + 6px); right:0; z-index:80;
    width:460px; max-width:calc(100vw - 2 * var(--sp-4));
    background:var(--surface); border:1px solid var(--line);
    border-radius:var(--r-lg); box-shadow:var(--shadow-lg);
    max-height:70vh; overflow-y:auto; padding-top:2px;
}
.search-drop .grp {
    padding:9px 12px 3px; font-size:10.5px; font-weight:600;
    letter-spacing:.08em; text-transform:uppercase; color:var(--ink-3);
}
.search-drop a.opt {
    display:flex; align-items:center; gap:10px; padding:6px 12px;
    color:var(--ink); text-decoration:none; font-size:13px;
}
.search-drop a.opt:hover, .search-drop a.opt.active { background:var(--accent-dim); }
.search-drop .opt-main { flex:1; min-width:0; display:flex; flex-direction:column; }
.search-drop .opt-title { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.search-drop .opt-title b { font-weight:600; color:var(--accent); }
.search-drop .opt-sub {
    font-size:11.5px; color:var(--ink-3);
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.search-drop .opt-sub b { font-weight:600; color:inherit; }
.search-drop .opt-meta { flex:none; font:11.5px var(--mono); color:var(--ink-3); }
.search-drop .st { flex:none; }
.search-drop .none { padding:14px 12px; font-size:13px; color:var(--ink-3); }
.search-drop .all {
    display:block; margin-top:2px; padding:9px 12px;
    border-top:1px solid var(--line-soft); background:var(--surface-2);
    font-size:12.5px; color:var(--accent); text-decoration:none;
}
.search-drop .all:hover { background:var(--surface-3); }
.iconbtn {
    width:34px; height:34px; border:1px solid var(--line); border-radius:var(--r);
    background:var(--surface-2); color:var(--ink-2);
    display:inline-flex; align-items:center; justify-content:center; cursor:pointer; padding:0;
}
.iconbtn:hover { background:var(--surface-3); color:var(--ink); }
.iconbtn .ico { width:16px; height:16px; }
.whoami {
    display:flex; align-items:center; gap:8px; font-size:13px; color:var(--ink-2);
    padding-left:var(--sp-4); border-left:1px solid var(--line);
}
.whoami .avatar {
    width:28px; height:28px; border-radius:50%; background:var(--brand-700);
    color:#fff; font-size:11.5px; font-weight:600;
    display:flex; align-items:center; justify-content:center;
}

.content { padding:var(--sp-6); max-width:1640px; width:100%; }

/* --- page heading --------------------------------------------------------- */
.page-head {
    display:flex; align-items:flex-start; gap:var(--sp-4);
    margin-bottom:var(--sp-5); flex-wrap:wrap;
}
.page-head h2 { font-size:21px; letter-spacing:-.02em; }
.page-sub { color:var(--ink-3); font-size:13px; margin:3px 0 0; }
.page-head .actions { margin-left:auto; display:flex; gap:var(--sp-2); align-items:center; }

/* ===========================================================================
   Components
   =========================================================================== */

/* --- buttons -------------------------------------------------------------- */
button, .btn, .action, .linkbtn, input[type=submit], input[type=button] {
    display:inline-flex; align-items:center; justify-content:center; gap:6px;
    height:34px; padding:0 14px;
    border:1px solid var(--line); border-radius:var(--r);
    background:var(--surface); color:var(--ink);
    font:inherit; font-size:13px; font-weight:500;
    cursor:pointer; text-decoration:none; white-space:nowrap;
}
button:hover, .btn:hover, .action:hover, .linkbtn:hover,
input[type=submit]:hover, input[type=button]:hover {
    background:var(--surface-3); text-decoration:none;
}
.btn-primary, button.action[type=submit], button[name=btnSearch], button[name=btnSave],
button[name=btnSubmit], button[name=btnAddOrg], button[name=btnUpdateOrg], button[name=btnLogin] {
    background:var(--accent); border-color:var(--accent); color:#fff;
}
.btn-primary:hover, button.action[type=submit]:hover, button[name=btnSearch]:hover,
button[name=btnSave]:hover, button[name=btnSubmit]:hover, button[name=btnAddOrg]:hover,
button[name=btnUpdateOrg]:hover, button[name=btnLogin]:hover {
    background:#0093a5; border-color:#0093a5; color:#fff;
}
.btn-sm { height:28px; padding:0 10px; font-size:12.5px; }
.btn-danger { background:var(--bad); border-color:var(--bad); color:#fff; }
.btn .ico, .btn-sm .ico { width:14px; height:14px; }

/* --- cards / panels ------------------------------------------------------- */
.panel {
    background:var(--surface); border:1px solid var(--line);
    border-radius:var(--r-lg); box-shadow:var(--shadow);
    margin-bottom:var(--sp-5); overflow:hidden;
}
.panel-head {
    display:flex; align-items:center; gap:var(--sp-3);
    padding:13px var(--sp-5); border-bottom:1px solid var(--line-soft);
}
.panel-head h3 { font-size:14px; font-weight:600; }
.panel-note { color:var(--ink-3); font-size:12px; font-weight:400; }
.panel-head .right { margin-left:auto; display:flex; gap:var(--sp-2); align-items:center; }
.panel-body { padding:var(--sp-5); }
.panel-body.tight { padding:0; }
.grid-2 { display:grid; grid-template-columns:repeat(auto-fit,minmax(430px,1fr)); gap:var(--sp-5); }
.grid-2 > .panel { margin-bottom:0; }

/* --- KPI tiles ------------------------------------------------------------ */
.kpi-row {
    display:grid; grid-template-columns:repeat(auto-fit,minmax(168px,1fr));
    gap:var(--sp-3); margin-bottom:var(--sp-5);
}
.kpi {
    background:var(--surface); border:1px solid var(--line);
    border-radius:var(--r-lg); padding:14px 16px; box-shadow:var(--shadow);
    position:relative; overflow:hidden;
}
.kpi::before {
    content:""; position:absolute; left:0; top:0; bottom:0; width:3px; background:var(--line);
}
.kpi.is-ok::before   { background:var(--ok); }
.kpi.is-bad::before  { background:var(--bad); }
.kpi.is-warn::before { background:var(--warn); }
.kpi-label {
    display:block; font-size:11px; text-transform:uppercase; letter-spacing:.07em;
    color:var(--ink-3); font-weight:600;
}
.kpi-value {
    display:block; font-size:26px; font-weight:600; letter-spacing:-.02em;
    margin:4px 0 1px; line-height:1.1;
}
.kpi.is-bad  .kpi-value { color:var(--bad); }
.kpi.is-ok   .kpi-value { color:var(--ok); }
.kpi.is-warn .kpi-value { color:var(--warn); }
.kpi-note { display:block; font-size:11.5px; color:var(--ink-3); }

/* KPI tiles are links (every number opens the rows behind it), so they need a
   pointer affordance without looking like buttons. */
a.kpi { text-decoration:none; color:inherit; display:block; transition:border-color .12s, transform .12s; }
a.kpi:hover {
    text-decoration:none; border-color:var(--accent);
    transform:translateY(-1px); box-shadow:0 3px 12px rgba(16,29,49,.09);
}
a.kpi:hover .kpi-label { color:var(--accent); }
a.kpi:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }

/* segmented range control */
.segmented { display:inline-flex; border:1px solid var(--line); border-radius:var(--r); overflow:hidden; }
.segmented a {
    padding:0 11px; height:32px; display:inline-flex; align-items:center;
    font-size:12.5px; color:var(--ink-2); text-decoration:none;
    border-right:1px solid var(--line); background:var(--surface); white-space:nowrap;
}
.segmented a:last-child { border-right:0; }
.segmented a:hover { background:var(--surface-3); text-decoration:none; }
.segmented a.on { background:var(--accent); color:#fff; }

/* clickable chart bars */
.chart a { cursor:pointer; }
.chart a:hover .bar { fill:var(--accent-hi); }

/* --- tables --------------------------------------------------------------- */
table.grid, table.cs-table { width:100%; border-collapse:collapse; font-size:13px; }
table.grid th, table.cs-table th {
    text-align:left; font-weight:600; font-size:11px; letter-spacing:.055em;
    text-transform:uppercase; color:var(--ink-3);
    padding:9px var(--sp-4); border-bottom:1px solid var(--line);
    background:var(--surface-2); white-space:nowrap;
}
table.grid td, table.cs-table td {
    padding:9px var(--sp-4); border-bottom:1px solid var(--line-soft);
    vertical-align:middle;
}
table.grid tr:last-child td, table.cs-table tr:last-child td { border-bottom:0; }
table.grid tbody tr:hover, table.cs-table tbody tr:hover { background:var(--surface-2); }
th.num, td.num { text-align:right; font-variant-numeric:tabular-nums; }
th.ctr, td.ctr { text-align:center; }
td.mono { font-family:var(--mono); font-size:12px; }
td.dim, .dim { color:var(--ink-3); }
td.strong { font-weight:600; }
.table-wrap { overflow-x:auto; }
/* Project names run to 60+ chars; without a cap they push the row's action
   link off-screen. Full name stays available via the title attribute. */
td.name-cell { max-width:330px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* sortable headers (cs-table) */
.cs-table th.sortable { cursor:pointer; user-select:none; position:relative; padding-right:20px; }
.cs-table th.sortable:hover { color:var(--ink); }
.cs-table th.sortable::after {
    content:"\2195"; position:absolute; right:7px; opacity:.28; font-size:11px;
}
.cs-table th.sort-asc::after  { content:"\2191"; opacity:1; color:var(--accent); }
.cs-table th.sort-desc::after { content:"\2193"; opacity:1; color:var(--accent); }

/* table toolbar + endless-scroll foot */
.tbl-toolbar {
    display:flex; align-items:center; gap:var(--sp-3); flex-wrap:wrap;
    padding:11px var(--sp-5); border-bottom:1px solid var(--line-soft);
    background:var(--surface-2);
}
.tbl-toolbar .filter { position:relative; }
.tbl-toolbar .filter input[type=text] { height:30px; width:230px; padding-left:29px; font-size:12.5px; }
.tbl-toolbar .filter .ico { position:absolute; left:9px; top:8px; width:14px; height:14px; color:var(--ink-3); }
.tbl-toolbar .spacer { flex:1; }
.tbl-count { font-size:12.5px; color:var(--ink-3); }
/* Foot of an endless table: how far in you are, and -- where the server capped
   the result set -- the way to ask for more. Doubles as the sentinel the reveal
   observer watches, so it must stay in flow and must not be display:none while
   rows remain. */
.tbl-end {
    display:flex; align-items:center; justify-content:center; gap:var(--sp-3);
    padding:12px var(--sp-5); border-top:1px solid var(--line-soft);
    font-size:12.5px; color:var(--ink-3); background:var(--surface-2);
}
.tbl-end-more { font-weight:600; color:var(--accent); }

/* empty state */
.empty { padding:38px var(--sp-5); text-align:center; color:var(--ink-3); }
.empty .ico { width:26px; height:26px; opacity:.4; margin-bottom:8px; }
.empty strong { display:block; color:var(--ink-2); font-weight:600; margin-bottom:3px; }

/* --- badges / status ------------------------------------------------------ */
.st {
    display:inline-block; padding:2px 8px; border-radius:20px;
    font-size:11.5px; font-weight:600; line-height:1.5; white-space:nowrap;
}
.st-ok   { background:var(--ok-bg);   color:var(--ok); }
.st-bad  { background:var(--bad-bg);  color:var(--bad); }
.st-warn { background:var(--warn-bg); color:var(--warn); }
.st-info { background:var(--info-bg); color:var(--info); }
.st-mute { background:var(--surface-3); color:var(--ink-3); }
.txt-bad { color:var(--bad); font-weight:600; }
.txt-ok  { color:var(--ok);  font-weight:600; }
.txt-warn{ color:var(--warn);font-weight:600; }

/* --- forms ---------------------------------------------------------------- */
label, .lbl { font-size:13px; color:var(--ink-2); font-weight:500; }
input[type=text], input[type=password], input[type=email], input[type=date],
input[type=number], select, textarea, .textBox, .text_medium {
    height:34px; padding:0 10px;
    border:1px solid var(--line); border-radius:var(--r);
    background:var(--surface); color:var(--ink);
    font:inherit; font-size:13px; max-width:100%;
}
textarea { height:auto; padding:8px 10px; }
input:focus, select:focus, textarea:focus {
    outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-dim);
}
input[readonly] { background:var(--surface-3); color:var(--ink-2); }
select { padding-right:6px; }

/* generic form rows used by registration/edit (legacy markup, restyled) */
.formcard { max-width:920px; }
.formcard ul { list-style:none; }
.formcard ul > li { padding:0 0 var(--sp-4); min-height:0; }
.formcard table { border-collapse:separate; border-spacing:0 0; width:100%; }
.formcard td { padding:6px 10px 6px 0; vertical-align:middle; }
.formcard td label { display:inline-block; min-width:130px; }
.field-row { display:flex; gap:var(--sp-4); flex-wrap:wrap; margin-bottom:var(--sp-4); }
.field { display:flex; flex-direction:column; gap:5px; }
.field > label { font-size:12px; color:var(--ink-2); font-weight:600; }
.form-actions {
    display:flex; gap:var(--sp-2); padding-top:var(--sp-4);
    border-top:1px solid var(--line-soft); margin-top:var(--sp-2);
}
.toolbar-table { border-collapse:collapse; }
.toolbar-table td { padding:0 5px 0 0; vertical-align:middle; }

/* messages */
.errormsg, .successmsg, .flash {
    display:block; padding:9px 13px; border-radius:var(--r);
    font-size:13px; margin-bottom:var(--sp-3);
}
.errormsg:empty, .successmsg:empty, .flash:empty { display:none; }
.errormsg { background:var(--bad-bg); color:var(--bad); border:1px solid rgba(192,50,43,.2); }
.successmsg, .flash { background:var(--ok-bg); color:var(--ok); border:1px solid rgba(15,123,79,.2); }

/* --- tabs (replaces jquery-ui tabs) --------------------------------------- */
.tabs { display:flex; gap:2px; border-bottom:1px solid var(--line); margin-bottom:var(--sp-5); }
.tabs a {
    padding:9px 16px; font-size:13.5px; font-weight:500; color:var(--ink-2);
    border-bottom:2px solid transparent; margin-bottom:-1px; text-decoration:none;
}
.tabs a:hover { color:var(--ink); text-decoration:none; }
.tabs a.active { color:var(--accent); border-bottom-color:var(--accent); }
.tabpane { display:none; }
.tabpane.active { display:block; }

/* --- charts (inline SVG, no libraries) ------------------------------------ */
.chart { width:100%; display:block; overflow:visible; }
.chart .bar   { fill:var(--accent); }
.chart .bar-2 { fill:var(--bad); }
.chart .axis  { stroke:var(--line); stroke-width:1; }
.chart .lbl   { fill:var(--ink-3); font-size:10px; font-family:var(--font); }
.chart .val   { fill:var(--ink-2); font-size:10px; font-family:var(--font); font-weight:600; }
.chart .line  { fill:none; stroke:var(--accent); stroke-width:2; }
.chart .area  { fill:var(--accent); opacity:.1; }

.meter { height:6px; border-radius:3px; background:var(--surface-3); overflow:hidden; min-width:70px; }
.meter > span { display:block; height:100%; background:var(--accent); border-radius:3px; }
.meter.over > span { background:var(--bad); }
.meter.warn > span { background:var(--warn); }

/* --- timeline (job detail) ------------------------------------------------ */
.timeline { list-style:none; padding:var(--sp-2) 0; }
.timeline li { position:relative; padding:0 0 var(--sp-5) 30px; }
.timeline li:last-child { padding-bottom:var(--sp-2); }
.timeline li::before {
    content:""; position:absolute; left:6px; top:4px;
    width:11px; height:11px; border-radius:50%;
    background:var(--surface); border:2px solid var(--ink-3);
}
.timeline li::after {
    content:""; position:absolute; left:11px; top:17px; bottom:0; width:1px; background:var(--line);
}
.timeline li:last-child::after { display:none; }
.timeline li.ok::before   { border-color:var(--ok);   background:var(--ok); }
.timeline li.bad::before  { border-color:var(--bad);  background:var(--bad); }
.timeline li.warn::before { border-color:var(--warn); background:var(--warn); }
.timeline .t-title { font-weight:600; font-size:13.5px; }
.timeline .t-meta  { font-size:12px; color:var(--ink-3); margin-top:1px; }

/* --- definition list ------------------------------------------------------ */
.dl { display:grid; grid-template-columns:minmax(130px,auto) 1fr; gap:9px var(--sp-4); font-size:13px; }
.dl dt { color:var(--ink-3); font-size:12px; }
.dl dd { margin:0; }

/* --- login ---------------------------------------------------------------- */
.login-wrap {
    min-height:100vh; display:flex; align-items:center; justify-content:center;
    background:linear-gradient(150deg,var(--brand-900),var(--brand-700) 55%,#0a4c5c);
    padding:var(--sp-5);
}
.login-card {
    width:100%; max-width:394px; background:var(--surface);
    border-radius:var(--r-lg); box-shadow:var(--shadow-lg); padding:34px 32px;
}
.login-card .logo { display:block; width:190px; max-width:70%; height:auto; margin-bottom:var(--sp-5); }
/* Logo ring across the top edge of the card. */
.login-card { position:relative; overflow:hidden; }
.login-card::before {
    content:""; position:absolute; left:0; right:0; top:0; height:3px; background:var(--thermal);
}
.login-card h1 { font-size:19px; margin-bottom:3px; }
.login-card .sub { color:var(--ink-3); font-size:13px; margin-bottom:var(--sp-5); }
.login-card .field { margin-bottom:var(--sp-4); }
.login-card input { width:100%; height:38px; }
.login-card button { width:100%; height:38px; margin-top:var(--sp-2); }
.login-foot { text-align:center; margin-top:var(--sp-5); font-size:11.5px; color:var(--ink-3); }

/* --- misc ----------------------------------------------------------------- */
.note {
    background:var(--info-bg); border:1px solid rgba(29,95,191,.18);
    color:var(--ink-2); border-radius:var(--r); padding:11px 14px;
    font-size:12.5px; margin-bottom:var(--sp-4);
}
.note strong { color:var(--ink); }
.note.warn { background:var(--warn-bg); border-color:rgba(154,100,0,.22); }
.note.bad  { background:var(--bad-bg);  border-color:rgba(192,50,43,.2); }
.hint { font-size:11.5px; color:var(--ink-3); }
.sr-only {
    position:absolute; width:1px; height:1px; overflow:hidden;
    clip:rect(0 0 0 0); white-space:nowrap;
}

@media (max-width:1080px) {
    :root { --sidebar-w:62px; }
    .sidebar-brand .sub, .nav a span:not(.tag), .nav-sec, .sidebar-foot { display:none; }
    .sidebar-brand .logo { display:none; }
    .sidebar-brand .logo-mark { display:block; margin:0 auto; }
    .sidebar-brand { justify-content:center; padding:14px 0; text-align:center; }
    .nav a { justify-content:center; }
    .content { padding:var(--sp-4); }
    .search { width:170px; }
}
@media print {
    .sidebar, .topbar, .tbl-toolbar, .pager, .page-head .actions { display:none !important; }
    .content { padding:0; } .panel { box-shadow:none; break-inside:avoid; }
}

/* --- job detail: failure diagnosis, variations, log viewer ---------------- */
/* Added 2026-07-25 with the on-disk log surfacing. */

.diag { border-left:3px solid var(--line); }
.diag-model    { border-left-color:var(--warn); }
.diag-platform { border-left-color:var(--bad); }
.diag-operator { border-left-color:var(--info); }
.diag .panel-head h3 { display:flex; align-items:center; gap:var(--sp-2); }
.diag .panel-head .ico { width:16px; height:16px; }
.diag-model .panel-head .ico    { color:var(--warn); }
.diag-platform .panel-head .ico { color:var(--bad); }
.diag-operator .panel-head .ico { color:var(--info); }

.diag-why  { margin:0 0 var(--sp-3); font-size:14px; color:var(--ink); max-width:78ch; }
.diag-sub  {
    margin:0 0 var(--sp-3); padding:var(--sp-3); max-width:78ch;
    background:var(--warn-bg); border-radius:var(--r-sm);
    font-size:13px; color:var(--ink-2);
    display:flex; gap:var(--sp-2); align-items:flex-start;
}
.diag-sub .ico { width:15px; height:15px; flex:0 0 auto; margin-top:2px; color:var(--warn); }
.diag-next { margin:0; font-size:13px; color:var(--ink-2); max-width:78ch; }
.diag-next strong { color:var(--ink); }

.diag-evidence { margin-top:var(--sp-4); }
.diag-evidence-head {
    font-size:11px; text-transform:uppercase; letter-spacing:.06em;
    color:var(--ink-3); font-weight:600; margin-bottom:var(--sp-2);
}
.diag-evidence pre {
    margin:0; padding:var(--sp-3) var(--sp-4);
    background:var(--surface-3); border:1px solid var(--line-soft);
    border-radius:var(--r-sm);
    font:12px/1.6 var(--mono); color:var(--ink-2);
    overflow-x:auto; white-space:pre;
}

.var-grid {
    display:grid; gap:var(--sp-2);
    grid-template-columns:repeat(auto-fill,minmax(150px,1fr));
}
.var {
    padding:var(--sp-3); border-radius:var(--r-sm);
    border:1px solid var(--line); background:var(--surface-2);
    display:flex; flex-direction:column; gap:2px;
}
.var-n { font-size:12px; font-weight:600; color:var(--ink); }
.var-s { font-size:12px; color:var(--ink-3); }
.var.ok      { background:var(--ok-bg);   border-color:transparent; }
.var.ok .var-s      { color:var(--ok); font-weight:600; }
.var.bad     { background:var(--bad-bg);  border-color:transparent; }
.var.bad .var-s     { color:var(--bad); font-weight:600; }
.var.unknown { opacity:.65; }

.timeline .t-dur {
    float:right; font:12px/1.5 var(--mono); color:var(--ink-3); font-weight:400;
}
.warn-text { color:var(--warn); }

tr.group-row td {
    background:var(--surface-3); font-size:11px; font-weight:600;
    text-transform:uppercase; letter-spacing:.06em; color:var(--ink-3);
    padding-top:var(--sp-2); padding-bottom:var(--sp-2);
}

.log-controls {
    display:flex; gap:var(--sp-2); align-items:center; flex-wrap:wrap;
    margin-bottom:var(--sp-3);
}
.log-controls input[type=text] {
    flex:1 1 240px; min-width:180px;
    padding:6px var(--sp-3); border:1px solid var(--line);
    border-radius:var(--r-sm); background:var(--surface);
    color:var(--ink); font:13px var(--font);
}
.log-controls .chk {
    display:flex; align-items:center; gap:6px;
    font-size:13px; color:var(--ink-2); white-space:nowrap;
}

.logview {
    border:1px solid var(--line-soft); border-radius:var(--r-sm);
    background:var(--surface-3); max-height:620px; overflow:auto;
}
.logview pre { margin:0; padding:var(--sp-3) 0; font:12px/1.65 var(--mono); }
.logview .ln {
    display:block; padding:0 var(--sp-4) 0 0; white-space:pre;
    color:var(--ink-2);
}
.logview .ln i {
    display:inline-block; width:62px; padding-right:var(--sp-3);
    text-align:right; color:var(--ink-3); opacity:.6;
    font-style:normal; -webkit-user-select:none; user-select:none;
}
.logview .l-bad  { background:var(--bad-bg);  color:var(--bad);  font-weight:600; }
.logview .l-warn { background:var(--warn-bg); color:var(--warn); }
.logview .l-ok   { color:var(--ok); }

/* Parametric analytics: sub-headings and a denser table for side-by-side
   comparisons where the full grid padding would push the pair out of line. */
.sub-h {
    margin:0 0 var(--sp-2); font-size:12px; font-weight:600;
    text-transform:uppercase; letter-spacing:.05em; color:var(--ink-3);
}
table.grid.compact th, table.grid.compact td {
    padding-top:var(--sp-2); padding-bottom:var(--sp-2); font-size:13px;
}
table.grid.compact td:first-child { padding-left:0; }

/* Default icon size. There was none: every .ico was sized by its context, so an
   icon used anywhere new (a <dd>, a paragraph) inflated to fill its container.
   Every existing rule is more specific than this, so they all still win. */
.ico { width:16px; height:16px; flex:0 0 auto; vertical-align:-3px; }

/* Panels in a 2-up row size to their own content rather than stretching to
   match the taller neighbour, which left a chart panel half empty. */
.grid-2.top { align-items:start; }

/* --- Customers ------------------------------------------------------------
   Added 2026-07-28 with view/customers.php. Everything below is scoped to the
   controls that page introduced: click-to-copy chips, the credential reveal,
   expandable organization rows and the definition list on the person report.
   -------------------------------------------------------------------------- */

/* Click-to-copy. The chip is a button but must read as text in a table cell,
   so it carries no chrome until hovered. */
.copy-chip {
    display: inline-flex; align-items: center; gap: 5px;
    max-width: 100%; padding: 2px 5px; margin: -2px -5px;
    border: 1px solid transparent; border-radius: var(--r-sm);
    background: none; color: inherit; font: inherit; text-align: left;
    cursor: pointer;
}
.copy-chip:hover  { background: var(--surface-3); border-color: var(--line); }
.copy-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.copy-val {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.copy-ico {
    width: 13px; height: 13px; flex: 0 0 auto;
    opacity: 0; transition: opacity var(--dur, .12s) ease; color: var(--ink-3);
}
.copy-chip:hover .copy-ico, .copy-chip:focus-visible .copy-ico { opacity: 1; }

/* Confirmation states. Applied for ~1.1s by cs-admin.js. */
.copy-chip.copied, .btn-xs.copied {
    background: var(--ok-bg); border-color: var(--ok); color: var(--ok);
}
.copy-chip.copied .copy-ico { opacity: 1; color: var(--ok); }
.copy-chip.copy-failed, .btn-xs.copy-failed {
    background: var(--bad-bg); border-color: var(--bad); color: var(--bad);
}

/* Small button used inside table cells and the credential control. */
.btn-xs {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 2px 7px; border: 1px solid var(--line); border-radius: var(--r-sm);
    background: var(--surface-2); color: var(--ink-2);
    font: inherit; font-size: 12px; line-height: 1.7; cursor: pointer;
    white-space: nowrap;
}
.btn-xs:hover { background: var(--surface-3); color: var(--ink); }
.btn-xs .ico  { width: 13px; height: 13px; }

/* Credential reveal. */
.cred { display: inline-flex; align-items: center; gap: 5px; }
.cred-val {
    padding: 2px 7px; border-radius: var(--r-sm);
    background: var(--warn-bg); border: 1px solid var(--warn);
    color: var(--ink); font-family: var(--mono); font-size: 12.5px;
    user-select: all;
}
.cred-bad     { color: var(--ink-3); font-size: 12px; font-style: italic; }
.cred-blocked { color: var(--ink-3); display: inline-flex; }
.cred-blocked .ico { width: 14px; height: 14px; }

/* Expandable organization rows. */
.disclose {
    display: inline-flex; align-items: center; justify-content: center;
    width: 20px; height: 20px; margin-right: 2px; padding: 0;
    border: 0; border-radius: var(--r-sm);
    background: none; color: var(--ink-3); cursor: pointer; vertical-align: middle;
}
.disclose:hover { background: var(--surface-3); color: var(--ink); }
.disclose .chev {
    width: 14px; height: 14px;
    transition: transform .13s ease;
}
.row-expand.open .disclose .chev { transform: rotate(90deg); }
.row-expand.open > td { background: var(--surface-2); }

.cs-table tr[data-child-of] > td { padding: 0; background: var(--surface-2); }
.sub-table {
    width: 100%; border-collapse: collapse;
    /* inset so the nested table reads as belonging to the row above it */
    border-left: 3px solid var(--accent);
}
.sub-table th {
    padding: 7px 12px; text-align: left; font-size: 11px; font-weight: 600;
    letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3);
    border-bottom: 1px solid var(--line-soft); white-space: nowrap;
}
.sub-table td {
    padding: 7px 12px; font-size: 13px; color: var(--ink-2);
    border-bottom: 1px solid var(--line-soft);
}
.sub-table tr:last-child td { border-bottom: 0; }
.sub-table td.strong { color: var(--ink); font-weight: 600; }
.sub-table .num, .sub-table th.num { text-align: right; }

/* Definition list on the person report. */
.deflist { display: grid; grid-template-columns: 150px 1fr; gap: 9px 16px; margin: 0; }
.deflist dt { color: var(--ink-3); font-size: 12.5px; padding-top: 2px; }
.deflist dd { margin: 0; color: var(--ink); font-size: 13.5px; min-height: 22px; }

/* A KPI row nested inside a panel body needs no outer margin. */
.kpi-row-tight { margin: 0; }

/* Flash variants. The base .flash is informational. */
.flash-bad  { background: var(--bad-bg);  border-color: var(--bad);  color: var(--ink); }
.flash-warn { background: var(--warn-bg); border-color: var(--warn); color: var(--ink); }

.nowrap { white-space: nowrap; }
.sep    { color: var(--ink-3); margin: 0 2px; }

/* Organization context block on the person report: a person's consumption only
   means something against the contract it is drawn from. */
.org-context {
    margin-top: var(--sp-4); padding-top: var(--sp-4);
    border-top: 1px solid var(--line-soft);
}
.org-context-head {
    display: flex; align-items: center; gap: var(--sp-2);
    margin-bottom: var(--sp-3); font-weight: 600;
}
.org-context-row {
    display: grid; grid-template-columns: 145px 1fr auto;
    align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-2);
}
.org-context-row .lbl { color: var(--ink-3); font-size: 12.5px; }
.org-context-row .val { color: var(--ink-2); font-size: 12.5px; white-space: nowrap; }
/* Running-now panel. A job that has held one state for over a day has almost
   certainly not progressed — tint the whole row rather than only the age cell,
   so it reads at a glance while scanning the Job column. */
table.grid tr.is-stale td { background:var(--warn-bg); }
.panel-note strong.warn { color:var(--warn); font-weight:600; }

/* --- job detail: Model Doctor scene diagram ------------------------------- */
/* Two orthographic views of the room with the flagged objects pinned. The SVG
   itself is drawn by the Doctor (coolsim_view.py) and injected by
   CS.modelDiagram; everything here is the frame around it. */
.md-scene { margin: var(--sp-4) 0; }
.md-viewbar {
    display: flex; gap: var(--sp-2); align-items: center; margin-bottom: var(--sp-2);
}
.md-viewbar .btn.on {
    background: var(--accent); border-color: var(--accent); color: var(--ink-inv);
}
.md-hint { margin-left: auto; font-size: 12.5px; }

.md-diagram {
    border: 1px solid var(--line); border-radius: var(--r);
    background: var(--surface-2); padding: var(--sp-3);
    min-height: 96px; display: flex; align-items: center; justify-content: center;
    /* A wide room must not stretch the page; it scrolls inside its own box. */
    overflow: auto;
}
/* The renderer emits width="100%" and no height, so the viewBox aspect governs.
   Capped so a long thin room cannot push the findings list off the screen. */
.md-diagram svg { display: block; width: 100%; height: auto; max-height: 520px; }
.md-loading { font-size: 13px; }

/* Selected object. Set inline by the script as well -- see the note there about
   the SVG's own <style> block not always surviving innerHTML. */
.md-diagram svg .obj[data-hi] { stroke: var(--accent); }

.md-group { margin-top: var(--sp-4); }
.md-group h4 {
    display: flex; align-items: center; gap: var(--sp-2);
    margin: 0 0 2px; font-size: 13.5px; font-weight: 600;
}
.md-count {
    font-size: 11.5px; font-weight: 600; color: var(--ink-2);
    background: var(--surface-3); border-radius: 999px; padding: 1px 8px;
}
.md-group-sub { margin: 0 0 var(--sp-2); font-size: 12.5px; color: var(--ink-3); }

.md-findings { list-style: none; margin: 0; padding: 0; }
.md-finding {
    display: flex; gap: var(--sp-3); align-items: flex-start;
    padding: var(--sp-2) var(--sp-2);
    border: 1px solid transparent; border-radius: var(--r-sm);
}
.md-finding.can-locate { cursor: pointer; }
.md-finding.can-locate:hover, .md-finding.can-locate:focus {
    background: var(--surface-2); border-color: var(--line); outline: none;
}
.md-finding.on { background: var(--accent-dim); border-color: var(--accent); }

.md-dot {
    width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; margin-top: 6px;
}
.md-finding.sev-err  .md-dot { background: var(--bad); }
.md-finding.sev-warn .md-dot { background: var(--warn); }

.md-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.md-obj  { font-weight: 600; font-size: 13px; }
.md-msg  { font-size: 12.5px; color: var(--ink-2); }
.md-detail { font-size: 11.5px; color: var(--ink-3); word-break: break-word; }
.md-rule {
    margin-left: auto; flex: 0 0 auto; font-size: 11px; color: var(--ink-3);
    font-family: var(--mono);
}

/* --- job detail: FLUENT residual history ---------------------------------- */
/* Categorical series palette, five slots, assigned in fixed order and never
   cycled. Both modes were checked with the OKLCH/CVD validator against the
   surface they actually sit on -- light on --surface-2 #f9fafb, dark on
   #182534. Worst adjacent-pair separation is dE 13.7 (deutan) light and 11.6
   (protan) dark, both clear of the 8.0 floor; every step is inside its mode's
   lightness band with contrast >= 3:1. Dark is a re-step of the same hues, not
   a lightened flip of the light values. Do not hand-edit one without re-running
   the validator on the whole row. */
:root {
    --s1:#1a6fb5;  /* continuity */
    --s2:#c2410c;  /* x-velocity */
    --s3:#0d9488;  /* y-velocity */
    --s4:#7c3aed;  /* z-velocity */
    --s5:#a16207;  /* energy     */
}
:root[data-theme="dark"] {
    --s1:#4f97e0; --s2:#e0674c; --s3:#12a294; --s4:#8e72f2; --s5:#b8892c;
}

.chart.resid { width:100%; height:auto; display:block; overflow:visible; }
.chart.resid path { fill:none; stroke-width:2; stroke-linejoin:round; stroke-linecap:round; }
.chart.resid path.s1 { stroke:var(--s1); }
.chart.resid path.s2 { stroke:var(--s2); }
.chart.resid path.s3 { stroke:var(--s3); }
.chart.resid path.s4 { stroke:var(--s4); }
.chart.resid path.s5 { stroke:var(--s5); }
/* Grid and axes stay recessive -- they orient, they are not the message. */
.chart.resid .grid { stroke:var(--line-soft); stroke-width:1; }
.chart.resid .axis { stroke:var(--line); stroke-width:1; }
.chart.resid .lbl  { fill:var(--ink-3); font-size:12px; font-family:var(--font); }
/* Reference lines are annotations, not data: ink colours, never a series hue. */
.chart.resid .diverge-ref  { stroke:var(--bad);  stroke-width:1.5; stroke-dasharray:6 4; opacity:.75; }
.chart.resid .converge-ref { stroke:var(--ok);   stroke-width:1.5; stroke-dasharray:6 4; opacity:.75; }
.chart.resid .reflbl { fill:var(--ink-3); font-size:11px; font-family:var(--font); }
.chart.resid .restart { stroke:var(--ink-3); stroke-width:1; stroke-dasharray:2 4; opacity:.5; }

/* Crosshair + readout, added by CS.residualChart. */
.chart.resid .xhair { stroke:var(--ink-3); stroke-width:1; opacity:.55; }
.chart.resid .dot   { stroke:var(--surface); stroke-width:2; }

.resid-wrap { position:relative; }
.resid-tip {
    position:absolute; pointer-events:none; z-index:5; display:none;
    background:var(--surface); border:1px solid var(--line); border-radius:var(--r-sm);
    box-shadow:var(--shadow); padding:var(--sp-2) var(--sp-3); font-size:12px;
    min-width:184px;
}
.resid-tip.on { display:block; }
.resid-tip h5 { margin:0 0 var(--sp-1); font-size:12px; font-weight:600; }
.resid-tip .row { display:flex; align-items:center; gap:var(--sp-2); }
.resid-tip .row .sw { width:9px; height:9px; border-radius:2px; flex:0 0 auto; }
.resid-tip .row .nm { color:var(--ink-2); }
/* The value is the thing being read, so it wears ink and is the only bold
   item -- the swatch beside it already carries series identity. */
.resid-tip .row .vl { margin-left:auto; font-family:var(--mono); font-weight:600; }

/* Legend. Always present -- five series is past the point where direct labels
   on the plot would fit without collisions. */
.resid-legend { display:flex; flex-wrap:wrap; gap:var(--sp-2) var(--sp-4); margin-top:var(--sp-2); }
.resid-legend .k { display:flex; align-items:center; gap:var(--sp-2); font-size:12.5px; color:var(--ink-2); }
.resid-legend .k .sw { width:11px; height:3px; border-radius:2px; }
.resid-legend .k.s1 .sw { background:var(--s1); }
.resid-legend .k.s2 .sw { background:var(--s2); }
.resid-legend .k.s3 .sw { background:var(--s3); }
.resid-legend .k.s4 .sw { background:var(--s4); }
.resid-legend .k.s5 .sw { background:var(--s5); }

/* --- job detail: downloads ------------------------------------------------ */
.dl-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(250px,1fr)); gap:var(--sp-3); }
.dl-item {
    display:flex; gap:var(--sp-3); align-items:flex-start; padding:var(--sp-3);
    border:1px solid var(--line); border-radius:var(--r); background:var(--surface-2);
    text-decoration:none; color:inherit;
    transition:border-color .12s, box-shadow .12s;
}
a.dl-item:hover { border-color:var(--accent); box-shadow:var(--shadow); }
.dl-item .dl-ico {
    flex:0 0 auto; width:38px; height:38px;
    display:flex; align-items:center; justify-content:center;
    border-radius:var(--r-sm); background:var(--accent-dim); color:var(--accent);
}
.dl-item .dl-ico .ico { width:20px; height:20px; }
.dl-item .dl-b { display:flex; flex-direction:column; gap:2px; min-width:0; }
.dl-item .dl-n { font-weight:600; font-size:13px; word-break:break-all; }
.dl-item .dl-k {
    font-size:11px; font-weight:600; letter-spacing:.02em;
    color:var(--ink-2); text-transform:uppercase;
}
.dl-item .dl-d { font-size:12px; color:var(--ink-3); }
.dl-item .dl-get {
    flex:0 0 auto; margin-left:auto; align-self:center;
    color:var(--ink-3); opacity:0; transition:opacity .12s;
}
.dl-item .dl-get .ico { width:16px; height:16px; }
a.dl-item:hover .dl-get { opacity:1; color:var(--accent); }
.dl-item.is-missing { opacity:.55; }
.dl-item.is-missing .dl-ico { background:var(--surface-3); color:var(--ink-3); }
.dl-item.is-missing .dl-d { font-style:italic; }

/* --- licence seat map ------------------------------------------------------ */
/* One cell per licensed seat, so "how many are left" is a count of dashed
   boxes rather than arithmetic. A client holding two seats fills two cells --
   consulting boxes routinely do, and drawing them as one would misreport the
   pool. See view/licences.php. */
.seatmap { display:flex; gap:10px; flex-wrap:wrap; }
.seat {
    flex:1 1 150px; min-width:150px; border:1px solid var(--line);
    border-radius:var(--r); padding:11px 12px; background:var(--surface-2);
}
.seat.taken { background:var(--bad-bg); border-color:var(--bad); }
.seat.free  { border-style:dashed; }
.seat-n {
    font-size:10px; text-transform:uppercase; letter-spacing:.08em;
    color:var(--ink-3); font-weight:600;
}
.seat.taken .seat-n { color:var(--bad); }
.seat-who { font-family:var(--mono); font-size:12px; margin-top:3px; font-weight:600; }
.seat.free .seat-who { color:var(--ink-3); font-weight:400; }
.seat-meta { font-size:11px; color:var(--ink-3); margin-top:2px; }
