Commit Graph

21 Commits

Author SHA1 Message Date
Sucukdeluxe
77661389f3 Add "keep only German audio" post-extract step for .DL. files
- New video-processor.ts: ffmpeg/ffprobe remux that keeps only the German
  audio track (by language tag, with safe fallbacks) and strips the ".DL."
  marker from the filename
- Runs after extraction in both the deferred and hybrid post-process paths,
  inside the per-package file-op chain; abortable, disk-space checked,
  mtime-preserving, atomic temp->replace so the original is never lost
- System ffmpeg via PATH / RD_FFMPEG_BIN; toggle + track-mode select in settings
2026-06-07 21:17:26 +02:00
Sucukdeluxe
397e667af2 chore: tidy tasks/todo.md (archive completed work, keep open backlog) 2026-06-07 20:17:26 +02:00
Sucukdeluxe
468df99142 Add extended diagnostics logging
- Electron crash handlers (render-process-gone, child-process-gone,
  unresponsive/responsive, process warnings) with a circuit-breaker
  auto-reload for renderer crashes
- Renderer error capture (window.onerror, unhandledrejection, React
  ErrorBoundary) forwarded to the main log via a one-way IPC channel
- Memory-pressure heartbeat measured against the V8 heap_size_limit
- Gated DEBUG log level (RD_DEBUG) and an in-memory ring of recent
  WARN/ERROR lines, exposed via the /errors endpoint and support bundle
- Disk-error classification (ENOSPC etc.) on download failures and
  integrity-check pass/fail logging
2026-06-07 17:00:06 +02:00
Sucukdeluxe
07b034440b Fix: bereits sauber benannte Folgen werden vom Collect nicht mehr verkrueppelt (Miniserien)
Bei Serien, deren per-Episode-Ordner nur einen Episode-only-Token + Titel tragen
("Show.E01.Titel...-GRP", KEIN S01), benannte der Collect eine vom Auto-Rename bereits
korrekt benannte Datei ("Show.S01E01...-GRP.mkv") neu — und haengte den Staffel/Folgen-
Token HINTER die Scene-Gruppe ("...-GRP.S01E01"). In der Library stand dann der Episoden-
titel + ein angehaengtes S01E01 statt sauber S01E01 (gemeldet fuer "Steven Spielbergs Taken").

decideAutoRenameBaseName behaelt im Guard-B-Zweig "Ziel-Ordner ohne SxxExx" jetzt die
QUELLE, wenn sie ein nicht obfuskierter Scene-Name ist (sie traegt dort den einzigen echten
SxxExx-Token) — statt den Token an den Ordnernamen anzuhaengen. Obfuskierte/rohe Quellen
werden weiter aus dem Ordner sauber benannt. Wirkt in Collect und Auto-Rename.

Adversarial (Workflow) abgesichert: der Diskriminator ist allein "Quelle obfuskiert?" —
die Praefix-Laenge ist KEIN Kriterium, sonst fielen kurze Serien (ER, V, 24, Yu) durch und
zeigten denselben Bug. Regressionstest mit ER.S01E01 gepinnt. 4 Unit- + 1 Integrationstest.
2026-06-06 02:51:46 +02:00
Sucukdeluxe
339c46bdd2 Fix: Folgen in vollstaendigem Episoden-Ordner OHNE -GROUP-Suffix werden umbenannt
Alte deutsche Dokus/Serien-Ordner ohne Gruppen-Suffix (Ordner endet auf bare Codec
".XviD", kein "-GROUP") wurden vom Auto-Rename als "kein Zielname" verworfen — die
Folge landete dann ROH in der Library (z.B. "safari-fm-s04e08a.avi" statt
"Fluss-Monster.S04E08a.Am.Essequibo.Teil.1.German.DOKU.SATRiP.XviD.avi").

buildAutoRenameBaseName akzeptiert jetzt zusaetzlich einen vollstaendigen Episoden-
Ordner: echter SxxExx-Token IM Ordnernamen UND ein Codec-/Aufloesungs-Marker
(SCENE_RESOLUTION_MARKER_RE / SCENE_CODEC_MARKER_RE, inkl. xvid/divx). Der Part-
Buchstabe a/b bleibt erhalten (Ordnername dient unveraendert als Zielname), sodass
Teil 1 und Teil 2 nicht kollidieren. Konservativ: ein nackter "Show.S01E01"-Ordner
ohne Qualitaets-/Codec-Marker wird weiterhin nicht abgeleitet. Greift in Auto-Rename
und Collect. 5 Unit- + 1 Collect-Integrationstest; v1.7.180-Fallback nutzt jetzt
dieselben Module-Konstanten (DRY).
2026-06-05 17:54:02 +02:00
Sucukdeluxe
afba79cdfd Fix: Folgen mit Bonus-Wort im Titel bleiben nicht mehr in "Downloader Fertig" liegen
Eine Folge mit gueltigem SxxExx-Token ist eine echte Episode, niemals Bonus/Extras —
auch wenn ihr Titel oder der Episoden-Ordnername ein Bonus-Wort enthaelt
(Interview/Outtakes/Special/Featurette/Making-Of/...). Bisher stufte der Library-
Collect (und Auto-Rename) solche Folgen als Extras ein und verschob sie NIE in die
Bibliothek — extrahiert und korrekt benannt, aber stumm liegengelassen (Skip nur via
logger.info, im Paket-Log unsichtbar). Betraf u.a. Revenge S04E19 "Interview".

Neue isBonusContent()-Guard an beiden Call-Sites: erst SxxExx pruefen (extractEpisodeToken),
nur ohne Token greift der Bonus-Filter (isInsideBonusDir / BONUS_FILENAME_RE). Echte Extras
ohne Token bleiben gefiltert. 2 Integrationstests + 5 Unit-Tests.
2026-06-04 23:05:50 +02:00
Sucukdeluxe
dc271e08ff Renaming: vollstaendigen Episoden-Ordner als Namen nutzen, wenn Quelle keinen SxxExx-Token hat
User-Report (Desktop-Log): "Kreuzfahrt ins Glück" — 25 Folgen "bet_kig_01_hdt.mkv" (obfuskiert,
KEIN SxxExx-Token) landeten roh in der Library, obwohl der Episoden-Ordner
"Kreuzfahrt.ins.Glueck.01.Hochzeitsreise.nach.Burma.2007.German.720p.HDTV.x264-BET" bereits der
saubere Name ist (Episode als "01" statt S01E01).

Ursache (vorbestehend, nicht v1.7.178/179): buildAutoRenameBaseName gibt null zurueck, sobald die
QUELLE keinen SxxExx-Token hat — das "Folge 01"-Nummernformat wurde nie unterstuetzt.

Fix: Fallback in decideAutoRenameBaseName — fehlt der Quell-Episode-Token und kann normal kein
Name abgeleitet werden, aber ein folderCandidate ist ein VOLLSTAENDIGER Scene-Release-Ordner
(Scene-Gruppe UND Aufloesung ODER Codec, kein reiner Season-Ordner), wird dieser Ordnername
direkt verwendet (note "folder-as-is"). Greift NUR ohne Quell-Episode-Token -> Mega-Direct
(mit Quell-Token) bleibt no-target. Aufloesung ODER Codec (nicht nur Aufloesung) deckt
DVDRip/XviD ohne 720p ab (Advisor-Punkt). Bonus/Sample werden vorher gefiltert.

Verifiziert: tsc 6, 682 Tests gruen (+3: Kreuzfahrt real, DVDRip-nur-Codec, Mega-Direct-bleibt-
no-target), Build gruen. Advisor + reproduzierter Diagnose-Test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 02:32:29 +02:00
Sucukdeluxe
e9c6a6bcae lessons: Renaming-Verschlimmbesserung (Unterstrich-Gruppe) dokumentiert 2026-06-03 11:57:29 +02:00
Sucukdeluxe
288a0762a6 Renaming 100%: collect leitet sauberen Namen selbst ab (gemeinsame Entscheidungsfunktion + Wurzel-Schutz)
User-Report (aus dem Desktop-Rename-Log): 17 Dateien landeten ROH in der Library
("tvarchiv...s07e12-720.mkv", "4sf-...s04e01.mkv") — Auto-Rename hatte sie verpasst, der
MKV-Collect schob sie mit dem rohen Scene-Namen weg.

Root Cause 1: Auto-Rename und collectMkvFilesToLibrary sind entkoppelte Scans. Auto-Rename
benennt nur present-and-stable Dateien in extractDir um; eine verpasste Datei (verpasster
Zyklus ODER lag in "Downloader Unfertig" ausserhalb extractDir) wurde von collect roh
weggeschoben (collect behielt blind den Basename).
Root Cause 2: decideAutoRenameBaseName fabrizierte Namen fuer token-lose generische Ordner
("Mega-Direct-Pack" -> "Mega-Direct-Pack.S01E01") wegen eines hasSceneGroupSuffix-Falsch-
Positivs auf "-Pack" — derselbe latente Bug haette Auto-Rename getroffen.

Fix:
- Namens-Entscheidung in EINE pure Funktion extrahiert: decideAutoRenameBaseName (Single
  Source of Truth fuer Auto-Rename UND Collect — koennen nicht mehr divergieren).
- Wurzel-Schutz darin: Rename nur, wenn ein folderCandidate einen echten Season-/Episode-
  Token traegt (kein Fabrizieren aus token-losen Ordnern). Fixt beide Pfade.
- collectMkvFilesToLibrary leitet den sauberen Namen via dieser Funktion ab (gegated auf
  autoRename4sf4sj — respektiert die Umbenenn-Einstellung), inkl. Companion-Untertitel und
  Dedup gegen den sauberen Namen. mkvFiles traegt jetzt sourceRoot fuer die Ordner-Herleitung.
- Auto-Rename-Loop nutzt jetzt die gemeinsame Funktion (behebt nebenbei 2 latente
  use-before-declaration/TDZ-Fehler an resolveRenameItem).
- Latenter Bug: Casing-Zaehler renamedCount -> renamed (war undeklariert -> ReferenceError,
  vom catch verschluckt -> Casing-Korrekturen wurden still verworfen).

Verifiziert: tsc 6 (von 9 — 3 latente Fehler nebenbei behoben), 678 Tests + 9 neue (7
Charakterisierung der Entscheidung + 2 Collect-Integration: raw->clean + Companion/.srt folgt
+ Datei ausserhalb extractDir), Build gruen. Adversarialer Review-Workflow (4 Linsen) + Advisor.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 01:09:21 +02:00
Sucukdeluxe
251c41ca6c Renaming-Logging: lueckenloses Desktop-Protokoll pro Sitzung + Post-Rename-Verifikation
User-Goal: bei kuenftigen Renaming-Problemen eine vollstaendige, sofort auffindbare Uebersicht —
JEDER Umbenenn-/Verschiebevorgang protokolliert UND danach verifiziert (liegt die Datei wirklich
unter dem Zielnamen? Quelle weg? richtige Schreibweise?).

- NEU desktop-rename-log.ts: pro Sitzung <Desktop>/Downloader-Log/rename-session_<ts>.txt; Ordner
  selbstheilend (mkdir recursive vor jedem Write -> auch nach Loeschung zur Laufzeit sofort wieder
  da). Synchroner Append, Schreibfehler verschluckt (bricht nie einen Download).
- verifyRename (sync) + verifyRenameAsync (Hot-Path): prueft Ziel-Existenz, echten On-Disk-Namen
  (case-genau via readdir), Quell-Abwesenheit; Level INFO/WARN/ERROR. Nutzt denselben \?\-Long-
  Path-Prefix wie der echte Rename (sonst falsche Urteile auf langen Scene-Pfaden).
- download-manager: renamePathWithExdevFallback = verifizierter Wrapper um die unveraenderte
  Raw-Logik (deckt alle Media-Renames ab) + 3 Sync-Sites (startup-Dedup, Deobfuskation, Suffix-Fix)
  via logVerifiedRenameSync; logRenameProcess spiegelt ins Desktop-Log.
- app-controller init/shutdown (getPath("desktop") gegen Startup-Crash abgesichert); support-bundle
  packt das Log mit ein.

Adversarialer Review-Workflow (4 Linsen) fand + behoben: Long-Path-Verify-Bug (falsches OK
maskiert halb-fertigen Move), readdir-Fehler-False-OK, sync-I/O im Hot-Path, getPath-Guard,
Test-Temp-Cleanup. tsc 9 (Baseline), 663 Tests (+7 neue), Build gruen.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 13:14:55 +02:00
Sucukdeluxe
ffcd0817cf Mega-Debrid: Account am Tageslimit bis Neustart parken (Streak-Heuristik) statt endlos neu testen
User-Entscheidung: ein Mega-Debrid-Account am Tageslimit soll bis zum Programm-Neustart
uebersprungen werden, nicht alle 20s/2min neu getestet.

Ground Truth (Support-Bundle gegrept): der limitierte Account liefert im Web-Pfad NIE eine
unterscheidbare Meldung — "Kein Server" = 0 Treffer, "Antwort leer" = 20.861. Tageslimit und
transienter Blip sind auf Message-Ebene nicht trennbar (generate() findet ohne processDebrid-
Code keinen Code -> return null -> "Antwort leer"). Ein Trigger auf "Kein Server" waere toter Code.

Loesung (Verhaltens-Signal statt Wortlaut):
- megaDebridEmptyResponseStreaks zaehlt aufeinanderfolgende "Antwort leer"/"Kein Server"-
  Treffer je Account; ab 3 wird der Account bis Neustart geparkt (until=MAX_SAFE_INTEGER,
  nur In-Memory -> Neustart loescht). Erfolg/anderer Fehler setzt zurueck.
- classifyAccountFailure markiert beide Signale als limitSignal (Symmetrie: ein einzelner
  evtl. transienter Treffer parkt NICHT, behaelt kurzen Cooldown).
- Skip-Branch: "uebersprungen (bis Neustart gesperrt)", traegt nicht zu earliestCooldownUntil
  bei (kein absurder Retry-Timer); Post-Loop wirft klare Endmeldung wenn alle geparkt.
- generate() surfacet "Kein Server" zusaetzlich als Page-Error (falls es doch im HTML steht).
- UI: Rotations-Verlauf zeigt "bis Neustart gesperrt".

Verifiziert: tsc 9 (Baseline), 655 Tests + 5 neue (inkl. Wiring-E2E der eine echte leere
Antwort durch unrestrictWithAccounts->classify->catch->Park treibt), Build gruen.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 21:08:43 +02:00
Sucukdeluxe
66878174e6 Feature: Mega-Debrid-Accounts einzeln (temporaer) deaktivieren — UI-Toggle
Backend war bereits vorhanden (megaDebridDisabledAccountIds + Rotation-Skip +
Storage-Normalisierung); es fehlte nur das UI. Spiegelt das Debrid-Link-Muster:
im Account-Bearbeiten-Dialog bekommt jeder Mega-Account einen Aktivieren/
Deaktivieren-Toggle (+ "Deaktiviert"-Badge). Der Disabled-Zustand wird im Dialog-
Draft gehalten (megaDisabledIds) und beim Speichern via applyAccountDialogToSettings
in megaDebridDisabledAccountIds uebernommen (gefiltert auf vorhandene Accounts).
Kein Live-Persist mitten im Dialog -> kohaerent mit dem draft-then-Save-Modell.

Wirkt OHNE Neustart: DebridService.unrestrictLink liest this.settings live
(setSettings propagiert die Liste), unrestrictWithAccounts ueberspringt deaktivierte
Accounts (gleicher Mechanismus wie Daily-Limit/Cooldown-Skip).

Test: "skips a manually disabled Mega-Debrid account" — acc1 disabled -> acc2 loest
auf (beweist den ID-Seam getMegaDebridAccountId). 643 Tests gruen, tsc 9, Build sauber.
GUI-Toggle compile-/build-verifiziert, im laufenden Electron noch nicht click-getestet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 13:08:09 +02:00
Sucukdeluxe
613ebfd50a Docs: lessons.md — Fix-Diagnose empirisch bestaetigen (Timeout != Account-Haenger)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 00:07:23 +02:00
Sucukdeluxe
4bded129ce Docs: lessons.md — Hung-Chat fortsetzen via reflog-Recovery
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 23:45:41 +02:00
Sucukdeluxe
2448ae5c7a Docs: lessons.md — Release-Verifikation + Gitea-UNIQUE-Recovery + curl-F-Leerzeichen
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 22:54:50 +02:00
Sucukdeluxe
3977184fd4 Account-Rotation: Login/Premium-Badges + Live-Rotations-Panel + "Alle pruefen"
- Pro Mega-Debrid-Account UND Debrid-Link-Key im Bearbeiten-Dialog: Badge mit
  Login-Gueltigkeit + Premium-Restlaufzeit (connectUser vip_end / account/infos premiumLeft)
- "Alle pruefen"-Button oben rechts; prueft alle Accounts (Concurrency-Cap 4),
  Ergebnis persistiert (debridAccountStatuses), ueberlebt Neustart
- Rotations-Verlauf-Panel: zeigt live welcher Account/Key versucht wurde + warum
  gewechselt (Ring-Buffer -> Snapshot -> UI), statt nur "Link-Umwandlung erneut"
- Bug A: Mega-Debrid Per-Account-Verbrauch wurde nie erfasst (Heute/Insgesamt immer 0)
- Bug B: isProviderConfigured erkannte reine megaCredentials-Multi-Config nicht
- Neu: account-check.ts (standalone), CHECK_DEBRID_ACCOUNTS IPC, 13 Tests

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 21:19:23 +02:00
Sucukdeluxe
d923d6dabb Docs: tasks/lessons.md — Befund-gegen-Realitaet gaten + Crash-Debris stashen
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 22:25:16 +02:00
Sucukdeluxe
35622445da Fix: Deferred-Final-Pass benennt frische Dateien vor dem Collect um
Folge-Fund zu 18eada9 (Opus-Verifikation des deferFreshFiles-Konzepts):
18eada9 schloss den "frische Datei landet mit Original-Scene-Namen in der
Library"-Bug nur fuer den Hybrid-Pfad (deferFreshFiles=true + Mehrfach-Paesse).
Der finale Deferred-Pass blieb betroffen.

Root Cause (verifiziert via failing Test gegen HEAD):
- runDeferredPostExtraction macht Rename -> Collect (deferFreshFiles=false). Ist
  eine Datei beim Deferred-Rename noch "frisch" (juenger als fileStabilizeMinAgeMs,
  prod=2000ms) -- v.a. eine eben per Nested-Extraction geschriebene Datei --
  ueberspringt der Frische-Gate sie, und der Collect moved sie mit Original-
  Scene-Namen in die Library. collectMkvFilesToLibrary benennt selbst nicht um
  (buildUniqueFlattenTargetPath, nur Flatten).
- Im Deferred-FINAL-Pass gibt es keinen concurrent Extractor-Write mehr
  (Extraktion inkl. Nested ist awaited) -- der Frische-Gate ist dort ein False
  Positive. Pre-existierender Gap (Frische-Skip aelter als 18eada9), auch
  v1.7.162 betroffen.

Fix (minimal): treatFilesAsStable-Param durch autoRenameExtractedVideoFiles(Impl).
Der Deferred-Final-Pass ruft mit treatFilesAsStable=true -> Frische-Gate umgangen
-> alle Dateien werden umbenannt, bevor der Collect sie sammelt. Hybrid-Pfad
unangetastet (nutzt ...Impl mit Default false -> Frische-Skip bleibt aktiv).

Regressionstest: frische Datei im Deferred-Pass landet UMBENANNT in der Library.
623 Tests gruen, tsc unveraendert (9 pre-existing).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 22:16:01 +02:00
Sucukdeluxe
682bd1d759 M2 sauber gelöst: Auto-Relaunch nach Backup-Import
Problem: nach importBackup hielt der Manager weiter die STALE In-Memory-Session
(Import schrieb nur auf Disk). blockAllPersistence wurde gesetzt um Überschreiben
zu verhindern, aber nie zurückgesetzt → ignorierte der User die manuelle
"Bitte neustarten"-Aufforderung und arbeitete weiter, ging bei hartem Crash
alles verloren (stille Persistenz-Blockade).

In-Memory-Reload verworfen: aborted activeTasks settlen ASYNC und greifen in
ihren finally-Blöcken auf this.session.items[id] zu — ein Session-Swap würde
dagegen racen. Sicherer Reload bräuchte async-Refactor (alle Tasks awaiten).

Lösung: Auto-Relaunch. Nach restored===true startet main.ts die App automatisch
neu (1.5s Delay für Toast). Der frische Prozess lädt die restored Session sauber
über den bewährten Startup-Pfad — null Stale-State-Risiko. Main-getrieben (nicht
Renderer), damit ein Renderer-Fehler den Restart nicht verhindern kann.
skipShutdownPersist/blockAllPersistence schützen weiterhin das kurze Fenster +
den Quit (prepareForShutdown:5680 überspringt Persistenz sauber, fasst die stale
Session nicht an). Nach Relaunch: frischer Prozess, Flags zurückgesetzt — Footgun weg.

621 Tests grün, tsc-Fehlerzahl unverändert (9 pre-existing).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 17:35:51 +02:00
Sucukdeluxe
7d52d5a495 Deferred-Post-Processing Lifecycle härten (H1/H2/M1) + 0-Byte-Fix (H3) + Dead Code (N1)
Aus der Bug-Analyse (3 Subagents): die Deferred-Post-Processing-Pipeline war
nur halb ins Abbruch-/Lifecycle-Management integriert — gleiche Ecke wie der
v1.7.156-Datenverlust.

H1: abortPostProcessing (globaler Stop/Shutdown/clearAll/external) bricht jetzt
    auch packageDeferredPostProcessAbortControllers + die neue Hybrid-Map ab.
    Vorher rasten MKV-Move/Cleanup/Rename gegen den synchronen Shutdown-Save.

H2: Hybrid-Post-Extract (Rename+MKV-Collect) lief als komplett ungetracktes
    detached Promise. Jetzt in packageHybridPostProcessControllers (Set/Package)
    registriert — SYNCHRON vor dem Promise, mit shouldAbort an beide Aufrufe.
    Bewusst SEPARAT von der Deferred-Map, sonst würde runDeferredPostExtraction's
    replace-Logik die laufende Hybrid-Arbeit selbst killen (Advisor-Fund).
    Cancel/Reset/Stop stoppt jetzt laufende Hybrid-Verschiebungen.

M1: hasAnyDeferredPostProcessPending() — Scheduler-Abschluss + finishRun-Clear
    gaten darauf. Run endet/Summary feuert nicht mehr während im Hintergrund
    noch Dateien verschoben werden; Run-State wird nicht mehr mittendrin geleert.

H3: validateDownloadedFileCompletion akzeptierte 0-Byte bei source=stream-end
    (kein Content-Length, keine Provider-Größe) als "fertig". Jetzt ok:false
    -> bestehender download_underflow-Retry-Pfad. Verhindert leere Datei = komplett.

N1: toter (unerreichbarer) Disk-Fallback-Block in findReadyArchiveSets +
    verwaiste pendingItemStatus-Map entfernt (verhaltensneutral).

Bewusst übersprungen: M2 (blockAllPersistence — vorgeschlagener Reset wäre
unsicher, In-Memory-Session ist nach Import stale) und M3 (cancelPendingAsyncSaves
— Generation-Guard schützt Korrektheit bereits). Siehe tasks/todo.md.

8 neue Tests (tests/download-completion.test.ts) inkl. H3-Regression. 621 Tests grün.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 16:39:34 +02:00
Sucukdeluxe
96bcbd13d7 Ember-Theme: warmer Amber-Akzent auf kühlem Navy
Redesign-Entscheid des Users (siehe design-mockups/): Aurora-Flavor "Ember".
Re-Skin der Dark+Light-Theme-Variablen + hartcodierte Cyan-Stellen:

- --accent Cyan #38bdf8 -> Amber #f2942d, neue --accent-2 Koral #ff7a5c
- Surfaces/Text/Muted leicht ins Warme verschoben (Warm-Kalt-Spannung:
  Amber-Signal auf kühlem Navy bleibt erhalten)
- Download-Progress Cyan-Gradient -> Amber->Koral (3 Stellen)
- Accent-Button + Border -> Amber
- Speed-Chart (App.tsx Canvas) Akzent -> Amber
- Grün (Entpacken/Online/Erfolg) bleibt semantisch unverändert

Bewusst KEINE Glas-/Glow-/Gradient-Mesh-Effekte (User lehnt KI-Look ab) —
nur die warme Farbwelt auf der bestehenden flachen Struktur.

design-mockups/: 4 Erst-Richtungen + Aurora-Flavor-Switcher + Forge (Referenz).
tasks/todo.md: Bug-/Feature-Analyse (3 parallele Subagents).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 16:17:47 +02:00