Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/deprecate-kumo-hairline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@cloudflare/kumo": minor
---

Deprecate `kumo-hairline` token in favor of `kumo-line`.

The `kumo-line` token has been redefined to use 10% black in light mode and 10% white in dark mode, unifying the two former border/ring tokens into a single semantic token. All internal usage has been migrated from `kumo-hairline` to `kumo-line`.

For backwards compatibility, `--color-kumo-hairline` is kept as a CSS alias for `--color-kumo-line`. Existing consumers using `bg-kumo-hairline`, `border-kumo-hairline`, `ring-kumo-hairline`, etc. will continue to work but should migrate to the `kumo-line` equivalents. The alias will be removed in the next major release.
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ kumo/

### Styling (CRITICAL)

- **ONLY semantic tokens**: `bg-kumo-base`, `text-kumo-default`, `border-kumo-line`, `ring-kumo-hairline`
- **ONLY semantic tokens**: `bg-kumo-base`, `text-kumo-default`, `border-kumo-line`, `ring-kumo-line`
- **NEVER raw Tailwind colors**: `bg-blue-500`, `text-gray-900` → fails lint
- **NEVER `dark:` variant**: dark mode automatic via `light-dark()` in CSS custom properties
- **Exceptions**: `bg-white`, `bg-black`, `text-white`, `text-black`, `transparent`
Expand Down
2 changes: 1 addition & 1 deletion lint/no-primitive-colors.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const INVALID_TOKEN_RULE = "invalid-color-token";

// We want to enforce use of Kumo semantic color tokens `--color-kumo-*`.
// Any Tailwind color utility (e.g. `bg-blue-500`) or legacy semantic
// utility (e.g. `bg-kumo-hairline`, `text-kumo-default`) in class strings should be
// utility (e.g. `bg-kumo-line`, `text-kumo-default`) in class strings should be
// replaced by semantic tokens / component APIs.

// Matches Tailwind-like color utilities in class strings.
Expand Down
4 changes: 2 additions & 2 deletions packages/kumo-docs-astro/src/components/Header.astro
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ const kumoVersion =
---

<header
class="sticky top-0 z-10 h-12 border-b border-kumo-hairline bg-kumo-canvas hidden lg:flex"
class="sticky top-0 z-10 h-12 border-b border-kumo-line bg-kumo-canvas hidden lg:flex"
>
<div
class="flex min-w-0 flex-1 items-center justify-end border-r border-kumo-hairline px-4"
class="flex min-w-0 flex-1 items-center justify-end border-r border-kumo-line px-4"
>
<a
href="https://github.com/cloudflare/kumo"
Expand Down
10 changes: 5 additions & 5 deletions packages/kumo-docs-astro/src/components/SearchDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -574,28 +574,28 @@ export function SearchDialog({ open, onOpenChange }: SearchDialogProps) {
</span>
<div className="flex items-center gap-4">
<span className="flex items-center gap-1">
<kbd className="rounded border border-kumo-hairline bg-kumo-base px-1.5 py-0.5">
<kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5">
</kbd>
<kbd className="rounded border border-kumo-hairline bg-kumo-base px-1.5 py-0.5">
<kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5">
</kbd>
<span>navigate</span>
</span>
<span className="flex items-center gap-1">
<kbd className="rounded border border-kumo-hairline bg-kumo-base px-1.5 py-0.5">
<kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5">
</kbd>
<span>open</span>
</span>
<span className="flex items-center gap-1">
<kbd className="rounded border border-kumo-hairline bg-kumo-base px-1.5 py-0.5">
<kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5">
⌘↵
</kbd>
<span>new tab</span>
</span>
<span className="flex items-center gap-1">
<kbd className="rounded border border-kumo-hairline bg-kumo-base px-1.5 py-0.5">
<kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5">
esc
</kbd>
<span>close</span>
Expand Down
18 changes: 9 additions & 9 deletions packages/kumo-docs-astro/src/components/SidebarNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export function SidebarNav({ currentPath }: SidebarNavProps) {
<>
<button
onClick={() => setSearchOpen(true)}
className="mb-3 flex w-full items-center gap-2 rounded-lg bg-kumo-control px-3 py-2 text-sm text-kumo-subtle ring-1 ring-kumo-line transition-all hover:ring-kumo-hairline focus:outline-none focus-visible:ring-2 focus-visible:ring-kumo-brand focus-visible:ring-inset"
className="mb-3 flex w-full items-center gap-2 rounded-lg bg-kumo-control px-3 py-2 text-sm text-kumo-subtle ring-1 ring-kumo-line transition-all hover:ring-kumo-line focus:outline-none focus-visible:ring-2 focus-visible:ring-kumo-brand focus-visible:ring-inset"
>
<MagnifyingGlassIcon size={16} className="shrink-0" />
<span>Search...</span>
Expand All @@ -236,7 +236,7 @@ export function SidebarNav({ currentPath }: SidebarNavProps) {
))}
</ul>

<div className="my-4 border-b border-kumo-hairline" />
<div className="my-4 border-b border-kumo-line" />

<div className="mb-4">
{/* Components Section */}
Expand Down Expand Up @@ -366,7 +366,7 @@ export function SidebarNav({ currentPath }: SidebarNavProps) {
{/* Mobile header bar with hamburger */}
<div
className={cn(
"fixed inset-x-0 top-0 z-50 flex h-12 items-center justify-between border-b border-kumo-hairline bg-kumo-canvas px-3 md:px-6 lg:hidden",
"fixed inset-x-0 top-0 z-50 flex h-12 items-center justify-between border-b border-kumo-line bg-kumo-canvas px-3 md:px-6 lg:hidden",
)}
>
<Button
Expand All @@ -384,12 +384,12 @@ export function SidebarNav({ currentPath }: SidebarNavProps) {
{/* Mobile slide-out drawer */}
<aside
className={cn(
"fixed inset-y-0 left-0 z-50 flex w-72 flex-col border-r border-kumo-hairline bg-kumo-canvas lg:hidden",
"fixed inset-y-0 left-0 z-50 flex w-72 flex-col border-r border-kumo-line bg-kumo-canvas lg:hidden",
"transition-transform duration-300 will-change-transform",
mobileMenuOpen ? "translate-x-0" : "-translate-x-full",
)}
>
<div className="flex h-12 flex-none items-center justify-between border-b border-kumo-hairline px-3">
<div className="flex h-12 flex-none items-center justify-between border-b border-kumo-line px-3">
<h1 className="text-base font-medium">Kumo</h1>
<Button
variant="ghost"
Expand All @@ -414,10 +414,10 @@ export function SidebarNav({ currentPath }: SidebarNavProps) {
<div
className={cn(
"fixed inset-y-0 left-0 z-50 hidden w-12 bg-kumo-canvas lg:block",
"border-r border-kumo-hairline",
"border-r border-kumo-line",
)}
>
<div className="relative h-12 border-b border-kumo-hairline">
<div className="relative h-12 border-b border-kumo-line">
<div className="absolute inset-0 grid place-items-center">
<Button
variant="ghost"
Expand All @@ -444,11 +444,11 @@ export function SidebarNav({ currentPath }: SidebarNavProps) {
"fixed inset-y-0 left-12 z-40 hidden w-64 flex-col bg-kumo-canvas lg:flex",
"transition-transform duration-300 ease-out will-change-transform",
sidebarOpen
? "translate-x-0 border-r border-kumo-hairline"
? "translate-x-0 border-r border-kumo-line"
: "-translate-x-full",
)}
>
<div className="h-12 flex-none border-b border-kumo-hairline" />
<div className="h-12 flex-none border-b border-kumo-line" />

<div
ref={desktopScrollRef}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ interface Props {
const { title, description, href } = Astro.props;
---

<div class="rounded-lg border border-kumo-hairline bg-kumo-elevated">
<div class="rounded-lg border border-kumo-line bg-kumo-elevated">
<div class="p-4">
<div class="text-kumo-default">{title}</div>
<div class="mt-1 text-sm text-kumo-secondary">{description}</div>

<div class="mt-4">
<a
href={href}
class="inline-flex items-center justify-center rounded-md border border-kumo-hairline bg-kumo-control px-3 py-1.5 text-sm font-medium text-kumo-default transition-colors hover:bg-kumo-recessed"
class="inline-flex items-center justify-center rounded-md border border-kumo-line bg-kumo-control px-3 py-1.5 text-sm font-medium text-kumo-default transition-colors hover:bg-kumo-recessed"
>
Learn more
</a>
</div>
</div>

<div class="border-kumo-hairline border-t bg-kumo-base p-2">
<div class="border-kumo-line border-t bg-kumo-base p-2">
<slot />
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ export function LegendDefaultDemo() {
<div className="space-y-4">
<h3 className="text-sm font-medium">Active State</h3>

<div className="flex flex-wrap gap-4 divide-x divide-kumo-hairline">
<div className="flex flex-wrap gap-4 divide-x divide-kumo-line">
<ChartLegend.LargeItem
name="Requests"
color={ChartPalette.semantic("Neutral", isDarkMode)}
Expand All @@ -430,7 +430,7 @@ export function LegendDefaultDemo() {

<h3 className="mt-12 text-sm font-medium">Inactive State</h3>

<div className="flex flex-wrap gap-4 divide-x divide-kumo-hairline">
<div className="flex flex-wrap gap-4 divide-x divide-kumo-line">
<ChartLegend.LargeItem
name="Requests"
color={ChartPalette.semantic("Neutral", isDarkMode)}
Expand All @@ -455,7 +455,7 @@ export function LegendDefaultDemo() {

<h3 className="mt-12 text-sm font-medium">Loading state</h3>

<div className="flex flex-wrap gap-4 divide-x divide-kumo-hairline">
<div className="flex flex-wrap gap-4 divide-x divide-kumo-line">
<ChartLegend.LargeItem loading />
</div>
</div>
Expand Down Expand Up @@ -688,7 +688,7 @@ export function ChartExampleDemo() {
<LayerCard>
<LayerCard.Secondary>Read latency</LayerCard.Secondary>
<LayerCard.Primary>
<div className="mb-2 flex gap-4 divide-x divide-kumo-hairline px-2">
<div className="mb-2 flex gap-4 divide-x divide-kumo-line px-2">
<ChartLegend.LargeItem
name="P99"
color={ChartPalette.semantic("Attention", isDarkMode)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export function PoweredByCloudflareVariantsDemo() {

export function PoweredByCloudflareFooterDemo() {
return (
<footer className="flex w-full items-center justify-between rounded-lg border border-kumo-hairline bg-kumo-elevated px-6 py-4">
<footer className="flex w-full items-center justify-between rounded-lg border border-kumo-line bg-kumo-elevated px-6 py-4">
<span className="text-sm text-kumo-subtle">
&copy; 2026 Your Company. All rights reserved.
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ export function CodeHighlightedCustomHighlightDemo() {
/>
</div>

<div className="flex flex-wrap gap-6 rounded-md border border-kumo-hairline bg-kumo-elevated p-4">
<div className="flex flex-wrap gap-6 rounded-md border border-kumo-line bg-kumo-elevated p-4">
<label className="flex flex-col gap-2">
<span className="text-sm text-kumo-subtle">Hue: {hue}°</span>
<input
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,13 @@ export function CommandPaletteBasicDemo() {
</CommandPalette.List>
<CommandPalette.Footer>
<span className="flex items-center gap-2">
<kbd className="rounded border border-kumo-hairline bg-kumo-base px-1.5 py-0.5 text-[10px]">
<kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5 text-[10px]">
↑↓
</kbd>
<span>Navigate</span>
</span>
<span className="flex items-center gap-2">
<kbd className="rounded border border-kumo-hairline bg-kumo-base px-1.5 py-0.5 text-[10px]">
<kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5 text-[10px]">
</kbd>
<span>Select</span>
Expand Down Expand Up @@ -431,13 +431,13 @@ export function CommandPaletteResultItemDemo() {
</CommandPalette.List>
<CommandPalette.Footer>
<span className="flex items-center gap-2">
<kbd className="rounded border border-kumo-hairline bg-kumo-base px-1.5 py-0.5 text-[10px]">
<kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5 text-[10px]">
↑↓
</kbd>
<span>Navigate</span>
</span>
<span className="flex items-center gap-2">
<kbd className="rounded border border-kumo-hairline bg-kumo-base px-1.5 py-0.5 text-[10px]">
<kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5 text-[10px]">
⌘↵
</kbd>
<span>Open in new tab</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ export function DatePickerRangeWithPresetsDemo() {
</Popover.Trigger>
<Popover.Content className="p-0">
<div className="flex">
<div className="flex flex-col gap-1 border-r border-kumo-hairline p-2 text-sm">
<div className="flex flex-col gap-1 border-r border-kumo-line p-2 text-sm">
{presets.map((preset) => {
const isActive = isPresetActive(preset);
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ export function DialogSizesDemo() {
<th className="px-3 py-2">Last Deployed</th>
</tr>
</thead>
<tbody className="divide-y divide-kumo-hairline">
<tbody className="divide-y divide-kumo-line">
<tr>
<td className="px-3 py-2">api-gateway-prod</td>
<td className="px-3 py-2">us-east-1</td>
Expand Down
16 changes: 8 additions & 8 deletions packages/kumo-docs-astro/src/components/demos/FlowDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const ExpandableNode = forwardRef<
<li
ref={ref}
{...props}
className="overflow-hidden rounded-lg bg-kumo-base shadow ring ring-kumo-hairline"
className="overflow-hidden rounded-lg bg-kumo-base shadow ring ring-kumo-line"
>
<button
type="button"
Expand All @@ -24,7 +24,7 @@ const ExpandableNode = forwardRef<
/>
</button>
{open && (
<div className="border-t border-kumo-hairline px-3 py-2 text-sm text-kumo-subtle">
<div className="border-t border-kumo-line px-3 py-2 text-sm text-kumo-subtle">
{children}
</div>
)}
Expand Down Expand Up @@ -92,7 +92,7 @@ export function FlowCustomContentDemo() {
return (
<Flow>
<Flow.Node
render={<li className="size-4 rounded-full bg-kumo-hairline" />}
render={<li className="size-4 rounded-full bg-kumo-line" />}
/>
<Flow.Node
render={
Expand Down Expand Up @@ -131,7 +131,7 @@ export function FlowAnchorDemo() {
<Flow.Node>Load balancer</Flow.Node>
<Flow.Node
render={
<li className="rounded-lg bg-kumo-overlay shadow-none ring ring-kumo-hairline">
<li className="rounded-lg bg-kumo-overlay shadow-none ring ring-kumo-line">
<Flow.Anchor
type="end"
render={
Expand All @@ -143,7 +143,7 @@ export function FlowAnchorDemo() {
<Flow.Anchor
type="start"
render={
<div className="m-1.5 mt-0 rounded bg-kumo-base px-2 py-1.5 shadow ring ring-kumo-hairline">
<div className="m-1.5 mt-0 rounded bg-kumo-base px-2 py-1.5 shadow ring ring-kumo-line">
Bindings
<span className="ml-3 w-5 text-kumo-subtle">2</span>
</div>
Expand All @@ -165,12 +165,12 @@ export function FlowCenteredDemo() {
return (
<Flow align="center">
<Flow.Node
render={<li className="size-4 rounded-full bg-kumo-hairline" />}
render={<li className="size-4 rounded-full bg-kumo-line" />}
/>
<Flow.Node>my-worker</Flow.Node>
<Flow.Node
render={
<li className="rounded-md bg-kumo-base px-3 py-6 shadow ring ring-kumo-hairline">
<li className="rounded-md bg-kumo-base px-3 py-6 shadow ring ring-kumo-line">
Taller node
</li>
}
Expand All @@ -182,7 +182,7 @@ export function FlowCenteredDemo() {
/** Large flow diagram demonstrating panning */
export function FlowPanningDemo() {
return (
<Flow className="rounded-lg border border-kumo-hairline">
<Flow className="rounded-lg border border-kumo-line">
<Flow.Node>Start</Flow.Node>
<Flow.Node>Authenticate</Flow.Node>
<Flow.Node>Validate</Flow.Node>
Expand Down
2 changes: 1 addition & 1 deletion packages/kumo-docs-astro/src/components/demos/HomeGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ export function HomeGrid() {
];

return (
<ul className="grid auto-rows-min grid-cols-1 gap-px bg-kumo-hairline md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4">
<ul className="grid auto-rows-min grid-cols-1 gap-px bg-kumo-line md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4">
{components.map((c) => {
const route = componentRoutes[c.id] || null;
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ const wpThemeStyles = `
--color-kumo-interact: #c3c4c7;

/* WP borders — very subtle gray */
--color-kumo-hairline: #c3c4c7;
--color-kumo-hairline: #2271b1;
--color-kumo-line: #2271b1;

/* WP text hierarchy */
--text-color-kumo-default: #1d2327;
Expand Down Expand Up @@ -300,7 +299,7 @@ function WPTopBar({
onToggleDarkMode: () => void;
}) {
return (
<div className="flex h-[48px] items-center justify-between border-b border-kumo-hairline bg-kumo-elevated px-4">
<div className="flex h-[48px] items-center justify-between border-b border-kumo-line bg-kumo-elevated px-4">
<div className="flex items-center gap-4">
<h1 className="text-lg font-semibold text-kumo-default">Posts</h1>
<Button variant="primary" size="sm">
Expand Down Expand Up @@ -418,7 +417,7 @@ export function KumoPressDemo() {
<div
data-theme="wordpress"
data-mode={darkMode ? "dark" : undefined}
className="flex h-[720px] overflow-hidden rounded-xl border border-kumo-hairline bg-kumo-elevated font-sans shadow-lg"
className="flex h-[720px] overflow-hidden rounded-xl border border-kumo-line bg-kumo-elevated font-sans shadow-lg"
>
{/* Sidebar */}
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function LayerCardFilterSubrequestsDemo() {
{filtered.map((row, i) => (
<div
key={row.origin}
className={`grid grid-cols-[1fr_auto_auto] items-center gap-x-4 px-1 py-2.5 ${i < filtered.length - 1 ? "border-b border-kumo-hairline" : ""}`}
className={`grid grid-cols-[1fr_auto_auto] items-center gap-x-4 px-1 py-2.5 ${i < filtered.length - 1 ? "border-b border-kumo-line" : ""}`}
>
<span className="truncate font-medium text-kumo-default">
{row.origin}
Expand Down
Loading