diff --git a/apps/admin/AGENTS.md b/apps/admin/AGENTS.md new file mode 100644 index 0000000..643577d --- /dev/null +++ b/apps/admin/AGENTS.md @@ -0,0 +1,9 @@ + + +# This is NOT the Next.js you know + +This version has breaking changes โ€” APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices. + +This block is written and re-added by `next dev` โ€” verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean. + + diff --git a/apps/admin/CLAUDE.md b/apps/admin/CLAUDE.md new file mode 100644 index 0000000..43c994c --- /dev/null +++ b/apps/admin/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/apps/admin/next-env.d.ts b/apps/admin/next-env.d.ts index 830fb59..ce4e94a 100644 --- a/apps/admin/next-env.d.ts +++ b/apps/admin/next-env.d.ts @@ -1,6 +1,7 @@ /// /// -/// +import "./.next/types/routes.d.ts"; +import "./.next/types/root-params.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/apps/admin/src/app/(admin)/ads/page.tsx b/apps/admin/src/app/(admin)/ads/page.tsx index 745ba9f..82ce061 100644 --- a/apps/admin/src/app/(admin)/ads/page.tsx +++ b/apps/admin/src/app/(admin)/ads/page.tsx @@ -99,7 +99,7 @@ function RewardKpis({ stats }: { stats: AdRewardStats }): React.ReactElement { > {card.title} - + {card.value} {card.subtext} diff --git a/apps/admin/src/app/(admin)/audit-log/[id]/page.tsx b/apps/admin/src/app/(admin)/audit-log/[id]/page.tsx index 21c64b6..e205a5a 100644 --- a/apps/admin/src/app/(admin)/audit-log/[id]/page.tsx +++ b/apps/admin/src/app/(admin)/audit-log/[id]/page.tsx @@ -71,7 +71,7 @@ export default async function AuditLogDetailPage({ params }: PageProps): Promise width: 4, height: 32, borderRadius: '999px', - background: 'linear-gradient(180deg, #3b82f6 0%, #8b5cf6 100%)', + background: 'linear-gradient(180deg, var(--d3-accent-main) 0%, var(--d3-tag-purple) 100%)', }} /> @@ -131,7 +131,7 @@ export default async function AuditLogDetailPage({ params }: PageProps): Promise sx={{ p: 2, borderRadius: '12px', - bgcolor: 'rgba(10, 17, 31, 0.7)', + bgcolor: 'var(--d3-bg-inset-soft)', border: `1px solid ${C.border}`, fontFamily: FONT_SANS, fontSize: '13px', diff --git a/apps/admin/src/app/(admin)/audit-log/page.tsx b/apps/admin/src/app/(admin)/audit-log/page.tsx index b8e3543..b071118 100644 --- a/apps/admin/src/app/(admin)/audit-log/page.tsx +++ b/apps/admin/src/app/(admin)/audit-log/page.tsx @@ -72,7 +72,7 @@ export default async function AuditLogPage({ searchParams }: PageProps): Promise width: 4, height: 32, borderRadius: '999px', - background: 'linear-gradient(180deg, #60a5fa 0%, #3b82f6 100%)', + background: 'linear-gradient(180deg, var(--d3-accent-light) 0%, var(--d3-accent-main) 100%)', }} /> @@ -182,7 +182,7 @@ export default async function AuditLogPage({ searchParams }: PageProps): Promise borderRadius: '8px', textTransform: 'none', px: 1.5, - '&:hover': { bgcolor: 'rgba(59, 130, 246, 0.15)', borderColor: C.accentLight }, + '&:hover': { bgcolor: 'var(--d3-accent-glow)', borderColor: C.accentLight }, }} > Inspect โ†’ diff --git a/apps/admin/src/app/(admin)/models/page.tsx b/apps/admin/src/app/(admin)/models/page.tsx index 4f134b6..221b4bb 100644 --- a/apps/admin/src/app/(admin)/models/page.tsx +++ b/apps/admin/src/app/(admin)/models/page.tsx @@ -345,7 +345,7 @@ export default function ServiceModelsPage(): React.ReactElement { width: 4, height: 34, borderRadius: '999px', - background: 'linear-gradient(180deg, #06b6d4 0%, #8b5cf6 50%, #3b82f6 100%)', + background: 'linear-gradient(180deg, var(--d3-tag-cyan) 0%, var(--d3-tag-purple) 50%, var(--d3-accent-main) 100%)', }} /> @@ -457,8 +457,8 @@ export default function ServiceModelsPage(): React.ReactElement { width: 44, height: 44, borderRadius: '12px', - bgcolor: 'rgba(6, 182, 212, 0.15)', - border: '1px solid rgba(6, 182, 212, 0.3)', + bgcolor: 'var(--d3-tag-cyan)', + border: '1px solid var(--d3-tag-cyan)', display: 'flex', alignItems: 'center', justifyContent: 'center', @@ -483,7 +483,7 @@ export default function ServiceModelsPage(): React.ReactElement { - + ๐Ÿ›ก๏ธ Auto Failover Route: {sttEndpoints.map((e) => e.providerType).join(' โž” ')} @@ -530,7 +530,7 @@ export default function ServiceModelsPage(): React.ReactElement { ) : ( sttEndpoints.map((ep) => ( - + #{ep.fallbackPriority} @@ -556,7 +556,7 @@ export default function ServiceModelsPage(): React.ReactElement { {ep.isDefault ? ( - + โญ DEFAULT ) : ( @@ -576,10 +576,10 @@ export default function ServiceModelsPage(): React.ReactElement { fontFamily: FONT_SANS, fontSize: '10px', color: C.green400, - borderColor: 'rgba(34, 197, 94, 0.4)', + borderColor: 'var(--d3-status-success)', px: 1, py: 0.25, - '&:hover': { bgcolor: 'rgba(34, 197, 94, 0.15)', borderColor: C.green400 }, + '&:hover': { bgcolor: 'var(--d3-status-success)', borderColor: C.green400 }, }} > Set Default @@ -596,7 +596,7 @@ export default function ServiceModelsPage(): React.ReactElement { borderColor: C.borderHl, px: 1, py: 0.25, - '&:hover': { bgcolor: 'rgba(59, 130, 246, 0.15)', borderColor: C.accentLight }, + '&:hover': { bgcolor: 'var(--d3-accent-glow)', borderColor: C.accentLight }, }} > {sttPingStatus[ep.id] || 'โšก Test'} @@ -676,7 +676,7 @@ export default function ServiceModelsPage(): React.ReactElement { {ep.modelId} {ep.isDefault && ( - + DEFAULT )} @@ -716,7 +716,7 @@ export default function ServiceModelsPage(): React.ReactElement { borderColor: C.borderHl, px: 1, py: 0.25, - '&:hover': { bgcolor: 'rgba(59, 130, 246, 0.15)', borderColor: C.accentLight }, + '&:hover': { bgcolor: 'var(--d3-accent-glow)', borderColor: C.accentLight }, }} > Delete @@ -740,11 +740,11 @@ export default function ServiceModelsPage(): React.ReactElement { fullWidth PaperProps={{ sx: { - bgcolor: 'rgba(17, 26, 48, 0.95)', + bgcolor: 'var(--d3-bg-card-soft)', backdropFilter: 'blur(32px)', border: `1px solid ${C.borderHl}`, borderRadius: '20px', - boxShadow: '0 24px 60px rgba(3, 7, 18, 0.8)', + boxShadow: '0 24px 60px var(--d3-scrim)', }, }} > @@ -772,7 +772,7 @@ export default function ServiceModelsPage(): React.ReactElement { if (preset.prompt) setSttPrompt(preset.prompt) }} sx={{ - bgcolor: 'rgba(10, 17, 31, 0.7)', + bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', '& fieldset': { borderColor: C.border }, @@ -796,7 +796,7 @@ export default function ServiceModelsPage(): React.ReactElement { size="small" placeholder="e.g. Groq Whisper LPU Fast" sx={{ - '& .MuiOutlinedInput-root': { bgcolor: 'rgba(10, 17, 31, 0.7)', color: C.bright, borderRadius: '10px' }, + '& .MuiOutlinedInput-root': { bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px' }, '& .MuiInputLabel-root': { color: C.dim }, }} /> @@ -807,7 +807,7 @@ export default function ServiceModelsPage(): React.ReactElement { label="Provider Type" onChange={(e) => setSttProviderType(e.target.value as STTProviderCategory)} sx={{ - bgcolor: 'rgba(10, 17, 31, 0.7)', + bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', '& fieldset': { borderColor: C.border }, @@ -834,7 +834,7 @@ export default function ServiceModelsPage(): React.ReactElement { size="small" placeholder="https://api.groq.com/openai/v1/audio/transcriptions" sx={{ - '& .MuiOutlinedInput-root': { bgcolor: 'rgba(10, 17, 31, 0.7)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO }, + '& .MuiOutlinedInput-root': { bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO }, '& .MuiInputLabel-root': { color: C.dim }, }} /> @@ -849,7 +849,7 @@ export default function ServiceModelsPage(): React.ReactElement { size="small" placeholder={sttEditingId ? 'โ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ข (๋ณ€๊ฒฝ ์‹œ ์ž…๋ ฅ)' : 'gsk_... or sk-... or token'} sx={{ - '& .MuiOutlinedInput-root': { bgcolor: 'rgba(10, 17, 31, 0.7)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO }, + '& .MuiOutlinedInput-root': { bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO }, '& .MuiInputLabel-root': { color: C.dim }, }} /> @@ -862,7 +862,7 @@ export default function ServiceModelsPage(): React.ReactElement { size="small" placeholder="e.g. whisper-large-v3-turbo, nova-3" sx={{ - '& .MuiOutlinedInput-root': { bgcolor: 'rgba(10, 17, 31, 0.7)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO }, + '& .MuiOutlinedInput-root': { bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO }, '& .MuiInputLabel-root': { color: C.dim }, }} /> @@ -876,7 +876,7 @@ export default function ServiceModelsPage(): React.ReactElement { label="Dispatch Method" onChange={(e) => setSttMethod(e.target.value as SttProviderEndpoint['method'])} sx={{ - bgcolor: 'rgba(10, 17, 31, 0.7)', + bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', '& fieldset': { borderColor: C.border }, @@ -897,7 +897,7 @@ export default function ServiceModelsPage(): React.ReactElement { size="small" placeholder="ko, en, auto" sx={{ - '& .MuiOutlinedInput-root': { bgcolor: 'rgba(10, 17, 31, 0.7)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO }, + '& .MuiOutlinedInput-root': { bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO }, '& .MuiInputLabel-root': { color: C.dim }, }} /> @@ -911,7 +911,7 @@ export default function ServiceModelsPage(): React.ReactElement { required size="small" sx={{ - '& .MuiOutlinedInput-root': { bgcolor: 'rgba(10, 17, 31, 0.7)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO }, + '& .MuiOutlinedInput-root': { bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO }, '& .MuiInputLabel-root': { color: C.dim }, }} /> @@ -926,7 +926,7 @@ export default function ServiceModelsPage(): React.ReactElement { required size="small" sx={{ - '& .MuiOutlinedInput-root': { bgcolor: 'rgba(10, 17, 31, 0.7)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO }, + '& .MuiOutlinedInput-root': { bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO }, '& .MuiInputLabel-root': { color: C.dim }, }} /> @@ -937,7 +937,7 @@ export default function ServiceModelsPage(): React.ReactElement { size="small" placeholder="e.g. D3RO, Kubernetes, React, LLM" sx={{ - '& .MuiOutlinedInput-root': { bgcolor: 'rgba(10, 17, 31, 0.7)', color: C.bright, borderRadius: '10px' }, + '& .MuiOutlinedInput-root': { bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px' }, '& .MuiInputLabel-root': { color: C.dim }, }} /> @@ -950,11 +950,11 @@ export default function ServiceModelsPage(): React.ReactElement { required helperText="๋ณ€๊ฒฝ ์‚ฌ์œ ๋ฅผ 3์ž ์ด์ƒ ์ž…๋ ฅํ•˜์„ธ์š”." size="small" - sx={{ '& .MuiOutlinedInput-root': { bgcolor: 'rgba(10, 17, 31, 0.7)', color: C.bright, borderRadius: '10px' } }} + sx={{ '& .MuiOutlinedInput-root': { bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px' } }} /> {/* Test Connection Inside Modal */} - + Live Connection Test (Synthetic Audio Ping) @@ -970,7 +970,7 @@ export default function ServiceModelsPage(): React.ReactElement { color: C.bright, borderColor: C.borderHl, textTransform: 'none', - '&:hover': { borderColor: C.accentLight, bgcolor: 'rgba(59, 130, 246, 0.15)' }, + '&:hover': { borderColor: C.accentLight, bgcolor: 'var(--d3-accent-glow)' }, }} > {testingInModal ? : null} @@ -985,8 +985,8 @@ export default function ServiceModelsPage(): React.ReactElement { sx={{ fontFamily: FONT_SANS, fontSize: '12px', - borderColor: sttTestModalResult.success ? 'rgba(34, 197, 94, 0.5)' : 'rgba(239, 68, 68, 0.5)', - color: sttTestModalResult.success ? C.green400 : '#f87171', + borderColor: sttTestModalResult.success ? 'var(--d3-status-success)' : 'var(--d3-status-danger)', + color: sttTestModalResult.success ? C.green400 : 'var(--d3-status-danger)', }} > {sttTestModalResult.message} @@ -1013,11 +1013,11 @@ export default function ServiceModelsPage(): React.ReactElement { fullWidth PaperProps={{ sx: { - bgcolor: 'rgba(17, 26, 48, 0.95)', + bgcolor: 'var(--d3-bg-card-soft)', backdropFilter: 'blur(32px)', border: `1px solid ${C.borderHl}`, borderRadius: '20px', - boxShadow: '0 24px 60px rgba(3, 7, 18, 0.8)', + boxShadow: '0 24px 60px var(--d3-scrim)', }, }} > @@ -1042,7 +1042,7 @@ export default function ServiceModelsPage(): React.ReactElement { setLlmCompletionCost(preset.completionCost) }} sx={{ - bgcolor: 'rgba(10, 17, 31, 0.7)', + bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', '& fieldset': { borderColor: C.border }, @@ -1062,7 +1062,7 @@ export default function ServiceModelsPage(): React.ReactElement { required fullWidth size="small" - sx={{ '& .MuiOutlinedInput-root': { bgcolor: 'rgba(10, 17, 31, 0.7)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO } }} + sx={{ '& .MuiOutlinedInput-root': { bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO } }} /> Provider Category @@ -1079,7 +1079,7 @@ export default function ServiceModelsPage(): React.ReactElement { value={llmProvider} label="Provider Category" onChange={(e) => setLlmProvider(e.target.value)} - sx={{ bgcolor: 'rgba(10, 17, 31, 0.7)', color: C.bright, borderRadius: '10px' }} + sx={{ bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px' }} > Local Sidecar Ollama Local Engine @@ -1095,7 +1095,7 @@ export default function ServiceModelsPage(): React.ReactElement { required fullWidth size="small" - sx={{ '& .MuiOutlinedInput-root': { bgcolor: 'rgba(10, 17, 31, 0.7)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO } }} + sx={{ '& .MuiOutlinedInput-root': { bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO } }} /> setLlmApiKey(e.target.value)} fullWidth size="small" - sx={{ '& .MuiOutlinedInput-root': { bgcolor: 'rgba(10, 17, 31, 0.7)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO } }} + sx={{ '& .MuiOutlinedInput-root': { bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO } }} /> setLlmPromptCost(e.target.value)} required size="small" - sx={{ '& .MuiOutlinedInput-root': { bgcolor: 'rgba(10, 17, 31, 0.7)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO } }} + sx={{ '& .MuiOutlinedInput-root': { bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO } }} /> setLlmCompletionCost(e.target.value)} required size="small" - sx={{ '& .MuiOutlinedInput-root': { bgcolor: 'rgba(10, 17, 31, 0.7)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO } }} + sx={{ '& .MuiOutlinedInput-root': { bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO } }} /> diff --git a/apps/admin/src/app/(admin)/page.tsx b/apps/admin/src/app/(admin)/page.tsx index dd0a21f..00df8c2 100644 --- a/apps/admin/src/app/(admin)/page.tsx +++ b/apps/admin/src/app/(admin)/page.tsx @@ -128,7 +128,7 @@ export default async function AdminOverviewPage(): Promise { width: 4, height: 32, borderRadius: '999px', - background: 'linear-gradient(180deg, #06b6d4 0%, #3b82f6 50%, #8b5cf6 100%)', + background: 'linear-gradient(180deg, var(--d3-tag-cyan) 0%, var(--d3-accent-main) 50%, var(--d3-tag-purple) 100%)', }} /> @@ -174,11 +174,11 @@ export default async function AdminOverviewPage(): Promise { fontSize: '12px', color: C.bright, borderColor: C.borderHl, - bgcolor: 'rgba(17, 26, 48, 0.6)', + bgcolor: 'var(--d3-bg-card-soft)', borderRadius: '10px', textTransform: 'none', px: 2, - '&:hover': { borderColor: C.accentLight, bgcolor: 'rgba(26, 38, 68, 0.8)' }, + '&:hover': { borderColor: C.accentLight, bgcolor: 'var(--d3-bg-raised-soft)' }, }} > View Pipelines Console โ†’ @@ -352,12 +352,12 @@ export default async function AdminOverviewPage(): Promise { sx={{ p: 2, borderRadius: '14px', - bgcolor: 'rgba(10, 17, 31, 0.65)', + bgcolor: 'var(--d3-bg-inset-soft)', border: `1px solid ${C.border}`, transition: 'all 0.2s ease', '&:hover': { borderColor: C.accentLight, - bgcolor: 'rgba(17, 26, 48, 0.8)', + bgcolor: 'var(--d3-bg-card-soft)', transform: 'translateY(-2px)', }, }} @@ -371,8 +371,8 @@ export default async function AdminOverviewPage(): Promise { width: 8, height: 8, borderRadius: '50%', - bgcolor: node.status === 'operational' ? '#10b981' : node.status === 'degraded' ? '#f59e0b' : '#ef4444', - boxShadow: `0 0 8px ${node.status === 'operational' ? '#10b981' : node.status === 'degraded' ? '#f59e0b' : '#ef4444'}`, + bgcolor: node.status === 'operational' ? 'var(--d3-status-success)' : node.status === 'degraded' ? 'var(--d3-status-warning)' : 'var(--d3-status-danger)', + boxShadow: `0 0 8px ${node.status === 'operational' ? 'var(--d3-status-success)' : node.status === 'degraded' ? 'var(--d3-status-warning)' : 'var(--d3-status-danger)'}`, }} /> diff --git a/apps/admin/src/app/(admin)/pipelines/page.tsx b/apps/admin/src/app/(admin)/pipelines/page.tsx index 6801825..773e275 100644 --- a/apps/admin/src/app/(admin)/pipelines/page.tsx +++ b/apps/admin/src/app/(admin)/pipelines/page.tsx @@ -44,7 +44,7 @@ export default async function PipelinesPage(): Promise { width: 4, height: 28, borderRadius: '999px', - background: 'linear-gradient(180deg, #06b6d4 0%, #3b82f6 100%)', + background: 'linear-gradient(180deg, var(--d3-tag-cyan) 0%, var(--d3-accent-main) 100%)', }} /> @@ -89,11 +89,11 @@ export default async function PipelinesPage(): Promise { fontSize: '12px', color: C.bright, borderColor: C.borderHl, - bgcolor: 'rgba(17, 26, 48, 0.6)', + bgcolor: 'var(--d3-bg-card-soft)', borderRadius: '10px', textTransform: 'none', px: 2, - '&:hover': { borderColor: C.accentLight, bgcolor: 'rgba(26, 38, 68, 0.8)' }, + '&:hover': { borderColor: C.accentLight, bgcolor: 'var(--d3-bg-raised-soft)' }, }} > โšก Run Diagnostic Ping @@ -129,19 +129,19 @@ export default async function PipelinesPage(): Promise { - + AVG LATENCY {whisper.avgLatencyMs}ms - + SPEEDUP FACTOR {whisper.speedupFactor} - + GPU VRAM {whisper.gpuVramUsage} @@ -149,7 +149,7 @@ export default async function PipelinesPage(): Promise { - + โ€ข Dual-Condition Flush: Audio buffer flushes parallel with model warm-up.
โ€ข Realtime Streaming: {whisper.partialStreamingFps} fps interim partial transcription in RecordingTip popup.
@@ -182,19 +182,19 @@ export default async function PipelinesPage(): Promise {
- + THROUGHPUT {ollama.tokensPerSecond} tok/s - + CONTEXT LIMIT {ollama.activeContextLimit} - + VRAM OCCUPANCY {ollama.vramAllocated} @@ -202,7 +202,7 @@ export default async function PipelinesPage(): Promise { - + โ€ข Loaded Models: {ollama.loadedModels.join(', ')}
โ€ข NDJSON Streaming: Zero-latency token streaming for Auto Polish & AI Chat.
@@ -238,19 +238,19 @@ export default async function PipelinesPage(): Promise {
- + LIVE STREAMS {realtimeVoice.activeStreams} Active - + AUDIO RTT {realtimeVoice.avgAudioRttMs}ms - + LOCAL FALLBACK {realtimeVoice.localFallbackRate} @@ -258,7 +258,7 @@ export default async function PipelinesPage(): Promise { - + โ€ข Ultra-low Latency: Full-duplex bidirectional voice-to-voice stream.
โ€ข Auto Failover: Drops gracefully to Local STT + Ollama + TTS if network drops.
@@ -291,19 +291,19 @@ export default async function PipelinesPage(): Promise {
- + INDEXED DOCS {ragVector.indexedDocuments.toLocaleString()} - + VECTOR CHUNKS {ragVector.totalVectorChunks.toLocaleString()} - + SEARCH HIT RATE {ragVector.topHitRatePercent}% @@ -311,7 +311,7 @@ export default async function PipelinesPage(): Promise { - + โ€ข Local Vector Store: Zero-cloud-leakage SQLite embeddings with cosine similarity.
โ€ข Average Search Latency: {ragVector.avgSearchLatencyMs}ms per 512-dim query.
@@ -345,7 +345,7 @@ export default async function PipelinesPage(): Promise {
- + SPEAKER ACCURACY {meetingIntelligence.speakerAccuracyPercent}% @@ -354,7 +354,7 @@ export default async function PipelinesPage(): Promise { Pyannote + LLM Consensus - + ACTIVE MEETINGS {meetingIntelligence.activeMeetingSessions} Live @@ -363,7 +363,7 @@ export default async function PipelinesPage(): Promise { Realtime Captions & Record - + TEMPLATES TODAY {meetingIntelligence.templatesGeneratedToday} Docs @@ -372,7 +372,7 @@ export default async function PipelinesPage(): Promise { Summary, Action Items, Jira - + MINDMAP EXPORTS {meetingIntelligence.mindmapsExported} Maps @@ -383,7 +383,7 @@ export default async function PipelinesPage(): Promise { - + โ€ข Speaker Attribution Architecture: Hybrid pipeline combining Pyannote 3.1 voiceprint embeddings with LLM conversational speaker inference.
โ€ข Multi-Document Synthesis (Phase 14.5): Simultaneous generation of Executive Summary, Action Item Checklist, Jira Issue Drafts, and Interactive Markdown Mindmaps.
diff --git a/apps/admin/src/app/(admin)/releases/page.tsx b/apps/admin/src/app/(admin)/releases/page.tsx index b915a94..f377684 100644 --- a/apps/admin/src/app/(admin)/releases/page.tsx +++ b/apps/admin/src/app/(admin)/releases/page.tsx @@ -165,7 +165,7 @@ function KpiCards({ hub }: { hub: ReleaseHub }): React.ReactElement { > {card.title}
- + {card.value} {card.subtext} diff --git a/apps/admin/src/app/(admin)/subscriptions/[id]/page.tsx b/apps/admin/src/app/(admin)/subscriptions/[id]/page.tsx index 6fb932c..7d97fef 100644 --- a/apps/admin/src/app/(admin)/subscriptions/[id]/page.tsx +++ b/apps/admin/src/app/(admin)/subscriptions/[id]/page.tsx @@ -80,7 +80,7 @@ export default async function SubscriptionDetailPage({ params }: PageProps): Pro width: 4, height: 32, borderRadius: '999px', - background: 'linear-gradient(180deg, #a855f7 0%, #3b82f6 100%)', + background: 'linear-gradient(180deg, var(--d3-tag-purple) 0%, var(--d3-accent-main) 100%)', }} /> diff --git a/apps/admin/src/app/(admin)/subscriptions/new/client.tsx b/apps/admin/src/app/(admin)/subscriptions/new/client.tsx index 21d7fca..a1ca5bc 100644 --- a/apps/admin/src/app/(admin)/subscriptions/new/client.tsx +++ b/apps/admin/src/app/(admin)/subscriptions/new/client.tsx @@ -31,7 +31,7 @@ export function NewSubscriptionClient({ initialUserId }: NewSubscriptionClientPr placeholder="Supabase user UUID" sx={{ '& .MuiOutlinedInput-root': { - bgcolor: 'rgba(10, 17, 31, 0.7)', + bgcolor: 'var(--d3-bg-inset-soft)', color: C.bright, borderRadius: '10px', fontFamily: FONT_MONO, diff --git a/apps/admin/src/app/(admin)/subscriptions/new/page.tsx b/apps/admin/src/app/(admin)/subscriptions/new/page.tsx index d4a417d..0d182d1 100644 --- a/apps/admin/src/app/(admin)/subscriptions/new/page.tsx +++ b/apps/admin/src/app/(admin)/subscriptions/new/page.tsx @@ -39,7 +39,7 @@ export default async function NewSubscriptionPage({ searchParams }: PageProps): width: 4, height: 32, borderRadius: '999px', - background: 'linear-gradient(180deg, #a855f7 0%, #3b82f6 100%)', + background: 'linear-gradient(180deg, var(--d3-tag-purple) 0%, var(--d3-accent-main) 100%)', }} /> diff --git a/apps/admin/src/app/(admin)/subscriptions/page.tsx b/apps/admin/src/app/(admin)/subscriptions/page.tsx index c17e0f7..d5b925e 100644 --- a/apps/admin/src/app/(admin)/subscriptions/page.tsx +++ b/apps/admin/src/app/(admin)/subscriptions/page.tsx @@ -115,7 +115,7 @@ export default async function AdminSubscriptionsPage({ searchParams }: PageProps width: 4, height: 32, borderRadius: '999px', - background: 'linear-gradient(180deg, #a855f7 0%, #3b82f6 100%)', + background: 'linear-gradient(180deg, var(--d3-tag-purple) 0%, var(--d3-accent-main) 100%)', }} /> @@ -305,7 +305,7 @@ export default async function AdminSubscriptionsPage({ searchParams }: PageProps borderRadius: '8px', textTransform: 'none', px: 1.5, - '&:hover': { bgcolor: 'rgba(59, 130, 246, 0.15)', borderColor: C.accentLight }, + '&:hover': { bgcolor: 'var(--d3-accent-glow)', borderColor: C.accentLight }, }} > Edit โ†’ diff --git a/apps/admin/src/app/(admin)/usage/page.tsx b/apps/admin/src/app/(admin)/usage/page.tsx index d8af0fd..cd4480c 100644 --- a/apps/admin/src/app/(admin)/usage/page.tsx +++ b/apps/admin/src/app/(admin)/usage/page.tsx @@ -84,7 +84,7 @@ export default async function AdminUsagePage(): Promise { width: 4, height: 32, borderRadius: '999px', - background: 'linear-gradient(180deg, #10b981 0%, #3b82f6 100%)', + background: 'linear-gradient(180deg, var(--d3-status-success) 0%, var(--d3-accent-main) 100%)', }} /> @@ -221,12 +221,12 @@ export default async function AdminUsagePage(): Promise { {(f.totalCalls ?? f.callCount ?? 0).toLocaleString()} calls ({(f.percentage ?? 10).toFixed(1)}%) โ€ข ${(f.estimatedCostUsd ?? f.totalCost).toFixed(2)}
- + @@ -138,15 +138,15 @@ export default async function AdminUserDetailPage({ params }: PageProps): Promis height: 48, borderRadius: '14px', background: isProPlus - ? 'linear-gradient(135deg, #a855f7 0%, #3b82f6 100%)' - : 'linear-gradient(135deg, #10b981 0%, #3b82f6 100%)', + ? 'linear-gradient(135deg, var(--d3-tag-purple) 0%, var(--d3-accent-main) 100%)' + : 'linear-gradient(135deg, var(--d3-status-success) 0%, var(--d3-accent-main) 100%)', display: 'flex', alignItems: 'center', justifyContent: 'center', - color: '#ffffff', + color: 'var(--d3-text-inverse)', fontWeight: 500, fontSize: '20px', - boxShadow: '0 0 20px rgba(59, 130, 246, 0.4)', + boxShadow: '0 0 20px var(--d3-accent-glow)', }} > {((profile.name as string) || (profile.email as string) || '?').charAt(0).toUpperCase()} @@ -188,7 +188,7 @@ export default async function AdminUserDetailPage({ params }: PageProps): Promis - + Entitlement source @@ -200,7 +200,7 @@ export default async function AdminUserDetailPage({ params }: PageProps): Promis {/* Tier-based Enabled Features */} - + Enabled Features diff --git a/apps/admin/src/app/(admin)/users/page.tsx b/apps/admin/src/app/(admin)/users/page.tsx index 66afb0d..dd63001 100644 --- a/apps/admin/src/app/(admin)/users/page.tsx +++ b/apps/admin/src/app/(admin)/users/page.tsx @@ -68,7 +68,7 @@ export default async function AdminUsersPage({ searchParams }: PageProps): Promi width: 4, height: 32, borderRadius: '999px', - background: 'linear-gradient(180deg, #3b82f6 0%, #8b5cf6 100%)', + background: 'linear-gradient(180deg, var(--d3-accent-main) 0%, var(--d3-tag-purple) 100%)', }} /> @@ -163,17 +163,17 @@ export default async function AdminUsersPage({ searchParams }: PageProps): Promi height: 34, borderRadius: '10px', background: isProPlus - ? 'linear-gradient(135deg, #a855f7 0%, #3b82f6 100%)' + ? 'linear-gradient(135deg, var(--d3-tag-purple) 0%, var(--d3-accent-main) 100%)' : isPro - ? 'linear-gradient(135deg, #10b981 0%, #3b82f6 100%)' - : 'linear-gradient(135deg, #64748b 0%, #475569 100%)', + ? 'linear-gradient(135deg, var(--d3-status-success) 0%, var(--d3-accent-main) 100%)' + : 'linear-gradient(135deg, var(--d3-text-label) 0%, var(--d3-text-label) 100%)', display: 'flex', alignItems: 'center', justifyContent: 'center', - color: '#ffffff', + color: 'var(--d3-text-inverse)', fontWeight: 500, fontSize: '13px', - boxShadow: isProPlus ? '0 0 12px rgba(168, 85, 247, 0.4)' : 'none', + boxShadow: isProPlus ? '0 0 12px var(--d3-tag-purple)' : 'none', }} > {u.name.charAt(0)} @@ -238,7 +238,7 @@ export default async function AdminUsersPage({ searchParams }: PageProps): Promi borderRadius: '8px', textTransform: 'none', px: 1.5, - '&:hover': { bgcolor: 'rgba(59, 130, 246, 0.15)', borderColor: C.accentLight }, + '&:hover': { bgcolor: 'var(--d3-accent-glow)', borderColor: C.accentLight }, }} > Manage โ†’ diff --git a/apps/admin/src/app/globals.css b/apps/admin/src/app/globals.css index edd29fe..c334475 100644 --- a/apps/admin/src/app/globals.css +++ b/apps/admin/src/app/globals.css @@ -1,29 +1,28 @@ -/* D3RO Voice Admin CRM โ€” "Midnight Glass v2" Global Styles */ +/* D3RO Voice Admin CRM โ€” "Midnight Glass v3" Global Styles */ /* ํฐํŠธ๋Š” layout.tsx ์˜ Pretendard Variable ๋‹ค์ด๋‚˜๋ฏน ์„œ๋ธŒ์…‹ ๋งํฌ๋กœ ๋กœ๋“œํ•œ๋‹ค (๋ Œ๋”๋ฅผ ๋ง‰๋Š” @import ์ด์ค‘ ๋กœ๋“œ๋Š” ์ œ๊ฑฐ). - ์ƒ‰ ๋ณ€์ˆ˜๋Š” @d3ro/ui SSOT๊ฐ€ MuiCssBaseline๋กœ ์ฃผ์ž…ํ•˜๋Š” --d3-*๋ฅผ ๊ทธ๋Œ€๋กœ ์“ด๋‹ค - (๊ด€๋ฆฌ์ž๋Š” ๊ณ ์ • ๋‹คํฌ: ๊ฐ’ ๋ฏธ์ง€์ • ์‹œ ์•„๋ž˜ ํด๋ฐฑ). */ + ์ƒ‰์€ @d3ro/ui SSOT๊ฐ€ MuiCssBaseline๋กœ ์ฃผ์ž…ํ•˜๋Š” --d3-* ๋งŒ ์“ด๋‹ค (๋กœ์ปฌ hex ํด๋ฐฑ ์—†์Œ). */ * { box-sizing: border-box; } /* ์˜๋ฏธ์  ๊ฐ•์กฐ๋Š” ์„ธ๋ฏธ๋ณผ๋“œ(600)๊นŒ์ง€ โ€” ๋ณผ๋“œ(700+) ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ ๊ธˆ์ง€ */ -strong, b { font-weight: 600; } +strong, b { font-weight: var(--d3-weight-strong); } body { margin: 0; padding: 0; - background-color: var(--d3-bg-app, #070b16); - color: var(--d3-text-primary, #eef2fb); + background-color: var(--d3-bg-app); + color: var(--d3-text-primary); font-family: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, 'Helvetica Neue', 'Segoe UI', 'Apple SD Gothic Neo', 'Noto Sans KR', sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; overflow-x: hidden; - background-image: - radial-gradient(ellipse 60% 40% at 10% 0%, rgba(6, 182, 212, 0.08) 0%, transparent 60%), - radial-gradient(ellipse 50% 50% at 90% 10%, rgba(59, 130, 246, 0.09) 0%, transparent 60%), - radial-gradient(ellipse 40% 40% at 50% 90%, rgba(139, 92, 246, 0.06) 0%, transparent 50%); + background-image: + radial-gradient(ellipse 60% 40% at 10% 0%, color-mix(in srgb, var(--d3-tag-cyan) 8%, transparent) 0%, transparent 60%), + radial-gradient(ellipse 50% 50% at 90% 10%, color-mix(in srgb, var(--d3-accent-main) 9%, transparent) 0%, transparent 60%), + radial-gradient(ellipse 40% 40% at 50% 90%, color-mix(in srgb, var(--d3-tag-purple) 6%, transparent) 0%, transparent 50%); background-attachment: fixed; } @@ -34,7 +33,12 @@ body { left: 0; right: 0; height: 320px; - background: radial-gradient(50% 100% at 50% 0%, rgba(59, 130, 246, 0.12) 0%, rgba(6, 182, 212, 0.04) 40%, transparent 100%); + background: radial-gradient( + 50% 100% at 50% 0%, + color-mix(in srgb, var(--d3-accent-main) 12%, transparent) 0%, + color-mix(in srgb, var(--d3-tag-cyan) 4%, transparent) 40%, + transparent 100% + ); pointer-events: none; z-index: 0; } @@ -42,8 +46,8 @@ body { /* High-End Subtle Grid Pattern */ .bg-grid { background-image: - linear-gradient(to right, rgba(148, 180, 255, 0.03) 1px, transparent 1px), - linear-gradient(to bottom, rgba(148, 180, 255, 0.03) 1px, transparent 1px); + linear-gradient(to right, var(--d3-glass-hairline) 1px, transparent 1px), + linear-gradient(to bottom, var(--d3-glass-hairline) 1px, transparent 1px); background-size: 32px 32px; } @@ -57,25 +61,24 @@ body { position: absolute; inset: 0; border-radius: inherit; - background: radial-gradient(ellipse 70% 55% at 18% -8%, rgba(59, 130, 246, 0.12) 0%, transparent 55%), - linear-gradient(180deg, rgba(148, 180, 255, 0.05) 0%, rgba(148, 180, 255, 0) 40%); + background: var(--d3-glass-sheen); pointer-events: none; } /* Glow effects */ -.glow-white { text-shadow: 0 0 15px rgba(255, 255, 255, 0.4); } -.glow-green { text-shadow: 0 0 15px rgba(16, 185, 129, 0.5); } -.glow-orange { text-shadow: 0 0 15px rgba(245, 158, 11, 0.5); } -.glow-red { text-shadow: 0 0 15px rgba(239, 68, 68, 0.5); } -.glow-blue { text-shadow: 0 0 15px rgba(59, 130, 246, 0.5); } -.glow-purple { text-shadow: 0 0 15px rgba(139, 92, 246, 0.5); } -.glow-cyan { text-shadow: 0 0 15px rgba(6, 182, 212, 0.5); } +.glow-white { text-shadow: 0 0 15px color-mix(in srgb, var(--d3-text-primary) 40%, transparent); } +.glow-green { text-shadow: 0 0 15px color-mix(in srgb, var(--d3-status-success) 50%, transparent); } +.glow-orange { text-shadow: 0 0 15px color-mix(in srgb, var(--d3-status-warning) 50%, transparent); } +.glow-red { text-shadow: 0 0 15px color-mix(in srgb, var(--d3-status-danger) 50%, transparent); } +.glow-blue { text-shadow: 0 0 15px color-mix(in srgb, var(--d3-accent-main) 50%, transparent); } +.glow-purple { text-shadow: 0 0 15px color-mix(in srgb, var(--d3-tag-purple) 50%, transparent); } +.glow-cyan { text-shadow: 0 0 15px color-mix(in srgb, var(--d3-tag-cyan) 50%, transparent); } /* Custom Sleek Scrollbar */ ::-webkit-scrollbar { width: 6px; height: 6px; } -::-webkit-scrollbar-track { background: rgba(7, 11, 22, 0.4); } -::-webkit-scrollbar-thumb { background: rgba(148, 180, 255, 0.15); border-radius: 999px; } -::-webkit-scrollbar-thumb:hover { background: rgba(148, 180, 255, 0.3); } +::-webkit-scrollbar-track { background: var(--d3-bg-inset-soft); } +::-webkit-scrollbar-thumb { background: var(--d3-glass-hairline); border-radius: 999px; } +::-webkit-scrollbar-thumb:hover { background: var(--d3-glass-hairlineStrong); } /* Pulse animation for live status */ @keyframes pulse-ring { @@ -91,13 +94,12 @@ body { position: absolute; inset: 0; border-radius: 50%; - background: #10b981; - animation: pulse-ring 2s cubic-bezier(0.24, 0, 0.38, 1) infinite; + background: var(--d3-status-success); + animation: pulse-ring 2s var(--d3-ease-out) infinite; } /* Selection */ ::selection { - background: rgba(59, 130, 246, 0.35); - color: #ffffff; + background: color-mix(in srgb, var(--d3-accent-main) 35%, transparent); + color: var(--d3-accent-ink); } - diff --git a/apps/admin/src/app/login/page.tsx b/apps/admin/src/app/login/page.tsx index b6621d9..5ccfa90 100644 --- a/apps/admin/src/app/login/page.tsx +++ b/apps/admin/src/app/login/page.tsx @@ -94,8 +94,8 @@ function LoginForm(): React.ReactElement { alignItems: 'center', justifyContent: 'center', minHeight: '100vh', - bgcolor: '#070b16', - backgroundImage: 'radial-gradient(ellipse 60% 50% at 50% 40%, rgba(59, 130, 246, 0.15) 0%, transparent 80%)', + bgcolor: 'var(--d3-bg-crtGlass)', + backgroundImage: 'radial-gradient(ellipse 60% 50% at 50% 40%, var(--d3-accent-glow) 0%, transparent 80%)', p: 2, position: 'relative', overflow: 'hidden', @@ -110,7 +110,7 @@ function LoginForm(): React.ReactElement { sx={{ width: '100%', maxWidth: 440, - boxShadow: '0 25px 60px rgba(0, 0, 0, 0.8), 0 0 40px rgba(59, 130, 246, 0.15)', + boxShadow: '0 25px 60px var(--d3-scrim), 0 0 40px var(--d3-accent-glow)', }} > {/* Brand Header */} @@ -120,15 +120,15 @@ function LoginForm(): React.ReactElement { width: 52, height: 52, borderRadius: '16px', - background: 'linear-gradient(135deg, #06b6d4 0%, #3b82f6 50%, #8b5cf6 100%)', + background: 'linear-gradient(135deg, var(--d3-tag-cyan) 0%, var(--d3-accent-main) 50%, var(--d3-tag-purple) 100%)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', - boxShadow: '0 0 25px rgba(59, 130, 246, 0.5)', + boxShadow: '0 0 25px var(--d3-accent-glow)', mb: 2, }} > - + @@ -290,7 +290,7 @@ function LoginForm(): React.ReactElement { export default function AdminLoginPage(): React.ReactElement { return ( - }> + }> ) diff --git a/apps/admin/src/app/unauthorized/page.tsx b/apps/admin/src/app/unauthorized/page.tsx index 64eb25d..6da3dbe 100644 --- a/apps/admin/src/app/unauthorized/page.tsx +++ b/apps/admin/src/app/unauthorized/page.tsx @@ -14,8 +14,8 @@ export default function UnauthorizedPage(): React.ReactElement { alignItems: 'center', justifyContent: 'center', minHeight: '100vh', - bgcolor: '#070b16', - backgroundImage: 'radial-gradient(ellipse 60% 50% at 50% 40%, rgba(239, 68, 68, 0.15) 0%, transparent 80%)', + bgcolor: 'var(--d3-bg-crtGlass)', + backgroundImage: 'radial-gradient(ellipse 60% 50% at 50% 40%, var(--d3-status-danger) 0%, transparent 80%)', p: 2, }} > @@ -26,7 +26,7 @@ export default function UnauthorizedPage(): React.ReactElement { width: '100%', maxWidth: 440, textAlign: 'center', - boxShadow: '0 25px 60px rgba(0, 0, 0, 0.8), 0 0 40px rgba(239, 68, 68, 0.2)', + boxShadow: '0 25px 60px var(--d3-scrim), 0 0 40px var(--d3-status-danger)', }} > @@ -66,7 +66,7 @@ export default function UnauthorizedPage(): React.ReactElement { sx={{ borderColor: C.borderHl, color: C.bright, - bgcolor: 'rgba(17, 26, 48, 0.5)', + bgcolor: 'var(--d3-bg-card-soft)', borderRadius: '10px', fontFamily: FONT_SANS, fontSize: '13px', @@ -75,7 +75,7 @@ export default function UnauthorizedPage(): React.ReactElement { py: 1.1, '&:hover': { borderColor: C.accentLight, - bgcolor: 'rgba(26, 38, 68, 0.8)', + bgcolor: 'var(--d3-bg-raised-soft)', }, }} > diff --git a/apps/admin/src/components/admin-sidebar.tsx b/apps/admin/src/components/admin-sidebar.tsx index 3a9ccf9..c21a3b0 100644 --- a/apps/admin/src/components/admin-sidebar.tsx +++ b/apps/admin/src/components/admin-sidebar.tsx @@ -168,14 +168,14 @@ export function AdminSidebar({ identity }: { height: '100%', display: 'flex', flexDirection: 'column', - bgcolor: 'rgba(11, 16, 31, 0.82)', + bgcolor: 'var(--d3-bg-card-soft)', backdropFilter: 'blur(28px)', border: `1px solid ${C.border}`, borderRadius: '22px', flexShrink: 0, position: 'relative', overflow: 'hidden', - boxShadow: '0 24px 60px rgba(3, 7, 18, 0.7), inset 0 1px 0 rgba(148, 180, 255, 0.1)', + boxShadow: '0 24px 60px var(--d3-scrim), inset 0 1px 0 var(--d3-glass-hairlineStrong)', }} > {/* Top Ambient Sheen */} @@ -186,7 +186,7 @@ export function AdminSidebar({ identity }: { left: 0, right: 0, height: 120, - background: 'radial-gradient(ellipse 80% 60% at 50% -10%, rgba(59, 130, 246, 0.18) 0%, transparent 80%)', + background: 'radial-gradient(ellipse 80% 60% at 50% -10%, var(--d3-accent-glow) 0%, transparent 80%)', pointerEvents: 'none', }} /> @@ -210,11 +210,11 @@ export function AdminSidebar({ identity }: { width: 34, height: 34, borderRadius: '10px', - background: 'linear-gradient(135deg, #06b6d4 0%, #3b82f6 50%, #8b5cf6 100%)', + background: 'linear-gradient(135deg, var(--d3-tag-cyan) 0%, var(--d3-accent-main) 50%, var(--d3-tag-purple) 100%)', display: 'flex', alignItems: 'center', justifyContent: 'center', - boxShadow: '0 0 20px rgba(59, 130, 246, 0.45)', + boxShadow: '0 0 20px var(--d3-accent-glow)', }} > @@ -260,8 +260,8 @@ export function AdminSidebar({ identity }: { px: 1, py: 0.35, borderRadius: '999px', - bgcolor: 'rgba(16, 185, 129, 0.12)', - border: '1px solid rgba(16, 185, 129, 0.25)', + bgcolor: 'var(--d3-status-success)', + border: '1px solid var(--d3-status-success)', }} > - + SESSION @@ -328,14 +328,14 @@ export function AdminSidebar({ identity }: { borderRadius: '12px', cursor: 'pointer', position: 'relative', - border: `1px solid ${active ? 'rgba(59, 130, 246, 0.35)' : 'transparent'}`, - bgcolor: active ? 'rgba(59, 130, 246, 0.14)' : 'transparent', + border: `1px solid ${active ? 'var(--d3-accent-glow)' : 'transparent'}`, + bgcolor: active ? 'var(--d3-accent-glow)' : 'transparent', color: active ? C.bright : C.text, - boxShadow: active ? '0 0 20px rgba(59, 130, 246, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.1)' : 'none', + boxShadow: active ? '0 0 20px var(--d3-accent-glow), inset 0 1px 0 var(--d3-overlay-strong)' : 'none', transition: 'all 0.18s cubic-bezier(0.16, 1, 0.3, 1)', '&:hover': { - bgcolor: active ? 'rgba(59, 130, 246, 0.2)' : 'rgba(26, 38, 68, 0.5)', - borderColor: active ? 'rgba(96, 165, 250, 0.5)' : C.border, + bgcolor: active ? 'var(--d3-accent-glow)' : 'var(--d3-bg-raised-soft)', + borderColor: active ? 'var(--d3-accent-light)' : C.border, color: C.bright, transform: 'translateX(3px)', }, @@ -379,7 +379,7 @@ export function AdminSidebar({ identity }: { {identity.email.slice(0, 1).toUpperCase()} @@ -442,7 +442,7 @@ export function AdminSidebar({ identity }: { transition: 'all 0.15s ease', '&:hover': { color: C.red400, - bgcolor: 'rgba(239, 68, 68, 0.12)', + bgcolor: 'var(--d3-status-danger)', }, }} > diff --git a/apps/admin/src/components/license-issuer-button.tsx b/apps/admin/src/components/license-issuer-button.tsx index ffdea27..a39a3f0 100644 --- a/apps/admin/src/components/license-issuer-button.tsx +++ b/apps/admin/src/components/license-issuer-button.tsx @@ -20,7 +20,7 @@ export function LicenseIssuerButton(): React.ReactElement { sx={{ ...primaryButtonSx, background: `linear-gradient(135deg, ${C.purple} 0%, ${C.accent} 100%)`, - boxShadow: '0 0 12px rgba(139, 92, 246, 0.4)' + boxShadow: '0 0 12px var(--d3-tag-purple)' }} > โšก Issue Ed25519 License Key diff --git a/apps/admin/src/components/license-issuer-dialog.tsx b/apps/admin/src/components/license-issuer-dialog.tsx index 765f974..a891693 100644 --- a/apps/admin/src/components/license-issuer-dialog.tsx +++ b/apps/admin/src/components/license-issuer-dialog.tsx @@ -117,7 +117,7 @@ export function LicenseIssuerDialog({ open, onClose }: LicenseIssuerDialogProps) bgcolor: C.app, border: `1px solid ${C.borderHl}`, borderRadius: '16px', - boxShadow: '0 20px 40px rgba(0, 0, 0, 0.8)', + boxShadow: '0 20px 40px var(--d3-scrim)', p: 1 } }} @@ -208,7 +208,7 @@ export function LicenseIssuerDialog({ open, onClose }: LicenseIssuerDialogProps) {generatedKey && ( - + {!auditRecorded && ( ๋ผ์ด์„ ์Šค๋Š” ๋ฐœ๊ธ‰๋˜์—ˆ์œผ๋‚˜ ๊ฐ์‚ฌ ๋กœ๊ทธ ๊ธฐ๋ก์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฐฑ์—”๋“œ ์—ฐ๊ฒฐ์„ ํ™•์ธํ•˜์„ธ์š”. @@ -223,7 +223,7 @@ export function LicenseIssuerDialog({ open, onClose }: LicenseIssuerDialogProps) fontSize: '11px', color: C.bright, p: 1.5, - bgcolor: 'rgba(255, 255, 255, 0.05)', + bgcolor: 'var(--d3-overlay-strong)', borderRadius: '6px', wordBreak: 'break-all', userSelect: 'all',