Files
com.gregkilmer.www/services/admin/public/admin.css
T
Claude a9fb5b3e85 Admin: write blog posts and manage images
A Posts page lists every post with Write a post: title, topic, kind,
date, summary, a cover picked from the vault or uploaded, the pages it is
about, the Markdown body with a rendered preview, and Save draft or
Publish. An Images page uploads several images into an _attachments
folder, shows which notes use each one, copies its embed line, and
deletes unused ones. The content service gains the attachment list,
upload and delete endpoints behind the editor and admin tokens.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
2026-10-12 03:40:59 +00:00

113 lines
8.0 KiB
CSS

/* The admin page follows the site's all-dark brand, kept plain: it is a tool. */
:root {
--sky: #0b111c;
--midnight: #131c2b;
--panel: #182335;
--line: #2a3a52;
--text: #f4f2ed;
--muted: #a9b4c2;
--teal: #14a39a;
--teal-bright: #2bc2b7;
--gold: #c9a24a;
--gold-bright: #d8b35a;
--red: #f0857a;
--add: #12382f;
--remove: #45202a;
color-scheme: dark;
}
* { box-sizing: border-box; }
body { margin: 0; background: var(--sky); color: var(--text); font: 15px/1.55 Montserrat, system-ui, sans-serif; }
a { color: var(--teal-bright); text-underline-offset: 3px; }
h1, h2, h3 { font-family: Cinzel, Georgia, serif; font-weight: 600; letter-spacing: 0.02em; }
h1 { font-size: 1.6rem; margin: 0 0 4px; }
h2 { font-size: 1.15rem; margin: 28px 0 10px; color: var(--gold-bright); }
code, pre, .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }
header.top { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 18px; padding: 12px 20px; background: var(--midnight); border-bottom: 1px solid var(--gold); }
header.top .brand { font-family: Cinzel, serif; color: var(--gold-bright); text-decoration: none; margin-right: 8px; }
header.top nav { display: flex; flex-wrap: wrap; gap: 4px 14px; }
header.top nav a { color: var(--text); text-decoration: none; padding: 4px 0; border-bottom: 2px solid transparent; }
header.top nav a[aria-current="page"] { border-color: var(--teal); }
.count { display: inline-block; min-width: 20px; padding: 0 6px; margin-left: 4px; border-radius: 10px; background: var(--gold); color: var(--midnight); font-size: 12px; font-weight: 700; text-align: center; }
main { max-width: 1100px; margin: 0 auto; padding: 24px 16px 64px; }
.lede { color: var(--muted); margin: 0 0 18px; }
.flash { padding: 10px 14px; border-left: 3px solid var(--teal); background: var(--panel); margin-bottom: 18px; }
.flash.err { border-color: var(--red); }
.flash ul { margin: 6px 0 0; padding-left: 20px; }
.panel { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 16px; margin-bottom: 16px; }
.grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.stat { font-size: 1.9rem; font-family: Cinzel, serif; color: var(--gold-bright); }
.muted { color: var(--muted); }
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
th { color: var(--muted); font-weight: 600; font-size: 13px; }
.table-wrap { overflow-x: auto; }
.pill { display: inline-block; padding: 1px 10px; border-radius: 999px; font-size: 12px; border: 1px solid var(--line); white-space: nowrap; }
.pill.live { border-color: var(--teal); color: var(--teal-bright); }
.pill.draft { border-color: var(--gold); color: var(--gold-bright); }
.pill.bad { border-color: var(--red); color: var(--red); }
.reason { margin: 4px 0; }
.reason code { color: var(--gold-bright); }
form.inline { display: inline; }
.actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 14px 0; }
button, .button { font: inherit; cursor: pointer; min-height: 36px; padding: 6px 18px; border-radius: 999px; border: 1px solid var(--gold); background: transparent; color: var(--text); text-decoration: none; display: inline-flex; align-items: center; }
button.primary { background: var(--teal); border-color: var(--teal); color: var(--midnight); font-weight: 600; }
button.danger { border-color: var(--red); color: var(--red); }
button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
label { display: block; margin: 10px 0 4px; font-size: 13px; color: var(--muted); }
label.check { display: flex; gap: 8px; align-items: center; color: var(--text); font-size: 15px; }
input, select, textarea { font: inherit; width: 100%; padding: 8px 10px; border-radius: 10px; border: 1px solid var(--line); background: var(--sky); color: var(--text); }
input[type="checkbox"] { width: auto; }
input:focus, select:focus, textarea:focus { border-color: var(--teal); }
.row { display: grid; gap: 0 14px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.filters { display: flex; flex-wrap: wrap; gap: 10px; align-items: end; margin-bottom: 16px; }
.filters > * { flex: 1 1 160px; }
.filters button { flex: 0 0 auto; }
.diff { background: var(--sky); border: 1px solid var(--line); border-radius: 10px; overflow-x: auto; padding: 8px 0; }
.diff div { white-space: pre-wrap; word-break: break-word; padding: 0 12px; font-family: ui-monospace, monospace; font-size: 13px; }
.diff .add { background: var(--add); }
.diff .add::before { content: "+ "; color: var(--teal-bright); }
.diff .remove { background: var(--remove); }
.diff .remove::before { content: "- "; color: var(--red); }
.diff .same::before { content: " "; }
.diff .skip { color: var(--muted); font-style: italic; }
.preview { background: var(--midnight); border: 1px solid var(--gold); border-radius: 10px; padding: 8px 22px; }
.preview img { max-width: 100%; }
dl.fields { display: grid; grid-template-columns: minmax(110px, max-content) 1fr; gap: 6px 16px; margin: 0; }
dl.fields dt { color: var(--muted); }
dl.fields dd { margin: 0; word-break: break-word; }
dl.fields pre { margin: 0; white-space: pre-wrap; }
input.num { width: 90px; }
/* Posts and Images */
.head-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; justify-content: space-between; }
.button.primary { background: var(--teal); border-color: var(--teal); color: var(--midnight); font-weight: 600; }
.hint { margin: 4px 0 0; font-size: 13px; color: var(--muted); }
.post-grid { display: grid; gap: 16px; grid-template-columns: minmax(0, 1fr) 320px; align-items: start; }
@media (max-width: 900px) { .post-grid { grid-template-columns: 1fr; } }
.side .panel h2 { margin-top: 0; font-size: 1.05rem; }
.side input[name="links"] { margin-bottom: 8px; }
.body-text { font-family: ui-monospace, monospace; font-size: 14px; line-height: 1.55; resize: vertical; min-height: 360px; }
.actions.stack { flex-direction: column; align-items: stretch; }
.actions.stack button { justify-content: center; }
.cover-preview { display: block; width: 100%; max-height: 180px; object-fit: cover; border-radius: 8px; margin-bottom: 6px; }
.cover-preview.wide { max-height: 320px; }
.post-preview h1 { margin-top: 4px; }
details summary { cursor: pointer; color: var(--muted); margin-top: 10px; }
.copy-row { display: flex; gap: 6px; align-items: center; }
.copy-row input { font-family: ui-monospace, monospace; font-size: 12px; padding: 4px 8px; }
.copy-row button { min-height: 30px; padding: 2px 12px; font-size: 13px; }
.thumbs { list-style: none; padding: 0; margin: 0; display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); }
.thumbs img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 8px; border: 1px solid var(--line); display: block; margin-bottom: 6px; }
.folders { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
.folders a { padding: 4px 14px; border: 1px solid var(--line); border-radius: 999px; color: var(--text); text-decoration: none; font-size: 14px; }
.folders a[aria-current] { border-color: var(--gold); color: var(--gold-bright); }
.images { list-style: none; padding: 0; margin: 0; display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.images li { margin: 0; display: flex; flex-direction: column; gap: 10px; }
.images img, .images .file { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 8px; display: block; background: var(--sky); }
.images .file { display: flex; align-items: center; justify-content: center; color: var(--muted); text-transform: uppercase; }
.images .meta { display: flex; flex-direction: column; gap: 6px; font-size: 14px; word-break: break-all; }
.images .used { font-size: 13px; }
form.inline { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; font-size: 13px; }
form.inline button { min-height: 30px; padding: 2px 12px; font-size: 13px; }
.preview img { max-height: 480px; object-fit: contain; }