@miozu/jera 0.3.0 → 0.4.3

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 (72) hide show
  1. package/CLAUDE.md +350 -59
  2. package/README.md +30 -22
  3. package/llms.txt +37 -4
  4. package/package.json +8 -2
  5. package/src/components/docs/CodeBlock.svelte +204 -0
  6. package/src/components/docs/DocSection.svelte +120 -0
  7. package/src/components/docs/PropsTable.svelte +136 -0
  8. package/src/components/docs/SplitPane.svelte +98 -0
  9. package/src/components/docs/index.js +14 -0
  10. package/src/components/feedback/Alert.svelte +234 -0
  11. package/src/components/feedback/EmptyState.svelte +6 -6
  12. package/src/components/feedback/ProgressBar.svelte +8 -8
  13. package/src/components/feedback/Skeleton.svelte +4 -4
  14. package/src/components/feedback/Spinner.svelte +1 -1
  15. package/src/components/feedback/Toast.svelte +137 -173
  16. package/src/components/forms/Checkbox.svelte +10 -10
  17. package/src/components/forms/Dropzone.svelte +14 -14
  18. package/src/components/forms/FileUpload.svelte +16 -16
  19. package/src/components/forms/IconInput.svelte +4 -4
  20. package/src/components/forms/Input.svelte +14 -14
  21. package/src/components/forms/NumberInput.svelte +13 -13
  22. package/src/components/forms/PinInput.svelte +8 -8
  23. package/src/components/forms/Radio.svelte +8 -8
  24. package/src/components/forms/RangeSlider.svelte +12 -12
  25. package/src/components/forms/SearchInput.svelte +10 -10
  26. package/src/components/forms/Select.svelte +156 -158
  27. package/src/components/forms/Switch.svelte +4 -4
  28. package/src/components/forms/Textarea.svelte +9 -9
  29. package/src/components/navigation/Accordion.svelte +1 -1
  30. package/src/components/navigation/AccordionItem.svelte +6 -6
  31. package/src/components/navigation/NavigationContainer.svelte +344 -0
  32. package/src/components/navigation/Sidebar.svelte +334 -0
  33. package/src/components/navigation/SidebarAccountGroup.svelte +495 -0
  34. package/src/components/navigation/SidebarAccountItem.svelte +492 -0
  35. package/src/components/navigation/SidebarGroup.svelte +230 -0
  36. package/src/components/navigation/SidebarGroupSwitcher.svelte +262 -0
  37. package/src/components/navigation/SidebarItem.svelte +210 -0
  38. package/src/components/navigation/SidebarNavigationItem.svelte +470 -0
  39. package/src/components/navigation/SidebarPopover.svelte +145 -0
  40. package/src/components/navigation/SidebarSearch.svelte +236 -0
  41. package/src/components/navigation/SidebarSection.svelte +158 -0
  42. package/src/components/navigation/SidebarToggle.svelte +86 -0
  43. package/src/components/navigation/Tabs.svelte +18 -18
  44. package/src/components/navigation/WorkspaceMenu.svelte +416 -0
  45. package/src/components/navigation/blocks/NavigationAccountGroup.svelte +396 -0
  46. package/src/components/navigation/blocks/NavigationCustomBlock.svelte +74 -0
  47. package/src/components/navigation/blocks/NavigationGroupSwitcher.svelte +277 -0
  48. package/src/components/navigation/blocks/NavigationSearch.svelte +300 -0
  49. package/src/components/navigation/blocks/NavigationSection.svelte +230 -0
  50. package/src/components/navigation/index.js +22 -0
  51. package/src/components/overlays/ConfirmDialog.svelte +18 -18
  52. package/src/components/overlays/Dropdown.svelte +2 -2
  53. package/src/components/overlays/DropdownDivider.svelte +1 -1
  54. package/src/components/overlays/DropdownItem.svelte +5 -5
  55. package/src/components/overlays/Modal.svelte +13 -13
  56. package/src/components/overlays/Popover.svelte +3 -3
  57. package/src/components/primitives/Avatar.svelte +12 -12
  58. package/src/components/primitives/Badge.svelte +7 -7
  59. package/src/components/primitives/Button.svelte +126 -174
  60. package/src/components/primitives/Card.svelte +15 -15
  61. package/src/components/primitives/Divider.svelte +3 -3
  62. package/src/components/primitives/LazyImage.svelte +1 -1
  63. package/src/components/primitives/Link.svelte +2 -2
  64. package/src/components/primitives/Stat.svelte +197 -0
  65. package/src/components/primitives/StatusBadge.svelte +24 -24
  66. package/src/index.js +62 -7
  67. package/src/tokens/colors.css +96 -128
  68. package/src/utils/highlighter.js +124 -0
  69. package/src/utils/index.js +7 -2
  70. package/src/utils/navigation.svelte.js +423 -0
  71. package/src/utils/reactive.svelte.js +126 -37
  72. package/src/utils/sidebar.svelte.js +211 -0
@@ -2,15 +2,6 @@
2
2
  @component Select
3
3
 
4
4
  An accessible dropdown select component with keyboard navigation.
5
- Demonstrates advanced Svelte 5 patterns:
6
-
7
- - $state for local UI state
8
- - $derived for computed values
9
- - $effect for side effects with cleanup
10
- - $bindable for two-way value binding
11
- - Actions for click-outside behavior
12
- - Keyboard navigation (ArrowUp/Down, Enter, Escape)
13
- - ARIA attributes for accessibility
14
5
 
15
6
  @example
16
7
  <Select
@@ -21,24 +12,12 @@
21
12
  bind:value={selected}
22
13
  placeholder="Select an option"
23
14
  />
24
-
25
- // With custom keys
26
- <Select
27
- options={users}
28
- bind:value={selectedUserId}
29
- labelKey="name"
30
- valueKey="id"
31
- />
32
15
  -->
33
16
  <script>
34
- import { cn, cv } from '../../utils/cn.svelte.js';
17
+ import { cn } from '../../utils/cn.svelte.js';
35
18
  import { clickOutside } from '../../actions/index.js';
36
19
  import { generateId } from '../../utils/reactive.svelte.js';
37
20
 
38
- /**
39
- * @typedef {{ [key: string]: any }} Option
40
- */
41
-
42
21
  let {
43
22
  options = [],
44
23
  value = $bindable(null),
@@ -51,52 +30,38 @@
51
30
  onchange
52
31
  } = $props();
53
32
 
54
- // Generate unique IDs for accessibility
55
33
  const triggerId = generateId();
56
34
  const listboxId = generateId();
57
35
 
58
- // Local state
59
36
  let isOpen = $state(false);
60
37
  let highlightedIndex = $state(-1);
61
38
  let triggerRef = $state(null);
62
39
  let listRef = $state(null);
63
40
 
64
- // Derived values
65
41
  const selectedOption = $derived(
66
42
  options.find(opt => opt[valueKey] === value) ?? null
67
43
  );
68
-
69
44
  const selectedLabel = $derived(
70
45
  selectedOption ? selectedOption[labelKey] : placeholder
71
46
  );
72
-
73
47
  const hasValue = $derived(value !== null && value !== undefined);
74
48
 
75
- // Keyboard navigation effect
76
49
  $effect(() => {
77
50
  if (!isOpen) {
78
51
  highlightedIndex = -1;
79
52
  return;
80
53
  }
81
-
82
- // Focus the listbox when opened
83
54
  listRef?.focus();
84
-
85
- // Set initial highlight to selected option
86
55
  const selectedIdx = options.findIndex(opt => opt[valueKey] === value);
87
56
  highlightedIndex = selectedIdx >= 0 ? selectedIdx : 0;
88
57
  });
89
58
 
90
- // Scroll highlighted option into view
91
59
  $effect(() => {
92
60
  if (!isOpen || highlightedIndex < 0) return;
93
-
94
- const listbox = listRef;
95
- const highlighted = listbox?.querySelector(`[data-index="${highlightedIndex}"]`);
61
+ const highlighted = listRef?.querySelector(`[data-index="${highlightedIndex}"]`);
96
62
  highlighted?.scrollIntoView({ block: 'nearest' });
97
63
  });
98
64
 
99
- // Handlers
100
65
  function toggle() {
101
66
  if (disabled) return;
102
67
  isOpen = !isOpen;
@@ -119,98 +84,46 @@
119
84
  switch (event.key) {
120
85
  case 'ArrowDown':
121
86
  event.preventDefault();
122
- if (!isOpen) {
123
- isOpen = true;
124
- } else {
125
- highlightedIndex = Math.min(highlightedIndex + 1, options.length - 1);
126
- }
87
+ if (!isOpen) isOpen = true;
88
+ else highlightedIndex = Math.min(highlightedIndex + 1, options.length - 1);
127
89
  break;
128
-
129
90
  case 'ArrowUp':
130
91
  event.preventDefault();
131
- if (!isOpen) {
132
- isOpen = true;
133
- } else {
134
- highlightedIndex = Math.max(highlightedIndex - 1, 0);
135
- }
92
+ if (!isOpen) isOpen = true;
93
+ else highlightedIndex = Math.max(highlightedIndex - 1, 0);
136
94
  break;
137
-
138
95
  case 'Enter':
139
96
  case ' ':
140
97
  event.preventDefault();
141
- if (isOpen && highlightedIndex >= 0) {
142
- select(options[highlightedIndex]);
143
- } else {
144
- toggle();
145
- }
98
+ if (isOpen && highlightedIndex >= 0) select(options[highlightedIndex]);
99
+ else toggle();
146
100
  break;
147
-
148
101
  case 'Escape':
149
102
  event.preventDefault();
150
103
  close();
151
104
  triggerRef?.focus();
152
105
  break;
153
-
154
106
  case 'Home':
155
107
  event.preventDefault();
156
108
  highlightedIndex = 0;
157
109
  break;
158
-
159
110
  case 'End':
160
111
  event.preventDefault();
161
112
  highlightedIndex = options.length - 1;
162
113
  break;
163
-
164
114
  case 'Tab':
165
115
  close();
166
116
  break;
167
117
  }
168
118
  }
169
-
170
- // Styles
171
- const triggerStyles = cv({
172
- base: [
173
- 'relative w-full flex items-center justify-between gap-2',
174
- 'h-10 px-3 rounded-lg border',
175
- 'text-sm text-left',
176
- 'transition-colors duration-150',
177
- 'focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2',
178
- 'disabled:opacity-50 disabled:cursor-not-allowed'
179
- ].join(' '),
180
-
181
- variants: {
182
- error: {
183
- true: 'border-error focus-visible:ring-error/50',
184
- false: 'border-border hover:border-muted focus-visible:ring-primary/50'
185
- },
186
- open: {
187
- true: 'border-primary ring-2 ring-primary/20',
188
- false: ''
189
- },
190
- hasValue: {
191
- true: 'text-text-strong',
192
- false: 'text-muted'
193
- }
194
- },
195
-
196
- defaults: {
197
- error: false,
198
- open: false,
199
- hasValue: false
200
- }
201
- });
202
119
  </script>
203
120
 
204
- <div
205
- class={cn('relative', className)}
206
- use:clickOutside={close}
207
- >
208
- <!-- Trigger Button -->
121
+ <div class={cn('select-wrapper', className)} use:clickOutside={close}>
209
122
  <button
210
123
  bind:this={triggerRef}
211
124
  id={triggerId}
212
125
  type="button"
213
- class={triggerStyles({ error, open: isOpen, hasValue })}
126
+ class={cn('select-trigger', isOpen && 'select-open', error && 'select-error', hasValue && 'has-value')}
214
127
  {disabled}
215
128
  aria-haspopup="listbox"
216
129
  aria-expanded={isOpen}
@@ -219,28 +132,12 @@
219
132
  onclick={toggle}
220
133
  onkeydown={handleKeydown}
221
134
  >
222
- <span class="truncate flex-1">
223
- {selectedLabel}
224
- </span>
225
-
226
- <!-- Chevron Icon -->
227
- <svg
228
- class={cn(
229
- 'w-4 h-4 shrink-0 text-muted transition-transform duration-200',
230
- isOpen && 'rotate-180'
231
- )}
232
- viewBox="0 0 24 24"
233
- fill="none"
234
- stroke="currentColor"
235
- stroke-width="2"
236
- stroke-linecap="round"
237
- stroke-linejoin="round"
238
- >
135
+ <span class="select-value">{selectedLabel}</span>
136
+ <svg class={cn('select-chevron', isOpen && 'rotated')} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
239
137
  <path d="m6 9 6 6 6-6" />
240
138
  </svg>
241
139
  </button>
242
140
 
243
- <!-- Dropdown Listbox -->
244
141
  {#if isOpen}
245
142
  <div
246
143
  bind:this={listRef}
@@ -248,60 +145,31 @@
248
145
  role="listbox"
249
146
  tabindex="-1"
250
147
  aria-labelledby={triggerId}
251
- aria-activedescendant={highlightedIndex >= 0 ? `${listboxId}-option-${highlightedIndex}` : undefined}
252
- class={cn(
253
- 'absolute z-50 w-full mt-1',
254
- 'max-h-60 overflow-auto',
255
- 'bg-surface border border-border rounded-lg shadow-lg',
256
- 'py-1',
257
- 'animate-in fade-in slide-in-from-top-2 duration-150'
258
- )}
148
+ class="select-dropdown"
259
149
  onkeydown={handleKeydown}
260
150
  >
261
151
  {#if options.length === 0}
262
- <div class="px-3 py-2 text-sm text-muted text-center">
263
- No options available
264
- </div>
152
+ <div class="select-empty">No options available</div>
265
153
  {:else}
266
154
  {#each options as option, index (option[valueKey])}
267
155
  {@const isSelected = option[valueKey] === value}
268
156
  {@const isHighlighted = index === highlightedIndex}
269
-
270
157
  <button
271
158
  id="{listboxId}-option-{index}"
272
159
  type="button"
273
160
  role="option"
274
161
  data-index={index}
275
162
  aria-selected={isSelected}
276
- class={cn(
277
- 'w-full flex items-center gap-2 px-3 py-2',
278
- 'text-sm text-left',
279
- 'transition-colors duration-75',
280
- 'focus:outline-none',
281
- isHighlighted && 'bg-hover',
282
- isSelected && 'text-primary font-medium',
283
- !isSelected && 'text-text'
284
- )}
163
+ class={cn('select-option', isHighlighted && 'highlighted', isSelected && 'selected')}
285
164
  onclick={() => select(option)}
286
165
  onmouseenter={() => highlightedIndex = index}
287
166
  >
288
- <!-- Check Icon for Selected -->
289
- <span class={cn('w-4 h-4 shrink-0', !isSelected && 'invisible')}>
290
- <svg
291
- viewBox="0 0 24 24"
292
- fill="none"
293
- stroke="currentColor"
294
- stroke-width="2.5"
295
- stroke-linecap="round"
296
- stroke-linejoin="round"
297
- >
167
+ <span class={cn('select-check', !isSelected && 'invisible')}>
168
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
298
169
  <path d="M20 6 9 17l-5-5" />
299
170
  </svg>
300
171
  </span>
301
-
302
- <span class="truncate flex-1">
303
- {option[labelKey]}
304
- </span>
172
+ <span class="select-option-label">{option[labelKey]}</span>
305
173
  </button>
306
174
  {/each}
307
175
  {/if}
@@ -310,17 +178,147 @@
310
178
  </div>
311
179
 
312
180
  <style>
313
- @keyframes fade-in {
314
- from { opacity: 0; }
315
- to { opacity: 1; }
181
+ .select-wrapper {
182
+ position: relative;
316
183
  }
317
184
 
318
- @keyframes slide-in-from-top-2 {
319
- from { transform: translateY(-0.5rem); }
320
- to { transform: translateY(0); }
185
+ .select-trigger {
186
+ position: relative;
187
+ width: 100%;
188
+ display: flex;
189
+ align-items: center;
190
+ justify-content: space-between;
191
+ gap: 0.5rem;
192
+ height: 2.5rem;
193
+ padding: 0 0.75rem;
194
+ border-radius: 0.5rem;
195
+ border: 1px solid var(--color-base03);
196
+ background-color: var(--color-base00);
197
+ color: var(--color-base04);
198
+ font-size: 0.875rem;
199
+ text-align: left;
200
+ cursor: pointer;
201
+ transition: border-color 150ms, box-shadow 150ms;
321
202
  }
322
203
 
323
- .animate-in {
324
- animation: fade-in 150ms ease-out, slide-in-from-top-2 150ms ease-out;
204
+ .select-trigger:hover:not(:disabled) {
205
+ border-color: var(--color-base04);
206
+ }
207
+
208
+ .select-trigger:focus-visible {
209
+ outline: none;
210
+ border-color: var(--color-base0D);
211
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-base0D) 20%, transparent);
212
+ }
213
+
214
+ .select-trigger:disabled {
215
+ opacity: 0.5;
216
+ cursor: not-allowed;
217
+ }
218
+
219
+ .select-trigger.has-value {
220
+ color: var(--color-base07);
221
+ }
222
+
223
+ .select-trigger.select-open {
224
+ border-color: var(--color-base0D);
225
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-base0D) 20%, transparent);
226
+ }
227
+
228
+ .select-trigger.select-error {
229
+ border-color: var(--color-base08);
230
+ }
231
+
232
+ .select-value {
233
+ flex: 1;
234
+ overflow: hidden;
235
+ text-overflow: ellipsis;
236
+ white-space: nowrap;
237
+ }
238
+
239
+ .select-chevron {
240
+ width: 1rem;
241
+ height: 1rem;
242
+ flex-shrink: 0;
243
+ color: var(--color-base04);
244
+ transition: transform 200ms;
245
+ }
246
+
247
+ .select-chevron.rotated {
248
+ transform: rotate(180deg);
249
+ }
250
+
251
+ .select-dropdown {
252
+ position: absolute;
253
+ z-index: 50;
254
+ width: 100%;
255
+ margin-top: 0.25rem;
256
+ max-height: 15rem;
257
+ overflow: auto;
258
+ background-color: var(--color-base01);
259
+ border: 1px solid var(--color-base03);
260
+ border-radius: 0.5rem;
261
+ box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.3);
262
+ padding: 0.25rem 0;
263
+ animation: dropdown-in 150ms ease-out;
264
+ }
265
+
266
+ .select-empty {
267
+ padding: 0.5rem 0.75rem;
268
+ font-size: 0.875rem;
269
+ color: var(--color-base04);
270
+ text-align: center;
271
+ }
272
+
273
+ .select-option {
274
+ width: 100%;
275
+ display: flex;
276
+ align-items: center;
277
+ gap: 0.5rem;
278
+ padding: 0.5rem 0.75rem;
279
+ font-size: 0.875rem;
280
+ text-align: left;
281
+ color: var(--color-base05);
282
+ background: transparent;
283
+ border: none;
284
+ cursor: pointer;
285
+ transition: background-color 75ms;
286
+ }
287
+
288
+ .select-option.highlighted {
289
+ background-color: var(--color-base02);
290
+ }
291
+
292
+ .select-option.selected {
293
+ color: var(--color-base0D);
294
+ font-weight: 500;
295
+ }
296
+
297
+ .select-check {
298
+ width: 1rem;
299
+ height: 1rem;
300
+ flex-shrink: 0;
301
+ }
302
+
303
+ .select-check.invisible {
304
+ visibility: hidden;
305
+ }
306
+
307
+ .select-option-label {
308
+ flex: 1;
309
+ overflow: hidden;
310
+ text-overflow: ellipsis;
311
+ white-space: nowrap;
312
+ }
313
+
314
+ @keyframes dropdown-in {
315
+ from {
316
+ opacity: 0;
317
+ transform: translateY(-0.5rem);
318
+ }
319
+ to {
320
+ opacity: 1;
321
+ transform: translateY(0);
322
+ }
325
323
  }
326
324
  </style>
@@ -91,16 +91,16 @@
91
91
  align-items: center;
92
92
  flex-shrink: 0;
93
93
  border-radius: var(--radius-full);
94
- background-color: var(--color-border);
94
+ background-color: var(--color-base03);
95
95
  transition: var(--transition-colors);
96
96
  }
97
97
 
98
98
  .switch-track-checked {
99
- background-color: var(--color-primary);
99
+ background-color: var(--color-base0D);
100
100
  }
101
101
 
102
102
  .switch-input:focus-visible + .switch-track {
103
- outline: 2px solid var(--color-primary);
103
+ outline: 2px solid var(--color-base0D);
104
104
  outline-offset: 2px;
105
105
  }
106
106
 
@@ -115,7 +115,7 @@
115
115
 
116
116
  .switch-label {
117
117
  font-size: var(--text-sm);
118
- color: var(--color-text);
118
+ color: var(--color-base05);
119
119
  }
120
120
 
121
121
  /* Size variants - Small */
@@ -81,9 +81,9 @@
81
81
  padding: var(--space-2) var(--space-3);
82
82
  font-size: var(--text-sm);
83
83
  line-height: 1.5;
84
- color: var(--color-text-strong);
85
- background-color: var(--color-bg);
86
- border: 1px solid var(--color-border-muted);
84
+ color: var(--color-base07);
85
+ background-color: var(--color-base00);
86
+ border: 1px solid var(--color-base02);
87
87
  border-radius: var(--radius-lg);
88
88
  transition: var(--transition-colors);
89
89
  resize: vertical;
@@ -91,13 +91,13 @@
91
91
  }
92
92
 
93
93
  .textarea-base::placeholder {
94
- color: var(--color-text-muted);
94
+ color: var(--color-base04);
95
95
  }
96
96
 
97
97
  .textarea-base:focus {
98
98
  outline: none;
99
- border-color: var(--color-primary);
100
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 20%, transparent);
99
+ border-color: var(--color-base0D);
100
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-base0D) 20%, transparent);
101
101
  }
102
102
 
103
103
  .textarea-base:disabled {
@@ -112,11 +112,11 @@
112
112
  }
113
113
 
114
114
  .textarea-error {
115
- border-color: var(--color-error);
115
+ border-color: var(--color-base08);
116
116
  }
117
117
 
118
118
  .textarea-error:focus {
119
- border-color: var(--color-error);
120
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-error) 20%, transparent);
119
+ border-color: var(--color-base08);
120
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-base08) 20%, transparent);
121
121
  }
122
122
  </style>
@@ -58,7 +58,7 @@
58
58
  .accordion {
59
59
  display: flex;
60
60
  flex-direction: column;
61
- border: 1px solid var(--color-border);
61
+ border: 1px solid var(--color-base03);
62
62
  border-radius: 0.5rem;
63
63
  overflow: hidden;
64
64
  }
@@ -84,7 +84,7 @@
84
84
 
85
85
  <style>
86
86
  .accordion-item {
87
- border-bottom: 1px solid var(--color-border);
87
+ border-bottom: 1px solid var(--color-base03);
88
88
  }
89
89
 
90
90
  .accordion-item:last-child {
@@ -105,18 +105,18 @@
105
105
  border: none;
106
106
  font-size: 0.9375rem;
107
107
  font-weight: 500;
108
- color: var(--color-text-strong);
108
+ color: var(--color-base07);
109
109
  cursor: pointer;
110
110
  text-align: left;
111
111
  transition: background 0.15s ease;
112
112
  }
113
113
 
114
114
  .accordion-trigger:hover:not([aria-disabled="true"]) {
115
- background: var(--color-surface);
115
+ background: var(--color-base01);
116
116
  }
117
117
 
118
118
  .accordion-trigger-open {
119
- background: var(--color-surface);
119
+ background: var(--color-base01);
120
120
  }
121
121
 
122
122
  .accordion-title {
@@ -125,7 +125,7 @@
125
125
 
126
126
  .accordion-icon {
127
127
  flex-shrink: 0;
128
- color: var(--color-text);
128
+ color: var(--color-base05);
129
129
  transition: transform 0.2s ease;
130
130
  }
131
131
 
@@ -140,7 +140,7 @@
140
140
  .accordion-body {
141
141
  padding: 0 1rem 1rem 1rem;
142
142
  font-size: 0.875rem;
143
- color: var(--color-text);
143
+ color: var(--color-base05);
144
144
  line-height: 1.6;
145
145
  }
146
146
  </style>