One of four divergent candidates for the operator/console theme family (successor to Skyrise for developer-product screens). Dense/pro type register, keyboard-first focus treatment, tabular numerals, coarse-pointer 44px touch floor, neutral code chips, dark card separation per house sweep. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
421 lines
16 KiB
CSS
421 lines
16 KiB
CSS
/*
|
|
* Blueprint — technical drawing.
|
|
*
|
|
* Light-first: a near-achromatic drafting-paper field (whisper of cool at
|
|
* hue 240, chroma ≤0.005 — the paper is calm gray; the BLUE lives in the ink
|
|
* and the accent, never washed into the field) carrying pure-white cards,
|
|
* with deep NAVY ink — the ink is navy, that is the signature. Hairline RULES are the organizing metaphor:
|
|
* borders sit slightly more present than usual (ink at ~0.17 alpha) and
|
|
* elevation stays minimal — surfaces separate by rule lines like a technical
|
|
* drawing, not by shadow. One azure accent (hue ~232) owns primary, links, and
|
|
* focus; the info status is pushed to violet (hue 285) so the two never read
|
|
* as the same swatch.
|
|
*
|
|
* Dark mode is the iconic inversion: THE DARK MODE IS THE BLUEPRINT. A deep
|
|
* drafting-blue field (low-chroma navy, hue 258 — unmistakably blue-leaning
|
|
* but calm), near-white blue-tinted ink, cards stepping a full lightness step
|
|
* above the field, and the azure accent turned luminous cyan with dark ink.
|
|
*
|
|
* Type is technical: Space Grotesk for headings (geometric, drafting-title),
|
|
* Inter for body, JetBrains Mono for code. Dense/pro register — 0.9375rem
|
|
* body, fixed rem sizes. Radius is a sharp 0.375rem; motion is precise
|
|
* (120/220/320/450ms) with springs aliased to the standard eases. Tables get
|
|
* tabular numerals — drafting tables demand aligned digits.
|
|
*
|
|
* Token contract matches lib-theme-caffe-florian/theme.css (Crema v1).
|
|
*/
|
|
|
|
/*
|
|
* Fonts: consuming apps load Space Grotesk + Inter + JetBrains Mono at the top
|
|
* of their entry CSS (where @import statements are allowed), via the Google
|
|
* Fonts URL documented in this theme's README. Embedding the @import here — or
|
|
* smuggling the URL in a comment for a build script to lift — breaks PostCSS's
|
|
* ordering rules, so neither is done in this file.
|
|
*/
|
|
|
|
:root {
|
|
--font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
--font-heading: "Space Grotesk", "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
|
|
--font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
|
|
|
/* Tailwind utility families. Distinct names so a consuming app's
|
|
* `@theme inline` can indirect to these (--font-heading/--font-sans collide
|
|
* with Tailwind's own font-* namespace). Mirror --font-heading/--font-sans. */
|
|
--heading-family: "Space Grotesk", "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
|
|
--body-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
|
|
/* ── Colors ── cool drafting-paper field, pure-white cards, deep navy ink,
|
|
* one azure accent. Rules do the separating; shadow stays out of it. */
|
|
--background: oklch(0.966 0.0035 240);
|
|
--foreground: oklch(0.23 0.045 258);
|
|
|
|
--card: oklch(1 0 0);
|
|
--card-foreground: oklch(0.23 0.045 258);
|
|
|
|
--popover: oklch(0.995 0.003 240);
|
|
--popover-foreground: oklch(0.23 0.045 258);
|
|
|
|
/* Primary — the azure of the drawing's live line (hue 232, L0.49), deep
|
|
* enough to carry a near-white label at ~6:1. Spent on the primary action,
|
|
* links, selection, and focus; nowhere else. */
|
|
--primary: oklch(0.49 0.13 232);
|
|
--primary-foreground: oklch(0.98 0.008 232);
|
|
|
|
--secondary: oklch(0.93 0.005 240);
|
|
--secondary-foreground: oklch(0.29 0.04 258);
|
|
|
|
--muted: oklch(0.93 0.0045 240);
|
|
--muted-foreground: oklch(0.45 0.03 255);
|
|
|
|
/* Accent — hover/selection tint: a pale azure wash with deep azure ink,
|
|
* not a second competing fill. */
|
|
--accent: oklch(0.925 0.028 232);
|
|
--accent-foreground: oklch(0.37 0.09 235);
|
|
|
|
/* ── Status ── deep fills with light labels for red/violet, bright fills
|
|
* with dark ink for green/amber. Info is pushed to VIOLET (hue 285) so it
|
|
* can never be mistaken for the azure primary (hue 232). */
|
|
--destructive: oklch(0.54 0.21 27);
|
|
--destructive-foreground: oklch(0.98 0.01 27);
|
|
--success: oklch(0.52 0.13 155);
|
|
--success-foreground: oklch(0.98 0.01 155);
|
|
--warning: oklch(0.76 0.15 78);
|
|
--warning-foreground: oklch(0.24 0.05 78);
|
|
--info: oklch(0.5 0.13 285);
|
|
--info-foreground: oklch(0.98 0.01 285);
|
|
|
|
/* Hairline rules — the theme's organizing metaphor. Navy ink at a slightly
|
|
* higher alpha than house-usual so every rule reads on the paper. */
|
|
--border: oklch(0.23 0.045 258 / 0.17);
|
|
--input: oklch(0.23 0.045 258 / 0.2);
|
|
--ring: oklch(0.49 0.13 232 / 0.6);
|
|
|
|
/* Chart palette — azure lead, then spaced drafting-ink hues (violet, red,
|
|
* amber, teal-green); hues ≥60° apart, adjacent lightness varied. */
|
|
--chart-1: oklch(0.55 0.13 235);
|
|
--chart-2: oklch(0.55 0.14 300);
|
|
--chart-3: oklch(0.62 0.17 25);
|
|
--chart-4: oklch(0.75 0.14 85);
|
|
--chart-5: oklch(0.66 0.11 165);
|
|
|
|
--sidebar: oklch(0.945 0.004 240);
|
|
--sidebar-foreground: oklch(0.23 0.045 258);
|
|
--sidebar-primary: oklch(0.49 0.13 232);
|
|
--sidebar-primary-foreground: oklch(0.98 0.008 232);
|
|
--sidebar-accent: oklch(0.925 0.028 232);
|
|
--sidebar-accent-foreground: oklch(0.37 0.09 235);
|
|
--sidebar-border: oklch(0.23 0.045 258 / 0.13);
|
|
--sidebar-ring: oklch(0.49 0.13 232 / 0.6);
|
|
|
|
/* Syntax — muted-precise: navy-family base with disciplined accents. */
|
|
--syntax-keyword: oklch(0.44 0.12 285);
|
|
--syntax-string: oklch(0.45 0.1 165);
|
|
--syntax-number: oklch(0.48 0.11 60);
|
|
--syntax-comment: oklch(0.55 0.02 250);
|
|
--syntax-function: oklch(0.45 0.13 235);
|
|
--syntax-type: oklch(0.45 0.09 200);
|
|
|
|
/* ── Chat surfaces ──
|
|
* Contract for lib-agent-chat-ui / lib-agent-dock-ui. User bubble is a
|
|
* deep navy-ink panel with light text (the drawing's title block);
|
|
* assistant bubble is a clean card with a hairline rule. */
|
|
--chat-user-bg: oklch(0.28 0.05 258);
|
|
--chat-user-fg: oklch(0.97 0.006 240);
|
|
--chat-assistant-bg: oklch(1 0 0);
|
|
--chat-assistant-fg: oklch(0.23 0.045 258);
|
|
--chat-assistant-border: oklch(0.23 0.045 258 / 0.17);
|
|
|
|
/* Sharp drafting radius. */
|
|
--radius: 0.375rem;
|
|
|
|
/* ── Motion ── precise, instrument-quick. Springs alias to the standard
|
|
* eases — a drawing never bounces. */
|
|
--duration-fast: 120ms;
|
|
--duration-base: 220ms;
|
|
--duration-slow: 320ms;
|
|
--duration-slower: 450ms;
|
|
--duration-spring: 220ms;
|
|
|
|
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
|
--ease-decelerate: cubic-bezier(0, 0, 0, 1);
|
|
--ease-accelerate: cubic-bezier(0.3, 0, 1, 1);
|
|
--ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
|
|
|
|
--ease-spring-gentle: var(--ease-standard);
|
|
--ease-spring-snappy: var(--ease-decelerate);
|
|
--ease-spring-bouncy: var(--ease-standard);
|
|
|
|
/* ── Typography ── dense/pro register, fixed rem, full role ramp. */
|
|
--text-hero-size: 3rem;
|
|
--text-hero-lh: 1.05;
|
|
--text-display-size: 2.25rem;
|
|
--text-display-lh: 1.1;
|
|
--text-headline-size: 1.625rem;
|
|
--text-headline-lh: 1.25;
|
|
--text-title-size: 1.25rem;
|
|
--text-title-lh: 1.35;
|
|
--text-subtitle-size: 1.0625rem;
|
|
--text-subtitle-lh: 1.45;
|
|
--text-body-size: 0.9375rem;
|
|
--text-body-lh: 1.5;
|
|
--text-label-size: 0.8125rem;
|
|
--text-label-lh: 1.125rem;
|
|
--text-caption-size: 0.75rem;
|
|
--text-caption-lh: 1.0625rem;
|
|
|
|
/* ── Elevation ── minimal on purpose — rule lines do the separating.
|
|
* Popovers and modals get just enough lift to read as floating. */
|
|
--elevation-0: none;
|
|
--elevation-1: 0 1px 1px oklch(0.23 0.045 258 / 0.04);
|
|
--elevation-2: 0 1px 2px oklch(0.23 0.045 258 / 0.06);
|
|
--elevation-3: 0 2px 6px -1px oklch(0.23 0.045 258 / 0.08), 0 1px 2px oklch(0.23 0.045 258 / 0.05);
|
|
--elevation-4: 0 8px 16px -4px oklch(0.23 0.045 258 / 0.1), 0 2px 4px -2px oklch(0.23 0.045 258 / 0.06);
|
|
--elevation-5: 0 16px 32px -8px oklch(0.23 0.045 258 / 0.14);
|
|
|
|
--spacing: 0.25rem;
|
|
|
|
--border-width-thin: 0.5px;
|
|
--border-width-base: 1px;
|
|
--border-width-thick: 2px;
|
|
--border-width-heavy: 4px;
|
|
|
|
/* No glass — inert values so consuming apps referencing these get no-ops. */
|
|
--glass-blur: 0px;
|
|
--glass-saturate: 100%;
|
|
--glass-brightness: 1;
|
|
--glass-contrast: 1;
|
|
}
|
|
|
|
/*
|
|
* Dark mode — THE BLUEPRINT. Deep drafting-blue field (low-chroma navy,
|
|
* hue 258 — blue-leaning but calm, never electric), near-white blue-tinted
|
|
* ink, cards stepping a full lightness step above the field, and the accent
|
|
* turned luminous cyan carrying dark ink.
|
|
*/
|
|
.dark {
|
|
--background: oklch(0.21 0.035 258);
|
|
--foreground: oklch(0.95 0.012 240);
|
|
|
|
--card: oklch(0.26 0.035 258);
|
|
--card-foreground: oklch(0.95 0.012 240);
|
|
|
|
--popover: oklch(0.28 0.035 258);
|
|
--popover-foreground: oklch(0.95 0.012 240);
|
|
|
|
/* Primary — the luminous cyan line on the blueprint, dark navy ink on
|
|
* top (bright-swatch/dark-ink pairing, ~9:1). */
|
|
--primary: oklch(0.78 0.12 220);
|
|
--primary-foreground: oklch(0.2 0.04 230);
|
|
|
|
--secondary: oklch(0.3 0.035 258);
|
|
--secondary-foreground: oklch(0.9 0.012 240);
|
|
|
|
--muted: oklch(0.3 0.035 258);
|
|
--muted-foreground: oklch(0.72 0.02 245);
|
|
|
|
--accent: oklch(0.34 0.06 230);
|
|
--accent-foreground: oklch(0.85 0.09 215);
|
|
|
|
--destructive: oklch(0.55 0.2 27);
|
|
--destructive-foreground: oklch(0.98 0.01 27);
|
|
--success: oklch(0.72 0.14 155);
|
|
--success-foreground: oklch(0.18 0.04 155);
|
|
--warning: oklch(0.78 0.15 80);
|
|
--warning-foreground: oklch(0.22 0.05 80);
|
|
--info: oklch(0.7 0.12 285);
|
|
--info-foreground: oklch(0.17 0.04 285);
|
|
|
|
/* Rules invert: light ink hairlines on the blueprint field. */
|
|
--border: oklch(0.95 0.012 240 / 0.15);
|
|
--input: oklch(0.95 0.012 240 / 0.18);
|
|
--ring: oklch(0.78 0.12 220 / 0.55);
|
|
|
|
--chart-1: oklch(0.72 0.12 220);
|
|
--chart-2: oklch(0.66 0.13 300);
|
|
--chart-3: oklch(0.7 0.16 25);
|
|
--chart-4: oklch(0.8 0.13 85);
|
|
--chart-5: oklch(0.74 0.11 165);
|
|
|
|
--sidebar: oklch(0.23 0.035 258);
|
|
--sidebar-foreground: oklch(0.95 0.012 240);
|
|
--sidebar-primary: oklch(0.78 0.12 220);
|
|
--sidebar-primary-foreground: oklch(0.2 0.04 230);
|
|
--sidebar-accent: oklch(0.34 0.06 230);
|
|
--sidebar-accent-foreground: oklch(0.85 0.09 215);
|
|
--sidebar-border: oklch(0.95 0.012 240 / 0.11);
|
|
--sidebar-ring: oklch(0.78 0.12 220 / 0.55);
|
|
|
|
--syntax-keyword: oklch(0.74 0.12 300);
|
|
--syntax-string: oklch(0.76 0.11 165);
|
|
--syntax-number: oklch(0.8 0.12 75);
|
|
--syntax-comment: oklch(0.62 0.02 250);
|
|
--syntax-function: oklch(0.76 0.11 220);
|
|
--syntax-type: oklch(0.74 0.09 195);
|
|
|
|
/* ── Chat surfaces (dark) ── */
|
|
--chat-user-bg: oklch(0.33 0.05 252);
|
|
--chat-user-fg: oklch(0.96 0.01 240);
|
|
--chat-assistant-bg: oklch(0.26 0.035 258);
|
|
--chat-assistant-fg: oklch(0.95 0.012 240);
|
|
--chat-assistant-border: oklch(0.95 0.012 240 / 0.15);
|
|
|
|
--elevation-1: 0 1px 1px oklch(0 0 0 / 0.25);
|
|
--elevation-2: 0 1px 2px oklch(0 0 0 / 0.3);
|
|
--elevation-3: 0 2px 6px -1px oklch(0 0 0 / 0.35), 0 1px 2px oklch(0 0 0 / 0.2);
|
|
--elevation-4: 0 8px 16px -4px oklch(0 0 0 / 0.4), 0 2px 4px -2px oklch(0 0 0 / 0.22);
|
|
--elevation-5: 0 16px 32px -8px oklch(0 0 0 / 0.5);
|
|
}
|
|
|
|
/*
|
|
* @layer base — Blueprint's precise, rule-lined drafting philosophy.
|
|
*
|
|
* No glass, no flourish. Geometric headings, hairline rules doing the
|
|
* separating, tabular digits in tables, and the azure line reserved for
|
|
* focus, selection, links, and the primary action.
|
|
*/
|
|
@layer base {
|
|
body {
|
|
min-height: 100vh;
|
|
-webkit-font-smoothing: antialiased;
|
|
-moz-osx-font-smoothing: grayscale;
|
|
letter-spacing: -0.004em;
|
|
font-family: var(--font-sans);
|
|
font-size: var(--text-body-size);
|
|
line-height: var(--text-body-lh);
|
|
}
|
|
|
|
/* Headings — Space Grotesk, geometric and technical. */
|
|
h1, h2, h3, h4,
|
|
[data-slot="card-title"],
|
|
[data-slot="dialog-title"],
|
|
[data-slot="sheet-title"],
|
|
[data-slot="alert-dialog-title"] {
|
|
font-family: var(--font-heading);
|
|
font-weight: 600;
|
|
letter-spacing: -0.015em;
|
|
color: var(--foreground);
|
|
}
|
|
|
|
code, kbd, samp, pre,
|
|
[data-slot="code"],
|
|
[data-slot="code-block"] {
|
|
font-family: var(--font-mono);
|
|
}
|
|
|
|
/* Inline code — neutral ink chip, never accent-colored. */
|
|
:not(pre) > code {
|
|
padding: 0.1em 0.35em;
|
|
border-radius: calc(var(--radius) * 0.5);
|
|
background: color-mix(in oklch, var(--foreground) 7%, transparent);
|
|
color: var(--foreground);
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
/* Selection — the azure line. */
|
|
::selection {
|
|
background: color-mix(in oklch, var(--primary) 28%, transparent);
|
|
color: var(--foreground);
|
|
}
|
|
|
|
/* Links — azure, underline-on-hover. */
|
|
a {
|
|
color: color-mix(in oklch, var(--primary) 75%, var(--foreground));
|
|
text-decoration-color: color-mix(in oklch, var(--primary) 40%, transparent);
|
|
text-underline-offset: 0.2em;
|
|
transition: text-decoration-color var(--duration-fast) var(--ease-standard);
|
|
}
|
|
a:hover {
|
|
text-decoration-color: var(--primary);
|
|
}
|
|
|
|
[data-slot="sidebar"] {
|
|
background: var(--sidebar);
|
|
border-right: var(--border-width-base) solid var(--sidebar-border);
|
|
}
|
|
|
|
/* Drafting tables demand aligned digits — tabular numerals on every
|
|
* table, and a .num utility for any numeric cell/stat elsewhere. */
|
|
[data-slot="table"],
|
|
.num {
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Focus-visible — keyboard-first is a Blueprint signature. A crisp,
|
|
* always-visible azure outline, offset (not inset). Placed outside
|
|
* @layer base so it beats Tailwind's default ring utilities.
|
|
*/
|
|
[data-slot="button"]:focus-visible,
|
|
[data-slot="input"]:focus-visible,
|
|
[data-slot="textarea"]:focus-visible,
|
|
[data-slot="select-trigger"]:focus-visible {
|
|
outline: 2px solid var(--primary);
|
|
outline-offset: 2px;
|
|
box-shadow: none;
|
|
}
|
|
|
|
/* Buttons — quiet weight; opacity absorb on press, instrument-quick. */
|
|
[data-slot="button"] {
|
|
font-weight: 500;
|
|
letter-spacing: -0.004em;
|
|
}
|
|
|
|
/* Card titles — pinned to the subtitle role so the scale is the theme's
|
|
* decision, not the card primitive's default. */
|
|
[data-slot="card-title"] {
|
|
font-size: var(--text-subtitle-size);
|
|
line-height: var(--text-subtitle-lh);
|
|
}
|
|
|
|
/* Touch targets — desktop keeps the dense drafting ladder; coarse pointers
|
|
* get the 44px floor on every control. */
|
|
@media (pointer: coarse) {
|
|
[data-slot="button"] {
|
|
min-height: 2.75rem;
|
|
min-width: 2.75rem;
|
|
}
|
|
[data-slot="input"],
|
|
[data-slot="select-trigger"] {
|
|
min-height: 2.75rem;
|
|
}
|
|
}
|
|
[data-slot="button"]:hover:not(:disabled) {
|
|
opacity: 0.9;
|
|
}
|
|
[data-slot="button"]:active:not(:disabled) {
|
|
opacity: 0.82;
|
|
transform: scale(0.99);
|
|
}
|
|
|
|
/* Inputs — clean card surface, hairline rule, azure focus as a flush
|
|
* 1px ring plus border-color change. */
|
|
[data-slot="input"],
|
|
[data-slot="textarea"],
|
|
[data-slot="select-trigger"] {
|
|
background: var(--card);
|
|
border: var(--border-width-base) solid var(--input);
|
|
border-radius: var(--radius);
|
|
color: var(--foreground);
|
|
transition:
|
|
border-color var(--duration-fast) var(--ease-standard),
|
|
box-shadow var(--duration-fast) var(--ease-standard);
|
|
}
|
|
[data-slot="input"]::placeholder,
|
|
[data-slot="textarea"]::placeholder {
|
|
color: var(--muted-foreground);
|
|
opacity: 0.8;
|
|
}
|
|
[data-slot="input"]:hover:not(:disabled),
|
|
[data-slot="textarea"]:hover:not(:disabled),
|
|
[data-slot="select-trigger"]:hover:not(:disabled) {
|
|
border-color: color-mix(in oklch, var(--foreground) 30%, transparent);
|
|
}
|
|
[data-slot="input"]:focus,
|
|
[data-slot="textarea"]:focus,
|
|
[data-slot="select-trigger"]:focus {
|
|
border-color: var(--primary);
|
|
box-shadow: 0 0 0 1px var(--primary);
|
|
outline: none;
|
|
}
|