From 7d6a340b1379e2cf049b76bdf4e176ac966bfdb9 Mon Sep 17 00:00:00 2001 From: Till JS Date: Wed, 22 Apr 2026 15:42:55 +0200 Subject: [PATCH] refactor(theming): migrate remaining 738 token violations across routes + components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expand validate-theme-tokens.mjs scope from ListViews only to all lib/modules/**/*.svelte and routes/(app)/**/*.svelte. Add a second rule banning the neutral Tailwind palette (gray/slate/zinc/neutral/stone-N) — these should be theme tokens (bg-card, bg-muted, text-foreground, text-muted-foreground, border-border) instead. Apply one-shot codemod (scripts/migrate-theme-tokens.mjs) that replaces: bg-gray-800/900 → bg-card bg-gray-600/700 → bg-muted (with opacity preserved) border-gray-600..900 → border-border text-gray-800/900 → text-foreground text-gray-300 → text-foreground/90 text-gray-400/500/700 → text-muted-foreground placeholder-gray-* → placeholder:text-muted-foreground/60 bg/border-white/N → bg-muted/N, border-border/N text-white/70-90 → text-foreground text-white/40-60 → text-muted-foreground text-white/10-30 → text-muted-foreground/70 42 files touched; biggest: presi/deck/[id] (91 subs), uload/analytics (58), uload/+page (53), presi/+page (47), who/PlayView (35), skilltree/Edit+AddXpModal (28 each), context/* (115 across 4 pages), uload/links+tags (50 across 2). Brand-literal overlays in moodlit/components/mood/{MoodFullscreen, MoodCard,CreateMoodDialog}.svelte stay unmigrated — they render on vivid colour gradients. Validator exempts these 3 files from the white-alpha rule; they still obey the neutral-palette rule. Result: 527 files pass validate:theme-tokens; svelte-check clean with 0 errors. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../modules/guides/views/DetailView.svelte | 4 +- .../inventory/components/StatusBadge.svelte | 2 +- .../components/AchievementCard.svelte | 22 ++- .../components/AchievementCelebration.svelte | 4 +- .../skilltree/components/AddSkillModal.svelte | 20 +- .../skilltree/components/AddXpModal.svelte | 32 +-- .../components/EditSkillModal.svelte | 32 +-- .../components/LevelUpCelebration.svelte | 4 +- .../skilltree/components/SkillCard.svelte | 18 +- .../components/SkillTemplates.svelte | 24 +-- .../skilltree/components/StatsOverview.svelte | 22 +-- .../src/lib/modules/who/views/PlayView.svelte | 45 +++-- .../admin/user-data/[userId]/+page.svelte | 2 +- .../web/src/routes/(app)/context/+page.svelte | 20 +- .../(app)/context/documents/+page.svelte | 18 +- .../(app)/context/documents/[id]/+page.svelte | 12 +- .../routes/(app)/context/spaces/+page.svelte | 18 +- .../(app)/context/spaces/[id]/+page.svelte | 20 +- .../web/src/routes/(app)/food/+page.svelte | 2 +- .../src/routes/(app)/food/[id]/+page.svelte | 2 +- .../src/routes/(app)/memoro/[id]/+page.svelte | 2 +- .../routes/(app)/moodlit/moods/+page.svelte | 6 +- .../routes/(app)/organizations/+page.svelte | 6 +- .../(app)/organizations/[id]/+page.svelte | 24 +-- .../organizations/[id]/landing/+page.svelte | 2 +- .../routes/(app)/picture/archive/+page.svelte | 2 +- .../web/src/routes/(app)/plants/+page.svelte | 2 +- .../web/src/routes/(app)/presi/+page.svelte | 58 +++--- .../routes/(app)/presi/deck/[id]/+page.svelte | 97 ++++----- .../(app)/presi/present/[id]/+page.svelte | 26 +-- .../src/routes/(app)/questions/+page.svelte | 8 +- .../routes/(app)/questions/[id]/+page.svelte | 4 +- .../(app)/quotes/categories/+page.svelte | 2 +- .../src/routes/(app)/skilltree/+page.svelte | 46 +++-- .../(app)/skilltree/achievements/+page.svelte | 28 ++- .../routes/(app)/skilltree/tree/+page.svelte | 14 +- .../web/src/routes/(app)/teams/+page.svelte | 4 +- .../routes/(app)/times/templates/+page.svelte | 2 +- .../web/src/routes/(app)/uload/+page.svelte | 49 ++--- .../(app)/uload/analytics/[id]/+page.svelte | 96 ++++----- .../src/routes/(app)/uload/links/+page.svelte | 33 ++-- .../src/routes/(app)/uload/tags/+page.svelte | 38 ++-- scripts/migrate-theme-tokens.mjs | 184 ++++++++++++++++++ scripts/validate-theme-tokens.mjs | 151 +++++++++----- 44 files changed, 747 insertions(+), 460 deletions(-) create mode 100644 scripts/migrate-theme-tokens.mjs diff --git a/apps/mana/apps/web/src/lib/modules/guides/views/DetailView.svelte b/apps/mana/apps/web/src/lib/modules/guides/views/DetailView.svelte index 2859e4667..47c08be4f 100644 --- a/apps/mana/apps/web/src/lib/modules/guides/views/DetailView.svelte +++ b/apps/mana/apps/web/src/lib/modules/guides/views/DetailView.svelte @@ -143,8 +143,8 @@
{catInfo.label} - {DIFFICULTY_LABELS[guide.difficulty]} - {guide.estimatedMinutes} min + {DIFFICULTY_LABELS[guide.difficulty]} + {guide.estimatedMinutes} min

{guide.title}

{guide.description}

diff --git a/apps/mana/apps/web/src/lib/modules/inventory/components/StatusBadge.svelte b/apps/mana/apps/web/src/lib/modules/inventory/components/StatusBadge.svelte index 8354aa81a..d287d04ae 100644 --- a/apps/mana/apps/web/src/lib/modules/inventory/components/StatusBadge.svelte +++ b/apps/mana/apps/web/src/lib/modules/inventory/components/StatusBadge.svelte @@ -21,7 +21,7 @@ lent: 'bg-amber-100 text-amber-800 dark:bg-amber-900/20 dark:text-amber-400', stored: 'bg-blue-100 text-blue-800 dark:bg-blue-900/20 dark:text-blue-400', for_sale: 'bg-purple-100 text-purple-800 dark:bg-purple-900/20 dark:text-purple-400', - disposed: 'bg-gray-100 text-gray-800 dark:bg-gray-900/20 dark:text-gray-400', + disposed: 'bg-muted text-foreground dark:bg-card/20 dark:text-muted-foreground', }; diff --git a/apps/mana/apps/web/src/lib/modules/skilltree/components/AchievementCard.svelte b/apps/mana/apps/web/src/lib/modules/skilltree/components/AchievementCard.svelte index 8bb692a7c..fbef2b774 100644 --- a/apps/mana/apps/web/src/lib/modules/skilltree/components/AchievementCard.svelte +++ b/apps/mana/apps/web/src/lib/modules/skilltree/components/AchievementCard.svelte @@ -20,7 +20,7 @@
@@ -36,34 +36,38 @@
{#if achievement.unlocked} {:else} - + {/if}
-

+

{achievement.name}

-

+

{achievement.description}

{#if !achievement.unlocked}
-
+
{achievement.progress} / {achievement.condition.threshold} {progressPercent}%
-
+
+{achievement.xpReward} XP {#if achievement.unlocked && achievement.unlockedAt} - + {new Date(achievement.unlockedAt).toLocaleDateString('de-DE')} {/if} diff --git a/apps/mana/apps/web/src/lib/modules/skilltree/components/AchievementCelebration.svelte b/apps/mana/apps/web/src/lib/modules/skilltree/components/AchievementCelebration.svelte index f19107812..6df867b9a 100644 --- a/apps/mana/apps/web/src/lib/modules/skilltree/components/AchievementCelebration.svelte +++ b/apps/mana/apps/web/src/lib/modules/skilltree/components/AchievementCelebration.svelte @@ -70,7 +70,7 @@

{result.achievement.name}

-

{result.achievement.description}

+

{result.achievement.description}

@@ -84,7 +84,7 @@
-

Klicken zum Schließen

+

Klicken zum Schließen

diff --git a/apps/mana/apps/web/src/lib/modules/skilltree/components/AddSkillModal.svelte b/apps/mana/apps/web/src/lib/modules/skilltree/components/AddSkillModal.svelte index 21c56ddb7..d514919bb 100644 --- a/apps/mana/apps/web/src/lib/modules/skilltree/components/AddSkillModal.svelte +++ b/apps/mana/apps/web/src/lib/modules/skilltree/components/AddSkillModal.svelte @@ -48,14 +48,14 @@ aria-modal="true" >

Neuer Skill

@@ -64,20 +64,20 @@
- +
-
- +
{#each Object.entries(BRANCH_INFO) as [key, info]} diff --git a/apps/mana/apps/web/src/lib/modules/skilltree/components/AddXpModal.svelte b/apps/mana/apps/web/src/lib/modules/skilltree/components/AddXpModal.svelte index 095de510c..c2fb14566 100644 --- a/apps/mana/apps/web/src/lib/modules/skilltree/components/AddXpModal.svelte +++ b/apps/mana/apps/web/src/lib/modules/skilltree/components/AddXpModal.svelte @@ -61,17 +61,17 @@ aria-modal="true" >

XP hinzufügen

-

{skill.name} (Lvl {skill.level})

+

{skill.name} (Lvl {skill.level})

@@ -80,7 +80,7 @@
- Schnellauswahl + Schnellauswahl
{#each xpPresets as preset} @@ -99,7 +99,7 @@
-
-
-
-
+
- Vorschau + Vorschau +{xp} XP
-
+
Neuer Stand: {(skill.totalXp + xp).toLocaleString()} XP
@@ -159,7 +159,7 @@ diff --git a/apps/mana/apps/web/src/lib/modules/skilltree/components/EditSkillModal.svelte b/apps/mana/apps/web/src/lib/modules/skilltree/components/EditSkillModal.svelte index 0b773f436..ac2e1413f 100644 --- a/apps/mana/apps/web/src/lib/modules/skilltree/components/EditSkillModal.svelte +++ b/apps/mana/apps/web/src/lib/modules/skilltree/components/EditSkillModal.svelte @@ -60,14 +60,14 @@ aria-modal="true" >

Skill bearbeiten

@@ -82,13 +82,13 @@

Skill löschen?

-

+

"{skill.name}" und alle zugehörigen Aktivitäten werden unwiderruflich gelöscht.

@@ -104,20 +104,22 @@
- +
-
- Kategorie + Kategorie
{#each Object.entries(BRANCH_INFO) as [key, info]}
-
+
-
Level
+
Level
{skill.level}
-
Total XP
+
Total XP
{skill.totalXp.toLocaleString()}
-
Erstellt
+
Erstellt
{new Date(skill.createdAt).toLocaleDateString('de-DE')}
@@ -182,7 +184,7 @@ diff --git a/apps/mana/apps/web/src/lib/modules/skilltree/components/LevelUpCelebration.svelte b/apps/mana/apps/web/src/lib/modules/skilltree/components/LevelUpCelebration.svelte index 9ebe9c6e7..5b405336d 100644 --- a/apps/mana/apps/web/src/lib/modules/skilltree/components/LevelUpCelebration.svelte +++ b/apps/mana/apps/web/src/lib/modules/skilltree/components/LevelUpCelebration.svelte @@ -66,7 +66,7 @@

LEVEL UP!

-

{skillName}

+

{skillName}

-

Klicken zum Schließen

+

Klicken zum Schließen

diff --git a/apps/mana/apps/web/src/lib/modules/skilltree/components/SkillCard.svelte b/apps/mana/apps/web/src/lib/modules/skilltree/components/SkillCard.svelte index bc12a25f1..aa0e7579b 100644 --- a/apps/mana/apps/web/src/lib/modules/skilltree/components/SkillCard.svelte +++ b/apps/mana/apps/web/src/lib/modules/skilltree/components/SkillCard.svelte @@ -21,7 +21,7 @@ function getLevelColor(level: number): string { const colors = [ - 'text-gray-400', + 'text-muted-foreground', 'text-blue-400', 'text-purple-400', 'text-pink-400', @@ -33,7 +33,7 @@

{skill.name}

-

{branchInfo.name}

+

{branchInfo.name}

{#each Array(skill.level) as _, i} {/each} {#each Array(5 - skill.level) as _, i} - + {/each}
@@ -60,7 +60,7 @@
@@ -71,8 +71,8 @@
- XP - + XP + {skill.totalXp.toLocaleString()} {#if !isMaxLevel} / {nextLevelXp.toLocaleString()} @@ -86,7 +86,7 @@ {#if skill.description} -

{skill.description}

+

{skill.description}

{/if} @@ -100,7 +100,7 @@
-

+

Starte schnell mit vorgefertigten Skill-Sets. Wähle eine Vorlage und füge einzelne Skills oder alle auf einmal hinzu.

@@ -135,15 +135,15 @@
{#each Object.entries(templates) as [name, skills]} -
+
-
+
@@ -164,10 +164,10 @@ {#if selectedTemplate === name} -
+
{#each skills as skill} {@const isAdded = addedSkills.has(skill.name)} -
+
{skill.name} - - {skill.description} + - {skill.description}
diff --git a/apps/mana/apps/web/src/lib/modules/skilltree/components/StatsOverview.svelte b/apps/mana/apps/web/src/lib/modules/skilltree/components/StatsOverview.svelte index c8c482bce..278043aaa 100644 --- a/apps/mana/apps/web/src/lib/modules/skilltree/components/StatsOverview.svelte +++ b/apps/mana/apps/web/src/lib/modules/skilltree/components/StatsOverview.svelte @@ -18,13 +18,13 @@
-
+
-

Gesamt-XP

+

Gesamt-XP

{userStats.totalXp.toLocaleString()}

@@ -33,13 +33,13 @@
-
+
-

Skills

+

Skills

{userStats.totalSkills}

@@ -48,13 +48,13 @@
-
+
-

Hochstes Level

+

Hochstes Level

{userStats.highestLevel}

@@ -63,13 +63,13 @@
-
+
-

Streak

+

Streak

{userStats.streakDays} Tage

@@ -80,16 +80,16 @@
-

Achievements

+

Achievements

- {achievementStats.unlocked}/{achievementStats.total}

diff --git a/apps/mana/apps/web/src/lib/modules/who/views/PlayView.svelte b/apps/mana/apps/web/src/lib/modules/who/views/PlayView.svelte index 906ebc2e6..dfceef804 100644 --- a/apps/mana/apps/web/src/lib/modules/who/views/PlayView.svelte +++ b/apps/mana/apps/web/src/lib/modules/who/views/PlayView.svelte @@ -116,17 +116,17 @@
-
+
-
+
{#if game?.status === 'won'} ✅ {game.revealedName} {:else if game?.status === 'surrendered'} @@ -135,7 +135,7 @@ Wer bin ich? {/if}
-
+
{#if game} {game.deckId} · {difficultyEmoji(game.difficulty)} · {game.messageCount} Fragen {/if} @@ -144,14 +144,14 @@ {#if game?.status === 'playing'}
{:else if game} -
+
-
@@ -266,9 +271,9 @@ onkeydown={(e) => e.key === 'Escape' && (showGuessModal = false)} role="presentation" > -
-

Wer ist es?

-

+

+

Wer ist es?

+

Wenn die KI deine Vermutung nicht erkannt hat, kannst du den Namen hier direkt eintragen.

@@ -277,13 +282,13 @@ bind:value={guessText} onkeydown={(e) => e.key === 'Enter' && submitGuess()} placeholder="z.B. Marie Curie" - class="mb-3 w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-sm text-white/90 placeholder-white/30 focus:border-purple-400/50 focus:outline-none" + class="mb-3 w-full rounded-lg border border-border/10 bg-muted/5 px-3 py-2 text-sm text-foreground placeholder-white/30 focus:border-purple-400/50 focus:outline-none" autofocus />
@@ -141,7 +141,7 @@ diff --git a/apps/mana/apps/web/src/routes/(app)/context/documents/[id]/+page.svelte b/apps/mana/apps/web/src/routes/(app)/context/documents/[id]/+page.svelte index bff0a04ea..5bd82137e 100644 --- a/apps/mana/apps/web/src/routes/(app)/context/documents/[id]/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/context/documents/[id]/+page.svelte @@ -135,7 +135,7 @@
{#each typeOptions as opt} @@ -156,7 +156,7 @@ class="rounded-md px-2.5 py-1 text-xs font-medium transition-colors {editType === opt.value ? 'bg-indigo-600 text-white' - : 'bg-gray-100 opacity-60 hover:opacity-100 dark:bg-gray-700'}" + : 'bg-muted opacity-60 hover:opacity-100 dark:bg-muted'}" onclick={() => { editType = opt.value; scheduleAutoSave(); @@ -166,7 +166,7 @@ {/each}
-
+
e.stopPropagation()} role="none" > @@ -223,7 +223,7 @@
diff --git a/apps/mana/apps/web/src/routes/(app)/context/spaces/+page.svelte b/apps/mana/apps/web/src/routes/(app)/context/spaces/+page.svelte index 4833ee809..577b2a57a 100644 --- a/apps/mana/apps/web/src/routes/(app)/context/spaces/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/context/spaces/+page.svelte @@ -53,7 +53,7 @@ } const inputClass = - 'w-full rounded-lg border border-gray-300 bg-white px-4 py-3 focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-200 dark:border-gray-600 dark:bg-gray-700'; + 'w-full rounded-lg border border-border-strong bg-white px-4 py-3 focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-200 dark:border-border dark:bg-muted'; @@ -78,7 +78,7 @@ {#if showCreateForm}

Neuen Space erstellen

@@ -119,7 +119,7 @@
@@ -142,7 +142,7 @@ type="text" bind:value={searchQuery} placeholder="Spaces durchsuchen..." - class="w-full rounded-lg border border-gray-300 bg-white py-2.5 pl-9 pr-4 focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-200 dark:border-gray-600 dark:bg-gray-700" + class="w-full rounded-lg border border-border-strong bg-white py-2.5 pl-9 pr-4 focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-200 dark:border-border dark:bg-muted" />
@@ -150,7 +150,7 @@
{#each filteredSpaces as space (space.id)}
{:else}

Noch keine Spaces

@@ -227,7 +227,7 @@ role="presentation" >
e.stopPropagation()} role="none" > @@ -239,7 +239,7 @@
diff --git a/apps/mana/apps/web/src/routes/(app)/context/spaces/[id]/+page.svelte b/apps/mana/apps/web/src/routes/(app)/context/spaces/[id]/+page.svelte index e47014dfb..8c012df89 100644 --- a/apps/mana/apps/web/src/routes/(app)/context/spaces/[id]/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/context/spaces/[id]/+page.svelte @@ -116,20 +116,20 @@ {:else}
{#if editingName}
{:else}

Keine Dokumente in diesem Space

{/if} diff --git a/apps/mana/apps/web/src/routes/(app)/memoro/[id]/+page.svelte b/apps/mana/apps/web/src/routes/(app)/memoro/[id]/+page.svelte index 7c98a31bf..669711b4b 100644 --- a/apps/mana/apps/web/src/routes/(app)/memoro/[id]/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/memoro/[id]/+page.svelte @@ -201,7 +201,7 @@ {tag.name} diff --git a/apps/mana/apps/web/src/routes/(app)/moodlit/moods/+page.svelte b/apps/mana/apps/web/src/routes/(app)/moodlit/moods/+page.svelte index b1fd84bd3..b2b310370 100644 --- a/apps/mana/apps/web/src/routes/(app)/moodlit/moods/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/moodlit/moods/+page.svelte @@ -165,7 +165,7 @@ : `linear-gradient(135deg, ${mood.colors.join(', ')})`}
diff --git a/apps/mana/apps/web/src/routes/(app)/organizations/+page.svelte b/apps/mana/apps/web/src/routes/(app)/organizations/+page.svelte index 33025a084..6641b038a 100644 --- a/apps/mana/apps/web/src/routes/(app)/organizations/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/organizations/+page.svelte @@ -20,8 +20,10 @@
🏢 -

No organizations yet

-

+

+ No organizations yet +

+

Create your first organization to get started

diff --git a/apps/mana/apps/web/src/routes/(app)/organizations/[id]/+page.svelte b/apps/mana/apps/web/src/routes/(app)/organizations/[id]/+page.svelte index 39264b592..f3b24c1ec 100644 --- a/apps/mana/apps/web/src/routes/(app)/organizations/[id]/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/organizations/[id]/+page.svelte @@ -58,7 +58,7 @@ {#snippet actions()}
Back @@ -94,21 +94,21 @@ {#if activeTab === 'overview'}
-

Details

+

Details

-
Name
-
{org.name}
+
Name
+
{org.name}
{#if org.slug}
-
Slug
-
{org.slug}
+
Slug
+
{org.slug}
{/if}
-
Created
-
+
Created
+
{new Date(org.createdAt).toLocaleDateString()}
@@ -116,7 +116,7 @@ -

Landing Page

+

Landing Page

{#if org.metadata?.landingPage?.enabled}

@@ -135,7 +135,9 @@ {/if}

{:else} -

Not configured yet

+

+ Not configured yet +

{/if}
{:else if activeTab === 'members'} -
+
Member management coming soon.
diff --git a/apps/mana/apps/web/src/routes/(app)/organizations/[id]/landing/+page.svelte b/apps/mana/apps/web/src/routes/(app)/organizations/[id]/landing/+page.svelte index fa13c455d..8635d5004 100644 --- a/apps/mana/apps/web/src/routes/(app)/organizations/[id]/landing/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/organizations/[id]/landing/+page.svelte @@ -43,7 +43,7 @@ {#snippet actions()}
Back to {org.name} diff --git a/apps/mana/apps/web/src/routes/(app)/picture/archive/+page.svelte b/apps/mana/apps/web/src/routes/(app)/picture/archive/+page.svelte index 3a382069e..258f04fd6 100644 --- a/apps/mana/apps/web/src/routes/(app)/picture/archive/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/picture/archive/+page.svelte @@ -66,7 +66,7 @@ > @@ -137,15 +145,17 @@ {#if showCreateModal}
-
+
-

Create New Deck

+

+ Create New Deck +

-
+
- Slide {index + 1} + Slide {index + 1}
Title
-
{#each slideBulletPoints as point, index}
- + updateBulletPoint(index, (e.target as HTMLInputElement).value)} - class="flex-1 px-4 py-2 border border-slate-300 dark:border-slate-600 rounded-lg bg-white dark:bg-slate-700 text-slate-900 dark:text-white focus:ring-2 focus:ring-primary-500" + class="flex-1 px-4 py-2 border border-border-strong dark:border-border rounded-lg bg-white dark:bg-muted text-foreground dark:text-white focus:ring-2 focus:ring-primary-500" placeholder="Add a point..." />
-
+
{#if currentSlide.content.imageUrl} {currentSlide.content.title} {/if} - {#if currentSlide.content.body}

+ {#if currentSlide.content.body}

{currentSlide.content.body}

{/if} {#if currentSlide.content.bulletPoints?.length} @@ -175,10 +175,10 @@ >
- -
+
{formatTime(elapsedSeconds)}
@@ -186,7 +186,7 @@
@@ -197,27 +197,27 @@ class="w-2 h-2 rounded-full transition-all" class:bg-primary-500={index === currentSlideIndex} class:w-4={index === currentSlideIndex} - class:bg-slate-500={index !== currentSlideIndex} + class:bg-muted={index !== currentSlideIndex} > {/each}
@@ -226,7 +226,7 @@
{:else}
-

No slides in this deck

+

No slides in this deck

{/if}
diff --git a/apps/mana/apps/web/src/routes/(app)/questions/+page.svelte b/apps/mana/apps/web/src/routes/(app)/questions/+page.svelte index 9669e0612..4f92c1b9b 100644 --- a/apps/mana/apps/web/src/routes/(app)/questions/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/questions/+page.svelte @@ -31,10 +31,10 @@ ); const statusIcons = { - open: { icon: Clock, color: 'text-gray-500' }, + open: { icon: Clock, color: 'text-muted-foreground' }, researching: { icon: CircleNotch, color: 'text-blue-500' }, answered: { icon: CheckCircle, color: 'text-green-500' }, - archived: { icon: Archive, color: 'text-gray-400' }, + archived: { icon: Archive, color: 'text-muted-foreground' }, }; const depthLabels: Record = { @@ -151,7 +151,7 @@
{#each filteredQuestions as question (question.id)} {@const StatusIcon = statusIcons[question.status]?.icon || Clock} - {@const statusColor = statusIcons[question.status]?.color || 'text-gray-500'} + {@const statusColor = statusIcons[question.status]?.color || 'text-muted-foreground'} {question.priority} diff --git a/apps/mana/apps/web/src/routes/(app)/questions/[id]/+page.svelte b/apps/mana/apps/web/src/routes/(app)/questions/[id]/+page.svelte index ba0b8181b..c79f6564d 100644 --- a/apps/mana/apps/web/src/routes/(app)/questions/[id]/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/questions/[id]/+page.svelte @@ -130,7 +130,7 @@ const statusLabels: Record = { open: { label: 'Offen', - color: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-300', + color: 'bg-muted text-muted-foreground dark:bg-card dark:text-foreground/90', }, researching: { label: 'Recherche', @@ -142,7 +142,7 @@ }, archived: { label: 'Archiviert', - color: 'bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400', + color: 'bg-muted text-muted-foreground dark:bg-card dark:text-muted-foreground', }, }; diff --git a/apps/mana/apps/web/src/routes/(app)/quotes/categories/+page.svelte b/apps/mana/apps/web/src/routes/(app)/quotes/categories/+page.svelte index 6a5ebfcd5..c220efe49 100644 --- a/apps/mana/apps/web/src/routes/(app)/quotes/categories/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/quotes/categories/+page.svelte @@ -109,7 +109,7 @@ >
{data.icon}

{$_(data.labelKey)}

-

+

{$_('categories.quotes', { values: { count: data.count } })}

diff --git a/apps/mana/apps/web/src/routes/(app)/skilltree/+page.svelte b/apps/mana/apps/web/src/routes/(app)/skilltree/+page.svelte index 489cf8934..cc2343639 100644 --- a/apps/mana/apps/web/src/routes/(app)/skilltree/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/skilltree/+page.svelte @@ -125,9 +125,8 @@ } async function handleExport() { - const { skillTable, activityTable, achievementTable } = await import( - '$lib/modules/skilltree/collections' - ); + const { skillTable, activityTable, achievementTable } = + await import('$lib/modules/skilltree/collections'); const [allSkillsData, allActivitiesData, allAchievementsData] = await Promise.all([ skillTable.toArray(), activityTable.toArray(), @@ -159,9 +158,8 @@ try { const text = await file.text(); const data = JSON.parse(text); - const { skillTable, activityTable, achievementTable } = await import( - '$lib/modules/skilltree/collections' - ); + const { skillTable, activityTable, achievementTable } = + await import('$lib/modules/skilltree/collections'); if (data.skills) await skillTable.bulkPut(data.skills); if (data.activities) await activityTable.bulkPut(data.activities); if (data.achievements) await achievementTable.bulkPut(data.achievements); @@ -181,7 +179,7 @@
-
+
@@ -192,13 +190,13 @@ {#if achievementStats.unlocked > 0} {achievementStats.unlocked} @@ -207,7 +205,7 @@ @@ -215,7 +213,7 @@ @@ -272,7 +270,7 @@ class="rounded-full px-4 py-2 text-sm font-medium transition-colors {selectedBranch === branch ? 'bg-emerald-600 text-white' - : 'bg-gray-800 text-gray-300 hover:bg-gray-700'}" + : 'bg-card text-foreground/90 hover:bg-muted'}" > {info.name} ({count}) @@ -284,13 +282,13 @@ {#if filteredSkills.length === 0}
-
- +
+
-

Noch keine Skills

-

Füge deinen ersten Skill hinzu und beginne dein Abenteuer!

+

Noch keine Skills

+

+ Füge deinen ersten Skill hinzu und beginne dein Abenteuer! +

@@ -111,8 +111,8 @@ onclick={() => (selectedCategory = category)} class="rounded-full px-4 py-2 text-sm font-medium transition-colors {selectedCategory === category - ? 'bg-yellow-500 text-gray-900' - : 'bg-gray-800 text-gray-300 hover:bg-gray-700'}" + ? 'bg-yellow-500 text-foreground' + : 'bg-card text-foreground/90 hover:bg-muted'}" > {info.name} ({count}) @@ -123,7 +123,7 @@ onclick={() => (showOnlyUnlocked = !showOnlyUnlocked)} class="rounded-full px-4 py-2 text-sm font-medium transition-colors {showOnlyUnlocked ? 'bg-yellow-500/20 text-yellow-400' - : 'bg-gray-800 text-gray-300 hover:bg-gray-700'}" + : 'bg-card text-foreground/90 hover:bg-muted'}" > {showOnlyUnlocked ? 'Nur freigeschaltete' : 'Alle zeigen'} @@ -133,13 +133,11 @@ {#if filteredAchievements().length === 0}
-
- +
+
-

Keine Achievements gefunden

-

+

Keine Achievements gefunden

+

{showOnlyUnlocked ? 'Du hast in dieser Kategorie noch keine Achievements freigeschaltet.' : 'Keine Achievements in dieser Kategorie.'} diff --git a/apps/mana/apps/web/src/routes/(app)/skilltree/tree/+page.svelte b/apps/mana/apps/web/src/routes/(app)/skilltree/tree/+page.svelte index fa2c06182..b8ebdcbb5 100644 --- a/apps/mana/apps/web/src/routes/(app)/skilltree/tree/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/skilltree/tree/+page.svelte @@ -59,14 +59,14 @@ Skill Tree View - SkillTree -

+
-
+
diff --git a/apps/mana/apps/web/src/routes/(app)/teams/+page.svelte b/apps/mana/apps/web/src/routes/(app)/teams/+page.svelte index fb09d9113..22d6514d0 100644 --- a/apps/mana/apps/web/src/routes/(app)/teams/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/teams/+page.svelte @@ -16,8 +16,8 @@
👥 -

No teams yet

-

+

No teams yet

+

Create or join a team to start collaborating

diff --git a/apps/mana/apps/web/src/routes/(app)/times/templates/+page.svelte b/apps/mana/apps/web/src/routes/(app)/times/templates/+page.svelte index 3da552b70..4e702b62e 100644 --- a/apps/mana/apps/web/src/routes/(app)/times/templates/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/times/templates/+page.svelte @@ -157,7 +157,7 @@ style="background-color: {project.color}" >
{:else} -
+
{/if}

{template.name}

diff --git a/apps/mana/apps/web/src/routes/(app)/uload/+page.svelte b/apps/mana/apps/web/src/routes/(app)/uload/+page.svelte index 8a654169b..3db876f6a 100644 --- a/apps/mana/apps/web/src/routes/(app)/uload/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/uload/+page.svelte @@ -248,9 +248,9 @@ } const inputClass = - 'w-full rounded-lg border border-gray-300 bg-white px-4 py-3 focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-200 dark:border-gray-600 dark:bg-gray-700'; + 'w-full rounded-lg border border-border-strong bg-white px-4 py-3 focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-200 dark:border-border dark:bg-muted'; const inputSmClass = - 'w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm focus:border-indigo-500 focus:outline-none dark:border-gray-600 dark:bg-gray-700'; + 'w-full rounded-lg border border-border-strong bg-white px-3 py-2 text-sm focus:border-indigo-500 focus:outline-none dark:border-border dark:bg-muted'; @@ -273,7 +273,7 @@
Alle Links @@ -289,7 +289,7 @@ {#if showCreateForm}
@@ -447,7 +447,7 @@ type="text" bind:value={searchQuery} placeholder="Links durchsuchen..." - class="w-60 rounded-lg border border-gray-300 bg-white py-2 pl-8 pr-3 text-sm focus:border-indigo-500 focus:outline-none dark:border-gray-600 dark:bg-gray-700" + class="w-60 rounded-lg border border-border-strong bg-white py-2 pl-8 pr-3 text-sm focus:border-indigo-500 focus:outline-none dark:border-border dark:bg-muted" />
-
+

Erweitert

@@ -701,7 +704,7 @@
@@ -727,7 +730,7 @@ role="presentation" >
e.stopPropagation()} role="none" > @@ -735,7 +738,7 @@

QR-Code

@@ -753,7 +756,7 @@
diff --git a/apps/mana/apps/web/src/routes/(app)/uload/analytics/[id]/+page.svelte b/apps/mana/apps/web/src/routes/(app)/uload/analytics/[id]/+page.svelte index 9ff76af9e..0c80d1309 100644 --- a/apps/mana/apps/web/src/routes/(app)/uload/analytics/[id]/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/uload/analytics/[id]/+page.svelte @@ -75,13 +75,13 @@
- - + +

Analytics

{#if link} -

+

/{link.shortCode}{link.originalUrl}

@@ -92,40 +92,40 @@ {#if loading}
{#each Array(4) as _} -
+
{/each}
{:else if !link} -
-

Link nicht gefunden

+
+

Link nicht gefunden

{:else}
-
-

Clicks

+
+

Clicks

{stats?.totalClicks ?? link.clickCount}

-
-

Unique

+
+

Unique

{stats?.uniqueVisitors ?? '-'}

-
-

Status

+
+

Status

{#if link.isActive} Aktiv {:else} - Inaktiv + Inaktiv {/if}

-
-

Erstellt

+
+

Erstellt

{new Date(link.createdAt).toLocaleDateString('de')}

@@ -133,11 +133,11 @@
-
+

Link Details

- Ziel-URL + Ziel-URL {#if link.title}
- Titel + Titel {link.title}
{/if} {#if link.utmSource || link.utmMedium || link.utmCampaign} -
-

+

+

UTM-Parameter

{#if link.utmSource} -
- Source: +
+ Source: {link.utmSource}
{/if} {#if link.utmMedium} -
- Medium: +
+ Medium: {link.utmMedium}
{/if} {#if link.utmCampaign} -
- Campaign: +
+ Campaign: {link.utmCampaign}
{/if} @@ -182,19 +182,19 @@ {/if} {#if link.expiresAt}
- Laeuft ab + Laeuft ab {new Date(link.expiresAt).toLocaleDateString('de')}
{/if} {#if link.maxClicks}
- Max Klicks + Max Klicks {link.clickCount} / {link.maxClicks}
{/if} {#if link.password}
- Passwortgeschuetzt + Passwortgeschuetzt Ja
{/if} @@ -202,7 +202,7 @@
-
+

Clicks ueber Zeit

@@ -211,7 +211,7 @@ onclick={() => changeDays(d)} class="rounded-md px-3 py-1 text-xs font-medium transition-colors {days === d ? 'bg-indigo-600 text-white' - : 'bg-white/10 text-white/60 hover:bg-white/15'}" + : 'bg-muted/10 text-muted-foreground hover:bg-muted/15'}" > {d}T @@ -227,28 +227,30 @@ style="height: {Math.max((day.count / maxTimelineCount) * 100, 2)}%" >
{/each}
-
+
{timeline[0]?.date} {timeline[timeline.length - 1]?.date}
{:else if !serverAvailable}
-

+

Detaillierte Analytics sind verfuegbar, wenn der uLoad-Server verbunden ist.

-

+

Lokaler Click-Count: {link.clickCount}

{:else} -

Noch keine Daten fuer diesen Zeitraum

+

+ Noch keine Daten fuer diesen Zeitraum +

{/if}
@@ -256,19 +258,19 @@ {#if serverAvailable}
-
+

Geraete

{#if devices.length > 0}
{#each devices as d}
- {d.deviceType || 'Unbekannt'} + {d.deviceType || 'Unbekannt'} {Math.round((d.count / totalDevices) * 100)}%
-
+
{:else} -

Keine Daten

+

Keine Daten

{/if}
-
+

Referrer

{#if referrers.length > 0}
{#each referrers.slice(0, 8) as r}
- + {r.referer || 'Direkt'} {r.count} @@ -297,24 +299,24 @@ {/each}
{:else} -

Keine Daten

+

Keine Daten

{/if}
-
+

Laender

{#if countries.length > 0}
{#each countries.slice(0, 8) as c}
- {c.country || 'Unbekannt'} + {c.country || 'Unbekannt'} {Math.round((c.count / totalCountries) * 100)}%
-
+
{:else} -

Keine Daten

+

Keine Daten

{/if}
diff --git a/apps/mana/apps/web/src/routes/(app)/uload/links/+page.svelte b/apps/mana/apps/web/src/routes/(app)/uload/links/+page.svelte index 0166d655f..5dcba90b4 100644 --- a/apps/mana/apps/web/src/routes/(app)/uload/links/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/uload/links/+page.svelte @@ -122,7 +122,7 @@ } const inputSmClass = - 'w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm focus:border-indigo-500 focus:outline-none dark:border-gray-600 dark:bg-gray-700'; + 'w-full rounded-lg border border-border-strong bg-white px-3 py-2 text-sm focus:border-indigo-500 focus:outline-none dark:border-border dark:bg-muted'; @@ -134,11 +134,7 @@
- +
@@ -159,9 +155,9 @@ selectedIds = selectedIds; } }} - class="rounded-lg border border-gray-300 px-3 py-2 text-sm font-medium transition-colors {selectMode + class="rounded-lg border border-border-strong px-3 py-2 text-sm font-medium transition-colors {selectMode ? 'bg-indigo-600 text-white' - : 'hover:bg-gray-50 dark:border-gray-600 dark:hover:bg-gray-700'}" + : 'hover:bg-muted dark:border-border dark:hover:bg-muted'}" > {selectMode ? 'Fertig' : 'Auswaehlen'} @@ -176,7 +172,7 @@ type="text" bind:value={searchQuery} placeholder="Links durchsuchen..." - class="w-60 rounded-lg border border-gray-300 bg-white py-2 pl-8 pr-3 text-sm focus:border-indigo-500 focus:outline-none dark:border-gray-600 dark:bg-gray-700" + class="w-60 rounded-lg border border-border-strong bg-white py-2 pl-8 pr-3 text-sm focus:border-indigo-500 focus:outline-none dark:border-border dark:bg-muted" />
e.key === 'Enter' && createTag()} />
- +
@@ -143,16 +149,16 @@ {tag.name}
- {getUsageCount(tag.id)} Links + {getUsageCount(tag.id)} Links diff --git a/scripts/migrate-theme-tokens.mjs b/scripts/migrate-theme-tokens.mjs new file mode 100644 index 000000000..46019ddd3 --- /dev/null +++ b/scripts/migrate-theme-tokens.mjs @@ -0,0 +1,184 @@ +#!/usr/bin/env node +/** + * One-shot migration: replace raw Tailwind neutral-palette + white-alpha + * utilities with theme tokens across the unified Mana web app. + * + * This is a surgical codemod, not a general-purpose tool. The mappings + * encode a specific design decision: `bg-gray-800` = `bg-card`, etc. + * Re-running is a no-op once the codebase is clean. + * + * Usage: + * node scripts/migrate-theme-tokens.mjs [--dry-run] + * + * The mappings are ordered by specificity — longer patterns first so + * `bg-gray-700/50` is tried before `bg-gray-700`. + */ + +import { execSync } from 'node:child_process'; +import { readFileSync, writeFileSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { dirname, join } from 'node:path'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const REPO_ROOT = join(__dirname, '..'); +const DRY_RUN = process.argv.includes('--dry-run'); + +const SCAN_GLOBS = [ + 'apps/mana/apps/web/src/lib/modules/**/*.svelte', + 'apps/mana/apps/web/src/routes/(app)/**/*.svelte', +]; + +/** + * Files where `bg-white/N`, `text-white/N`, etc. are brand-literal overlays + * on vivid gradient backgrounds, not theme-intent. These stay untouched + * and are allowlisted in the validator via scoped