From 84d94c49e999f91abe4b521012d3d64739e77836 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Wed, 15 Apr 2026 23:00:12 +0200 Subject: [PATCH] fix: align client portal shell and chat styles --- .../src/components/ClientLayout.test.tsx | 23 ++++ apps/clients/src/components/ClientLayout.tsx | 15 +-- apps/clients/src/main.css | 106 ++++++++++-------- apps/clients/src/mainCss.test.ts | 15 +++ 4 files changed, 105 insertions(+), 54 deletions(-) create mode 100644 apps/clients/src/components/ClientLayout.test.tsx create mode 100644 apps/clients/src/mainCss.test.ts diff --git a/apps/clients/src/components/ClientLayout.test.tsx b/apps/clients/src/components/ClientLayout.test.tsx new file mode 100644 index 0000000..17c3972 --- /dev/null +++ b/apps/clients/src/components/ClientLayout.test.tsx @@ -0,0 +1,23 @@ +import { describe, expect, it } from "vitest"; +import { renderWithProviders } from "../test/testHelpers"; +import { ClientLayout } from "./ClientLayout"; + +describe("ClientLayout", () => { + it("uses the main app style header shell and centered content container", () => { + const { container } = renderWithProviders(); + + const header = container.querySelector("header"); + expect(header).toHaveClass("h-[75px]"); + expect(header).toHaveClass("bg-navbar-background"); + + const headerInner = header?.firstElementChild; + expect(headerInner).toHaveClass("w-full"); + expect(headerInner).toHaveClass("max-w-7xl"); + expect(headerInner).toHaveClass("mx-auto"); + + const main = container.querySelector("main"); + expect(main).toHaveClass("w-full"); + expect(main).toHaveClass("max-w-7xl"); + expect(main).toHaveClass("mx-auto"); + }); +}); diff --git a/apps/clients/src/components/ClientLayout.tsx b/apps/clients/src/components/ClientLayout.tsx index 20719a0..16609cf 100644 --- a/apps/clients/src/components/ClientLayout.tsx +++ b/apps/clients/src/components/ClientLayout.tsx @@ -36,14 +36,10 @@ export function ClientLayout() { }; return ( -
- {/* Top bar */} -
-
- {/* Brand */} - Xtablo - - {/* User info + logout */} +
+
+
+ Xtablo
@@ -58,8 +54,7 @@ export function ClientLayout() {
- {/* Page content */} -
+
diff --git a/apps/clients/src/main.css b/apps/clients/src/main.css index a896ff7..2782768 100644 --- a/apps/clients/src/main.css +++ b/apps/clients/src/main.css @@ -1,6 +1,8 @@ @import "tailwindcss"; @import "tw-animate-css"; +@source "../../../packages/chat-ui/src/**/*.{ts,tsx}"; + @custom-variant dark (&:is(.dark *)); :root { @@ -37,41 +39,45 @@ --sidebar-accent-foreground: oklch(0.205 0 0); --sidebar-border: oklch(0.922 0 0); --sidebar-ring: oklch(0.708 0 0); + --navbar-background: rgb(249, 250, 251); + --navbar-darker: #e5e7eb; } .dark { - --background: oklch(0.145 0 0); - --foreground: oklch(0.985 0 0); - --card: oklch(0.145 0 0); - --card-foreground: oklch(0.985 0 0); - --popover: oklch(0.145 0 0); - --popover-foreground: oklch(0.985 0 0); - --primary: oklch(0.985 0 0); - --primary-foreground: oklch(0.205 0 0); - --secondary: oklch(0.269 0 0); - --secondary-foreground: oklch(0.985 0 0); - --muted: oklch(0.269 0 0); - --muted-foreground: oklch(0.708 0 0); - --accent: oklch(0.269 0 0); - --accent-foreground: oklch(0.985 0 0); + --background: oklch(0.17 0.012 290); + --foreground: oklch(0.985 0.005 290); + --card: oklch(0.16 0.014 290); + --card-foreground: oklch(0.985 0.005 290); + --popover: oklch(0.16 0.014 290); + --popover-foreground: oklch(0.985 0.005 290); + --primary: oklch(0.985 0.005 290); + --primary-foreground: oklch(0.2 0.012 290); + --secondary: oklch(0.22 0.018 290); + --secondary-foreground: oklch(0.985 0.005 290); + --muted: oklch(0.22 0.018 290); + --muted-foreground: oklch(0.65 0.02 290); + --accent: oklch(0.22 0.018 290); + --accent-foreground: oklch(0.985 0.005 290); --destructive: oklch(0.396 0.141 25.723); --destructive-foreground: oklch(0.637 0.237 25.331); - --border: oklch(0.269 0 0); - --input: oklch(0.269 0 0); - --ring: oklch(0.439 0 0); - --chart-1: oklch(0.488 0.243 264.376); + --border: oklch(0.26 0.02 290); + --input: oklch(0.26 0.02 290); + --ring: oklch(0.45 0.03 290); + --chart-1: oklch(0.55 0.2 290); --chart-2: oklch(0.696 0.17 162.48); --chart-3: oklch(0.769 0.188 70.08); --chart-4: oklch(0.627 0.265 303.9); --chart-5: oklch(0.645 0.246 16.439); - --sidebar: oklch(0.205 0 0); - --sidebar-foreground: oklch(0.985 0 0); - --sidebar-primary: oklch(0.488 0.243 264.376); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.269 0 0); - --sidebar-accent-foreground: oklch(0.985 0 0); - --sidebar-border: oklch(0.269 0 0); - --sidebar-ring: oklch(0.439 0 0); + --sidebar: oklch(0.18 0.016 290); + --sidebar-foreground: oklch(0.985 0.005 290); + --sidebar-primary: oklch(0.55 0.2 290); + --sidebar-primary-foreground: oklch(0.985 0.005 290); + --sidebar-accent: oklch(0.24 0.02 290); + --sidebar-accent-foreground: oklch(0.985 0.005 290); + --sidebar-border: oklch(0.26 0.02 290); + --sidebar-ring: oklch(0.45 0.03 290); + --navbar-background: #1e1b2e; + --navbar-darker: #141121; } @theme inline { @@ -111,8 +117,8 @@ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); --color-sidebar-border: var(--sidebar-border); --color-sidebar-ring: var(--sidebar-ring); - --color-navbar-background: #292e39; - --color-navbar-darker: #171920; + --color-navbar-background: var(--navbar-background); + --color-navbar-darker: var(--navbar-darker); } @layer base { @@ -122,31 +128,43 @@ body { @apply bg-background text-foreground; } + @media (display-mode: standalone) { + body { + padding-top: env(safe-area-inset-top); + padding-bottom: env(safe-area-inset-bottom); + padding-left: env(safe-area-inset-left); + padding-right: env(safe-area-inset-right); + } + } } .str-chat { - --str-chat__primary-color: #8b7396; - --str-chat__active-primary-color: #6e5c7d; + --str-chat__primary-color: #804eec; + --str-chat__active-primary-color: #6f3fd4; --str-chat__surface-color: #f5f3f7; --str-chat__secondary-surface-color: #e8e4ec; - --str-chat__primary-surface-color: #ebe7f0; - --str-chat__primary-surface-color-low-emphasis: #f2f0f5; + --str-chat__primary-surface-color: #f4f3ff; + --str-chat__primary-surface-color-low-emphasis: #f8f7ff; --str-chat__border-radius-circle: 6px; + --str-chat__own-message-bubble-color: #804eec; + --str-chat__own-message-text-color: #ffffff; } .dark .str-chat { - --str-chat__primary-color: #a68bb5; - --str-chat__active-primary-color: #8b7396; - --str-chat__surface-color: rgba(120, 107, 130, 0.25); - --str-chat__secondary-surface-color: rgba(140, 130, 150, 0.18); - --str-chat__primary-surface-color: rgba(166, 139, 181, 0.12); - --str-chat__primary-surface-color-low-emphasis: rgba(166, 139, 181, 0.06); - --str-chat__background-color: rgba(110, 100, 120, 0.2); - --str-chat__secondary-background-color: rgba(80, 72, 88, 0.35); - --str-chat__border-color: rgba(120, 107, 130, 0.28); - --str-chat__text-color: #f5f3f7; - --str-chat__text-low-emphasis-color: #b8b0c0; - --str-chat__disabled-color: rgba(155, 143, 165, 0.35); + --str-chat__primary-color: #9b6ff0; + --str-chat__active-primary-color: #804eec; + --str-chat__surface-color: rgba(128, 78, 236, 0.12); + --str-chat__secondary-surface-color: rgba(128, 78, 236, 0.08); + --str-chat__primary-surface-color: rgba(128, 78, 236, 0.1); + --str-chat__primary-surface-color-low-emphasis: rgba(128, 78, 236, 0.05); + --str-chat__background-color: rgba(30, 27, 46, 0.6); + --str-chat__secondary-background-color: rgba(20, 17, 33, 0.5); + --str-chat__border-color: rgba(128, 78, 236, 0.15); + --str-chat__text-color: #eeeaf5; + --str-chat__text-low-emphasis-color: #a8a0b8; + --str-chat__disabled-color: rgba(128, 78, 236, 0.2); + --str-chat__own-message-bubble-color: #804eec; + --str-chat__own-message-text-color: #ffffff; } @keyframes gradient-x { diff --git a/apps/clients/src/mainCss.test.ts b/apps/clients/src/mainCss.test.ts new file mode 100644 index 0000000..c150cce --- /dev/null +++ b/apps/clients/src/mainCss.test.ts @@ -0,0 +1,15 @@ +import { readFileSync } from "node:fs"; +import { resolve } from "node:path"; +import { describe, expect, it } from "vitest"; + +const mainCss = readFileSync(resolve(process.cwd(), "src/main.css"), "utf8"); + +describe("clients main.css", () => { + it("keeps the chat source and theme tokens aligned with the main app", () => { + expect(mainCss).toContain('@source "../../../packages/chat-ui/src/**/*.{ts,tsx}";'); + expect(mainCss).toContain("--navbar-background: rgb(249, 250, 251);"); + expect(mainCss).toContain("--color-navbar-background: var(--navbar-background);"); + expect(mainCss).toContain("--str-chat__own-message-bubble-color: #804eec;"); + expect(mainCss).toContain("--str-chat__own-message-text-color: #ffffff;"); + }); +});