zeus-css 1.0.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 +81 -0
- package/bin/init.js +89 -0
- package/dist/zeus.css +8456 -0
- package/dist/zeus.min.css +1 -0
- package/package.json +44 -0
- package/scss/.stylelintrc.json +41 -0
- package/scss/API.md +168 -0
- package/scss/CHANGELOG.md +281 -0
- package/scss/LICENSE +21 -0
- package/scss/README.md +160 -0
- package/scss/cheatsheet.md +249 -0
- package/scss/dist/zeus.css +8465 -0
- package/scss/dist/zeus.css.map +1 -0
- package/scss/dist/zeus.min.css +1 -0
- package/scss/dist/zeus.min.css.map +1 -0
- package/scss/foundation/core/_api.scss +10 -0
- package/scss/foundation/core/_design.scss +33 -0
- package/scss/foundation/core/_engine.scss +18 -0
- package/scss/foundation/core/buttons/variants.scss +72 -0
- package/scss/foundation/core/design/_design-system.scss +41 -0
- package/scss/foundation/core/design/_validate.scss +114 -0
- package/scss/foundation/core/design/borders/border-line.scss +29 -0
- package/scss/foundation/core/design/borders/border-radius.scss +31 -0
- package/scss/foundation/core/design/buttons/sizes.scss +32 -0
- package/scss/foundation/core/design/colors/_color-derivation.scss +80 -0
- package/scss/foundation/core/design/colors/base-colors.scss +31 -0
- package/scss/foundation/core/design/colors/semantic-colors.scss +130 -0
- package/scss/foundation/core/design/core/basic.scss +40 -0
- package/scss/foundation/core/design/dimensions/sizes.scss +29 -0
- package/scss/foundation/core/design/dimensions/spaces.scss +42 -0
- package/scss/foundation/core/design/effects/_z-index.scss +30 -0
- package/scss/foundation/core/design/effects/shadows.scss +65 -0
- package/scss/foundation/core/design/layout/grid.scss +86 -0
- package/scss/foundation/core/design/typography/typography.scss +435 -0
- package/scss/foundation/core/engine/_fluid-core.scss +54 -0
- package/scss/foundation/core/engine/animations.scss +91 -0
- package/scss/foundation/core/engine/buttons.scss +226 -0
- package/scss/foundation/core/engine/color-api.scss +37 -0
- package/scss/foundation/core/engine/helpers.scss +39 -0
- package/scss/foundation/core/engine/layout.scss +156 -0
- package/scss/foundation/core/engine/responsive.scss +67 -0
- package/scss/foundation/core/engine/shadows.scss +186 -0
- package/scss/foundation/core/engine/shortcuts.scss +30 -0
- package/scss/foundation/core/engine/sizing.scss +49 -0
- package/scss/foundation/core/engine/theme-builder.scss +83 -0
- package/scss/foundation/core/engine/typographics.scss +44 -0
- package/scss/foundation/core/engine/typography-calc.scss +71 -0
- package/scss/foundation/foundation.scss +29 -0
- package/scss/foundation/views/_render.scss +13 -0
- package/scss/foundation/views/components/_alert.scss +103 -0
- package/scss/foundation/views/components/_avatar.scss +84 -0
- package/scss/foundation/views/components/_badge.scss +100 -0
- package/scss/foundation/views/components/_breadcrumb.scss +70 -0
- package/scss/foundation/views/components/_card.scss +117 -0
- package/scss/foundation/views/components/_dropdown.scss +123 -0
- package/scss/foundation/views/components/_form.scss +209 -0
- package/scss/foundation/views/components/_index.scss +20 -0
- package/scss/foundation/views/components/_modal.scss +138 -0
- package/scss/foundation/views/components/_pagination.scss +82 -0
- package/scss/foundation/views/components/_skeleton.scss +69 -0
- package/scss/foundation/views/components/_table.scss +94 -0
- package/scss/foundation/views/components/_tabs.scss +96 -0
- package/scss/foundation/views/components/_toast.scss +139 -0
- package/scss/foundation/views/components/_tooltip.scss +100 -0
- package/scss/foundation/views/patterns/_hero.scss +121 -0
- package/scss/foundation/views/patterns/_index.scss +8 -0
- package/scss/foundation/views/patterns/_sidebar-layout.scss +83 -0
- package/scss/foundation/views/render/_layer-order.scss +11 -0
- package/scss/foundation/views/render/classes/_animations.scss +233 -0
- package/scss/foundation/views/render/classes/_aspect-ratio.scss +17 -0
- package/scss/foundation/views/render/classes/_borders.scss +31 -0
- package/scss/foundation/views/render/classes/_buttons.scss +40 -0
- package/scss/foundation/views/render/classes/_colors.scss +83 -0
- package/scss/foundation/views/render/classes/_compounds.scss +103 -0
- package/scss/foundation/views/render/classes/_containers.scss +20 -0
- package/scss/foundation/views/render/classes/_misc-utils.scss +51 -0
- package/scss/foundation/views/render/classes/_position.scss +56 -0
- package/scss/foundation/views/render/classes/_sections.scss +30 -0
- package/scss/foundation/views/render/classes/_shadows.scss +198 -0
- package/scss/foundation/views/render/classes/_sizes.scss +39 -0
- package/scss/foundation/views/render/classes/_sizing-utils.scss +53 -0
- package/scss/foundation/views/render/classes/_spacing.scss +91 -0
- package/scss/foundation/views/render/classes/_state-variants.scss +47 -0
- package/scss/foundation/views/render/classes/_typography.scss +32 -0
- package/scss/foundation/views/render/classes/_utilities.scss +103 -0
- package/scss/foundation/views/render/classes/_z-index.scss +22 -0
- package/scss/foundation/views/render/classes/flexbox.scss +56 -0
- package/scss/foundation/views/render/classes/grid.scss +195 -0
- package/scss/foundation/views/render/classes.scss +116 -0
- package/scss/foundation/views/render/html-body.scss +54 -0
- package/scss/foundation/views/render/property-registration.scss +77 -0
- package/scss/foundation/views/render/reset.scss +147 -0
- package/scss/foundation/views/render/root-generator.scss +166 -0
- package/scss/foundation/views/render/root.scss +19 -0
- package/scss/foundation/views/render/typography.scss +129 -0
- package/scss/llms.txt +247 -0
- package/scss/package.json +89 -0
- package/scss/scripts/gen-cheatsheet.mjs +178 -0
- package/scss/scripts/gen-tokens.mjs +91 -0
- package/scss/scripts/test-compile.mjs +474 -0
- package/scss/zeus.config.scss +99 -0
- package/scss/zeus.customize.scss +246 -0
- package/scss/zeus.scss +17 -0
- package/scss/zeus.token.sets.example.scss +176 -0
- package/scss/zeus.tokens.json +687 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// ╔══════════════════════════════════════════════════════════════╗
|
|
2
|
+
// ║ ⚡ Zeus CSS — Fluid Core ║
|
|
3
|
+
// ║ ║
|
|
4
|
+
// ║ Framework internal engine and mixins for fluid core. ║
|
|
5
|
+
// ╚══════════════════════════════════════════════════════════════╝
|
|
6
|
+
|
|
7
|
+
@use "sass:math";
|
|
8
|
+
|
|
9
|
+
// ╔══════════════════════════════════════════════════════════════╗
|
|
10
|
+
// ║ ⚙️ Zeus Fluid Core — shared engine for clamp() generation ║
|
|
11
|
+
// ║ ║
|
|
12
|
+
// ║ Private file — NOT part of the public API. ║
|
|
13
|
+
// ║ Consumed by: ║
|
|
14
|
+
// ║ sizing.scss → useclamp-sizing() (px output) ║
|
|
15
|
+
// ║ typography-calc.scss → useclamp-typography() (rem output) ║
|
|
16
|
+
// ║ ║
|
|
17
|
+
// ║ Single source of truth for: ║
|
|
18
|
+
// ║ · precision rounding (round-to) ║
|
|
19
|
+
// ║ · linear fluid formula (zeus-cqi-fluid) ║
|
|
20
|
+
// ║ ║
|
|
21
|
+
// ║ Output: native clamp(min, preferred, max) ║
|
|
22
|
+
// ║ clamp() is faster to parse than max(min()) and produces ║
|
|
23
|
+
// ║ more compact, readable compiled CSS output. ║
|
|
24
|
+
// ╚══════════════════════════════════════════════════════════════╝
|
|
25
|
+
|
|
26
|
+
// ── round-to($value, $digits) ───────────────────────────────────
|
|
27
|
+
// Rounds $value to $digits decimal places.
|
|
28
|
+
// Prevents floating-point noise in compiled CSS output.
|
|
29
|
+
// round-to(1.041666, 3) → 1.042
|
|
30
|
+
// round-to(0.427083, 3) → 0.427
|
|
31
|
+
@function round-to($value, $digits: 1) {
|
|
32
|
+
$factor: math.pow(10, $digits);
|
|
33
|
+
@return math.div(math.round($value * $factor), $factor);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ── zeus-cqi-fluid($low, $high, $c-floor, $c-ceil, $unit, $accuracy) ──
|
|
37
|
+
//
|
|
38
|
+
// Engine for dynamic value interpolation using Container Queries.
|
|
39
|
+
// Uses native clamp() for faster browser parsing and cleaner CSS output.
|
|
40
|
+
//
|
|
41
|
+
// Output: clamp(${low}${unit}, calc(...cqi), ${high}${unit})
|
|
42
|
+
//
|
|
43
|
+
@function zeus-cqi-fluid($low, $high, $c-floor, $c-ceil, $unit, $accuracy: 1, $step: 0.1) {
|
|
44
|
+
$raw-slope: math.div($high - $low, $c-ceil - $c-floor);
|
|
45
|
+
$slope-cqi: round-to($raw-slope * 100, $accuracy);
|
|
46
|
+
|
|
47
|
+
// Derive intercept using rounded slope so endpoints match $low and $high with 100% precision
|
|
48
|
+
$intercept: $low - (math.div($slope-cqi, 100) * $c-floor);
|
|
49
|
+
$intercept-px: round-to($intercept, $accuracy);
|
|
50
|
+
|
|
51
|
+
$preferred-value: round(calc(#{$intercept-px}#{$unit} + #{$slope-cqi}cqi), #{$step}#{$unit});
|
|
52
|
+
|
|
53
|
+
@return clamp(#{$low}#{$unit}, #{$preferred-value}, #{$high}#{$unit});
|
|
54
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// ╔══════════════════════════════════════════════════════════════╗
|
|
2
|
+
// ║ ⚡ Zeus CSS — Animations ║
|
|
3
|
+
// ║ ║
|
|
4
|
+
// ║ Framework internal engine and mixins for animations. ║
|
|
5
|
+
// ╚══════════════════════════════════════════════════════════════╝
|
|
6
|
+
|
|
7
|
+
@use "sass:map";
|
|
8
|
+
|
|
9
|
+
// ╔══════════════════════════════════════════════════════════════╗
|
|
10
|
+
// ║ 🎬 Zeus Animation Engine — mixins only, no top-level CSS ║
|
|
11
|
+
// ║ ║
|
|
12
|
+
// ║ This file is part of the zeus.scss module-only entry point ║
|
|
13
|
+
// ║ (@use "zeus" as * inside .module.scss files) and MUST NOT ║
|
|
14
|
+
// ║ emit any top-level CSS — every component consuming it would ║
|
|
15
|
+
// ║ otherwise get a duplicate copy of that CSS in its own ║
|
|
16
|
+
// ║ compiled output. ║
|
|
17
|
+
// ║ ║
|
|
18
|
+
// ║ The @keyframes these mixins reference (zeus-fade-in, etc.) ║
|
|
19
|
+
// ║ are defined ONCE, globally, in: ║
|
|
20
|
+
// ║ views/render/classes/_animations.scss ║
|
|
21
|
+
// ║ which is only ever compiled as part of foundation.scss. ║
|
|
22
|
+
// ║ CSS @keyframes names are global page-wide identifiers, so ║
|
|
23
|
+
// ║ this works correctly even though the two files are separate.║
|
|
24
|
+
// ╚══════════════════════════════════════════════════════════════╝
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
// ─── MIXINS ────────────────────────────────────────────────────
|
|
28
|
+
// Each mixin sets animation properties only — no @keyframes inside.
|
|
29
|
+
|
|
30
|
+
// 1. Fade In
|
|
31
|
+
// Usage: @include fade-in(0.5s, 0.2s);
|
|
32
|
+
@mixin fade-in($duration: 0.3s, $delay: 0s, $timing: ease-in-out) {
|
|
33
|
+
opacity: 0;
|
|
34
|
+
animation: zeus-fade-in $duration $timing $delay forwards;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 2. Slide In (from any direction)
|
|
38
|
+
// Usage: @include slide-in(left, 0.4s);
|
|
39
|
+
@mixin slide-in(
|
|
40
|
+
$direction: bottom,
|
|
41
|
+
$duration: 0.3s,
|
|
42
|
+
$delay: 0s,
|
|
43
|
+
$timing: ease-out
|
|
44
|
+
) {
|
|
45
|
+
opacity: 0;
|
|
46
|
+
|
|
47
|
+
@if $direction == bottom {
|
|
48
|
+
animation: zeus-slide-in-bottom $duration $timing $delay forwards;
|
|
49
|
+
} @else if $direction == top {
|
|
50
|
+
animation: zeus-slide-in-top $duration $timing $delay forwards;
|
|
51
|
+
} @else if $direction == left {
|
|
52
|
+
animation: zeus-slide-in-left $duration $timing $delay forwards;
|
|
53
|
+
} @else if $direction == right {
|
|
54
|
+
animation: zeus-slide-in-right $duration $timing $delay forwards;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 3. Scale (hover zoom)
|
|
59
|
+
// Usage: @include scale(1.1, 0.3s);
|
|
60
|
+
@mixin scale($scale: 1.05, $duration: 0.3s, $timing: ease-in-out) {
|
|
61
|
+
transition: transform $duration $timing;
|
|
62
|
+
|
|
63
|
+
&:hover,
|
|
64
|
+
&:focus {
|
|
65
|
+
transform: scale($scale);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 4. Bounce
|
|
70
|
+
// Usage: @include bounce(0.6s, infinite);
|
|
71
|
+
@mixin bounce($duration: 0.8s, $iteration: 1, $delay: 0s) {
|
|
72
|
+
animation: zeus-bounce $duration ease-in-out $delay $iteration;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 5. Pulse (heartbeat)
|
|
76
|
+
// Usage: @include pulse(1.5s, infinite);
|
|
77
|
+
@mixin pulse($duration: 1s, $iteration: infinite) {
|
|
78
|
+
animation: zeus-pulse $duration ease-in-out $iteration;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// 6. Rotate
|
|
82
|
+
// Usage: @include rotate(360deg, 2s, linear, infinite);
|
|
83
|
+
@mixin rotate($degrees: 360deg, $duration: 1s, $timing: linear, $iteration: 1) {
|
|
84
|
+
--_zeus-rotate-deg: #{$degrees};
|
|
85
|
+
animation: zeus-rotate $duration $timing $iteration;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Note: the scroll-driven animation classes (.z-scroll-reveal/-tilt/-scale)
|
|
89
|
+
// and ALL @keyframes (including the ones the mixins above reference) live in
|
|
90
|
+
// views/render/classes/_animations.scss — see the header comment at the top
|
|
91
|
+
// of this file for why.
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
// ╔══════════════════════════════════════════════════════════════╗
|
|
2
|
+
// ║ ⚡ Zeus CSS — Buttons ║
|
|
3
|
+
// ║ ║
|
|
4
|
+
// ║ Framework internal engine and mixins for buttons. ║
|
|
5
|
+
// ╚══════════════════════════════════════════════════════════════╝
|
|
6
|
+
|
|
7
|
+
@use "sass:map";
|
|
8
|
+
@use "../buttons/variants" as *;
|
|
9
|
+
@use "../design/buttons/sizes" as *;
|
|
10
|
+
@use "./helpers" as *;
|
|
11
|
+
@use "./sizing" as *;
|
|
12
|
+
@use "./layout" as *;
|
|
13
|
+
|
|
14
|
+
// ------------------------------------------------------------
|
|
15
|
+
// Foundation: Base button reset & structure
|
|
16
|
+
// ------------------------------------------------------------
|
|
17
|
+
@mixin button-base-reset() {
|
|
18
|
+
// Layout & Display
|
|
19
|
+
display: inline-flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: center;
|
|
22
|
+
box-sizing: border-box;
|
|
23
|
+
|
|
24
|
+
// Box model parameters
|
|
25
|
+
margin: 0;
|
|
26
|
+
padding: 0;
|
|
27
|
+
gap: var(--space-sm);
|
|
28
|
+
|
|
29
|
+
// Border & Outline
|
|
30
|
+
border: none;
|
|
31
|
+
border-radius: 0;
|
|
32
|
+
outline: none;
|
|
33
|
+
|
|
34
|
+
// Background & Color
|
|
35
|
+
background: none;
|
|
36
|
+
color: var(--color-text);
|
|
37
|
+
|
|
38
|
+
// Text styling attributes
|
|
39
|
+
font: var(--text-link);
|
|
40
|
+
line-height: 1;
|
|
41
|
+
text-align: center;
|
|
42
|
+
text-decoration: none;
|
|
43
|
+
|
|
44
|
+
// Interaction
|
|
45
|
+
cursor: pointer;
|
|
46
|
+
user-select: none;
|
|
47
|
+
-webkit-tap-highlight-color: transparent;
|
|
48
|
+
|
|
49
|
+
// Disabled state
|
|
50
|
+
&[disabled] {
|
|
51
|
+
opacity: 0.5;
|
|
52
|
+
pointer-events: none;
|
|
53
|
+
cursor: default;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Remove browser defaults
|
|
57
|
+
&[type="button"],
|
|
58
|
+
&[type="reset"],
|
|
59
|
+
&[type="submit"] {
|
|
60
|
+
appearance: none;
|
|
61
|
+
-webkit-appearance: none;
|
|
62
|
+
-moz-appearance: none;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Accessible focus
|
|
66
|
+
&:focus {
|
|
67
|
+
outline: revert;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ------------------------------------------------------------
|
|
72
|
+
// Layout: Standard button padding & shape
|
|
73
|
+
// ------------------------------------------------------------
|
|
74
|
+
@mixin button-structure() {
|
|
75
|
+
// Padding presets
|
|
76
|
+
padding: var(--space-md) var(--space-lg);
|
|
77
|
+
// gap: var(--space-sm);
|
|
78
|
+
|
|
79
|
+
//default width
|
|
80
|
+
width: fit-content;
|
|
81
|
+
|
|
82
|
+
// Border
|
|
83
|
+
border-radius: var(--border-radius-sm);
|
|
84
|
+
|
|
85
|
+
// Layout adjustments
|
|
86
|
+
align-items: center;
|
|
87
|
+
justify-content: space-between;
|
|
88
|
+
|
|
89
|
+
// Inner text flow
|
|
90
|
+
text-align: center;
|
|
91
|
+
text-decoration: none;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ╔══════════════════════════════════════════════════════════════╗
|
|
95
|
+
// ║ 🔘 Zeus Button Engine ║
|
|
96
|
+
// ║ ║
|
|
97
|
+
// ║ Pattern: State Map → Direct Render (no intermediate fn) ║
|
|
98
|
+
// ╚══════════════════════════════════════════════════════════════╝
|
|
99
|
+
|
|
100
|
+
/// Render a map of CSS properties
|
|
101
|
+
@mixin _render($props) {
|
|
102
|
+
@if $props and $props != null {
|
|
103
|
+
@each $prop, $val in $props {
|
|
104
|
+
#{$prop}: #{$val};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/// Apply all states for a button variant
|
|
110
|
+
/// Uses direct map access instead of a getter function
|
|
111
|
+
@mixin button-apply-variant($variant: "primary") {
|
|
112
|
+
@if not map.has-key($button-variants, $variant) {
|
|
113
|
+
@error "[Zeus Button] Unknown variant '#{$variant}'. Available: #{map.keys($button-variants)}";
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
$states: map.get($button-variants, $variant);
|
|
117
|
+
|
|
118
|
+
// Default state — always present
|
|
119
|
+
@include _render(map.get($states, "default"));
|
|
120
|
+
|
|
121
|
+
// Interactive states — guard with :not([disabled])
|
|
122
|
+
$hover: map.get($states, "hover");
|
|
123
|
+
$active: map.get($states, "active");
|
|
124
|
+
|
|
125
|
+
@if $hover {
|
|
126
|
+
&:not([disabled]):hover {
|
|
127
|
+
@include _render($hover);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@if $active {
|
|
132
|
+
&:not([disabled]):active {
|
|
133
|
+
@include _render($active);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ╔══════════════════════════════════════════════════════════════╗
|
|
139
|
+
// ║ Public API: Complete button mixins ║
|
|
140
|
+
// ╚══════════════════════════════════════════════════════════════╝
|
|
141
|
+
@mixin btn-primary() {
|
|
142
|
+
@include button-base-reset();
|
|
143
|
+
@include button-structure();
|
|
144
|
+
@include button-apply-variant("primary");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@mixin btn-secondary() {
|
|
148
|
+
@include button-base-reset();
|
|
149
|
+
@include button-structure();
|
|
150
|
+
@include button-apply-variant("secondary");
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@mixin btn-tertiary() {
|
|
154
|
+
@include button-base-reset();
|
|
155
|
+
@include button-structure();
|
|
156
|
+
@include button-apply-variant("tertiary");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@mixin btn-icon-only() {
|
|
160
|
+
@include button-base-reset();
|
|
161
|
+
@include box-size(md);
|
|
162
|
+
|
|
163
|
+
// Icon-specific overrides
|
|
164
|
+
padding: 0;
|
|
165
|
+
justify-content: center;
|
|
166
|
+
|
|
167
|
+
@include button-apply-variant("icon-only");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// ------------------------------------------------------------
|
|
171
|
+
// Dynamic Button Variant Generator
|
|
172
|
+
// Creates a complete button with base, structure, and variant
|
|
173
|
+
// ------------------------------------------------------------
|
|
174
|
+
@mixin btn-variant($variant: "primary") {
|
|
175
|
+
@include button-base-reset();
|
|
176
|
+
@include button-structure();
|
|
177
|
+
@include button-apply-variant($variant);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// ------------------------------------------------------------
|
|
181
|
+
// Size System: Apply button size from tokens
|
|
182
|
+
// Clamp by default — always fluid, no flag check
|
|
183
|
+
// ------------------------------------------------------------
|
|
184
|
+
@mixin btn-size($size: "md") {
|
|
185
|
+
@if not map.has-key($button-sizes, $size) {
|
|
186
|
+
@error "Invalid button size '#{$size}'. Available: #{map.keys($button-sizes)}";
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
$size-config: map.get($button-sizes, $size);
|
|
190
|
+
|
|
191
|
+
// Font size
|
|
192
|
+
@if map.has-key($size-config, "font") {
|
|
193
|
+
$font-config: map.get($size-config, "font");
|
|
194
|
+
$min: map.get($font-config, "floor");
|
|
195
|
+
$max: map.get($font-config, "ceil");
|
|
196
|
+
font-size: useclamp-sizing($min, $max);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Padding Y (block axis)
|
|
200
|
+
@if map.has-key($size-config, "py") {
|
|
201
|
+
$py: map.get($size-config, "py");
|
|
202
|
+
$min: map.get($py, "floor");
|
|
203
|
+
$max: map.get($py, "ceil");
|
|
204
|
+
padding-block: useclamp-sizing($min, $max);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Padding X (inline axis) — logical property, not left/right, so RTL
|
|
208
|
+
// layouts get the correct side without a separate override.
|
|
209
|
+
@if map.has-key($size-config, "px") {
|
|
210
|
+
$px: map.get($size-config, "px");
|
|
211
|
+
$min: map.get($px, "floor");
|
|
212
|
+
$max: map.get($px, "ceil");
|
|
213
|
+
padding-inline: useclamp-sizing($min, $max);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Line height
|
|
217
|
+
@if map.has-key($size-config, "line-height") {
|
|
218
|
+
line-height: map.get($size-config, "line-height");
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Border radius
|
|
222
|
+
@if map.has-key($size-config, "border-radius") {
|
|
223
|
+
$radius: map.get($size-config, "border-radius");
|
|
224
|
+
border-radius: var(--border-radius-#{$radius});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// ╔══════════════════════════════════════════════════════════════╗
|
|
2
|
+
// ║ ⚡ Zeus CSS — Color Api ║
|
|
3
|
+
// ║ ║
|
|
4
|
+
// ║ Framework internal engine and mixins for color api. ║
|
|
5
|
+
// ╚══════════════════════════════════════════════════════════════╝
|
|
6
|
+
|
|
7
|
+
@use "sass:map";
|
|
8
|
+
@use "sass:meta";
|
|
9
|
+
@use "sass:color";
|
|
10
|
+
@use "../../../zeus.config" as config;
|
|
11
|
+
@use "./helpers" as *;
|
|
12
|
+
|
|
13
|
+
// ╔══════════════════════════════════════════════════════════════╗
|
|
14
|
+
// ║ 🎨 Zeus Color API — Universal Palette Mode ║
|
|
15
|
+
// ║ ║
|
|
16
|
+
// ║ Usage: ║
|
|
17
|
+
// ║ color("primary") → oklch(...) ║
|
|
18
|
+
// ║ color("primary", $alpha: 0.5) → oklch(... / 0.5) ║
|
|
19
|
+
// ╚══════════════════════════════════════════════════════════════╝
|
|
20
|
+
|
|
21
|
+
// Internal: flat lookup map directly from config
|
|
22
|
+
$_flat-palette: config.$zeus-colors !default;
|
|
23
|
+
|
|
24
|
+
/// Retrieve any color from the design palette with optional alpha
|
|
25
|
+
@function color($name, $alpha: 1) {
|
|
26
|
+
$resolved: map-get-safe($_flat-palette, $name);
|
|
27
|
+
|
|
28
|
+
@if $resolved == null {
|
|
29
|
+
@error "[Zeus Color] '#{$name}' not found in palette. Available: #{map.keys($_flat-palette)}";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@if $alpha < 1 {
|
|
33
|
+
@return color.change($resolved, $alpha: $alpha);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@return $resolved;
|
|
37
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// ╔══════════════════════════════════════════════════════════════╗
|
|
2
|
+
// ║ ⚡ Zeus CSS — Helpers ║
|
|
3
|
+
// ║ ║
|
|
4
|
+
// ║ Framework internal engine and mixins for helpers. ║
|
|
5
|
+
// ╚══════════════════════════════════════════════════════════════╝
|
|
6
|
+
|
|
7
|
+
@use "sass:map";
|
|
8
|
+
@use "sass:meta";
|
|
9
|
+
@use "sass:string";
|
|
10
|
+
|
|
11
|
+
// ============================================================
|
|
12
|
+
// Helper Functions
|
|
13
|
+
// ============================================================
|
|
14
|
+
|
|
15
|
+
//-----------------------------------------------------------------
|
|
16
|
+
// Extracts values from the provided map structure with type validation and unquoted key normalization
|
|
17
|
+
@function map-get-safe($map, $key) {
|
|
18
|
+
@if meta.type-of($map) != "map" {
|
|
19
|
+
@return null;
|
|
20
|
+
}
|
|
21
|
+
// Direct key match (fast path)
|
|
22
|
+
@if map.has-key($map, $key) {
|
|
23
|
+
@return map.get($map, $key);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Normalize both candidate key and map keys to unquoted strings and compare.
|
|
27
|
+
$needle: string.unquote("#{$key}");
|
|
28
|
+
|
|
29
|
+
@each $k in map.keys($map) {
|
|
30
|
+
$candidate: string.unquote("#{$k}");
|
|
31
|
+
@if $candidate == $needle {
|
|
32
|
+
@return map.get($map, $k);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Not found
|
|
37
|
+
@return null;
|
|
38
|
+
}
|
|
39
|
+
//-----------------------------------------------------------------
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// ╔══════════════════════════════════════════════════════════════╗
|
|
2
|
+
// ║ ⚡ Zeus CSS — Layout ║
|
|
3
|
+
// ║ ║
|
|
4
|
+
// ║ Framework internal engine and mixins for layout. ║
|
|
5
|
+
// ╚══════════════════════════════════════════════════════════════╝
|
|
6
|
+
|
|
7
|
+
@use "sass:map";
|
|
8
|
+
@use "./responsive" as *;
|
|
9
|
+
@use "../design/borders/border-radius" as *;
|
|
10
|
+
@use "../design/borders/border-line" as *;
|
|
11
|
+
@use "../design/dimensions/sizes" as *;
|
|
12
|
+
@use "../design/dimensions/spaces" as *;
|
|
13
|
+
@use "./helpers" as *;
|
|
14
|
+
@use "./sizing" as *;
|
|
15
|
+
|
|
16
|
+
// === adaptive private mixin ===
|
|
17
|
+
// CSS-Var-First: references the :root token instead of recomputing clamp()
|
|
18
|
+
// inline — the computation lives once in root-generator.scss. Smaller
|
|
19
|
+
// compiled CSS, and the value stays overridable at runtime via the CSS var.
|
|
20
|
+
@mixin _adaptive-size($property, $var-name, $type, $map, $important: false) {
|
|
21
|
+
@if not map.has-key($map, $type) {
|
|
22
|
+
@error "Type '#{$type}' not found!";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@if $important {
|
|
26
|
+
#{$property}: var(--#{$var-name}-#{$type}) !important;
|
|
27
|
+
} @else {
|
|
28
|
+
#{$property}: var(--#{$var-name}-#{$type});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// - - - - - - - - - - - - - -
|
|
33
|
+
|
|
34
|
+
// Applies dynamically-scaled responsive rounded corners based on predefined maps
|
|
35
|
+
@mixin border-radius($type) {
|
|
36
|
+
@include _adaptive-size("border-radius", "border-radius", $type, $border-radius, false);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// - - - - - - - - - - - - - -
|
|
40
|
+
|
|
41
|
+
// Configures responsive border thickness and strokes across viewport ranges
|
|
42
|
+
@mixin border-line($type) {
|
|
43
|
+
@include _adaptive-size("border-width", "border-line", $type, $border-line, false);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// - - - - - - - - - - - - - -
|
|
47
|
+
|
|
48
|
+
// Mixin for icon sizes through devices — always clamp()
|
|
49
|
+
@mixin box-size($type) {
|
|
50
|
+
@if not map.has-key($icon-size, $type) {
|
|
51
|
+
@error "Icon size '#{$type}' not found in $icon-size map!";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
width: var(--size-icon-#{$type});
|
|
55
|
+
height: var(--size-icon-#{$type});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// - - - - - - - - - - - - - -
|
|
59
|
+
|
|
60
|
+
// Mixin for padding with optional direction — references --space-* :root token
|
|
61
|
+
@mixin padding($size, $direction: null) {
|
|
62
|
+
@if not map.has-key($space, $size) {
|
|
63
|
+
@error "space size '#{$size}' not found in $space map!";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
$value: var(--space-#{$size});
|
|
67
|
+
|
|
68
|
+
@if $direction == "x" or $direction == "inline" {
|
|
69
|
+
padding-inline: $value;
|
|
70
|
+
} @else if $direction == "y" or $direction == "block" {
|
|
71
|
+
padding-block: $value;
|
|
72
|
+
} @else if $direction == null {
|
|
73
|
+
padding: $value;
|
|
74
|
+
} @else {
|
|
75
|
+
padding-#{$direction}: $value;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Mixin for margin with optional direction — references --space-* :root token
|
|
80
|
+
@mixin margin($size, $direction: null) {
|
|
81
|
+
@if not map.has-key($space, $size) {
|
|
82
|
+
@error "space size '#{$size}' not found in $space map!";
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
$value: var(--space-#{$size});
|
|
86
|
+
|
|
87
|
+
@if $direction == "x" or $direction == "inline" {
|
|
88
|
+
margin-inline: $value;
|
|
89
|
+
} @else if $direction == "y" or $direction == "block" {
|
|
90
|
+
margin-block: $value;
|
|
91
|
+
} @else if $direction == null {
|
|
92
|
+
margin: $value;
|
|
93
|
+
} @else {
|
|
94
|
+
margin-#{$direction}: $value;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Mixin for gap with optional direction — references --space-* :root token
|
|
99
|
+
@mixin gap($size, $direction: null) {
|
|
100
|
+
@if not map.has-key($space, $size) {
|
|
101
|
+
@error "space size '#{$size}' not found in $space map!";
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
$value: var(--space-#{$size});
|
|
105
|
+
|
|
106
|
+
@if $direction == "x" or $direction == "column" {
|
|
107
|
+
column-gap: $value;
|
|
108
|
+
} @else if $direction == "y" or $direction == "row" {
|
|
109
|
+
row-gap: $value;
|
|
110
|
+
} @else if $direction == null {
|
|
111
|
+
gap: $value;
|
|
112
|
+
} @else {
|
|
113
|
+
@error "gap() direction must be null, 'x', 'column', 'y', or 'row'. Got: '#{$direction}'";
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// - - - - - - - - - - - - - -
|
|
118
|
+
// DEMONSTRATION & API USAGE
|
|
119
|
+
// @include padding("md"); // all sides
|
|
120
|
+
// @include padding("md", "top"); // top only
|
|
121
|
+
// @include padding("md", "x"); // left-right
|
|
122
|
+
// @include padding("md", "y"); // top-bottom
|
|
123
|
+
// @include margin("lg"); // all sides
|
|
124
|
+
// @include margin("2xl", "bottom"); // bottom only
|
|
125
|
+
// @include gap("md"); // gap (grid & flex)
|
|
126
|
+
// @include gap("lg", "x"); // column-gap only
|
|
127
|
+
// @include gap("sm", "y"); // row-gap only
|
|
128
|
+
// - - - - - - - - - - - - - -
|
|
129
|
+
|
|
130
|
+
@mixin not-first-child() {
|
|
131
|
+
&:where(:not(:first-child)) {
|
|
132
|
+
@content;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@mixin not-last-child() {
|
|
137
|
+
&:where(:not(:last-child)) {
|
|
138
|
+
@content;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
@mixin horizontal-scroll() {
|
|
143
|
+
@media only screen {
|
|
144
|
+
overflow-x: auto;
|
|
145
|
+
white-space: nowrap;
|
|
146
|
+
width: 100%;
|
|
147
|
+
@content;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@mixin no-horizontal-scroll() {
|
|
152
|
+
overflow-x: visible;
|
|
153
|
+
white-space: normal;
|
|
154
|
+
width: auto;
|
|
155
|
+
}
|
|
156
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// ╔══════════════════════════════════════════════════════════════╗
|
|
2
|
+
// ║ ⚡ Zeus CSS — Responsive ║
|
|
3
|
+
// ║ ║
|
|
4
|
+
// ║ Framework internal engine and mixins for responsive. ║
|
|
5
|
+
// ╚══════════════════════════════════════════════════════════════╝
|
|
6
|
+
|
|
7
|
+
@use "sass:map";
|
|
8
|
+
@use "../design/layout/grid" as *;
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@function bp($key) {
|
|
12
|
+
@if not map.has-key($breakpoints, $key) {
|
|
13
|
+
@error "Breakpoint '#{$key}' not found in $breakpoints!";
|
|
14
|
+
}
|
|
15
|
+
@return map.get($breakpoints, $key);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@function _max($breakpoint) {
|
|
19
|
+
@return $breakpoint - 0.02px;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// = = = = = = = = = = = = = = = =
|
|
23
|
+
// Modern Parameter-Driven Responsive API
|
|
24
|
+
// = = = = = = = = = = = = = = = =
|
|
25
|
+
|
|
26
|
+
@mixin screen-above($breakpoint) {
|
|
27
|
+
@media screen and (min-width: #{bp($breakpoint)}) {
|
|
28
|
+
@content;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@mixin screen-below($breakpoint) {
|
|
33
|
+
@media screen and (max-width: #{_max(bp($breakpoint))}) {
|
|
34
|
+
@content;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@mixin screen-between($lower, $upper) {
|
|
39
|
+
@media screen and (min-width: #{bp($lower)}) and (max-width: #{_max(bp($upper))}) {
|
|
40
|
+
@content;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// ─── Exclusive Layout Exclusion (Hide) ─────────────────
|
|
45
|
+
// Scopes: 'handheld', 'mobile', 'tablet', 'desktop' (all singular).
|
|
46
|
+
@mixin suppress-on($scope) {
|
|
47
|
+
@if $scope == 'handheld' {
|
|
48
|
+
@media screen and (max-width: #{_max(bp(lg))}) {
|
|
49
|
+
display: none !important;
|
|
50
|
+
}
|
|
51
|
+
} @else if $scope == 'mobile' {
|
|
52
|
+
@media screen and (max-width: #{_max(bp(md))}) {
|
|
53
|
+
display: none !important;
|
|
54
|
+
}
|
|
55
|
+
} @else if $scope == 'tablet' {
|
|
56
|
+
@media screen and (min-width: #{bp(md)}) and (max-width: #{_max(bp(lg))}) {
|
|
57
|
+
display: none !important;
|
|
58
|
+
}
|
|
59
|
+
} @else if $scope == 'desktop' {
|
|
60
|
+
@media screen and (min-width: #{bp(lg)}) {
|
|
61
|
+
display: none !important;
|
|
62
|
+
}
|
|
63
|
+
} @else {
|
|
64
|
+
@error "[Zeus] suppress-on(): unknown scope '#{$scope}'. Expected 'handheld', 'mobile', 'tablet', or 'desktop'.";
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|