2 Commits
Author SHA1 Message Date
hnzio dfa236390d Release 0.5.6 2026-10-22 20:54:46 +02:00
hnzio b2467b87f5 Release 0.5.5 2026-10-22 20:41:34 +02:00
9 changed files with 761 additions and 702 deletions

No files matched your search

+44
View File
@@ -237,3 +237,47 @@
- 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
## Oberflächenkorrektur 0.5.5
| Kriterium | Nachweis | Stand |
| ------------------------------------- | ------------------------------------------------------------------------------------------- | --------------------- |
| Nachtblau und Glaswirkung erkennbar | berechnete Transparenz/Unschärfe und Desktop-/Mobilaufnahmen in Darkmode geprüft | erfüllt am 22.10.2026 |
| Schreibfelder im Ruhezustand sichtbar | deckende Feldfarbe, feine Kontur, Innenabstand und Textcursor im Piece-Editor geprüft | erfüllt am 22.10.2026 |
| Goldener Tastaturfokus | berechnete Fokusfarbe und Fokus-Schatten am Titelfeld geprüft; Cyanrahmen nicht mehr aktiv | erfüllt am 22.10.2026 |
| Inhaltsgerechte Feldhöhen | kurze Einleitung ist niedriger als ausführliche Moderationsfläche; beide bleiben skalierbar | erfüllt am 22.10.2026 |
| Lightmode und Smartphone erhalten | fünf Arbeitsansichten bei 1440 × 1000 und 390 × 844 Pixeln ohne Seitenüberlauf geprüft | erfüllt am 22.10.2026 |
## Ausgeführte Prüfungen Oberflächenkorrektur 0.5.5
- `npm run check`: 0 Fehler und 0 Warnungen
- `npm run build`: erfolgreich mit `@sveltejs/adapter-node`
- gezielter Chromium-Lauf in Light/Dark und Desktop/Mobil ohne Konsolenfehler
oder horizontalen Seitenüberlauf; Glas-, Feld- und Fokuswerte zusätzlich
programmatisch geprüft
- vollständige Unit- und E2E-Matrix gemäß Auftrag nicht erneut ausgeführt
- `git diff --check`: erfolgreich
## Oberflächenkorrektur 0.5.6
| Kriterium | Nachweis | Stand |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------- | --------------------- |
| Gold-/Violettlicht und Glasflächen sichtbar | Fundus und Editor in Light/Dark auf Desktop und Mobil visuell sowie über berechnete Werte geprüft | erfüllt am 22.10.2026 |
| Schreibflächen ruhig und eindeutig abgegrenzt | deckende Feldfarbe, Kontur und goldener Fokus im geöffneten Piece-Editor geprüft | erfüllt am 22.10.2026 |
| Neuanlage und Suche unmittelbar erreichbar | sichtbare Fundusaktionen sowie geöffnete Vorlagenauswahl auf Desktop und Mobil geprüft | erfüllt am 22.10.2026 |
| Zusatzfilter und Zeilenaktionen zugänglich | native Aufklappelemente für Filter und Aktionen per Browserinteraktion geprüft | erfüllt am 22.10.2026 |
| Funduszeilen per Tastatur zu öffnen | erster Titeleintrag fokussiert, mit Eingabetaste geöffnet und Editoraufruf geprüft | erfüllt am 22.10.2026 |
| Lightmode und Smartphone ohne Seitenüberlauf | Chromium-Messung bei 1440 × 1000 und 390 × 844 Pixeln in beiden Themes | erfüllt am 22.10.2026 |
## Ausgeführte Prüfungen Oberflächenkorrektur 0.5.6
- `npm run check`: 0 Fehler und 0 Warnungen
- gezielter Chromium-Lauf für Fundus und geöffneten Piece-Editor bei
1440 × 1000 und 390 × 844 Pixeln in Light/Dark ohne Konsolenfehler oder
horizontalen Seitenüberlauf
- Neuanlage, Zusatzfilter, Aktionsmenü, Tastaturöffnung, Glaswerte und goldener
Fokus automatisiert kontrolliert; alle erzeugten Desktop-/Mobilaufnahmen
visuell geprüft
- Produktionsbuild sowie vollständige Unit- und E2E-Matrix gemäß Auftrag nicht
ausgeführt
- `git diff --check`: erfolgreich
+36
View File
@@ -7,6 +7,42 @@ Anmeldung, Rollen, persistente Inhaltsbearbeitung, Sendungsplanung,
Live-Steuerung, Präsentationsausgabe und lokaler Betriebsweg sind dokumentiert.
Etappe 6 wurde nicht begonnen.
## Oberflächenkorrektur 0.5.6
- sichtbare statische Gold- und Blauviolettlichter hinter den halbtransparenten
Navigations- und Editorflächen
- klarere Glaswirkung in Navigation sowie Kopf, Tabs und Fuß des Piece-Editors;
Schreibflächen bleiben deckend, ruhig und goldfokussiert
- Fundus mit dauerhaft sichtbarer Suche und Neuanlage, aufklappbaren Zusatzfiltern
und inhaltsorientierten, vollständig anklickbaren Zeilen
- vorhandene Vorschaubilder beziehungsweise kleine Symbolplatzhalter sowie
gebündelte Menüs für Duplizieren und Archivieren
- bestehende Server-Actions, Filterlogik und Editor-Bereiche unverändert
Geprüft wurden `npm run check` sowie Fundus und geöffneter Piece-Editor in
Chromium bei 1440 × 1000 und 390 × 844 Pixeln in Light/Dark. Die gezielte
Kontrolle umfasste Tastaturöffnung, Menüs, Fokus, Glaswerte, Seitenüberlauf und
visuell geprüfte Screenshots. Produktionsbuild und vollständige Testmatrix wurden
gemäß Auftrag nicht ausgeführt.
## Oberflächenkorrektur 0.5.5
- dunkle Grundfläche mit sehr zurückhaltenden Gold-/Cyan-Lichtfeldern innerhalb
der Anwendung statt gleichmäßig deckender Blauflächen
- Navigation, große Arbeitsflächen und Piece-Dialog als dunkles beziehungsweise
helles Glas mit feiner Lichtkante, Unschärfe und ruhigem Schatten
- Gold für Dialogkontur, Fokus, aktive Zustände und Hauptaktionen; Cyan nur noch
für ergänzende redaktionelle Hinweise und Links
- klar abgegrenzte, weitgehend deckende Schreibfelder mit Goldfokus, Platzhaltern
und nach Textrolle abgestuften Höhen
- bestehende nachträgliche CSS-Override-Schicht entfernt und die Gestaltung in
gemeinsame Tokens und ursprüngliche Komponentenregeln zurückgeführt
Geprüft wurden Typen, Produktionsbuild sowie gezielte Chromium-Ansichten von
Eingang, Fundus, Piece-Editor, Sendungsplanung und Live-Steuerung bei 1440 × 1000
und 390 × 844 Pixeln in beiden Themes. Die vollständige Unit- und E2E-Matrix
bleibt wie beauftragt Schritt 3 vorbehalten.
## Oberflächenrelease 0.5.4
- gemeinsame Light-/Dark-Tokens für ruhige Arbeitsflächen, Cyan als
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "sendewerk",
"version": "0.5.4",
"version": "0.5.6",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sendewerk",
"version": "0.5.4",
"version": "0.5.6",
"dependencies": {
"@node-rs/argon2": "^2.2.2",
"better-sqlite3": "^13.0.3",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "sendewerk",
"private": true,
"version": "0.5.4",
"version": "0.5.6",
"type": "module",
"engines": {
"node": ">=22.17 <25"
+547 -596
View File
File diff suppressed because it is too large. Load diff
@@ -5,7 +5,7 @@
name,
label,
value = $bindable(),
rows = 7,
rows = 4,
placeholder = '',
privateField = false,
form
@@ -228,6 +228,7 @@
>Titel<input
name="presentationTitle"
maxlength="300"
placeholder="Optionaler Anzeigetitel"
bind:value={draft.presentationTitle}
/></label
>
@@ -236,6 +237,7 @@
name="presentationImageUrl"
type="url"
maxlength="2000"
placeholder="https://…"
bind:value={draft.presentationImageUrl}
/></label
>
@@ -244,6 +246,7 @@
name="presentationDescription"
rows="3"
maxlength="1000"
placeholder="Kurzer Text zur Vorschau"
bind:value={draft.presentationDescription}></textarea></label
>
</div>
+120 -102
View File
@@ -59,101 +59,112 @@
<h1>Fundus</h1>
<p class="page-intro">Vorbereitete Inhalte für kommende Sendungen.</p>
</div>
<div class="heading-stat" aria-label={`${visiblePieces.length} gefundene Inhalte`}>
<strong>{visiblePieces.length}</strong><span>Inhalte</span>
<div class="fundus-heading-actions">
<div class="heading-stat" aria-label={`${visiblePieces.length} gefundene Inhalte`}>
<strong>{visiblePieces.length}</strong><span>Inhalte</span>
</div>
<details class="template-picker">
<summary><span aria-hidden="true">+</span> Neues Piece</summary>
<div class="template-grid">
{#each data.templates as template (template.id)}
<form method="POST" action="?/create">
<input type="hidden" name="template" value={template.id} />
<button type="submit"
><strong>{template.name}</strong><span>{template.description}</span></button
>
</form>
{/each}
</div>
</details>
</div>
</header>
{#if form?.error}<div class="form-message error" role="alert">{form.error}</div>{/if}
{#if form?.success}<div class="form-message success" role="status">{form.success}</div>{/if}
<details class="template-picker">
<summary>Neues Piece anlegen</summary>
<div class="template-grid">
{#each data.templates as template (template.id)}
<form method="POST" action="?/create">
<input type="hidden" name="template" value={template.id} />
<button type="submit"
><strong>{template.name}</strong><span>{template.description}</span></button
>
</form>
{/each}
</div>
</details>
<form
id="library-filters"
class="library-filters"
method="GET"
aria-label="Fundus durchsuchen und filtern"
>
<label class="search-field"
><span aria-hidden="true">⌕</span><span class="sr-only">Fundus durchsuchen</span><input
name="q"
type="search"
value={data.filters.query}
placeholder="Titel, Quelle oder Thema suchen"
/></label
>
<label
><span>Status</span><select name="status"
><option value="">Alle</option><option
value="ready"
selected={data.filters.status === 'ready'}>Sendefertig</option
><option value="preparing" selected={data.filters.status === 'preparing'}>In Arbeit</option
></select
></label
>
<label
><span>Format</span><select name="format"
><option value="">Alle</option>{#each data.taxonomy.formats as item (item.id)}<option
value={item.id}
selected={data.filters.formatId === item.id}>{item.name}</option
>{/each}</select
></label
>
<label
><span>Thema</span><select name="topic"
><option value="">Alle</option>{#each data.taxonomy.topics as item (item.id)}<option
value={item.id}
selected={data.filters.topicId === item.id}>{item.name}</option
>{/each}</select
></label
>
<label
><span>Abschnitt</span><select name="category"
><option value="">Alle</option>{#each data.taxonomy.categories as item (item.id)}<option
value={item.id}
selected={data.filters.categoryId === item.id}>{item.name}</option
>{/each}</select
></label
>
<button class="secondary-button" type="submit">Anwenden</button>
<button class="text-button" type="button" onclick={resetFilters}>Zurücksetzen</button>
<div class="fundus-search-row">
<label class="search-field"
><span aria-hidden="true">⌕</span><span class="sr-only">Fundus durchsuchen</span><input
name="q"
type="search"
value={data.filters.query}
placeholder="Titel, Quelle oder Thema suchen"
/></label
>
<button class="secondary-button" type="submit">Suchen</button>
<details class="filter-picker">
<summary><span aria-hidden="true">≡</span> Weitere Filter</summary>
<div class="filter-panel">
<label
><span>Status</span><select name="status"
><option value="">Alle</option><option
value="ready"
selected={data.filters.status === 'ready'}>Sendefertig</option
><option value="preparing" selected={data.filters.status === 'preparing'}
>In Arbeit</option
></select
></label
>
<label
><span>Format</span><select name="format"
><option value="">Alle</option>{#each data.taxonomy.formats as item (item.id)}<option
value={item.id}
selected={data.filters.formatId === item.id}>{item.name}</option
>{/each}</select
></label
>
<label
><span>Thema</span><select name="topic"
><option value="">Alle</option>{#each data.taxonomy.topics as item (item.id)}<option
value={item.id}
selected={data.filters.topicId === item.id}>{item.name}</option
>{/each}</select
></label
>
<label
><span>Abschnitt</span><select name="category"
><option value="">Alle</option
>{#each data.taxonomy.categories as item (item.id)}<option
value={item.id}
selected={data.filters.categoryId === item.id}>{item.name}</option
>{/each}</select
></label
>
<div class="library-filter-options" aria-label="Fundusauswahl erweitern">
<label class="filter-checkbox">
<input
type="checkbox"
name="includeUsed"
value="1"
checked={showUsedPieces}
onchange={(event) => setSourceFilter('includeUsed', event.currentTarget.checked)}
/>
<span>Auch verwendete Inhalte zeigen</span>
</label>
<label class="filter-checkbox">
<input
type="checkbox"
name="includePlanned"
value="1"
checked={showPlannedPieces}
onchange={(event) => setSourceFilter('includePlanned', event.currentTarget.checked)}
/>
<span>Auch eingeplante Inhalte zeigen</span>
</label>
</div>
<div class="filter-actions">
<button class="secondary-button" type="submit">Filter anwenden</button>
<button class="text-button" type="button" onclick={resetFilters}>Zurücksetzen</button>
</div>
</div>
</details>
</div>
</form>
<div class="library-filter-options" aria-label="Fundusauswahl erweitern">
<label class="filter-checkbox">
<input
type="checkbox"
name="includeUsed"
value="1"
form="library-filters"
checked={showUsedPieces}
onchange={(event) => setSourceFilter('includeUsed', event.currentTarget.checked)}
/>
<span>Auch verwendete Inhalte zeigen</span>
</label>
<label class="filter-checkbox">
<input
type="checkbox"
name="includePlanned"
value="1"
form="library-filters"
checked={showPlannedPieces}
onchange={(event) => setSourceFilter('includePlanned', event.currentTarget.checked)}
/>
<span>Auch eingeplante Inhalte zeigen</span>
</label>
</div>
{#if visiblePieces.length}
<div class="piece-grid">
@@ -166,9 +177,12 @@
class="piece-thumbnail"
src={`/media/${piece.mediaId}`}
alt=""
/>{:else}<span class="piece-thumbnail piece-thumbnail-placeholder" aria-hidden="true"
>S</span
>{/if}
/>{:else}<span class="piece-thumbnail piece-thumbnail-placeholder" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none">
<path d="M4.5 6.5h15v11h-15zM7.5 14l3-3 2.2 2.2 1.8-1.7 2.5 2.5" />
<circle cx="15.8" cy="9.2" r="1.2" />
</svg>
</span>{/if}
<div class="piece-primary">
<h2><a href={resolve('/fundus/[id]', { id: piece.id })}>{piece.title}</a></h2>
<p>{piece.summary || 'Noch keine Kurzbeschreibung.'}</p>
@@ -193,22 +207,26 @@
></span
>
</div>
<div class="piece-actions">
<a class="text-link" href={resolve('/fundus/[id]', { id: piece.id })}>Bearbeiten</a>
<form method="POST" action="?/duplicate">
<input type="hidden" name="pieceId" value={piece.id} /><button
class="text-button"
type="submit">Duplizieren</button
>
</form>
<form method="POST" action="?/archive">
<input type="hidden" name="pieceId" value={piece.id} /><input
type="hidden"
name="revision"
value={piece.revision}
/><button class="text-button danger-text" type="submit">Archivieren</button>
</form>
</div>
<details class="piece-actions">
<summary aria-label={`Aktionen für ${piece.title}`}
><span aria-hidden="true">•••</span></summary
>
<div class="piece-actions-popover">
<form method="POST" action="?/duplicate">
<input type="hidden" name="pieceId" value={piece.id} /><button
class="text-button"
type="submit">Duplizieren</button
>
</form>
<form method="POST" action="?/archive">
<input type="hidden" name="pieceId" value={piece.id} /><input
type="hidden"
name="revision"
value={piece.revision}
/><button class="text-button danger-text" type="submit">Archivieren</button>
</form>
</div>
</details>
</article>
{/each}
</div>
+7
View File
@@ -303,6 +303,7 @@
name="summary"
rows="3"
maxlength="2000"
placeholder="Worum geht es in wenigen Sätzen?"
bind:value={draft.summary}></textarea></label
>
<fieldset>
@@ -367,6 +368,7 @@
>Name<input
name="sourceLabel"
maxlength="200"
placeholder="Name der Quelle"
bind:value={source.label}
/></label
><label
@@ -374,6 +376,7 @@
name="sourceUrl"
type="url"
maxlength="2000"
placeholder="https://…"
bind:value={source.url}
/></label
><label
@@ -382,6 +385,7 @@
type="number"
min="0"
max="86400"
placeholder="Optional"
bind:value={source.timecodeSeconds}
/></label
><button
@@ -442,6 +446,7 @@
>Titel<input
name="presentationTitle"
maxlength="300"
placeholder="Optionaler Anzeigetitel"
bind:value={draft.presentationTitle}
oninput={() => (draft.presentationTitleManual = true)}
/></label
@@ -451,6 +456,7 @@
name="presentationImageUrl"
type="url"
maxlength="2000"
placeholder="https://…"
bind:value={draft.presentationImageUrl}
oninput={() => (draft.presentationImageManual = true)}
/></label
@@ -460,6 +466,7 @@
name="presentationDescription"
rows="3"
maxlength="1000"
placeholder="Kurzer Text zur Vorschau"
bind:value={draft.presentationDescription}
oninput={() => (draft.presentationDescriptionManual = true)}></textarea></label
>