fractalstyler2 0.0.1 → 0.1.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.
@@ -0,0 +1,93 @@
1
+ // =============================================================================
2
+ // MOLECULE FRACTALS — self-similar: each is a small graph of atom fractals.
3
+ // -----------------------------------------------------------------------------
4
+ // This is the payoff of the model. A molecule reads like a recipe of atoms,
5
+ // and a component (next layer up) reads like a recipe of molecules. Same move
6
+ // at every scale — that is the "fractal" in fractalstyler2.
7
+ // =============================================================================
8
+
9
+ @use 'config' as *
10
+ @use 'atoms' as *
11
+ @use 'responsive' as *
12
+
13
+ // Stack — vertical rhythm with one shared gap.
14
+ =stack($gap: xs, $x: null)
15
+ +box($x)
16
+ +gap($gap)
17
+
18
+ // Cluster — wrapping row of chips/tags/buttons.
19
+ =cluster($gap: xs, $x: start, $y: center)
20
+ +row($x, $y)
21
+ +wrap
22
+ +gap($gap)
23
+
24
+ // Center — a centered reading column bounded by a measure.
25
+ =center-column($max: var(--measure, 60ch), $pad: s)
26
+ max-width: $max
27
+ +mx-auto
28
+ +px($pad)
29
+
30
+ // Cover — fills a min-height with a centered focal child.
31
+ =cover($min: 100vh, $pad: s)
32
+ +box
33
+ min-height: $min
34
+ +pad($pad)
35
+ > *
36
+ margin-block: 0
37
+ > .center
38
+ +my-auto
39
+
40
+ // Frame — fixed aspect-ratio media box.
41
+ =frame($ratio: 16 / 9)
42
+ aspect-ratio: $ratio
43
+ overflow: hidden
44
+ > :is(img, video, iframe)
45
+ +full
46
+ object-fit: cover
47
+
48
+ // Reel — horizontal scroll-snap rail.
49
+ =reel($gap: xs)
50
+ +row
51
+ +gap($gap)
52
+ overflow-x: auto
53
+ overscroll-behavior-inline: contain
54
+ scroll-snap-type: inline mandatory
55
+ > *
56
+ scroll-snap-align: start
57
+ flex: 0 0 auto
58
+
59
+ // Sidebar — an intrinsic rail beside a fluid main; wraps when tight.
60
+ =with-sidebar($rail: 240px, $gap: s, $min: 60%)
61
+ +row
62
+ +wrap
63
+ +gap($gap)
64
+ > .rail
65
+ flex-basis: $rail
66
+ flex-grow: 1
67
+ > .flow
68
+ flex-basis: 0
69
+ flex-grow: 999
70
+ min-width: $min
71
+
72
+ // Surface — the "material" fractal: skin + elevation in one call.
73
+ // The building block of every card/panel/popover.
74
+ =surface($bg: surface, $pad: s, $radius: 12, $elevation: none)
75
+ +bg($bg)
76
+ +border
77
+ +radius($radius)
78
+ +pad($pad)
79
+ @if $elevation != none
80
+ +shadow($elevation)
81
+
82
+ // Responsive column grid from a per-breakpoint map:
83
+ // +cols((base: 1, sm: 2, lg: 3))
84
+ =cols($map, $gap: s)
85
+ display: grid
86
+ grid-auto-flow: row
87
+ +gap($gap)
88
+ @each $bp, $n in $map
89
+ @if $bp == base
90
+ grid-template-columns: repeat($n, minmax(0, 1fr))
91
+ @else
92
+ +at($bp)
93
+ grid-template-columns: repeat($n, minmax(0, 1fr))
@@ -0,0 +1,43 @@
1
+ // =============================================================================
2
+ // RESPONSIVE FRACTALS — the units that let any other fractal grow with the page.
3
+ // -----------------------------------------------------------------------------
4
+ // These are self-similar too: +at(md) wraps any block of fractal calls in a
5
+ // breakpoint, so a "responsive component" is just a component whose fractals
6
+ // are re-stated inside +at(...).
7
+ // =============================================================================
8
+
9
+ @use 'sass:map'
10
+ @use 'config' as *
11
+
12
+ // +at(md) — mobile-first min-width query by name (sm/md/lg/xl) or raw length.
13
+ =at($name)
14
+ $edge: $name
15
+ @if map.has-key($breakpoints, $name)
16
+ $edge: bp($name)
17
+ @media (min-width: #{$edge})
18
+ @content
19
+
20
+ // +until(md) — max-width query (one below the named edge).
21
+ =until($name)
22
+ $edge: $name
23
+ @if map.has-key($breakpoints, $name)
24
+ $edge: bp($name)
25
+ @media (max-width: #{$edge})
26
+ @content
27
+
28
+ // Container-query fractals — component-scoped responsiveness.
29
+ =cq
30
+ container-type: inline-size
31
+
32
+ =cq-at($width)
33
+ @container (min-width: #{$width})
34
+ @content
35
+
36
+ =cq-until($width)
37
+ @container (max-width: #{$width})
38
+ @content
39
+
40
+ // Motion / preference-aware fractal.
41
+ =reduce-motion
42
+ @media (prefers-reduced-motion: reduce)
43
+ @content
@@ -0,0 +1,127 @@
1
+ // =============================================================================
2
+ // TOKENS — the only place literal values live. Everything else is a fractal
3
+ // that consumes these custom properties. Light is the marker-free default so
4
+ // tokens stay defined during SSR and with JS disabled; dark comes from
5
+ // prefers-color-scheme and from an explicit [data-mode='dark'].
6
+ // =============================================================================
7
+
8
+ :root
9
+ color-scheme: light
10
+
11
+ // Fonts
12
+ --font-sans: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif
13
+ --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace
14
+
15
+ // Fluid type scale (Utopia 360→1240)
16
+ --text-xs: 0.75rem
17
+ --text-sm: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem)
18
+ --text-md: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem)
19
+ --text-lg: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem)
20
+ --text-xl: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem)
21
+ --text-2xl: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem)
22
+ --text-3xl: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem)
23
+ --text-4xl: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem)
24
+
25
+ // Fluid space scale
26
+ --space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem)
27
+ --space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem)
28
+ --space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem)
29
+ --space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem)
30
+ --space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem)
31
+ --space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem)
32
+ --space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem)
33
+ --space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem)
34
+ --space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem)
35
+ --space-s-l: clamp(1.125rem, 0.5625rem + 2.5vw, 2.5rem)
36
+
37
+ // Radius
38
+ --radius-0: 0
39
+ --radius-2: 2px
40
+ --radius-4: 4px
41
+ --radius-6: 6px
42
+ --radius-8: 8px
43
+ --radius-12: 12px
44
+ --radius-16: 16px
45
+ --radius-24: 24px
46
+ --radius-full: 9999px
47
+
48
+ // Shadow
49
+ --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06)
50
+ --shadow-md: 0 4px 12px rgba(15, 23, 42, 0.08)
51
+ --shadow-lg: 0 12px 32px rgba(15, 23, 42, 0.12)
52
+
53
+ // Layering
54
+ --z-base: 0
55
+ --z-raised: 10
56
+ --z-sticky: 100
57
+ --z-modal: 200
58
+ --z-toast: 300
59
+
60
+ // Layout
61
+ --header-height: 64px
62
+ --footer-height: 56px
63
+ --measure: 65ch
64
+
65
+ // Light palette (marker-free default)
66
+ --bg: #fdfefe
67
+ --bg-surface: #f8f7f7
68
+ --bg-raised: #f1f5f9
69
+ --text-primary: #0f172a
70
+ --text-secondary: #5b6472
71
+ --text-muted: #929497
72
+ --text-inverse: #ffffff
73
+ --border: #e2e8f0
74
+ --border-strong: #cbd5e1
75
+ --theme: #007f4e
76
+ --theme-hover: #00663f
77
+ --theme-active: #005031
78
+ --ring: rgba(0, 127, 78, 0.35)
79
+
80
+ @media (prefers-color-scheme: dark)
81
+ :root:not([data-mode='light'])
82
+ color-scheme: dark
83
+ --bg: #131313
84
+ --bg-surface: #1e1e1e
85
+ --bg-raised: #2b2b2b
86
+ --text-primary: #f9fafb
87
+ --text-secondary: #a7adb7
88
+ --text-muted: #6b7280
89
+ --text-inverse: #0b0f17
90
+ --border: #2f3030
91
+ --border-strong: #4a4b4b
92
+ --theme: #10b981
93
+ --theme-hover: #34d399
94
+ --theme-active: #059669
95
+ --ring: rgba(16, 185, 129, 0.4)
96
+
97
+ [data-mode='dark']
98
+ color-scheme: dark
99
+ --bg: #131313
100
+ --bg-surface: #1e1e1e
101
+ --bg-raised: #2b2b2b
102
+ --text-primary: #f9fafb
103
+ --text-secondary: #a7adb7
104
+ --text-muted: #6b7280
105
+ --text-inverse: #0b0f17
106
+ --border: #2f3030
107
+ --border-strong: #4a4b4b
108
+ --theme: #10b981
109
+ --theme-hover: #34d399
110
+ --theme-active: #059669
111
+ --ring: rgba(16, 185, 129, 0.4)
112
+
113
+ [data-mode='light']
114
+ color-scheme: light
115
+ --bg: #fdfefe
116
+ --bg-surface: #f8f7f7
117
+ --bg-raised: #f1f5f9
118
+ --text-primary: #0f172a
119
+ --text-secondary: #5b6472
120
+ --text-muted: #929497
121
+ --text-inverse: #ffffff
122
+ --border: #e2e8f0
123
+ --border-strong: #cbd5e1
124
+ --theme: #007f4e
125
+ --theme-hover: #00663f
126
+ --theme-active: #005031
127
+ --ring: rgba(0, 127, 78, 0.35)
@@ -0,0 +1,125 @@
1
+ // =============================================================================
2
+ // UTILITY PROJECTION — the *other* way to consume a fractal.
3
+ // -----------------------------------------------------------------------------
4
+ // A fractal is a mixin. Here we bind a subset of them to class names so they
5
+ // stay usable straight from markup (`class="box gap-m pad-l"`). This is the
6
+ // key idea: utility classes are not a separate system — they are a generated
7
+ // projection of the exact same fractals your components compose. Emit only the
8
+ // atoms you want in markup; delete this whole file if you go SASS-only.
9
+ // =============================================================================
10
+
11
+ @use 'config' as *
12
+ @use 'atoms' as *
13
+ @use 'molecules' as *
14
+ @use 'responsive' as *
15
+
16
+ // --- Flow ------------------------------------------------------------------
17
+ .box
18
+ +box
19
+ .row
20
+ +row
21
+ &.wrap
22
+ +wrap
23
+
24
+ // Alignment modifiers, semantic and axis-aware.
25
+ .box
26
+ &.xcenter
27
+ align-items: center
28
+ &.xleft
29
+ align-items: flex-start
30
+ &.xright
31
+ align-items: flex-end
32
+ &.ycenter
33
+ justify-content: center
34
+ &.ytop
35
+ justify-content: flex-start
36
+ &.ybot
37
+ justify-content: flex-end
38
+
39
+ .row
40
+ &.ycenter
41
+ align-items: center
42
+ &.ytop
43
+ align-items: flex-start
44
+ &.ybot
45
+ align-items: flex-end
46
+ &.xbetween
47
+ justify-content: space-between
48
+ &.xevenly
49
+ justify-content: space-evenly
50
+ &.xleft
51
+ justify-content: flex-start
52
+ &.xright
53
+ justify-content: flex-end
54
+
55
+ // Fixed column grids.
56
+ @for $n from 1 through 6
57
+ .grid-cols-#{$n}
58
+ +grid($n)
59
+
60
+ .center
61
+ +center
62
+
63
+ // --- Spacing scale → gap-* / pad-* -----------------------------------------
64
+ @each $s in $space-steps
65
+ .gap-#{$s}
66
+ +gap($s)
67
+ .pad-#{$s}
68
+ +pad($s)
69
+ .px-#{$s}
70
+ +px($s)
71
+ .py-#{$s}
72
+ +py($s)
73
+
74
+ // --- Radius / shadow / surface ---------------------------------------------
75
+ @each $r in $radius-steps
76
+ .radius-#{$r}
77
+ +radius($r)
78
+
79
+ @each $s in $shadow-steps
80
+ .shadow-#{$s}
81
+ +shadow($s)
82
+
83
+ @each $role in $surface-roles
84
+ .bg-#{$role}
85
+ +bg($role)
86
+
87
+ .border
88
+ +border
89
+ @each $side in top right bottom left
90
+ .border-#{$side}
91
+ +border($side)
92
+
93
+ // --- Type ------------------------------------------------------------------
94
+ @each $t in $text-steps
95
+ .text-#{$t}
96
+ +type($t)
97
+
98
+ .truncate
99
+ +truncate
100
+
101
+ // Semantic type primitives — so you stop retyping `.text-sm .lh15 .muted`.
102
+ .body
103
+ +type(md)
104
+ +leading(1.6)
105
+ +ink(primary)
106
+ .muted
107
+ +ink(secondary)
108
+ .eyebrow
109
+ +type(sm)
110
+ +ink(muted)
111
+ text-transform: uppercase
112
+ letter-spacing: 0.06em
113
+ font-weight: 500
114
+
115
+ // --- Sizing shortcuts ------------------------------------------------------
116
+ .wfull
117
+ +w(100%)
118
+ .hfull
119
+ +h(100%)
120
+ .full
121
+ +full
122
+ .grow
123
+ +grow
124
+ .min0
125
+ +min0
@@ -0,0 +1,20 @@
1
+ // =============================================================================
2
+ // STYLES ENTRY — the full emitted stylesheet in cascade order.
3
+ // -----------------------------------------------------------------------------
4
+ // 1. tokens the CSS custom properties (only literal values)
5
+ // 2. base fluid reset
6
+ // 3. utilities atom fractals projected to markup classes (optional layer)
7
+ // 4. blocks components composed from fractals
8
+ // 5. layouts page templates composed from fractals
9
+ //
10
+ // Consume from a SvelteKit app: import '$lib/styles/index.sass'
11
+ // or from package: import 'fractalstyler2/styles'
12
+ // The fractal mixins/functions themselves emit nothing until called, so output
13
+ // contains only what you use.
14
+ // =============================================================================
15
+
16
+ @use './tokens'
17
+ @use './base'
18
+ @use './utilities'
19
+ @use './blocks'
20
+ @use './layouts'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes