kiso 0.5.2.pre → 0.6.0.pre
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.
- checksums.yaml +4 -4
- data/app/assets/tailwind/kiso/button.css +12 -3
- data/app/assets/tailwind/kiso/checkbox.css +13 -2
- data/app/assets/tailwind/kiso/color-mode.css +15 -3
- data/app/assets/tailwind/kiso/dashboard.css +97 -44
- data/app/assets/tailwind/kiso/dialog.css +39 -5
- data/app/assets/tailwind/kiso/engine.css +117 -34
- data/app/assets/tailwind/kiso/input-otp.css +24 -4
- data/app/assets/tailwind/kiso/palettes/blue.css +14 -5
- data/app/assets/tailwind/kiso/palettes/green.css +9 -5
- data/app/assets/tailwind/kiso/palettes/orange.css +9 -5
- data/app/assets/tailwind/kiso/palettes/violet.css +9 -5
- data/app/assets/tailwind/kiso/palettes/zinc.css +11 -7
- data/app/assets/tailwind/kiso/radio-group.css +11 -4
- data/app/assets/tailwind/kiso/slider.css +25 -6
- data/app/assets/tailwind/kiso/tooltip.css +37 -11
- data/app/helpers/kiso/app_component_helper.rb +83 -34
- data/app/helpers/kiso/component_helper.rb +227 -70
- data/app/helpers/kiso/icon_helper.rb +101 -39
- data/app/helpers/kiso/theme_helper.rb +50 -9
- data/app/helpers/kiso/ui_context_helper.rb +87 -35
- data/app/javascript/controllers/kiso/combobox_controller.js +10 -2
- data/app/javascript/controllers/kiso/command_controller.js +2 -0
- data/app/javascript/controllers/kiso/command_dialog_controller.js +4 -0
- data/app/javascript/controllers/kiso/dialog_controller.js +6 -1
- data/app/javascript/controllers/kiso/dialog_trigger_controller.js +1 -1
- data/app/javascript/controllers/kiso/dropdown_menu_controller.js +23 -5
- data/app/javascript/controllers/kiso/index.js +25 -0
- data/app/javascript/controllers/kiso/input_otp_controller.js +5 -3
- data/app/javascript/controllers/kiso/popover_controller.js +18 -4
- data/app/javascript/controllers/kiso/select_controller.js +10 -2
- data/app/javascript/controllers/kiso/sidebar_controller.js +26 -4
- data/app/javascript/controllers/kiso/slider_controller.js +3 -3
- data/app/javascript/controllers/kiso/theme_controller.js +2 -1
- data/app/javascript/controllers/kiso/toggle_controller.js +2 -0
- data/app/javascript/controllers/kiso/toggle_group_controller.js +3 -0
- data/app/javascript/controllers/kiso/tooltip_controller.js +3 -0
- data/app/javascript/kiso/utils/focusable.js +14 -0
- data/app/javascript/kiso/utils/highlight.js +15 -1
- data/app/views/kiso/components/_alert.html.erb +2 -0
- data/app/views/kiso/components/_alert_dialog.html.erb +5 -2
- data/app/views/kiso/components/_app.html.erb +2 -0
- data/app/views/kiso/components/_aspect_ratio.html.erb +1 -0
- data/app/views/kiso/components/_avatar.html.erb +6 -2
- data/app/views/kiso/components/_button.html.erb +3 -0
- data/app/views/kiso/components/_checkbox.html.erb +1 -0
- data/app/views/kiso/components/_color_mode_button.html.erb +2 -0
- data/app/views/kiso/components/_color_mode_select.html.erb +2 -0
- data/app/views/kiso/components/_combobox.html.erb +3 -0
- data/app/views/kiso/components/_command.html.erb +2 -0
- data/app/views/kiso/components/_dashboard_group.html.erb +4 -0
- data/app/views/kiso/components/_dashboard_navbar.html.erb +2 -0
- data/app/views/kiso/components/_dashboard_panel.html.erb +1 -0
- data/app/views/kiso/components/_dashboard_sidebar.html.erb +2 -0
- data/app/views/kiso/components/_dashboard_toolbar.html.erb +2 -0
- data/app/views/kiso/components/_dialog.html.erb +3 -0
- data/app/views/kiso/components/_dropdown_menu.html.erb +2 -0
- data/app/views/kiso/components/_empty.html.erb +2 -0
- data/app/views/kiso/components/_field.html.erb +2 -0
- data/app/views/kiso/components/_field_group.html.erb +1 -0
- data/app/views/kiso/components/_field_set.html.erb +1 -0
- data/app/views/kiso/components/_input_group.html.erb +1 -0
- data/app/views/kiso/components/_input_otp.html.erb +3 -0
- data/app/views/kiso/components/_nav.html.erb +2 -0
- data/app/views/kiso/components/_page_card.html.erb +3 -0
- data/app/views/kiso/components/_page_header.html.erb +3 -0
- data/app/views/kiso/components/_page_section.html.erb +2 -0
- data/app/views/kiso/components/_pagination.html.erb +2 -0
- data/app/views/kiso/components/_popover.html.erb +3 -0
- data/app/views/kiso/components/_select.html.erb +3 -0
- data/app/views/kiso/components/_select_native.html.erb +2 -0
- data/app/views/kiso/components/_separator.html.erb +2 -0
- data/app/views/kiso/components/_skeleton.html.erb +1 -0
- data/app/views/kiso/components/_slider.html.erb +4 -0
- data/app/views/kiso/components/_spinner.html.erb +2 -0
- data/app/views/kiso/components/_stats_card.html.erb +2 -0
- data/app/views/kiso/components/_stats_grid.html.erb +1 -0
- data/app/views/kiso/components/_switch.html.erb +2 -0
- data/app/views/kiso/components/_table.html.erb +2 -0
- data/app/views/kiso/components/_textarea.html.erb +3 -0
- data/app/views/kiso/components/_toggle.html.erb +2 -0
- data/app/views/kiso/components/_toggle_group.html.erb +2 -0
- data/app/views/kiso/components/_tooltip.html.erb +3 -0
- data/app/views/kiso/components/alert_dialog/_action.html.erb +1 -0
- data/app/views/kiso/components/alert_dialog/_cancel.html.erb +1 -0
- data/app/views/kiso/components/alert_dialog/_description.html.erb +1 -0
- data/app/views/kiso/components/alert_dialog/_title.html.erb +1 -0
- data/app/views/kiso/components/avatar/_image.html.erb +1 -0
- data/app/views/kiso/components/breadcrumb/_separator.html.erb +3 -0
- data/app/views/kiso/components/combobox/_chips.html.erb +3 -0
- data/app/views/kiso/components/command/_dialog.html.erb +2 -0
- data/app/views/kiso/components/dashboard_sidebar/_collapse.html.erb +2 -0
- data/app/views/kiso/components/dialog/_close.html.erb +1 -0
- data/app/views/kiso/components/field/_error.html.erb +4 -0
- data/app/views/kiso/components/field/_label.html.erb +2 -0
- data/app/views/kiso/components/field/_separator.html.erb +3 -0
- data/app/views/kiso/components/input_otp/_separator.html.erb +2 -0
- data/app/views/kiso/components/input_otp/_slot.html.erb +2 -0
- data/app/views/kiso/components/nav/_section.html.erb +4 -0
- data/app/views/kiso/components/tooltip/_content.html.erb +2 -0
- data/lib/generators/kiso/install/USAGE +23 -0
- data/lib/generators/kiso/install/install_generator.rb +91 -0
- data/lib/generators/kiso/install/templates/design_system.md.tt +190 -0
- data/lib/generators/kiso/install/templates/initializer.rb.tt +40 -0
- data/lib/kiso/cli/make.rb +6 -3
- data/lib/kiso/cli.rb +10 -0
- data/lib/kiso/color_utils.rb +31 -8
- data/lib/kiso/configuration.rb +11 -0
- data/lib/kiso/engine.rb +9 -2
- data/lib/kiso/propshaft_tailwind_stub_filter.rb +9 -2
- data/lib/kiso/themes/avatar.rb +40 -6
- data/lib/kiso/themes/badge.rb +5 -1
- data/lib/kiso/themes/color_mode_button.rb +11 -0
- data/lib/kiso/themes/color_mode_select.rb +7 -0
- data/lib/kiso/themes/dashboard.rb +28 -0
- data/lib/kiso/themes/dropdown_menu.rb +2 -2
- data/lib/kiso/themes/input_otp.rb +6 -3
- data/lib/kiso/themes/nav.rb +17 -0
- data/lib/kiso/themes/pagination.rb +9 -4
- data/lib/kiso/themes/shared.rb +27 -7
- data/lib/kiso/version.rb +5 -2
- metadata +5 -1
|
@@ -1,7 +1,23 @@
|
|
|
1
|
-
/* Kiso Engine CSS
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/* ── Kiso Engine CSS ──────────────────────────────────────────────────────────
|
|
2
|
+
Main entry point for Kiso's CSS, imported by host apps via tailwindcss-rails
|
|
3
|
+
engine bundling. This file aggregates:
|
|
4
|
+
|
|
5
|
+
1. Per-component CSS for transitions, animations, pseudo-states, and layout
|
|
6
|
+
mechanics that ERB partials cannot express (most styling lives in Ruby
|
|
7
|
+
theme modules at lib/kiso/themes/ as computed Tailwind classes).
|
|
8
|
+
2. Tailwind @source directives so the engine's own class references are
|
|
9
|
+
scanned during the host app's Tailwind build.
|
|
10
|
+
3. @font-face declarations for the Geist typeface family.
|
|
11
|
+
4. @theme blocks defining structural tokens (radius, container) and the full
|
|
12
|
+
semantic color system (light + dark mode via .dark class).
|
|
13
|
+
5. @layer base defaults for <body>.
|
|
14
|
+
──────────────────────────────────────────────────────────────────────────── */
|
|
15
|
+
|
|
16
|
+
/* === Component CSS Imports ===
|
|
17
|
+
Each file handles CSS-only concerns for a specific component or component
|
|
18
|
+
family: animations, pseudo-element indicators, popover overrides, layout
|
|
19
|
+
grid mechanics, etc. If a component needs no CSS beyond Tailwind utilities,
|
|
20
|
+
it does not have a file here. */
|
|
5
21
|
|
|
6
22
|
@import "./button.css";
|
|
7
23
|
@import "./checkbox.css";
|
|
@@ -13,18 +29,22 @@
|
|
|
13
29
|
@import "./slider.css";
|
|
14
30
|
@import "./tooltip.css";
|
|
15
31
|
|
|
16
|
-
/*
|
|
32
|
+
/* === Tailwind Source Scanning ===
|
|
33
|
+
Tell Tailwind v4 to scan Kiso's own source files for class references.
|
|
34
|
+
Without these, utility classes referenced in ERB partials, helpers, theme
|
|
35
|
+
modules, and presets would not be generated in the host app's CSS output.
|
|
17
36
|
Paths are relative to THIS file (app/assets/tailwind/kiso/engine.css).
|
|
18
|
-
|
|
37
|
+
WARNING: wrong paths fail SILENTLY — classes simply won't generate. */
|
|
19
38
|
@source "../../../views"; /* → app/views */
|
|
20
39
|
@source "../../../helpers"; /* → app/helpers */
|
|
21
40
|
@source "../../../../lib/kiso/themes"; /* → lib/kiso/themes */
|
|
22
41
|
@source "../../../../lib/kiso/presets"; /* → lib/kiso/presets */
|
|
23
42
|
|
|
24
43
|
/* === Geist Font (by Vercel) ===
|
|
25
|
-
Self-hosted variable fonts — no CDN
|
|
26
|
-
Licensed under the SIL Open Font License (see OFL.txt
|
|
27
|
-
Host apps can override --font-sans / --font-mono in their
|
|
44
|
+
Self-hosted variable fonts loaded from the engine's asset pipeline — no CDN
|
|
45
|
+
dependency. Licensed under the SIL Open Font License (see OFL.txt in the
|
|
46
|
+
fonts directory). Host apps can override --font-sans / --font-mono in their
|
|
47
|
+
own @theme block to use a different typeface. */
|
|
28
48
|
|
|
29
49
|
@font-face {
|
|
30
50
|
font-family: "Geist";
|
|
@@ -42,20 +62,61 @@
|
|
|
42
62
|
src: url("/kiso/GeistMonoVF.woff2") format("woff2");
|
|
43
63
|
}
|
|
44
64
|
|
|
45
|
-
/*
|
|
46
|
-
|
|
65
|
+
/* Register Geist as the default sans and mono font stacks.
|
|
66
|
+
Using @theme inline so these values are inlined into the generated CSS
|
|
67
|
+
rather than emitted as separate custom properties (reduces output size).
|
|
68
|
+
Host apps can override by redefining --font-sans / --font-mono in their
|
|
69
|
+
own @theme block — Tailwind v4 merges @theme blocks, last definition wins. */
|
|
47
70
|
@theme inline {
|
|
48
71
|
--font-sans: "Geist", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
49
72
|
--font-mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
50
73
|
}
|
|
51
74
|
|
|
75
|
+
/* === Structural Tokens ===
|
|
76
|
+
Framework-level layout primitives that host apps can tune. These are
|
|
77
|
+
namespaced with --kiso- to avoid collisions with Tailwind's own variables.
|
|
78
|
+
Override in the host app's own @theme block:
|
|
79
|
+
@theme { --kiso-radius: 0.5rem; --kiso-container: 64rem; } */
|
|
80
|
+
|
|
81
|
+
@theme {
|
|
82
|
+
/* Base radius unit — the single knob that controls the entire border-radius
|
|
83
|
+
scale. Namespaced as --kiso-radius (our variable) vs --radius-* (Tailwind's
|
|
84
|
+
built-in scale that we override below). */
|
|
85
|
+
--kiso-radius: 0.25rem;
|
|
86
|
+
|
|
87
|
+
/* Maximum content width, used by the Container component. */
|
|
88
|
+
--kiso-container: 80rem;
|
|
89
|
+
|
|
90
|
+
/* Computed radius scale — overrides Tailwind's built-in --radius-* variables
|
|
91
|
+
with values derived from --kiso-radius using the same multiplier system as
|
|
92
|
+
Nuxt UI's --ui-radius. This wires rounded-sm, rounded-md, rounded-lg, etc.
|
|
93
|
+
through our base variable so changing --kiso-radius shifts every component's
|
|
94
|
+
border-radius proportionally.
|
|
95
|
+
|
|
96
|
+
At the default 0.25rem, computed values match Tailwind's defaults exactly,
|
|
97
|
+
making this invisible until a host app changes --kiso-radius. */
|
|
98
|
+
--radius-xs: calc(var(--kiso-radius) * 0.5); /* 0.125rem */
|
|
99
|
+
--radius-sm: var(--kiso-radius); /* 0.25rem */
|
|
100
|
+
--radius-md: calc(var(--kiso-radius) * 1.5); /* 0.375rem */
|
|
101
|
+
--radius-lg: calc(var(--kiso-radius) * 2); /* 0.5rem */
|
|
102
|
+
--radius-xl: calc(var(--kiso-radius) * 3); /* 0.75rem */
|
|
103
|
+
--radius-2xl: calc(var(--kiso-radius) * 4); /* 1rem */
|
|
104
|
+
--radius-3xl: calc(var(--kiso-radius) * 6); /* 1.5rem */
|
|
105
|
+
--radius-4xl: calc(var(--kiso-radius) * 8); /* 2rem */
|
|
106
|
+
}
|
|
107
|
+
|
|
52
108
|
/* === Semantic Color Tokens ===
|
|
53
|
-
Purpose-named
|
|
54
|
-
|
|
109
|
+
Purpose-named CSS custom properties that flip automatically in dark mode
|
|
110
|
+
(via the .dark class below). Components reference these tokens through
|
|
111
|
+
Tailwind utilities — bg-primary, text-foreground, border-border, etc. —
|
|
112
|
+
and never use raw palette shades or Tailwind dark: prefixes.
|
|
55
113
|
|
|
56
|
-
|
|
114
|
+
Each semantic color has a -foreground companion for accessible text pairing:
|
|
115
|
+
bg-primary + text-primary-foreground is always readable.
|
|
57
116
|
|
|
58
|
-
|
|
117
|
+
Host apps can customize brand colors in two ways:
|
|
118
|
+
|
|
119
|
+
1. Define a shade scale (Tailwind-native approach):
|
|
59
120
|
@theme {
|
|
60
121
|
--color-primary-50: oklch(...);
|
|
61
122
|
--color-primary-500: oklch(...);
|
|
@@ -66,10 +127,15 @@
|
|
|
66
127
|
|
|
67
128
|
2. Override the semantic token directly:
|
|
68
129
|
@theme { --color-primary: oklch(0.55 0.10 237); }
|
|
130
|
+
|
|
131
|
+
See project/design-system.md for the full token table and compound variant
|
|
132
|
+
formulas that use these tokens.
|
|
69
133
|
*/
|
|
70
134
|
|
|
71
135
|
@theme {
|
|
72
|
-
/* Brand /
|
|
136
|
+
/* ── Brand / Action Colors ──
|
|
137
|
+
Auto-wire from shade scale (if host defines --color-*-500 etc.),
|
|
138
|
+
falling back to Tailwind's built-in palette colors as defaults. */
|
|
73
139
|
--color-primary: var(--color-primary-500, var(--color-rose-500));
|
|
74
140
|
--color-primary-foreground: var(--color-primary-50, white);
|
|
75
141
|
|
|
@@ -88,31 +154,40 @@
|
|
|
88
154
|
--color-error: var(--color-error-500, var(--color-red-600));
|
|
89
155
|
--color-error-foreground: var(--color-error-50, white);
|
|
90
156
|
|
|
91
|
-
/* Surface
|
|
92
|
-
|
|
93
|
-
|
|
157
|
+
/* ── Surface Tokens ──
|
|
158
|
+
Neutral tokens for page backgrounds, text, borders, and UI chrome.
|
|
159
|
+
These map to Tailwind's zinc scale by default. */
|
|
160
|
+
--color-background: white; /* Page background */
|
|
161
|
+
--color-foreground: var(--color-zinc-950); /* Default text color */
|
|
94
162
|
|
|
95
|
-
--color-muted: var(--color-zinc-100);
|
|
96
|
-
--color-muted-foreground: var(--color-zinc-500);
|
|
163
|
+
--color-muted: var(--color-zinc-100); /* Subdued backgrounds (e.g., table headers) */
|
|
164
|
+
--color-muted-foreground: var(--color-zinc-500); /* Secondary/helper text */
|
|
97
165
|
|
|
98
|
-
--color-accent: var(--color-zinc-100);
|
|
99
|
-
--color-accent-foreground: var(--color-zinc-900);
|
|
166
|
+
--color-accent: var(--color-zinc-100); /* Interactive hover backgrounds */
|
|
167
|
+
--color-accent-foreground: var(--color-zinc-900); /* Text on accent backgrounds */
|
|
100
168
|
|
|
101
|
-
--color-inverted: var(--color-zinc-900);
|
|
102
|
-
--color-inverted-foreground: white;
|
|
103
|
-
--color-elevated: var(--color-zinc-100);
|
|
104
|
-
--color-accented: var(--color-zinc-300);
|
|
169
|
+
--color-inverted: var(--color-zinc-900); /* Inverse surface (solid neutral variant bg) */
|
|
170
|
+
--color-inverted-foreground: white; /* Text on inverted surface */
|
|
171
|
+
--color-elevated: var(--color-zinc-100); /* Soft/subtle neutral variant background */
|
|
172
|
+
--color-accented: var(--color-zinc-300); /* Subtle neutral variant ring color */
|
|
105
173
|
|
|
106
|
-
--color-border: var(--color-zinc-200);
|
|
107
|
-
--color-border-accented: var(--color-zinc-300);
|
|
174
|
+
--color-border: var(--color-zinc-200); /* Default borders (cards, inputs) */
|
|
175
|
+
--color-border-accented: var(--color-zinc-300); /* Emphasized borders */
|
|
108
176
|
|
|
109
|
-
--color-ring: var(--color-zinc-400);
|
|
177
|
+
--color-ring: var(--color-zinc-400); /* Focus rings */
|
|
110
178
|
}
|
|
111
179
|
|
|
112
180
|
/* === Dark Mode ===
|
|
113
|
-
Redefine
|
|
181
|
+
Redefine every semantic token under .dark so components never need Tailwind
|
|
182
|
+
dark: prefixes. The .dark class is set on <html> by kiso_theme_script (a
|
|
183
|
+
blocking inline script that runs before first paint to avoid FOUC).
|
|
184
|
+
|
|
185
|
+
Brand colors shift from shade 500 → 400 (brighter on dark backgrounds).
|
|
186
|
+
Foreground companions shift from shade 50 → 950 (dark text on bright bg).
|
|
187
|
+
Surface tokens invert: light grays become dark grays, white becomes near-black. */
|
|
114
188
|
|
|
115
189
|
.dark {
|
|
190
|
+
/* ── Brand / Action Colors (dark) ── */
|
|
116
191
|
--color-primary: var(--color-primary-400, var(--color-rose-400));
|
|
117
192
|
--color-primary-foreground: var(--color-primary-950, var(--color-zinc-950));
|
|
118
193
|
|
|
@@ -131,6 +206,7 @@
|
|
|
131
206
|
--color-error: var(--color-error-400, var(--color-red-400));
|
|
132
207
|
--color-error-foreground: var(--color-error-950, var(--color-zinc-950));
|
|
133
208
|
|
|
209
|
+
/* ── Surface Tokens (dark) ── */
|
|
134
210
|
--color-background: var(--color-zinc-950);
|
|
135
211
|
--color-foreground: var(--color-zinc-50);
|
|
136
212
|
|
|
@@ -152,9 +228,16 @@
|
|
|
152
228
|
}
|
|
153
229
|
|
|
154
230
|
/* === Page Defaults ===
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
231
|
+
Apply sensible base styles to <body> so host apps start with the correct
|
|
232
|
+
semantic colors and font rendering. Uses @layer base (lowest Tailwind
|
|
233
|
+
priority) so any utility classes on <body> override automatically.
|
|
234
|
+
|
|
235
|
+
- bg-background / text-foreground: wires semantic tokens, auto-flips in
|
|
236
|
+
dark mode without host app doing anything
|
|
237
|
+
- antialiased: subpixel rendering for crisp text
|
|
238
|
+
- font-synthesis-weight: none: prevents browsers from synthesizing bold
|
|
239
|
+
weights for the variable font (Geist handles all weights natively)
|
|
240
|
+
- text-rendering: optimizeLegibility: enables kerning and ligatures */
|
|
158
241
|
|
|
159
242
|
@layer base {
|
|
160
243
|
body {
|
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
/*
|
|
1
|
+
/* ── Input OTP ───────────────────────────────────────────────────────────────
|
|
2
|
+
Caret animation and separator-adjacent border-radius for the OTP input
|
|
3
|
+
component (kui(:input_otp)).
|
|
4
|
+
|
|
5
|
+
Why CSS instead of ERB?
|
|
6
|
+
1. The blinking caret requires a @keyframes animation.
|
|
7
|
+
2. Separator-adjacent slot rounding requires :has() and adjacent-sibling
|
|
8
|
+
selectors, which cannot be expressed as Tailwind utility classes.
|
|
9
|
+
──────────────────────────────────────────────────────────────────────────── */
|
|
10
|
+
|
|
11
|
+
/* ── Caret blink animation ─────────────────────────────────────────────────
|
|
12
|
+
A blinking cursor shown in the active (focused, empty) OTP slot. Registered
|
|
13
|
+
as a Tailwind animation token via @theme inline so it can be applied with
|
|
14
|
+
the `animate-caret-blink` utility class in the theme module. */
|
|
2
15
|
|
|
3
16
|
@theme inline {
|
|
4
17
|
--animate-caret-blink: caret-blink 1s ease-out infinite;
|
|
@@ -9,9 +22,16 @@
|
|
|
9
22
|
20%, 50% { opacity: 0; }
|
|
10
23
|
}
|
|
11
24
|
|
|
12
|
-
/* Separator-adjacent rounding
|
|
13
|
-
|
|
14
|
-
|
|
25
|
+
/* ── Separator-adjacent slot rounding ──────────────────────────────────────
|
|
26
|
+
OTP slots are visually joined (negative margin, no individual rounding) to
|
|
27
|
+
form a continuous row. When a separator element sits between slots, the
|
|
28
|
+
slots on either side of it need rounded corners to form distinct visual
|
|
29
|
+
groups. The :has() selector rounds the right edge of the slot before a
|
|
30
|
+
separator, and the adjacent-sibling selector rounds the left edge of the
|
|
31
|
+
slot after a separator (and resets its negative margin).
|
|
32
|
+
|
|
33
|
+
Uses @layer utilities so these rules participate in Tailwind's specificity
|
|
34
|
+
layer, matching the border-radius utilities used on the first/last slots. */
|
|
15
35
|
|
|
16
36
|
@layer utilities {
|
|
17
37
|
[data-slot="input-otp-slot"]:has(+ [data-slot="input-otp-separator"]) {
|
|
@@ -1,21 +1,29 @@
|
|
|
1
|
-
/* Kiso Color Palette: Blue
|
|
1
|
+
/* ── Kiso Color Palette: Blue ─────────────────────────────────────────────────
|
|
2
2
|
A professional blue palette — classic SaaS/enterprise feel.
|
|
3
3
|
Based on shadcn/ui's Blue theme with OKLCH color values.
|
|
4
4
|
|
|
5
|
+
Palettes override Kiso's default semantic color tokens (defined in engine.css)
|
|
6
|
+
using a [data-palette] attribute selector. This lets host apps switch color
|
|
7
|
+
schemes without redefining @theme variables.
|
|
8
|
+
|
|
5
9
|
Usage:
|
|
6
|
-
1. Import in your CSS: @import "
|
|
10
|
+
1. Import in your Tailwind CSS: @import "kiso/palettes/blue.css";
|
|
7
11
|
2. Add to your HTML: <html data-palette="blue"> or <body data-palette="blue">
|
|
8
|
-
|
|
12
|
+
|
|
13
|
+
Dark mode is handled by a companion rule below that targets either
|
|
14
|
+
`.dark [data-palette="blue"]` (dark class on an ancestor) or
|
|
15
|
+
`[data-palette="blue"].dark` (dark class on the same element).
|
|
16
|
+
──────────────────────────────────────────────────────────────────────────── */
|
|
9
17
|
|
|
10
18
|
[data-palette="blue"] {
|
|
11
|
-
/* Brand / action colors — vibrant blue */
|
|
19
|
+
/* ── Brand / action colors — vibrant blue ── */
|
|
12
20
|
--color-primary: oklch(0.488 0.243 264.376);
|
|
13
21
|
--color-primary-foreground: oklch(0.97 0.014 254.604);
|
|
14
22
|
|
|
15
23
|
--color-secondary: oklch(0.967 0.001 286.375);
|
|
16
24
|
--color-secondary-foreground: oklch(0.21 0.006 285.885);
|
|
17
25
|
|
|
18
|
-
/* Surface tokens — slate-tinted neutrals */
|
|
26
|
+
/* ── Surface tokens — slate-tinted neutrals ── */
|
|
19
27
|
--color-background: oklch(1 0 0);
|
|
20
28
|
--color-foreground: oklch(0.13 0.028 261.692);
|
|
21
29
|
|
|
@@ -36,6 +44,7 @@
|
|
|
36
44
|
--color-ring: oklch(0.488 0.243 264.376);
|
|
37
45
|
}
|
|
38
46
|
|
|
47
|
+
/* Dark mode overrides */
|
|
39
48
|
.dark [data-palette="blue"],
|
|
40
49
|
[data-palette="blue"].dark {
|
|
41
50
|
--color-primary: oklch(0.42 0.18 266);
|
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
/* Kiso Color Palette: Green
|
|
1
|
+
/* ── Kiso Color Palette: Green ────────────────────────────────────────────────
|
|
2
2
|
A fresh, natural green palette — great for eco, health, or finance apps.
|
|
3
3
|
Based on shadcn/ui's Green theme with OKLCH color values.
|
|
4
4
|
|
|
5
|
+
Palettes override Kiso's default semantic color tokens (defined in engine.css)
|
|
6
|
+
using a [data-palette] attribute selector. See blue.css for full documentation.
|
|
7
|
+
|
|
5
8
|
Usage:
|
|
6
|
-
1. Import in your CSS: @import "
|
|
9
|
+
1. Import in your Tailwind CSS: @import "kiso/palettes/green.css";
|
|
7
10
|
2. Add to your HTML: <html data-palette="green"> or <body data-palette="green">
|
|
8
|
-
*/
|
|
11
|
+
──────────────────────────────────────────────────────────────────────────── */
|
|
9
12
|
|
|
10
13
|
[data-palette="green"] {
|
|
11
|
-
/* Brand / action colors — vivid green */
|
|
14
|
+
/* ── Brand / action colors — vivid green ── */
|
|
12
15
|
--color-primary: oklch(0.648 0.2 131.684);
|
|
13
16
|
--color-primary-foreground: oklch(0.986 0.031 120.757);
|
|
14
17
|
|
|
15
18
|
--color-secondary: oklch(0.967 0.001 286.375);
|
|
16
19
|
--color-secondary-foreground: oklch(0.21 0.006 285.885);
|
|
17
20
|
|
|
18
|
-
/* Surface tokens — zinc neutrals */
|
|
21
|
+
/* ── Surface tokens — zinc neutrals ── */
|
|
19
22
|
--color-background: oklch(1 0 0);
|
|
20
23
|
--color-foreground: oklch(0.141 0.005 285.823);
|
|
21
24
|
|
|
@@ -36,6 +39,7 @@
|
|
|
36
39
|
--color-ring: oklch(0.648 0.2 131.684);
|
|
37
40
|
}
|
|
38
41
|
|
|
42
|
+
/* Dark mode overrides */
|
|
39
43
|
.dark [data-palette="green"],
|
|
40
44
|
[data-palette="green"].dark {
|
|
41
45
|
--color-primary: oklch(0.648 0.2 131.684);
|
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
/* Kiso Color Palette: Orange
|
|
1
|
+
/* ── Kiso Color Palette: Orange ───────────────────────────────────────────────
|
|
2
2
|
A warm, energetic palette — great for creative, food, or community apps.
|
|
3
3
|
Based on shadcn/ui's Orange theme with OKLCH color values.
|
|
4
4
|
|
|
5
|
+
Palettes override Kiso's default semantic color tokens (defined in engine.css)
|
|
6
|
+
using a [data-palette] attribute selector. See blue.css for full documentation.
|
|
7
|
+
|
|
5
8
|
Usage:
|
|
6
|
-
1. Import in your CSS: @import "
|
|
9
|
+
1. Import in your Tailwind CSS: @import "kiso/palettes/orange.css";
|
|
7
10
|
2. Add to your HTML: <html data-palette="orange"> or <body data-palette="orange">
|
|
8
|
-
*/
|
|
11
|
+
──────────────────────────────────────────────────────────────────────────── */
|
|
9
12
|
|
|
10
13
|
[data-palette="orange"] {
|
|
11
|
-
/* Brand / action colors — warm orange */
|
|
14
|
+
/* ── Brand / action colors — warm orange ── */
|
|
12
15
|
--color-primary: oklch(0.646 0.222 41.116);
|
|
13
16
|
--color-primary-foreground: oklch(0.98 0.016 73.684);
|
|
14
17
|
|
|
15
18
|
--color-secondary: oklch(0.97 0.001 106.424);
|
|
16
19
|
--color-secondary-foreground: oklch(0.216 0.006 56.043);
|
|
17
20
|
|
|
18
|
-
/* Surface tokens — warm stone neutrals */
|
|
21
|
+
/* ── Surface tokens — warm stone neutrals ── */
|
|
19
22
|
--color-background: oklch(1 0 0);
|
|
20
23
|
--color-foreground: oklch(0.147 0.004 49.25);
|
|
21
24
|
|
|
@@ -36,6 +39,7 @@
|
|
|
36
39
|
--color-ring: oklch(0.646 0.222 41.116);
|
|
37
40
|
}
|
|
38
41
|
|
|
42
|
+
/* Dark mode overrides */
|
|
39
43
|
.dark [data-palette="orange"],
|
|
40
44
|
[data-palette="orange"].dark {
|
|
41
45
|
--color-primary: oklch(0.705 0.213 47.604);
|
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
/* Kiso Color Palette: Violet
|
|
1
|
+
/* ── Kiso Color Palette: Violet ───────────────────────────────────────────────
|
|
2
2
|
A rich, creative purple palette — great for design tools or premium brands.
|
|
3
3
|
Based on shadcn/ui's Violet theme with OKLCH color values.
|
|
4
4
|
|
|
5
|
+
Palettes override Kiso's default semantic color tokens (defined in engine.css)
|
|
6
|
+
using a [data-palette] attribute selector. See blue.css for full documentation.
|
|
7
|
+
|
|
5
8
|
Usage:
|
|
6
|
-
1. Import in your CSS: @import "
|
|
9
|
+
1. Import in your Tailwind CSS: @import "kiso/palettes/violet.css";
|
|
7
10
|
2. Add to your HTML: <html data-palette="violet"> or <body data-palette="violet">
|
|
8
|
-
*/
|
|
11
|
+
──────────────────────────────────────────────────────────────────────────── */
|
|
9
12
|
|
|
10
13
|
[data-palette="violet"] {
|
|
11
|
-
/* Brand / action colors — vivid violet */
|
|
14
|
+
/* ── Brand / action colors — vivid violet ── */
|
|
12
15
|
--color-primary: oklch(0.541 0.281 293.009);
|
|
13
16
|
--color-primary-foreground: oklch(0.969 0.016 293.756);
|
|
14
17
|
|
|
15
18
|
--color-secondary: oklch(0.967 0.001 286.375);
|
|
16
19
|
--color-secondary-foreground: oklch(0.21 0.006 285.885);
|
|
17
20
|
|
|
18
|
-
/* Surface tokens — gray neutrals */
|
|
21
|
+
/* ── Surface tokens — gray neutrals ── */
|
|
19
22
|
--color-background: oklch(1 0 0);
|
|
20
23
|
--color-foreground: oklch(0.13 0.028 261.692);
|
|
21
24
|
|
|
@@ -36,6 +39,7 @@
|
|
|
36
39
|
--color-ring: oklch(0.541 0.281 293.009);
|
|
37
40
|
}
|
|
38
41
|
|
|
42
|
+
/* Dark mode overrides */
|
|
39
43
|
.dark [data-palette="violet"],
|
|
40
44
|
[data-palette="violet"].dark {
|
|
41
45
|
--color-primary: oklch(0.606 0.25 292.717);
|
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
/* Kiso Color Palette: Zinc
|
|
2
|
-
A neutral, cool-toned palette using the Zinc scale
|
|
3
|
-
Based on shadcn/ui's Zinc theme with OKLCH
|
|
1
|
+
/* ── Kiso Color Palette: Zinc ─────────────────────────────────────────────────
|
|
2
|
+
A neutral, cool-toned palette using the Zinc scale — minimal color,
|
|
3
|
+
maximum content focus. Based on shadcn/ui's Zinc theme with OKLCH values.
|
|
4
|
+
|
|
5
|
+
Palettes override Kiso's default semantic color tokens (defined in engine.css)
|
|
6
|
+
using a [data-palette] attribute selector. See blue.css for full documentation.
|
|
4
7
|
|
|
5
8
|
Usage:
|
|
6
|
-
1. Import in your CSS: @import "
|
|
9
|
+
1. Import in your Tailwind CSS: @import "kiso/palettes/zinc.css";
|
|
7
10
|
2. Add to your HTML: <html data-palette="zinc"> or <body data-palette="zinc">
|
|
8
|
-
*/
|
|
11
|
+
──────────────────────────────────────────────────────────────────────────── */
|
|
9
12
|
|
|
10
13
|
[data-palette="zinc"] {
|
|
11
|
-
/* Brand / action colors —
|
|
14
|
+
/* ── Brand / action colors — near-black primary (inverts in dark mode) ── */
|
|
12
15
|
--color-primary: oklch(0.21 0.006 285.885);
|
|
13
16
|
--color-primary-foreground: oklch(0.985 0 0);
|
|
14
17
|
|
|
15
18
|
--color-secondary: oklch(0.967 0.001 286.375);
|
|
16
19
|
--color-secondary-foreground: oklch(0.21 0.006 285.885);
|
|
17
20
|
|
|
18
|
-
/* Surface tokens */
|
|
21
|
+
/* ── Surface tokens ── */
|
|
19
22
|
--color-background: oklch(1 0 0);
|
|
20
23
|
--color-foreground: oklch(0.141 0.005 285.823);
|
|
21
24
|
|
|
@@ -36,6 +39,7 @@
|
|
|
36
39
|
--color-ring: oklch(0.705 0.015 286.067);
|
|
37
40
|
}
|
|
38
41
|
|
|
42
|
+
/* Dark mode overrides */
|
|
39
43
|
.dark [data-palette="zinc"],
|
|
40
44
|
[data-palette="zinc"].dark {
|
|
41
45
|
--color-primary: oklch(0.92 0.004 286.32);
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
/*
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/* ── Radio Group ─────────────────────────────────────────────────────────────
|
|
2
|
+
Filled-circle indicator via CSS ::after pseudo-element for radio inputs.
|
|
3
|
+
|
|
4
|
+
Why CSS instead of ERB?
|
|
5
|
+
Native <input type="radio"> cannot contain child elements, so the selected
|
|
6
|
+
indicator dot must be rendered as a pseudo-element. Same pattern as
|
|
7
|
+
Checkbox — uses currentColor for the fill, which inherits the text color
|
|
8
|
+
set by compound variants (e.g., checked:text-primary-foreground).
|
|
9
|
+
|
|
10
|
+
The grid + place-content: center pattern centers the ::after dot within
|
|
11
|
+
the radio circle regardless of its size variant. */
|
|
5
12
|
|
|
6
13
|
[data-radio-group-part="item"] {
|
|
7
14
|
display: grid;
|
|
@@ -1,25 +1,44 @@
|
|
|
1
|
+
/* ── Slider ──────────────────────────────────────────────────────────────────
|
|
2
|
+
Thumb positioning and disabled state for the custom Slider component.
|
|
3
|
+
|
|
4
|
+
Why CSS instead of ERB?
|
|
5
|
+
The slider thumb is positioned via inline `left: N%` styles set by the
|
|
6
|
+
kiso--slider Stimulus controller. CSS handles the centering transform
|
|
7
|
+
(translateX(-50%)) and vertical alignment that must work in concert with
|
|
8
|
+
that dynamic inline style. The disabled state uses :has(input:disabled)
|
|
9
|
+
which cannot be expressed as a Tailwind utility.
|
|
10
|
+
|
|
11
|
+
Uses @layer components so utility classes can override if needed.
|
|
12
|
+
──────────────────────────────────────────────────────────────────────────── */
|
|
13
|
+
|
|
1
14
|
@layer components {
|
|
2
|
-
/* Center the thumb over its left % position
|
|
15
|
+
/* Center the thumb horizontally over its left % position, and vertically
|
|
16
|
+
within the track. The negative margin-top pulls the thumb up by half
|
|
17
|
+
its own height (--thumb-offset) so it sits centered on the track line. */
|
|
3
18
|
[data-slot="slider-thumb"] {
|
|
4
19
|
transform: translateX(-50%);
|
|
5
20
|
top: 50%;
|
|
6
21
|
margin-top: calc(-1 * var(--thumb-offset, 0.5rem));
|
|
7
22
|
}
|
|
8
23
|
|
|
9
|
-
/* Size-specific thumb offsets
|
|
24
|
+
/* Size-specific thumb offsets — each size variant has a different thumb
|
|
25
|
+
diameter, so the vertical centering offset must match. Uses :where()
|
|
26
|
+
to keep specificity low (0,0,0 for the class selector), allowing
|
|
27
|
+
the theme module's size classes to remain the authority on thumb size. */
|
|
10
28
|
[data-slot="slider"] :where([data-slot="slider-thumb"].size-3) {
|
|
11
|
-
--thumb-offset: 0.375rem;
|
|
29
|
+
--thumb-offset: 0.375rem; /* half of 0.75rem (size-3) */
|
|
12
30
|
}
|
|
13
31
|
|
|
14
32
|
[data-slot="slider"] :where([data-slot="slider-thumb"].size-4) {
|
|
15
|
-
--thumb-offset: 0.5rem;
|
|
33
|
+
--thumb-offset: 0.5rem; /* half of 1rem (size-4) */
|
|
16
34
|
}
|
|
17
35
|
|
|
18
36
|
[data-slot="slider"] :where([data-slot="slider-thumb"].size-5) {
|
|
19
|
-
--thumb-offset: 0.625rem;
|
|
37
|
+
--thumb-offset: 0.625rem; /* half of 1.25rem (size-5) */
|
|
20
38
|
}
|
|
21
39
|
|
|
22
|
-
/* Disabled state
|
|
40
|
+
/* Disabled state — dim the entire slider and prevent interaction.
|
|
41
|
+
Uses :has(input:disabled) to detect the hidden range input's state. */
|
|
23
42
|
[data-slot="slider"]:has(input:disabled) {
|
|
24
43
|
opacity: 0.5;
|
|
25
44
|
pointer-events: none;
|
|
@@ -1,33 +1,57 @@
|
|
|
1
|
-
/* Tooltip
|
|
1
|
+
/* ── Tooltip ─────────────────────────────────────────────────────────────────
|
|
2
|
+
Display overrides, popover UA stylesheet resets, entry/exit animations,
|
|
3
|
+
and reduced-motion support for the Tooltip component.
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
Why CSS instead of ERB?
|
|
6
|
+
Tooltips use [popover="manual"] for positioning (via Floating UI) and need
|
|
7
|
+
CSS to work around browser UA stylesheet conflicts, animate entry/exit,
|
|
8
|
+
and handle the :popover-open pseudo-class. None of this can be expressed
|
|
9
|
+
as Tailwind utility classes.
|
|
10
|
+
|
|
11
|
+
Key browser issue: the UA stylesheet hides [popover]:not(:popover-open)
|
|
12
|
+
with display: none in the UA layer. But Tailwind's `flex` utility class
|
|
13
|
+
(in the author layer) has higher specificity and overrides it, making
|
|
14
|
+
non-open popovers visible. We fix this with an explicit author-layer rule.
|
|
15
|
+
See MEMORY.md for the full explanation.
|
|
16
|
+
──────────────────────────────────────────────────────────────────────────── */
|
|
17
|
+
|
|
18
|
+
/* ── Root display ──────────────────────────────────────────────────────────
|
|
19
|
+
Same pattern as Button: @layer components so utility classes can override. */
|
|
4
20
|
@layer components {
|
|
5
21
|
[data-slot="tooltip"] {
|
|
6
22
|
display: inline-flex;
|
|
7
23
|
}
|
|
8
24
|
}
|
|
9
25
|
|
|
10
|
-
/*
|
|
11
|
-
|
|
12
|
-
|
|
26
|
+
/* ── Popover UA stylesheet overrides ──────────────────────────────────────
|
|
27
|
+
Two browser UA stylesheet behaviors must be explicitly overridden:
|
|
28
|
+
|
|
29
|
+
1. Hidden state: the UA hides non-open popovers with display: none, but
|
|
30
|
+
Tailwind's `flex` utility (author layer) overrides the UA layer. This
|
|
31
|
+
rule enforces hidden state in the author layer to match the UA intent.
|
|
32
|
+
|
|
33
|
+
2. Positioning reset: browsers apply inset: 0, margin: auto, and
|
|
34
|
+
width/height: fit-content to :popover-open elements, which fights
|
|
35
|
+
Floating UI's inline positioning styles. We reset inset and margin
|
|
36
|
+
so Floating UI has full control over placement. */
|
|
13
37
|
[data-slot="tooltip-content"]:not(:popover-open) {
|
|
14
38
|
display: none;
|
|
15
39
|
}
|
|
16
40
|
|
|
17
|
-
/* Reset UA popover styles — browsers apply inset: 0, margin: auto, and
|
|
18
|
-
width/height: fit-content to [popover]:popover-open, which overrides
|
|
19
|
-
Floating UI's inline-style positioning. */
|
|
20
41
|
[data-slot="tooltip-content"] {
|
|
21
42
|
inset: unset;
|
|
22
43
|
margin: 0;
|
|
23
44
|
}
|
|
24
45
|
|
|
25
|
-
/* Entry
|
|
46
|
+
/* ── Entry/exit animations ────────────────────────────────────────────────
|
|
47
|
+
data-state is set by the kiso--tooltip Stimulus controller:
|
|
48
|
+
- "open" on show (after showPopover()) → fade in + scale up from 95%
|
|
49
|
+
- "closed" on hide (before hidePopover()) → fade out + scale down to 95%
|
|
50
|
+
with `forwards` fill to hold opacity: 0 until hidePopover() removes it */
|
|
26
51
|
[data-slot="tooltip-content"][data-state="open"] {
|
|
27
52
|
animation: kiso-tooltip-in 150ms ease-out;
|
|
28
53
|
}
|
|
29
54
|
|
|
30
|
-
/* Exit animation — fade out + scale to 95% */
|
|
31
55
|
[data-slot="tooltip-content"][data-state="closed"] {
|
|
32
56
|
animation: kiso-tooltip-out 100ms ease-in forwards;
|
|
33
57
|
}
|
|
@@ -39,7 +63,9 @@
|
|
|
39
63
|
to { opacity: 0; transform: scale(0.95); }
|
|
40
64
|
}
|
|
41
65
|
|
|
42
|
-
/*
|
|
66
|
+
/* ── Reduced motion ───────────────────────────────────────────────────────
|
|
67
|
+
Disable animations for users who prefer reduced motion. The tooltip will
|
|
68
|
+
still appear/disappear, just without the fade/scale transition. */
|
|
43
69
|
@media (prefers-reduced-motion: reduce) {
|
|
44
70
|
[data-slot="tooltip-content"][data-state="open"],
|
|
45
71
|
[data-slot="tooltip-content"][data-state="closed"] {
|