@rokkit/themes 1.0.0-next.125 → 1.0.0-next.128

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.
Files changed (137) hide show
  1. package/README.md +118 -9
  2. package/build.mjs +237 -0
  3. package/package.json +43 -28
  4. package/src/base/breadcrumbs.css +46 -0
  5. package/src/base/button.css +247 -0
  6. package/src/base/card.css +36 -0
  7. package/src/base/carousel.css +122 -12
  8. package/src/base/connector.css +92 -0
  9. package/src/base/display.css +91 -0
  10. package/src/base/floating-action.css +388 -0
  11. package/src/base/floating-navigation.css +381 -0
  12. package/src/base/grid.css +93 -0
  13. package/src/base/index.css +39 -0
  14. package/src/base/input.css +198 -39
  15. package/src/base/item.css +78 -0
  16. package/src/base/list.css +179 -0
  17. package/src/base/menu.css +274 -0
  18. package/src/base/pill.css +57 -0
  19. package/src/base/progress.css +28 -15
  20. package/src/base/range.css +121 -0
  21. package/src/base/rating.css +40 -0
  22. package/src/base/reveal.css +37 -0
  23. package/src/base/search-filter.css +132 -0
  24. package/src/base/select.css +411 -0
  25. package/src/base/shine.css +14 -0
  26. package/src/base/stepper.css +140 -0
  27. package/src/base/switch.css +152 -0
  28. package/src/base/table.css +143 -33
  29. package/src/base/tabs.css +171 -0
  30. package/src/base/tilt.css +14 -0
  31. package/src/base/timeline.css +84 -0
  32. package/src/base/toggle.css +138 -0
  33. package/src/base/toolbar.css +337 -0
  34. package/src/base/tree.css +195 -11
  35. package/src/base/upload-progress.css +155 -0
  36. package/src/base/upload-target.css +67 -0
  37. package/src/glass/button.css +152 -0
  38. package/src/glass/floating-action.css +61 -0
  39. package/src/glass/floating-navigation.css +74 -0
  40. package/src/glass/index.css +23 -0
  41. package/src/glass/input.css +124 -0
  42. package/src/glass/list.css +122 -0
  43. package/src/glass/menu.css +92 -0
  44. package/src/glass/range.css +61 -0
  45. package/src/glass/search-filter.css +49 -0
  46. package/src/glass/select.css +178 -0
  47. package/src/glass/switch.css +28 -0
  48. package/src/glass/table.css +87 -0
  49. package/src/glass/tabs.css +58 -0
  50. package/src/glass/timeline.css +46 -0
  51. package/src/glass/toggle.css +48 -0
  52. package/src/glass/toolbar.css +84 -0
  53. package/src/glass/tree.css +104 -0
  54. package/src/index.css +18 -0
  55. package/src/index.js +25 -2
  56. package/src/material/button.css +153 -0
  57. package/src/material/floating-action.css +60 -0
  58. package/src/material/floating-navigation.css +74 -0
  59. package/src/material/index.css +23 -0
  60. package/src/material/input.css +118 -40
  61. package/src/material/list.css +90 -64
  62. package/src/material/menu.css +92 -0
  63. package/src/material/range.css +62 -0
  64. package/src/material/search-filter.css +49 -0
  65. package/src/material/select.css +170 -0
  66. package/src/material/switch.css +28 -0
  67. package/src/material/table.css +87 -0
  68. package/src/material/tabs.css +62 -0
  69. package/src/material/timeline.css +46 -0
  70. package/src/material/toggle.css +48 -0
  71. package/src/material/toolbar.css +84 -0
  72. package/src/material/tree.css +100 -0
  73. package/src/minimal/button.css +152 -0
  74. package/src/minimal/floating-action.css +59 -0
  75. package/src/minimal/floating-navigation.css +70 -0
  76. package/src/minimal/index.css +23 -0
  77. package/src/minimal/input.css +81 -120
  78. package/src/minimal/list.css +90 -104
  79. package/src/minimal/menu.css +88 -0
  80. package/src/minimal/range.css +61 -0
  81. package/src/minimal/search-filter.css +49 -0
  82. package/src/minimal/select.css +168 -0
  83. package/src/minimal/switch.css +28 -0
  84. package/src/minimal/table.css +87 -0
  85. package/src/minimal/tabs.css +53 -31
  86. package/src/minimal/timeline.css +45 -0
  87. package/src/minimal/toggle.css +48 -0
  88. package/src/minimal/toolbar.css +84 -0
  89. package/src/minimal/tree.css +100 -0
  90. package/src/rokkit/button.css +225 -0
  91. package/src/rokkit/connector.css +11 -0
  92. package/src/rokkit/floating-action.css +65 -0
  93. package/src/rokkit/floating-navigation.css +83 -0
  94. package/src/rokkit/grid.css +46 -0
  95. package/src/rokkit/index.css +27 -0
  96. package/src/rokkit/input.css +130 -0
  97. package/src/rokkit/list.css +127 -0
  98. package/src/rokkit/menu.css +93 -0
  99. package/src/rokkit/range.css +62 -0
  100. package/src/rokkit/search-filter.css +49 -0
  101. package/src/rokkit/select.css +185 -0
  102. package/src/rokkit/switch.css +28 -0
  103. package/src/rokkit/table.css +68 -38
  104. package/src/rokkit/tabs.css +82 -0
  105. package/src/rokkit/timeline.css +46 -0
  106. package/src/rokkit/toggle.css +36 -52
  107. package/src/rokkit/toolbar.css +84 -0
  108. package/src/rokkit/tree.css +123 -0
  109. package/src/rokkit/upload-progress.css +102 -0
  110. package/src/rokkit/upload-target.css +50 -0
  111. package/src/base/alert.css +0 -30
  112. package/src/base/animation.css +0 -37
  113. package/src/base/atoms.css +0 -58
  114. package/src/base/core.css +0 -107
  115. package/src/base/layout.css +0 -65
  116. package/src/base/molecules.css +0 -109
  117. package/src/base/organisms.css +0 -66
  118. package/src/base/scrollbar.css +0 -16
  119. package/src/base/toggles.css +0 -17
  120. package/src/base.css +0 -13
  121. package/src/markdown.css +0 -955
  122. package/src/material/base.css +0 -12
  123. package/src/material/form.css +0 -30
  124. package/src/material.css +0 -9
  125. package/src/minimal/base.css +0 -8
  126. package/src/minimal/form.css +0 -87
  127. package/src/minimal.css +0 -11
  128. package/src/mixins/mixins.scss +0 -66
  129. package/src/mixins/palette.scss +0 -48
  130. package/src/prism.css +0 -102
  131. package/src/rokkit/alert.css +0 -4
  132. package/src/rokkit/atoms.css +0 -52
  133. package/src/rokkit/carousel.css +0 -19
  134. package/src/rokkit/layout.css +0 -17
  135. package/src/rokkit/molecules.css +0 -124
  136. package/src/rokkit/organisms.css +0 -307
  137. package/src/rokkit.css +0 -11
package/README.md CHANGED
@@ -1,13 +1,122 @@
1
- # Themes
1
+ # @rokkit/themes
2
2
 
3
- Contains the following themes for use with `Rokkit` components.
3
+ Theme styles for `@rokkit/ui` headless components.
4
4
 
5
- - Rokkit
6
- - Modern
7
- - Material
5
+ ## Architecture
8
6
 
9
- This package also includes some mixins which make it easy to implement `light` and `dark` modes.
7
+ This package follows a **headless component + themed styles** pattern:
10
8
 
11
- - markdown.css: A customized variant of Github flavored markdown
12
- - prism.css: A variation of the prism syntax highlighting colors using CSS variables to support light and dark modes.
13
- - palette.css: Light and dark palettes using CSS variables.
9
+ - **Components** (`@rokkit/ui`) - Provide structure, behavior, and accessibility via data attributes
10
+ - **Themes** (`@rokkit/themes`) - Provide visual styling that targets those data attributes
11
+
12
+ ### Directory Structure
13
+
14
+ ```
15
+ src/
16
+ ├── base/ # Structural styles (layout, positioning)
17
+ │ ├── index.css # All base styles
18
+ │ └── menu.css # Menu structural styles
19
+ ├── rokkit/ # Default theme (gradients + borders)
20
+ │ ├── index.css # All rokkit theme styles
21
+ │ └── menu.css # Menu themed styles
22
+ ├── minimal/ # Clean + subtle theme
23
+ ├── material/ # Elevation + shadows theme
24
+ ├── glass/ # Blur + transparency theme
25
+ └── index.css # Main entry (imports base + all themes)
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ ### Full Theme (base + all themes)
31
+
32
+ ```ts
33
+ import '@rokkit/themes'
34
+ ```
35
+
36
+ ### Base Only (for custom theming)
37
+
38
+ ```ts
39
+ import '@rokkit/themes/base'
40
+ ```
41
+
42
+ ### Rokkit Theme Only
43
+
44
+ ```ts
45
+ import '@rokkit/themes/rokkit'
46
+ ```
47
+
48
+ ### Individual Component Styles
49
+
50
+ ```ts
51
+ import '@rokkit/themes/base/menu.css'
52
+ import '@rokkit/themes/rokkit/menu.css'
53
+ ```
54
+
55
+ ## Data Attributes
56
+
57
+ Components use semantic data attributes for styling hooks:
58
+
59
+ ### Common Attributes
60
+
61
+ | Attribute | Values | Description |
62
+ | --------------- | ---------------- | -------------- |
63
+ | `data-size` | `sm`, `md`, `lg` | Size variant |
64
+ | `data-disabled` | `true` | Disabled state |
65
+ | `data-align` | `left`, `right` | Alignment |
66
+
67
+ ### Menu-Specific Attributes
68
+
69
+ | Attribute | Description |
70
+ | ----------------------- | ----------------------- |
71
+ | `data-menu` | Menu container |
72
+ | `data-menu-trigger` | Trigger button |
73
+ | `data-menu-dropdown` | Dropdown panel |
74
+ | `data-menu-item` | Menu item |
75
+ | `data-menu-item-custom` | Custom snippet wrapper |
76
+ | `data-menu-group` | Group container |
77
+ | `data-menu-group-label` | Group header |
78
+ | `data-menu-divider` | Divider line |
79
+ | `data-menu-open` | Open state on container |
80
+
81
+ ## Theme Scoping
82
+
83
+ Rokkit is the default theme — its styles apply without any wrapper.
84
+
85
+ Other themes are scoped with `data-style` to allow switching:
86
+
87
+ ```html
88
+ <div data-style="minimal">
89
+ <!-- Components here use minimal theme -->
90
+ </div>
91
+ ```
92
+
93
+ For global application, set on the root element:
94
+
95
+ ```html
96
+ <html data-style="material"></html>
97
+ ```
98
+
99
+ ## Creating Custom Themes
100
+
101
+ 1. Copy `src/rokkit/` to `src/my-theme/`
102
+ 2. Modify styles using same data attribute selectors
103
+ 3. Wrap selectors with `[data-style='my-theme']` scope
104
+ 4. Import your theme alongside or instead of rokkit
105
+
106
+ ## CSS Custom Properties
107
+
108
+ Themes use semantic CSS custom properties for consistency:
109
+
110
+ ```css
111
+ /* Surface colors (backgrounds) */
112
+ --surface-z0 through --surface-z10
113
+
114
+ /* Text colors */
115
+ --text-primary, --text-secondary, --text-muted
116
+
117
+ /* Interactive colors */
118
+ --primary, --primary-hover, --primary-active
119
+
120
+ /* State colors */
121
+ --success, --warning, --error, --info
122
+ ```
package/build.mjs ADDED
@@ -0,0 +1,237 @@
1
+ /**
2
+ * @rokkit/themes — CSS Build Script
3
+ *
4
+ * Compiles theme CSS with UnoCSS, expanding @apply directives into real CSS
5
+ * (including correct dark mode sibling rules).
6
+ *
7
+ * Outputs separate files per theme:
8
+ * dist/base.css — structural styles + default CSS variable palette
9
+ * dist/rokkit.css — rokkit theme (gradients, glowing borders)
10
+ * dist/minimal.css — minimal theme (clean, subtle)
11
+ * dist/material.css — material theme (elevation, shadows)
12
+ * dist/glass.css — glass theme (blur, transparency)
13
+ *
14
+ * Post-processing: adds compound selector form so dark mode works when
15
+ * data-mode and data-style are on the SAME element (e.g. body):
16
+ * Generated: [data-mode="dark"] [data-style="rokkit"] [data-toggle]
17
+ * Added also: [data-mode="dark"][data-style="rokkit"] [data-toggle]
18
+ */
19
+
20
+ import { createGenerator, presetWind3, transformerDirectives } from 'unocss'
21
+ import { Theme } from '@rokkit/core'
22
+ import { readFileSync, writeFileSync, mkdirSync } from 'fs'
23
+ import { resolve, dirname, join } from 'path'
24
+ import { fileURLToPath } from 'url'
25
+ import MagicString from 'magic-string'
26
+
27
+ const __dirname = dirname(fileURLToPath(import.meta.url))
28
+
29
+ // ─── UnoCSS config ────────────────────────────────────────────────────────────
30
+
31
+ const theme = new Theme()
32
+
33
+ const uno = await createGenerator({
34
+ presets: [
35
+ presetWind3({
36
+ dark: {
37
+ light: '[data-mode="light"]',
38
+ dark: '[data-mode="dark"]'
39
+ }
40
+ })
41
+ ],
42
+ shortcuts: [
43
+ ['skin-default', theme.getPalette()],
44
+ ...theme.getShortcuts('surface'),
45
+ ...theme.getShortcuts('primary'),
46
+ ...theme.getShortcuts('secondary'),
47
+ ...theme.getShortcuts('accent'),
48
+ ...theme.getShortcuts('success'),
49
+ ...theme.getShortcuts('warning'),
50
+ ...theme.getShortcuts('danger'),
51
+ ...theme.getShortcuts('error'),
52
+ ...theme.getShortcuts('info'),
53
+ ['text-on-primary', 'text-surface-50'],
54
+ ['text-on-secondary', 'text-surface-50'],
55
+ ['text-on-info', 'text-surface-50'],
56
+ ['text-on-success', 'text-surface-50'],
57
+ ['text-on-warning', 'text-surface-50'],
58
+ ['text-on-error', 'text-surface-50'],
59
+ ['text-on-surface', 'text-surface-50']
60
+ ],
61
+ theme: {
62
+ colors: theme.getColorRules()
63
+ }
64
+ })
65
+
66
+ // ─── CSS @import resolver ─────────────────────────────────────────────────────
67
+
68
+ /**
69
+ * Recursively inlines local @import statements.
70
+ * External imports (http, @, ~) are left unchanged.
71
+ */
72
+ function resolveImports(filePath, seen = new Set()) {
73
+ if (seen.has(filePath)) return ''
74
+ seen.add(filePath)
75
+
76
+ const content = readFileSync(filePath, 'utf-8')
77
+ return content.replace(/@import\s+['"]([^'"]+)['"]\s*;/g, (match, importPath) => {
78
+ if (importPath.startsWith('http') || importPath.startsWith('@') || importPath.startsWith('~')) {
79
+ return match
80
+ }
81
+ const resolvedPath = resolve(dirname(filePath), importPath)
82
+ return resolveImports(resolvedPath, seen)
83
+ })
84
+ }
85
+
86
+ // ─── UnoCSS @apply processor ─────────────────────────────────────────────────
87
+
88
+ const transformer = transformerDirectives()
89
+
90
+ async function processCSS(content, filename) {
91
+ const s = new MagicString(content)
92
+ await transformer.transform(s, filename, {
93
+ uno,
94
+ tokens: new Set(),
95
+ generate: async (tokens) => uno.generate(tokens, { preflights: false })
96
+ })
97
+ return s.toString()
98
+ }
99
+
100
+ // ─── Post-processing: fix dark mode selectors ─────────────────────────────────
101
+
102
+ /**
103
+ * UnoCSS generates dark mode rules as descendant selectors:
104
+ * [data-mode="dark"] [data-style="rokkit"] [data-component]
105
+ *
106
+ * This doesn't match when both data-mode and data-style are on the SAME element
107
+ * (e.g. <body data-mode="dark" data-style="rokkit">).
108
+ *
109
+ * For each such rule, we also add the compound selector form:
110
+ * [data-mode="dark"][data-style="rokkit"] [data-component]
111
+ *
112
+ * Both forms are emitted so either usage pattern works.
113
+ */
114
+ function fixModeSelectors(css) {
115
+ const modePattern = /\[data-mode="(?:dark|light)"\] \[data-style="[^"]+"\]/
116
+
117
+ let result = ''
118
+ let i = 0
119
+
120
+ while (i < css.length) {
121
+ // Find next { (opening of a declarations block)
122
+ const braceOpen = css.indexOf('{', i)
123
+ if (braceOpen === -1) {
124
+ result += css.slice(i)
125
+ break
126
+ }
127
+
128
+ const selectorText = css.slice(i, braceOpen)
129
+
130
+ // Only expand selectors that contain the problematic pattern
131
+ if (modePattern.test(selectorText)) {
132
+ // Split on comma, but only top-level commas (not inside :not(), :is(), etc.)
133
+ const parts = splitTopLevelSelectors(selectorText)
134
+ const expanded = []
135
+
136
+ for (const part of parts) {
137
+ const m = part.match(/^(\s*)(\[data-mode="(?:dark|light)"\]) (\[data-style="[^"]+"\])(.*)$/)
138
+ if (m) {
139
+ const [, ws, modeSelector, styleSelector, rest] = m
140
+ // Compound form: [data-mode="X"][data-style="Y"]rest (same-element match)
141
+ expanded.push(`${ws}${modeSelector}${styleSelector}${rest}`)
142
+ }
143
+ // Always include original descendant form
144
+ expanded.push(part)
145
+ }
146
+
147
+ result += expanded.join(',') + '{'
148
+ } else {
149
+ result += selectorText + '{'
150
+ }
151
+
152
+ // Find the matching closing brace, handling nesting
153
+ let depth = 1
154
+ let j = braceOpen + 1
155
+ while (j < css.length && depth > 0) {
156
+ if (css[j] === '{') depth++
157
+ else if (css[j] === '}') depth--
158
+ j++
159
+ }
160
+
161
+ result += css.slice(braceOpen + 1, j)
162
+ i = j
163
+ }
164
+
165
+ return result
166
+ }
167
+
168
+ /**
169
+ * Split a selector list by top-level commas only (not inside parentheses).
170
+ */
171
+ function splitTopLevelSelectors(text) {
172
+ const parts = []
173
+ let depth = 0
174
+ let start = 0
175
+
176
+ for (let i = 0; i < text.length; i++) {
177
+ if (text[i] === '(') depth++
178
+ else if (text[i] === ')') depth--
179
+ else if (text[i] === ',' && depth === 0) {
180
+ parts.push(text.slice(start, i))
181
+ start = i + 1
182
+ }
183
+ }
184
+ parts.push(text.slice(start))
185
+ return parts
186
+ }
187
+
188
+ // ─── Build ────────────────────────────────────────────────────────────────────
189
+
190
+ const srcDir = join(__dirname, 'src')
191
+ const distDir = join(__dirname, 'dist')
192
+
193
+ async function buildFile(inputPath, outputName, label) {
194
+ const fullCSS = resolveImports(inputPath)
195
+ const compiled = await processCSS(fullCSS, outputName)
196
+ const fixed = fixModeSelectors(compiled)
197
+ writeFileSync(join(distDir, outputName), fixed, 'utf-8')
198
+ console.log(`✓ dist/${outputName} (${label})`)
199
+ }
200
+
201
+ async function build() {
202
+ mkdirSync(distDir, { recursive: true })
203
+
204
+ // base.css: structural styles + palette CSS variable defaults
205
+ const paletteCSS = readFileSync(join(srcDir, 'palette.css'), 'utf-8')
206
+ const compiledPalette = await processCSS(paletteCSS, 'palette.css')
207
+ const baseCSS = resolveImports(join(srcDir, 'base', 'index.css'))
208
+ const compiledBase = await processCSS(baseCSS, 'base.css')
209
+ const baseFull = fixModeSelectors(compiledPalette + '\n' + compiledBase)
210
+ writeFileSync(join(distDir, 'base.css'), baseFull, 'utf-8')
211
+ console.log('✓ dist/base.css (structural styles + palette defaults)')
212
+
213
+ // Per-theme files
214
+ for (const [name, label] of [
215
+ ['rokkit', 'gradients + glowing borders'],
216
+ ['minimal', 'clean + subtle'],
217
+ ['material', 'elevation + shadows'],
218
+ ['glass', 'blur + transparency']
219
+ ]) {
220
+ await buildFile(join(srcDir, name, 'index.css'), `${name}.css`, label)
221
+ }
222
+
223
+ // Full bundle: base + all themes
224
+ const allThemes = ['base', 'rokkit', 'minimal', 'material', 'glass']
225
+ const bundleParts = allThemes.map((name) =>
226
+ readFileSync(join(distDir, `${name}.css`), 'utf-8')
227
+ )
228
+ writeFileSync(join(distDir, 'index.css'), bundleParts.join('\n'), 'utf-8')
229
+ console.log('✓ dist/index.css (full bundle)')
230
+
231
+ console.log('\n@rokkit/themes build complete.')
232
+ }
233
+
234
+ build().catch((err) => {
235
+ console.error('Build failed:', err)
236
+ process.exit(1)
237
+ })
package/package.json CHANGED
@@ -1,37 +1,52 @@
1
1
  {
2
2
  "name": "@rokkit/themes",
3
- "version": "1.0.0-next.125",
4
- "description": "Themes for use with rokkit components.",
5
- "author": "Jerry Thomas <me@jerrythomas.name>",
6
- "license": "MIT",
7
- "module": "src/index.js",
8
- "types": "dist/index.d.ts",
3
+ "version": "1.0.0-next.128",
4
+ "description": "Theme styles for @rokkit/ui components",
9
5
  "type": "module",
10
- "publishConfig": {
11
- "access": "public"
12
- },
13
- "scripts": {
14
- "prepublishOnly": "tsc --project tsconfig.build.json",
15
- "clean": "rm -rf dist",
16
- "build": "bun clean && bun prepublishOnly"
6
+ "main": "./src/index.js",
7
+ "exports": {
8
+ ".": {
9
+ "style": "./src/index.css",
10
+ "import": "./src/index.js",
11
+ "default": "./src/index.js"
12
+ },
13
+ "./styles": "./src/index.css",
14
+ "./dist": "./dist/index.css",
15
+ "./base.css": "./dist/base.css",
16
+ "./rokkit.css": "./dist/rokkit.css",
17
+ "./minimal.css": "./dist/minimal.css",
18
+ "./material.css": "./dist/material.css",
19
+ "./glass.css": "./dist/glass.css",
20
+ "./base": "./src/base/index.css",
21
+ "./base/*": "./src/base/*.css",
22
+ "./rokkit": "./src/rokkit/index.css",
23
+ "./rokkit/*": "./src/rokkit/*.css",
24
+ "./minimal": "./src/minimal/index.css",
25
+ "./minimal/*": "./src/minimal/*.css",
26
+ "./material": "./src/material/index.css",
27
+ "./material/*": "./src/material/*.css",
28
+ "./glass": "./src/glass/index.css",
29
+ "./glass/*": "./src/glass/*.css"
17
30
  },
18
31
  "files": [
19
- "src"
32
+ "src",
33
+ "dist",
34
+ "build.mjs"
20
35
  ],
21
- "exports": {
22
- "./modern.css": "./src/modern.css",
23
- "./material.css": "./src/material.css",
24
- "./minimal.css": "./src/minimal.css",
25
- "./rokkit.css": "./src/rokkit.css",
26
- "./prism.css": "./src/prism.css",
27
- "./palette.css": "./src/palette.css",
28
- "./markdown.css": "./src/markdown.css",
29
- "./package.json": "./src/package.json",
30
- ".": {
31
- "import": "./src/index.js"
32
- }
36
+ "scripts": {
37
+ "build": "bun run build.mjs"
33
38
  },
34
39
  "dependencies": {
35
- "@rokkit/core": "latest"
36
- }
40
+ "@rokkit/core": "1.0.0-next.128"
41
+ },
42
+ "devDependencies": {
43
+ "magic-string": "^0.30.21",
44
+ "unocss": "^66.5.1"
45
+ },
46
+ "keywords": [
47
+ "themes",
48
+ "css",
49
+ "styles",
50
+ "ui"
51
+ ]
37
52
  }
@@ -0,0 +1,46 @@
1
+ /* BreadCrumbs — base structural styles */
2
+
3
+ [data-breadcrumbs] {
4
+ display: block;
5
+ }
6
+
7
+ [data-breadcrumb-list] {
8
+ display: flex;
9
+ align-items: center;
10
+ list-style: none;
11
+ padding: 0;
12
+ margin: 0;
13
+ gap: 0.25rem;
14
+ }
15
+
16
+ [data-breadcrumb-item] {
17
+ display: flex;
18
+ align-items: center;
19
+ }
20
+
21
+ [data-breadcrumb-separator] {
22
+ display: flex;
23
+ align-items: center;
24
+ opacity: 0.5;
25
+ }
26
+
27
+ [data-breadcrumb-link] {
28
+ display: flex;
29
+ align-items: center;
30
+ gap: 0.25rem;
31
+ background: none;
32
+ border: none;
33
+ cursor: pointer;
34
+ padding: 0.25rem 0.5rem;
35
+ border-radius: 0.25rem;
36
+ font: inherit;
37
+ color: inherit;
38
+ }
39
+
40
+ [data-breadcrumb-current] {
41
+ display: flex;
42
+ align-items: center;
43
+ gap: 0.25rem;
44
+ padding: 0.25rem 0.5rem;
45
+ font-weight: 600;
46
+ }