fractalstyler2 0.4.0 → 0.7.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.
- package/README.md +114 -95
- package/dist/cli.js +105 -25
- package/dist/components/Accordion.svelte +44 -0
- package/dist/components/Accordion.svelte.d.ts +23 -0
- package/dist/components/AccordionItem.svelte +44 -0
- package/dist/components/AccordionItem.svelte.d.ts +21 -0
- package/dist/components/AppShell.svelte +86 -0
- package/dist/components/AppShell.svelte.d.ts +39 -0
- package/dist/components/ColorPicker.svelte +38 -0
- package/dist/components/ColorPicker.svelte.d.ts +6 -0
- package/dist/components/Hero.svelte +14 -0
- package/dist/components/Hero.svelte.d.ts +9 -0
- package/dist/components/LayoutPicker.svelte +34 -0
- package/dist/components/LayoutPicker.svelte.d.ts +6 -0
- package/dist/components/MotionPicker.svelte +34 -0
- package/dist/components/MotionPicker.svelte.d.ts +6 -0
- package/dist/components/PageShell.svelte +14 -0
- package/dist/components/PageShell.svelte.d.ts +9 -0
- package/dist/components/PageSplit.svelte +26 -0
- package/dist/components/PageSplit.svelte.d.ts +18 -0
- package/dist/components/ShapePicker.svelte +37 -0
- package/dist/components/ShapePicker.svelte.d.ts +6 -0
- package/dist/css/fractalstyler.css +10643 -0
- package/dist/css/fractalstyler.min.css +2 -0
- package/dist/index.d.ts +18 -6
- package/dist/index.js +30 -12
- package/dist/mcp/schemas/compile_fractals.json +3 -3
- package/dist/mcp/schemas/css_to_fractals.json +1 -1
- package/dist/mcp/schemas/generate_component.json +2 -2
- package/dist/mcp/schemas/instructions.md +41 -14
- package/dist/mcp/schemas/list_fractals.json +9 -7
- package/dist/mcp/schemas/validate_recipe.json +2 -2
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +334 -237
- package/dist/presets.core.d.ts +42 -0
- package/dist/presets.core.js +190 -0
- package/dist/presets.svelte.d.ts +6 -0
- package/dist/presets.svelte.js +21 -0
- package/dist/styles/_00_presets.sass +111 -0
- package/dist/styles/_00_themes.sass +1061 -0
- package/dist/styles/_00_tokens.sass +57 -17
- package/dist/styles/_01_config.sass +77 -70
- package/dist/styles/_02_dimensions.sass +174 -0
- package/dist/styles/_03_containers.sass +105 -0
- package/dist/styles/_04_layouts.sass +100 -0
- package/dist/styles/_05_shells.sass +374 -0
- package/dist/styles/_06_visuals.sass +236 -0
- package/dist/styles/_07_interactions.sass +112 -0
- package/dist/styles/_08_own.sass +4 -0
- package/dist/styles/canonical-markups.md +160 -0
- package/dist/styles/index.sass +11 -18
- package/dist/themes.d.ts +7 -0
- package/dist/themes.js +45 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +2 -0
- package/package.json +26 -15
- package/plugin.json +11 -10
- package/registry.json +2002 -0
- package/skills/fractal-styler/SKILL.md +137 -50
- package/skills/fractal-styler/references/fractals.md +416 -28
- package/skills/fractal-styler/references/tokens.md +110 -36
- package/dist/styles/_02_fonts.sass +0 -13
- package/dist/styles/_03_responsive.sass +0 -31
- package/dist/styles/_04_atoms.sass +0 -155
- package/dist/styles/_05_molecules.sass +0 -97
- package/dist/styles/_06_recipes.sass +0 -189
- package/dist/styles/_07_base.sass +0 -44
- package/dist/styles/_08_blocks.sass +0 -433
- package/dist/styles/_09_utilities.sass +0 -208
- package/dist/styles/_10_layouts.sass +0 -373
- package/dist/styles/_11_own.sass +0 -21
- package/dist/styles/_fractals.sass +0 -14
- package/skills/style-migration/SKILL.md +0 -45
- package/templates/_00_tokens.sass +0 -136
- package/templates/_01_config.sass +0 -66
- package/templates/_02_fonts.sass +0 -13
- package/templates/_03_responsive.sass +0 -31
- package/templates/_04_atoms.sass +0 -155
- package/templates/_05_molecules.sass +0 -97
- package/templates/_06_recipes.sass +0 -189
- package/templates/_07_base.sass +0 -44
- package/templates/_08_blocks.sass +0 -433
- package/templates/_09_utilities.sass +0 -207
- package/templates/_10_layouts.sass +0 -373
- package/templates/_11_own.sass +0 -21
- package/templates/_fractals.sass +0 -14
- package/templates/index.sass +0 -18
|
@@ -28,9 +28,20 @@
|
|
|
28
28
|
--border-subtle: #EDF2F7
|
|
29
29
|
--theme-color: #04825B
|
|
30
30
|
--theme-color-alt: #047857
|
|
31
|
-
--
|
|
32
|
-
--
|
|
31
|
+
--success: #10B981
|
|
32
|
+
--success-hover: #059669
|
|
33
|
+
--warning: #F59E0B
|
|
34
|
+
--warning-hover: #D97706
|
|
35
|
+
--danger: #EF4444
|
|
36
|
+
--danger-hover: #DC2626
|
|
37
|
+
--info: #3B82F6
|
|
38
|
+
--info-hover: #2563EB
|
|
39
|
+
--feedback-error: #DC2626
|
|
33
40
|
--ring: rgba(0, 127, 78, 0.35)
|
|
41
|
+
// Per-mode shadows (registry v1)
|
|
42
|
+
--shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06)
|
|
43
|
+
--shadow-md: 0 4px 12px rgba(15, 23, 42, 0.08)
|
|
44
|
+
--shadow-lg: 0 12px 32px rgba(15, 23, 42, 0.12)
|
|
34
45
|
|
|
35
46
|
=dark-theme-tokens
|
|
36
47
|
color-scheme: dark
|
|
@@ -54,10 +65,21 @@
|
|
|
54
65
|
--state-selected: #32405E
|
|
55
66
|
--theme-color: #38BDF8
|
|
56
67
|
--theme-color-alt: #0EA5E9
|
|
57
|
-
--theme: var(--theme-color)
|
|
58
|
-
--theme-hover: var(--theme-color-alt)
|
|
59
68
|
--text-inverse: #0E1118
|
|
69
|
+
--success: #34D399
|
|
70
|
+
--success-hover: #6EE7B7
|
|
71
|
+
--warning: #FBBF24
|
|
72
|
+
--warning-hover: #FCD34D
|
|
73
|
+
--danger: #F87171
|
|
74
|
+
--danger-hover: #FCA5A5
|
|
75
|
+
--info: #60A5FA
|
|
76
|
+
--info-hover: #93C5FD
|
|
77
|
+
--feedback-error: #F87171
|
|
60
78
|
--ring: rgba(16, 185, 129, 0.4)
|
|
79
|
+
// Per-mode shadows (registry v1)
|
|
80
|
+
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4)
|
|
81
|
+
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35)
|
|
82
|
+
--shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.45)
|
|
61
83
|
|
|
62
84
|
:root
|
|
63
85
|
color-scheme: light
|
|
@@ -76,17 +98,17 @@
|
|
|
76
98
|
--text-3xl: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem)
|
|
77
99
|
--text-4xl: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem)
|
|
78
100
|
|
|
79
|
-
// Fluid space scale
|
|
101
|
+
// Fluid space scale — the comfortable values. data-layout scales at USE
|
|
102
|
+
// sites: gaps/margins × var(--gap-scale), paddings × var(--pad-scale).
|
|
80
103
|
--space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem)
|
|
81
104
|
--space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem)
|
|
82
105
|
--space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem)
|
|
83
|
-
--space-
|
|
84
|
-
--space-
|
|
85
|
-
--space-
|
|
106
|
+
--space-sm: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem)
|
|
107
|
+
--space-md: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem)
|
|
108
|
+
--space-lg: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem)
|
|
86
109
|
--space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem)
|
|
87
110
|
--space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem)
|
|
88
111
|
--space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem)
|
|
89
|
-
--space-s-l: clamp(1.125rem, 0.5625rem + 2.5vw, 2.5rem)
|
|
90
112
|
|
|
91
113
|
// Radius (Concentric hierarchy)
|
|
92
114
|
--radius-0: 0
|
|
@@ -100,15 +122,25 @@
|
|
|
100
122
|
--radius-24: 24px
|
|
101
123
|
--radius-full: 9999px
|
|
102
124
|
|
|
125
|
+
// Radius channels — compositions read these; shape presets remap them.
|
|
126
|
+
// Defaults = curved (registry v1); unset data-shape IS curved.
|
|
127
|
+
--radius-sm: 8px
|
|
128
|
+
--radius-md: 16px
|
|
129
|
+
--radius-lg: 24px
|
|
130
|
+
|
|
131
|
+
// Motion language (registry v1) — durations and easings all compositions read.
|
|
132
|
+
--motion-fast: 120ms
|
|
133
|
+
--motion-base: 160ms
|
|
134
|
+
--motion-slow: 240ms
|
|
135
|
+
--ease-out: cubic-bezier(0.16, 1, 0.3, 1)
|
|
136
|
+
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1)
|
|
137
|
+
|
|
103
138
|
// Control Heights
|
|
104
139
|
--control-h-sm: 26px
|
|
105
140
|
--control-h-md: 32px
|
|
106
141
|
--control-h-lg: 38px
|
|
107
142
|
|
|
108
|
-
// Shadow
|
|
109
|
-
--shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06)
|
|
110
|
-
--shadow-md: 0 4px 12px rgba(15, 23, 42, 0.08)
|
|
111
|
-
--shadow-lg: 0 12px 32px rgba(15, 23, 42, 0.12)
|
|
143
|
+
// Shadow values live in the theme mixins (per-mode since registry v1).
|
|
112
144
|
|
|
113
145
|
// Layering
|
|
114
146
|
--z-base: 0
|
|
@@ -119,14 +151,24 @@
|
|
|
119
151
|
|
|
120
152
|
// Layout
|
|
121
153
|
--header-height: 48px
|
|
122
|
-
--footer-height:
|
|
154
|
+
--footer-height: 32px
|
|
123
155
|
--measure: 65ch
|
|
156
|
+
--page-gutter: clamp(1rem, 4vw, 2rem)
|
|
157
|
+
--sidebar-width: 260px
|
|
158
|
+
--toc-width: 240px
|
|
159
|
+
--card-min: 16rem
|
|
160
|
+
--breakpoint: 768px
|
|
124
161
|
|
|
125
162
|
// Default Light Palette
|
|
126
163
|
+light-theme-tokens
|
|
127
164
|
|
|
165
|
+
// Plain :root, NOT :root:not([data-mode='light']). The :not() was redundant —
|
|
166
|
+
// [data-mode='light'] is emitted below and wins on source order at equal
|
|
167
|
+
// specificity — and it was harmful: :not() pushed this to (0,2,0), which
|
|
168
|
+
// outranks a .theme-* class at (0,1,0). Under OS dark mode every theme's
|
|
169
|
+
// surface tokens were silently overridden by these generic defaults.
|
|
128
170
|
@media (prefers-color-scheme: dark)
|
|
129
|
-
:root
|
|
171
|
+
:root
|
|
130
172
|
+dark-theme-tokens
|
|
131
173
|
|
|
132
174
|
[data-mode='dark']
|
|
@@ -134,5 +176,3 @@
|
|
|
134
176
|
|
|
135
177
|
[data-mode='light']
|
|
136
178
|
+light-theme-tokens
|
|
137
|
-
|
|
138
|
-
|
|
@@ -1,70 +1,77 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
$
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
$
|
|
21
|
-
|
|
22
|
-
//
|
|
23
|
-
$
|
|
24
|
-
$
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// config — the builder knobs the Contract names. All !default: overridable at
|
|
3
|
+
// compile time, never edited in place. The numbered filename is not a valid
|
|
4
|
+
// Sass identifier, so a consumer MUST namespace the configuring load:
|
|
5
|
+
//
|
|
6
|
+
// @use 'styles/01_config' as cfg with ($literal-max: 256)
|
|
7
|
+
// @use 'styles/index' as *
|
|
8
|
+
//
|
|
9
|
+
// Configure before anything else loads 01_config, or Sass rejects it.
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
// The responsive seam. Every loop-generated class takes -mob (below) and
|
|
13
|
+
// -desk (at or above) this width.
|
|
14
|
+
$breakpoint: 768px !default
|
|
15
|
+
$responsive-modes: (mob: 'all and (max-width: #{$breakpoint - 1})', desk: 'all and (min-width: #{$breakpoint})') !default
|
|
16
|
+
|
|
17
|
+
// Literal ladder: the discrete pixel values .gap-{N}, .radius-{N}, .w-{N}… emit.
|
|
18
|
+
//
|
|
19
|
+
// Fine at the bottom, where interfaces genuinely need 1px and 2px precision,
|
|
20
|
+
// then multiples of $literal-step the rest of the way. A continuous 1…256
|
|
21
|
+
// range emitted 7,302 rungs per band to serve maybe forty useful values;
|
|
22
|
+
// nobody types .marg-left--193.
|
|
23
|
+
$literal-fine: (0, 1, 2, 4, 6, 8, 12) !default
|
|
24
|
+
$literal-step: 8 !default
|
|
25
|
+
$literal-max: 512 !default
|
|
26
|
+
|
|
27
|
+
// Space literals stop earlier than sizing ones. Gaps, paddings and margins are
|
|
28
|
+
// 24 of the 28 classes emitted per rung (marg doubles for negatives), so they
|
|
29
|
+
// dominate the output — and a 512px gap is meaningless where a 512px width is
|
|
30
|
+
// not. Large spacing is the preset steps' job: --space-3xl is already ~120px.
|
|
31
|
+
$literal-space-max: 64 !default
|
|
32
|
+
|
|
33
|
+
// Radius stops early for the same reason: .radius-full already handles pills,
|
|
34
|
+
// and the shape presets top out at --radius-lg (~24-32px). A 512px corner is
|
|
35
|
+
// not a corner.
|
|
36
|
+
$literal-radius-max: 64 !default
|
|
37
|
+
|
|
38
|
+
// Named steps for grid stepping and the shell rails (not the responsive seam).
|
|
39
|
+
$breakpoints: (sm: 640px, md: 768px, lg: 1024px, xl: 1280px) !default
|
|
40
|
+
|
|
41
|
+
// ============================================================================
|
|
42
|
+
// base — element baseline. Builder infrastructure, not registry classes: the
|
|
43
|
+
// registry is a list of classes; this only makes documents predictable so the
|
|
44
|
+
// classes behave. Deliberately minimal — no typographic opinions beyond body.
|
|
45
|
+
// ============================================================================
|
|
46
|
+
|
|
47
|
+
*,
|
|
48
|
+
*::before,
|
|
49
|
+
*::after
|
|
50
|
+
box-sizing: border-box
|
|
51
|
+
|
|
52
|
+
*
|
|
53
|
+
margin: 0
|
|
54
|
+
|
|
55
|
+
body, html
|
|
56
|
+
font-family: var(--font-sans)
|
|
57
|
+
font-size: var(--text-sm)
|
|
58
|
+
line-height: 1.5
|
|
59
|
+
color: var(--text-primary)
|
|
60
|
+
background: var(--bg)
|
|
61
|
+
box-sizing: border-box
|
|
62
|
+
|
|
63
|
+
img,
|
|
64
|
+
video,
|
|
65
|
+
svg
|
|
66
|
+
display: block
|
|
67
|
+
max-width: 100%
|
|
68
|
+
|
|
69
|
+
button,
|
|
70
|
+
input,
|
|
71
|
+
select,
|
|
72
|
+
textarea
|
|
73
|
+
font: inherit
|
|
74
|
+
color: inherit
|
|
75
|
+
|
|
76
|
+
a
|
|
77
|
+
color: inherit
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// dimensions — L1. The loop-generated half of the registry: 17 space families,
|
|
3
|
+
// radius, size, viewport heights, shadows — each class in three bands (base,
|
|
4
|
+
// -mob, -desk) per Contract 7. Presets are token-routed; literals are px.
|
|
5
|
+
// ============================================================================
|
|
6
|
+
|
|
7
|
+
@use 'sass:string'
|
|
8
|
+
@use 'sass:list'
|
|
9
|
+
@use 'sass:math'
|
|
10
|
+
@use '01_config' as *
|
|
11
|
+
|
|
12
|
+
// The literal ladder, built once: the fine tail, then every $literal-step up
|
|
13
|
+
// to $literal-max. Radius and sizing iterate all of it.
|
|
14
|
+
$literals: $literal-fine
|
|
15
|
+
@for $i from 2 through math.div($literal-max, $literal-step)
|
|
16
|
+
$literals: list.append($literals, $i * $literal-step)
|
|
17
|
+
|
|
18
|
+
// The space families take the same ladder truncated at $literal-space-max,
|
|
19
|
+
// radius at $literal-radius-max. Only sizing runs the whole thing.
|
|
20
|
+
$space-literals: ()
|
|
21
|
+
@each $n in $literals
|
|
22
|
+
@if $n <= $literal-space-max
|
|
23
|
+
$space-literals: list.append($space-literals, $n)
|
|
24
|
+
|
|
25
|
+
$radius-literals: ()
|
|
26
|
+
@each $n in $literals
|
|
27
|
+
@if $n <= $literal-radius-max
|
|
28
|
+
$radius-literals: list.append($radius-literals, $n)
|
|
29
|
+
$steps: ('3xs' '2xs' 'xs' 'sm' 'md' 'lg' 'xl' '2xl' '3xl')
|
|
30
|
+
|
|
31
|
+
// Space families, role-split for the layout preset: gaps/margins separate
|
|
32
|
+
// content (× --gap-scale); paddings are the container's breathing (× --pad-scale).
|
|
33
|
+
$gap-families: (gap: gap, rgap: row-gap, cgap: column-gap)
|
|
34
|
+
|
|
35
|
+
$pad-families: (pad: padding, pad-x: padding-inline, pad-y: padding-block, pad-top: padding-top, pad-right: padding-right, pad-bottom: padding-bottom, pad-left: padding-left)
|
|
36
|
+
|
|
37
|
+
// Negatives ride margin families only (Contract: `--` infix).
|
|
38
|
+
$marg-families: (marg: margin, marg-x: margin-inline, marg-y: margin-block, marg-top: margin-top, marg-right: margin-right, marg-bottom: margin-bottom, marg-left: margin-left)
|
|
39
|
+
|
|
40
|
+
// --- Base band ---------------------------------------------------------------
|
|
41
|
+
@each $name, $prop in $gap-families
|
|
42
|
+
@each $step in $steps
|
|
43
|
+
.#{$name}-#{$step}
|
|
44
|
+
#{$prop}: calc(var(--space-#{$step}) * var(--gap-scale, 1))
|
|
45
|
+
@each $n in $space-literals
|
|
46
|
+
.#{$name}-#{$n}
|
|
47
|
+
#{$prop}: #{$n}px
|
|
48
|
+
|
|
49
|
+
@each $name, $prop in $pad-families
|
|
50
|
+
@each $step in $steps
|
|
51
|
+
.#{$name}-#{$step}
|
|
52
|
+
#{$prop}: calc(var(--space-#{$step}) * var(--pad-scale, 1))
|
|
53
|
+
@each $n in $space-literals
|
|
54
|
+
.#{$name}-#{$n}
|
|
55
|
+
#{$prop}: #{$n}px
|
|
56
|
+
|
|
57
|
+
@each $name, $prop in $marg-families
|
|
58
|
+
@each $step in $steps
|
|
59
|
+
.#{$name}-#{$step}
|
|
60
|
+
#{$prop}: calc(var(--space-#{$step}) * var(--gap-scale, 1))
|
|
61
|
+
.#{$name}--#{$step}
|
|
62
|
+
#{$prop}: calc(var(--space-#{$step}) * var(--gap-scale, 1) * -1)
|
|
63
|
+
@each $n in $space-literals
|
|
64
|
+
.#{$name}-#{$n}
|
|
65
|
+
#{$prop}: #{$n}px
|
|
66
|
+
.#{$name}--#{$n}
|
|
67
|
+
#{$prop}: -#{$n}px
|
|
68
|
+
|
|
69
|
+
// Radius — literal px (0 = the reset); never rides shape presets.
|
|
70
|
+
@each $n in $radius-literals
|
|
71
|
+
.radius-#{$n}
|
|
72
|
+
border-radius: #{$n}px
|
|
73
|
+
|
|
74
|
+
.radius-full
|
|
75
|
+
border-radius: var(--radius-full)
|
|
76
|
+
|
|
77
|
+
// The radius CHANNELS as classes. Unlike the numeric ladder these follow
|
|
78
|
+
// data-shape, so a card on .radius-md goes round -> curved -> pro -> sharp with
|
|
79
|
+
// the preset. Reach for these first; the literals are for exact requirements.
|
|
80
|
+
@each $step in ('sm' 'md' 'lg')
|
|
81
|
+
.radius-#{$step}
|
|
82
|
+
border-radius: var(--radius-#{$step})
|
|
83
|
+
|
|
84
|
+
// Size
|
|
85
|
+
@each $n in $literals
|
|
86
|
+
.w-#{$n}
|
|
87
|
+
width: #{$n}px
|
|
88
|
+
.h-#{$n}
|
|
89
|
+
height: #{$n}px
|
|
90
|
+
.square-#{$n}
|
|
91
|
+
width: #{$n}px
|
|
92
|
+
height: #{$n}px
|
|
93
|
+
|
|
94
|
+
.wfull
|
|
95
|
+
width: 100%
|
|
96
|
+
.hfull
|
|
97
|
+
height: 100%
|
|
98
|
+
.full
|
|
99
|
+
width: 100%
|
|
100
|
+
height: 100%
|
|
101
|
+
.min0
|
|
102
|
+
min-width: 0
|
|
103
|
+
min-height: 0
|
|
104
|
+
|
|
105
|
+
// Viewport heights
|
|
106
|
+
.hfull-vh
|
|
107
|
+
min-height: 100vh
|
|
108
|
+
.hfull-vh-fitted
|
|
109
|
+
min-height: calc(100vh - var(--header-height, 48px) - var(--footer-height))
|
|
110
|
+
|
|
111
|
+
// --- Responsive bands: -mob / -desk, generated wholesale (Contract 7) --------
|
|
112
|
+
@each $mode, $query in $responsive-modes
|
|
113
|
+
@media #{string.unquote($query)}
|
|
114
|
+
@each $name, $prop in $gap-families
|
|
115
|
+
@each $step in $steps
|
|
116
|
+
.#{$name}-#{$step}-#{$mode}
|
|
117
|
+
#{$prop}: calc(var(--space-#{$step}) * var(--gap-scale, 1))
|
|
118
|
+
@each $n in $space-literals
|
|
119
|
+
.#{$name}-#{$n}-#{$mode}
|
|
120
|
+
#{$prop}: #{$n}px
|
|
121
|
+
@each $name, $prop in $pad-families
|
|
122
|
+
@each $step in $steps
|
|
123
|
+
.#{$name}-#{$step}-#{$mode}
|
|
124
|
+
#{$prop}: calc(var(--space-#{$step}) * var(--pad-scale, 1))
|
|
125
|
+
@each $n in $space-literals
|
|
126
|
+
.#{$name}-#{$n}-#{$mode}
|
|
127
|
+
#{$prop}: #{$n}px
|
|
128
|
+
@each $name, $prop in $marg-families
|
|
129
|
+
@each $step in $steps
|
|
130
|
+
.#{$name}-#{$step}-#{$mode}
|
|
131
|
+
#{$prop}: calc(var(--space-#{$step}) * var(--gap-scale, 1))
|
|
132
|
+
.#{$name}--#{$step}-#{$mode}
|
|
133
|
+
#{$prop}: calc(var(--space-#{$step}) * var(--gap-scale, 1) * -1)
|
|
134
|
+
@each $n in $space-literals
|
|
135
|
+
.#{$name}-#{$n}-#{$mode}
|
|
136
|
+
#{$prop}: #{$n}px
|
|
137
|
+
.#{$name}--#{$n}-#{$mode}
|
|
138
|
+
#{$prop}: -#{$n}px
|
|
139
|
+
@each $n in $radius-literals
|
|
140
|
+
.radius-#{$n}-#{$mode}
|
|
141
|
+
border-radius: #{$n}px
|
|
142
|
+
.radius-full-#{$mode}
|
|
143
|
+
border-radius: var(--radius-full)
|
|
144
|
+
@each $step in ('sm' 'md' 'lg')
|
|
145
|
+
.radius-#{$step}-#{$mode}
|
|
146
|
+
border-radius: var(--radius-#{$step})
|
|
147
|
+
@each $n in $literals
|
|
148
|
+
.w-#{$n}-#{$mode}
|
|
149
|
+
width: #{$n}px
|
|
150
|
+
.h-#{$n}-#{$mode}
|
|
151
|
+
height: #{$n}px
|
|
152
|
+
.square-#{$n}-#{$mode}
|
|
153
|
+
width: #{$n}px
|
|
154
|
+
height: #{$n}px
|
|
155
|
+
.wfull-#{$mode}
|
|
156
|
+
width: 100%
|
|
157
|
+
.hfull-#{$mode}
|
|
158
|
+
height: 100%
|
|
159
|
+
.full-#{$mode}
|
|
160
|
+
width: 100%
|
|
161
|
+
height: 100%
|
|
162
|
+
.min0-#{$mode}
|
|
163
|
+
min-width: 0
|
|
164
|
+
min-height: 0
|
|
165
|
+
.hfull-vh-#{$mode}
|
|
166
|
+
min-height: 100vh
|
|
167
|
+
.hfull-vh-fitted-#{$mode}
|
|
168
|
+
min-height: calc(100vh - var(--header-height, 48px) - var(--footer-height))
|
|
169
|
+
.shadow-sm-#{$mode}
|
|
170
|
+
box-shadow: var(--shadow-sm)
|
|
171
|
+
.shadow-md-#{$mode}
|
|
172
|
+
box-shadow: var(--shadow-md)
|
|
173
|
+
.shadow-lg-#{$mode}
|
|
174
|
+
box-shadow: var(--shadow-lg)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// flow — L2. Containers and the alignment universe, verbatim from the
|
|
3
|
+
// registry. Alignment classes are nested under their base — never standalone.
|
|
4
|
+
// x/y are physical axes, always (Contract 4).
|
|
5
|
+
// ============================================================================
|
|
6
|
+
.box
|
|
7
|
+
display: flex
|
|
8
|
+
flex-direction: column
|
|
9
|
+
&.xcenter
|
|
10
|
+
align-items: center
|
|
11
|
+
text-align: center
|
|
12
|
+
&.xleft
|
|
13
|
+
align-items: flex-start
|
|
14
|
+
text-align: left
|
|
15
|
+
&.xright
|
|
16
|
+
align-items: flex-end
|
|
17
|
+
text-align: right
|
|
18
|
+
&.ycenter
|
|
19
|
+
justify-content: center
|
|
20
|
+
&.ytop
|
|
21
|
+
justify-content: flex-start
|
|
22
|
+
&.ybot
|
|
23
|
+
justify-content: flex-end
|
|
24
|
+
&.ybetween
|
|
25
|
+
justify-content: space-between
|
|
26
|
+
&.yevenly
|
|
27
|
+
justify-content: space-evenly
|
|
28
|
+
&.yaround
|
|
29
|
+
justify-content: space-around
|
|
30
|
+
|
|
31
|
+
.row
|
|
32
|
+
display: flex
|
|
33
|
+
flex-direction: row
|
|
34
|
+
&.xleft
|
|
35
|
+
justify-content: flex-start
|
|
36
|
+
&.xcenter
|
|
37
|
+
justify-content: center
|
|
38
|
+
&.xright
|
|
39
|
+
justify-content: flex-end
|
|
40
|
+
&.xbetween
|
|
41
|
+
justify-content: space-between
|
|
42
|
+
&.xevenly
|
|
43
|
+
justify-content: space-evenly
|
|
44
|
+
&.xaround
|
|
45
|
+
justify-content: space-around
|
|
46
|
+
&.ycenter
|
|
47
|
+
align-items: center
|
|
48
|
+
&.ytop
|
|
49
|
+
align-items: flex-start
|
|
50
|
+
&.ybot
|
|
51
|
+
align-items: flex-end
|
|
52
|
+
|
|
53
|
+
.grid
|
|
54
|
+
display: grid
|
|
55
|
+
&.center
|
|
56
|
+
place-items: center
|
|
57
|
+
&.xcenter
|
|
58
|
+
justify-items: center
|
|
59
|
+
text-align: center
|
|
60
|
+
&.xleft
|
|
61
|
+
justify-items: start
|
|
62
|
+
text-align: left
|
|
63
|
+
&.xright
|
|
64
|
+
justify-items: end
|
|
65
|
+
text-align: right
|
|
66
|
+
&.xstretch
|
|
67
|
+
justify-items: stretch
|
|
68
|
+
&.ycenter
|
|
69
|
+
align-items: center
|
|
70
|
+
&.ytop
|
|
71
|
+
align-items: start
|
|
72
|
+
&.ybot
|
|
73
|
+
align-items: end
|
|
74
|
+
&.ystretch
|
|
75
|
+
align-items: stretch
|
|
76
|
+
&.xbetween
|
|
77
|
+
justify-content: space-between
|
|
78
|
+
&.xevenly
|
|
79
|
+
justify-content: space-evenly
|
|
80
|
+
&.xaround
|
|
81
|
+
justify-content: space-around
|
|
82
|
+
&.ybetween
|
|
83
|
+
align-content: space-between
|
|
84
|
+
&.yevenly
|
|
85
|
+
align-content: space-evenly
|
|
86
|
+
&.yaround
|
|
87
|
+
align-content: space-around
|
|
88
|
+
|
|
89
|
+
.wrap
|
|
90
|
+
flex-wrap: wrap
|
|
91
|
+
|
|
92
|
+
.grow
|
|
93
|
+
flex: 1 1 0%
|
|
94
|
+
|
|
95
|
+
.shrink-0
|
|
96
|
+
flex-shrink: 0
|
|
97
|
+
|
|
98
|
+
.relative
|
|
99
|
+
position: relative
|
|
100
|
+
.absolute
|
|
101
|
+
position: absolute
|
|
102
|
+
.fixed
|
|
103
|
+
position: fixed
|
|
104
|
+
.sticky
|
|
105
|
+
position: sticky
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// layouts — L3. Grids (gridding golden rules), card-grid, prose, frame
|
|
3
|
+
// presets, reel. Grids are pure stepping: no default gap — compose .gap-*
|
|
4
|
+
// (self-sufficiency; a default gap is an opinion the system doesn't hold).
|
|
5
|
+
// ============================================================================
|
|
6
|
+
|
|
7
|
+
@use 'sass:string'
|
|
8
|
+
@use 'sass:list'
|
|
9
|
+
@use 'sass:map'
|
|
10
|
+
@use '01_config' as *
|
|
11
|
+
|
|
12
|
+
$sm: map.get($breakpoints, sm)
|
|
13
|
+
$md: map.get($breakpoints, md)
|
|
14
|
+
$lg: map.get($breakpoints, lg)
|
|
15
|
+
|
|
16
|
+
// Gridding golden rules: exactly 3 items → 3→1, never 2+1; count 4 or a
|
|
17
|
+
// multiple of 4 → 4→2→1, never 3+1; 6 → 6→3→2→1 (both rules hold throughout).
|
|
18
|
+
.grid-1
|
|
19
|
+
display: grid
|
|
20
|
+
grid-template-columns: repeat(1, minmax(0, 1fr))
|
|
21
|
+
|
|
22
|
+
.grid-2
|
|
23
|
+
display: grid
|
|
24
|
+
grid-template-columns: repeat(1, minmax(0, 1fr))
|
|
25
|
+
@media #{string.unquote('(min-width: #{$md})')}
|
|
26
|
+
grid-template-columns: repeat(2, minmax(0, 1fr))
|
|
27
|
+
|
|
28
|
+
.grid-3
|
|
29
|
+
display: grid
|
|
30
|
+
grid-template-columns: repeat(1, minmax(0, 1fr))
|
|
31
|
+
@media #{string.unquote('(min-width: #{$lg})')}
|
|
32
|
+
grid-template-columns: repeat(3, minmax(0, 1fr))
|
|
33
|
+
|
|
34
|
+
.grid-4
|
|
35
|
+
display: grid
|
|
36
|
+
grid-template-columns: repeat(1, minmax(0, 1fr))
|
|
37
|
+
@media #{string.unquote('(min-width: #{$sm})')}
|
|
38
|
+
grid-template-columns: repeat(2, minmax(0, 1fr))
|
|
39
|
+
@media #{string.unquote('(min-width: #{$lg})')}
|
|
40
|
+
grid-template-columns: repeat(4, minmax(0, 1fr))
|
|
41
|
+
|
|
42
|
+
.grid-6
|
|
43
|
+
display: grid
|
|
44
|
+
grid-template-columns: repeat(1, minmax(0, 1fr))
|
|
45
|
+
@media #{string.unquote('(min-width: #{$sm})')}
|
|
46
|
+
grid-template-columns: repeat(2, minmax(0, 1fr))
|
|
47
|
+
@media #{string.unquote('(min-width: #{$md})')}
|
|
48
|
+
grid-template-columns: repeat(3, minmax(0, 1fr))
|
|
49
|
+
@media #{string.unquote('(min-width: #{$lg})')}
|
|
50
|
+
grid-template-columns: repeat(6, minmax(0, 1fr))
|
|
51
|
+
|
|
52
|
+
// Auto-fit repeatable cards — column count negotiable, min track from config.
|
|
53
|
+
.card-grid
|
|
54
|
+
display: grid
|
|
55
|
+
grid-template-columns: repeat(auto-fit, minmax(min(var(--card-min), 100%), 1fr))
|
|
56
|
+
|
|
57
|
+
// Prose — the reading measure (≤ 760px) + typographic rhythm (rhythm authored).
|
|
58
|
+
.prose
|
|
59
|
+
max-width: min(100%, 760px)
|
|
60
|
+
margin-inline: auto
|
|
61
|
+
line-height: 1.65
|
|
62
|
+
// Rhythm comes from gap, not from adjacent-sibling margins: one rule
|
|
63
|
+
// instead of a combinator, and it cannot leak into nested content.
|
|
64
|
+
display: flex
|
|
65
|
+
flex-direction: column
|
|
66
|
+
gap: calc(var(--space-sm) * var(--gap-scale, 1))
|
|
67
|
+
h1, h2, h3, h4
|
|
68
|
+
line-height: 1.25
|
|
69
|
+
font-weight: 600
|
|
70
|
+
// Extra breathing above a heading, on top of the gap.
|
|
71
|
+
margin-top: calc(var(--space-2xs) * var(--gap-scale, 1))
|
|
72
|
+
&:first-child
|
|
73
|
+
margin-top: 0
|
|
74
|
+
|
|
75
|
+
// Frame presets — aspect-ratio media boxes (replaces any frame abstraction).
|
|
76
|
+
$frame-ratios: ('16-9': '16 / 9', '9-16': '9 / 16', '4-3': '4 / 3', '3-4': '3 / 4', '3-2': '3 / 2', '2-3': '2 / 3', '1-1': '1 / 1')
|
|
77
|
+
@each $name, $ratio in $frame-ratios
|
|
78
|
+
.frame-#{$name}
|
|
79
|
+
aspect-ratio: #{$ratio}
|
|
80
|
+
overflow: hidden
|
|
81
|
+
position: relative
|
|
82
|
+
img, video, iframe
|
|
83
|
+
width: 100%
|
|
84
|
+
height: 100%
|
|
85
|
+
object-fit: cover
|
|
86
|
+
|
|
87
|
+
// Reel — the human-driven scroll-snap rail (filmstrip). Open for carousel duty.
|
|
88
|
+
.reel
|
|
89
|
+
display: flex
|
|
90
|
+
flex-direction: row
|
|
91
|
+
overflow-x: auto
|
|
92
|
+
overscroll-behavior-inline: contain
|
|
93
|
+
scroll-snap-type: inline mandatory
|
|
94
|
+
// The system's one permitted `>`. Snap targets must be the rail's own
|
|
95
|
+
// children: a descendant selector would make nested elements snap too and
|
|
96
|
+
// the rail would catch in the wrong places. Kept deliberately — see the
|
|
97
|
+
// combinator guard in scripts/validate-deck.js.
|
|
98
|
+
> *
|
|
99
|
+
flex: 0 0 auto
|
|
100
|
+
scroll-snap-align: start
|