minka-ds 0.1.5 → 0.1.8
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/package.json
CHANGED
|
@@ -52,7 +52,7 @@ function FilterChip(props: FilterChipProps) {
|
|
|
52
52
|
{values.map((value, i) => (
|
|
53
53
|
<span
|
|
54
54
|
key={i}
|
|
55
|
-
className="inline-flex items-center gap-1 rounded-full border border-[var(--color-border-default)] px-2 py-0.5 text-caption text-[var(--color-text-default)]"
|
|
55
|
+
className="inline-flex items-center gap-1 rounded-full border border-[var(--color-border-default)] bg-[var(--color-bg-base)] px-2 py-0.5 text-caption text-[var(--color-text-default)]"
|
|
56
56
|
>
|
|
57
57
|
{value.label}
|
|
58
58
|
<button
|
|
@@ -21,13 +21,14 @@ import { Tabs, TabsList, TabsTrigger } from "./tabs"
|
|
|
21
21
|
interface FilterCategory {
|
|
22
22
|
id: string
|
|
23
23
|
label: string
|
|
24
|
-
type?: "list" | "date" | "amount"
|
|
24
|
+
type?: "list" | "date" | "amount" | "hours"
|
|
25
25
|
values?: string[]
|
|
26
26
|
renderValue?: (value: string) => React.ReactNode
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
type AmountValue = { exact: number } | { min?: number; max?: number }
|
|
30
|
-
type
|
|
30
|
+
type HoursValue = { from: string; to: string }
|
|
31
|
+
type CategoryValue = string | DateRange | AmountValue | HoursValue
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
type Step = 1 | 2 | 3
|
|
@@ -58,10 +59,13 @@ function FilterCombobox({
|
|
|
58
59
|
const [amountExact, setAmountExact] = React.useState("")
|
|
59
60
|
const [amountMin, setAmountMin] = React.useState("")
|
|
60
61
|
const [amountMax, setAmountMax] = React.useState("")
|
|
62
|
+
const [hoursInput, setHoursInput] = React.useState("")
|
|
63
|
+
const [hoursInputTo, setHoursInputTo] = React.useState("")
|
|
61
64
|
const [search, setSearch] = React.useState("")
|
|
62
65
|
|
|
63
66
|
const containerRef = React.useRef<HTMLDivElement>(null)
|
|
64
67
|
const searchRef = React.useRef<HTMLInputElement>(null)
|
|
68
|
+
const isSingle = categories.length === 1
|
|
65
69
|
|
|
66
70
|
// Close on outside click
|
|
67
71
|
React.useEffect(() => {
|
|
@@ -89,6 +93,20 @@ function FilterCombobox({
|
|
|
89
93
|
setAmountExact("")
|
|
90
94
|
setAmountMin("")
|
|
91
95
|
setAmountMax("")
|
|
96
|
+
setHoursInput("")
|
|
97
|
+
setHoursInputTo("")
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function handleToggle() {
|
|
101
|
+
if (open) {
|
|
102
|
+
handleClose()
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
// Single-category: skip step 1 and jump straight to options
|
|
106
|
+
if (isSingle) {
|
|
107
|
+
openCategory(categories[0])
|
|
108
|
+
}
|
|
109
|
+
setOpen(true)
|
|
92
110
|
}
|
|
93
111
|
|
|
94
112
|
function openCategory(cat: FilterCategory) {
|
|
@@ -104,6 +122,16 @@ function FilterCombobox({
|
|
|
104
122
|
return
|
|
105
123
|
}
|
|
106
124
|
|
|
125
|
+
if (cat.type === "hours") {
|
|
126
|
+
setSelectedCategory(cat)
|
|
127
|
+
setSelectedValues(new Set())
|
|
128
|
+
setHoursInput("")
|
|
129
|
+
setHoursInputTo("")
|
|
130
|
+
setSearch("")
|
|
131
|
+
setStep(2)
|
|
132
|
+
return
|
|
133
|
+
}
|
|
134
|
+
|
|
107
135
|
if (cat.type === "amount") {
|
|
108
136
|
const custom = existing.find((v): v is AmountValue =>
|
|
109
137
|
typeof v === "object" && ("exact" in v || "min" in v || "max" in v)
|
|
@@ -147,6 +175,12 @@ function FilterCombobox({
|
|
|
147
175
|
handleClose()
|
|
148
176
|
}
|
|
149
177
|
|
|
178
|
+
function applyCustomHours() {
|
|
179
|
+
if (!selectedCategory || !hoursInput || !hoursInputTo) return
|
|
180
|
+
onApply(selectedCategory.id, [{ from: hoursInput, to: hoursInputTo }])
|
|
181
|
+
handleClose()
|
|
182
|
+
}
|
|
183
|
+
|
|
150
184
|
function applyCustomAmount() {
|
|
151
185
|
if (!selectedCategory) return
|
|
152
186
|
let value: AmountValue
|
|
@@ -177,6 +211,7 @@ function FilterCombobox({
|
|
|
177
211
|
|
|
178
212
|
const isDate = selectedCategory?.type === "date"
|
|
179
213
|
const isAmount = selectedCategory?.type === "amount"
|
|
214
|
+
const isHours = selectedCategory?.type === "hours"
|
|
180
215
|
|
|
181
216
|
const step2AllValues = selectedCategory?.values ?? []
|
|
182
217
|
|
|
@@ -193,8 +228,8 @@ function FilterCombobox({
|
|
|
193
228
|
|
|
194
229
|
return (
|
|
195
230
|
<div ref={containerRef} className={cn("relative inline-block", className)}>
|
|
196
|
-
{trigger ? trigger({ open, onClick:
|
|
197
|
-
<Button variant="default" size="sm" className="h-7 text-caption gap-1.5 px-2.5" onClick={
|
|
231
|
+
{trigger ? trigger({ open, onClick: handleToggle }) : (
|
|
232
|
+
<Button variant="default" size="sm" className="h-7 text-caption gap-1.5 px-2.5" onClick={handleToggle}>
|
|
198
233
|
<PlusIcon className="size-3.5" />
|
|
199
234
|
Add filter
|
|
200
235
|
</Button>
|
|
@@ -204,11 +239,11 @@ function FilterCombobox({
|
|
|
204
239
|
<div className={cn(
|
|
205
240
|
dropdownAlign === "right" ? "absolute right-0 top-full mt-1.5 overflow-hidden [border-radius:var(--radius-popover)]" : "absolute left-0 top-full mt-1.5 overflow-hidden [border-radius:var(--radius-popover)]",
|
|
206
241
|
"bg-[var(--color-bg-overlay)] shadow-[var(--shadow-popover)] ring-1 ring-[var(--color-border-subtle)]",
|
|
207
|
-
"[z-index:var(--z-
|
|
208
|
-
step === 3 && isDate ? "w-auto" : "w-56"
|
|
242
|
+
"[z-index:var(--z-floating)]",
|
|
243
|
+
step === 3 && isDate ? "w-auto" : step === 3 && isHours ? "w-80" : "w-56"
|
|
209
244
|
)}>
|
|
210
245
|
|
|
211
|
-
{/* Step 1 — category list */}
|
|
246
|
+
{/* Step 1 — category list (multi-category mode only) */}
|
|
212
247
|
{step === 1 && (
|
|
213
248
|
<ul className="p-1">
|
|
214
249
|
{categories.map(cat => (
|
|
@@ -222,10 +257,12 @@ function FilterCombobox({
|
|
|
222
257
|
{/* Step 2 — value list */}
|
|
223
258
|
{step === 2 && selectedCategory && (
|
|
224
259
|
<>
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
260
|
+
{!isSingle && (
|
|
261
|
+
<StepHeader
|
|
262
|
+
title={selectedCategory.label}
|
|
263
|
+
onBack={() => { setStep(1); setSearch("") }}
|
|
264
|
+
/>
|
|
265
|
+
)}
|
|
229
266
|
{showSearch && (
|
|
230
267
|
<div className="px-1 pt-1">
|
|
231
268
|
<SearchInput ref={searchRef} value={search} onChange={setSearch} />
|
|
@@ -236,17 +273,28 @@ function FilterCombobox({
|
|
|
236
273
|
? <EmptyRow />
|
|
237
274
|
: step2Filtered.map(value => (
|
|
238
275
|
<li key={value}>
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
276
|
+
{selectedCategory.type === "hours" ? (
|
|
277
|
+
<PickerRow onClick={() => { onApply(selectedCategory.id, [value]); handleClose() }}>
|
|
278
|
+
{selectedCategory.renderValue?.(value) ?? value}
|
|
279
|
+
</PickerRow>
|
|
280
|
+
) : (
|
|
281
|
+
<CheckRow
|
|
282
|
+
checked={selectedValues.has(value)}
|
|
283
|
+
onToggle={() => toggleValue(value)}
|
|
284
|
+
>
|
|
285
|
+
{selectedCategory.renderValue?.(value) ?? value}
|
|
286
|
+
</CheckRow>
|
|
287
|
+
)}
|
|
245
288
|
</li>
|
|
246
289
|
))
|
|
247
290
|
}
|
|
291
|
+
{selectedCategory.type === "hours" && (
|
|
292
|
+
<li>
|
|
293
|
+
<PickerRow onClick={() => setStep(3)}>Custom range</PickerRow>
|
|
294
|
+
</li>
|
|
295
|
+
)}
|
|
248
296
|
</ul>
|
|
249
|
-
{selectedValues.size > 0 && (
|
|
297
|
+
{selectedValues.size > 0 && selectedCategory.type !== "hours" && (
|
|
250
298
|
<div className="p-1">
|
|
251
299
|
<Button size="sm" className="w-full" onClick={applyValues}>
|
|
252
300
|
Apply
|
|
@@ -259,10 +307,12 @@ function FilterCombobox({
|
|
|
259
307
|
{/* Step 3 — custom date range */}
|
|
260
308
|
{step === 3 && isDate && (
|
|
261
309
|
<>
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
310
|
+
{!isSingle && (
|
|
311
|
+
<StepHeader
|
|
312
|
+
title={selectedCategory?.label ?? "Date"}
|
|
313
|
+
onBack={() => setStep(1)}
|
|
314
|
+
/>
|
|
315
|
+
)}
|
|
266
316
|
<div className="p-1">
|
|
267
317
|
<Calendar mode="range" selected={dateRange} onSelect={setDateRange} numberOfMonths={1} />
|
|
268
318
|
</div>
|
|
@@ -276,14 +326,49 @@ function FilterCombobox({
|
|
|
276
326
|
</>
|
|
277
327
|
)}
|
|
278
328
|
|
|
279
|
-
{/* Step 3 — custom
|
|
280
|
-
{step === 3 &&
|
|
329
|
+
{/* Step 3 — hours custom range */}
|
|
330
|
+
{step === 3 && isHours && (
|
|
281
331
|
<>
|
|
282
332
|
<StepHeader
|
|
283
|
-
title="
|
|
284
|
-
onBack={() =>
|
|
333
|
+
title="Custom range"
|
|
334
|
+
onBack={() => setStep(2)}
|
|
285
335
|
/>
|
|
286
|
-
<div className="
|
|
336
|
+
<div className="p-2 flex flex-col gap-2">
|
|
337
|
+
<div className="flex items-center gap-2">
|
|
338
|
+
<Input
|
|
339
|
+
type="time"
|
|
340
|
+
value={hoursInput}
|
|
341
|
+
onChange={e => setHoursInput(e.target.value)}
|
|
342
|
+
className="flex-1"
|
|
343
|
+
/>
|
|
344
|
+
<span className="text-body-sm text-[var(--color-text-muted)] shrink-0">–</span>
|
|
345
|
+
<Input
|
|
346
|
+
type="time"
|
|
347
|
+
value={hoursInputTo}
|
|
348
|
+
onChange={e => setHoursInputTo(e.target.value)}
|
|
349
|
+
className="flex-1"
|
|
350
|
+
/>
|
|
351
|
+
</div>
|
|
352
|
+
{hoursInput !== "" && hoursInputTo !== "" &&
|
|
353
|
+
!isNaN(parseFloat(hoursInput)) && !isNaN(parseFloat(hoursInputTo)) && (
|
|
354
|
+
<Button size="sm" className="w-full" onClick={applyCustomHours}>
|
|
355
|
+
Apply
|
|
356
|
+
</Button>
|
|
357
|
+
)}
|
|
358
|
+
</div>
|
|
359
|
+
</>
|
|
360
|
+
)}
|
|
361
|
+
|
|
362
|
+
{/* Step 3 — custom amount */}
|
|
363
|
+
{step === 3 && isAmount && (
|
|
364
|
+
<>
|
|
365
|
+
{!isSingle && (
|
|
366
|
+
<StepHeader
|
|
367
|
+
title="Amount"
|
|
368
|
+
onBack={() => setStep(1)}
|
|
369
|
+
/>
|
|
370
|
+
)}
|
|
371
|
+
<div className="p-2 flex flex-col gap-2">
|
|
287
372
|
<Tabs
|
|
288
373
|
value={amountMode}
|
|
289
374
|
onValueChange={v => setAmountMode(v as "exact" | "range")}
|
|
@@ -427,4 +512,4 @@ function EmptyRow() {
|
|
|
427
512
|
// ── Exports ────────────────────────────────────────────────────────────────────
|
|
428
513
|
|
|
429
514
|
export { FilterCombobox }
|
|
430
|
-
export type { FilterCategory, CategoryValue, AmountValue }
|
|
515
|
+
export type { FilterCategory, CategoryValue, AmountValue, HoursValue }
|
|
@@ -52,6 +52,7 @@ interface SearchBarProps {
|
|
|
52
52
|
onRemoveFilter?: (categoryId: string, value: CategoryValue) => void
|
|
53
53
|
onClearFilters?: () => void
|
|
54
54
|
filterValueLabel?: (categoryId: string, value: CategoryValue) => string
|
|
55
|
+
alwaysShowFilterBar?: boolean
|
|
55
56
|
|
|
56
57
|
children?: React.ReactNode
|
|
57
58
|
className?: string
|
|
@@ -73,11 +74,13 @@ function SearchBar({
|
|
|
73
74
|
onRemoveFilter,
|
|
74
75
|
onClearFilters,
|
|
75
76
|
filterValueLabel = defaultFilterValueLabel,
|
|
77
|
+
alwaysShowFilterBar = false,
|
|
76
78
|
children,
|
|
77
79
|
className,
|
|
78
80
|
}: SearchBarProps) {
|
|
79
81
|
const hasActiveFilters = Object.values(activeFilters).some(v => v.length > 0)
|
|
80
82
|
const hasFilterCategories = filterCategories.length > 0
|
|
83
|
+
const showFilterBar = hasActiveFilters || alwaysShowFilterBar
|
|
81
84
|
|
|
82
85
|
return (
|
|
83
86
|
<div data-search-bar className={cn("relative flex flex-col", className)}>
|
|
@@ -86,7 +89,7 @@ function SearchBar({
|
|
|
86
89
|
<InputGroup
|
|
87
90
|
className={cn(
|
|
88
91
|
"h-12",
|
|
89
|
-
|
|
92
|
+
showFilterBar && "[border-bottom-left-radius:0] [border-bottom-right-radius:0]"
|
|
90
93
|
)}
|
|
91
94
|
>
|
|
92
95
|
<InputGroupAddon align="inline-start">
|
|
@@ -101,15 +104,15 @@ function SearchBar({
|
|
|
101
104
|
onFocus={onFocus}
|
|
102
105
|
autoComplete="off"
|
|
103
106
|
/>
|
|
104
|
-
{(!!value || (hasFilterCategories && !hasActiveFilters) || (!value && !!kbdHint)) && (
|
|
107
|
+
{(!!value || (hasFilterCategories && !hasActiveFilters && !alwaysShowFilterBar) || (!value && !!kbdHint)) && (
|
|
105
108
|
<InputGroupAddon align="inline-end">
|
|
106
109
|
{value && (
|
|
107
110
|
<InputGroupButton size="sm" variant="ghost" onClick={() => onChange("")} className="text-[var(--color-text-muted)] hover:text-[var(--color-text-default)]">
|
|
108
111
|
<XIcon className="size-4" />
|
|
109
112
|
</InputGroupButton>
|
|
110
113
|
)}
|
|
111
|
-
{!value && kbdHint && !hasFilterCategories && <Kbd>{kbdHint}</Kbd>}
|
|
112
|
-
{hasFilterCategories && !hasActiveFilters && (
|
|
114
|
+
{!value && kbdHint && (!hasFilterCategories || alwaysShowFilterBar) && <Kbd>{kbdHint}</Kbd>}
|
|
115
|
+
{hasFilterCategories && !hasActiveFilters && !alwaysShowFilterBar && (
|
|
113
116
|
<>
|
|
114
117
|
{!value && kbdHint && <Kbd>{kbdHint}</Kbd>}
|
|
115
118
|
<span className="h-4 w-px bg-[var(--color-border-default)]" />
|
|
@@ -130,41 +133,102 @@ function SearchBar({
|
|
|
130
133
|
)}
|
|
131
134
|
</InputGroup>
|
|
132
135
|
|
|
133
|
-
{/* Filter bar
|
|
134
|
-
{
|
|
136
|
+
{/* Filter bar */}
|
|
137
|
+
{showFilterBar && (
|
|
135
138
|
<div className="flex flex-wrap items-center gap-3 [border-bottom-left-radius:var(--radius-card)] [border-bottom-right-radius:var(--radius-card)] border border-t-0 border-[var(--color-border-default)] bg-[var(--color-bg-raised)] px-3 py-2.5">
|
|
136
|
-
{
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
139
|
+
{alwaysShowFilterBar ? (
|
|
140
|
+
// Always-open mode: one trigger per category, active ones show chips
|
|
141
|
+
<>
|
|
142
|
+
<span className="text-caption text-[var(--color-text-default)] shrink-0">Filters:</span>
|
|
143
|
+
{filterCategories.map(cat => {
|
|
144
|
+
const activeVals = activeFilters[cat.id] ?? []
|
|
145
|
+
const hasActive = activeVals.length > 0
|
|
146
|
+
|
|
147
|
+
if (hasActive) {
|
|
148
|
+
return (
|
|
149
|
+
<FilterCombobox
|
|
150
|
+
key={cat.id}
|
|
151
|
+
categories={[cat]}
|
|
152
|
+
onApply={onApplyFilter ?? (() => {})}
|
|
153
|
+
activeFilters={activeFilters}
|
|
154
|
+
trigger={({ onClick }) => (
|
|
155
|
+
<FilterChip
|
|
156
|
+
label={cat.label}
|
|
157
|
+
values={activeVals.map(v => ({
|
|
158
|
+
label: filterValueLabel(cat.id, v),
|
|
159
|
+
onRemove: () => onRemoveFilter?.(cat.id, v),
|
|
160
|
+
}))}
|
|
161
|
+
onLabelClick={onClick}
|
|
162
|
+
/>
|
|
163
|
+
)}
|
|
164
|
+
/>
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return (
|
|
169
|
+
<FilterCombobox
|
|
170
|
+
key={cat.id}
|
|
171
|
+
categories={[cat]}
|
|
172
|
+
onApply={onApplyFilter ?? (() => {})}
|
|
173
|
+
activeFilters={activeFilters}
|
|
174
|
+
trigger={({ onClick }) => (
|
|
175
|
+
<button
|
|
176
|
+
type="button"
|
|
177
|
+
onClick={onClick}
|
|
178
|
+
className="inline-flex items-center gap-1 rounded-full border border-[var(--color-border-default)] px-2 py-0.5 text-caption text-[var(--color-text-muted)] hover:text-[var(--color-text-default)] hover:border-[var(--color-border-hover,var(--color-border-default))] transition-colors"
|
|
179
|
+
>
|
|
180
|
+
{cat.label}
|
|
181
|
+
<PlusIcon className="size-3 shrink-0" />
|
|
182
|
+
</button>
|
|
183
|
+
)}
|
|
184
|
+
/>
|
|
185
|
+
)
|
|
186
|
+
})}
|
|
187
|
+
{hasActiveFilters && (
|
|
141
188
|
<FilterChip
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
label: filterValueLabel(categoryId, v),
|
|
146
|
-
onRemove: () => onRemoveFilter?.(categoryId, v),
|
|
147
|
-
}))}
|
|
148
|
-
onLabelClick={() => {}}
|
|
189
|
+
variant="clear-all"
|
|
190
|
+
className="ml-auto"
|
|
191
|
+
onClear={onClearFilters ?? (() => {})}
|
|
149
192
|
/>
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
193
|
+
)}
|
|
194
|
+
</>
|
|
195
|
+
) : (
|
|
196
|
+
// Legacy mode: active chips + generic Add button
|
|
197
|
+
<>
|
|
198
|
+
{Object.entries(activeFilters)
|
|
199
|
+
.filter(([, vals]) => vals.length > 0)
|
|
200
|
+
.map(([categoryId, values]) => {
|
|
201
|
+
const cat = filterCategories.find(c => c.id === categoryId)
|
|
202
|
+
return (
|
|
203
|
+
<FilterChip
|
|
204
|
+
key={categoryId}
|
|
205
|
+
label={cat?.label ?? categoryId}
|
|
206
|
+
values={values.map(v => ({
|
|
207
|
+
label: filterValueLabel(categoryId, v),
|
|
208
|
+
onRemove: () => onRemoveFilter?.(categoryId, v),
|
|
209
|
+
}))}
|
|
210
|
+
onLabelClick={() => {}}
|
|
211
|
+
/>
|
|
212
|
+
)
|
|
213
|
+
})}
|
|
214
|
+
<FilterCombobox
|
|
215
|
+
categories={filterCategories}
|
|
216
|
+
onApply={onApplyFilter ?? (() => {})}
|
|
217
|
+
activeFilters={activeFilters}
|
|
218
|
+
trigger={({ onClick }) => (
|
|
219
|
+
<Button variant="default" size="sm" className="h-7 text-caption gap-1.5 px-2.5" onClick={onClick}>
|
|
220
|
+
<PlusIcon className="size-3.5" />
|
|
221
|
+
Add
|
|
222
|
+
</Button>
|
|
223
|
+
)}
|
|
224
|
+
/>
|
|
225
|
+
<FilterChip
|
|
226
|
+
variant="clear-all"
|
|
227
|
+
className="ml-auto"
|
|
228
|
+
onClear={onClearFilters ?? (() => {})}
|
|
229
|
+
/>
|
|
230
|
+
</>
|
|
231
|
+
)}
|
|
168
232
|
</div>
|
|
169
233
|
)}
|
|
170
234
|
|
package/tokens/primitives.css
CHANGED
|
@@ -22,6 +22,18 @@
|
|
|
22
22
|
|
|
23
23
|
/* --- Color scales --- */
|
|
24
24
|
|
|
25
|
+
--primitive-beige-50: oklch(0.990 0.008 98);
|
|
26
|
+
--primitive-beige-100: oklch(0.982 0.030 98);
|
|
27
|
+
--primitive-beige-200: oklch(0.968 0.052 98);
|
|
28
|
+
--primitive-beige-300: oklch(0.948 0.072 98);
|
|
29
|
+
--primitive-beige-400: oklch(0.918 0.083 98);
|
|
30
|
+
--primitive-beige-500: oklch(0.876 0.085 98);
|
|
31
|
+
--primitive-beige-600: oklch(0.792 0.076 98);
|
|
32
|
+
--primitive-beige-700: oklch(0.680 0.062 98);
|
|
33
|
+
--primitive-beige-800: oklch(0.480 0.044 98);
|
|
34
|
+
--primitive-beige-900: oklch(0.310 0.028 98);
|
|
35
|
+
--primitive-beige-950: oklch(0.230 0.020 98);
|
|
36
|
+
|
|
25
37
|
--primitive-red-50: oklch(0.95 0.03 28);
|
|
26
38
|
--primitive-red-100: oklch(0.93 0.05 28);
|
|
27
39
|
--primitive-red-200: oklch(0.89 0.07 28);
|
|
@@ -58,9 +70,9 @@
|
|
|
58
70
|
--primitive-yellow-900: oklch(0.3 0.07 98);
|
|
59
71
|
--primitive-yellow-950: oklch(0.25 0.06 98);
|
|
60
72
|
|
|
61
|
-
--primitive-lulo-50: oklch(0.
|
|
62
|
-
--primitive-lulo-100: oklch(0.
|
|
63
|
-
--primitive-lulo-200: oklch(0.
|
|
73
|
+
--primitive-lulo-50: oklch(0.967 0.099 118);
|
|
74
|
+
--primitive-lulo-100: oklch(0.918 0.136 116);
|
|
75
|
+
--primitive-lulo-200: oklch(0.869 0.173 114);
|
|
64
76
|
--primitive-lulo-300: oklch(0.82 0.21 112);
|
|
65
77
|
--primitive-lulo-400: oklch(0.76 0.2 112);
|
|
66
78
|
--primitive-lulo-500: oklch(0.7 0.18 112);
|
|
@@ -106,6 +118,18 @@
|
|
|
106
118
|
--primitive-sea-900: oklch(0.29 0.07 220);
|
|
107
119
|
--primitive-sea-950: oklch(0.24 0.06 220);
|
|
108
120
|
|
|
121
|
+
--primitive-slate-50: oklch(0.950 0.012 218);
|
|
122
|
+
--primitive-slate-100: oklch(0.932 0.020 218);
|
|
123
|
+
--primitive-slate-200: oklch(0.898 0.032 218);
|
|
124
|
+
--primitive-slate-300: oklch(0.848 0.042 218);
|
|
125
|
+
--primitive-slate-400: oklch(0.762 0.054 218);
|
|
126
|
+
--primitive-slate-500: oklch(0.656 0.063 218);
|
|
127
|
+
--primitive-slate-600: oklch(0.560 0.054 218);
|
|
128
|
+
--primitive-slate-700: oklch(0.472 0.046 218);
|
|
129
|
+
--primitive-slate-800: oklch(0.352 0.034 218);
|
|
130
|
+
--primitive-slate-900: oklch(0.248 0.023 218);
|
|
131
|
+
--primitive-slate-950: oklch(0.198 0.017 218);
|
|
132
|
+
|
|
109
133
|
--primitive-blue-50: oklch(0.95 0.03 257);
|
|
110
134
|
--primitive-blue-100: oklch(0.93 0.04 257);
|
|
111
135
|
--primitive-blue-200: oklch(0.88 0.06 257);
|