This is an automated email from the ASF dual-hosted git repository.

hsluoyz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/casbin-gateway.git

commit d952752011bcdf99b5e0c4cdbe85a9d1f0f2780d
Author: Yang Luo <[email protected]>
AuthorDate: Fri Sep 4 14:56:02 2026 +0800

    style(theme): replace the neutral palette with warm amber and ink
---
 web/src/App.tsx                           |   2 +-
 web/src/components/shared/app-sidebar.tsx |  14 +-
 web/src/index.css                         | 212 ++++++++++++++++++------------
 web/src/pages/SigninPage.tsx              |   2 +-
 4 files changed, 138 insertions(+), 92 deletions(-)

diff --git a/web/src/App.tsx b/web/src/App.tsx
index a4293eb..f6f052e 100644
--- a/web/src/App.tsx
+++ b/web/src/App.tsx
@@ -319,7 +319,7 @@ export default function App() {
           <footer className="flex items-center justify-center border-t py-5">
             <a target="_blank" rel="noreferrer" 
href="https://github.com/apache/casbin-gateway";>
               <img
-                className="h-[30px] w-auto"
+                className="h-[30px] w-auto dark:invert dark:hue-rotate-180"
                 alt="Casbin"
                 src={`${Setting.StaticBaseUrl}/img/casbin_logo_1024x256.png`}
               />
diff --git a/web/src/components/shared/app-sidebar.tsx 
b/web/src/components/shared/app-sidebar.tsx
index 80554c4..309b506 100644
--- a/web/src/components/shared/app-sidebar.tsx
+++ b/web/src/components/shared/app-sidebar.tsx
@@ -84,11 +84,13 @@ function NavLink({
     <Link
       to={to}
       className={cn(
-        "flex items-center gap-2.5 rounded-md px-2.5 py-2 text-sm 
transition-colors",
+        "relative flex items-center gap-2.5 rounded-md px-2.5 py-2 text-sm 
transition-colors",
         collapsed && "justify-center px-0",
         nested && !collapsed && "pl-9 text-[13px]",
         active
-          ? "bg-sidebar-accent text-sidebar-accent-foreground font-medium"
+          // The amber rule is what marks the page you are on; the tinted fill
+          // alone is too quiet to find at a glance down a rail this long.
+          ? "bg-sidebar-accent text-sidebar-accent-foreground 
before:bg-sidebar-primary font-medium before:absolute before:top-1.5 
before:bottom-1.5 before:left-0 before:w-[3px] before:rounded-full 
before:content-['']"
           : "text-sidebar-foreground/70 hover:bg-sidebar-accent/60 
hover:text-sidebar-foreground",
       )}
     >
@@ -170,7 +172,13 @@ export function AppSidebar({
             <img
               src={`${Setting.StaticBaseUrl}/img/logo_384x96.png`}
               alt="Casbin Gateway"
-              className={cn("w-auto object-contain transition-all", 
railCollapsed ? "h-5" : "h-7 max-w-[150px]")}
+              // The wordmark is black ink on transparent. Inverting luminance
+              // and rotating the hue back lights it up without draining the
+              // colour out of the gopher and the shield.
+              className={cn(
+                "w-auto object-contain transition-all dark:invert 
dark:hue-rotate-180",
+                railCollapsed ? "h-5" : "h-7 max-w-[150px]",
+              )}
             />
           </Link>
         </div>
diff --git a/web/src/index.css b/web/src/index.css
index c3824e8..1d76dd5 100644
--- a/web/src/index.css
+++ b/web/src/index.css
@@ -3,96 +3,112 @@
 
 @custom-variant dark (&:is(.dark *));
 
-/* shadcn's neutral base palette. --primary is a neutral near-black rather than
-   a hue, so the semantic colours below carry all the meaning a page needs.
-   Those three are kept low-chroma on purpose: they are ink for a word or a
-   dot, never a wash behind a panel. */
+/* "Amber & Ink". The palette comes off the casbin mark: the orange star is the
+   primary, the shield green is success, the gopher blue is info. Nothing here
+   is a true neutral — every grey carries a warm hue, so the page reads as 
paper
+   and ink rather than as a default component library. */
 :root {
-  --radius: 0.625rem;
-
-  --background: oklch(1 0 0);
-  --foreground: oklch(0.145 0 0);
-  --card: oklch(1 0 0);
-  --card-foreground: oklch(0.145 0 0);
-  --popover: oklch(1 0 0);
-  --popover-foreground: oklch(0.145 0 0);
-  --primary: oklch(0.205 0 0);
-  --primary-foreground: oklch(0.985 0 0);
-  --secondary: oklch(0.97 0 0);
-  --secondary-foreground: oklch(0.205 0 0);
-  --muted: oklch(0.97 0 0);
-  --muted-foreground: oklch(0.556 0 0);
-  --accent: oklch(0.97 0 0);
-  --accent-foreground: oklch(0.205 0 0);
-  --destructive: oklch(0.577 0.245 27.325);
-  --destructive-foreground: oklch(0.985 0 0);
-  --success: oklch(0.52 0.115 152);
-  --success-foreground: oklch(0.985 0 0);
-  --warning: oklch(0.55 0.115 65);
-  --warning-foreground: oklch(0.985 0 0);
-  --info: oklch(0.52 0.115 248);
-  --info-foreground: oklch(0.985 0 0);
-  --border: oklch(0.922 0 0);
-  --input: oklch(0.922 0 0);
-  --ring: oklch(0.708 0 0);
-
-  --chart-1: oklch(0.646 0.222 41.116);
-  --chart-2: oklch(0.6 0.118 184.704);
-  --chart-3: oklch(0.398 0.07 227.392);
-  --chart-4: oklch(0.828 0.189 84.429);
-  --chart-5: oklch(0.769 0.188 70.08);
-
-  --sidebar: oklch(0.985 0 0);
-  --sidebar-foreground: oklch(0.145 0 0);
-  --sidebar-primary: oklch(0.205 0 0);
-  --sidebar-primary-foreground: oklch(0.985 0 0);
-  --sidebar-accent: oklch(0.97 0 0);
-  --sidebar-accent-foreground: oklch(0.205 0 0);
-  --sidebar-border: oklch(0.922 0 0);
-  --sidebar-ring: oklch(0.708 0 0);
+  --radius: 0.5rem;
+
+  /* Paper, with the card lifted a shade above it: that gap is most of the
+     layering the page needs, so panels can stay nearly shadowless. */
+  --background: oklch(0.974 0.010 83);
+  --foreground: oklch(0.205 0.014 60);
+  --card: oklch(0.999 0.003 85);
+  --card-foreground: oklch(0.205 0.014 60);
+  --popover: oklch(0.999 0.003 85);
+  --popover-foreground: oklch(0.205 0.014 60);
+
+  /* Deep enough to serve as link ink and as a button fill under white. */
+  --primary: oklch(0.545 0.155 48);
+  --primary-foreground: oklch(0.99 0.012 90);
+  --secondary: oklch(0.955 0.014 78);
+  --secondary-foreground: oklch(0.30 0.024 55);
+  --muted: oklch(0.957 0.011 78);
+  --muted-foreground: oklch(0.505 0.020 62);
+  --accent: oklch(0.945 0.028 70);
+  --accent-foreground: oklch(0.33 0.050 48);
+
+  /* Held apart from --primary by hue and chroma, not by lightness alone: these
+     are ink for a word or a dot and often sit in the same row as a link. */
+  --destructive: oklch(0.545 0.205 25);
+  --destructive-foreground: oklch(0.99 0.012 90);
+  --success: oklch(0.505 0.125 150);
+  --success-foreground: oklch(0.99 0.012 90);
+  --warning: oklch(0.545 0.120 90);
+  --warning-foreground: oklch(0.99 0.012 90);
+  --info: oklch(0.520 0.115 235);
+  --info-foreground: oklch(0.99 0.012 90);
+
+  --border: oklch(0.893 0.014 75);
+  --input: oklch(0.878 0.016 75);
+  --ring: oklch(0.545 0.155 48);
+
+  --chart-1: oklch(0.620 0.155 48);
+  --chart-2: oklch(0.580 0.115 200);
+  --chart-3: oklch(0.660 0.130 92);
+  --chart-4: oklch(0.500 0.115 150);
+  --chart-5: oklch(0.520 0.130 300);
+
+  /* The rail is a deeper sheet of the same paper, so it reads as a separate
+     surface without needing a heavy border. */
+  --sidebar: oklch(0.950 0.016 80);
+  --sidebar-foreground: oklch(0.245 0.016 60);
+  --sidebar-primary: oklch(0.545 0.155 48);
+  --sidebar-primary-foreground: oklch(0.99 0.012 90);
+  --sidebar-accent: oklch(0.922 0.032 68);
+  --sidebar-accent-foreground: oklch(0.355 0.085 45);
+  --sidebar-border: oklch(0.886 0.018 75);
+  --sidebar-ring: oklch(0.545 0.155 48);
 }
 
 .dark {
-  --background: oklch(0.145 0 0);
-  --foreground: oklch(0.985 0 0);
-  --card: oklch(0.205 0 0);
-  --card-foreground: oklch(0.985 0 0);
-  --popover: oklch(0.205 0 0);
-  --popover-foreground: oklch(0.985 0 0);
-  --primary: oklch(0.922 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);
-  --destructive: oklch(0.704 0.191 22.216);
-  --destructive-foreground: oklch(0.985 0 0);
-  --success: oklch(0.72 0.105 158);
-  --success-foreground: oklch(0.145 0 0);
-  --warning: oklch(0.78 0.115 72);
-  --warning-foreground: oklch(0.145 0 0);
-  --info: oklch(0.7 0.095 245);
-  --info-foreground: oklch(0.145 0 0);
-  --border: oklch(1 0 0 / 12%);
-  --input: oklch(1 0 0 / 18%);
-  --ring: oklch(0.556 0 0);
-
-  --chart-1: oklch(0.488 0.243 264.376);
-  --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.985 0 0);
-  --sidebar-primary-foreground: oklch(0.205 0 0);
-  --sidebar-accent: oklch(0.269 0 0);
-  --sidebar-accent-foreground: oklch(0.985 0 0);
-  --sidebar-border: oklch(1 0 0 / 12%);
-  --sidebar-ring: oklch(0.556 0 0);
+  /* Warm charcoal, not neutral black: the same hue the light mode uses for 
ink. */
+  --background: oklch(0.175 0.010 62);
+  --foreground: oklch(0.955 0.008 85);
+  --card: oklch(0.218 0.012 62);
+  --card-foreground: oklch(0.955 0.008 85);
+  --popover: oklch(0.228 0.012 62);
+  --popover-foreground: oklch(0.955 0.008 85);
+
+  --primary: oklch(0.735 0.152 58);
+  --primary-foreground: oklch(0.200 0.045 50);
+  --secondary: oklch(0.272 0.014 62);
+  --secondary-foreground: oklch(0.945 0.010 82);
+  --muted: oklch(0.272 0.014 62);
+  --muted-foreground: oklch(0.715 0.016 72);
+  --accent: oklch(0.305 0.028 58);
+  --accent-foreground: oklch(0.930 0.030 72);
+
+  /* Filled semantic chips are a lit swatch with dark ink here — white on a 
warm
+     fill bright enough to read against this background never clears 4.5:1. */
+  --destructive: oklch(0.680 0.180 25);
+  --destructive-foreground: oklch(0.175 0.030 30);
+  --success: oklch(0.735 0.130 152);
+  --success-foreground: oklch(0.175 0.020 150);
+  --warning: oklch(0.785 0.125 92);
+  --warning-foreground: oklch(0.190 0.030 80);
+  --info: oklch(0.720 0.105 235);
+  --info-foreground: oklch(0.175 0.025 240);
+
+  --border: oklch(0.86 0.030 70 / 14%);
+  --input: oklch(0.86 0.030 70 / 20%);
+  --ring: oklch(0.735 0.152 58);
+
+  --chart-1: oklch(0.740 0.155 55);
+  --chart-2: oklch(0.720 0.105 200);
+  --chart-3: oklch(0.800 0.125 92);
+  --chart-4: oklch(0.680 0.115 152);
+  --chart-5: oklch(0.700 0.125 302);
+
+  --sidebar: oklch(0.198 0.011 62);
+  --sidebar-foreground: oklch(0.930 0.010 82);
+  --sidebar-primary: oklch(0.735 0.152 58);
+  --sidebar-primary-foreground: oklch(0.200 0.045 50);
+  --sidebar-accent: oklch(0.312 0.038 55);
+  --sidebar-accent-foreground: oklch(0.900 0.045 72);
+  --sidebar-border: oklch(0.86 0.030 70 / 14%);
+  --sidebar-ring: oklch(0.735 0.152 58);
 }
 
 @theme inline {
@@ -142,7 +158,10 @@
   --color-sidebar-border: var(--sidebar-border);
   --color-sidebar-ring: var(--sidebar-ring);
 
-  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, 
"Helvetica Neue", sans-serif;
+  /* Inter is never fetched, so the CJK faces are what a zh reader actually
+     gets; without them Windows falls back to a mismatched SimSun. */
+  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, 
"Helvetica Neue",
+    "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
   --font-mono: "Cascadia Code", "Fira Mono", Consolas, ui-monospace, monospace;
 }
 
@@ -157,6 +176,18 @@
     @apply bg-background text-foreground antialiased;
     font-feature-settings: "rlig" 1, "calt" 1;
   }
+  ::selection {
+    background-color: color-mix(in oklab, var(--primary) 22%, transparent);
+  }
+  /* Titles set a touch tighter than the body — at these sizes that tracking is
+     most of what separates a heading from bold text. */
+  h1, h2, h3, [data-slot="card-title"], [data-slot="dialog-title"] {
+    letter-spacing: -0.012em;
+  }
+  /* Counts, costs and token totals are read down a column, not across a line. 
*/
+  table {
+    font-variant-numeric: tabular-nums;
+  }
 }
 
 @layer utilities {
@@ -174,9 +205,16 @@
     background-color: var(--border);
     border-radius: 4px;
   }
+  .scrollbar-thin::-webkit-scrollbar-thumb:hover {
+    background-color: color-mix(in oklab, var(--primary) 45%, transparent);
+  }
   .scrollbar-thin::-webkit-scrollbar-track {
     background: transparent;
   }
+  /* Figures that should line up with each other rather than with prose. */
+  .tabular {
+    font-variant-numeric: tabular-nums;
+  }
 }
 
 @keyframes dot-bounce {
diff --git a/web/src/pages/SigninPage.tsx b/web/src/pages/SigninPage.tsx
index f474899..9cf2975 100644
--- a/web/src/pages/SigninPage.tsx
+++ b/web/src/pages/SigninPage.tsx
@@ -99,7 +99,7 @@ export default function SigninPage() {
           <img
             src={`${Setting.StaticBaseUrl}/img/logo_384x96.png`}
             alt="Casbin Gateway"
-            className="h-10 w-auto max-w-[260px] object-contain"
+            className="h-10 w-auto max-w-[260px] object-contain dark:invert 
dark:hue-rotate-180"
           />
         </div>
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to