@font-face{font-family:"Inter";font-style:normal;font-weight:100 900;font-display:swap;src:url(/static/inter.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
:root{--bg:#f5f6fa;--card:#fff;--line:#e4e7ef;--line-strong:#cfd4e0;--text:#111827;--muted:#667085;--accent:#4048c8;--accent-bg:#eef0ff;--good:#12805c;--good-bg:#e6f6ef;--bad:#c2362f;--bad-bg:#fdecea;--warn:#b25e09;--warn-bg:#fdf2e3;--bar:#2a78d6;--shadow:0 1px 2px rgb(16 24 40/.05);--shadow-hover:0 4px 12px rgb(16 24 40/.08);color-scheme:light}
@media (prefers-color-scheme:dark){:root{--bg:#0b0f1a;--card:#131a2b;--line:#243049;--line-strong:#34425f;--text:#e8ecf6;--muted:#8d97ad;--accent:#8b97ff;--accent-bg:rgb(139 151 255/.14);--good:#45c795;--good-bg:rgb(69 199 149/.14);--bad:#f07a72;--bad-bg:rgb(240 122 114/.14);--warn:#f0a54a;--warn-bg:rgb(240 165 74/.14);--bar:#3987e3;--shadow:none;--shadow-hover:0 4px 16px rgb(0 0 0/.35);color-scheme:dark}}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--text);font:14.5px/1.55 "Inter",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;font-feature-settings:"cv11","tnum" 0;-webkit-font-smoothing:antialiased}
a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:6px}
h1{font-size:1.55rem;margin:0;letter-spacing:-.025em;font-weight:700}h2{font-size:1rem;margin:0 0 12px;font-weight:650;letter-spacing:-.01em}
.sub{margin:4px 0 0;color:var(--muted);font-size:.88rem}
h2.group{font-size:.72rem;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);font-weight:650;margin:22px 0 10px}
h2.group:first-of-type{margin-top:4px}
/* Header: brand | nav | account. On a phone the nav gets its own row and scrolls. */
.top{position:sticky;top:0;z-index:5;display:flex;align-items:center;gap:20px;padding:0 24px;min-height:58px;background:color-mix(in srgb,var(--card) 92%,transparent);backdrop-filter:saturate(1.4) blur(8px);border-bottom:1px solid var(--line)}
.brand{font-weight:750;color:var(--text);letter-spacing:-.02em;white-space:nowrap;display:flex;align-items:center}.brand:hover{text-decoration:none}
.brand span{font-weight:650;font-size:.7rem;padding:2px 8px;border-radius:99px;background:var(--accent);color:var(--card);margin-left:8px;letter-spacing:.02em}
.top nav{display:flex;gap:2px;flex:1;overflow-x:auto;scrollbar-width:none}
.top nav::-webkit-scrollbar{display:none}
.top nav a{padding:7px 12px;border-radius:8px;color:var(--muted);font-weight:550;white-space:nowrap;font-size:.92rem}
.top nav a:hover{color:var(--text);background:var(--bg);text-decoration:none}
.top nav a[aria-current]{background:var(--accent-bg);color:var(--accent)}
.me{display:flex;align-items:center;gap:14px;white-space:nowrap}
.who{display:flex;align-items:center;gap:8px;color:var(--text);font-weight:550;font-size:.9rem;padding:4px 10px 4px 4px;border-radius:99px;border:1px solid var(--line)}
.who:hover{text-decoration:none;border-color:var(--line-strong)}.who[aria-current]{border-color:var(--accent)}
.avatar{display:grid;place-items:center;width:26px;height:26px;border-radius:50%;background:var(--accent);color:var(--card);font-size:.75rem;font-weight:700}
.page{max-width:1200px;margin:0 auto;padding:28px 24px 64px}
.center{min-height:100vh;display:grid;place-items:center;padding:16px}
.head{display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:18px}
.card{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:20px;margin-bottom:16px;min-width:0;box-shadow:var(--shadow)}
.card.flush{padding:0;overflow-x:auto}.pad{padding:16px 20px 0}.narrow{max-width:460px}
.login{width:100%;max-width:380px;display:flex;flex-direction:column;gap:14px}
label{display:flex;flex-direction:column;gap:6px;font-weight:550;font-size:.9rem}
input,select{font:inherit;color:inherit;background:var(--card);border:1px solid var(--line-strong);border-radius:10px;padding:9px 12px;min-height:40px}
input:focus,select:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:transparent}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:38px;padding:0 16px;border-radius:10px;border:1px solid var(--line-strong);background:var(--card);color:var(--text);font:inherit;font-weight:600;font-size:.88rem;cursor:pointer;white-space:nowrap;box-shadow:var(--shadow);transition:border-color .15s,background .15s}
.btn:hover{text-decoration:none;border-color:var(--muted)}
.btn.primary{background:var(--accent);border-color:transparent;color:var(--card)}.btn.primary:hover{filter:brightness(1.08)}
.btn.danger{background:var(--bad);border-color:transparent;color:#fff}.btn.danger:hover{filter:brightness(1.08)}
button.link{background:none;border:0;color:var(--muted);font:inherit;font-size:.9rem;cursor:pointer;padding:6px 2px}button.link:hover{color:var(--text)}
@media (max-width:860px){
  .top{flex-wrap:wrap;gap:0 12px;padding:8px 12px 0}
  .top nav{order:3;flex-basis:100%;margin:6px -12px 0;padding:0 12px 8px;mask-image:linear-gradient(90deg,#000 85%,transparent)}
  .me{margin-left:auto}.who-name{display:none}.who{padding:3px;border:0}
}
.tiles{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin-bottom:16px}
.tile{display:flex;flex-direction:column;gap:4px;background:var(--card);border:1px solid var(--line);border-radius:14px;padding:16px 18px;color:var(--text);box-shadow:var(--shadow);transition:box-shadow .15s,border-color .15s;min-width:0}
a.tile:hover{text-decoration:none;border-color:var(--line-strong);box-shadow:var(--shadow-hover)}
.tile span{color:var(--muted);font-size:.82rem;font-weight:550}.tile b{font-size:1.65rem;font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1.2}.tile small{color:var(--muted);font-size:.8rem}
.tile.warn{box-shadow:inset 3px 0 0 var(--warn),var(--shadow)}.tile.warn b{color:var(--warn)}
.grid2{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px}
table{width:100%;border-collapse:collapse;font-size:.9rem}
th{text-align:left;font-size:.72rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);padding:10px 16px;border-bottom:1px solid var(--line);white-space:nowrap}
td{padding:10px 16px;border-bottom:1px solid var(--line);vertical-align:top}
tbody tr:last-child td{border-bottom:0}tr.dim{opacity:.55}
tbody tr:hover td{background:color-mix(in srgb,var(--bg) 60%,transparent)}
table.plain td{padding:8px 0}
.r{text-align:right;font-variant-numeric:tabular-nums}.nowrap{white-space:nowrap}
.muted{color:var(--muted)}.small{font-size:.8rem}.mono{font-family:ui-monospace,Menlo,monospace}.bad-text{color:var(--bad)}
.badge{display:inline-block;padding:1px 9px;border-radius:99px;font-size:.75rem;font-weight:650;background:var(--bg);color:var(--muted);white-space:nowrap}
.badge.good{background:var(--good-bg);color:var(--good)}.badge.bad{background:var(--bad-bg);color:var(--bad)}.badge.warn{background:var(--warn-bg);color:var(--warn)}
.alert{padding:10px 14px;border-radius:10px;margin:0 0 16px}.alert.good{background:var(--good-bg)}.alert.bad{background:var(--bad-bg)}
.filters{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:16px}.filters input{flex:1;min-width:200px;max-width:360px}
.pager{display:flex;gap:8px;align-items:center;justify-content:flex-end;padding:12px 16px;border-top:1px solid var(--line)}
.pager span{margin-right:auto;color:var(--muted)}
.seg{display:inline-flex;gap:2px;padding:3px;border:1px solid var(--line);border-radius:10px;background:var(--card)}
.seg a{padding:5px 12px;border-radius:7px;color:var(--muted);font-weight:600}.seg a[aria-current]{background:var(--bg);color:var(--text)}
.cols{display:block;width:100%;height:120px;border-bottom:1px solid var(--line)}
.cols .hit{fill:transparent}.cols g:hover .hit{fill:var(--bg)}
.cols .bar{fill:var(--bar)}
code{font-family:ui-monospace,Menlo,monospace;font-size:.85em;background:var(--card);border:1px solid var(--line);padding:1px 6px;border-radius:6px}
@media (max-width:860px){.tiles{grid-template-columns:repeat(2,minmax(0,1fr))}.grid2{grid-template-columns:minmax(0,1fr)}.page{padding:20px 12px 48px}.tile b{font-size:1.35rem}}
.card h2:not(:first-child){margin-top:20px}

/* ---- Logs ---------------------------------------------------------------- */
/* Service tabs. Wider than .seg because each carries a count. */
.tabs{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:16px}
.tab{display:flex;flex-direction:column;gap:6px;padding:10px 16px;border:1px solid var(--line);border-radius:12px;background:var(--card);color:var(--muted);font-weight:600;min-width:150px}
.tab.on{border-color:var(--accent);color:var(--text)}
.tab:hover{text-decoration:none;border-color:var(--muted)}
.tab .badge{font-weight:650}
/* One card per instance: state first, because "is it running" is the question. */
.instances{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:10px;margin-bottom:8px}
.inst{display:flex;flex-direction:column;gap:3px;padding:12px 14px;border:1px solid var(--line);border-radius:12px;color:var(--text)}
.inst.on{border-color:var(--accent)}
.inst:hover{text-decoration:none;border-color:var(--muted)}
.inst b{font-weight:650;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.filters .check{flex-direction:row;align-items:center;gap:6px;font-weight:500;color:var(--muted)}
.filters select{min-height:40px}
td.pad-cell{padding:24px 16px}
.lead{font-size:1.05rem;margin:0 0 10px;display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.errtext{margin:0 0 12px;padding:10px 14px;border-radius:10px;background:var(--bad-bg);color:var(--bad);font-size:.85rem;white-space:pre-wrap;word-break:break-word}
.facts th{width:120px;text-transform:none;letter-spacing:0;font-size:.8rem;padding:6px 12px 6px 0;border:0;vertical-align:top}
.facts td{border:0;padding:6px 0}
.stack{margin:0;padding:14px;border-radius:10px;background:var(--bg);border:1px solid var(--line);overflow-x:auto;font-family:ui-monospace,Menlo,monospace;font-size:.78rem;line-height:1.55;white-space:pre-wrap;word-break:break-word}
tr.here{background:var(--bg)}

/* ---- Health --------------------------------------------------------------- */
.health-head{display:flex;align-items:center;gap:10px;margin-bottom:6px}
.health-head h2{margin:0}
.lead-sm{margin:0 0 14px;color:var(--muted)}
/* How full the database pool is. */
.meter{display:block;width:100%;height:5px;border-radius:99px;background:var(--bg);overflow:hidden;margin-top:4px;min-width:60px}
.meter rect{fill:var(--bar)}
/* Memory over 48 hours. A shape, not a chart: is this line going up? */
.spark{width:110px;height:30px;display:block}
.spark polyline{fill:none;stroke:var(--bar);stroke-width:1.5;vector-effect:non-scaling-stroke}
tr.strain td{padding-top:0;border-bottom:1px solid var(--line);font-size:.85rem}
/* Why something is not ok. Stated, not hinted at. */
.why{padding:12px 14px;border-radius:10px;background:var(--bg);border:1px solid var(--line);margin:0 0 16px}
.why-bad{background:var(--bad-bg);border-color:transparent}
.why b{font-size:.85rem}
ul.reasons{margin:6px 0 0;padding-left:18px}
ul.reasons li{margin:3px 0;font-size:.88rem;color:var(--muted)}
.why-bad ul.reasons li{color:var(--text)}
.alert.warn{background:var(--warn-bg)}
.actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:8px 0}
.actions label{display:flex;gap:8px;align-items:center}
.danger-zone{margin-top:12px;border-top:1px solid var(--line);padding-top:12px}
.danger-zone summary{cursor:pointer;color:var(--bad)}
.bar-cell{width:40%}.bar-cell .bar{fill:var(--bar)}
/* Phone: wide tables scroll sideways inside their card instead of
   squeezing every cell into a tall column. */
@media (max-width:860px){.card.flush table{min-width:720px}td{white-space:nowrap}td .small,td .muted{white-space:normal}}
/* Control and Backups */
.form-stack{display:flex;flex-direction:column;gap:10px;margin:10px 0 0;max-width:520px}
.form-stack label{display:flex;flex-direction:column;gap:4px;font-size:.88rem}
.form-stack input{height:38px;padding:0 10px;border:1px solid var(--line-strong);border-radius:8px;background:var(--card);color:var(--text);font:inherit}
.inline-confirm{display:inline-block;text-align:right}
.inline-confirm summary{list-style:none}.inline-confirm summary::-webkit-details-marker{display:none}
.inline-confirm[open] summary{display:none}
.inline-confirm form{margin:0}
.btn[disabled]{opacity:.5;cursor:not-allowed}
.wrap{white-space:pre-wrap;word-break:break-word;max-width:520px}
pre.output{margin:6px 0 0;padding:10px;border-radius:8px;background:var(--bg);border:1px solid var(--line);font-family:ui-monospace,Menlo,monospace;font-size:.75rem;white-space:pre-wrap;word-break:break-word;max-height:240px;overflow:auto}
.uptime{display:flex;gap:24px;flex-wrap:wrap;margin:8px 0 12px}.uptime div{display:flex;flex-direction:column}.uptime b{font-size:1.25rem;font-variant-numeric:tabular-nums}
.alert:not(.good):not(.bad):not(.warn){background:var(--bg);border:1px solid var(--line)}
.job-list{list-style:none;margin:8px 0 0;padding:0}
.job-list li{display:flex;flex-wrap:wrap;gap:8px 16px;align-items:center;justify-content:space-between;padding:12px 20px;border-top:1px solid var(--line)}
.job-list li>div{flex:1 1 240px;min-width:0}
.job-list form{margin:0}
.head.pad+.note{padding-top:0;margin:-8px 0 0}

/* ============================================================================
   Modern additions for VaultHub Admin 2026
   Tokens (CSS custom properties) stay in :root above; classes below use
   them so dark/light adjust automatically.

   - .badge           small status pill (succeeded | failed | warn | info)
   - .segments        saved filter chips with active state
   - .bulk-actions    toolbar that docks to the data table on scroll
   - .data-table      dense, sticky-header tables with row hover and selection
   - .filters         inline search row used by /users, /deployments etc.
   - .deploy-form     small grid layout for the rollout card
   ============================================================================ */

.badge{display:inline-block;padding:2px 8px;border-radius:999px;font-size:.72rem;font-weight:650;letter-spacing:.01em;line-height:1.6;text-transform:lowercase}
.badge-succeeded{background:var(--good-bg);color:var(--good)}
.badge-failed{background:var(--bad-bg);color:var(--bad)}
.badge-warn{background:var(--warn-bg);color:var(--warn)}
.badge-info{background:var(--accent-bg);color:var(--accent)}
.badge-pending{background:var(--bg);color:var(--muted);border:1px solid var(--line)}

.segments{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:0 0 12px;padding:10px 12px;border:1px solid var(--line);border-radius:8px;background:var(--bg)}
.segments .muted{margin-right:4px;font-size:.78rem}
.segments .chip{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;border-radius:999px;background:var(--card);border:1px solid var(--line);font-size:.78rem;color:var(--muted);text-decoration:none}
.segments .chip:hover{color:var(--text);text-decoration:none}
.segments .chip.active{background:var(--accent);color:var(--card);border-color:var(--accent)}
.segments .chip small{opacity:.7}
.segments form{display:inline-flex;gap:6px;align-items:center;margin-left:auto}
.segments form input[type=text]{padding:4px 8px;border:1px solid var(--line);border-radius:6px;background:var(--card);color:var(--text);font-size:.78rem}

.filters{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 14px;align-items:center}
.filters input,.filters select{padding:7px 10px;border:1px solid var(--line);border-radius:8px;background:var(--card);color:var(--text);font-size:.88rem}
.filters input{flex:1;min-width:200px}
.filters button{padding:7px 14px;background:var(--accent);color:var(--card);border:0;border-radius:8px;font-weight:600;cursor:pointer}

.data-table{width:100%;border-collapse:separate;border-spacing:0;font-size:.88rem}
.data-table thead th{position:sticky;top:0;background:var(--card);text-align:left;padding:10px 14px;border-bottom:1px solid var(--line);font-weight:650;font-size:.78rem;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;z-index:1}
.data-table tbody td{padding:10px 14px;border-bottom:1px solid var(--line);vertical-align:middle}
.data-table tbody tr:hover{background:var(--bg)}
.data-table .r{text-align:right;font-variant-numeric:tabular-nums}

.bulk-actions{position:sticky;bottom:0;display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:10px 14px;margin-top:14px;background:var(--card);border:1px solid var(--line);border-radius:8px;box-shadow:var(--shadow-hover)}
.bulk-actions select{padding:7px 10px;border:1px solid var(--line);border-radius:8px;background:var(--card);color:var(--text);font-size:.88rem;min-width:200px}
.bulk-actions button{padding:7px 14px;background:var(--accent);color:var(--card);border:0;border-radius:8px;font-weight:600;cursor:pointer}

.deploy-form{display:grid;grid-template-columns:1fr 1fr 1fr auto;gap:8px;align-items:end}
.deploy-form label{display:flex;flex-direction:column;gap:4px;font-size:.78rem;color:var(--muted)}
.deploy-form .full{grid-column:1/-1}
.deploy-form input,.deploy-form select,.deploy-form textarea{padding:8px 10px;border:1px solid var(--line);border-radius:8px;background:var(--card);color:var(--text);font-size:.88rem;font-family:inherit}
.deploy-form button{padding:9px 18px;background:var(--accent);color:var(--card);border:0;border-radius:8px;font-weight:600;cursor:pointer;align-self:end}
@media (max-width:700px){.deploy-form{grid-template-columns:1fr 1fr}}

.link.danger{color:var(--bad);background:none;border:0;padding:0;font:inherit;cursor:pointer}
.link.danger:hover{text-decoration:underline}

/* Accessibility: focus ring on inputs in new sections */
.filters input:focus-visible,.filters select:focus-visible,
.data-table :focus-visible,.deploy-form *:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:8px}

/* Skeletons / placeholder while data loads (used by HTMX fragments) */
.skeleton{background:linear-gradient(90deg,var(--bg) 0%,var(--card) 50%,var(--bg) 100%);background-size:200% 100%;animation:skel 1.2s linear infinite;border-radius:6px;color:transparent}
@keyframes skel{0%{background-position:200% 0}100%{background-position:-200% 0}}
@media (prefers-reduced-motion:reduce){.skeleton{animation:none}}

/* Toast: success / error notifications posted from any page */
.toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);padding:10px 18px;border-radius:8px;background:var(--text);color:var(--bg);font-size:.9rem;font-weight:500;box-shadow:var(--shadow-hover);z-index:100;animation:fade-in 240ms var(--ease)}
.toast.good{background:var(--good);color:var(--card)}
.toast.bad{background:var(--bad);color:var(--card)}
@keyframes fade-in{from{opacity:0;transform:translateX(-50%) translateY(8px)}to{opacity:1;transform:translateX(-50%) translateY(0)}}

/* SSR friendly — define --ease used by toast animation if not already in root */
:root{--ease:cubic-bezier(0.2,0.8,0.2,1)}

/* ---- Monitoring page ---------------------------------------------------- */
/* 2-up grid of cards; the kpi row inside each card puts four small numbers
   in a row next to the title so the headline info is above the fold. */
.grid.two{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px;margin-bottom:16px}
@media (max-width:860px){.grid.two{grid-template-columns:minmax(0,1fr)}}
.card > header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:8px;flex-wrap:wrap}
.card > header h2{margin:0}
.kpi{display:flex;gap:18px;align-items:flex-end;flex-wrap:wrap}
.kpi > div{display:flex;flex-direction:column;align-items:flex-end;line-height:1.1}
.kpi b{font-size:1.15rem;font-weight:700;font-variant-numeric:tabular-nums;letter-spacing:-.01em;color:var(--text)}
.kpi span{font-size:.72rem;color:var(--muted);text-transform:uppercase;letter-spacing:.06em;margin-top:2px}
.card .spark{display:block;width:100%;height:60px;margin:8px 0 6px;color:var(--accent);overflow:visible}
table.kv{font-size:.88rem}
table.kv th{font-weight:600;text-transform:none;letter-spacing:0;color:var(--muted);padding:6px 0;width:1%;white-space:nowrap;border-bottom:0}
table.kv td{padding:6px 0;border-bottom:0;font-variant-numeric:tabular-nums}
table.kv tr{border-bottom:1px solid var(--line)}
table.kv tr:last-child{border-bottom:0}
.card > footer{display:flex;align-items:center;gap:12px;margin-top:14px;padding-top:12px;border-top:1px solid var(--line);flex-wrap:wrap}
.card > footer .muted{font-size:.8rem}
.card h3{font-size:.72rem;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);font-weight:600;margin:18px 0 8px}
.card h3:first-of-type{margin-top:8px}
.card.bad-card{border-color:var(--bad);background:color-mix(in srgb,var(--bad-bg) 60%,var(--card))}
button.link.danger{color:var(--bad);background:transparent;border:0;padding:6px 10px;border-radius:6px;cursor:pointer;font:inherit;font-weight:600}
button.link.danger:hover{background:var(--bad-bg)}
form.inline{display:inline-flex;gap:6px;align-items:center}
.head .seg .muted{padding:5px 12px}
