@import "tailwindcss" source(none); @source "../src"; @import "tw-animate-css"; @font-face { font-family: "Inter"; font-style: normal; font-weight: 400 700; font-display: optional; src: url("/fonts/inter-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } @font-face { font-family: "Fraunces"; font-style: normal; font-weight: 400 700; font-display: optional; src: url("/fonts/fraunces-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } @font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 400 500; font-display: optional; src: url("/fonts/jetbrains-mono-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } @custom-variant dark (&:is(.dark *)); @theme inline { --radius-sm: calc(var(--radius) - 4px); --radius-md: calc(var(--radius) - 2px); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) + 4px); --color-background: var(--background); --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-border: var(--border); --color-input: var(--input); --color-ring: var(--ring); --font-serif: "Fraunces", ui-serif, Georgia, serif; --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif; --font-mono: "JetBrains Mono", ui-monospace, monospace; } /* ============================================================ Carlos Arias — sumi-e brand palette Ink on paper, vermillion as seal. Written as hex so these values are eyeball-verifiable against brand/BRAND.md, which is the source of truth. Do not "improve" a colour here — change it in the brand guide first. Two choices worth preserving: · The ground is never pure white. Washi-toned. · The near-black is blue-black, not neutral grey — real sumi ink has a cool cast, and the whole ramp inherits it. ============================================================ */ :root { --radius: 2px; /* near-square, not rounded */ --background: #f6f5f2; /* washi paper */ --foreground: #14151a; /* sumi ink */ --card: #f6f5f2; --card-foreground: #14151a; --popover: #efeeea; --popover-foreground: #14151a; /* Primary is INK, not red. The seal is never a button ground. */ --primary: #14151a; --primary-foreground: #f6f5f2; --secondary: #efeeea; --secondary-foreground: #3d3f47; --muted: #efeeea; --muted-foreground: #6e7078; /* Shuniku 朱肉 — seal ink. Target 1–2% coverage per screen. */ --accent: #d0342c; --accent-foreground: #ffffff; --destructive: #9b1c17; /* deeper than the seal, so errors never read as brand */ --destructive-foreground: #ffffff; --border: #dfddd7; --input: #dfddd7; --ring: #d0342c; /* ---- brand extras the base theme has no slot for ---- */ --ca-ink-2: #3d3f47; --ca-ink-3: #6e7078; --ca-ink-4: #9a9ca3; --ca-seal: #d0342c; /* Motion. Wabi-sabi motion is slow and never demands attention. Nothing bounces, nothing pulses, nothing loops in the viewport. If an effect asks to be watched, it belongs to another brand. */ --ca-dur-quick: 180ms; --ca-dur-base: 280ms; --ca-dur-slow: 620ms; --ca-dur-ink: 1500ms; --ca-ease: cubic-bezier(0.33, 0.1, 0.25, 1); --ca-ease-press: cubic-bezier(0.2, 0.9, 0.3, 1); --ca-reveal-y: 12px; --ca-stagger: 70ms; } .dark { --background: #121317; --foreground: #edece8; --card: #121317; --card-foreground: #edece8; --popover: #191a1f; --popover-foreground: #edece8; --primary: #edece8; --primary-foreground: #121317; --secondary: #191a1f; --secondary-foreground: #c2c1bd; --muted: #191a1f; --muted-foreground: #8b8d95; /* Lifted on dark — #d0342c muddies against near-black. Not a naive inversion. */ --accent: #e8564a; --accent-foreground: #121317; --destructive: #e8564a; --destructive-foreground: #121317; --border: #2a2c33; --input: #2a2c33; --ring: #e8564a; --ca-ink-2: #c2c1bd; --ca-ink-3: #8b8d95; --ca-ink-4: #5e606a; --ca-seal: #e8564a; } /* Ink-surface values exposed globally, so anything that has to sit on a dark ground (the header while the mobile menu is open, an overlay, a badge) can reach them without hardcoding a hex or relying on being nested inside .ca-ink-surface. Mirrors brand/tokens.css — keep the two in step. Note: an undefined var() invalidates the whole declaration silently, so a missing name here shows up as "the colour just didn't apply", not an error. */ :root { --ca-ink-surface-bg: #121317; --ca-ink-surface-bg-2: #191a1f; --ca-ink-surface-rule: #2a2c33; --ca-ink-surface-fg: #edece8; --ca-ink-surface-fg-2: #c2c1bd; --ca-ink-surface-fg-3: #8b8d95; --ca-ink-surface-fg-4: #5e606a; --ca-ink-surface-seal: #e8564a; } /* ---- Ink surface ---- A section that stays ink-ground in BOTH themes, for committed dark moments where the content itself demands darkness. Remaps the semantic tokens locally, so anything nested inside needs no changes. Use sparingly — one per page at most. */ /* IMPORTANT: this overrides the --color-* layer, NOT --background/--foreground. The theme declares `--color-background: var(--background)` on :root, and a custom property is substituted where it is DECLARED — so --color-background resolved to paper at :root and only inherits from there. Redefining --background on a descendant cannot retroactively change it, and the section silently renders paper-on-paper. (.dark works only because it sits on , the same element as :root, so the declaration re-resolves there. A nested scope has no such luck.) Every utility — bg-background, text-muted-foreground, border-border — reads the --color-* names, so overriding those is both correct and sufficient. */ .ca-ink-surface { /* BOTH names are required, and for different consumers: --foreground ← what Tailwind utilities compile to. `@theme inline` emits `.text-foreground { color: var(--foreground) }`, referencing the underlying variable, not the alias. --color-foreground ← what hand-written CSS in this file uses, and what cannot be reached by overriding the raw name alone (it was already substituted at :root). Set one and half the section is wrong in a way that only shows up as dark-on-dark text. Keep them in lockstep. */ --background: #121317; --color-background: #121317; --foreground: #edece8; --color-foreground: #edece8; --card: #121317; --color-card: #121317; --card-foreground: #edece8; --color-card-foreground: #edece8; --popover: #191a1f; --color-popover: #191a1f; --popover-foreground: #edece8; --color-popover-foreground: #edece8; --primary: #edece8; --color-primary: #edece8; --primary-foreground: #121317; --color-primary-foreground: #121317; --secondary: #191a1f; --color-secondary: #191a1f; --secondary-foreground: #c2c1bd; --color-secondary-foreground: #c2c1bd; --muted: #191a1f; --color-muted: #191a1f; --muted-foreground: #8b8d95; --color-muted-foreground: #8b8d95; --accent: #e8564a; --color-accent: #e8564a; --accent-foreground: #121317; --color-accent-foreground: #121317; --border: #2a2c33; --color-border: #2a2c33; --input: #2a2c33; --color-input: #2a2c33; --ring: #e8564a; --color-ring: #e8564a; --ca-ink-2: #c2c1bd; --ca-ink-3: #8b8d95; --ca-ink-4: #5e606a; --ca-seal: #e8564a; background-color: var(--color-background); color: var(--color-foreground); } @layer base { * { border-color: var(--color-border); } html { scroll-behavior: smooth; } body { margin: 0; background-color: var(--color-background); color: var(--color-foreground); font-family: var(--font-sans); font-feature-settings: "ss01", "cv11"; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; } ::selection { background-color: color-mix(in oklab, var(--color-primary) 25%, transparent); } :where(a, button, input, textarea, select, summary):focus-visible { outline: 2px solid var(--color-ring) !important; outline-offset: 3px; } @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; transition-duration: 0.01ms !important; } } } @layer components { /* ============================================================ Brand primitives — defined ONCE, used everywhere. Anything reused across more than one page belongs here, not in a page's