From 9cba8b48297cebdcdfe7839475820ce6f7baab38 Mon Sep 17 00:00:00 2001 From: Cory Hawklvelt Date: Sun, 26 Apr 2026 17:06:45 +0930 Subject: [PATCH] feat: add visual theme indicators and fix logo colors for dev/staging environments --- src/components/branding/SecuirdLogo.tsx | 28 ++++++--- src/components/branding/ThemeIndicator.tsx | 42 +++++++++++++ .../layouts/AuthenticatedLayout.tsx | 4 +- src/components/layouts/MarketingLayout.tsx | 20 ++++--- src/components/layouts/PublicLayout.tsx | 8 ++- src/index.css | 59 ++++++++++++++++++- 6 files changed, 139 insertions(+), 22 deletions(-) create mode 100644 src/components/branding/ThemeIndicator.tsx diff --git a/src/components/branding/SecuirdLogo.tsx b/src/components/branding/SecuirdLogo.tsx index aa80334..f8fd0dc 100644 --- a/src/components/branding/SecuirdLogo.tsx +++ b/src/components/branding/SecuirdLogo.tsx @@ -10,6 +10,9 @@ interface SecuirdLogoProps { * Secuird Logo - Abstract gate/doorway mark * Represents controlled entry and policy enforcement * Two vertical pillars forming a gateway with negative space + * + * Uses inline styles for theme colors to ensure they work correctly + * across all theme configurations (default, dev, preprod) */ export function SecuirdLogo({ size = "md", @@ -22,31 +25,38 @@ export function SecuirdLogo({ lg: "w-12 h-12", }; - const bgClasses = { - default: "bg-primary", - light: "bg-sidebar-primary", + // Use inline styles for theme colors to ensure they work at runtime + const getBgStyle = () => { + if (variant === "light") { + return { + backgroundColor: "hsl(var(--theme-sidebar-primary, 173 65% 36%))", + color: "hsl(var(--theme-sidebar-primary-foreground, 0 0% 100%))" + }; + } + return { + backgroundColor: "hsl(var(--theme-primary, 173 65% 36%))", + color: "hsl(var(--theme-primary-foreground, 0 0% 100%))" + }; }; - - const iconColor = variant === "light" - ? "text-sidebar-primary-foreground" - : "text-primary-foreground"; + + const bgStyle = getBgStyle(); return (
{/* Abstract gate - two pillars with archway */} = { + dev: "Development Environment", + preprod: "Staging / Pre-Production", + }; + + const themeLabel = themeLabels[theme] || theme; + + if (showBanner) { + return ( +
+ {themeLabel} — {appName} +
+ ); + } + + return ( + + + {themeLabel} + + ); +} \ No newline at end of file diff --git a/src/components/layouts/AuthenticatedLayout.tsx b/src/components/layouts/AuthenticatedLayout.tsx index 73ab8d6..b192e7e 100644 --- a/src/components/layouts/AuthenticatedLayout.tsx +++ b/src/components/layouts/AuthenticatedLayout.tsx @@ -3,11 +3,13 @@ import { SidebarProvider } from "@/components/ui/sidebar"; import { AppSidebar } from "@/components/navigation/AppSidebar"; import { TopBar } from "@/components/navigation/TopBar"; import ApiDevTools from "@/components/dev/ApiDevTools"; +import { ThemeIndicator } from "@/components/branding/ThemeIndicator"; export default function AuthenticatedLayout() { return ( -
+ +
diff --git a/src/components/layouts/MarketingLayout.tsx b/src/components/layouts/MarketingLayout.tsx index e5998f2..d957dbc 100644 --- a/src/components/layouts/MarketingLayout.tsx +++ b/src/components/layouts/MarketingLayout.tsx @@ -1,16 +1,17 @@ import { Link, Outlet, useLocation } from "react-router-dom"; import { SecuirdLogo as GatehouseLogo } from "@/components/branding/SecuirdLogo"; +import { ThemeIndicator } from "@/components/branding/ThemeIndicator"; import { Button } from "@/components/ui/button"; import { config } from "@/config"; import { cn } from "@/lib/utils"; import { -Shield, -Key, -CreditCard, -Play, -Lock, -Menu, -X + Shield, + Key, + CreditCard, + Play, + Lock, + Menu, + X } from "lucide-react"; import { useState } from "react"; @@ -29,8 +30,11 @@ const [mobileMenuOpen, setMobileMenuOpen] = useState(false); return (
+ {/* Theme indicator banner for dev/staging */} + + {/* Header */} -
+