+
{incomingCall.callerName.charAt(0).toUpperCase()}
{/* Ringing phone icon */}
diff --git a/packages/web/src/utils/gradients.ts b/packages/web/src/utils/gradients.ts
new file mode 100644
index 00000000..357791e4
--- /dev/null
+++ b/packages/web/src/utils/gradients.ts
@@ -0,0 +1,58 @@
+/**
+ * Aether Drift gradient palettes for avatars and server icons.
+ * Deterministic color assignment based on entity ID (snowflake) or name.
+ */
+
+export interface GradientEntry {
+ gradient: string;
+ glow: string;
+}
+
+// ── Avatar gradients (user fallbacks) ──
+const AVATAR_GRADIENTS: GradientEntry[] = [
+ { gradient: 'linear-gradient(135deg, #059669, #10b981)', glow: '#10b981' }, // mint
+ { gradient: 'linear-gradient(135deg, #3b82f6, #6366f1)', glow: '#6366f1' }, // sky
+ { gradient: 'linear-gradient(135deg, #a78bfa, #c084fc)', glow: '#c084fc' }, // lavender
+ { gradient: 'linear-gradient(135deg, #f97316, #ef4444)', glow: '#f97316' }, // coral
+ { gradient: 'linear-gradient(135deg, #f43f5e, #ec4899)', glow: '#ec4899' }, // rose
+ { gradient: 'linear-gradient(135deg, #14b8a6, #06b6d4)', glow: '#06b6d4' }, // teal
+ { gradient: 'linear-gradient(135deg, #f59e0b, #eab308)', glow: '#f59e0b' }, // amber
+];
+
+// ── Server icon gradients (server fallbacks) ──
+const SERVER_GRADIENTS: GradientEntry[] = [
+ { gradient: 'linear-gradient(135deg, #ef4444, #f97316)', glow: '#f97316' }, // red-orange
+ { gradient: 'linear-gradient(135deg, #ec4899, #f472b6)', glow: '#ec4899' }, // pink
+ { gradient: 'linear-gradient(135deg, #14b8a6, #06b6d4)', glow: '#06b6d4' }, // teal-cyan
+ { gradient: 'linear-gradient(135deg, #f59e0b, #eab308)', glow: '#f59e0b' }, // amber-yellow
+ { gradient: 'linear-gradient(135deg, #3b82f6, #6366f1)', glow: '#6366f1' }, // blue-indigo
+ { gradient: 'linear-gradient(135deg, #a78bfa, #c084fc)', glow: '#c084fc' }, // lavender
+ { gradient: 'linear-gradient(135deg, #059669, #10b981)', glow: '#10b981' }, // mint
+];
+
+// ── Home button (DM / Backspace) — fixed indigo-purple gradient ──
+export const HOME_GRADIENT: GradientEntry = {
+ gradient: 'linear-gradient(135deg, #6366f1, #8b5cf6)',
+ glow: '#8b5cf6',
+};
+
+/** djb2 hash → stable unsigned 32-bit integer. */
+function hashString(str: string): number {
+ let hash = 5381;
+ for (let i = 0; i < str.length; i++) {
+ hash = ((hash << 5) + hash + str.charCodeAt(i)) >>> 0;
+ }
+ return hash;
+}
+
+/** Deterministic gradient for a user avatar. Prefers ID for stability; falls back to name. */
+export function getAvatarGradient(id?: string | null, name?: string): GradientEntry {
+ const key = id || name || 'unknown';
+ return AVATAR_GRADIENTS[hashString(key) % AVATAR_GRADIENTS.length]!;
+}
+
+/** Deterministic gradient for a server icon. Prefers ID for stability; falls back to name. */
+export function getServerGradient(id?: string | null, name?: string): GradientEntry {
+ const key = id || name || 'unknown';
+ return SERVER_GRADIENTS[hashString(key) % SERVER_GRADIENTS.length]!;
+}
diff --git a/packages/web/tailwind.config.js b/packages/web/tailwind.config.js
index d7cf73fa..a3410b0b 100644
--- a/packages/web/tailwind.config.js
+++ b/packages/web/tailwind.config.js
@@ -7,61 +7,6 @@ export default {
theme: {
extend: {
colors: {
- // ── LEGACY (preserved until Phase 5 removal) ──
- discord: {
- // Backgrounds (darkest → lightest) — Discord "Dark" theme
- 'bg-floating': '#080a0b',
- 'bg-tertiary': '#111214',
- 'bg-server': '#111214',
- 'bg-user-area': '#1a1b1e',
- 'bg-secondary': '#1e1f22',
- 'bg-members': '#1e1f22',
- 'bg-home': '#1a1d20',
- 'bg-hover': '#232428',
- 'bg-primary': '#232428',
- 'bg-input': '#2b2d31',
- 'bg-surface': '#2b2d31',
- 'bg-surface-higher': '#313338',
- 'bg-active': '#313338',
- 'bg-accent': '#353840',
- 'bg-overlay': 'rgba(0, 0, 0, 0.90)',
-
- // Text
- 'text-primary': '#ffffff',
- 'text-normal': '#dcdcdf',
- 'text-secondary': '#c5c6ca',
- 'text-muted': '#abacb2',
- 'text-header': '#ffffff',
- 'text-link': '#76aff6',
- 'text-positive': '#73c48b',
- 'text-warning': '#faa900',
- 'text-danger': '#ff938e',
-
- // Channel/Interactive
- 'channels-default': '#999aa1',
- 'interactive-muted': '#4e5058',
-
- // Brand
- 'blurple': '#5865f2',
- 'blurple-hover': '#4452bb',
- 'blurple-active': '#3a48a3',
-
- // Status
- 'green': '#23a55a',
- 'yellow': '#f0b232',
- 'red': '#f23f43',
- 'red-hover': '#a9232e',
-
- // Notification badge
- 'notification': '#da3e44',
-
- // Modifiers (semi-transparent — works on any background)
- 'modifier-hover': 'rgba(255,255,255,0.08)',
- 'modifier-active': 'rgba(255,255,255,0.16)',
- 'modifier-selected': 'rgba(255,255,255,0.20)',
- 'modifier-accent': 'rgba(255,255,255,0.12)',
- },
-
// ── AETHER DRIFT TOKENS ──
surface: {
base: 'var(--bg-base)',