diff --git a/docs/ACCEPTANCE.md b/docs/ACCEPTANCE.md index c870f45..e0ee587 100644 --- a/docs/ACCEPTANCE.md +++ b/docs/ACCEPTANCE.md @@ -215,3 +215,25 @@ Präsentationswerkzeug visuell kontrolliert; langer Titel bricht vollständig um, Werkzeugfläche ist opak und die Speicherleiste überdeckt mobil keine Eingaben - `bash -n start.sh` und `git diff --check`: erfolgreich + +## Oberflächenrelease 0.5.4 + +| Kriterium | Nachweis | Stand | +| ------------------------------------------ | ---------------------------------------------------------------------------------------------- | --------------------- | +| Klare Hierarchie in beiden Themes | Eingang, Fundus, Editor, Sendungsplan und Live-Steuerung in Light/Dark visuell kontrolliert | erfüllt am 22.10.2026 | +| Exakte heinzlive-Darkmode-Farben | berechnete Theme-Tokens und Screenshots der dunklen Arbeitsansichten geprüft | erfüllt am 22.10.2026 | +| Responsive Darstellung ohne Seitenüberlauf | Chromium-Messung bei 1440 × 1000 und 390 × 844 Pixeln auf allen gezielt geprüften Ansichten | erfüllt am 22.10.2026 | +| Sendungsplan-Aktionen bleiben erreichbar | drei sichtbare Aktionen einer Planzeile liegen waagerecht auf gleicher Höhe; Mobilbild geprüft | erfüllt am 22.10.2026 | +| Fokus und reduzierte Bewegung | sichtbarer Cyan-Fokusring und bestehende `prefers-reduced-motion`-Regeln im Stylesheet geprüft | erfüllt am 22.10.2026 | + +## Ausgeführte Prüfungen Oberflächenrelease 0.5.4 + +- `npm run check`: 0 Fehler und 0 Warnungen +- `npm run build`: erfolgreich mit `@sveltejs/adapter-node` +- gezielter Chromium-Lauf für Eingang, Fundus, Piece-Editor, Sendungsplan und + Live-Steuerung bei 1440 × 1000 und 390 × 844 Pixeln in Light/Dark ohne + Konsolenfehler oder horizontalen Seitenüberlauf +- Desktop- und Mobilaufnahmen aller genannten Ansichten visuell kontrolliert +- vollständige Unit- und E2E-Matrix nicht erneut ausgeführt, weil dieser Release + ausschließlich Darstellung und redaktionelle Kurztexte verändert +- `git diff --check`: erfolgreich diff --git a/docs/STATUS.md b/docs/STATUS.md index 90280e2..1183196 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -7,6 +7,30 @@ Anmeldung, Rollen, persistente Inhaltsbearbeitung, Sendungsplanung, Live-Steuerung, Präsentationsausgabe und lokaler Betriebsweg sind dokumentiert. Etappe 6 wurde nicht begonnen. +## Oberflächenrelease 0.5.4 + +- gemeinsame Light-/Dark-Tokens für ruhige Arbeitsflächen, Cyan als + Interaktionsfarbe und Gold für die jeweilige Hauptaktion +- Darkmode im heinzlive-Farbraum mit Hintergrund `#0B1220`, Flächen `#152238`, + Text `#FFF7E8`, Sekundärtext `#A9B6C8`, Gold `#E7B957`, Cyan `#67DDE8` und + Grenzen `#30435C` +- vereinheitlichte Navigation, Formulare, Meldungen, Listen, Sendungsplan, + Live-Steuerung und Piece-Dialoge ohne Änderung der Bedienlogik +- kompaktere Planzeilen mit sichtbarem Drag-Griff und waagerechter Aktionsgruppe; + Klick-, Touch- und Tastaturalternativen bleiben erhalten +- verständliche Kontextnamen „Fundusfassung“ und „Sendungsfassung“ sowie weniger + technische Erläuterungen im redaktionellen Arbeitsfluss +- dezente Speicheraktion im gespeicherten Zustand und hervorgehobene Aktion bei + ungespeicherten Änderungen, Fehlern oder Konflikten + +Für diesen Design-Release wurden `npm run check`, `npm run build` und gezielte +Chromium-Sichtkontrollen auf Eingang, Fundus, Piece-Editor, Sendungsplan und +Live-Steuerung bei 1440 × 1000 sowie 390 × 844 Pixeln in Light/Dark ausgeführt. +Konsolenfehler und horizontaler Seitenüberlauf traten dabei nicht auf. Die +vollständige Unit- und E2E-Matrix wurde für die rein visuelle Änderung bewusst +nicht erneut ausgeführt; die fachlichen Nachweise der Etappen 1 bis 5 bleiben +unverändert. + ## Umgesetzter Stand Etappe 1 - SvelteKit-/TypeScript-Monolith mit Node-Adapter diff --git a/package-lock.json b/package-lock.json index d36d868..f2d320a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sendewerk", - "version": "0.5.3", + "version": "0.5.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sendewerk", - "version": "0.5.3", + "version": "0.5.4", "dependencies": { "@node-rs/argon2": "^2.2.2", "better-sqlite3": "^13.0.3", diff --git a/package.json b/package.json index 80fd4db..1286174 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "sendewerk", "private": true, - "version": "0.5.3", + "version": "0.5.4", "type": "module", "engines": { "node": ">=22.17 <25" diff --git a/src/app.css b/src/app.css index aa51b3d..dba2330 100644 --- a/src/app.css +++ b/src/app.css @@ -9,46 +9,56 @@ sans-serif; font-synthesis: none; color-scheme: light; - --bg: #f3f1ec; - --bg-elevated: rgba(255, 255, 255, 0.78); - --panel: #fffefa; + --bg: #f4f7fb; + --bg-elevated: rgba(255, 255, 255, 0.82); + --panel: #fdfefe; --panel-strong: #ffffff; - --panel-soft: #ebe9e3; - --text: #20211f; - --text-muted: #6e706b; - --text-faint: #969891; - --line: rgba(35, 36, 33, 0.1); - --line-strong: rgba(35, 36, 33, 0.16); - --accent: #225a4e; - --accent-soft: #dfece7; - --accent-text: #173e36; - --gold: #c99530; - --danger: #a94a43; - --shadow: 0 18px 45px rgba(56, 52, 44, 0.08); + --panel-soft: #edf2f7; + --text: #172033; + --text-muted: #5d6a7d; + --text-faint: #8491a3; + --line: #dce4ed; + --line-strong: #c5d0dd; + --accent: #087e98; + --accent-soft: #dff5f8; + --accent-text: #07586b; + --gold: #e7b957; + --primary: #d9a43d; + --primary-text: #172033; + --success: #247a5a; + --warning: #9a6a12; + --danger: #b34148; + --shadow: 0 16px 38px rgba(26, 45, 72, 0.09); + --shadow-large: 0 28px 70px rgba(16, 31, 52, 0.18); --sidebar-width: 14rem; - --radius-large: 1.5rem; - --radius-medium: 1rem; - --radius-small: 0.7rem; + --radius-large: 1.35rem; + --radius-medium: 0.95rem; + --radius-small: 0.65rem; } :root[data-theme='dark'] { color-scheme: dark; - --bg: #151714; - --bg-elevated: rgba(31, 34, 30, 0.82); - --panel: #20231f; - --panel-strong: #272a26; - --panel-soft: #2b2e29; - --text: #f1f0ea; - --text-muted: #b1b4ab; - --text-faint: #858980; - --line: rgba(244, 243, 236, 0.1); - --line-strong: rgba(244, 243, 236, 0.18); - --accent: #74b9a7; - --accent-soft: #203d36; - --accent-text: #d9f3eb; + --bg: #0b1220; + --bg-elevated: rgba(21, 34, 56, 0.86); + --panel: #152238; + --panel-strong: #152238; + --panel-soft: #101c30; + --text: #fff7e8; + --text-muted: #a9b6c8; + --text-faint: #7f91a8; + --line: #30435c; + --line-strong: #415875; + --accent: #67dde8; + --accent-soft: #17394c; + --accent-text: #baf8ff; --gold: #e7b957; - --danger: #e48a81; - --shadow: 0 20px 55px rgba(0, 0, 0, 0.24); + --primary: #e7b957; + --primary-text: #0b1220; + --success: #69d6a5; + --warning: #e7b957; + --danger: #ff8d91; + --shadow: 0 18px 42px rgba(0, 0, 0, 0.22); + --shadow-large: 0 32px 80px rgba(0, 0, 0, 0.42); } * { @@ -65,13 +75,7 @@ body { margin: 0; min-width: 20rem; min-height: 100vh; - background: - radial-gradient( - circle at 94% 4%, - color-mix(in srgb, var(--accent) 7%, transparent), - transparent 24rem - ), - var(--bg); + background: var(--bg); color: var(--text); font-size: 0.95rem; line-height: 1.5; @@ -99,7 +103,7 @@ a { } :focus-visible { - outline: 3px solid color-mix(in srgb, var(--accent) 72%, white); + outline: 3px solid var(--accent); outline-offset: 3px; } @@ -1685,8 +1689,9 @@ a { min-height: 2.7rem; padding: 0.6rem 0.9rem; border-radius: var(--radius-small); - background: var(--accent); - color: var(--panel-strong); + background: var(--primary); + box-shadow: 0 7px 18px color-mix(in srgb, var(--gold) 18%, transparent); + color: var(--primary-text); } .secondary-button, @@ -1749,13 +1754,14 @@ a { } .form-message.error { - border-color: color-mix(in srgb, var(--danger) 45%, var(--line)); - background: color-mix(in srgb, var(--danger) 8%, var(--panel)); + border-color: color-mix(in srgb, var(--danger) 68%, var(--line)); + background: color-mix(in srgb, var(--danger) 13%, var(--panel)); + color: var(--text); } .form-message.success { - border-color: color-mix(in srgb, var(--accent) 38%, var(--line)); - background: color-mix(in srgb, var(--accent-soft) 55%, var(--panel)); + border-color: color-mix(in srgb, var(--success) 45%, var(--line)); + background: color-mix(in srgb, var(--success) 10%, var(--panel)); } .account-summary { @@ -4140,6 +4146,393 @@ a { display: none; } +/* Shared visual language: calm work surfaces, cyan interaction, one gold primary action. */ +.sidebar { + border-color: color-mix(in srgb, var(--line) 82%, transparent); + background: color-mix(in srgb, var(--bg-elevated) 92%, transparent); + box-shadow: 8px 0 28px color-mix(in srgb, var(--bg) 70%, transparent); +} + +.brand-mark { + background: var(--accent); + box-shadow: 0 7px 18px color-mix(in srgb, var(--accent) 24%, transparent); +} + +:root[data-theme='dark'] .brand-mark i { + background: var(--bg); +} + +.main-navigation a.active, +.utility-navigation a.active { + border: 1px solid color-mix(in srgb, var(--accent) 24%, var(--line)); + background: var(--accent-soft); + box-shadow: none; + color: var(--accent); +} + +.main-navigation a:hover, +.utility-navigation a:hover, +.theme-toggle:hover { + background: var(--panel-soft); +} + +.theme-toggle, +.logout-button { + border-color: var(--line); +} + +.primary-button, +.secondary-button, +.text-button, +.main-navigation a, +.utility-navigation a, +.inbox-item, +.piece-card, +.usage-row { + transition: + background-color 140ms ease, + border-color 140ms ease, + color 140ms ease, + box-shadow 140ms ease; +} + +.primary-button:hover:not(:disabled) { + background: color-mix(in srgb, var(--primary) 88%, white); + box-shadow: 0 9px 22px color-mix(in srgb, var(--gold) 26%, transparent); +} + +.secondary-button:hover:not(:disabled) { + border-color: color-mix(in srgb, var(--accent) 55%, var(--line)); + background: var(--accent-soft); + color: var(--accent-text); +} + +.text-button, +.text-link, +.auth-link, +.source-feature a { + color: var(--accent); +} + +input, +select, +textarea { + caret-color: var(--accent); +} + +input:focus, +select:focus, +textarea:focus { + border-color: var(--accent) !important; +} + +.quiet-panel, +.builder-pane, +.show-create-panel, +.show-library, +.show-settings, +.live-current, +.next-card, +.live-progress, +.readonly-actions { + border-color: var(--line); + box-shadow: 0 8px 24px color-mix(in srgb, var(--bg) 64%, transparent); +} + +.capture-panel { + padding: clamp(1rem, 2vw, 1.35rem); + border: 0; + box-shadow: var(--shadow); +} + +.capture-form input, +.upload-form input, +.library-filters input, +.library-filters select { + border-color: var(--line-strong); + background: var(--panel-soft); +} + +.inbox-list { + display: grid; + gap: 0.45rem; +} + +.inbox-item { + padding: 0.8rem 0.9rem; + border: 1px solid transparent; + border-radius: var(--radius-small); + background: color-mix(in srgb, var(--panel) 76%, transparent); +} + +.inbox-item:hover, +.inbox-item:focus-visible { + border-color: var(--line); + background: var(--panel); +} + +.inbox-item > span:last-child { + color: var(--accent); + font-weight: 720; +} + +.piece-grid { + border-color: var(--line); + box-shadow: 0 8px 26px color-mix(in srgb, var(--bg) 70%, transparent); +} + +.piece-card:hover, +.piece-card:focus-within { + background: var(--panel-soft); +} + +.piece-actions { + display: flex; + align-items: center; + flex-wrap: wrap; + justify-content: flex-end; + gap: 0.55rem; +} + +.status-label.ready { + background: color-mix(in srgb, var(--success) 15%, var(--panel)); + color: var(--success); +} + +.show-state.ready, +.show-state.live { + color: var(--success); +} + +.live-link { + background: var(--primary); + color: var(--primary-text); +} + +.builder-workspace { + gap: 0.9rem; +} + +.builder-pane { + border: 0; + background: var(--panel); +} + +.run-list { + border-top-color: var(--line); +} + +.run-section { + padding: 0.8rem 0; +} + +.section-drag-handle, +.usage-drag-copy { + position: relative; +} + +.section-drag-handle { + padding-right: 7rem; +} + +.usage-drag-copy { + padding-left: 1.2rem; +} + +.usage-drag-copy::before { + position: absolute; + top: 50%; + left: -0.2rem; + color: var(--text-faint); + font-size: 1rem; + line-height: 1; + content: '⠿'; + transform: translateY(-50%); +} + +.usage-row { + padding: 0.55rem 0.6rem; + border: 1px solid transparent; + background: var(--panel-soft); +} + +.usage-row:hover, +.usage-row:focus-within { + border-color: var(--line-strong); + background: var(--panel-strong); +} + +.usage-row > div:first-child { + display: grid; + min-width: 0; +} + +.usage-row .row-actions { + display: flex; + align-items: center; + gap: 0.18rem; + padding: 0.16rem; + border: 1px solid var(--line); + border-radius: 0.7rem; + background: var(--panel); +} + +.row-actions > form > button, +.usage-edit-button { + border: 0; + background: transparent; +} + +.row-actions > form > button:hover:not(:disabled), +.usage-edit-button:hover { + background: var(--accent-soft); + color: var(--accent); +} + +.piece-editor-dialog { + border-color: color-mix(in srgb, var(--line-strong) 84%, transparent); + background: color-mix(in srgb, var(--panel-strong) 96%, transparent); + box-shadow: var(--shadow-large); + backdrop-filter: blur(24px) saturate(1.15); +} + +.piece-editor-dialog::backdrop { + background: color-mix(in srgb, var(--bg) 72%, transparent); + backdrop-filter: blur(10px); +} + +.piece-dialog-header, +.piece-dialog-tabs, +.piece-dialog-footer { + background: color-mix(in srgb, var(--panel-strong) 90%, transparent); + backdrop-filter: blur(20px) saturate(1.2); +} + +.piece-dialog-header { + padding: 1rem 1.15rem 0.8rem; +} + +.piece-dialog-tabs { + gap: 0.35rem; + padding: 0.45rem 1.15rem; +} + +.piece-dialog-tabs button { + min-height: 2.2rem; + padding-inline: 0.85rem; +} + +.piece-dialog-tabs button.active { + background: var(--accent-soft); + box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 20%, transparent); + color: var(--accent); +} + +.piece-dialog-workspace { + background: var(--bg); +} + +.piece-editor-panel { + width: min(100%, 62rem); +} + +.piece-panel-heading { + margin-bottom: 0.7rem; +} + +.markdown-editor-field { + padding: 0.75rem 0; + border: 0; + border-bottom: 1px solid var(--line); + border-radius: 0; + background: transparent; +} + +.piece-writing-stack .markdown-editor-field:first-child { + padding-top: 0; +} + +.piece-writing-stack .markdown-editor-field:last-child { + border-bottom: 0; +} + +.markdown-editor-field.private-field { + padding: 0.85rem; + border: 1px solid color-mix(in srgb, var(--gold) 38%, var(--line)); + border-radius: var(--radius-medium); + background: color-mix(in srgb, var(--gold) 7%, var(--panel)); +} + +.markdown-editor-field textarea { + min-height: 8.5rem; + padding: 0.7rem 0.2rem; + border: 0; + border-bottom: 1px solid var(--line-strong); + border-radius: 0; + background: transparent; + font-size: 0.9rem; +} + +.markdown-editor-field textarea:focus { + border-bottom-color: var(--accent) !important; + outline: 0; +} + +.markdown-toolbar button { + border-color: transparent; + background: var(--panel-soft); +} + +.piece-meta-details, +.piece-source-editor, +.piece-media-panel, +.piece-source-summary { + border-color: var(--line); + background: color-mix(in srgb, var(--panel) 72%, transparent); + box-shadow: none; +} + +.piece-presentation-preview { + border-color: var(--line-strong); + box-shadow: 0 12px 28px color-mix(in srgb, var(--bg) 72%, transparent); +} + +.piece-dialog-primary-action .save-indicator { + color: var(--text-faint); +} + +.piece-dialog-primary-action .save-indicator.problem { + color: var(--danger); + font-weight: 720; +} + +.live-toolbar { + border: 0; + box-shadow: var(--shadow); +} + +.live-current { + border: 0; +} + +.moderation-card { + background: var(--panel-soft); +} + +.transition-card { + background: color-mix(in srgb, var(--gold) 9%, var(--panel)); +} + +.progress-track span { + background: var(--gold); +} + +.rail-section.active, +.live-run-item.current { + background: var(--accent-soft); + color: var(--accent-text); +} + @media (max-width: 72rem) { .library-filters { grid-template-columns: repeat(3, minmax(0, 1fr)); @@ -4733,6 +5126,66 @@ a { } } +@media (max-width: 52rem) { + .mobile-header, + .mobile-navigation { + border-color: color-mix(in srgb, var(--line) 82%, transparent); + background: color-mix(in srgb, var(--bg-elevated) 90%, transparent); + box-shadow: 0 8px 28px color-mix(in srgb, var(--bg) 72%, transparent); + backdrop-filter: blur(24px) saturate(1.25); + } + + .mobile-navigation a.active { + background: var(--accent-soft); + color: var(--accent); + } + + .capture-panel, + .builder-pane, + .live-toolbar, + .live-current { + border-radius: var(--radius-large); + } + + .piece-dialog-tabs { + scrollbar-width: none; + } + + .piece-dialog-footer { + box-shadow: 0 -10px 30px color-mix(in srgb, var(--bg) 72%, transparent); + } + + .usage-row { + grid-template-columns: minmax(0, 1fr) auto; + } + + .usage-row .row-actions { + align-self: center; + } + + .section-drag-handle { + padding-right: 0; + } + + .live-header-actions { + overflow-x: auto; + justify-content: flex-start; + padding-bottom: 0.2rem; + } + + .live-header-actions > * { + flex: 0 0 auto; + } + + .live-current-actions { + align-items: stretch; + } + + .live-current-actions form:last-child { + margin-left: 0; + } +} + @media (prefers-reduced-motion: reduce) { *, *::before, diff --git a/src/lib/components/UsageEditorDialog.svelte b/src/lib/components/UsageEditorDialog.svelte index 4f005f6..6d52e8b 100644 --- a/src/lib/components/UsageEditorDialog.svelte +++ b/src/lib/components/UsageEditorDialog.svelte @@ -64,7 +64,7 @@ onrequestclose={requestClose} > {#snippet header()} -
Verwendung in dieser Sendung
+Sendungsfassung