f473be4033
Add an optional auth-token (bearer) field and a custom-headers textarea to
the MCP 'Add server' pane. URL-mode servers are now registered by writing
hermes config directly via the venv's config helpers (save_env_value +
save_config) instead of shelling into the interactive, network-probing
'hermes mcp add --url' flow that hung/504'd on auth challenges.
- Token is stored in ~/.hermes/.env (mode 600) and referenced in config.yaml
as 'Authorization: Bearer ${MCP_<NAME>_API_KEY}' — never plaintext config.
- Registration is non-blocking: no live probe, so a slow/unreachable server
can't hang the request.
- Add a per-server 'Test' button (POST /api/mcp/test -> hermes mcp test).
- Contract tests for the new fields, payload, no-probe path, and test route.
1665 lines
38 KiB
CSS
1665 lines
38 KiB
CSS
/* HERMES · Operations Console
|
|
* ─────────────────────────────────────────────────────────────────────────
|
|
* Aesthetic: aerospace technical document. Warm document cream, deep ink,
|
|
* single hazard-orange accent. Stencil display + grotesk body + slab mono.
|
|
* Generous whitespace, hairline rules, corner registration marks, faint
|
|
* grid background. The look of an FAA ops binder, deliberately.
|
|
*/
|
|
|
|
:root {
|
|
/* Paper stock */
|
|
--paper: #f6f1e3;
|
|
--paper-2: #efe9d6;
|
|
--paper-3: #e6ddc4;
|
|
--paper-4: #ddd2b6;
|
|
--paper-card: #faf6ea;
|
|
|
|
/* Ink */
|
|
--ink: #1c1c1f;
|
|
--ink-2: #46443d;
|
|
--ink-3: #807c6c;
|
|
--ink-4: #b0aa97;
|
|
|
|
/* Rules */
|
|
--rule: #c4bba1;
|
|
--rule-soft: #d9d1ba;
|
|
--rule-faint: #e5ddc6;
|
|
|
|
/* Accents — single hazard orange, used surgically */
|
|
--hazard: #c95a2b;
|
|
--hazard-deep: #a4471f;
|
|
--hazard-soft: rgba(201, 90, 43, 0.10);
|
|
--hazard-line: rgba(201, 90, 43, 0.30);
|
|
|
|
/* Signal — quieted */
|
|
--ok: #5d7a32;
|
|
--ok-soft: rgba(93, 122, 50, 0.10);
|
|
--err: #8c2727;
|
|
--err-soft: rgba(140, 39, 39, 0.08);
|
|
--info: #2d5d80;
|
|
|
|
/* Type */
|
|
--ff-display: "Big Shoulders Stencil Display", "Big Shoulders Display", "Impact", sans-serif;
|
|
--ff-sans: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
|
|
--ff-mono: "JetBrains Mono", ui-monospace, "Menlo", "Consolas", monospace;
|
|
|
|
/* Geometry */
|
|
--nav-w: 236px;
|
|
--readout-h: 32px;
|
|
--gutter: 28px;
|
|
--radius: 3px; /* very small — feels printed, not webby */
|
|
--radius-md: 5px;
|
|
}
|
|
|
|
*, *::before, *::after { box-sizing: border-box; }
|
|
|
|
html, body {
|
|
margin: 0;
|
|
padding: 0;
|
|
background: var(--paper);
|
|
color: var(--ink);
|
|
font-family: var(--ff-sans);
|
|
font-size: 14px;
|
|
line-height: 1.5;
|
|
height: 100vh;
|
|
overflow: hidden;
|
|
-webkit-font-smoothing: antialiased;
|
|
}
|
|
|
|
body {
|
|
display: grid;
|
|
grid-template-columns: var(--nav-w) 1fr;
|
|
grid-template-rows: 1fr var(--readout-h);
|
|
grid-template-areas: "nav main" "bar bar";
|
|
}
|
|
|
|
/* Faint 16px grid — like the squared paper inside an engineering pad */
|
|
body::before {
|
|
content: "";
|
|
position: fixed; inset: 0;
|
|
pointer-events: none; z-index: 0;
|
|
background-image:
|
|
linear-gradient(to right, rgba(28, 28, 31, 0.022) 1px, transparent 1px),
|
|
linear-gradient(to bottom, rgba(28, 28, 31, 0.022) 1px, transparent 1px);
|
|
background-size: 16px 16px;
|
|
}
|
|
|
|
/* Decorative diagonal stamp watermark — barely visible, in one corner */
|
|
body::after {
|
|
content: "REV / 0.15.1 / CONFIDENTIAL / NOT FOR DISTRIBUTION";
|
|
position: fixed;
|
|
bottom: 60px;
|
|
right: -90px;
|
|
transform: rotate(-90deg);
|
|
transform-origin: bottom right;
|
|
font-family: var(--ff-mono);
|
|
font-size: 9.5px;
|
|
font-weight: 500;
|
|
letter-spacing: 0.4em;
|
|
color: var(--ink);
|
|
opacity: 0.05;
|
|
pointer-events: none;
|
|
z-index: 0;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
/* ─── Registration crosshairs in viewport corners ────────────────────── */
|
|
.reg {
|
|
position: fixed;
|
|
width: 16px; height: 16px;
|
|
z-index: 4;
|
|
pointer-events: none;
|
|
}
|
|
.reg::before, .reg::after {
|
|
content: ""; position: absolute;
|
|
background: var(--ink-3);
|
|
}
|
|
.reg::before { left: 7px; top: 0; bottom: 0; width: 1px; }
|
|
.reg::after { top: 7px; left: 0; right: 0; height: 1px; }
|
|
.reg-tl { top: 12px; left: 12px; }
|
|
.reg-tr { top: 12px; right: 12px; }
|
|
.reg-bl { bottom: 44px; left: 12px; }
|
|
.reg-br { bottom: 44px; right: 12px; }
|
|
|
|
/* ─── Sidebar / Masthead ─────────────────────────────────────────────── */
|
|
.nav {
|
|
grid-area: nav;
|
|
background: var(--paper);
|
|
border-right: 1px solid var(--rule);
|
|
padding: 28px 22px 18px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
z-index: 2;
|
|
overflow-y: auto;
|
|
position: relative;
|
|
}
|
|
|
|
.masthead {
|
|
margin-bottom: 26px;
|
|
padding-bottom: 18px;
|
|
border-bottom: 1px solid var(--rule);
|
|
}
|
|
|
|
.masthead-title {
|
|
font-family: var(--ff-display);
|
|
font-weight: 800;
|
|
font-size: 38px;
|
|
line-height: 0.85;
|
|
letter-spacing: 0.04em;
|
|
color: var(--ink);
|
|
position: relative;
|
|
}
|
|
|
|
.masthead-title::after {
|
|
content: "";
|
|
display: inline-block;
|
|
width: 7px; height: 7px;
|
|
background: var(--hazard);
|
|
margin-left: 6px;
|
|
vertical-align: super;
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.masthead-sub {
|
|
font-family: var(--ff-mono);
|
|
font-size: 9.5px;
|
|
font-weight: 500;
|
|
letter-spacing: 0.22em;
|
|
color: var(--ink-2);
|
|
margin-top: 8px;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.masthead-meta {
|
|
font-family: var(--ff-mono);
|
|
font-size: 9.5px;
|
|
letter-spacing: 0.16em;
|
|
color: var(--ink-3);
|
|
margin-top: 14px;
|
|
text-transform: uppercase;
|
|
display: flex;
|
|
gap: 6px;
|
|
}
|
|
.masthead-meta span:first-child { color: var(--ink-3); }
|
|
.masthead-meta span:last-child { color: var(--ink-2); font-weight: 500; }
|
|
|
|
.masthead-stamp {
|
|
margin-top: 16px;
|
|
padding: 6px 8px;
|
|
border: 1px dashed var(--rule);
|
|
border-radius: var(--radius);
|
|
font-family: var(--ff-mono);
|
|
font-size: 9px;
|
|
letter-spacing: 0.14em;
|
|
color: var(--ink-3);
|
|
text-transform: uppercase;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
.masthead-stamp .stamp-line { color: var(--hazard); font-size: 8px; }
|
|
|
|
/* Numbered nav — large stencil index on the left, label beside */
|
|
.dial {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0;
|
|
}
|
|
|
|
.dial-item {
|
|
display: grid;
|
|
grid-template-columns: 40px 1fr;
|
|
align-items: baseline;
|
|
gap: 14px;
|
|
padding: 11px 0 11px 10px;
|
|
margin-left: -10px;
|
|
border: 0;
|
|
background: transparent;
|
|
cursor: pointer;
|
|
text-align: left;
|
|
border-left: 2px solid transparent;
|
|
color: var(--ink-2);
|
|
transition: color 0.14s, border-left-color 0.14s;
|
|
}
|
|
.dial-item:hover { color: var(--ink); }
|
|
.dial-item:hover .dial-num { color: var(--ink-2); }
|
|
|
|
.dial-item[data-active] {
|
|
color: var(--ink);
|
|
border-left-color: var(--hazard);
|
|
}
|
|
.dial-item[data-active] .dial-num { color: var(--hazard); }
|
|
.dial-item[data-active] .dial-name::after {
|
|
content: "←";
|
|
margin-left: 8px;
|
|
color: var(--hazard);
|
|
font-family: var(--ff-mono);
|
|
font-size: 11px;
|
|
}
|
|
|
|
.dial-num {
|
|
font-family: var(--ff-display);
|
|
font-weight: 700;
|
|
font-size: 24px;
|
|
letter-spacing: 0.04em;
|
|
line-height: 0.9;
|
|
color: var(--ink-3);
|
|
}
|
|
|
|
.dial-name {
|
|
font-family: var(--ff-sans);
|
|
font-weight: 500;
|
|
font-size: 14.5px;
|
|
letter-spacing: -0.005em;
|
|
}
|
|
|
|
.nav-foot {
|
|
margin-top: auto;
|
|
padding: 14px 0 0;
|
|
border-top: 1px solid var(--rule);
|
|
font-family: var(--ff-mono);
|
|
font-size: 10px;
|
|
color: var(--ink-3);
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
}
|
|
|
|
.kv { display: flex; justify-content: space-between; gap: 10px; }
|
|
.kv-k {
|
|
color: var(--ink-4);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.16em;
|
|
}
|
|
.kv-v {
|
|
color: var(--ink-2);
|
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
max-width: 150px; text-align: right;
|
|
}
|
|
|
|
/* ─── Main column ────────────────────────────────────────────────────── */
|
|
.main {
|
|
grid-area: main;
|
|
overflow-y: auto;
|
|
padding: 32px 48px 48px;
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.pane {
|
|
display: none;
|
|
flex-direction: column;
|
|
gap: 28px;
|
|
max-width: 1180px;
|
|
}
|
|
.pane[data-active] { display: flex; animation: fade-in 240ms ease-out; }
|
|
|
|
@keyframes fade-in {
|
|
from { opacity: 0; transform: translateY(4px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
|
|
/* Folio — chapter-opener header for each pane */
|
|
.folio {
|
|
display: grid;
|
|
grid-template-columns: auto 1fr auto;
|
|
gap: 24px;
|
|
align-items: end;
|
|
padding-bottom: 22px;
|
|
border-bottom: 1px solid var(--rule);
|
|
position: relative;
|
|
}
|
|
|
|
.folio::after {
|
|
/* a thin orange tick at the folio bottom-left corner */
|
|
content: "";
|
|
position: absolute;
|
|
left: 0; bottom: -1px;
|
|
width: 56px; height: 2px;
|
|
background: var(--hazard);
|
|
}
|
|
|
|
.folio-rail {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
min-width: 110px;
|
|
}
|
|
|
|
.folio-num {
|
|
font-family: var(--ff-display);
|
|
font-weight: 800;
|
|
font-size: 72px;
|
|
line-height: 0.82;
|
|
letter-spacing: 0.04em;
|
|
color: var(--ink);
|
|
}
|
|
|
|
.folio-tag {
|
|
font-family: var(--ff-mono);
|
|
font-size: 9.5px;
|
|
font-weight: 500;
|
|
letter-spacing: 0.22em;
|
|
color: var(--ink-3);
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.folio-title {
|
|
margin: 0;
|
|
font-family: var(--ff-sans);
|
|
font-weight: 300;
|
|
font-size: 44px;
|
|
line-height: 1;
|
|
letter-spacing: -0.03em;
|
|
color: var(--ink);
|
|
align-self: end;
|
|
padding-bottom: 6px;
|
|
}
|
|
|
|
.folio-actions {
|
|
display: flex;
|
|
gap: 8px;
|
|
padding-bottom: 8px;
|
|
}
|
|
|
|
/* ─── Block (sub-section panel) ──────────────────────────────────────── */
|
|
.block {
|
|
background: var(--paper-card);
|
|
border: 1px solid var(--rule);
|
|
border-radius: var(--radius);
|
|
padding: 22px 24px;
|
|
position: relative;
|
|
}
|
|
|
|
.block-head {
|
|
display: flex;
|
|
align-items: baseline;
|
|
gap: 12px;
|
|
margin-bottom: 16px;
|
|
padding-bottom: 12px;
|
|
border-bottom: 1px solid var(--rule-soft);
|
|
}
|
|
|
|
.block-id {
|
|
font-family: var(--ff-mono);
|
|
font-size: 10px;
|
|
font-weight: 600;
|
|
letter-spacing: 0.18em;
|
|
color: var(--hazard);
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.block-name {
|
|
font-family: var(--ff-sans);
|
|
font-weight: 500;
|
|
font-size: 14.5px;
|
|
letter-spacing: -0.005em;
|
|
color: var(--ink);
|
|
}
|
|
|
|
.block-meta {
|
|
font-family: var(--ff-mono);
|
|
font-size: 10px;
|
|
letter-spacing: 0.1em;
|
|
color: var(--ink-3);
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.block-actions {
|
|
margin-left: auto;
|
|
display: flex;
|
|
gap: 6px;
|
|
}
|
|
|
|
/* ─── Grid ───────────────────────────────────────────────────────────── */
|
|
.grid { display: grid; gap: 14px; }
|
|
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(252px, 1fr)); }
|
|
|
|
/* ─── Provider cards ─────────────────────────────────────────────────── */
|
|
.pcard {
|
|
background: var(--paper-card);
|
|
border: 1px solid var(--rule);
|
|
border-radius: var(--radius);
|
|
padding: 14px 16px 14px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
position: relative;
|
|
transition: border-color 0.16s;
|
|
}
|
|
|
|
.pcard:hover { border-color: var(--ink-3); }
|
|
|
|
/* Stencil number badge in corner — like a part-number stamp */
|
|
.pcard-mark {
|
|
position: absolute;
|
|
top: 12px; right: 14px;
|
|
font-family: var(--ff-display);
|
|
font-weight: 700;
|
|
font-size: 26px;
|
|
letter-spacing: 0.04em;
|
|
line-height: 1;
|
|
color: var(--ink-4);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.pcard.busy .pcard-mark { color: var(--hazard); }
|
|
|
|
/* Top busy-LED bar — only when an OAuth is in flight */
|
|
.pcard::before {
|
|
content: "";
|
|
position: absolute;
|
|
top: -1px; left: -1px;
|
|
width: 56px; height: 2px;
|
|
background: var(--rule);
|
|
border-radius: 0;
|
|
transition: background 0.2s;
|
|
}
|
|
.pcard.busy::before {
|
|
background: var(--hazard);
|
|
animation: led-pulse 1.4s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes led-pulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.45; }
|
|
}
|
|
|
|
.pcard-kind {
|
|
font-family: var(--ff-mono);
|
|
font-size: 9px;
|
|
font-weight: 600;
|
|
letter-spacing: 0.18em;
|
|
color: var(--ink-3);
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.pcard-title {
|
|
font-family: var(--ff-sans);
|
|
font-weight: 500;
|
|
font-size: 20px;
|
|
letter-spacing: -0.02em;
|
|
line-height: 1;
|
|
color: var(--ink);
|
|
margin: -2px 0 0;
|
|
}
|
|
|
|
.pcard-sub {
|
|
font-family: var(--ff-mono);
|
|
font-size: 10.5px;
|
|
color: var(--ink-3);
|
|
letter-spacing: 0.04em;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.auth-pill {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
width: fit-content;
|
|
margin-top: 7px;
|
|
padding: 3px 7px;
|
|
border: 1px solid var(--rule);
|
|
border-radius: 999px;
|
|
font-family: var(--ff-mono);
|
|
font-size: 9px;
|
|
font-weight: 700;
|
|
letter-spacing: 0.12em;
|
|
text-transform: uppercase;
|
|
color: var(--ink-2);
|
|
background: rgba(255,255,255,0.03);
|
|
}
|
|
|
|
.auth-pill[data-state="authenticated"] {
|
|
border-color: rgba(168, 210, 122, 0.45);
|
|
color: #a8d27a;
|
|
}
|
|
|
|
.auth-pill[data-state="usage_limited"] {
|
|
border-color: rgba(232, 138, 138, 0.55);
|
|
color: #e88a8a;
|
|
}
|
|
|
|
.auth-pill[data-state="error"] {
|
|
border-color: rgba(232, 138, 138, 0.55);
|
|
color: #e88a8a;
|
|
}
|
|
|
|
.auth-pill[data-state="unauthenticated"] {
|
|
border-color: rgba(246, 241, 227, 0.22);
|
|
color: var(--ink-3);
|
|
}
|
|
|
|
.pcard-creds {
|
|
list-style: none;
|
|
margin: 0; padding: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
min-height: 22px;
|
|
border-top: 1px solid var(--rule-soft);
|
|
padding-top: 10px;
|
|
}
|
|
|
|
.pcard-creds li {
|
|
display: grid;
|
|
grid-template-columns: 22px 1fr auto;
|
|
gap: 6px;
|
|
align-items: center;
|
|
font-family: var(--ff-mono);
|
|
font-size: 10.5px;
|
|
color: var(--ink-2);
|
|
padding: 4px 0;
|
|
border-bottom: 1px dotted var(--rule-soft);
|
|
}
|
|
.pcard-creds li:last-child { border-bottom: 0; }
|
|
|
|
.pcard-creds .ix {
|
|
color: var(--ink-3);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.pcard-creds .label {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
overflow: hidden;
|
|
min-width: 0;
|
|
}
|
|
|
|
.pcard-creds .label > span {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.pcard-creds .account-id {
|
|
color: var(--ink-3);
|
|
font-size: 9.5px;
|
|
font-weight: 400;
|
|
}
|
|
|
|
.pcard-creds li.active .ix,
|
|
.pcard-creds li.active .label {
|
|
color: var(--hazard);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.pcard-creds .x {
|
|
color: var(--ink-4);
|
|
background: none; border: 0; cursor: pointer; font: inherit;
|
|
padding: 0 6px;
|
|
font-family: var(--ff-mono);
|
|
font-size: 13px;
|
|
line-height: 1;
|
|
}
|
|
.pcard-creds .x:hover { color: var(--err); }
|
|
|
|
.pcard-empty {
|
|
color: var(--ink-4);
|
|
font-family: var(--ff-mono);
|
|
font-size: 10px;
|
|
letter-spacing: 0.18em;
|
|
padding: 8px 0 4px;
|
|
text-align: center;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.pcard-actions {
|
|
display: flex;
|
|
gap: 6px;
|
|
margin-top: auto;
|
|
}
|
|
.pcard-actions .grow { flex: 1; }
|
|
|
|
.pcard-log {
|
|
background: var(--paper-2);
|
|
color: var(--ink-2);
|
|
border: 1px solid var(--rule-soft);
|
|
border-radius: var(--radius);
|
|
padding: 7px 9px;
|
|
font-family: var(--ff-mono);
|
|
font-size: 10px;
|
|
line-height: 1.55;
|
|
max-height: 90px;
|
|
overflow-y: auto;
|
|
white-space: pre-wrap;
|
|
margin: 0;
|
|
}
|
|
|
|
.oauth-input {
|
|
display: grid;
|
|
gap: 5px;
|
|
color: var(--ink-3);
|
|
font-family: var(--ff-mono);
|
|
font-size: 10px;
|
|
}
|
|
|
|
.oauth-input > div {
|
|
display: flex;
|
|
gap: 6px;
|
|
}
|
|
|
|
.oauth-input input {
|
|
min-width: 0;
|
|
flex: 1;
|
|
border: 1px solid var(--rule);
|
|
border-radius: var(--radius);
|
|
background: var(--paper-card);
|
|
color: var(--ink);
|
|
font: inherit;
|
|
padding: 6px 8px;
|
|
}
|
|
|
|
/* ─── Buttons ────────────────────────────────────────────────────────── */
|
|
.btn, .btn-primary, .btn-mini, .btn-danger, .btn-ghost {
|
|
font: inherit;
|
|
font-family: var(--ff-sans);
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
border-radius: var(--radius);
|
|
border: 1px solid var(--ink);
|
|
background: var(--paper-card);
|
|
color: var(--ink);
|
|
padding: 7px 14px;
|
|
font-size: 12.5px;
|
|
letter-spacing: 0;
|
|
transition: background 0.12s, color 0.12s, border-color 0.12s, transform 0.06s;
|
|
}
|
|
|
|
.btn:hover { background: var(--ink); color: var(--paper); }
|
|
.btn:active { transform: translateY(0.5px); }
|
|
|
|
.btn-primary {
|
|
background: var(--ink);
|
|
color: var(--paper);
|
|
border-color: var(--ink);
|
|
font-weight: 600;
|
|
letter-spacing: 0.005em;
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
background: var(--hazard);
|
|
border-color: var(--hazard);
|
|
color: var(--paper-card);
|
|
}
|
|
|
|
.btn-mini {
|
|
padding: 4px 9px;
|
|
font-size: 10px;
|
|
background: transparent;
|
|
color: var(--ink-2);
|
|
border-color: var(--rule);
|
|
font-family: var(--ff-mono);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.14em;
|
|
font-weight: 600;
|
|
}
|
|
.btn-mini:hover { color: var(--ink); border-color: var(--ink); background: transparent; }
|
|
|
|
.btn-danger {
|
|
background: transparent;
|
|
color: var(--err);
|
|
border-color: var(--err);
|
|
}
|
|
.btn-danger:hover { background: var(--err); color: var(--paper); }
|
|
|
|
.btn-ghost {
|
|
background: transparent;
|
|
border-color: transparent;
|
|
color: var(--ink-2);
|
|
font-family: var(--ff-mono);
|
|
font-size: 11px;
|
|
letter-spacing: 0.12em;
|
|
text-transform: uppercase;
|
|
font-weight: 600;
|
|
padding: 6px 10px;
|
|
}
|
|
.btn-ghost:hover { color: var(--hazard); background: transparent; }
|
|
|
|
button:disabled { opacity: 0.45; cursor: not-allowed; }
|
|
|
|
/* ─── Forms ──────────────────────────────────────────────────────────── */
|
|
input, select {
|
|
font: inherit;
|
|
font-family: var(--ff-sans);
|
|
background: var(--paper-card);
|
|
color: var(--ink);
|
|
border: 1px solid var(--rule);
|
|
border-radius: var(--radius);
|
|
padding: 7px 11px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
input:focus, select:focus {
|
|
outline: none;
|
|
border-color: var(--ink);
|
|
box-shadow: inset 0 -2px 0 var(--hazard);
|
|
}
|
|
|
|
input::placeholder {
|
|
color: var(--ink-4);
|
|
font-family: var(--ff-mono);
|
|
font-size: 11px;
|
|
letter-spacing: 0.04em;
|
|
}
|
|
|
|
select {
|
|
appearance: none;
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5'%3E%3Cpath d='M0 0L4 5L8 0Z' fill='%23807c6c'/%3E%3C/svg%3E");
|
|
background-repeat: no-repeat;
|
|
background-position: right 10px center;
|
|
padding-right: 28px;
|
|
}
|
|
|
|
.row { display: flex; align-items: center; gap: 8px; }
|
|
.row.gap { gap: 14px; }
|
|
.grow { flex: 1 1 auto; }
|
|
|
|
.field-inline {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
font-family: var(--ff-mono);
|
|
font-size: 10.5px;
|
|
letter-spacing: 0.06em;
|
|
text-transform: uppercase;
|
|
color: var(--ink-3);
|
|
}
|
|
.field-inline input {
|
|
width: 70px;
|
|
padding: 4px 8px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.key-row { display: flex; gap: 8px; align-items: center; }
|
|
.key-row input { flex: 1; font-family: var(--ff-mono); }
|
|
|
|
.status {
|
|
font-family: var(--ff-mono);
|
|
font-size: 10.5px;
|
|
color: var(--ink-3);
|
|
min-height: 14px;
|
|
letter-spacing: 0.06em;
|
|
text-transform: uppercase;
|
|
}
|
|
.status.ok { color: var(--ok); }
|
|
.status.err { color: var(--err); }
|
|
|
|
/* ─── Routing pane ───────────────────────────────────────────────────── */
|
|
.primary-row {
|
|
display: grid;
|
|
grid-template-columns: 220px 1fr auto;
|
|
gap: 10px;
|
|
}
|
|
|
|
.chain-edit {
|
|
list-style: none;
|
|
margin: 0 0 16px;
|
|
padding: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 5px;
|
|
counter-reset: hop;
|
|
}
|
|
|
|
.chain-edit li {
|
|
display: grid;
|
|
grid-template-columns: 36px 200px 1fr auto auto;
|
|
gap: 10px;
|
|
align-items: center;
|
|
padding: 7px 10px;
|
|
background: var(--paper);
|
|
border: 1px solid var(--rule);
|
|
border-radius: var(--radius);
|
|
position: relative;
|
|
}
|
|
|
|
.chain-edit li::before {
|
|
/* hop arrow on the left */
|
|
content: "▸";
|
|
position: absolute;
|
|
left: -14px;
|
|
color: var(--ink-4);
|
|
font-size: 11px;
|
|
}
|
|
|
|
.chain-edit li:first-child::before { color: var(--hazard); }
|
|
|
|
.chain-edit li .idx {
|
|
font-family: var(--ff-display);
|
|
font-weight: 700;
|
|
font-size: 22px;
|
|
text-align: center;
|
|
color: var(--hazard);
|
|
line-height: 1;
|
|
}
|
|
|
|
.chain-edit li select, .chain-edit li input {
|
|
background: var(--paper-card);
|
|
padding: 5px 10px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.chain-edit li .moves { display: flex; gap: 2px; }
|
|
.chain-edit li .moves button {
|
|
background: var(--paper-card);
|
|
border: 1px solid var(--rule);
|
|
color: var(--ink-2);
|
|
padding: 4px 9px;
|
|
font-size: 11px;
|
|
font-family: var(--ff-mono);
|
|
}
|
|
.chain-edit li .moves button:hover { color: var(--hazard); border-color: var(--hazard); }
|
|
|
|
/* ─── Tables ─────────────────────────────────────────────────────────── */
|
|
.table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
background: var(--paper-card);
|
|
border: 1px solid var(--rule);
|
|
border-radius: var(--radius);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.table th, .table td {
|
|
padding: 9px 14px;
|
|
font-size: 12.5px;
|
|
text-align: left;
|
|
border-bottom: 1px solid var(--rule-soft);
|
|
}
|
|
|
|
.table th {
|
|
background: var(--paper-2);
|
|
color: var(--ink-3);
|
|
font-family: var(--ff-mono);
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.16em;
|
|
font-size: 10px;
|
|
}
|
|
|
|
.table tr:last-child td { border-bottom: 0; }
|
|
.table tr:hover td { background: var(--paper-2); }
|
|
|
|
.table .badge {
|
|
display: inline-block;
|
|
padding: 2px 8px;
|
|
font-size: 9.5px;
|
|
border-radius: 0;
|
|
background: transparent;
|
|
border: 1px solid var(--rule);
|
|
font-family: var(--ff-mono);
|
|
letter-spacing: 0.12em;
|
|
color: var(--ink-3);
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
/* ─── Lists ──────────────────────────────────────────────────────────── */
|
|
.list {
|
|
list-style: none; margin: 0; padding: 0;
|
|
background: var(--paper-card);
|
|
border: 1px solid var(--rule);
|
|
border-radius: var(--radius);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.list li {
|
|
padding: 12px 18px;
|
|
border-bottom: 1px solid var(--rule-soft);
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
gap: 12px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.list li:last-child { border-bottom: 0; }
|
|
|
|
.list .id {
|
|
font-family: var(--ff-mono);
|
|
font-size: 10.5px;
|
|
color: var(--ink-3);
|
|
letter-spacing: 0.04em;
|
|
}
|
|
|
|
.list .empty {
|
|
color: var(--ink-4);
|
|
font-family: var(--ff-mono);
|
|
font-size: 10.5px;
|
|
letter-spacing: 0.18em;
|
|
text-transform: uppercase;
|
|
justify-content: center;
|
|
padding: 24px 0;
|
|
}
|
|
|
|
/* ─── Raw output / Logs ──────────────────────────────────────────────── */
|
|
.raw {
|
|
background: var(--paper-card);
|
|
color: var(--ink-2);
|
|
border: 1px solid var(--rule);
|
|
border-radius: var(--radius);
|
|
padding: 18px 22px;
|
|
margin: 0;
|
|
font-family: var(--ff-mono);
|
|
font-size: 11.5px;
|
|
line-height: 1.7;
|
|
white-space: pre-wrap;
|
|
max-height: 62vh;
|
|
overflow-y: auto;
|
|
position: relative;
|
|
}
|
|
|
|
.raw::before {
|
|
/* dog-ear / corner-fold marker */
|
|
content: "";
|
|
position: absolute;
|
|
top: 0; right: 0;
|
|
width: 14px; height: 14px;
|
|
background: linear-gradient(135deg, transparent 50%, var(--rule-soft) 50%);
|
|
}
|
|
|
|
.log {
|
|
background: var(--paper-2);
|
|
color: var(--ink-2);
|
|
border: 1px solid var(--rule-soft);
|
|
border-radius: var(--radius);
|
|
padding: 10px 12px;
|
|
margin: 12px 0 0;
|
|
font-family: var(--ff-mono);
|
|
font-size: 10.5px;
|
|
line-height: 1.6;
|
|
max-height: 160px;
|
|
overflow-y: auto;
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
/* ─── MCP form ───────────────────────────────────────────────────────── */
|
|
.mcp-form {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr) auto;
|
|
gap: 10px;
|
|
align-items: start;
|
|
}
|
|
.mcp-form textarea {
|
|
grid-column: 1 / 3;
|
|
resize: vertical;
|
|
min-height: 2.4em;
|
|
font-family: var(--ff-mono);
|
|
}
|
|
.mcp-form button { grid-row: 1 / -1; align-self: stretch; }
|
|
.mcp-hint {
|
|
margin: 10px 0 0;
|
|
font-size: 0.8rem;
|
|
line-height: 1.5;
|
|
color: var(--ink-60, #555);
|
|
}
|
|
.mcp-hint code { font-family: var(--ff-mono); font-size: 0.92em; }
|
|
.row-actions { display: inline-flex; gap: 8px; align-items: center; }
|
|
|
|
/* ─── Readout / bottom status bar ────────────────────────────────────── */
|
|
.readout {
|
|
grid-area: bar;
|
|
background: var(--ink);
|
|
color: var(--paper);
|
|
border-top: 1px solid var(--ink);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0;
|
|
padding: 0 16px;
|
|
font-family: var(--ff-mono);
|
|
font-size: 10.5px;
|
|
letter-spacing: 0.08em;
|
|
z-index: 5;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.rd-tag {
|
|
font-family: var(--ff-display);
|
|
font-weight: 800;
|
|
font-size: 13px;
|
|
letter-spacing: 0.1em;
|
|
color: var(--hazard);
|
|
padding: 0 10px 0 0;
|
|
}
|
|
|
|
.rd-sep { color: var(--ink-3); padding: 0 12px; }
|
|
|
|
.rd-cell { display: inline-flex; align-items: baseline; gap: 6px; }
|
|
|
|
.rd-k {
|
|
color: var(--ink-4);
|
|
font-weight: 500;
|
|
letter-spacing: 0.18em;
|
|
}
|
|
|
|
#bar-primary { color: var(--hazard); font-weight: 600; }
|
|
#bar-chain { color: var(--paper); font-weight: 600; }
|
|
#bar-version { color: var(--paper); font-weight: 500; }
|
|
|
|
.rd-msg { color: var(--paper); padding-right: 12px; min-height: 14px; }
|
|
|
|
.rd-led {
|
|
width: 7px; height: 7px;
|
|
border-radius: 50%;
|
|
background: var(--ok);
|
|
margin-left: 4px;
|
|
box-shadow: 0 0 6px var(--ok);
|
|
}
|
|
.readout.busy .rd-led { background: var(--hazard); box-shadow: 0 0 6px var(--hazard); animation: led-pulse 1.4s ease-in-out infinite; }
|
|
.readout.error .rd-led { background: var(--err); box-shadow: 0 0 6px var(--err); }
|
|
|
|
/* ─── Sidebar group divider ──────────────────────────────────────────── */
|
|
.dial-divider {
|
|
margin: 14px -22px 4px 0;
|
|
padding: 14px 12px 4px;
|
|
border-top: 1px solid var(--rule);
|
|
position: relative;
|
|
}
|
|
|
|
.dial-divider span {
|
|
font-family: var(--ff-mono);
|
|
font-size: 9px;
|
|
letter-spacing: 0.24em;
|
|
color: var(--ink-4);
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
/* ─── Tabs ───────────────────────────────────────────────────────────── */
|
|
.tabs {
|
|
display: flex;
|
|
gap: 0;
|
|
border-bottom: 1px solid var(--rule);
|
|
margin-bottom: 22px;
|
|
}
|
|
|
|
.tab {
|
|
font: inherit;
|
|
font-family: var(--ff-sans);
|
|
font-weight: 500;
|
|
font-size: 13px;
|
|
color: var(--ink-3);
|
|
background: transparent;
|
|
border: 0;
|
|
border-bottom: 2px solid transparent;
|
|
padding: 10px 18px 12px;
|
|
cursor: pointer;
|
|
margin-bottom: -1px;
|
|
transition: color 0.12s, border-bottom-color 0.12s;
|
|
}
|
|
|
|
.tab:hover { color: var(--ink); }
|
|
|
|
.tab[data-active] {
|
|
color: var(--ink);
|
|
border-bottom-color: var(--hazard);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.tab-count {
|
|
display: inline-block;
|
|
margin-left: 4px;
|
|
font-family: var(--ff-mono);
|
|
font-size: 10.5px;
|
|
color: var(--ink-4);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.tab[data-active] .tab-count { color: var(--hazard); }
|
|
|
|
.tab-body { display: none; }
|
|
.tab-body[data-active] { display: block; }
|
|
|
|
/* ─── Cards grid (skills/plugins/bundles) ────────────────────────────── */
|
|
.cards-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(308px, 1fr));
|
|
gap: 12px;
|
|
}
|
|
|
|
.scard {
|
|
background: var(--paper-card);
|
|
border: 1px solid var(--rule);
|
|
border-radius: var(--radius);
|
|
padding: 14px 16px 12px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
position: relative;
|
|
transition: border-color 0.14s;
|
|
}
|
|
.scard:hover { border-color: var(--ink-3); }
|
|
|
|
.scard-tag {
|
|
position: absolute;
|
|
top: 12px; right: 14px;
|
|
font-family: var(--ff-mono);
|
|
font-size: 9px;
|
|
font-weight: 600;
|
|
letter-spacing: 0.16em;
|
|
color: var(--ink-4);
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.scard.disabled .scard-tag,
|
|
.scard[data-status='disabled'] .scard-tag,
|
|
.scard[data-status='not enabled'] .scard-tag {
|
|
color: var(--ink-4);
|
|
}
|
|
|
|
.scard[data-status='enabled'] .scard-tag {
|
|
color: var(--ok);
|
|
}
|
|
|
|
.scard.user .scard-tag { color: var(--hazard); }
|
|
|
|
.scard-title {
|
|
font-family: var(--ff-sans);
|
|
font-weight: 600;
|
|
font-size: 15px;
|
|
letter-spacing: -0.01em;
|
|
line-height: 1.2;
|
|
color: var(--ink);
|
|
margin: 0;
|
|
padding-right: 60px;
|
|
}
|
|
|
|
.scard-sub {
|
|
font-family: var(--ff-mono);
|
|
font-size: 10px;
|
|
color: var(--ink-3);
|
|
letter-spacing: 0.04em;
|
|
display: flex;
|
|
gap: 8px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.scard-sub > span { display: inline-flex; gap: 4px; align-items: baseline; }
|
|
|
|
.scard-sub strong {
|
|
color: var(--ink-2);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.scard-desc {
|
|
font-size: 12.5px;
|
|
color: var(--ink-2);
|
|
margin: 0;
|
|
line-height: 1.5;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 3;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.scard-chips {
|
|
display: flex;
|
|
gap: 4px;
|
|
flex-wrap: wrap;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.chip {
|
|
display: inline-block;
|
|
padding: 2px 8px;
|
|
border-radius: 999px;
|
|
background: var(--paper-2);
|
|
border: 1px solid var(--rule-soft);
|
|
font-family: var(--ff-mono);
|
|
font-size: 9.5px;
|
|
letter-spacing: 0.08em;
|
|
color: var(--ink-3);
|
|
text-transform: lowercase;
|
|
}
|
|
|
|
.chip.hook { background: var(--hazard-soft); border-color: var(--hazard-line); color: var(--hazard-deep); }
|
|
.chip.platform { background: rgba(45, 93, 128, 0.10); border-color: rgba(45, 93, 128, 0.30); color: var(--info); }
|
|
.chip.cat { background: var(--paper-3); }
|
|
.chip.lang { background: var(--paper-2); }
|
|
|
|
.scard-actions {
|
|
margin-top: auto;
|
|
display: flex;
|
|
gap: 6px;
|
|
padding-top: 8px;
|
|
border-top: 1px solid var(--rule-soft);
|
|
}
|
|
|
|
.scard-actions .grow { flex: 1; }
|
|
|
|
.scard-stars {
|
|
font-family: var(--ff-mono);
|
|
font-size: 11px;
|
|
color: var(--ink-3);
|
|
}
|
|
|
|
.scard-stars::before {
|
|
content: "★";
|
|
color: var(--hazard);
|
|
margin-right: 4px;
|
|
}
|
|
|
|
/* ─── Stat grid (curator dashboard) ──────────────────────────────────── */
|
|
.stat-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
|
gap: 12px;
|
|
}
|
|
|
|
.stat-tile {
|
|
background: var(--paper-card);
|
|
border: 1px solid var(--rule);
|
|
border-radius: var(--radius);
|
|
padding: 18px 20px;
|
|
position: relative;
|
|
}
|
|
|
|
.stat-tile::before {
|
|
content: "";
|
|
position: absolute;
|
|
top: -1px; left: -1px;
|
|
width: 36px; height: 2px;
|
|
background: var(--hazard);
|
|
}
|
|
|
|
.stat-label {
|
|
font-family: var(--ff-mono);
|
|
font-size: 9.5px;
|
|
font-weight: 600;
|
|
letter-spacing: 0.18em;
|
|
color: var(--ink-3);
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.stat-value {
|
|
font-family: var(--ff-display);
|
|
font-weight: 700;
|
|
font-size: 44px;
|
|
line-height: 1;
|
|
letter-spacing: 0.02em;
|
|
color: var(--ink);
|
|
margin-top: 8px;
|
|
}
|
|
|
|
.stat-sub {
|
|
font-family: var(--ff-mono);
|
|
font-size: 10px;
|
|
color: var(--ink-3);
|
|
margin-top: 6px;
|
|
letter-spacing: 0.04em;
|
|
}
|
|
|
|
.stat-tile.ok .stat-value { color: var(--ok); }
|
|
.stat-tile.warn .stat-value { color: var(--hazard-deep); }
|
|
|
|
/* ─── Key/value list ─────────────────────────────────────────────────── */
|
|
.kv-list {
|
|
margin: 0;
|
|
display: grid;
|
|
grid-template-columns: auto 1fr;
|
|
gap: 8px 18px;
|
|
font-family: var(--ff-mono);
|
|
font-size: 12px;
|
|
}
|
|
|
|
.kv-list dt {
|
|
color: var(--ink-3);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.1em;
|
|
font-size: 10px;
|
|
padding-top: 2px;
|
|
}
|
|
|
|
.kv-list dd {
|
|
margin: 0;
|
|
color: var(--ink);
|
|
}
|
|
|
|
/* ─── Empty-pane prompt ──────────────────────────────────────────────── */
|
|
.empty-pane {
|
|
background: var(--paper-card);
|
|
border: 1px dashed var(--rule);
|
|
border-radius: var(--radius);
|
|
padding: 32px 24px;
|
|
text-align: center;
|
|
color: var(--ink-3);
|
|
font-family: var(--ff-mono);
|
|
font-size: 11px;
|
|
letter-spacing: 0.06em;
|
|
grid-column: 1 / -1;
|
|
}
|
|
|
|
.empty-pane code {
|
|
background: var(--paper-2);
|
|
padding: 1px 5px;
|
|
border-radius: 3px;
|
|
border: 1px solid var(--rule-soft);
|
|
font-size: 10.5px;
|
|
color: var(--ink-2);
|
|
}
|
|
|
|
/* ─── Editor (memory) ────────────────────────────────────────────────── */
|
|
.editor {
|
|
width: 100%;
|
|
min-height: 200px;
|
|
max-height: 50vh;
|
|
background: var(--paper-card);
|
|
color: var(--ink);
|
|
border: 1px solid var(--rule);
|
|
border-radius: var(--radius);
|
|
padding: 14px 16px;
|
|
font-family: var(--ff-mono);
|
|
font-size: 12px;
|
|
line-height: 1.6;
|
|
resize: vertical;
|
|
}
|
|
.editor:focus { outline: none; border-color: var(--ink); box-shadow: inset 0 -2px 0 var(--hazard); }
|
|
|
|
/* Squeeze long sidebar — let it scroll & shorten dial padding so 18 items fit */
|
|
.dial-item { padding-top: 9px; padding-bottom: 9px; }
|
|
.dial-num { font-size: 22px; }
|
|
|
|
/* ─── Scrollbar ──────────────────────────────────────────────────────── */
|
|
::-webkit-scrollbar { width: 8px; height: 8px; }
|
|
::-webkit-scrollbar-track { background: transparent; }
|
|
::-webkit-scrollbar-thumb {
|
|
background: var(--paper-4);
|
|
border-radius: 0;
|
|
border: 2px solid transparent;
|
|
background-clip: padding-box;
|
|
}
|
|
::-webkit-scrollbar-thumb:hover { background: var(--ink-3); background-clip: padding-box; }
|
|
|
|
::selection { background: var(--hazard-soft); color: var(--ink); }
|
|
|
|
/* ─── Responsive — narrow viewport collapses the nav numerals ────────── */
|
|
@media (max-width: 1100px) {
|
|
:root { --nav-w: 200px; }
|
|
.folio-num { font-size: 56px; }
|
|
.folio-title { font-size: 36px; }
|
|
.main { padding: 28px 32px 40px; }
|
|
}
|
|
|
|
@media (max-width: 880px) {
|
|
:root { --nav-w: 64px; }
|
|
.masthead-title { font-size: 22px; }
|
|
.masthead-sub, .masthead-meta, .masthead-stamp, .nav-foot { display: none; }
|
|
.dial-item { grid-template-columns: 1fr; gap: 0; padding-left: 6px; }
|
|
.dial-name { display: none; }
|
|
.dial-num { font-size: 20px; }
|
|
}
|
|
|
|
/* ─── API User Table ──────────────────────────────────────────────────── */
|
|
.api-user-table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
background: var(--paper-card);
|
|
border: 1px solid var(--rule);
|
|
border-radius: var(--radius);
|
|
overflow: hidden;
|
|
margin-top: 22px;
|
|
}
|
|
|
|
.api-user-table th, .api-user-table td {
|
|
padding: 9px 14px;
|
|
font-size: 12.5px;
|
|
text-align: left;
|
|
border-bottom: 1px solid var(--rule-soft);
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.api-user-table th {
|
|
background: var(--paper-2);
|
|
color: var(--ink-3);
|
|
font-family: var(--ff-mono);
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.16em;
|
|
font-size: 10px;
|
|
}
|
|
|
|
.api-user-table tr:last-child td { border-bottom: 0; }
|
|
.api-user-table tr:hover td { background: var(--paper-2); }
|
|
|
|
.api-user-name {
|
|
font-weight: 500;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.cell-sub {
|
|
font-size: 11px;
|
|
color: var(--ink-3);
|
|
}
|
|
|
|
.key-mask {
|
|
font-family: var(--ff-mono);
|
|
font-size: 11.5px;
|
|
color: var(--ink-2);
|
|
letter-spacing: 0.04em;
|
|
}
|
|
|
|
.action-cell {
|
|
white-space: nowrap;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 4px;
|
|
padding: 6px 14px;
|
|
}
|
|
|
|
.empty-cell {
|
|
color: var(--ink-3);
|
|
font-style: italic;
|
|
text-align: center;
|
|
padding: 24px;
|
|
}
|
|
|
|
/* ─── Badges ─────────────────────────────────────────────────────────── */
|
|
.badge {
|
|
display: inline-block;
|
|
padding: 2px 8px;
|
|
font-size: 9.5px;
|
|
border-radius: 0;
|
|
background: transparent;
|
|
border: 1px solid var(--rule);
|
|
font-family: var(--ff-mono);
|
|
letter-spacing: 0.12em;
|
|
color: var(--ink-3);
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.badge-active {
|
|
border-color: #6ab04c;
|
|
color: #6ab04c;
|
|
}
|
|
|
|
.badge-revoked {
|
|
border-color: var(--err);
|
|
color: var(--err);
|
|
}
|
|
|
|
.badge-deleted {
|
|
border-color: var(--ink-3);
|
|
color: var(--ink-3);
|
|
opacity: 0.6;
|
|
}
|
|
|
|
.badge-pre {
|
|
border-color: #7c6fcd;
|
|
color: #7c6fcd;
|
|
}
|
|
|
|
.badge-post {
|
|
border-color: #0097a7;
|
|
color: #0097a7;
|
|
}
|
|
|
|
/* ─── Dialog ─────────────────────────────────────────────────────────── */
|
|
dialog {
|
|
background: var(--paper-card);
|
|
color: var(--ink);
|
|
border: 1px solid var(--rule);
|
|
border-radius: var(--radius);
|
|
padding: 28px 32px;
|
|
min-width: 340px;
|
|
max-width: 480px;
|
|
width: 100%;
|
|
}
|
|
|
|
dialog::backdrop {
|
|
background: rgba(0, 0, 0, 0.55);
|
|
}
|
|
|
|
dialog h2 {
|
|
margin: 0 0 20px;
|
|
font-family: var(--ff-sans);
|
|
font-weight: 300;
|
|
font-size: 24px;
|
|
letter-spacing: -0.02em;
|
|
}
|
|
|
|
.dialog-field {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 5px;
|
|
margin-bottom: 14px;
|
|
}
|
|
|
|
.dialog-field label {
|
|
font-family: var(--ff-mono);
|
|
font-size: 10px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.14em;
|
|
color: var(--ink-3);
|
|
}
|
|
|
|
.dialog-field-check {
|
|
flex-direction: row;
|
|
align-items: center;
|
|
}
|
|
|
|
.dialog-field-check label {
|
|
font-family: var(--ff-sans);
|
|
font-size: 13px;
|
|
text-transform: none;
|
|
letter-spacing: 0;
|
|
color: var(--ink);
|
|
font-weight: 400;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.field-hint {
|
|
font-weight: 400;
|
|
text-transform: none;
|
|
letter-spacing: 0;
|
|
color: var(--ink-3);
|
|
}
|
|
|
|
.expires-presets {
|
|
display: flex;
|
|
gap: 6px;
|
|
flex-wrap: wrap;
|
|
margin-top: 4px;
|
|
}
|
|
|
|
.dialog-error {
|
|
font-family: var(--ff-mono);
|
|
font-size: 11px;
|
|
color: var(--hazard);
|
|
padding: 8px 10px;
|
|
background: var(--hazard-soft);
|
|
border: 1px solid var(--hazard-line);
|
|
border-radius: var(--radius);
|
|
margin-bottom: 4px;
|
|
display: none;
|
|
}
|
|
|
|
.dialog-error:not(:empty) {
|
|
display: block;
|
|
}
|
|
|
|
.dialog-actions {
|
|
display: flex;
|
|
gap: 8px;
|
|
margin-top: 20px;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.reveal-body {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
}
|
|
|
|
.reveal-warning {
|
|
font-family: var(--ff-mono);
|
|
font-size: 11px;
|
|
color: var(--hazard);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.1em;
|
|
margin: 0;
|
|
}
|
|
|
|
.reveal-key-wrap {
|
|
background: var(--paper-2);
|
|
border: 1px solid var(--rule);
|
|
border-radius: var(--radius);
|
|
padding: 12px 16px;
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.reveal-key-wrap code {
|
|
font-family: var(--ff-mono);
|
|
font-size: 13px;
|
|
word-break: break-all;
|
|
color: var(--ink);
|
|
}
|
|
|
|
/* ─── Responsive — narrow viewport stacks API table ─────────────────── */
|
|
@media (max-width: 600px) {
|
|
.api-user-table, .api-user-table thead, .api-user-table tbody,
|
|
.api-user-table th, .api-user-table td, .api-user-table tr {
|
|
display: block;
|
|
}
|
|
|
|
.api-user-table thead tr {
|
|
position: absolute;
|
|
top: -9999px;
|
|
left: -9999px;
|
|
}
|
|
|
|
.api-user-table tr {
|
|
border: 1px solid var(--rule);
|
|
border-radius: var(--radius);
|
|
margin-bottom: 10px;
|
|
background: var(--paper-card);
|
|
}
|
|
|
|
.api-user-table td {
|
|
border-bottom: 1px solid var(--rule-soft);
|
|
position: relative;
|
|
padding-left: 50%;
|
|
}
|
|
|
|
.api-user-table td::before {
|
|
position: absolute;
|
|
top: 9px;
|
|
left: 14px;
|
|
width: calc(50% - 20px);
|
|
white-space: nowrap;
|
|
font-family: var(--ff-mono);
|
|
font-size: 9.5px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.14em;
|
|
color: var(--ink-3);
|
|
content: attr(data-label);
|
|
}
|
|
|
|
.action-cell {
|
|
padding-left: 14px;
|
|
}
|
|
}
|