From 9a94f725c7868dbf48285c7c903d94fa465941b0 Mon Sep 17 00:00:00 2001 From: Loyyd Date: Fri, 10 Jul 2026 10:49:12 +0200 Subject: [PATCH] Improve admin dashboard usability --- src/pages/admin/index.astro | 1780 +++++++++++++++++------------------ src/styles/admin.css | 1550 ++++++++++++++++++++++++++++++ 2 files changed, 2418 insertions(+), 912 deletions(-) create mode 100644 src/styles/admin.css diff --git a/src/pages/admin/index.astro b/src/pages/admin/index.astro index 6bdea2c6..382e3c36 100644 --- a/src/pages/admin/index.astro +++ b/src/pages/admin/index.astro @@ -1,4 +1,5 @@ --- +import "../../styles/admin.css"; import { getArchiveEntries } from "../../lib/archive"; import { speechAdminEntryFromArchiveEntry } from "../../lib/admin-speeches"; import { calendarEvents, recurringCalendarEvents } from "../../data/events"; @@ -13,15 +14,24 @@ const plausibleDomain = import.meta.env.PUBLIC_PLAUSIBLE_DOMAIN ?? ""; const today = new Date().toISOString().slice(0, 10); const latestEntry = entries[0]; const latestEntryTitle = latestEntry?.data.title ?? latestEntry?.id ?? "No content yet"; +const latestEntryType = latestEntry?.data.type ?? "content"; +const latestEntryDateIso = latestEntry?.data.published?.slice(0, 10) ?? ""; const latestEntryDate = latestEntry?.data.published ? new Intl.DateTimeFormat("en-IE", { day: "numeric", month: "short", year: "numeric" }).format(new Date(latestEntry.data.published)) : "No date"; const totalEvents = calendarEvents.length + recurringCalendarEvents.length; -const configuredServices = [contactFormEndpoint, plausibleDomain].filter(Boolean).length; +const contactConfigured = Boolean(contactFormEndpoint); +const analyticsConfigured = Boolean(plausibleDomain); +const configuredServices = [contactConfigured, analyticsConfigured].filter(Boolean).length; const speechAdminEntries = speechEntries.map((entry) => speechAdminEntryFromArchiveEntry(entry, today)); +const speakerLabels = { + rev: "Rev. Sun Myung Moon", + mrs: "Dr. Hak Ja Han Moon", + other: "Other speaker", +}; const adminConfig = { analyticsDashboardUrl, - contactEndpointConfigured: Boolean(contactFormEndpoint), + contactEndpointConfigured: contactConfigured, contactSubmissionsUrl, plausibleDomain, }; @@ -33,906 +43,698 @@ const adminConfig = { - FamilyFed.ie Admin + + Overview · FamilyFed.ie Admin - -
-
-
-
- -
-

admin.familyfed.ie

-

FamilyFed.ie Admin

-
-
-
-
+ Skip to content -
-
+
+
+
+
+

Speech library

+

{speechAdminEntries.length} files in the archive

+
+
+
+
+ + + +
+
+ + + +
+

+
+
    + {speechAdminEntries.map((speech) => ( +
  • + +
  • + ))} +
+ + +
+ +
+
+
+

New speech

+

Generate a Markdown file for content/speeches.

+
+ New file +
+
+
+ + + + + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + + Paste the existing HTML content or write simple HTML paragraphs. +
+ + + +
+ + Generated Markdown + Complete the required fields to generate a file. + +
+ +
+ + Download or copy the file, add it to the path above, then commit and deploy. +
+
+
+
+
+
+
+ + + + +
diff --git a/src/styles/admin.css b/src/styles/admin.css new file mode 100644 index 00000000..d4011749 --- /dev/null +++ b/src/styles/admin.css @@ -0,0 +1,1550 @@ +:root { + color-scheme: light; + --admin-bg: #f3f5f4; + --admin-surface: #ffffff; + --admin-surface-soft: #f8faf9; + --admin-sidebar: #18303a; + --admin-sidebar-soft: #24424d; + --admin-text: #1c292f; + --admin-muted: #66757b; + --admin-border: #dce4e1; + --admin-border-strong: #cbd7d2; + --admin-primary: #b44f2e; + --admin-primary-hover: #8f391f; + --admin-primary-soft: #fff0e9; + --admin-blue: #2f6488; + --admin-blue-soft: #eaf3f8; + --admin-success: #2d6c52; + --admin-success-soft: #e9f5ef; + --admin-warning: #916019; + --admin-warning-soft: #fff5dd; + --admin-danger: #a23c2b; + --admin-shadow: 0 10px 30px rgba(24, 48, 58, 0.07); + --admin-radius: 12px; + --admin-radius-small: 8px; +} + +* { + box-sizing: border-box; +} + +html { + min-width: 320px; + background: var(--admin-bg); + scroll-behavior: smooth; +} + +body { + min-height: 100vh; + margin: 0; + color: var(--admin-text); + background: var(--admin-bg); + font-family: + Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", + sans-serif; + font-size: 15px; + line-height: 1.5; + -webkit-font-smoothing: antialiased; +} + +button, +input, +select, +textarea { + font: inherit; +} + +button, +a { + -webkit-tap-highlight-color: transparent; +} + +a { + color: var(--admin-primary-hover); + text-underline-offset: 3px; +} + +code { + padding: 2px 5px; + border-radius: 5px; + background: rgba(28, 41, 47, 0.07); + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + font-size: 0.9em; +} + +:focus-visible { + outline: 3px solid rgba(180, 79, 46, 0.25); + outline-offset: 2px; +} + +.admin-skip-link { + position: fixed; + top: 12px; + left: 12px; + z-index: 100; + padding: 10px 14px; + border-radius: var(--admin-radius-small); + color: #ffffff; + background: var(--admin-primary); + font-weight: 800; + text-decoration: none; + transform: translateY(-160%); +} + +.admin-skip-link:focus { + transform: translateY(0); +} + +.admin-visually-hidden { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + margin: -1px; + padding: 0; + border: 0; + clip: rect(0 0 0 0); + clip-path: inset(50%); + white-space: nowrap; +} + +.admin-app { + display: grid; + grid-template-columns: 258px minmax(0, 1fr); + min-height: 100vh; +} + +.admin-sidebar { + position: sticky; + top: 0; + z-index: 30; + display: flex; + align-self: start; + height: 100vh; + flex-direction: column; + gap: 28px; + padding: 26px 18px 20px; + color: #ffffff; + background: + radial-gradient(circle at 5% 0%, rgba(83, 133, 158, 0.34), transparent 34%), + var(--admin-sidebar); +} + +.admin-brand { + display: flex; + min-width: 0; + gap: 12px; + align-items: center; + padding: 0 7px; + color: #ffffff; + text-decoration: none; +} + +.admin-brand-mark { + display: grid; + width: 46px; + height: 46px; + flex: 0 0 46px; + place-items: center; + border-radius: 13px; + background: #ffffff; + box-shadow: 0 10px 24px rgba(0, 0, 0, 0.18); +} + +.admin-brand-mark img { + width: 38px; + height: 38px; + object-fit: contain; +} + +.admin-brand-copy { + min-width: 0; +} + +.admin-brand-copy strong, +.admin-brand-copy span { + display: block; +} + +.admin-brand-copy strong { + overflow: hidden; + font-size: 16px; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.admin-brand-copy span { + margin-top: 3px; + color: rgba(255, 255, 255, 0.66); + font-size: 12px; +} + +.admin-nav { + display: grid; + gap: 6px; +} + +.admin-nav-label { + margin: 0 10px 5px; + color: rgba(255, 255, 255, 0.5); + font-size: 10px; + font-weight: 800; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +.admin-nav-button { + display: flex; + width: 100%; + min-height: 46px; + gap: 11px; + align-items: center; + padding: 10px 12px; + border: 1px solid transparent; + border-radius: 9px; + color: rgba(255, 255, 255, 0.72); + background: transparent; + font-weight: 700; + text-align: left; + cursor: pointer; + transition: 150ms ease; + transition-property: color, background, border-color, transform; +} + +.admin-nav-button svg { + width: 19px; + height: 19px; + flex: 0 0 19px; +} + +.admin-nav-button:hover { + color: #ffffff; + background: rgba(255, 255, 255, 0.07); +} + +.admin-nav-button[aria-selected="true"] { + border-color: rgba(255, 255, 255, 0.08); + color: #ffffff; + background: var(--admin-sidebar-soft); + box-shadow: 0 8px 22px rgba(0, 0, 0, 0.13); +} + +.admin-nav-button[aria-selected="true"]::after { + width: 6px; + height: 6px; + margin-left: auto; + border-radius: 50%; + background: #ef9a77; + content: ""; +} + +.admin-sidebar-note { + display: grid; + gap: 8px; + margin-top: auto; + padding: 14px; + border: 1px solid rgba(255, 255, 255, 0.09); + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); +} + +.admin-sidebar-note strong { + font-size: 13px; +} + +.admin-sidebar-note p { + margin: 0; + color: rgba(255, 255, 255, 0.62); + font-size: 12px; + line-height: 1.55; +} + +.admin-page { + min-width: 0; +} + +.admin-topbar { + position: sticky; + top: 0; + z-index: 20; + display: flex; + min-height: 82px; + gap: 24px; + align-items: center; + justify-content: space-between; + padding: 16px clamp(22px, 3vw, 42px); + border-bottom: 1px solid rgba(220, 228, 225, 0.92); + background: rgba(255, 255, 255, 0.9); + backdrop-filter: blur(16px); +} + +.admin-topbar-copy { + min-width: 0; +} + +.admin-topbar-copy p, +.admin-topbar-copy h1 { + margin: 0; +} + +.admin-topbar-copy p { + color: var(--admin-muted); + font-size: 12px; + font-weight: 750; +} + +.admin-topbar-copy h1 { + margin-top: 1px; + font-size: 23px; + line-height: 1.2; +} + +.admin-topbar-actions { + display: flex; + flex-wrap: wrap; + gap: 9px; + align-items: center; + justify-content: flex-end; +} + +.admin-main { + width: min(1440px, 100%); + margin: 0 auto; + padding: 30px clamp(22px, 3vw, 42px) 52px; +} + +.admin-tab-panel { + display: grid; + gap: 22px; +} + +.admin-tab-panel[hidden], +[hidden] { + display: none !important; +} + +.admin-section-heading { + display: flex; + gap: 24px; + align-items: end; + justify-content: space-between; +} + +.admin-section-heading h2, +.admin-section-heading p { + margin: 0; +} + +.admin-section-heading h2 { + margin-top: 3px; + font-size: clamp(25px, 3vw, 34px); + line-height: 1.16; + letter-spacing: -0.025em; +} + +.admin-section-heading > div > p:last-child { + max-width: 720px; + margin-top: 7px; + color: var(--admin-muted); +} + +.admin-eyebrow { + color: var(--admin-primary) !important; + font-size: 11px; + font-weight: 850; + letter-spacing: 0.1em; + text-transform: uppercase; +} + +.admin-section-actions, +.admin-button-row { + display: flex; + flex-wrap: wrap; + gap: 9px; + align-items: center; +} + +.admin-button, +.admin-link-button { + display: inline-flex; + min-height: 42px; + gap: 8px; + align-items: center; + justify-content: center; + padding: 9px 14px; + border: 1px solid var(--admin-border-strong); + border-radius: var(--admin-radius-small); + color: var(--admin-text); + background: var(--admin-surface); + box-shadow: 0 1px 2px rgba(24, 48, 58, 0.04); + font-weight: 750; + font-size: 14px; + line-height: 1.2; + text-decoration: none; + cursor: pointer; + transition: 150ms ease; + transition-property: border-color, background, color, box-shadow, transform; +} + +.admin-button svg, +.admin-link-button svg { + width: 17px; + height: 17px; +} + +.admin-button:hover, +.admin-link-button:hover { + border-color: #b8c7c1; + background: #fbfcfb; + box-shadow: 0 4px 12px rgba(24, 48, 58, 0.08); + transform: translateY(-1px); +} + +.admin-button-primary, +.admin-link-button-primary { + border-color: var(--admin-primary); + color: #ffffff; + background: var(--admin-primary); +} + +.admin-button-primary:hover, +.admin-link-button-primary:hover { + border-color: var(--admin-primary-hover); + color: #ffffff; + background: var(--admin-primary-hover); +} + +.admin-button-subtle { + border-color: transparent; + color: var(--admin-primary-hover); + background: var(--admin-primary-soft); + box-shadow: none; +} + +.admin-button-quiet { + border-color: transparent; + color: var(--admin-muted); + background: transparent; + box-shadow: none; +} + +.admin-button:disabled, +.admin-link-button[aria-disabled="true"] { + border-color: var(--admin-border); + color: #95a19d; + background: #edf1ef; + box-shadow: none; + cursor: not-allowed; + pointer-events: none; + transform: none; +} + +.admin-overview-banner { + position: relative; + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 30px; + align-items: center; + overflow: hidden; + padding: 30px; + border: 1px solid rgba(47, 100, 136, 0.16); + border-radius: 16px; + color: #ffffff; + background: + radial-gradient(circle at 88% 18%, rgba(104, 163, 194, 0.34), transparent 34%), + linear-gradient(135deg, #18303a, #244957); + box-shadow: var(--admin-shadow); +} + +.admin-overview-banner::after { + position: absolute; + right: -70px; + bottom: -115px; + width: 270px; + height: 270px; + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: 50%; + content: ""; +} + +.admin-banner-copy, +.admin-banner-actions { + position: relative; + z-index: 1; +} + +.admin-banner-copy h2, +.admin-banner-copy p { + margin: 0; +} + +.admin-banner-copy h2 { + max-width: 700px; + font-size: clamp(27px, 4vw, 40px); + line-height: 1.08; + letter-spacing: -0.035em; +} + +.admin-banner-copy p { + max-width: 680px; + margin-top: 10px; + color: rgba(255, 255, 255, 0.7); +} + +.admin-banner-actions { + display: grid; + min-width: 190px; + gap: 9px; +} + +.admin-banner-actions .admin-button, +.admin-banner-actions .admin-link-button { + width: 100%; +} + +.admin-banner-actions .admin-button:not(.admin-button-primary), +.admin-banner-actions .admin-link-button { + border-color: rgba(255, 255, 255, 0.16); + color: #ffffff; + background: rgba(255, 255, 255, 0.08); + box-shadow: none; +} + +.admin-banner-actions .admin-button:not(.admin-button-primary):hover, +.admin-banner-actions .admin-link-button:hover { + background: rgba(255, 255, 255, 0.14); +} + +.admin-stat-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 14px; +} + +.admin-stat-card { + display: grid; + grid-template-columns: auto minmax(0, 1fr); + gap: 13px; + align-items: start; + min-height: 128px; + padding: 18px; + border: 1px solid var(--admin-border); + border-radius: var(--admin-radius); + background: var(--admin-surface); + box-shadow: 0 3px 16px rgba(24, 48, 58, 0.035); +} + +.admin-stat-icon { + display: grid; + width: 38px; + height: 38px; + place-items: center; + border-radius: 10px; + color: var(--admin-blue); + background: var(--admin-blue-soft); +} + +.admin-stat-icon.is-warm { + color: var(--admin-primary); + background: var(--admin-primary-soft); +} + +.admin-stat-icon.is-green { + color: var(--admin-success); + background: var(--admin-success-soft); +} + +.admin-stat-icon svg { + width: 19px; + height: 19px; +} + +.admin-stat-copy { + min-width: 0; +} + +.admin-stat-copy span, +.admin-stat-copy strong, +.admin-stat-copy small { + display: block; +} + +.admin-stat-copy span { + color: var(--admin-muted); + font-size: 12px; + font-weight: 700; +} + +.admin-stat-copy strong { + margin-top: 4px; + overflow-wrap: anywhere; + font-size: 25px; + line-height: 1.1; + letter-spacing: -0.025em; +} + +.admin-stat-copy small { + margin-top: 8px; + color: var(--admin-muted); + font-size: 11px; +} + +.admin-overview-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 14px; + align-items: stretch; +} + +.admin-panel { + overflow: hidden; + border: 1px solid var(--admin-border); + border-radius: var(--admin-radius); + background: var(--admin-surface); + box-shadow: 0 3px 16px rgba(24, 48, 58, 0.035); +} + +.admin-panel-header { + display: flex; + min-height: 76px; + gap: 16px; + align-items: flex-start; + justify-content: space-between; + padding: 18px 20px; + border-bottom: 1px solid var(--admin-border); +} + +.admin-panel-header h3, +.admin-panel-header p { + margin: 0; +} + +.admin-panel-header h3 { + font-size: 18px; + line-height: 1.3; +} + +.admin-panel-header p { + margin-top: 4px; + color: var(--admin-muted); + font-size: 13px; +} + +.admin-panel-body { + padding: 20px; +} + +.admin-panel-body-compact { + padding: 0; +} + +.admin-latest-card { + display: grid; + gap: 12px; +} + +.admin-content-type { + display: inline-flex; + width: fit-content; + padding: 4px 8px; + border-radius: 999px; + color: var(--admin-blue); + background: var(--admin-blue-soft); + font-size: 11px; + font-weight: 800; + text-transform: capitalize; +} + +.admin-latest-card h4, +.admin-latest-card p { + margin: 0; +} + +.admin-latest-card h4 { + font-size: 18px; + line-height: 1.35; +} + +.admin-latest-card p { + color: var(--admin-muted); + font-size: 13px; +} + +.admin-status-stack { + display: grid; + gap: 11px; +} + +.admin-status-row { + display: flex; + gap: 12px; + align-items: center; + justify-content: space-between; +} + +.admin-status-row-copy { + min-width: 0; +} + +.admin-status-row-copy strong, +.admin-status-row-copy small { + display: block; +} + +.admin-status-row-copy strong { + font-size: 14px; +} + +.admin-status-row-copy small { + margin-top: 2px; + color: var(--admin-muted); + font-size: 12px; +} + +.admin-status-pill { + display: inline-flex; + width: fit-content; + min-height: 27px; + flex: 0 0 auto; + gap: 6px; + align-items: center; + padding: 4px 9px; + border: 1px solid transparent; + border-radius: 999px; + font-size: 11px; + font-weight: 850; + white-space: nowrap; +} + +.admin-status-pill::before { + width: 6px; + height: 6px; + border-radius: 50%; + background: currentColor; + content: ""; +} + +.admin-status-pill.is-ready { + border-color: rgba(45, 108, 82, 0.2); + color: var(--admin-success); + background: var(--admin-success-soft); +} + +.admin-status-pill.is-warning { + border-color: rgba(145, 96, 25, 0.2); + color: var(--admin-warning); + background: var(--admin-warning-soft); +} + +.admin-status-pill.is-neutral { + border-color: rgba(47, 100, 136, 0.18); + color: var(--admin-blue); + background: var(--admin-blue-soft); +} + +.admin-workflow-list { + display: grid; + gap: 14px; + margin: 0; + padding: 0; + counter-reset: admin-workflow; + list-style: none; +} + +.admin-workflow-list li { + display: grid; + grid-template-columns: 28px minmax(0, 1fr); + gap: 10px; + color: var(--admin-muted); + font-size: 13px; + counter-increment: admin-workflow; +} + +.admin-workflow-list li::before { + display: grid; + width: 26px; + height: 26px; + place-items: center; + border-radius: 8px; + color: var(--admin-primary-hover); + background: var(--admin-primary-soft); + content: counter(admin-workflow); + font-size: 11px; + font-weight: 850; +} + +.admin-event-layout { + display: grid; + grid-template-columns: minmax(0, 1.25fr) minmax(340px, 0.75fr); + gap: 18px; + align-items: start; +} + +.admin-preview-panel { + position: sticky; + top: 104px; +} + +.admin-form { + display: grid; + gap: 18px; +} + +.admin-form-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 15px; +} + +.admin-field { + min-width: 0; +} + +.admin-field label { + display: flex; + gap: 7px; + align-items: baseline; + margin-bottom: 7px; + font-size: 13px; + font-weight: 800; +} + +.admin-field .admin-optional { + color: var(--admin-muted); + font-size: 11px; + font-weight: 600; +} + +.admin-field input, +.admin-field select, +.admin-field textarea, +.admin-code-output { + width: 100%; + min-height: 44px; + padding: 10px 11px; + border: 1px solid var(--admin-border-strong); + border-radius: var(--admin-radius-small); + color: var(--admin-text); + background: #ffffff; + box-shadow: inset 0 1px 2px rgba(24, 48, 58, 0.025); + transition: 140ms ease; + transition-property: border-color, box-shadow; +} + +.admin-field textarea { + min-height: 138px; + line-height: 1.55; + resize: vertical; +} + +.admin-field textarea.admin-speech-body { + min-height: 330px; + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + font-size: 13px; +} + +.admin-field input::placeholder, +.admin-field textarea::placeholder { + color: #98a5a0; +} + +.admin-field input:focus, +.admin-field select:focus, +.admin-field textarea:focus, +.admin-code-output:focus { + border-color: var(--admin-primary); + outline: none; + box-shadow: 0 0 0 3px rgba(180, 79, 46, 0.13); +} + +.admin-field-help { + display: block; + margin-top: 6px; + color: var(--admin-muted); + font-size: 11px; +} + +.admin-form-footer { + display: flex; + flex-wrap: wrap; + gap: 10px; + align-items: center; + justify-content: space-between; + padding-top: 2px; +} + +.admin-message { + min-height: 20px; + color: var(--admin-muted); + font-size: 12px; +} + +.admin-message.is-success { + color: var(--admin-success); + font-weight: 750; +} + +.admin-message.is-error { + color: var(--admin-danger); + font-weight: 750; +} + +.admin-output-block { + display: grid; + gap: 12px; +} + +.admin-output-meta { + display: grid; + gap: 4px; +} + +.admin-output-meta strong { + font-size: 12px; +} + +.admin-path { + color: var(--admin-muted); + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + font-size: 11px; + overflow-wrap: anywhere; +} + +.admin-code-output { + min-height: 380px; + color: #233137; + background: #f6f9f7; + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + font-size: 12px; + line-height: 1.55; + resize: vertical; +} + +.admin-handoff-note { + display: grid; + grid-template-columns: auto minmax(0, 1fr); + gap: 10px; + align-items: start; + padding: 12px; + border: 1px solid rgba(47, 100, 136, 0.16); + border-radius: 9px; + color: #355664; + background: var(--admin-blue-soft); + font-size: 12px; +} + +.admin-handoff-note svg { + width: 17px; + height: 17px; + margin-top: 1px; + color: var(--admin-blue); +} + +.admin-speech-layout { + display: grid; + grid-template-columns: minmax(340px, 410px) minmax(0, 1fr); + gap: 18px; + align-items: start; +} + +.admin-speech-collection { + position: sticky; + top: 104px; +} + +.admin-speech-toolbar { + display: grid; + gap: 10px; + padding: 14px; + border-bottom: 1px solid var(--admin-border); + background: var(--admin-surface-soft); +} + +.admin-search-wrap { + position: relative; +} + +.admin-search-wrap svg { + position: absolute; + top: 50%; + left: 12px; + width: 17px; + height: 17px; + color: var(--admin-muted); + pointer-events: none; + transform: translateY(-50%); +} + +.admin-search-wrap input, +.admin-filter-select { + width: 100%; + min-height: 42px; + border: 1px solid var(--admin-border-strong); + border-radius: var(--admin-radius-small); + color: var(--admin-text); + background: #ffffff; +} + +.admin-search-wrap input { + padding: 9px 11px 9px 38px; +} + +.admin-filter-row { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 8px; +} + +.admin-filter-select { + padding: 8px 10px; +} + +.admin-speech-result-count { + min-height: 18px; + margin: 0; + color: var(--admin-muted); + font-size: 11px; +} + +.admin-speech-list { + display: grid; + max-height: calc(100vh - 330px); + min-height: 420px; + overflow: auto; + overscroll-behavior: contain; + margin: 0; + padding: 8px; + list-style: none; + scrollbar-color: #bdc8c4 transparent; +} + +.admin-speech-list > li { + min-width: 0; +} + +.admin-speech-row { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 10px; + align-items: center; + width: 100%; + min-height: 76px; + padding: 11px 10px; + border: 1px solid transparent; + border-radius: 8px; + color: var(--admin-text); + background: transparent; + text-align: left; + cursor: pointer; +} + +.admin-speech-list > li + li .admin-speech-row { + border-top-color: var(--admin-border); + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.admin-speech-row:hover { + border-color: var(--admin-border); + background: var(--admin-surface-soft); +} + +.admin-speech-row.is-selected { + border-color: rgba(180, 79, 46, 0.25); + background: var(--admin-primary-soft); +} + +.admin-speech-row-copy { + min-width: 0; +} + +.admin-speech-row-title { + display: -webkit-box; + overflow: hidden; + font-size: 13px; + font-weight: 800; + line-height: 1.35; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; +} + +.admin-speech-row-meta { + display: flex; + flex-wrap: wrap; + gap: 5px 9px; + margin-top: 5px; + color: var(--admin-muted); + font-size: 10px; +} + +.admin-speech-row-path { + display: block; + overflow: hidden; + margin-top: 4px; + color: #82908b; + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + font-size: 9px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.admin-speech-row-chevron { + display: grid; + width: 30px; + height: 30px; + place-items: center; + border-radius: 8px; + color: var(--admin-muted); + background: #ffffff; +} + +.admin-speech-row-chevron svg { + width: 15px; + height: 15px; +} + +.admin-speech-empty { + padding: 48px 20px; + color: var(--admin-muted); + text-align: center; +} + +.admin-speech-list-footer { + display: grid; + padding: 12px 14px 14px; + border-top: 1px solid var(--admin-border); +} + +.admin-speech-editor .admin-panel-body { + padding: 22px; +} + +.admin-code-details { + overflow: hidden; + border: 1px solid var(--admin-border); + border-radius: var(--admin-radius-small); + background: var(--admin-surface-soft); +} + +.admin-code-details summary { + display: flex; + gap: 12px; + align-items: center; + justify-content: space-between; + min-height: 47px; + padding: 10px 12px; + font-weight: 800; + font-size: 12px; + cursor: pointer; +} + +.admin-code-details summary .admin-path { + max-width: 65%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.admin-code-details[open] summary { + border-bottom: 1px solid var(--admin-border); +} + +.admin-code-details-body { + display: grid; + gap: 10px; + padding: 12px; +} + +.admin-code-details .admin-code-output { + min-height: 240px; +} + +.admin-settings-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 16px; +} + +.admin-setting-card { + display: grid; + gap: 17px; + padding: 20px; + border: 1px solid var(--admin-border); + border-radius: var(--admin-radius); + background: var(--admin-surface); + box-shadow: 0 3px 16px rgba(24, 48, 58, 0.035); +} + +.admin-setting-card-header { + display: flex; + gap: 16px; + align-items: flex-start; + justify-content: space-between; +} + +.admin-setting-card-icon { + display: grid; + width: 42px; + height: 42px; + flex: 0 0 42px; + place-items: center; + border-radius: 11px; + color: var(--admin-blue); + background: var(--admin-blue-soft); +} + +.admin-setting-card-icon svg { + width: 20px; + height: 20px; +} + +.admin-setting-card-title { + min-width: 0; + flex: 1; +} + +.admin-setting-card-title h3, +.admin-setting-card-title p { + margin: 0; +} + +.admin-setting-card-title h3 { + font-size: 17px; +} + +.admin-setting-card-title p { + margin-top: 4px; + color: var(--admin-muted); + font-size: 12px; +} + +.admin-setting-detail { + display: grid; + gap: 6px; + padding: 12px; + border-radius: 9px; + background: var(--admin-surface-soft); +} + +.admin-setting-detail span, +.admin-setting-detail strong { + display: block; +} + +.admin-setting-detail span { + color: var(--admin-muted); + font-size: 11px; +} + +.admin-setting-detail strong { + font-size: 13px; + overflow-wrap: anywhere; +} + +.admin-settings-wide { + grid-column: 1 / -1; +} + +.admin-settings-workflow { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 12px; +} + +.admin-settings-step { + padding: 14px; + border: 1px solid var(--admin-border); + border-radius: 9px; + background: var(--admin-surface-soft); +} + +.admin-settings-step span, +.admin-settings-step strong, +.admin-settings-step p { + display: block; + margin: 0; +} + +.admin-settings-step span { + color: var(--admin-primary); + font-size: 10px; + font-weight: 850; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.admin-settings-step strong { + margin-top: 4px; + font-size: 14px; +} + +.admin-settings-step p { + margin-top: 5px; + color: var(--admin-muted); + font-size: 12px; +} + +@media (max-width: 1220px) { + .admin-stat-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .admin-overview-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .admin-overview-grid .admin-panel:last-child { + grid-column: 1 / -1; + } + + .admin-event-layout { + grid-template-columns: minmax(0, 1fr) minmax(310px, 0.68fr); + } + + .admin-speech-layout { + grid-template-columns: minmax(320px, 360px) minmax(0, 1fr); + } +} + +@media (max-width: 1000px) { + .admin-app { + grid-template-columns: 1fr; + } + + .admin-sidebar { + position: relative; + display: grid; + grid-template-columns: auto minmax(0, 1fr); + height: auto; + gap: 20px; + align-items: center; + padding: 14px 18px; + } + + .admin-brand { + padding: 0; + } + + .admin-brand-mark { + width: 42px; + height: 42px; + flex-basis: 42px; + } + + .admin-brand-mark img { + width: 35px; + height: 35px; + } + + .admin-nav { + display: flex; + min-width: 0; + gap: 5px; + justify-content: flex-end; + overflow-x: auto; + } + + .admin-nav-label, + .admin-sidebar-note { + display: none; + } + + .admin-nav-button { + width: auto; + flex: 0 0 auto; + padding: 9px 11px; + } + + .admin-nav-button[aria-selected="true"]::after { + display: none; + } + + .admin-event-layout, + .admin-speech-layout { + grid-template-columns: 1fr; + } + + .admin-preview-panel, + .admin-speech-collection { + position: static; + } + + .admin-speech-list { + max-height: 520px; + min-height: 0; + } +} + +@media (max-width: 720px) { + .admin-sidebar { + grid-template-columns: 1fr; + gap: 12px; + } + + .admin-brand { + justify-content: center; + } + + .admin-nav { + justify-content: flex-start; + } + + .admin-nav-button { + flex: 1 0 auto; + justify-content: center; + } + + .admin-topbar { + min-height: 72px; + padding: 13px 18px; + } + + .admin-topbar-actions .admin-status-pill { + display: none; + } + + .admin-main { + padding: 22px 16px 40px; + } + + .admin-section-heading, + .admin-overview-banner { + align-items: stretch; + grid-template-columns: 1fr; + } + + .admin-section-heading { + flex-direction: column; + } + + .admin-section-actions { + width: 100%; + } + + .admin-overview-banner { + padding: 23px; + } + + .admin-banner-actions { + grid-template-columns: repeat(2, minmax(0, 1fr)); + min-width: 0; + } + + .admin-banner-actions .admin-link-button { + grid-column: 1 / -1; + } + + .admin-overview-grid, + .admin-settings-grid, + .admin-settings-workflow { + grid-template-columns: 1fr; + } + + .admin-overview-grid .admin-panel:last-child, + .admin-settings-wide { + grid-column: auto; + } + + .admin-form-grid { + grid-template-columns: 1fr; + } + + .admin-panel-header, + .admin-panel-body, + .admin-speech-editor .admin-panel-body { + padding-right: 16px; + padding-left: 16px; + } + + .admin-form-footer { + align-items: stretch; + flex-direction: column; + } + + .admin-form-footer .admin-button-row { + width: 100%; + } + + .admin-form-footer .admin-button, + .admin-form-footer .admin-link-button { + flex: 1 1 150px; + } +} + +@media (max-width: 520px) { + .admin-brand-copy span { + display: none; + } + + .admin-nav-button { + min-width: 70px; + gap: 5px; + flex-direction: column; + font-size: 11px; + } + + .admin-topbar-copy p { + display: none; + } + + .admin-topbar-copy h1 { + font-size: 20px; + } + + .admin-topbar-actions .admin-link-button { + min-height: 39px; + padding: 8px 10px; + } + + .admin-stat-grid { + grid-template-columns: 1fr; + } + + .admin-stat-card { + min-height: 105px; + } + + .admin-banner-actions { + grid-template-columns: 1fr; + } + + .admin-banner-actions .admin-link-button { + grid-column: auto; + } + + .admin-section-actions .admin-button, + .admin-section-actions .admin-link-button { + flex: 1 1 140px; + } + + .admin-filter-row { + grid-template-columns: 1fr; + } + + .admin-speech-row-path { + display: none; + } + + .admin-code-details summary { + align-items: flex-start; + flex-direction: column; + } + + .admin-code-details summary .admin-path { + max-width: 100%; + } +} + +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } + + *, + *::before, + *::after { + scroll-behavior: auto !important; + transition-duration: 0.01ms !important; + } +}