Files
zooqueenandHanzo Dev ab187aa2be Paint the console ground from the chosen theme, not the OS scheme
The @hanzo/gui engine writes --background onto :root and paints <body> from
it with an unlayered rule for prefers-color-scheme, which outranks every
Tailwind layer, so a visitor on a light OS got a light page under dark text.
The app's ground token is --ground, and an unlayered `html body` rule sets
the ground and ink of the scheme the theme provider chose. The d3 charts
read the same token.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-15 12:01:09 -07:00

249 lines
8.0 KiB
CSS

@import "tailwindcss";
@plugin "tailwindcss-animate";
@custom-variant dark (&:is(.dark *));
/* ===========================================================================
DESIGN TOKENS — the lux.cloud design language, expressed once.
Ported from lux/cloud/apps/web/src/styles.css. That file states its palette
as raw literals (#000 / #f5f5f5 / rgba(255,255,255,.08)); here the same
values are the token layer every Tailwind utility already reads, so the
whole app inherits the look without a single page being edited. There is no
second class system — `bg-background`, `border-border`, `text-muted-
foreground` ARE the lux.cloud palette now.
The scheme is dark-first, matching lux.cloud (its <html> ships class="dark"
and `color-scheme: dark`). Light is a faithful inversion, kept because
bootnode ships a theme toggle and dropping it would lose a feature.
=========================================================================== */
@theme inline {
/* Zen, from @hanzo/font — the faces are imported in layout.tsx. */
--font-sans: var(--font-zen-sans);
--font-mono: var(--font-zen-mono);
/* Radii, from lux.cloud's measured geometry: 8px side-nav rows, 10px
buttons/inputs, 16px panels and cards. */
--radius-sm: calc(var(--radius) - 4px); /* 6px */
--radius-md: calc(var(--radius) - 2px); /* 8px */
--radius-lg: var(--radius); /* 10px */
--radius-xl: calc(var(--radius) + 6px); /* 16px — .panel / .card */
/* The page ground is --ground: the @hanzo/gui engine writes its own
--background onto :root for the OS colour scheme, and that one would win. */
--color-background: var(--ground);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-success: var(--success);
--color-warning: var(--warning);
--color-border: var(--border);
--color-border-strong: var(--border-strong);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
--animate-accordion-down: accordion-down 0.2s ease-out;
--animate-accordion-up: accordion-up 0.2s ease-out;
/* Shell geometry — one source of truth for the header/sidebar contract, so
the sidebar's sticky offset can never drift from the header's height. */
--header-h: 57px;
--sidebar-w: 236px;
}
@keyframes accordion-down {
from {
height: 0;
}
to {
height: var(--radix-accordion-content-height);
}
}
@keyframes accordion-up {
from {
height: var(--radix-accordion-content-height);
}
to {
height: 0;
}
}
/* --- light ---------------------------------------------------------------
The inversion of the dark scheme, not a separate design: same hairline
borders, same near-monochrome surfaces, same accent semantics. */
:root {
--radius: 0.625rem; /* 10px */
--ground: #ffffff;
--foreground: #0a0a0a;
--card: #ffffff;
--card-foreground: #0a0a0a;
--popover: #ffffff;
--popover-foreground: #0a0a0a;
--primary: #0a0a0a;
--primary-foreground: #ffffff;
--secondary: #f5f5f5;
--secondary-foreground: #0a0a0a;
--muted: #f5f5f5;
--muted-foreground: rgba(10, 10, 10, 0.55);
--accent: #f2f2f2;
--accent-foreground: #0a0a0a;
--destructive: #d1242f;
--destructive-foreground: #ffffff;
--success: #1a7f37;
--warning: #9a6700;
--border: rgba(0, 0, 0, 0.1);
--border-strong: rgba(0, 0, 0, 0.22);
--input: rgba(0, 0, 0, 0.16);
--ring: rgba(0, 0, 0, 0.4);
--chart-1: #0a0a0a;
--chart-2: #525252;
--chart-3: #737373;
--chart-4: #a3a3a3;
--chart-5: #d4d4d4;
--sidebar: #ffffff;
--sidebar-foreground: #0a0a0a;
--sidebar-primary: #0a0a0a;
--sidebar-primary-foreground: #ffffff;
--sidebar-accent: #f2f2f2;
--sidebar-accent-foreground: #0a0a0a;
--sidebar-border: rgba(0, 0, 0, 0.1);
--sidebar-ring: rgba(0, 0, 0, 0.4);
}
/* --- dark (the lux.cloud scheme, verbatim) -------------------------------
Pure black ground, #f5f5f5 ink, 55% muted, 8% hairline / 18% strong border,
#1a1a1a active fill, and lux.cloud's status greens/ambers/reds. */
.dark {
--ground: #000000;
--foreground: #f5f5f5;
--card: #000000;
--card-foreground: #f5f5f5;
/* Popovers/menus sit ON the black ground, so they lift to #0a0a0a — the same
one-step lift lux.cloud gives .try-lux-panel and .org-menu. */
--popover: #0a0a0a;
--popover-foreground: #f5f5f5;
--primary: #f5f5f5;
--primary-foreground: #000000;
--secondary: #0a0a0a;
--secondary-foreground: #f5f5f5;
--muted: #0a0a0a;
--muted-foreground: rgba(245, 245, 245, 0.55);
--accent: #1a1a1a;
--accent-foreground: #f5f5f5;
--destructive: #ff7b72;
--destructive-foreground: #000000;
--success: #3fb950;
--warning: #d29922;
--border: rgba(255, 255, 255, 0.08);
--border-strong: rgba(255, 255, 255, 0.18);
--input: rgba(255, 255, 255, 0.18);
--ring: rgba(245, 245, 245, 0.6);
--chart-1: #f5f5f5;
--chart-2: #a8a8ff;
--chart-3: #8bffd1;
--chart-4: #ffd18b;
--chart-5: #ff8bc0;
--sidebar: #000000;
--sidebar-foreground: #f5f5f5;
--sidebar-primary: #f5f5f5;
--sidebar-primary-foreground: #000000;
--sidebar-accent: #1a1a1a;
--sidebar-accent-foreground: #f5f5f5;
--sidebar-border: rgba(255, 255, 255, 0.08);
--sidebar-ring: rgba(245, 245, 245, 0.6);
}
@layer base {
* {
@apply border-border outline-ring/50;
}
html {
color-scheme: light;
}
html.dark {
color-scheme: dark;
}
body {
@apply bg-background text-foreground;
/* lux.cloud's type voice: 1.5 leading, -0.01em tracking, no synthetic
weights, smoothed. */
line-height: 1.5;
letter-spacing: -0.01em;
font-synthesis-weight: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
}
/* Display type. lux.cloud sizes its headings with clamp() so a 40px h1 does
not eat a third of a 390px phone; the same curve applies here to every
heading rather than page by page. Tailwind's text-* utilities still win
wherever a page sets one explicitly. */
h1 {
font-size: clamp(1.75rem, 5.5vw, 2.5rem);
letter-spacing: -0.02em;
line-height: 1.1;
}
h2 {
letter-spacing: -0.02em;
}
.container {
margin-inline: auto;
width: 100%;
max-width: 1400px;
padding-inline: 2rem;
}
}
@layer components {
/* The console's horizontal section strip below the sidebar breakpoint hides
its scrollbar (lux.cloud does the same) — the active row is scrolled into
view instead, so the affordance is position, not a scrollbar. */
.no-scrollbar {
scrollbar-width: none;
}
.no-scrollbar::-webkit-scrollbar {
display: none;
}
}
/* The @hanzo/gui engine paints <body> from its own palette for the OS colour
scheme with an unlayered rule, and an unlayered rule outranks every layer
above. This one is unlayered too and more specific, so the page takes the
ground and ink of the scheme the theme provider chose. */
html body {
background: var(--ground);
color: var(--foreground);
}