/* * Oat — warm greige, cozy-neutral theme. Oat, driftwood, mushroom, raw linen. * * The thesis: a genuinely NEUTRAL, calm consumer surface that still has warmth * and material character. The neutral is a real GREIGE mid-tone (grey-warm), * not a pale near-white and not a drenched color field. Built for an everyday * personal-cloud utility that should feel grounded and tactile, never loud. * * Escape from the "AI cream" band (L 0.84–0.97, warm chroma, hue 40–100) is by * DEPTH + restraint, not by picking a different hue: the body background sits at * a noticeably lower lightness (L≈0.91) with very low warm chroma (≈0.009, hue * ~78), so it reads as a soft grey-warm "oat" surface rather than a bright cream. * Cards step UP to a warm near-white (L≈0.975) so the card-on-field separation * is clearly visible and does real hierarchy work — that visible step is the * theme's premium tell. Ink is a warm charcoal-taupe. The accent is a soft, * muted clay-rose coral (hue ~35), spent surgically on the primary action, * selection and focus; a muted slate-blue is the single cool counterpoint (info). * * Dark mode is "oats at night": a warm dark taupe-charcoal (low chroma, warm * hue ~70, deep but not pure black and never blue-gray), cards stepping lighter * like firelight on material, the coral brightened, dark-ink-on-bright per the * contract's contrast pattern. * * Token contract: Crema v1 (create-crema-app/TOKEN_CONTRACT.md). */ /* * Fonts: consuming apps load Hanken Grotesk + Fraunces + 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 when the theme is imported after other statements, so neither * is done in this file. */ :root { --font-sans: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; --font-heading: "Fraunces", "Hanken Grotesk", Georgia, serif; --font-mono: "JetBrains Mono", ui-monospace, 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: "Fraunces", "Hanken Grotesk", Georgia, serif; --body-family: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; /* ── Colors ── greige mid-tone field, warm near-white cards, warm * charcoal-taupe ink, muted clay-rose coral accent. */ /* Body field: a genuine grey-warm "oat", noticeably below cream lightness. */ --background: oklch(0.91 0.009 78); --foreground: oklch(0.24 0.012 55); /* Cards step UP toward warm near-white — the visible card-on-field step. */ --card: oklch(0.975 0.006 82); --card-foreground: oklch(0.24 0.012 55); --popover: oklch(0.98 0.005 82); --popover-foreground: oklch(0.24 0.012 55); /* Primary: muted clay-rose coral. Deep enough that warm-white text clears * the 4.5:1 floor (white-on-mid-coral usually misses; this is L≈0.55). */ --primary: oklch(0.55 0.15 35); --primary-foreground: oklch(0.99 0.01 60); /* Secondary / muted: a soft greige a step below the field. */ --secondary: oklch(0.86 0.014 75); --secondary-foreground: oklch(0.3 0.012 55); --muted: oklch(0.86 0.012 78); --muted-foreground: oklch(0.44 0.012 60); /* Accent: a pale coral wash carrying deep-coral ink. */ --accent: oklch(0.88 0.03 32); --accent-foreground: oklch(0.4 0.12 32); /* Status quartet — kept clearly distinct from the muted coral primary: * destructive is a hotter, higher-chroma true red; success sage-green; * warning amber; info the cool slate-blue counterpoint. */ --destructive: oklch(0.55 0.21 25); --destructive-foreground: oklch(0.99 0.01 60); --success: oklch(0.57 0.12 150); --success-foreground: oklch(0.14 0.04 150); --warning: oklch(0.76 0.13 75); --warning-foreground: oklch(0.24 0.04 75); --info: oklch(0.52 0.12 245); --info-foreground: oklch(0.99 0.01 60); --border: oklch(0.24 0.012 55 / 0.14); --input: oklch(0.24 0.012 55 / 0.14); --ring: oklch(0.55 0.15 35 / 0.5); /* Chart palette — cozy-neutral swatches: clay coral / sage / slate-blue / * amber / mauve. Hues ≥60° apart, adjacent-index lightness alternated. */ --chart-1: oklch(0.62 0.13 35); --chart-2: oklch(0.68 0.09 150); --chart-3: oklch(0.6 0.1 245); --chart-4: oklch(0.78 0.1 75); --chart-5: oklch(0.7 0.07 320); --sidebar: oklch(0.89 0.011 78); --sidebar-foreground: oklch(0.24 0.012 55); --sidebar-primary: oklch(0.55 0.15 35); --sidebar-primary-foreground: oklch(0.99 0.01 60); --sidebar-accent: oklch(0.88 0.03 32); --sidebar-accent-foreground: oklch(0.4 0.12 32); --sidebar-border: oklch(0.24 0.012 55 / 0.1); --sidebar-ring: oklch(0.55 0.15 35 / 0.5); /* Syntax (Tier 2) — warm-neutral code palette. */ --syntax-keyword: oklch(0.5 0.14 35); --syntax-string: oklch(0.5 0.1 150); --syntax-number: oklch(0.54 0.12 75); --syntax-comment: oklch(0.55 0.008 78); --syntax-function: oklch(0.5 0.12 245); --syntax-type: oklch(0.52 0.08 200); /* ── Chat surfaces ── * Contract for lib-agent-chat-ui / lib-agent-dock-ui. User bubble is a * filled deep-coral panel with warm-white text; assistant bubble is a * card-like warm-white surface with a hairline border. */ --chat-user-bg: oklch(0.5 0.14 35); --chat-user-fg: oklch(0.99 0.01 60); --chat-assistant-bg: oklch(0.975 0.006 82); --chat-assistant-fg: oklch(0.24 0.012 55); --chat-assistant-border: oklch(0.24 0.012 55 / 0.12); /* Soft-friendly radius. */ --radius: 1rem; /* ── Motion ── calm-buoyant, base ~300ms. Springs are real, gently damped. */ --duration-fast: 160ms; --duration-base: 300ms; --duration-slow: 450ms; --duration-slower: 600ms; --duration-spring: 500ms; --ease-standard: cubic-bezier(0.25, 0.1, 0.25, 1); --ease-decelerate: cubic-bezier(0, 0, 0.2, 1); --ease-accelerate: cubic-bezier(0.4, 0, 1, 1); --ease-spring-gentle: linear(0, 0.04 8%, 0.12 15%, 0.23 22%, 0.37 30%, 0.51 38%, 0.63 46%, 0.74 54%, 0.83 62%, 0.89 70%, 0.94 78%, 0.97 86%, 0.99 94%, 1); --ease-spring-snappy: linear(0, 0.06 6%, 0.18 12%, 0.33 18%, 0.5 25%, 0.65 32%, 0.8 40%, 0.9 48%, 0.98 56%, 1.015 64%, 1.02 72%, 1.015 80%, 1.005 88%, 1); --ease-spring-bouncy: linear(0, 0.08 8%, 0.22 16%, 0.4 24%, 0.58 32%, 0.75 40%, 0.88 48%, 0.98 56%, 1.04 64%, 1.06 72%, 1.04 80%, 1.01 86%, 0.995 92%, 1); /* Emphasized moments settle with the gentle spring. */ --ease-emphasized: var(--ease-spring-gentle); /* ── Typography ── product register, fixed rem, full role ramp. * Warm-humanist and cozy but crisp: Fraunces headings, Hanken Grotesk body. */ --text-hero-size: 3.5rem; --text-hero-lh: 1.05; --text-display-size: 3rem; --text-display-lh: 1.1; --text-headline-size: 2rem; --text-headline-lh: 1.2; --text-title-size: 1.5rem; --text-title-lh: 1.3; --text-subtitle-size: 1.25rem; --text-subtitle-lh: 1.5; --text-body-size: 1.0625rem; --text-body-lh: 1.65; --text-label-size: 0.9375rem; --text-label-lh: 1.25rem; --text-caption-size: 0.8125rem; --text-caption-lh: 1.125rem; /* ── Elevation ── soft warm-grey diffuse shadows, derived from the warm * ink at low alpha. Gentle, tactile, never a hard drop. */ --elevation-0: none; --elevation-1: 0 1px 2px oklch(0.24 0.012 55 / 0.05); --elevation-2: 0 1px 3px oklch(0.24 0.012 55 / 0.07), 0 1px 2px oklch(0.24 0.012 55 / 0.04); --elevation-3: 0 4px 12px -3px oklch(0.24 0.012 55 / 0.08), 0 2px 6px -3px oklch(0.24 0.012 55 / 0.05); --elevation-4: 0 12px 28px -6px oklch(0.24 0.012 55 / 0.1), 0 6px 12px -6px oklch(0.24 0.012 55 / 0.05); --elevation-5: 0 24px 48px -10px oklch(0.24 0.012 55 / 0.16); --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 — "oats at night". Warm dark taupe-charcoal (L≈0.20, hue ~70), deep * but not pure black and not blue-gray. Cards step LIGHTER (firelight on * material). Coral brightens; status foregrounds go dark-ink-on-bright. */ .dark { --background: oklch(0.2 0.008 70); --foreground: oklch(0.92 0.01 82); --card: oklch(0.26 0.009 70); --card-foreground: oklch(0.92 0.01 82); --popover: oklch(0.275 0.009 70); --popover-foreground: oklch(0.92 0.01 82); --primary: oklch(0.68 0.14 38); --primary-foreground: oklch(0.2 0.03 38); --secondary: oklch(0.28 0.008 70); --secondary-foreground: oklch(0.9 0.01 82); --muted: oklch(0.28 0.008 70); --muted-foreground: oklch(0.71 0.011 80); --accent: oklch(0.32 0.05 35); --accent-foreground: oklch(0.85 0.08 38); --destructive: oklch(0.65 0.2 28); --destructive-foreground: oklch(0.18 0.03 28); --success: oklch(0.68 0.14 150); --success-foreground: oklch(0.18 0.03 150); --warning: oklch(0.8 0.13 75); --warning-foreground: oklch(0.22 0.04 75); --info: oklch(0.7 0.12 245); --info-foreground: oklch(0.16 0.03 245); --border: oklch(0.92 0.01 82 / 0.12); --input: oklch(0.92 0.01 82 / 0.12); --ring: oklch(0.68 0.14 38 / 0.5); --chart-1: oklch(0.72 0.13 38); --chart-2: oklch(0.74 0.09 150); --chart-3: oklch(0.7 0.1 245); --chart-4: oklch(0.82 0.1 75); --chart-5: oklch(0.76 0.07 320); --sidebar: oklch(0.22 0.008 70); --sidebar-foreground: oklch(0.92 0.01 82); --sidebar-primary: oklch(0.68 0.14 38); --sidebar-primary-foreground: oklch(0.2 0.03 38); --sidebar-accent: oklch(0.32 0.05 35); --sidebar-accent-foreground: oklch(0.85 0.08 38); --sidebar-border: oklch(0.92 0.01 82 / 0.08); --sidebar-ring: oklch(0.68 0.14 38 / 0.5); --syntax-keyword: oklch(0.75 0.13 38); --syntax-string: oklch(0.74 0.12 150); --syntax-number: oklch(0.8 0.12 75); --syntax-comment: oklch(0.55 0.008 78); --syntax-function: oklch(0.72 0.12 245); --syntax-type: oklch(0.72 0.08 200); /* ── Chat surfaces (dark) ── */ --chat-user-bg: oklch(0.55 0.15 38); --chat-user-fg: oklch(0.99 0.01 60); --chat-assistant-bg: oklch(0.26 0.009 70); --chat-assistant-fg: oklch(0.92 0.01 82); --chat-assistant-border: oklch(0.92 0.01 82 / 0.12); /* Deep warm shadows for the night palette. */ --elevation-1: 0 1px 2px oklch(0 0 0 / 0.3); --elevation-2: 0 1px 3px oklch(0 0 0 / 0.4), 0 1px 2px oklch(0 0 0 / 0.25); --elevation-3: 0 4px 12px -3px oklch(0 0 0 / 0.4), 0 2px 6px -3px oklch(0 0 0 / 0.28); --elevation-4: 0 12px 28px -6px oklch(0 0 0 / 0.45), 0 6px 12px -6px oklch(0 0 0 / 0.3); --elevation-5: 0 24px 48px -10px oklch(0 0 0 / 0.55); } /* * @layer base — Oat's cozy-neutral philosophy. * * No glass, no brutalist offsets. Warm-humanist type, soft-round corners, * gentle diffuse shadows. Cards sit on the greige field with a hairline border * AND a visible lightness step so hierarchy reads even before the shadow does. */ @layer base { body { min-height: 100vh; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; letter-spacing: -0.006em; font-family: var(--font-sans); font-size: var(--text-body-size); line-height: var(--text-body-lh); } 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.012em; color: var(--foreground); } code, kbd, samp, pre, [data-slot="code"], [data-slot="code-block"] { font-family: var(--font-mono); } /* Inline code — neutral ink on a warm tinted chip. Coral stays reserved * for actions, links and focus so the accent keeps pointing at one thing. */ :not(pre) > code { padding: 0.1em 0.35em; border-radius: calc(var(--radius) * 0.4); background: color-mix(in oklch, var(--foreground) 7%, transparent); color: var(--foreground); font-size: 0.9em; } /* Selection — soft coral wash. */ ::selection { background: color-mix(in oklch, var(--primary) 20%, transparent); color: var(--foreground); } /* Anchor links — coral, underline warms on hover. */ a { color: var(--primary); 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); } /* Card & overlay surfaces — soft warm-grey diffuse shadow so surfaces feel * lifted off the oat field, tactile rather than hard-edged. */ [data-slot="card"], [data-slot="popover-content"], [data-slot="dropdown-menu-content"], [data-slot="context-menu-content"], [data-slot="menubar-content"], [data-slot="hover-card-content"], [data-slot="select-content"], [data-slot="combobox-content"], [data-slot="command"], [data-slot="tooltip-content"], [data-slot="sheet-content"], [data-slot="dialog-content"], [data-slot="alert-dialog-content"], [data-slot="drawer-content"] { border: var(--border-width-base) solid var(--border); box-shadow: var(--elevation-3); } .dark [data-slot="card"], .dark [data-slot="popover-content"], .dark [data-slot="dropdown-menu-content"], .dark [data-slot="context-menu-content"], .dark [data-slot="menubar-content"], .dark [data-slot="hover-card-content"], .dark [data-slot="select-content"], .dark [data-slot="combobox-content"], .dark [data-slot="command"], .dark [data-slot="tooltip-content"], .dark [data-slot="sheet-content"], .dark [data-slot="dialog-content"], .dark [data-slot="alert-dialog-content"], .dark [data-slot="drawer-content"] { box-shadow: var(--elevation-4); } [data-slot="button"] { font-weight: 500; } [data-slot="sidebar"] { background: var(--sidebar); border-right: var(--border-width-base) solid var(--sidebar-border); } } /* * Unlayered control tuning — placed outside @layer base so it beats Tailwind's * default utility classes shipped with shadcn primitives. Oat's controls are * comfortable with soft-round corners and a flush coral focus ring rather than * Tailwind's 3px halo. Inputs are ≥44px everywhere; buttons keep their density * ladder under a mouse and clear the 44px touch floor on coarse pointers. */ @media (pointer: coarse) { [data-slot="button"] { min-height: 2.75rem; min-width: 2.75rem; } } [data-slot="button"]:hover:not(:disabled) { opacity: 0.9; } [data-slot="button"]:active:not(:disabled) { opacity: 0.82; transform: scale(0.99); } [data-slot="button"]:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; box-shadow: none; } [data-slot="input"], [data-slot="textarea"], [data-slot="select-trigger"] { min-height: 2.75rem; padding-inline: 1rem; font-size: 0.9375rem; background: var(--card); border: 1px solid var(--border); 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="textarea"] { min-height: 6.25rem; padding-block: 0.75rem; line-height: 1.55; resize: vertical; } [data-slot="input"]::placeholder, [data-slot="textarea"]::placeholder { color: var(--muted-foreground); opacity: 0.7; } [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) 25%, transparent); } [data-slot="input"]:focus, [data-slot="input"]:focus-visible, [data-slot="textarea"]:focus, [data-slot="textarea"]:focus-visible, [data-slot="select-trigger"]:focus, [data-slot="select-trigger"]:focus-visible { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); outline: none; } /* ─── Cards ─── * Warm near-white surface a clear step above the oat field, soft-round 1rem * corners, hairline border, gentle lift on hover. */ [data-slot="card"] { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; transition: border-color var(--duration-base) var(--ease-standard), box-shadow var(--duration-base) var(--ease-standard); } [data-slot="card"]:hover { box-shadow: var(--elevation-4); } [data-slot="card-title"] { font-family: var(--font-heading); font-weight: 600; letter-spacing: -0.012em; font-size: var(--text-title-size); line-height: var(--text-title-lh); } [data-slot="card-description"] { color: var(--muted-foreground); font-size: 0.9375rem; }