kaze-design-system 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/components.css CHANGED
@@ -3719,6 +3719,51 @@
3719
3719
  margin: var(--space-1) 0;
3720
3720
  }
3721
3721
 
3722
+ /* ── FilterPill ──────────────────────────────────────────── */
3723
+ .filter-pill {
3724
+ display: inline-flex;
3725
+ align-items: center;
3726
+ gap: var(--space-1-5);
3727
+ padding: var(--space-1) var(--space-3);
3728
+ font-size: var(--font-size-sm);
3729
+ font-weight: var(--font-weight-medium);
3730
+ line-height: 1.5;
3731
+ border-radius: var(--radius-full);
3732
+ border: 1px solid var(--color-border);
3733
+ background-color: var(--color-bg);
3734
+ color: var(--color-fg-secondary);
3735
+ cursor: pointer;
3736
+ -webkit-user-select: none;
3737
+ user-select: none;
3738
+ white-space: nowrap;
3739
+ transition: background-color var(--duration-normal) var(--ease-default),
3740
+ border-color var(--duration-normal) var(--ease-default),
3741
+ color var(--duration-normal) var(--ease-default);
3742
+ }
3743
+
3744
+ .filter-pill:hover {
3745
+ background-color: var(--color-surface-hover);
3746
+ }
3747
+
3748
+ .filter-pill:focus-visible {
3749
+ outline: var(--ring-width) solid var(--ring-color);
3750
+ outline-offset: var(--ring-offset);
3751
+ }
3752
+
3753
+ .filter-pill--active {
3754
+ border-color: var(--filter-pill-color, var(--color-primary));
3755
+ background-color: color-mix(in srgb, var(--filter-pill-color, var(--color-primary)) 8%, transparent);
3756
+ color: var(--filter-pill-color, var(--color-fg));
3757
+ }
3758
+
3759
+ .filter-pill__dot {
3760
+ width: 8px;
3761
+ height: 8px;
3762
+ border-radius: var(--radius-full);
3763
+ background-color: var(--filter-pill-color, currentColor);
3764
+ flex-shrink: 0;
3765
+ }
3766
+
3722
3767
  /* ── Command Palette (additions) ────────────────────────── */
3723
3768
 
3724
3769
  .command-palette__group {
@@ -0,0 +1,31 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { cn } from "../../lib/utils.js";
4
+ const FilterPill = forwardRef(
5
+ ({ active, color, dot, className, style, children, ...rest }, ref) => {
6
+ const pillStyle = color ? { ...style, "--filter-pill-color": color } : style;
7
+ return /* @__PURE__ */ jsxs(
8
+ "button",
9
+ {
10
+ ref,
11
+ type: "button",
12
+ className: cn(
13
+ "filter-pill",
14
+ active && "filter-pill--active",
15
+ className
16
+ ),
17
+ style: pillStyle,
18
+ "aria-pressed": active,
19
+ ...rest,
20
+ children: [
21
+ dot && /* @__PURE__ */ jsx("span", { className: "filter-pill__dot", "aria-hidden": "true" }),
22
+ children
23
+ ]
24
+ }
25
+ );
26
+ }
27
+ );
28
+ FilterPill.displayName = "FilterPill";
29
+ export {
30
+ FilterPill
31
+ };
@@ -2,6 +2,7 @@
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import { useState, useCallback, useEffect, useMemo, useContext, createContext } from "react";
4
4
  const STORAGE_KEY = "kaze-theme";
5
+ const PALETTE_STORAGE_KEY = "kaze-palette";
5
6
  const ThemeContext = createContext(void 0);
6
7
  function getSystemTheme() {
7
8
  if (typeof window === "undefined") return "light";
@@ -19,11 +20,26 @@ function resolveTheme(theme) {
19
20
  if (theme === "system") return getSystemTheme();
20
21
  return theme;
21
22
  }
23
+ function getStoredPalette() {
24
+ if (typeof window === "undefined") return "warm";
25
+ const stored = localStorage.getItem(PALETTE_STORAGE_KEY);
26
+ if (stored === "warm" || stored === "cool") return stored;
27
+ return "warm";
28
+ }
29
+ function applyPalette(palette) {
30
+ if (typeof document === "undefined") return;
31
+ if (palette === "cool") {
32
+ document.documentElement.setAttribute("data-palette", "cool");
33
+ } else {
34
+ document.documentElement.removeAttribute("data-palette");
35
+ }
36
+ }
22
37
  function ThemeProvider({
23
38
  children,
24
39
  defaultTheme
25
40
  }) {
26
41
  const [theme, setThemeState] = useState(defaultTheme ?? "light");
42
+ const [palette, setPaletteState] = useState("warm");
27
43
  const [resolvedTheme, setResolvedTheme] = useState(
28
44
  defaultTheme === "dark" ? "dark" : "light"
29
45
  );
@@ -46,12 +62,22 @@ function ThemeProvider({
46
62
  const toggleTheme = useCallback(() => {
47
63
  setTheme(resolvedTheme === "light" ? "dark" : "light");
48
64
  }, [resolvedTheme, setTheme]);
65
+ const setPalette = useCallback((newPalette) => {
66
+ setPaletteState(newPalette);
67
+ if (typeof window !== "undefined") {
68
+ localStorage.setItem(PALETTE_STORAGE_KEY, newPalette);
69
+ }
70
+ applyPalette(newPalette);
71
+ }, []);
49
72
  useEffect(() => {
50
73
  const stored = getStoredTheme();
51
74
  if (stored !== (defaultTheme ?? "light")) {
52
75
  setThemeState(stored);
53
76
  }
54
77
  applyTheme(resolveTheme(stored));
78
+ const storedPalette = getStoredPalette();
79
+ setPaletteState(storedPalette);
80
+ applyPalette(storedPalette);
55
81
  }, []);
56
82
  useEffect(() => {
57
83
  applyTheme(resolveTheme(theme));
@@ -66,8 +92,8 @@ function ThemeProvider({
66
92
  return () => mql.removeEventListener("change", handler);
67
93
  }, [theme, applyTheme]);
68
94
  const value = useMemo(
69
- () => ({ theme, resolvedTheme, setTheme, toggleTheme }),
70
- [theme, resolvedTheme, setTheme, toggleTheme]
95
+ () => ({ theme, resolvedTheme, setTheme, toggleTheme, palette, setPalette }),
96
+ [theme, resolvedTheme, setTheme, toggleTheme, palette, setPalette]
71
97
  );
72
98
  return /* @__PURE__ */ jsx(ThemeContext.Provider, { value, children });
73
99
  }
package/dist/index.js CHANGED
@@ -21,6 +21,7 @@ import { EmptyState } from "./components/EmptyState/EmptyState.js";
21
21
  import { FAB } from "./components/FAB/FAB.js";
22
22
  import { FAQ, FAQItem } from "./components/FAQ/FAQ.js";
23
23
  import { FeatureCard, FeatureGrid } from "./components/FeatureGrid/FeatureGrid.js";
24
+ import { FilterPill } from "./components/FilterPill/FilterPill.js";
24
25
  import { FormField } from "./components/FormField/FormField.js";
25
26
  import { Grid } from "./components/Grid/Grid.js";
26
27
  import { Heading } from "./components/Heading/Heading.js";
@@ -97,6 +98,7 @@ export {
97
98
  FAQItem,
98
99
  FeatureCard,
99
100
  FeatureGrid,
101
+ FilterPill,
100
102
  FormField,
101
103
  Grid,
102
104
  Heading,
@@ -4,7 +4,13 @@ const CHART_COLORS = [
4
4
  "var(--chart-purple)",
5
5
  "var(--chart-amber)",
6
6
  "var(--chart-red)",
7
- "var(--chart-cyan)"
7
+ "var(--chart-cyan)",
8
+ "var(--chart-lime)",
9
+ "var(--chart-pink)",
10
+ "var(--chart-orange)",
11
+ "var(--chart-teal)",
12
+ "var(--chart-yellow)",
13
+ "var(--chart-green)"
8
14
  ];
9
15
  export {
10
16
  CHART_COLORS
package/dist/tokens.js CHANGED
@@ -28,7 +28,13 @@ const color = {
28
28
  warningFg: "var(--color-warning-fg)",
29
29
  info: "var(--color-info)",
30
30
  infoLight: "var(--color-info-light)",
31
- infoFg: "var(--color-info-fg)"
31
+ infoFg: "var(--color-info-fg)",
32
+ accentA: "var(--color-accent-a)",
33
+ accentALight: "var(--color-accent-a-light)",
34
+ accentAFg: "var(--color-accent-a-fg)",
35
+ accentB: "var(--color-accent-b)",
36
+ accentBLight: "var(--color-accent-b-light)",
37
+ accentBFg: "var(--color-accent-b-fg)"
32
38
  };
33
39
  const chart = {
34
40
  emerald: "var(--chart-emerald)",
@@ -36,7 +42,13 @@ const chart = {
36
42
  purple: "var(--chart-purple)",
37
43
  amber: "var(--chart-amber)",
38
44
  red: "var(--chart-red)",
39
- cyan: "var(--chart-cyan)"
45
+ cyan: "var(--chart-cyan)",
46
+ lime: "var(--chart-lime)",
47
+ pink: "var(--chart-pink)",
48
+ orange: "var(--chart-orange)",
49
+ teal: "var(--chart-teal)",
50
+ yellow: "var(--chart-yellow)",
51
+ green: "var(--chart-green)"
40
52
  };
41
53
  const space = {
42
54
  0: "var(--space-0)",
@@ -58,6 +70,7 @@ const space = {
58
70
  24: "var(--space-24)"
59
71
  };
60
72
  const radius = {
73
+ sharp: "var(--radius-sharp)",
61
74
  sm: "var(--radius-sm)",
62
75
  md: "var(--radius-md)",
63
76
  lg: "var(--radius-lg)",
@@ -0,0 +1,10 @@
1
+ import { type ButtonHTMLAttributes } from "react";
2
+ export interface FilterPillProps extends ButtonHTMLAttributes<HTMLButtonElement> {
3
+ /** Whether the pill is in an active/selected state */
4
+ active?: boolean;
5
+ /** Dynamic accent color (CSS color value). Applied via --filter-pill-color custom property */
6
+ color?: string;
7
+ /** Show a colored dot indicator before the label */
8
+ dot?: boolean;
9
+ }
10
+ export declare const FilterPill: import("react").ForwardRefExoticComponent<FilterPillProps & import("react").RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,2 @@
1
+ export { FilterPill } from "./FilterPill";
2
+ export type { FilterPillProps } from "./FilterPill";
@@ -6,6 +6,8 @@ export { Card, CardHeader, CardTitle, CardDescription, CardBody, CardFooter, } f
6
6
  export type { CardProps, CardVariant, CardHeaderProps, CardTitleProps, CardDescriptionProps, CardBodyProps, CardFooterProps, } from "./Card";
7
7
  export { Badge } from "./Badge";
8
8
  export type { BadgeProps, BadgeVariant } from "./Badge";
9
+ export { FilterPill } from "./FilterPill";
10
+ export type { FilterPillProps } from "./FilterPill";
9
11
  export { Input } from "./Input";
10
12
  export type { InputProps } from "./Input";
11
13
  export { Select } from "./Select";
@@ -1,10 +1,13 @@
1
1
  import { type ReactNode } from "react";
2
2
  export type Theme = "light" | "dark" | "system";
3
+ export type Palette = "warm" | "cool";
3
4
  export interface ThemeContextValue {
4
5
  theme: Theme;
5
6
  resolvedTheme: "light" | "dark";
6
7
  setTheme: (theme: Theme) => void;
7
8
  toggleTheme: () => void;
9
+ palette: Palette;
10
+ setPalette: (palette: Palette) => void;
8
11
  }
9
12
  export interface ThemeProviderProps {
10
13
  children: ReactNode;
@@ -1,2 +1,2 @@
1
1
  /** Shared chart color palette using CSS custom properties */
2
- export declare const CHART_COLORS: readonly ["var(--chart-emerald)", "var(--chart-blue)", "var(--chart-purple)", "var(--chart-amber)", "var(--chart-red)", "var(--chart-cyan)"];
2
+ export declare const CHART_COLORS: readonly ["var(--chart-emerald)", "var(--chart-blue)", "var(--chart-purple)", "var(--chart-amber)", "var(--chart-red)", "var(--chart-cyan)", "var(--chart-lime)", "var(--chart-pink)", "var(--chart-orange)", "var(--chart-teal)", "var(--chart-yellow)", "var(--chart-green)"];
@@ -33,6 +33,12 @@ export declare const color: {
33
33
  readonly info: "var(--color-info)";
34
34
  readonly infoLight: "var(--color-info-light)";
35
35
  readonly infoFg: "var(--color-info-fg)";
36
+ readonly accentA: "var(--color-accent-a)";
37
+ readonly accentALight: "var(--color-accent-a-light)";
38
+ readonly accentAFg: "var(--color-accent-a-fg)";
39
+ readonly accentB: "var(--color-accent-b)";
40
+ readonly accentBLight: "var(--color-accent-b-light)";
41
+ readonly accentBFg: "var(--color-accent-b-fg)";
36
42
  };
37
43
  export declare const chart: {
38
44
  readonly emerald: "var(--chart-emerald)";
@@ -41,6 +47,12 @@ export declare const chart: {
41
47
  readonly amber: "var(--chart-amber)";
42
48
  readonly red: "var(--chart-red)";
43
49
  readonly cyan: "var(--chart-cyan)";
50
+ readonly lime: "var(--chart-lime)";
51
+ readonly pink: "var(--chart-pink)";
52
+ readonly orange: "var(--chart-orange)";
53
+ readonly teal: "var(--chart-teal)";
54
+ readonly yellow: "var(--chart-yellow)";
55
+ readonly green: "var(--chart-green)";
44
56
  };
45
57
  export declare const space: {
46
58
  readonly 0: "var(--space-0)";
@@ -62,6 +74,7 @@ export declare const space: {
62
74
  readonly 24: "var(--space-24)";
63
75
  };
64
76
  export declare const radius: {
77
+ readonly sharp: "var(--radius-sharp)";
65
78
  readonly sm: "var(--radius-sm)";
66
79
  readonly md: "var(--radius-md)";
67
80
  readonly lg: "var(--radius-lg)";
@@ -70,3 +83,4 @@ export declare const radius: {
70
83
  readonly full: "var(--radius-full)";
71
84
  };
72
85
  export type Theme = "light" | "dark";
86
+ export type Palette = "warm" | "cool";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kaze-design-system",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "MIT",
package/tokens.css CHANGED
@@ -18,6 +18,19 @@
18
18
  --zinc-900: #1c1917;
19
19
  --zinc-950: #0c0a09;
20
20
 
21
+ /* ── Color: Cool Slate Scale (purple-tinted) ─────────── */
22
+ --slate-50: #f8f8fa;
23
+ --slate-100: #f0eff4;
24
+ --slate-200: #e0dfe8;
25
+ --slate-300: #cccad8;
26
+ --slate-400: #6b6880;
27
+ --slate-500: #56536b;
28
+ --slate-600: #423f57;
29
+ --slate-700: #302e40;
30
+ --slate-800: #211f2c;
31
+ --slate-900: #16141f;
32
+ --slate-950: #0f0e16;
33
+
21
34
  /* ── Color: Palette (12 hues × 10 shades) ─────────────── */
22
35
 
23
36
  --red-50: #fef2f2; --red-100: #fee2e2; --red-200: #fecaca;
@@ -80,6 +93,14 @@
80
93
  --pink-600: #db2777; --pink-700: #be185d; --pink-800: #9d174d;
81
94
  --pink-900: #831843;
82
95
 
96
+ /* ── Color: Accent (dual-accent for category tagging) ── */
97
+ --color-accent-a: var(--blue-500);
98
+ --color-accent-a-light: var(--blue-50);
99
+ --color-accent-a-fg: var(--blue-600);
100
+ --color-accent-b: var(--red-500);
101
+ --color-accent-b-light: var(--red-50);
102
+ --color-accent-b-fg: var(--red-600);
103
+
83
104
  /* ── Color: Semantic ───────────────────────────────────── */
84
105
  --color-bg: #ffffff;
85
106
  --color-bg-secondary: var(--zinc-50);
@@ -153,6 +174,20 @@
153
174
  --chart-yellow: var(--yellow-500);
154
175
  --chart-green: var(--green-500);
155
176
 
177
+ /* Numbered aliases for programmatic access */
178
+ --chart-1: var(--chart-blue);
179
+ --chart-2: var(--chart-emerald);
180
+ --chart-3: var(--chart-amber);
181
+ --chart-4: var(--chart-pink);
182
+ --chart-5: var(--chart-cyan);
183
+ --chart-6: var(--chart-red);
184
+ --chart-7: var(--chart-lime);
185
+ --chart-8: var(--chart-purple);
186
+ --chart-9: var(--chart-orange);
187
+ --chart-10: var(--chart-teal);
188
+ --chart-11: var(--chart-yellow);
189
+ --chart-12: var(--chart-green);
190
+
156
191
  /* ── Typography ────────────────────────────────────────── */
157
192
  --font-sans: var(--font-montserrat, "Montserrat"), var(--font-noto-sans-jp, "Noto Sans JP"), -apple-system, BlinkMacSystemFont,
158
193
  "Segoe UI", "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo,
@@ -211,6 +246,7 @@
211
246
 
212
247
  /* ── Border Radius ─────────────────────────────────────── */
213
248
  --radius-none: 0;
249
+ --radius-sharp: 0px; /* deliberate zero radius — typographic / tool UI */
214
250
  --radius-sm: 0.375rem; /* 6px */
215
251
  --radius-md: 0.5rem; /* 8px */
216
252
  --radius-lg: 0.625rem; /* 10px — default card */
@@ -218,10 +254,11 @@
218
254
  --radius-2xl: 1rem; /* 16px */
219
255
  --radius-full: 9999px;
220
256
 
221
- /* 3-tier semantic radius (inspired by DaisyUI) */
222
- --radius-box: var(--radius-lg); /* Card, Modal, Panel */
223
- --radius-field: var(--radius-md); /* Input, Button, Select */
224
- --radius-selector: var(--radius-sm); /* Checkbox, Toggle, Badge */
257
+ /* 4-tier semantic radius (inspired by DaisyUI) */
258
+ --radius-box: var(--radius-lg); /* Card, Modal, Panel */
259
+ --radius-field: var(--radius-md); /* Input, Button, Select */
260
+ --radius-selector: var(--radius-sm); /* Checkbox, Toggle, Badge */
261
+ /* --radius-sharp: available for deliberate zero-radius design decisions */
225
262
 
226
263
  /* ── Shadows — Minimal ─────────────────────────────────── */
227
264
  --shadow-none: none;
@@ -322,6 +359,13 @@
322
359
  --color-info-fg: var(--blue-400); /* Brighter blue for dark bg readability */
323
360
  --color-info-strong: var(--blue-500);
324
361
 
362
+ --color-accent-a: var(--blue-400);
363
+ --color-accent-a-light: rgba(59, 130, 246, 0.1);
364
+ --color-accent-a-fg: var(--blue-400);
365
+ --color-accent-b: var(--red-400);
366
+ --color-accent-b-light: rgba(239, 68, 68, 0.1);
367
+ --color-accent-b-fg: var(--red-400);
368
+
325
369
  --color-overlay: rgba(0, 0, 0, 0.7);
326
370
 
327
371
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -333,6 +377,72 @@
333
377
  --ring-color: rgba(168, 162, 158, 0.3);
334
378
  }
335
379
 
380
+ /* ── Cool Palette (slate-based, purple-tinted) ────────────── */
381
+ /* Switch from warm zinc to cool slate via data-palette="cool".
382
+ Composable with data-theme: works for both light and dark. */
383
+ [data-palette="cool"] {
384
+ --color-bg: #ffffff;
385
+ --color-bg-secondary: var(--slate-50);
386
+ --color-bg-tertiary: var(--slate-100);
387
+ --color-bg-inverse: var(--slate-950);
388
+
389
+ --color-fg: var(--slate-950);
390
+ --color-fg-secondary: var(--slate-500);
391
+ --color-fg-tertiary: var(--slate-400);
392
+ --color-fg-inverse: #ffffff;
393
+ --color-fg-muted: var(--slate-600);
394
+
395
+ --color-border: var(--slate-200);
396
+ --color-border-strong: var(--slate-300);
397
+ --color-border-subtle: var(--slate-100);
398
+
399
+ --color-surface: #ffffff;
400
+ --color-surface-hover: var(--slate-50);
401
+ --color-surface-active: var(--slate-100);
402
+
403
+ --color-primary: var(--slate-950);
404
+ --color-primary-fg: #ffffff;
405
+ --color-primary-hover: var(--slate-800);
406
+
407
+ --color-secondary: var(--slate-100);
408
+ --color-secondary-fg: var(--slate-900);
409
+ --color-secondary-hover: var(--slate-200);
410
+
411
+ --ring-color: rgba(107, 104, 128, 0.3);
412
+ }
413
+
414
+ /* Cool palette × Dark theme */
415
+ [data-palette="cool"][data-theme="dark"] {
416
+ --color-bg: var(--slate-950);
417
+ --color-bg-secondary: var(--slate-900);
418
+ --color-bg-tertiary: var(--slate-800);
419
+ --color-bg-inverse: #ffffff;
420
+
421
+ --color-fg: var(--slate-50);
422
+ --color-fg-secondary: var(--slate-400);
423
+ --color-fg-tertiary: var(--slate-400);
424
+ --color-fg-inverse: var(--slate-950);
425
+ --color-fg-muted: var(--slate-400);
426
+
427
+ --color-border: var(--slate-800);
428
+ --color-border-strong: var(--slate-700);
429
+ --color-border-subtle: var(--slate-900);
430
+
431
+ --color-surface: var(--slate-900);
432
+ --color-surface-hover: var(--slate-800);
433
+ --color-surface-active: var(--slate-700);
434
+
435
+ --color-primary: #ffffff;
436
+ --color-primary-fg: var(--slate-950);
437
+ --color-primary-hover: var(--slate-200);
438
+
439
+ --color-secondary: var(--slate-800);
440
+ --color-secondary-fg: var(--slate-100);
441
+ --color-secondary-hover: var(--slate-700);
442
+
443
+ --ring-color: rgba(204, 202, 216, 0.3);
444
+ }
445
+
336
446
  /* ── Dark Theme Fallback (JS-disabled) ────────────────────── */
337
447
  /* When JS is unavailable, respect OS dark mode preference.
338
448
  If JS sets data-theme="light", this will NOT apply (thanks to :not()).
@@ -387,6 +497,13 @@
387
497
  --color-info-fg: var(--blue-400);
388
498
  --color-info-strong: var(--blue-500);
389
499
 
500
+ --color-accent-a: var(--blue-400);
501
+ --color-accent-a-light: rgba(59, 130, 246, 0.1);
502
+ --color-accent-a-fg: var(--blue-400);
503
+ --color-accent-b: var(--red-400);
504
+ --color-accent-b-light: rgba(239, 68, 68, 0.1);
505
+ --color-accent-b-fg: var(--red-400);
506
+
390
507
  --color-overlay: rgba(0, 0, 0, 0.7);
391
508
 
392
509
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
package/utilities.css CHANGED
@@ -164,6 +164,36 @@
164
164
  .tabular-nums { font-variant-numeric: tabular-nums; }
165
165
  .font-mono { font-family: var(--font-mono); }
166
166
 
167
+ /* ── Grid Presets ────────────────────────────────────────── */
168
+ .grid--2-col {
169
+ display: grid;
170
+ grid-template-columns: repeat(2, minmax(0, 1fr));
171
+ gap: var(--space-4);
172
+ }
173
+ .grid--3-col {
174
+ display: grid;
175
+ grid-template-columns: repeat(3, minmax(0, 1fr));
176
+ gap: var(--space-4);
177
+ }
178
+ .grid--auto {
179
+ display: grid;
180
+ grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
181
+ gap: var(--space-4);
182
+ }
183
+
184
+ @media (max-width: 767px) {
185
+ .grid--2-col,
186
+ .grid--3-col {
187
+ grid-template-columns: 1fr;
188
+ }
189
+ }
190
+
191
+ /* ── Text Helpers ────────────────────────────────────────── */
192
+ .text--secondary {
193
+ font-size: var(--font-size-xs);
194
+ color: var(--color-fg-secondary);
195
+ }
196
+
167
197
  /* ── Background Colors ───────────────────────────────────── */
168
198
  .bg-primary { background-color: var(--color-bg); }
169
199
  .bg-secondary { background-color: var(--color-bg-secondary); }