From 37feea8df3d3ed5f139b4fbad42391cc524db4dd Mon Sep 17 00:00:00 2001 From: Sean O'Connor Date: Sun, 22 Mar 2026 16:49:20 -0400 Subject: [PATCH] ui: fix dead links in dashboard, update theme to teal/cyan - Fix broken /trials links to use study-scoped routes - Fix /wizard/ link to proper wizard URL with studyId - Add studyId to getLiveTrials API response - Update theme colors to teal/cyan sci-fi style - Add custom CSS utilities for glow effects and chamfered corners - Consolidate docs and archive outdated files --- src/app/dashboard/page.tsx | 8 +- src/server/api/routers/dashboard.ts | 1 + src/styles/globals.css | 250 ++++++++++++++++------------ 3 files changed, 151 insertions(+), 108 deletions(-) diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx index 01121d6..7089d59 100755 --- a/src/app/dashboard/page.tsx +++ b/src/app/dashboard/page.tsx @@ -239,7 +239,7 @@ export default function DashboardPage() { className="group h-auto justify-start px-4 py-4" asChild > - +
@@ -353,7 +353,7 @@ export default function DashboardPage() { @@ -367,7 +367,7 @@ export default function DashboardPage() { No trials are currently running.

) : ( @@ -404,7 +404,7 @@ export default function DashboardPage() { className="bg-primary hover:bg-primary/90 gap-2" asChild > - + Spectate / Jump In diff --git a/src/server/api/routers/dashboard.ts b/src/server/api/routers/dashboard.ts index 8b8cc38..c26b38d 100755 --- a/src/server/api/routers/dashboard.ts +++ b/src/server/api/routers/dashboard.ts @@ -143,6 +143,7 @@ export const dashboardRouter = createTRPCRouter({ const live = await ctx.db .select({ id: trials.id, + studyId: studies.id, startedAt: trials.startedAt, experimentName: experiments.name, participantCode: participants.participantCode, diff --git a/src/styles/globals.css b/src/styles/globals.css index c012f4d..20bcece 100755 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -7,6 +7,7 @@ @theme { --font-sans: var(--font-sans), ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace; } @theme inline { @@ -14,6 +15,7 @@ --radius-md: calc(var(--radius) - 2px); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) + 4px); + --radius-2xl: calc(var(--radius) + 8px); --color-background: var(--background); --color-foreground: var(--foreground); --color-card: var(--card); @@ -84,48 +86,49 @@ } :root { - /* Light Mode (Inverted: White BG, gray Cards) */ - --radius: 0.5rem; - --background: hsl(0 0% 100%); - /* Pure White Background */ + /* Light Mode - Teal/Cyan Sci-Fi Theme */ + --radius: 0.75rem; + /* More rounded */ + --background: hsl(190 40% 98%); + /* Very Light Cyan Background */ --foreground: hsl(240 10% 3.9%); - --card: hsl(240 4.8% 95.9%); - /* Light Gray Card */ + --card: hsl(180 20% 97%); + /* Light Teal Card */ --card-foreground: hsl(240 10% 3.9%); --popover: hsl(0 0% 100%); --popover-foreground: hsl(240 10% 3.9%); - --primary: hsl(221.2 83.2% 53.3%); - /* Indigo-600 */ - --primary-foreground: hsl(210 40% 98%); - --secondary: hsl(210 40% 96.1%); - --secondary-foreground: hsl(222.2 47.4% 11.2%); - --muted: hsl(210 40% 96.1%); - --muted-foreground: hsl(215.4 16.3% 46.9%); - --accent: hsl(210 40% 96.1%); - --accent-foreground: hsl(222.2 47.4% 11.2%); + /* Teal Primary - Robot/Sci-fi feel */ + --primary: hsl(173 80% 40%); + /* Teal-500: #14b8a6 */ + --primary-foreground: hsl(180 50% 10%); + /* Dark teal text on teal */ + --secondary: hsl(180 30% 92%); + --secondary-foreground: hsl(173 60% 20%); + --muted: hsl(180 20% 94%); + --muted-foreground: hsl(180 10% 40%); + --accent: hsl(180 40% 90%); + --accent-foreground: hsl(173 60% 20%); + /* Red for destructive, Cyan for highlights */ --destructive: hsl(0 84.2% 60.2%); - --destructive-foreground: hsl(210 40% 98%); - --border: hsl(214.3 31.8% 91.4%); - --input: hsl(214.3 31.8% 91.4%); - --ring: hsl(221.2 83.2% 53.3%); - --chart-1: hsl(221.2 83.2% 53.3%); - --chart-2: hsl(173 58% 39%); - --chart-3: hsl(197 37% 24%); - --chart-4: hsl(43 74% 66%); - --chart-5: hsl(27 87% 67%); - --sidebar: hsl(240 4.8% 95.9%); - /* Zinc-100: Distinct contrast against white BG */ + --destructive-foreground: hsl(0 0% 98%); + --border: hsl(180 20% 80%); + /* Slightly more visible border */ + --input: hsl(180 20% 80%); + --ring: hsl(173 80% 40%); + /* Chart colors - teal/cyan themed */ + --chart-1: hsl(173 80% 40%); + --chart-2: hsl(190 80% 55%); + --chart-3: hsl(200 70% 50%); + --chart-4: hsl(160 70% 45%); + --chart-5: hsl(210 70% 55%); + --sidebar: hsl(180 15% 94%); --sidebar-foreground: hsl(240 10% 3.9%); - /* Dark Text */ - --sidebar-primary: hsl(221.2 83.2% 53.3%); - /* Indigo Accent */ - --sidebar-primary-foreground: hsl(0 0% 98%); - --sidebar-accent: hsl(240 5.9% 90%); - /* Zinc-200: Slightly darker for hover */ - --sidebar-accent-foreground: hsl(240 5.9% 10%); - --sidebar-border: hsl(240 5.9% 90%); - /* Zinc-200 Border */ - --sidebar-ring: hsl(217.2 91.2% 59.8%); + --sidebar-primary: hsl(173 80% 40%); + --sidebar-primary-foreground: hsl(180 50% 10%); + --sidebar-accent: hsl(180 25% 88%); + --sidebar-accent-foreground: hsl(173 60% 20%); + --sidebar-border: hsl(180 20% 85%); + --sidebar-ring: hsl(173 80% 50%); --shadow-color: hsl(0 0% 0%); --shadow-opacity: 0; @@ -152,16 +155,43 @@ @media (prefers-color-scheme: dark) { :root { - --background: hsl(240 10% 3.9%); - --foreground: hsl(0 0% 98%); - /* Distinct Card Background for better contrast */ - --card: hsl(240 5% 9%); - --card-foreground: hsl(0 0% 98%); - --popover: hsl(240 5% 9%); - --popover-foreground: hsl(0 0% 98%); - --primary: hsl(0 0% 98%); - --primary-foreground: hsl(240 5.9% 10%); - --secondary: hsl(240 3.7% 15.9%); + /* Dark Mode - Teal/Cyan Sci-Fi Theme */ + --background: hsl(200 20% 8%); + /* Dark cyan/black */ + --foreground: hsl(180 20% 95%); + /* Light cyan text */ + --card: hsl(200 15% 12%); + /* Slightly lighter card */ + --card-foreground: hsl(180 20% 95%); + --popover: hsl(200 15% 10%); + --popover-foreground: hsl(180 20% 95%); + --primary: hsl(173 80% 45%); + /* Teal-500: brighter in dark */ + --primary-foreground: hsl(180 50% 10%); + --secondary: hsl(200 15% 15%); + --secondary-foreground: hsl(180 20% 90%); + --muted: hsl(200 15% 15%); + --muted-foreground: hsl(180 10% 60%); + --accent: hsl(173 60% 25%); + --accent-foreground: hsl(180 20% 95%); + --destructive: hsl(0 70% 55%); + --destructive-foreground: hsl(0 0% 100%); + --border: hsl(200 15% 20%); + --input: hsl(200 15% 20%); + --ring: hsl(173 80% 45%); + --chart-1: hsl(173 75% 50%); + --chart-2: hsl(180 70% 60%); + --chart-3: hsl(190 65% 55%); + --chart-4: hsl(160 60% 50%); + --chart-5: hsl(200 60% 55%); + --sidebar: hsl(200 15% 10%); + --sidebar-foreground: hsl(180 20% 90%); + --sidebar-primary: hsl(173 80% 45%); + --sidebar-primary-foreground: hsl(180 50% 10%); + --sidebar-accent: hsl(200 15% 18%); + --sidebar-accent-foreground: hsl(180 20% 90%); + --sidebar-border: hsl(200 15% 18%); + --sidebar-ring: hsl(173 80% 50%); --secondary-foreground: hsl(0 0% 98%); --muted: hsl(240 3.7% 15.9%); --muted-foreground: hsl(240 5% 64.9%); @@ -188,64 +218,6 @@ } } -@layer base { - .dark { - --background: hsl(240 10% 3.9%); - --foreground: hsl(0 0% 98%); - --card: hsl(240 5% 9%); - --card-foreground: hsl(0 0% 98%); - --popover: hsl(240 5% 9%); - --popover-foreground: hsl(0 0% 98%); - --primary: hsl(0 0% 98%); - --primary-foreground: hsl(240 5.9% 10%); - --secondary: hsl(240 3.7% 15.9%); - --secondary-foreground: hsl(0 0% 98%); - --muted: hsl(240 3.7% 15.9%); - --muted-foreground: hsl(240 5% 64.9%); - --accent: hsl(240 3.7% 15.9%); - --accent-foreground: hsl(0 0% 98%); - --destructive: hsl(0 62.8% 30.6%); - --destructive-foreground: hsl(0 0% 98%); - --border: hsl(240 3.7% 15.9%); - --input: hsl(240 3.7% 15.9%); - --ring: hsl(240 4.9% 83.9%); - --chart-1: hsl(220 70% 50%); - --chart-2: hsl(160 60% 45%); - --chart-3: hsl(30 80% 55%); - --chart-4: hsl(280 65% 60%); - --chart-5: hsl(340 75% 55%); - --sidebar: hsl(240 5.9% 10%); - --sidebar-foreground: hsl(240 4.8% 95.9%); - --sidebar-primary: hsl(224.3 76.3% 48%); - --sidebar-primary-foreground: hsl(0 0% 100%); - --sidebar-accent: hsl(240 3.7% 15.9%); - --sidebar-accent-foreground: hsl(240 4.8% 95.9%); - --sidebar-border: hsl(240 3.7% 15.9%); - --sidebar-border: hsl(240 3.7% 15.9%); - --sidebar-ring: hsl(217.2 91.2% 59.8%); - - /* Validation Dark Mode */ - --validation-error-bg: hsl(0 75% 15%); - /* Red 950-ish */ - --validation-error-text: hsl(0 100% 90%); - /* Red 100 */ - --validation-error-border: hsl(0 50% 30%); - /* Red 900 */ - --validation-warning-bg: hsl(30 90% 10%); - /* Amber 950-ish */ - --validation-warning-text: hsl(30 100% 90%); - /* Amber 100 */ - --validation-warning-border: hsl(30 60% 30%); - /* Amber 900 */ - --validation-info-bg: hsl(210 50% 15%); - /* Blue 950-ish */ - --validation-info-text: hsl(210 100% 90%); - /* Blue 100 */ - --validation-info-border: hsl(210 40% 30%); - /* Blue 900 */ - } -} - :root { /* Validation Light Mode Defaults */ --validation-error-bg: hsl(0 85% 97%); @@ -292,6 +264,76 @@ } } +/* Custom Component Theming */ +@layer utilities { + /* Chamfered corners - subtle sci-fi tech feel */ + .chamfer { + clip-path: polygon( + 0.75rem, 0, + 100% 0, + 100% calc(100% - 0.75rem), + calc(100% - 0.75rem) 100%, + 0 100% + ); + } + + /* Soft corners - very rounded */ + .rounded-chonk { + border-radius: 1rem; + } + + /* Card with subtle gradient */ + .card-teal { + background: linear-gradient( + 135deg, + hsl(var(--card) / 1) 0%, + hsl(var(--card-hue, 180) var(--card-sat, 20%) var(--card-light, 95%) / 0.5) 100% + ); + } + + /* Glow effects for primary actions */ + .glow-teal { + box-shadow: 0 0 20px hsl(var(--primary) / 0.3); + } + + .glow-teal:hover { + box-shadow: 0 0 30px hsl(var(--primary) / 0.5); + } + + /* Subtle pulse animation for active states */ + @keyframes pulse-glow { + 0%, 100% { + box-shadow: 0 0 10px hsl(var(--primary) / 0.2); + } + 50% { + box-shadow: 0 0 20px hsl(var(--primary) / 0.4); + } + } + + .animate-pulse-glow { + animation: pulse-glow 2s ease-in-out infinite; + } + + /* Italic/oblique text for labels */ + .font-slant { + font-style: oblique 10deg; + } + + /* Micro-interaction: subtle scale */ + .hover-scale { + transition: transform 150ms ease-out; + } + + .hover-scale:hover { + transform: scale(1.02); + } + + /* Border glow on focus */ + .ring-glow:focus-visible { + box-shadow: 0 0 0 2px var(--background), 0 0 0 4px var(--primary); + } +} + /* Viewport height constraint for proper flex layout */ html, body,