farvist 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +324 -0
  3. package/assets/farvist.js +187 -0
  4. package/assets/icons/farvist-icons.svg +49 -0
  5. package/assets/logo.svg +11 -0
  6. package/assets/og-image.svg +34 -0
  7. package/assets/patterns/blob.svg +9 -0
  8. package/assets/patterns/dots.svg +3 -0
  9. package/assets/patterns/grid.svg +3 -0
  10. package/assets/patterns/mesh.svg +20 -0
  11. package/dist/farvist.css +8967 -0
  12. package/dist/farvist.min.css +1 -0
  13. package/package.json +53 -0
  14. package/scss/abstracts/_functions.scss +85 -0
  15. package/scss/abstracts/_index.scss +9 -0
  16. package/scss/abstracts/_mixins.scss +78 -0
  17. package/scss/abstracts/_variables.scss +252 -0
  18. package/scss/base/_reset.scss +120 -0
  19. package/scss/base/_root.scss +87 -0
  20. package/scss/base/_typography.scss +102 -0
  21. package/scss/components/_accordion.scss +64 -0
  22. package/scss/components/_alerts.scss +63 -0
  23. package/scss/components/_avatar.scss +76 -0
  24. package/scss/components/_badges.scss +54 -0
  25. package/scss/components/_breadcrumb.scss +44 -0
  26. package/scss/components/_buttons.scss +163 -0
  27. package/scss/components/_callout.scss +37 -0
  28. package/scss/components/_cards.scss +74 -0
  29. package/scss/components/_chip.scss +61 -0
  30. package/scss/components/_dropdown.scss +90 -0
  31. package/scss/components/_empty-state.scss +37 -0
  32. package/scss/components/_forms.scss +125 -0
  33. package/scss/components/_icon.scss +25 -0
  34. package/scss/components/_list-group.scss +60 -0
  35. package/scss/components/_modal.scss +95 -0
  36. package/scss/components/_navbar.scss +67 -0
  37. package/scss/components/_pagination.scss +51 -0
  38. package/scss/components/_progress.scss +60 -0
  39. package/scss/components/_range.scss +58 -0
  40. package/scss/components/_rating.scss +26 -0
  41. package/scss/components/_segmented.scss +51 -0
  42. package/scss/components/_skeleton.scss +52 -0
  43. package/scss/components/_spinner.scss +60 -0
  44. package/scss/components/_stat.scss +32 -0
  45. package/scss/components/_stepper.scss +78 -0
  46. package/scss/components/_switch.scss +65 -0
  47. package/scss/components/_table.scss +51 -0
  48. package/scss/components/_tabs.scss +64 -0
  49. package/scss/components/_timeline.scss +77 -0
  50. package/scss/components/_toast.scss +79 -0
  51. package/scss/components/_tooltip.scss +45 -0
  52. package/scss/farvist.scss +60 -0
  53. package/scss/layout/_grid.scss +83 -0
  54. package/scss/utilities/_backgrounds.scss +110 -0
  55. package/scss/utilities/_effects.scss +118 -0
  56. package/scss/utilities/_spacing.scss +76 -0
  57. package/scss/utilities/_utilities.scss +213 -0
@@ -0,0 +1,252 @@
1
+ // =============================================================================
2
+ // Farvist · Abstracts · Variables
3
+ // -----------------------------------------------------------------------------
4
+ // Every design decision in Farvist is a token defined here. Components and the
5
+ // utility generators read from these maps, so changing one value cascades
6
+ // everywhere. Override any token at import time:
7
+ //
8
+ // @use 'farvist' with ($primary: #00e0ff, $glass-blur: 22px);
9
+ //
10
+ // Each token carries `!default` so a `with (...)` configuration wins.
11
+ //
12
+ // The default look is a dark, futuristic "glass" theme. A light theme ships as
13
+ // a [data-theme="light"] override in base/_root.scss.
14
+ // =============================================================================
15
+
16
+ @use 'sass:map';
17
+
18
+ // -- Brand / theme colors (neon-leaning) --------------------------------------
19
+ $primary: #6d4af5 !default; // electric violet (AA: white text 5.3:1)
20
+ $secondary: #7c8aa5 !default; // cool slate
21
+ $success: #34d399 !default; // emerald
22
+ $danger: #fb5b78 !default; // rose
23
+ $warning: #fbbf24 !default; // amber
24
+ $info: #22d3ee !default; // cyan
25
+ $accent: #e879f9 !default; // fuchsia
26
+ $light: #e7ecf5 !default;
27
+ $dark: #0b0f1d !default;
28
+
29
+ // A map of the theme colors lets `@each` loops stamp out every color variant
30
+ // of a utility or component in a single pass. Add a key here and `.btn-*`,
31
+ // `.badge-*`, `.alert-*`, `.text-*`, `.bg-*`, `.glow-*` all gain it for free.
32
+ $theme-colors: (
33
+ 'primary': $primary,
34
+ 'secondary': $secondary,
35
+ 'success': $success,
36
+ 'danger': $danger,
37
+ 'warning': $warning,
38
+ 'info': $info,
39
+ 'accent': $accent,
40
+ 'light': $light,
41
+ 'dark': $dark,
42
+ ) !default;
43
+
44
+ // -- Greyscale ----------------------------------------------------------------
45
+ $white: #ffffff !default;
46
+ $black: #000000 !default;
47
+
48
+ $grays: (
49
+ '100': #f1f5f9,
50
+ '200': #e2e8f0,
51
+ '300': #cbd5e1,
52
+ '400': #94a3b8,
53
+ '500': #64748b,
54
+ '600': #475569,
55
+ '700': #334155,
56
+ '800': #1e293b,
57
+ '900': #0f172a,
58
+ ) !default;
59
+
60
+ // -- Surfaces (dark theme defaults) -------------------------------------------
61
+ $body-bg-dark: #060912 !default; // deep space base
62
+ $body-text-dark: #e6ebf5 !default;
63
+ $muted-dark: #95a3c4 !default;
64
+
65
+ // Light theme surfaces (used by the [data-theme="light"] override).
66
+ $body-bg-light: #eef1f8 !default;
67
+ $body-text-light: #0f172a !default;
68
+ $muted-light: #586b8f !default;
69
+
70
+ $border-color: rgba($white, 0.10) !default;
71
+
72
+ // -- Glassmorphism ------------------------------------------------------------
73
+ // The frosted-glass surface is built from translucent fills + a backdrop blur.
74
+ $glass-blur: 16px !default;
75
+ $glass-saturate: 140% !default;
76
+
77
+ $glass-bg-dark: rgba(255, 255, 255, 0.06) !default;
78
+ $glass-bg-strong-dark: rgba(255, 255, 255, 0.10) !default;
79
+ $glass-border-dark: rgba(255, 255, 255, 0.14) !default;
80
+ $surface-solid-dark: #121a2e !default; // opaque fallback when blur unsupported
81
+
82
+ $glass-bg-light: rgba(255, 255, 255, 0.55) !default;
83
+ $glass-bg-strong-light: rgba(255, 255, 255, 0.70) !default;
84
+ $glass-border-light: rgba(255, 255, 255, 0.80) !default;
85
+ $surface-solid-light: #ffffff !default;
86
+
87
+ // -- Gradients ----------------------------------------------------------------
88
+ // Built from the color tokens so a palette change cascades automatically.
89
+ $gradients: (
90
+ 'primary': linear-gradient(135deg, $primary 0%, $info 100%),
91
+ 'accent': linear-gradient(135deg, $accent 0%, $primary 100%),
92
+ 'sunset': linear-gradient(135deg, $danger 0%, $warning 100%),
93
+ 'aurora': linear-gradient(135deg, $success 0%, $info 100%),
94
+ ) !default;
95
+
96
+ // Radial "orbs" painted behind the page so glass surfaces have color to blur.
97
+ $bg-gradient-dark:
98
+ radial-gradient(48rem 48rem at 82% -12%, rgba($primary, 0.28), transparent 60%),
99
+ radial-gradient(36rem 36rem at -8% 18%, rgba($info, 0.20), transparent 58%),
100
+ radial-gradient(40rem 40rem at 50% 118%, rgba($accent, 0.18), transparent 58%) !default;
101
+ $bg-gradient-light:
102
+ radial-gradient(48rem 48rem at 82% -12%, rgba($primary, 0.18), transparent 60%),
103
+ radial-gradient(36rem 36rem at -8% 18%, rgba($info, 0.16), transparent 58%),
104
+ radial-gradient(40rem 40rem at 50% 118%, rgba($accent, 0.14), transparent 58%) !default;
105
+
106
+ // -- Neon glows ---------------------------------------------------------------
107
+ $glows: (
108
+ 'primary': 0 0 26px rgba($primary, 0.55),
109
+ 'accent': 0 0 26px rgba($accent, 0.55),
110
+ 'info': 0 0 26px rgba($info, 0.55),
111
+ 'success': 0 0 26px rgba($success, 0.50),
112
+ 'danger': 0 0 26px rgba($danger, 0.50),
113
+ 'warning': 0 0 26px rgba($warning, 0.50),
114
+ ) !default;
115
+
116
+ // -- Mesh gradient backdrops --------------------------------------------------
117
+ // Each value is a stack of radial "orbs" used as a background-image. Drives the
118
+ // `.bg-mesh-*` utilities — the headline free feature Tailwind/Bootstrap lack.
119
+ $bg-meshes: (
120
+ 'aurora': (
121
+ radial-gradient(55rem 55rem at 80% -10%, rgba($primary, 0.35), transparent 60%),
122
+ radial-gradient(45rem 45rem at -10% 25%, rgba($info, 0.28), transparent 58%),
123
+ radial-gradient(50rem 50rem at 55% 120%, rgba($accent, 0.24), transparent 58%)
124
+ ),
125
+ 'sunset': (
126
+ radial-gradient(55rem 55rem at 85% 0%, rgba($warning, 0.30), transparent 60%),
127
+ radial-gradient(50rem 50rem at 8% 18%, rgba($danger, 0.28), transparent 58%),
128
+ radial-gradient(45rem 45rem at 60% 120%, rgba($accent, 0.22), transparent 58%)
129
+ ),
130
+ 'ocean': (
131
+ radial-gradient(55rem 55rem at 80% -10%, rgba($info, 0.32), transparent 60%),
132
+ radial-gradient(50rem 50rem at 0% 30%, rgba($success, 0.24), transparent 58%),
133
+ radial-gradient(45rem 45rem at 50% 120%, rgba($primary, 0.22), transparent 58%)
134
+ ),
135
+ 'nebula': (
136
+ radial-gradient(50rem 50rem at 75% 8%, rgba($primary, 0.40), transparent 55%),
137
+ radial-gradient(40rem 40rem at 18% 28%, rgba($accent, 0.30), transparent 55%),
138
+ radial-gradient(45rem 45rem at 55% 115%, rgba($info, 0.25), transparent 58%)
139
+ ),
140
+ ) !default;
141
+
142
+ // -- Spacing scale ------------------------------------------------------------
143
+ $spacer: 1rem !default;
144
+ $spacers: (
145
+ 0: 0,
146
+ 1: $spacer * 0.25, // 4px
147
+ 2: $spacer * 0.5, // 8px
148
+ 3: $spacer * 0.75, // 12px
149
+ 4: $spacer, // 16px
150
+ 5: $spacer * 1.5, // 24px
151
+ 6: $spacer * 2, // 32px
152
+ 7: $spacer * 3, // 48px
153
+ 8: $spacer * 4, // 64px
154
+ ) !default;
155
+
156
+ // -- Typography ---------------------------------------------------------------
157
+ $font-family-base: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica,
158
+ Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji' !default;
159
+ $font-family-mono: ui-monospace, SFMono-Regular, 'SF Mono', 'JetBrains Mono', Menlo,
160
+ Consolas, 'Liberation Mono', monospace !default;
161
+
162
+ $font-size-root: 16px !default;
163
+ $font-size-base: 1rem !default;
164
+
165
+ $font-sizes: (
166
+ 'xs': 0.75rem,
167
+ 'sm': 0.875rem,
168
+ 'base': 1rem,
169
+ 'lg': 1.125rem,
170
+ 'xl': 1.25rem,
171
+ '2xl': 1.5rem,
172
+ '3xl': 1.875rem,
173
+ '4xl': 2.25rem,
174
+ '5xl': 3.25rem,
175
+ ) !default;
176
+
177
+ $font-weights: (
178
+ 'light': 300,
179
+ 'normal': 400,
180
+ 'medium': 500,
181
+ 'semibold': 600,
182
+ 'bold': 700,
183
+ 'black': 800,
184
+ ) !default;
185
+
186
+ $line-height-base: 1.6 !default;
187
+ $headings-line-height: 1.15 !default;
188
+ $headings-font-weight: 700 !default;
189
+
190
+ $headings: (
191
+ 1: map.get($font-sizes, '4xl'),
192
+ 2: map.get($font-sizes, '3xl'),
193
+ 3: map.get($font-sizes, '2xl'),
194
+ 4: map.get($font-sizes, 'xl'),
195
+ 5: map.get($font-sizes, 'lg'),
196
+ 6: map.get($font-sizes, 'base'),
197
+ ) !default;
198
+
199
+ // -- Borders & radius ---------------------------------------------------------
200
+ $border-width: 1px !default;
201
+ $border-radius: 0.75rem !default; // softer, more modern default
202
+
203
+ $radii: (
204
+ 'none': 0,
205
+ 'sm': 0.375rem,
206
+ 'md': 0.625rem,
207
+ 'lg': 0.875rem,
208
+ 'xl': 1.125rem,
209
+ '2xl': 1.5rem,
210
+ 'pill': 50rem,
211
+ 'full': 50%,
212
+ ) !default;
213
+
214
+ // -- Elevation (deep, for dark surfaces) --------------------------------------
215
+ $shadows: (
216
+ 'sm': (0 1px 2px rgba($black, 0.30)),
217
+ 'md': (0 8px 20px rgba($black, 0.35)),
218
+ 'lg': (0 18px 44px rgba($black, 0.45)),
219
+ 'xl': (0 30px 70px rgba($black, 0.55)),
220
+ ) !default;
221
+
222
+ // -- Grid & breakpoints -------------------------------------------------------
223
+ $grid-columns: 12 !default;
224
+ $grid-gutter: 1.5rem !default;
225
+
226
+ $grid-breakpoints: (
227
+ 'xs': 0,
228
+ 'sm': 576px,
229
+ 'md': 768px,
230
+ 'lg': 992px,
231
+ 'xl': 1200px,
232
+ 'xxl': 1400px,
233
+ ) !default;
234
+
235
+ $container-max-widths: (
236
+ 'sm': 540px,
237
+ 'md': 720px,
238
+ 'lg': 960px,
239
+ 'xl': 1140px,
240
+ 'xxl': 1320px,
241
+ ) !default;
242
+
243
+ // -- Motion & layering --------------------------------------------------------
244
+ $transition-base: 0.2s ease !default;
245
+
246
+ $z-layers: (
247
+ 'dropdown': 1000,
248
+ 'sticky': 1020,
249
+ 'fixed': 1030,
250
+ 'modal': 1050,
251
+ 'tooltip': 1070,
252
+ ) !default;
@@ -0,0 +1,120 @@
1
+ // =============================================================================
2
+ // Farvist · Base · Modern reset
3
+ // A compact, opinionated reset (in the spirit of Andy Bell / normalize) that
4
+ // removes default margins, fixes box-sizing, and respects user preferences.
5
+ // =============================================================================
6
+
7
+ @use '../abstracts' as *;
8
+
9
+ *,
10
+ *::before,
11
+ *::after {
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ * {
16
+ margin: 0;
17
+ }
18
+
19
+ html {
20
+ font-size: $font-size-root;
21
+ -webkit-text-size-adjust: 100%;
22
+ -moz-tab-size: 4;
23
+ tab-size: 4;
24
+ scroll-behavior: smooth;
25
+ }
26
+
27
+ body {
28
+ min-height: 100vh;
29
+ font-family: $font-family-base;
30
+ font-size: $font-size-base;
31
+ line-height: $line-height-base;
32
+ color: var(--fv-body-color);
33
+ // Base color plus fixed radial "orbs" so glass surfaces have color to blur.
34
+ background-color: var(--fv-body-bg);
35
+ background-image: var(--fv-bg-gradient);
36
+ background-attachment: fixed;
37
+ background-repeat: no-repeat;
38
+ -webkit-font-smoothing: antialiased;
39
+ text-rendering: optimizeLegibility;
40
+ transition: background-color $transition-base, color $transition-base;
41
+ }
42
+
43
+ // Media defaults: block-level and never overflow their container.
44
+ img,
45
+ picture,
46
+ video,
47
+ canvas,
48
+ svg {
49
+ display: block;
50
+ max-width: 100%;
51
+ height: auto;
52
+ }
53
+
54
+ // Inputs should inherit typography rather than impose browser defaults.
55
+ input,
56
+ button,
57
+ textarea,
58
+ select {
59
+ font: inherit;
60
+ color: inherit;
61
+ }
62
+
63
+ button {
64
+ background: none;
65
+ border: none;
66
+ cursor: pointer;
67
+ }
68
+
69
+ // Avoid long words breaking layout.
70
+ p,
71
+ h1,
72
+ h2,
73
+ h3,
74
+ h4,
75
+ h5,
76
+ h6 {
77
+ overflow-wrap: break-word;
78
+ }
79
+
80
+ // Opt-in: strip list styling only when an author marks a list as a "list" role.
81
+ ul[role='list'],
82
+ ol[role='list'] {
83
+ list-style: none;
84
+ padding: 0;
85
+ }
86
+
87
+ a {
88
+ color: $primary;
89
+ text-decoration: none;
90
+
91
+ &:hover {
92
+ text-decoration: underline;
93
+ }
94
+ }
95
+
96
+ table {
97
+ border-collapse: collapse;
98
+ width: 100%;
99
+ }
100
+
101
+ // A clear, consistent focus ring for keyboard users only.
102
+ :focus-visible {
103
+ outline: 2px solid $primary;
104
+ outline-offset: 2px;
105
+ }
106
+
107
+ // Honour users who ask for less motion.
108
+ @media (prefers-reduced-motion: reduce) {
109
+ html {
110
+ scroll-behavior: auto;
111
+ }
112
+
113
+ *,
114
+ *::before,
115
+ *::after {
116
+ animation-duration: 0.01ms !important;
117
+ animation-iteration-count: 1 !important;
118
+ transition-duration: 0.01ms !important;
119
+ }
120
+ }
@@ -0,0 +1,87 @@
1
+ // =============================================================================
2
+ // Farvist · Base · :root custom properties + themes
3
+ // The Sass tokens are mirrored into CSS custom properties so the whole system
4
+ // can be re-themed at runtime. The default is the dark "glass" theme; adding
5
+ // `data-theme="light"` to <html> swaps the surface variables.
6
+ // =============================================================================
7
+
8
+ @use '../abstracts' as *;
9
+
10
+ :root {
11
+ color-scheme: dark;
12
+
13
+ // Theme colors -> --fv-primary, --fv-accent, --fv-danger, ...
14
+ @each $name, $value in $theme-colors {
15
+ --fv-#{$name}: #{$value};
16
+ }
17
+
18
+ // Greyscale -> --fv-gray-100 ... --fv-gray-900
19
+ @each $key, $value in $grays {
20
+ --fv-gray-#{$key}: #{$value};
21
+ }
22
+
23
+ --fv-white: #{$white};
24
+ --fv-black: #{$black};
25
+
26
+ // Surfaces & text (dark theme)
27
+ --fv-body-bg: #{$body-bg-dark};
28
+ --fv-bg-gradient: #{$bg-gradient-dark};
29
+ --fv-body-color: #{$body-text-dark};
30
+ --fv-muted: #{$muted-dark};
31
+ --fv-border-color: #{$border-color};
32
+ --fv-code-bg: rgba(255, 255, 255, 0.07);
33
+ --fv-bg-pattern: rgba(255, 255, 255, 0.10); // ink for .bg-grid/.bg-dots/etc.
34
+
35
+ // Glass surface variables (consumed by the glass() mixin & .glass utilities)
36
+ --fv-glass-bg: #{$glass-bg-dark};
37
+ --fv-glass-bg-strong: #{$glass-bg-strong-dark};
38
+ --fv-glass-border: #{$glass-border-dark};
39
+ --fv-glass-blur: #{$glass-blur};
40
+ --fv-glass-saturate: #{$glass-saturate};
41
+ --fv-surface-solid: #{$surface-solid-dark};
42
+
43
+ // Typography
44
+ --fv-font-base: #{$font-family-base};
45
+ --fv-font-mono: #{$font-family-mono};
46
+ --fv-line-height: #{$line-height-base};
47
+
48
+ // Shape & motion
49
+ --fv-border-radius: #{$border-radius};
50
+ --fv-border-width: #{$border-width};
51
+ --fv-transition: #{$transition-base};
52
+ --fv-focus-ring: 0 0 0 3px #{rgba($primary, 0.45)};
53
+
54
+ // Elevation -> --fv-shadow-sm ... --fv-shadow-xl
55
+ @each $name, $value in $shadows {
56
+ --fv-shadow-#{$name}: #{$value};
57
+ }
58
+
59
+ // Neon glows -> --fv-glow-primary ...
60
+ @each $name, $value in $glows {
61
+ --fv-glow-#{$name}: #{$value};
62
+ }
63
+
64
+ // Gradients -> --fv-gradient-primary ...
65
+ @each $name, $value in $gradients {
66
+ --fv-gradient-#{$name}: #{$value};
67
+ }
68
+ }
69
+
70
+ // -- Light theme --------------------------------------------------------------
71
+ :root[data-theme='light'],
72
+ [data-theme='light'] {
73
+ color-scheme: light;
74
+
75
+ --fv-body-bg: #{$body-bg-light};
76
+ --fv-bg-gradient: #{$bg-gradient-light};
77
+ --fv-body-color: #{$body-text-light};
78
+ --fv-muted: #{$muted-light};
79
+ --fv-border-color: rgba(15, 23, 42, 0.12);
80
+ --fv-code-bg: rgba(15, 23, 42, 0.06);
81
+ --fv-bg-pattern: rgba(15, 23, 42, 0.10); // dark ink so patterns read on the light surface
82
+
83
+ --fv-glass-bg: #{$glass-bg-light};
84
+ --fv-glass-bg-strong: #{$glass-bg-strong-light};
85
+ --fv-glass-border: #{$glass-border-light};
86
+ --fv-surface-solid: #{$surface-solid-light};
87
+ }
@@ -0,0 +1,102 @@
1
+ // =============================================================================
2
+ // Farvist · Base · Typography
3
+ // Default element styles. Headings are generated from the `$headings` map so
4
+ // the type scale stays the single source of truth. Surface colors reference
5
+ // theme custom properties so they adapt to dark/light.
6
+ // =============================================================================
7
+
8
+ @use 'sass:map';
9
+ @use '../abstracts' as *;
10
+
11
+ // Generate h1..h6 (and matching .h1..-.h6 classes) from one map.
12
+ @each $level, $size in $headings {
13
+ h#{$level},
14
+ .h#{$level} {
15
+ margin-bottom: spacer(3);
16
+ font-size: $size;
17
+ font-weight: $headings-font-weight;
18
+ line-height: $headings-line-height;
19
+ letter-spacing: -0.01em;
20
+ }
21
+ }
22
+
23
+ p {
24
+ margin-bottom: spacer(4);
25
+ }
26
+
27
+ a {
28
+ transition: color $transition-base;
29
+ }
30
+
31
+ small,
32
+ .text-small {
33
+ font-size: map.get($font-sizes, 'sm');
34
+ }
35
+
36
+ strong,
37
+ b {
38
+ font-weight: map.get($font-weights, 'semibold');
39
+ }
40
+
41
+ // Inline & block code share the mono stack.
42
+ code,
43
+ pre,
44
+ kbd,
45
+ samp {
46
+ font-family: $font-family-mono;
47
+ }
48
+
49
+ code {
50
+ padding: 0.2em 0.45em;
51
+ font-size: 0.875em;
52
+ color: var(--fv-info);
53
+ background-color: var(--fv-code-bg);
54
+ border: $border-width solid var(--fv-border-color);
55
+ border-radius: map.get($radii, 'sm');
56
+ }
57
+
58
+ pre {
59
+ padding: spacer(4);
60
+ margin-bottom: spacer(4);
61
+ overflow: auto;
62
+ font-size: map.get($font-sizes, 'sm');
63
+ background-color: var(--fv-code-bg);
64
+ border: $border-width solid var(--fv-border-color);
65
+ border-radius: map.get($radii, 'md');
66
+
67
+ code {
68
+ padding: 0;
69
+ color: inherit;
70
+ background: none;
71
+ border: 0;
72
+ }
73
+ }
74
+
75
+ kbd {
76
+ padding: 0.15em 0.45em;
77
+ font-size: 0.85em;
78
+ color: var(--fv-body-color);
79
+ background-color: var(--fv-code-bg);
80
+ border: $border-width solid var(--fv-border-color);
81
+ border-radius: map.get($radii, 'sm');
82
+ }
83
+
84
+ blockquote {
85
+ padding-left: spacer(4);
86
+ margin-bottom: spacer(4);
87
+ color: var(--fv-muted);
88
+ border-left: 3px solid var(--fv-primary);
89
+ }
90
+
91
+ hr {
92
+ height: 0;
93
+ margin: spacer(5) 0;
94
+ border: 0;
95
+ border-top: $border-width solid var(--fv-border-color);
96
+ }
97
+
98
+ ul,
99
+ ol {
100
+ margin-bottom: spacer(4);
101
+ padding-left: spacer(5);
102
+ }
@@ -0,0 +1,64 @@
1
+ // =============================================================================
2
+ // Farvist · Components · Accordion (native <details>, no JS)
3
+ // Markup:
4
+ // <details class="accordion-item">
5
+ // <summary>Question</summary>
6
+ // <div class="accordion-body">Answer…</div>
7
+ // </details>
8
+ // =============================================================================
9
+
10
+ @use 'sass:map';
11
+ @use '../abstracts' as *;
12
+
13
+ .accordion-item {
14
+ margin-bottom: spacer(2);
15
+ border-radius: map.get($radii, 'lg');
16
+ overflow: hidden;
17
+ @include glass;
18
+
19
+ > summary {
20
+ display: flex;
21
+ align-items: center;
22
+ justify-content: space-between;
23
+ gap: spacer(3);
24
+ padding: spacer(3) spacer(4);
25
+ font-weight: map.get($font-weights, 'semibold');
26
+ list-style: none;
27
+ cursor: pointer;
28
+ transition: background-color $transition-base;
29
+
30
+ &::-webkit-details-marker {
31
+ display: none;
32
+ }
33
+
34
+ // CSS chevron that flips when open.
35
+ &::after {
36
+ content: '';
37
+ flex-shrink: 0;
38
+ width: 0.5rem;
39
+ height: 0.5rem;
40
+ border-right: 2px solid var(--fv-muted);
41
+ border-bottom: 2px solid var(--fv-muted);
42
+ transform: rotate(45deg);
43
+ transition: transform $transition-base;
44
+ }
45
+
46
+ &:hover {
47
+ background-color: var(--fv-glass-bg);
48
+ }
49
+
50
+ &:focus-visible {
51
+ outline: 0;
52
+ box-shadow: var(--fv-focus-ring);
53
+ }
54
+ }
55
+
56
+ &[open] > summary::after {
57
+ transform: rotate(-135deg);
58
+ }
59
+ }
60
+
61
+ .accordion-body {
62
+ padding: 0 spacer(4) spacer(4);
63
+ color: var(--fv-muted);
64
+ }
@@ -0,0 +1,63 @@
1
+ // =============================================================================
2
+ // Farvist · Components · Alerts
3
+ // Glass-tinted feedback banners. Each variant derives a translucent fill, a
4
+ // colored border, and a light-tinted text from a single theme color.
5
+ // =============================================================================
6
+
7
+ @use 'sass:map';
8
+ @use 'sass:color';
9
+ @use '../abstracts' as *;
10
+
11
+ .alert {
12
+ position: relative;
13
+ // Neutral, theme-aware text stays readable on both dark and light glass.
14
+ color: var(--fv-body-color);
15
+ padding: spacer(4) spacer(5);
16
+ margin-bottom: spacer(4);
17
+ border: $border-width solid transparent;
18
+ border-radius: map.get($radii, 'lg');
19
+ backdrop-filter: blur(var(--fv-glass-blur)) saturate(var(--fv-glass-saturate));
20
+ -webkit-backdrop-filter: blur(var(--fv-glass-blur)) saturate(var(--fv-glass-saturate));
21
+ }
22
+
23
+ .alert-heading {
24
+ margin-bottom: spacer(2);
25
+ font-weight: map.get($font-weights, 'bold');
26
+ }
27
+
28
+ .alert > :last-child {
29
+ margin-bottom: 0;
30
+ }
31
+
32
+ // Each variant contributes the hue via a translucent fill, a colored border
33
+ // and a colored left accent — readable in either theme.
34
+ @each $name, $clr in $theme-colors {
35
+ .alert-#{$name} {
36
+ background-color: rgba($clr, 0.13);
37
+ border-color: rgba($clr, 0.42);
38
+ border-left: 3px solid $clr;
39
+
40
+ .alert-heading {
41
+ color: $clr;
42
+ }
43
+
44
+ .alert-link {
45
+ color: $clr;
46
+ font-weight: map.get($font-weights, 'semibold');
47
+ text-decoration: underline;
48
+ }
49
+ }
50
+ }
51
+
52
+ // In the light theme the near-white alert fill needs darker accent text. Mix
53
+ // the hue toward the light ink so the heading/link clear WCAG AA (≥ 4.5:1).
54
+ [data-theme='light'] {
55
+ @each $name, $clr in $theme-colors {
56
+ .alert-#{$name} {
57
+ .alert-heading,
58
+ .alert-link {
59
+ color: color.mix($body-text-light, $clr, 65%);
60
+ }
61
+ }
62
+ }
63
+ }