/* pech admin.
 *
 * A control surface, not a document: scanned and operated rather than read top to bottom. So
 * state is encoded in shape as well as in number, and every figure carries where it came from
 * — measured, derived, or absent. A number with no source is a number nobody can check, and
 * this panel's whole job is telling an operator what is true about their node.
 *
 * Warm paper rather than the usual dashboard grey: this is a tool people keep open for hours,
 * and a cold ground makes the accent colour do work the accent should not have to do.
 */

:root {
  --ground:#f5f3ee; --surface:#ffffff; --sunken:#edeae3;
  --ink:#17150f; --ink2:#55503f; --ink3:#857e6a;
  --rule:#d9d3c6; --rule2:#ebe6db;
  --ember:#c94000; --ember2:#f7ede7;
  --ok:#2c6e49; --okbg:#e6f0e9;
  --warn:#8a5c00; --warnbg:#f6eddb;
  --crit:#9d211b; --critbg:#f7e7e5;
  --void:#6b6455; --voidbg:#eae7df;
  --mono:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,monospace;
  --sans:ui-sans-serif,-apple-system,"Segoe UI",Helvetica,sans-serif;
}

/* The un-stamped default: only prefers-color-scheme separates light from dark here, and an
   explicit light choice must still win over a dark system setting. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground:#131210; --surface:#1b1a17; --sunken:#100f0d;
    --ink:#f0ece2; --ink2:#b8b2a2; --ink3:#847e6e;
    --rule:#332f28; --rule2:#26231e;
    --ember:#ff6a2b; --ember2:#2a1710;
    --ok:#6fbf8f; --okbg:#14251b;
    --warn:#d6a55c; --warnbg:#2a2113;
    --crit:#f0817a; --critbg:#2b1614;
    --void:#8b8474; --voidbg:#1d1b17;
  }
}
:root[data-theme="dark"] {
  --ground:#131210; --surface:#1b1a17; --sunken:#100f0d;
  --ink:#f0ece2; --ink2:#b8b2a2; --ink3:#847e6e;
  --rule:#332f28; --rule2:#26231e;
  --ember:#ff6a2b; --ember2:#2a1710;
  --ok:#6fbf8f; --okbg:#14251b;
  --warn:#d6a55c; --warnbg:#2a2113;
  --crit:#f0817a; --critbg:#2b1614;
  --void:#8b8474; --voidbg:#1d1b17;
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
body{font-family:var(--sans);font-size:13.5px;color:var(--ink);background:var(--ground);line-height:1.5;-webkit-font-smoothing:antialiased}
a{color:var(--ember);text-decoration:none}
a:hover{color:var(--ink)}
:focus-visible{outline:2px solid var(--ember);outline-offset:2px}

/* --- Frame ------------------------------------------------------------- */

.app{display:grid;grid-template-columns:196px 1fr;min-height:100vh}
/* Signed out there is no rail, so there is no column for it. Hiding the rail alone removes it
   from the grid and the content slides into the 196px track meant for it. */
.app.no-rail{grid-template-columns:1fr}

.rail{background:var(--sunken);border-right:1px solid var(--rule);padding:14px 0;font-family:var(--mono);font-size:12px;display:flex;flex-direction:column;position:sticky;top:0;height:100vh;overflow-y:auto}
.brand{display:flex;align-items:center;gap:9px;padding:0 14px 13px;border-bottom:1px solid var(--rule);margin-bottom:6px;font-weight:700;letter-spacing:.04em;font-size:13px}
.mark{width:14px;height:14px;background:var(--ember);flex:none}
.rgroup{padding:12px 14px 4px;font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink3)}
.ritem{display:block;padding:5px 14px;color:var(--ink2);border-left:2px solid transparent}
.ritem:hover{color:var(--ink);background:var(--rule2)}
.ritem.active{color:var(--ink);background:var(--surface);border-left-color:var(--ember);font-weight:600}
#logout-btn{margin:auto 14px 4px;background:none;border:1px solid var(--rule);color:var(--ink3);padding:5px 10px;font-family:var(--mono);font-size:11px;cursor:pointer}
#logout-btn:hover{color:var(--crit);border-color:var(--crit)}

main{padding:20px 24px 40px;max-width:1280px}
.page{display:flex;flex-direction:column;gap:18px}

h2{font-family:var(--sans);font-size:17px;font-weight:620;letter-spacing:-.01em;padding-bottom:10px;border-bottom:1px solid var(--rule);text-wrap:balance}
h3{font-size:13px;font-weight:640;margin-bottom:9px}

/* --- Figures ------------------------------------------------------------
 * Hairline grid rather than floating cards: the figures are one instrument
 * read together, and a gap between cards invites reading them separately. */

.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(172px,1fr));gap:1px;background:var(--rule);border:1px solid var(--rule)}
.stat-card{background:var(--surface);padding:12px 14px;display:flex;flex-direction:column;gap:3px;min-width:0}
.stat-card .label{font-family:var(--mono);font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink3)}
.stat-card .value{font-family:var(--mono);font-size:20px;font-weight:600;letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1.15;overflow-wrap:anywhere;color:var(--ink)}
.stat-card .value.ok{color:var(--ok)} .stat-card .value.crit{color:var(--crit)} .stat-card .value.warn{color:var(--warn)}

/* A value copied character by character — an address, a key, a port. Breaking one across
   lines is how a digit goes missing between the screen and a config file. */
.value-atomic{overflow-wrap:normal;word-break:keep-all;white-space:nowrap;overflow-x:auto;font-size:15px}

/* --- Provenance ---------------------------------------------------------
 * Where a figure came from, next to the figure. */

.prov{font-family:var(--mono);font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink3);display:flex;align-items:center;gap:5px;margin-top:2px}
.prov::before{content:"";width:6px;height:6px;flex:none}
.prov-measured::before{background:var(--ok)}
.prov-derived::before{background:var(--ink3)}
.prov-absent{font-family:var(--mono);font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink3);display:flex;align-items:center;gap:5px;margin-top:2px}
.prov-absent::before{content:"";width:6px;height:6px;flex:none;box-shadow:inset 0 0 0 1px var(--ink3)}

/* A designed absence. Not an empty box: a blank panel reads as broken or still loading, and
   the difference between "zero" and "never measured" is the thing an operator needs. */
.void-state{border:1px dashed var(--rule);background:var(--voidbg);padding:16px;flex:1;min-width:220px;display:flex;flex-direction:column;gap:5px}
.void-title{font-size:13px;font-weight:620;color:var(--ink2)}
.void-detail{font-size:12px;color:var(--ink3);line-height:1.5}

/* --- Tables -------------------------------------------------------------- */

.tw{overflow-x:auto;border:1px solid var(--rule);background:var(--surface)}
table{width:100%;border-collapse:collapse;font-size:12.5px}
th,td{text-align:left;padding:8px 12px;border-bottom:1px solid var(--rule2)}
th{font-family:var(--mono);font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink3);background:var(--sunken);font-weight:500;white-space:nowrap}
td{font-family:var(--mono);font-variant-numeric:tabular-nums;color:var(--ink2)}
td:first-child{color:var(--ink);font-weight:600}
tbody tr:last-child td{border-bottom:none}
tbody tr:hover td{background:var(--rule2)}

/* --- Panels, forms, messages --------------------------------------------- */

.panel{background:var(--surface);border:1px solid var(--rule);padding:14px}
.panel ul{padding-left:18px}
.panel li{margin:4px 0;font-size:12.5px;color:var(--ink2)}

button,input,select,textarea{font-family:var(--mono);font-size:12.5px;color:var(--ink)}
button{background:var(--ink);color:var(--ground);border:none;padding:6px 14px;cursor:pointer;font-weight:600;letter-spacing:.01em}
button:hover{background:var(--ember)}
input,select,textarea{background:var(--surface);border:1px solid var(--rule);padding:6px 9px;min-width:0}
input:focus,select:focus,textarea:focus{border-color:var(--ember);outline:none}
input::placeholder{color:var(--ink3)}

.form-row{display:flex;gap:9px;align-items:center;margin:7px 0;flex-wrap:wrap}
.form-col{display:flex;flex-direction:column;gap:9px;max-width:640px;margin:9px 0}
.form-row label{min-width:104px;font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink3)}

/* A field's meaning must not live only in its placeholder: the hint disappears exactly when
   the value appears, so a filled form becomes a row of unlabelled boxes. */
.field{display:flex;flex-direction:column;gap:3px}
.field > label{font-family:var(--mono);font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink3)}
.field-note{font-size:11.5px;color:var(--ink3)}

/* An empty message is not a message: without this the border draws a stray mark under every
   form that has not said anything yet. */
.msg:empty{display:none}
.msg{padding:9px 12px;margin:9px 0;font-size:12.5px;border-left:2px solid}
.msg-ok{background:var(--okbg);border-color:var(--ok);color:var(--ok)}
.msg-err{background:var(--critbg);border-color:var(--crit);color:var(--crit)}

pre{background:var(--sunken);border:1px solid var(--rule);padding:11px;overflow-x:auto;font-family:var(--mono);font-size:11.5px;margin:9px 0;color:var(--ink2)}
.qr-wrap{background:#fff;padding:10px;border:1px solid var(--rule);display:inline-block}
.qr-wrap svg{display:block;height:240px;width:240px}

/* --- Login --------------------------------------------------------------- */

.gate{width:min(340px,100%);margin:12vh auto;display:flex;flex-direction:column;gap:12px}

@media (max-width:760px){
  .app{grid-template-columns:1fr}
  .rail{position:static;height:auto;flex-direction:row;flex-wrap:wrap;align-items:center;gap:2px;padding:8px}
  .rail nav{display:flex;flex-wrap:wrap;gap:2px}
  .rgroup{display:none}
  .brand{border:none;margin:0;padding:0 10px 0 4px}
  .ritem{border-left:none;border-bottom:2px solid transparent;padding:4px 8px}
  .ritem.active{border-left:none;border-bottom-color:var(--ember)}
  main{padding:14px}
}
