diff --git a/dashboard/src/lib/components/HeaderNav.svelte b/dashboard/src/lib/components/HeaderNav.svelte index 1db82454..38b75c13 100644 --- a/dashboard/src/lib/components/HeaderNav.svelte +++ b/dashboard/src/lib/components/HeaderNav.svelte @@ -98,10 +98,14 @@ diff --git a/dashboard/src/lib/components/MarkdownContent.svelte b/dashboard/src/lib/components/MarkdownContent.svelte index 2e2538e5..33f887ca 100644 --- a/dashboard/src/lib/components/MarkdownContent.svelte +++ b/dashboard/src/lib/components/MarkdownContent.svelte @@ -1193,7 +1193,9 @@ background: rgba(0, 0, 0, 0.02); } - :global(html:not(.dark)) .markdown-content :global(.math-display-wrapper:hover) { + :global(html:not(.dark)) + .markdown-content + :global(.math-display-wrapper:hover) { border-color: rgba(0, 0, 0, 0.18); box-shadow: 0 0 12px rgba(0, 0, 0, 0.05); } @@ -1208,15 +1210,21 @@ } /* --- Math scrollbar (light mode) --- */ - :global(html:not(.dark)) .markdown-content :global(.math-display-content::-webkit-scrollbar-track) { + :global(html:not(.dark)) + .markdown-content + :global(.math-display-content::-webkit-scrollbar-track) { background: rgba(0, 0, 0, 0.04); } - :global(html:not(.dark)) .markdown-content :global(.math-display-content::-webkit-scrollbar-thumb) { + :global(html:not(.dark)) + .markdown-content + :global(.math-display-content::-webkit-scrollbar-thumb) { background: rgba(0, 0, 0, 0.15); } - :global(html:not(.dark)) .markdown-content :global(.math-display-content::-webkit-scrollbar-thumb:hover) { + :global(html:not(.dark)) + .markdown-content + :global(.math-display-content::-webkit-scrollbar-thumb:hover) { background: rgba(0, 0, 0, 0.25); } @@ -1239,7 +1247,9 @@ color: oklch(0.2 0 0); } - :global(html:not(.dark)) .markdown-content :global(.latex-proof-content::after) { + :global(html:not(.dark)) + .markdown-content + :global(.latex-proof-content::after) { color: oklch(0.4 0 0); } @@ -1254,7 +1264,9 @@ } /* --- LaTeX diagram/figure placeholder --- */ - :global(html:not(.dark)) .markdown-content :global(.latex-diagram-placeholder) { + :global(html:not(.dark)) + .markdown-content + :global(.latex-diagram-placeholder) { background: rgba(0, 0, 0, 0.02); border: 1px dashed rgba(0, 0, 0, 0.2); color: rgba(0, 0, 0, 0.45); diff --git a/dashboard/src/lib/components/ModelCard.svelte b/dashboard/src/lib/components/ModelCard.svelte index 9d8a538f..fd1b7a5f 100644 --- a/dashboard/src/lib/components/ModelCard.svelte +++ b/dashboard/src/lib/components/ModelCard.svelte @@ -6,36 +6,41 @@ TopologyEdge, } from "$lib/stores/app.svelte"; import { debugMode, topologyData } from "$lib/stores/app.svelte"; - import { browser } from '$app/environment'; + import { browser } from "$app/environment"; // Theme detection let isDark = $state(true); $effect(() => { if (!browser) return; - const update = () => { isDark = document.documentElement.classList.contains('dark'); }; + const update = () => { + isDark = document.documentElement.classList.contains("dark"); + }; update(); const observer = new MutationObserver(update); - observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] }); + observer.observe(document.documentElement, { + attributes: true, + attributeFilter: ["class"], + }); return () => observer.disconnect(); }); // Theme-aware colors let tc = $derived({ - accent: isDark ? '#FFD700' : '#1a1a1a', - accentDim: isDark ? 'rgba(255,215,0,0.1)' : 'rgba(26,26,26,0.06)', - accentGlow: isDark ? 'rgba(255,215,0,0.1)' : 'rgba(0,0,0,0.03)', - outlineActive: isDark ? '#FFD700' : '#374151', - outlineInactive: isDark ? '#4B5563' : '#d1d5db', - strokeActive: isDark ? '#FFD700' : '#374151', - strokeInactive: isDark ? '#4B5563' : '#d1d5db', - caseFill: isDark ? '#0a0a0a' : '#f3f4f6', - caseDetail: isDark ? '#374151' : '#d1d5db', - errorDot: isDark ? '#f87171' : '#dc2626', - statusInactive: isDark ? '#4B5563' : '#9ca3af', - connGood: isDark ? 'rgba(255,255,255,0.85)' : 'rgba(30,30,30,0.85)', - connBad: isDark ? 'rgba(248,113,113,0.85)' : 'rgba(220,38,38,0.85)', - scanlineColor: isDark ? 'rgba(255,215,0,0.02)' : 'rgba(0,0,0,0.01)', + accent: isDark ? "#FFD700" : "#1a1a1a", + accentDim: isDark ? "rgba(255,215,0,0.1)" : "rgba(26,26,26,0.06)", + accentGlow: isDark ? "rgba(255,215,0,0.1)" : "rgba(0,0,0,0.03)", + outlineActive: isDark ? "#FFD700" : "#374151", + outlineInactive: isDark ? "#4B5563" : "#d1d5db", + strokeActive: isDark ? "#FFD700" : "#374151", + strokeInactive: isDark ? "#4B5563" : "#d1d5db", + caseFill: isDark ? "#0a0a0a" : "#f3f4f6", + caseDetail: isDark ? "#374151" : "#d1d5db", + errorDot: isDark ? "#f87171" : "#dc2626", + statusInactive: isDark ? "#4B5563" : "#9ca3af", + connGood: isDark ? "rgba(255,255,255,0.85)" : "rgba(30,30,30,0.85)", + connBad: isDark ? "rgba(248,113,113,0.85)" : "rgba(220,38,38,0.85)", + scanlineColor: isDark ? "rgba(255,215,0,0.02)" : "rgba(0,0,0,0.01)", }); interface Props { @@ -702,7 +707,9 @@ y1={node.y} x2={node2.x} y2={node2.y} - stroke={node.isUsed && node2.isUsed ? tc.strokeActive : tc.strokeInactive} + stroke={node.isUsed && node2.isUsed + ? tc.strokeActive + : tc.strokeInactive} stroke-width="1" stroke-dasharray={node.isUsed && node2.isUsed ? "4,2" : "2,4"} opacity={node.isUsed && node2.isUsed ? 0.4 : 0.15} @@ -738,9 +745,7 @@ dominant-baseline="hanging" font-size="6" font-family="SF Mono, Monaco, monospace" - fill={conn.iface - ? tc.connGood - : tc.connBad} + fill={conn.iface ? tc.connGood : tc.connBad} > {conn.arrow} {isRdma @@ -757,9 +762,7 @@ dominant-baseline="hanging" font-size="6" font-family="SF Mono, Monaco, monospace" - fill={conn.iface - ? tc.connGood - : tc.connBad} + fill={conn.iface ? tc.connGood : tc.connBad} > {conn.arrow} {isRdma @@ -778,9 +781,7 @@ dominant-baseline="auto" font-size="6" font-family="SF Mono, Monaco, monospace" - fill={conn.iface - ? tc.connGood - : tc.connBad} + fill={conn.iface ? tc.connGood : tc.connBad} > {conn.arrow} {isRdma @@ -799,9 +800,7 @@ dominant-baseline="auto" font-size="6" font-family="SF Mono, Monaco, monospace" - fill={conn.iface - ? tc.connGood - : tc.connBad} + fill={conn.iface ? tc.connGood : tc.connBad} > {conn.arrow} {isRdma diff --git a/dashboard/src/lib/components/TopologyGraph.svelte b/dashboard/src/lib/components/TopologyGraph.svelte index 48140be5..a4e21eec 100644 --- a/dashboard/src/lib/components/TopologyGraph.svelte +++ b/dashboard/src/lib/components/TopologyGraph.svelte @@ -38,60 +38,79 @@ // Theme-aware colors - read from CSS custom properties function getThemeColors() { - if (typeof document === 'undefined') return getDefaultColors(); + if (typeof document === "undefined") return getDefaultColors(); const style = getComputedStyle(document.documentElement); - const isDark = document.documentElement.classList.contains('dark'); + const isDark = document.documentElement.classList.contains("dark"); return { - accent: style.getPropertyValue('--exo-yellow').trim() || (isDark ? 'oklch(0.85 0.18 85)' : 'oklch(0.20 0.02 85)'), - accentRgb: isDark ? '255,215,0' : '30,28,20', - deviceCase: isDark ? '#1a1a1a' : '#e8e8e8', - deviceCaseDark: isDark ? '#2c2c2c' : '#d4d4d4', - deviceScreen: isDark ? '#0a0a12' : '#f0f0f5', - deviceScreenFill: isDark ? 'rgba(0,20,40,0.9)' : 'rgba(240,242,248,0.95)', - labelWhite: isDark ? '#FFFFFF' : '#1a1a1a', - labelMuted: isDark ? 'rgba(179,179,179,0.9)' : 'rgba(80,80,80,0.9)', - labelDim: isDark ? 'rgba(179,179,179,0.7)' : 'rgba(100,100,100,0.7)', - wireDefault: isDark ? 'rgba(179,179,179,0.8)' : 'rgba(120,120,120,0.6)', - wireBright: isDark ? 'rgba(255,255,255,0.9)' : 'rgba(30,30,30,0.9)', - wireFiltered: isDark ? 'rgba(140,140,140,0.6)' : 'rgba(160,160,160,0.5)', - gridStroke: isDark ? 'var(--exo-light-gray, #B3B3B3)' : 'var(--exo-light-gray, #888888)', - errorText: isDark ? 'rgba(248,113,113,0.9)' : 'rgba(220,38,38,0.9)', - normalText: isDark ? 'rgba(255,255,255,0.85)' : 'rgba(30,30,30,0.85)', - gpuChip: isDark ? 'rgba(80, 80, 90, 0.7)' : 'rgba(180, 180, 190, 0.7)', - detailOverlay: isDark ? 'rgba(0,0,0,0.35)' : 'rgba(0,0,0,0.08)', - deviceShadow: isDark ? 'rgba(0,0,0,0.2)' : 'rgba(0,0,0,0.06)', - deviceHighlight: isDark ? 'rgba(255,255,255,0.08)' : 'rgba(255,255,255,0.5)', - tbActive: isDark ? 'rgba(234,179,8,0.9)' : 'rgba(30,28,20,0.9)', - tbInactive: isDark ? 'rgba(100,100,100,0.7)' : 'rgba(160,160,160,0.7)', - deviceDetail: isDark ? '#374151' : '#c0c0c0', + accent: + style.getPropertyValue("--exo-yellow").trim() || + (isDark ? "oklch(0.85 0.18 85)" : "oklch(0.20 0.02 85)"), + accentRgb: isDark ? "255,215,0" : "30,28,20", + deviceCase: isDark ? "#1a1a1a" : "#e8e8e8", + deviceCaseDark: isDark ? "#2c2c2c" : "#d4d4d4", + deviceScreen: isDark ? "#0a0a12" : "#f0f0f5", + deviceScreenFill: isDark ? "rgba(0,20,40,0.9)" : "rgba(240,242,248,0.95)", + labelWhite: isDark ? "#FFFFFF" : "#1a1a1a", + labelMuted: isDark ? "rgba(179,179,179,0.9)" : "rgba(80,80,80,0.9)", + labelDim: isDark ? "rgba(179,179,179,0.7)" : "rgba(100,100,100,0.7)", + wireDefault: isDark ? "rgba(179,179,179,0.8)" : "rgba(120,120,120,0.6)", + wireBright: isDark ? "rgba(255,255,255,0.9)" : "rgba(30,30,30,0.9)", + wireFiltered: isDark ? "rgba(140,140,140,0.6)" : "rgba(160,160,160,0.5)", + gridStroke: isDark + ? "var(--exo-light-gray, #B3B3B3)" + : "var(--exo-light-gray, #888888)", + errorText: isDark ? "rgba(248,113,113,0.9)" : "rgba(220,38,38,0.9)", + normalText: isDark ? "rgba(255,255,255,0.85)" : "rgba(30,30,30,0.85)", + gpuChip: isDark ? "rgba(80, 80, 90, 0.7)" : "rgba(180, 180, 190, 0.7)", + detailOverlay: isDark ? "rgba(0,0,0,0.35)" : "rgba(0,0,0,0.08)", + deviceShadow: isDark ? "rgba(0,0,0,0.2)" : "rgba(0,0,0,0.06)", + deviceHighlight: isDark + ? "rgba(255,255,255,0.08)" + : "rgba(255,255,255,0.5)", + tbActive: isDark ? "rgba(234,179,8,0.9)" : "rgba(30,28,20,0.9)", + tbInactive: isDark ? "rgba(100,100,100,0.7)" : "rgba(160,160,160,0.7)", + deviceDetail: isDark ? "#374151" : "#c0c0c0", }; } function getDefaultColors() { return { - accent: 'oklch(0.85 0.18 85)', accentRgb: '255,215,0', - deviceCase: '#1a1a1a', deviceCaseDark: '#2c2c2c', deviceScreen: '#0a0a12', - deviceScreenFill: 'rgba(0,20,40,0.9)', labelWhite: '#FFFFFF', - labelMuted: 'rgba(179,179,179,0.9)', labelDim: 'rgba(179,179,179,0.7)', - wireDefault: 'rgba(179,179,179,0.8)', wireBright: 'rgba(255,255,255,0.9)', - wireFiltered: 'rgba(140,140,140,0.6)', - gridStroke: 'var(--exo-light-gray, #B3B3B3)', - errorText: 'rgba(248,113,113,0.9)', normalText: 'rgba(255,255,255,0.85)', - gpuChip: 'rgba(80, 80, 90, 0.7)', detailOverlay: 'rgba(0,0,0,0.35)', - deviceShadow: 'rgba(0,0,0,0.2)', deviceHighlight: 'rgba(255,255,255,0.08)', - tbActive: 'rgba(234,179,8,0.9)', tbInactive: 'rgba(100,100,100,0.7)', - deviceDetail: '#374151', + accent: "oklch(0.85 0.18 85)", + accentRgb: "255,215,0", + deviceCase: "#1a1a1a", + deviceCaseDark: "#2c2c2c", + deviceScreen: "#0a0a12", + deviceScreenFill: "rgba(0,20,40,0.9)", + labelWhite: "#FFFFFF", + labelMuted: "rgba(179,179,179,0.9)", + labelDim: "rgba(179,179,179,0.7)", + wireDefault: "rgba(179,179,179,0.8)", + wireBright: "rgba(255,255,255,0.9)", + wireFiltered: "rgba(140,140,140,0.6)", + gridStroke: "var(--exo-light-gray, #B3B3B3)", + errorText: "rgba(248,113,113,0.9)", + normalText: "rgba(255,255,255,0.85)", + gpuChip: "rgba(80, 80, 90, 0.7)", + detailOverlay: "rgba(0,0,0,0.35)", + deviceShadow: "rgba(0,0,0,0.2)", + deviceHighlight: "rgba(255,255,255,0.08)", + tbActive: "rgba(234,179,8,0.9)", + tbInactive: "rgba(100,100,100,0.7)", + deviceDetail: "#374151", }; } let themeColors = $state(getThemeColors()); $effect(() => { - if (typeof document === 'undefined') return; + if (typeof document === "undefined") return; const observer = new MutationObserver(() => { themeColors = getThemeColors(); }); - observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] }); + observer.observe(document.documentElement, { + attributes: true, + attributeFilter: ["class"], + }); return () => observer.disconnect(); });