feat(frontend): IMPHNEN design deep integration — full 5-layer redesign
Layer 0 — Foundation: - Dark mode palette (30+ CSS var pairs in [data-theme='dark']) - CSS-first theme engine in styles.css (@theme + CSS vars) - UseTheme hook with light/dark/system support + localStorage persistence - Fixed animation keyframes (shimmer 1.5s canonical, glowPulse moved to CSS) - Smooth theme switch transitions via .theme-transitioning class Layer 1 — Shared UI Components: - Badge: success/warning variants now use CSS vars (bg-success-soft text-success) - Toast: rewritten with CSS vars, z-index fixed (40), repositioned top-right - Skeleton: added variant prop (rounded/circular/rectangular) - EmptyState: new component with icon + title + description + action - Button: added tertiary variant + icon-sm size - Card: added elevated/bordered variants - Input: added soft variant Layer 2 — Layout & Navigation: - TabStrip: new horizontal tab navigation with spring underline indicator (z-30) - Sidebar: expanded by default (w-64), brand assets always visible - Header: simplified brand bar, removed redundant page titles, added ThemeToggle - MobileTabBar: enhanced with spring dot indicator + glass bg + safe area - DashboardLayout: integrated TabStrip between Header and content - ParticleBackground: lazy render, skips on mobile/reduced-motion Layer 3 — Feature Components: - MessageCard: 30+ hardcoded hex replacements → semantic CSS vars - MessagesPanel: stat badges use Badge component variants - DashboardStats: StatCard with variant system (primary/success/warning/destructive) - UserSummaryList/UserProfileDetail/ChannelProfileDetail: all hardcoded colors → CSS vars - AudioVisualizer: reads --primary CSS var at paint time - ActiveSpeakers/RecordingsSubPanel: hardcoded colors → CSS vars Layer 4 — Polish: - EmptyState integrated across messages/dashboard/live panels - Theme toggle wired in Header + App root - Hover state audit for consistency - Entry animations verified (cardStagger/cardItem pattern in all panels) Resolves DESIGN_TOKENS.md §13.x issues: hardcoded colors, shimmer mismatch, glow-pulse fragmentation, z-index collisions, toast positioning.
This commit is contained in:
@@ -80,13 +80,13 @@ function parseStringList(value?: string | null): string[] {
|
||||
function severityColor(severity: string) {
|
||||
switch (severity) {
|
||||
case "critical":
|
||||
return "bg-red-100 text-red-700 border-red-200";
|
||||
return "bg-destructive-soft text-destructive border-destructive/20";
|
||||
case "high":
|
||||
return "bg-orange-100 text-orange-700 border-orange-200";
|
||||
return "bg-warning-soft text-warning border-warning/20";
|
||||
case "medium":
|
||||
return "bg-yellow-100 text-yellow-700 border-yellow-200";
|
||||
return "bg-warning-soft text-warning border-warning/20";
|
||||
case "low":
|
||||
return "bg-blue-100 text-blue-700 border-blue-200";
|
||||
return "bg-info-soft text-info border-info/20";
|
||||
default:
|
||||
return "bg-muted text-muted-foreground border-border";
|
||||
}
|
||||
@@ -238,18 +238,18 @@ function MessageRow({
|
||||
|
||||
if (message.is_forward) {
|
||||
return (
|
||||
<div className="flex items-center gap-1.5 mb-2 text-[12px] text-muted-foreground/70 border-l-2 border-amber-400/40 pl-2.5 py-1">
|
||||
<Forward className="h-3 w-3 shrink-0 text-amber-500" />
|
||||
<span className="font-medium text-amber-600/70">Forwarded</span>
|
||||
<div className="flex items-center gap-1.5 mb-2 text-[12px] text-muted-foreground/70 border-l-2 border-warning/40 pl-2.5 py-1">
|
||||
<Forward className="h-3 w-3 shrink-0 text-warning" />
|
||||
<span className="font-medium text-warning/70">Forwarded</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (message.is_crosspost) {
|
||||
return (
|
||||
<div className="flex items-center gap-1.5 mb-2 text-[12px] text-muted-foreground/70 border-l-2 border-sky-400/40 pl-2.5 py-1">
|
||||
<MessageCircle className="h-3 w-3 shrink-0 text-sky-500" />
|
||||
<span className="font-medium text-sky-600/70">Crossposted</span>
|
||||
<div className="flex items-center gap-1.5 mb-2 text-[12px] text-muted-foreground/70 border-l-2 border-info/40 pl-2.5 py-1">
|
||||
<MessageCircle className="h-3 w-3 shrink-0 text-info" />
|
||||
<span className="font-medium text-info/70">Crossposted</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -409,8 +409,8 @@ function MessageRow({
|
||||
<div
|
||||
className={`rounded-lg border-l-[3px] px-3 py-2 ${
|
||||
aiStatus === "flagged"
|
||||
? "border-l-pink-400 bg-pink-50/40"
|
||||
: "border-l-emerald-400 bg-emerald-50/40"
|
||||
? "border-l-tertiary bg-tertiary/5"
|
||||
: "border-l-success bg-success-soft"
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-start gap-2 text-[11px]">
|
||||
@@ -431,7 +431,7 @@ function MessageRow({
|
||||
|
||||
{/* AI Error */}
|
||||
{message.ai_error ? (
|
||||
<div className="rounded-lg bg-pink-50/40 px-3 py-2 text-[12px] text-pink-600">
|
||||
<div className="rounded-lg bg-tertiary/5 px-3 py-2 text-[12px] text-tertiary">
|
||||
AI error: {message.ai_error}
|
||||
</div>
|
||||
) : null}
|
||||
@@ -451,7 +451,7 @@ function MessageRow({
|
||||
{isReanalyzing ? "Reanalyzing..." : "Re-analyze"}
|
||||
</Button>
|
||||
{aiStatus === "error" && (
|
||||
<span className="text-[11px] text-pink-600/70">
|
||||
<span className="text-[11px] text-tertiary/70">
|
||||
Click to retry analysis
|
||||
</span>
|
||||
)}
|
||||
@@ -483,7 +483,7 @@ export function MessageCard({ messages, onReanalyze }: MessageCardProps) {
|
||||
return (
|
||||
<article
|
||||
className={`group rounded-xl border bg-card shadow-sm transition-all hover:border-primary/30 hover:shadow-md ${
|
||||
firstMsg.deleted_at ? "border-red-200 opacity-60" : "border-border"
|
||||
firstMsg.deleted_at ? "border-destructive/20 opacity-60" : "border-border"
|
||||
}`}
|
||||
>
|
||||
<div className="flex gap-3 p-4">
|
||||
|
||||
Reference in New Issue
Block a user