mirror of
https://github.com/hanzoai/bootnode.git
synced 2026-09-30 20:46:32 +00:00
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]>
249 lines
8.0 KiB
CSS
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);
|
|
}
|