- new is_admin column on invites (migration 4) with DEFAULT 0
- requireAdmin middleware returns 404 for non-admins so the route's
existence isn't leaked; path obscured as /fenjaops (not /admin)
- admin/ dir lives outside public/ and protected/; only reachable via
the explicit gated mount + /api/fenjaops/{invites,joins} endpoints
- bin/invite.js gains `admin add|remove|list` subcommands
- OPERATIONS.md + CLAUDE.md + PROJECT.md document the hidden URL
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
145 lines
3.5 KiB
CSS
145 lines
3.5 KiB
CSS
/* ─────────────────────────────────────────────────────────────
|
|
admin/admin.css — utilitarian read-only admin styles. Shares
|
|
Fenja's paper/ink palette with the public site but drops the
|
|
editorial serif in favour of system-sans for scannability.
|
|
───────────────────────────────────────────────────────────── */
|
|
|
|
:root {
|
|
--paper: #faf6ee;
|
|
--paper-2: #f6f2e8;
|
|
--ink: #2e2e28;
|
|
--ink-soft: #5f5e5e;
|
|
--ink-dim: #8a887f;
|
|
--line: rgba(46, 46, 40, 0.12);
|
|
--accent: #b96b58;
|
|
--admin: #8a3a2f;
|
|
}
|
|
|
|
* { box-sizing: border-box; }
|
|
|
|
html, body {
|
|
margin: 0;
|
|
padding: 0;
|
|
background: var(--paper);
|
|
color: var(--ink);
|
|
font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
font-size: 14px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.masthead {
|
|
padding: 32px 48px 8px;
|
|
border-bottom: 1px solid var(--line);
|
|
}
|
|
.masthead h1 {
|
|
margin: 0 0 4px;
|
|
font-family: "Newsreader", Georgia, serif;
|
|
font-size: 34px;
|
|
font-weight: 400;
|
|
letter-spacing: -0.015em;
|
|
}
|
|
.masthead .dim { color: var(--ink-dim); font-style: italic; }
|
|
.masthead .meta {
|
|
margin: 0;
|
|
color: var(--ink-dim);
|
|
font-size: 13px;
|
|
}
|
|
.masthead code {
|
|
background: var(--paper-2);
|
|
padding: 1px 6px;
|
|
border-radius: 3px;
|
|
font-size: 12.5px;
|
|
}
|
|
|
|
.panel {
|
|
padding: 28px 48px;
|
|
border-bottom: 1px solid var(--line);
|
|
}
|
|
.panel h2 {
|
|
margin: 0 0 16px;
|
|
font-family: "Newsreader", Georgia, serif;
|
|
font-size: 20px;
|
|
font-weight: 500;
|
|
letter-spacing: -0.005em;
|
|
color: var(--ink);
|
|
}
|
|
.panel h2 .dim { color: var(--ink-dim); font-weight: 400; font-style: italic; }
|
|
|
|
/* Stats cards */
|
|
.stats {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
|
gap: 16px;
|
|
max-width: 900px;
|
|
}
|
|
.stat {
|
|
background: var(--paper-2);
|
|
padding: 16px 20px;
|
|
border-radius: 6px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
}
|
|
.stat-k {
|
|
font-size: 11.5px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.12em;
|
|
color: var(--ink-dim);
|
|
font-weight: 600;
|
|
}
|
|
.stat-v {
|
|
font-family: "Newsreader", Georgia, serif;
|
|
font-size: 32px;
|
|
font-weight: 500;
|
|
color: var(--ink);
|
|
line-height: 1;
|
|
}
|
|
|
|
/* Tables */
|
|
.t {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
.t th,
|
|
.t td {
|
|
text-align: left;
|
|
padding: 10px 14px;
|
|
border-bottom: 1px solid var(--line);
|
|
vertical-align: top;
|
|
}
|
|
.t thead th {
|
|
font-size: 11.5px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.12em;
|
|
color: var(--ink-dim);
|
|
font-weight: 600;
|
|
border-bottom: 1px solid var(--line);
|
|
background: var(--paper-2);
|
|
}
|
|
.t tbody tr:hover { background: var(--paper-2); }
|
|
.t .num { text-align: right; font-variant-numeric: tabular-nums; }
|
|
.t .mono { font-family: ui-monospace, "SF Mono", Consolas, monospace; font-size: 12px; color: var(--ink-soft); }
|
|
.t .when { white-space: nowrap; color: var(--ink-soft); font-size: 13px; }
|
|
.t .badge {
|
|
display: inline-block;
|
|
font-size: 10.5px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.12em;
|
|
color: var(--admin);
|
|
font-weight: 700;
|
|
}
|
|
|
|
.empty {
|
|
margin: 12px 2px 0;
|
|
color: var(--ink-dim);
|
|
font-style: italic;
|
|
font-size: 13px;
|
|
}
|
|
|
|
@media (max-width: 640px) {
|
|
.masthead, .panel { padding-left: 20px; padding-right: 20px; }
|
|
.masthead h1 { font-size: 26px; }
|
|
.t th, .t td { padding: 8px 10px; }
|
|
.t .mono { display: none; }
|
|
}
|