@semanticus/semanticus-css 0.8.0 → 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.
Files changed (166) hide show
  1. package/NOTICE +16 -16
  2. package/README.md +128 -29
  3. package/dist/semanticus-no-utilities.css +11 -0
  4. package/dist/semanticus-semantics.css +3 -4
  5. package/dist/semanticus-utilities.css +11 -0
  6. package/dist/semanticus.css +4 -12
  7. package/dist/semanticus.palette.amber.css +1 -1
  8. package/dist/semanticus.palette.azure.css +1 -0
  9. package/dist/semanticus.palette.blue.css +1 -1
  10. package/dist/semanticus.palette.cyan.css +1 -1
  11. package/dist/semanticus.palette.fuchsia.css +1 -1
  12. package/dist/semanticus.palette.green.css +1 -1
  13. package/dist/semanticus.palette.grey.css +1 -1
  14. package/dist/semanticus.palette.indigo.css +1 -1
  15. package/dist/semanticus.palette.jade.css +1 -1
  16. package/dist/semanticus.palette.lime.css +1 -1
  17. package/dist/semanticus.palette.orange.css +1 -1
  18. package/dist/semanticus.palette.pink.css +1 -1
  19. package/dist/semanticus.palette.pumpkin.css +1 -1
  20. package/dist/semanticus.palette.purple.css +1 -1
  21. package/dist/semanticus.palette.red.css +1 -1
  22. package/dist/semanticus.palette.sand.css +1 -1
  23. package/dist/semanticus.palette.slate.css +1 -1
  24. package/dist/semanticus.palette.violet.css +1 -1
  25. package/dist/semanticus.palette.yellow.css +1 -1
  26. package/dist/semanticus.palette.zinc.css +1 -1
  27. package/dist/semanticus.size.pico.css +1 -1
  28. package/package.json +28 -16
  29. package/src/components/_card.css +84 -0
  30. package/src/components/_sidebar.css +49 -0
  31. package/src/components/modules.css +2 -0
  32. package/src/index.css +8 -10
  33. package/src/no-utilities.css +22 -0
  34. package/src/palettes/amber.css +28 -53
  35. package/src/palettes/azure.css +31 -0
  36. package/src/palettes/blue.css +28 -53
  37. package/src/palettes/cyan.css +28 -53
  38. package/src/palettes/fuchsia.css +28 -53
  39. package/src/palettes/green.css +28 -53
  40. package/src/palettes/grey.css +28 -53
  41. package/src/palettes/indigo.css +28 -53
  42. package/src/palettes/jade.css +28 -53
  43. package/src/palettes/lime.css +28 -53
  44. package/src/palettes/orange.css +28 -53
  45. package/src/palettes/pink.css +28 -53
  46. package/src/palettes/pumpkin.css +28 -53
  47. package/src/palettes/purple.css +28 -53
  48. package/src/palettes/red.css +28 -53
  49. package/src/palettes/sand.css +28 -53
  50. package/src/palettes/slate.css +28 -53
  51. package/src/palettes/violet.css +28 -53
  52. package/src/palettes/yellow.css +28 -53
  53. package/src/palettes/zinc.css +28 -53
  54. package/src/semantics/{_aria-busy.css → attributes/_aria-busy.css} +0 -3
  55. package/src/semantics/{_hidden.css → attributes/_hidden.css} +0 -3
  56. package/src/semantics/attributes/_popover.css +13 -0
  57. package/src/semantics/attributes/_role-group-search.css +137 -0
  58. package/src/semantics/{_role-toolbar.css → attributes/_role-toolbar.css} +2 -5
  59. package/src/semantics/{_role-tooltip.css → attributes/_role-tooltip.css} +6 -9
  60. package/src/semantics/elements/_abbr.css +5 -0
  61. package/src/semantics/elements/_address.css +7 -0
  62. package/src/semantics/elements/_article.css +3 -0
  63. package/src/semantics/elements/_aside.css +10 -0
  64. package/src/semantics/elements/_blockquote.css +18 -0
  65. package/src/semantics/elements/_body.css +5 -0
  66. package/src/semantics/{_button.css → elements/_button.css} +23 -26
  67. package/src/semantics/{_code.css → elements/_code.css} +11 -11
  68. package/src/semantics/elements/_del.css +3 -0
  69. package/src/semantics/{_details.css → elements/_details.css} +42 -43
  70. package/src/semantics/elements/_dialog.css +113 -0
  71. package/src/semantics/{_document.css → elements/_document.css} +10 -4
  72. package/src/semantics/{_embedded.css → elements/_embedded.css} +0 -3
  73. package/src/semantics/{_figure.css → elements/_figure.css} +0 -3
  74. package/src/semantics/elements/_footer.css +10 -0
  75. package/src/semantics/elements/_header.css +10 -0
  76. package/src/semantics/elements/_headings.css +24 -0
  77. package/src/semantics/elements/_hgroup.css +14 -0
  78. package/src/semantics/{_hr.css → elements/_hr.css} +1 -4
  79. package/src/semantics/{_input.css → elements/_input.css} +34 -38
  80. package/src/semantics/elements/_ins.css +4 -0
  81. package/src/semantics/elements/_links.css +61 -0
  82. package/src/semantics/elements/_lists.css +22 -0
  83. package/src/semantics/elements/_main.css +3 -0
  84. package/src/semantics/elements/_mark.css +6 -0
  85. package/src/semantics/{_nav.css → elements/_nav.css} +5 -8
  86. package/src/semantics/elements/_p.css +11 -0
  87. package/src/semantics/{_progress.css → elements/_progress.css} +5 -8
  88. package/src/semantics/elements/_section.css +4 -0
  89. package/src/semantics/elements/_small.css +3 -0
  90. package/src/semantics/elements/_strong.css +4 -0
  91. package/src/semantics/elements/_sub.css +7 -0
  92. package/src/semantics/elements/_sup.css +7 -0
  93. package/src/semantics/{_table.css → elements/_table.css} +10 -7
  94. package/src/semantics/{_type-checkbox-radio.css → elements/_type-checkbox-radio.css} +19 -22
  95. package/src/semantics/{_type-color.css → elements/_type-color.css} +2 -5
  96. package/src/semantics/{_type-date.css → elements/_type-date.css} +1 -4
  97. package/src/semantics/elements/_type-file.css +23 -0
  98. package/src/semantics/{_type-range.css → elements/_type-range.css} +11 -14
  99. package/src/semantics/elements/_type-search.css +30 -0
  100. package/src/semantics/index.css +2 -5
  101. package/src/semantics/modules.css +46 -37
  102. package/src/sizes/pico.css +21 -29
  103. package/src/utilities/_grid.css +306 -0
  104. package/src/utilities/_variables.css +27 -42
  105. package/src/utilities/borders/_border-radius.css +54 -79
  106. package/src/utilities/borders/_border-style.css +15 -5
  107. package/src/utilities/borders/_border-width.css +0 -28
  108. package/src/utilities/colors/_bg-colors.css +75 -0
  109. package/src/utilities/colors/_border-colors.css +17 -39
  110. package/src/utilities/colors/_subtle-colors.css +145 -0
  111. package/src/utilities/colors/_text-bg-colors.css +62 -0
  112. package/src/utilities/colors/_text-colors.css +32 -409
  113. package/src/utilities/effects/_focus-ring.css +33 -0
  114. package/src/utilities/effects/_shadows.css +0 -33
  115. package/src/utilities/index.css +16 -0
  116. package/src/utilities/layout/_misc.css +2 -5
  117. package/src/utilities/layout/{_grid.css → _ratio.css} +0 -19
  118. package/src/utilities/modules.css +9 -3
  119. package/src/utilities/sizing/_width.css +8 -0
  120. package/src/utilities/spacing/_gap.css +144 -144
  121. package/src/utilities/spacing/_margin.css +324 -324
  122. package/src/utilities/spacing/_padding.css +324 -324
  123. package/src/utilities/typography/_font-sizes.css +6 -6
  124. package/src/variables/_all.css +2 -20
  125. package/src/variables/_elements.css +29 -33
  126. package/src/variables/_theme.css +336 -0
  127. package/src/variants/_variables.css +24 -0
  128. package/src/variants/intent/_contrast.css +46 -0
  129. package/src/variants/intent/_danger.css +38 -0
  130. package/src/variants/intent/_info.css +38 -0
  131. package/src/variants/intent/_primary.css +38 -0
  132. package/src/variants/intent/_secondary.css +38 -0
  133. package/src/variants/intent/_success.css +38 -0
  134. package/src/variants/intent/_warning.css +38 -0
  135. package/src/variants/{_container.css → modifiers/_container.css} +3 -10
  136. package/src/variants/modifiers/_ghost.css +164 -0
  137. package/src/variants/modifiers/_striped.css +11 -0
  138. package/src/variants/modifiers/_subtle.css +133 -0
  139. package/src/variants/modules.css +12 -15
  140. package/src/_normalize.css +0 -214
  141. package/src/semantics/_article.css +0 -12
  142. package/src/semantics/_aside.css +0 -16
  143. package/src/semantics/_body.css +0 -8
  144. package/src/semantics/_dialog.css +0 -157
  145. package/src/semantics/_footer.css +0 -12
  146. package/src/semantics/_header.css +0 -12
  147. package/src/semantics/_links.css +0 -50
  148. package/src/semantics/_main.css +0 -10
  149. package/src/semantics/_role-group-search.css +0 -129
  150. package/src/semantics/_section.css +0 -9
  151. package/src/semantics/_type-file.css +0 -26
  152. package/src/semantics/_type-search.css +0 -34
  153. package/src/semantics/_typography.css +0 -146
  154. package/src/utilities/colors/_background-colors.css +0 -248
  155. package/src/variables/_colors.css +0 -366
  156. package/src/variables/_components.css +0 -318
  157. package/src/variables/_icons.css +0 -43
  158. package/src/variables/_layout.css +0 -128
  159. package/src/variants/_card.css +0 -45
  160. package/src/variants/_contained.css +0 -43
  161. package/src/variants/_contrast.css +0 -47
  162. package/src/variants/_ghost.css +0 -61
  163. package/src/variants/_panel.css +0 -18
  164. package/src/variants/_secondary.css +0 -35
  165. package/src/variants/_sidebar.css +0 -11
  166. package/src/variants/_striped.css +0 -10
@@ -1,6 +1,3 @@
1
- /**
2
- * Input type range
3
- */
4
1
  [type=range] {
5
2
  -webkit-appearance: none;
6
3
  -moz-appearance: none;
@@ -12,24 +9,24 @@
12
9
  &::-webkit-slider-runnable-track {
13
10
  width: 100%;
14
11
  height: 0.375rem;
15
- border-radius: var(--border-radius);
16
- background-color: var(--range-border-color);
12
+ border-radius: var(--radius);
13
+ background-color: var(--range-track-border);
17
14
  transition: background-color var(--transition), box-shadow var(--transition);
18
15
  }
19
16
 
20
17
  &::-moz-range-track {
21
18
  width: 100%;
22
19
  height: 0.375rem;
23
- border-radius: var(--border-radius);
24
- background-color: var(--range-border-color);
20
+ border-radius: var(--radius);
21
+ background-color: var(--range-track-border);
25
22
  transition: background-color var(--transition), box-shadow var(--transition);
26
23
  }
27
24
 
28
25
  &::-ms-track {
29
26
  width: 100%;
30
27
  height: 0.375rem;
31
- border-radius: var(--border-radius);
32
- background-color: var(--range-border-color);
28
+ border-radius: var(--radius);
29
+ background-color: var(--range-track-border);
33
30
  transition: background-color var(--transition), box-shadow var(--transition);
34
31
  }
35
32
 
@@ -40,7 +37,7 @@
40
37
  margin-top: -0.4375rem;
41
38
  border: 2px solid var(--range-thumb-border);
42
39
  border-radius: 50%;
43
- background-color: var(--range-thumb-color);
40
+ background-color: var(--range-thumb-fill);
44
41
  cursor: pointer;
45
42
  transition: background-color var(--transition), transform var(--transition);
46
43
  }
@@ -52,7 +49,7 @@
52
49
  margin-top: -0.4375rem;
53
50
  border: 2px solid var(--range-thumb-border);
54
51
  border-radius: 50%;
55
- background-color: var(--range-thumb-color);
52
+ background-color: var(--range-thumb-fill);
56
53
  cursor: pointer;
57
54
  transition: background-color var(--transition), transform var(--transition);
58
55
  }
@@ -64,14 +61,14 @@
64
61
  margin-top: -0.4375rem;
65
62
  border: 2px solid var(--range-thumb-border);
66
63
  border-radius: 50%;
67
- background-color: var(--range-thumb-color);
64
+ background-color: var(--range-thumb-fill);
68
65
  cursor: pointer;
69
66
  transition: background-color var(--transition), transform var(--transition);
70
67
  }
71
68
 
72
69
  &:active, &:focus-within {
73
- --range-border-color: var(--range-active-border);
74
- --range-thumb-color: var(--range-thumb-active);
70
+ --range-track-border: var(--range-track-border-active);
71
+ --range-thumb-fill: var(--range-thumb-fill-active);
75
72
  }
76
73
 
77
74
  &:active {
@@ -0,0 +1,30 @@
1
+ input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search] {
2
+ padding-inline-start: calc(var(--input-spacing-horizontal) + 1.75rem);
3
+ background-image: var(--icon-search);
4
+ background-position: left calc(var(--input-spacing-horizontal) + 0.125rem) center;
5
+ background-size: 1rem auto;
6
+ background-repeat: no-repeat;
7
+
8
+ &[aria-invalid] {
9
+ padding-inline-start: calc(var(--input-spacing-horizontal) + 1.75rem);
10
+ /* Using calc with var to workaround LightningCSS minification bug with 3-value syntax */
11
+ background-position: left calc(var(--input-spacing-horizontal) * 0 + 1.125rem) center, right calc(var(--input-spacing-horizontal) * 0 + 0.75rem) center;
12
+ }
13
+
14
+ &[aria-invalid=false] {
15
+ background-image: var(--icon-search), var(--icon-valid);
16
+ }
17
+
18
+ &[aria-invalid=true] {
19
+ background-image: var(--icon-search), var(--icon-invalid);
20
+ }
21
+ }
22
+
23
+ [dir=rtl] input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search] {
24
+ background-position: right calc(var(--input-spacing-horizontal) * 0 + 1.125rem) center;
25
+
26
+ &[aria-invalid] {
27
+ /* Using calc with var to workaround LightningCSS minification bug with 3-value syntax */
28
+ background-position: right calc(var(--input-spacing-horizontal) * 0 + 1.125rem) center, left calc(var(--input-spacing-horizontal) * 0 + 0.75rem) center;
29
+ }
30
+ }
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * Semantic-first HTML styling (no variants or utility classes)
5
5
  *
6
- * Adapted from Pico CSS (https://picocss.com)
7
- * Original work: Copyright (c) 2019-2024 Pico CSS
6
+ * Original works: see https://github.com/semanticus/semanticus-css/blob/main/NOTICE for copyright and license details
7
+ *
8
8
  * Modifications: Copyright (c) 2026 Joao Goncalves
9
9
  * Licensed under MIT (https://github.com/semanticus/semanticus-css/blob/main/LICENSE)
10
10
  */
@@ -12,8 +12,5 @@
12
12
  /* Variables */
13
13
  @import '../variables/_all.css';
14
14
 
15
- /* Normalize */
16
- @import '../_normalize.css';
17
-
18
15
  /* Semantic Components */
19
16
  @import "./modules.css";
@@ -1,38 +1,47 @@
1
- /**
2
- * Semanticus CSS Semantics Modules
3
- * Just the semantic component styles (no variables, no normalize)
4
- * Used by the full version which imports variables/normalize separately
5
- */
1
+ @import "./attributes/_aria-busy.css";
2
+ @import "./attributes/_hidden.css";
3
+ @import "./attributes/_popover.css";
4
+ @import "./attributes/_role-group-search.css";
5
+ @import "./attributes/_role-toolbar.css";
6
+ @import "./attributes/_role-tooltip.css";
6
7
 
7
- @import "./_aria-busy.css";
8
- @import "./_article.css";
9
- @import "./_aside.css";
10
- @import "./_body.css";
11
- @import "./_button.css";
12
- @import "./_code.css";
13
- @import "./_details.css";
14
- @import "./_dialog.css";
15
- @import "./_document.css";
16
- @import "./_embedded.css";
17
- @import "./_figure.css";
18
- @import "./_footer.css";
19
- @import "./_header.css";
20
- @import "./_hidden.css";
21
- @import "./_hr.css";
22
- @import "./_input.css";
23
- @import "./_links.css";
24
- @import "./_main.css";
25
- @import "./_nav.css";
26
- @import "./_progress.css";
27
- @import "./_role-group-search.css";
28
- @import "./_role-toolbar.css";
29
- @import "./_role-tooltip.css";
30
- @import "./_section.css";
31
- @import "./_table.css";
32
- @import "./_type-checkbox-radio.css";
33
- @import "./_type-color.css";
34
- @import "./_type-date.css";
35
- @import "./_type-file.css";
36
- @import "./_type-range.css";
37
- @import "./_type-search.css";
38
- @import "./_typography.css";
8
+ @import "./elements/_abbr.css";
9
+ @import "./elements/_address.css";
10
+ @import "./elements/_article.css";
11
+ @import "./elements/_aside.css";
12
+ @import "./elements/_blockquote.css";
13
+ @import "./elements/_body.css";
14
+ @import "./elements/_button.css";
15
+ @import "./elements/_code.css";
16
+ @import "./elements/_del.css";
17
+ @import "./elements/_details.css";
18
+ @import "./elements/_dialog.css";
19
+ @import "./elements/_document.css";
20
+ @import "./elements/_embedded.css";
21
+ @import "./elements/_figure.css";
22
+ @import "./elements/_footer.css";
23
+ @import "./elements/_header.css";
24
+ @import "./elements/_headings.css";
25
+ @import "./elements/_hgroup.css";
26
+ @import "./elements/_hr.css";
27
+ @import "./elements/_input.css";
28
+ @import "./elements/_ins.css";
29
+ @import "./elements/_links.css";
30
+ @import "./elements/_lists.css";
31
+ @import "./elements/_main.css";
32
+ @import "./elements/_mark.css";
33
+ @import "./elements/_nav.css";
34
+ @import "./elements/_p.css";
35
+ @import "./elements/_progress.css";
36
+ @import "./elements/_section.css";
37
+ @import "./elements/_small.css";
38
+ @import "./elements/_strong.css";
39
+ @import "./elements/_sub.css";
40
+ @import "./elements/_sup.css";
41
+ @import "./elements/_table.css";
42
+ @import "./elements/_type-checkbox-radio.css";
43
+ @import "./elements/_type-color.css";
44
+ @import "./elements/_type-date.css";
45
+ @import "./elements/_type-file.css";
46
+ @import "./elements/_type-range.css";
47
+ @import "./elements/_type-search.css";
@@ -16,36 +16,28 @@
16
16
  --text-underline-offset: 0.1rem;
17
17
 
18
18
  /* Borders & Effects – global defaults for border-radius, border-width, outline, and transition */
19
- --border-radius: 0.25rem;
20
- --border-width: 0.0625rem; /* 1px – base border width used by forms, tables, etc. */
21
- --outline-width: 0.125rem; /* 2px – focus-ring width */
19
+ --radius: 0.25rem;
20
+ --border-size: 0.0625rem; /* 1px – base border width used by forms, tables, etc. */
21
+ --outline-size: 0.125rem; /* 2px – focus-ring width */
22
22
  --transition: 0.2s ease-in-out; /* Default transition timing for interactive state changes */
23
23
 
24
24
  /* Spacing – shared base unit used for padding, margins, and gaps throughout the layout */
25
- --spacing: 1rem;
26
- --responsive-multiplier: 1; /* Multiplier applied to spacing for responsive adjustments at wider breakpoints */
25
+ --base-spacing: 1rem;
26
+ --spacing: var(--base-spacing);
27
27
  --typography-spacing-vertical: 1rem; /* Vertical margin below typographic elements (p, lists, etc.) */
28
- --block-spacing-vertical: var(--spacing); /* Vertical padding inside block-level components (cards, modals, etc.) */
29
- --block-spacing-horizontal: var(--spacing); /* Horizontal padding inside block-level components */
30
- --grid-column-gap: var(--spacing); /* Column gap in CSS Grid layouts */
31
- --grid-row-gap: var(--spacing); /* Row gap in CSS Grid layouts */
32
- --form-element-spacing-vertical: 0.75rem; /* Vertical padding inside form inputs, selects, and textareas */
33
- --form-element-spacing-horizontal: 1rem; /* Horizontal padding inside form inputs, selects, and textareas */
28
+ --input-spacing-vertical: 0.75rem; /* Vertical padding inside form inputs, selects, and textareas */
29
+ --input-spacing-horizontal: 1rem; /* Horizontal padding inside form inputs, selects, and textareas */
34
30
 
35
31
  /* Shadows – used by [role="group"] and [role="search"] button/input combos */
36
32
  --group-shadow: 0 0 0 rgba(0, 0, 0, 0); /* Default (no shadow) */
37
- --group-shadow-focus-with-button: 0 0 0 var(--outline-width) var(--color-primary-focus); /* Focus ring when a button inside the group is focused */
38
- --group-shadow-focus-with-input: 0 0 0 0.0625rem var(--form-border-color); /* Focus ring when an input inside the group is focused */
39
-
40
- /* Modal – backdrop overlay settings */
41
- --modal-overlay-backdrop-filter: blur(0.375rem); /* Applies a blur behind the modal overlay */
33
+ --group-shadow-focus-button: 0 0 0 var(--outline-size) var(--color-primary-focus-ring); /* Focus ring when a button inside the group is focused */
34
+ --group-shadow-focus-input: 0 0 0 0.0625rem var(--input-border); /* Focus ring when an input inside the group is focused */
42
35
 
43
36
  /* Navigation – spacing and breadcrumb configuration */
44
- --nav-link-spacing-vertical: 0.5rem; /* Vertical padding inside nav links */
45
- --nav-link-spacing-horizontal: 0.5rem; /* Horizontal padding inside nav links */
37
+ --nav-link-gap: calc(var(--spacing) * 0.5); /* padding inside nav links */
46
38
  --nav-breadcrumb-divider: ">"; /* Character displayed between breadcrumb items */
47
39
 
48
- --sidebar-width: 25%; /* Sidebar width */
40
+ --sidebar-size: 25%; /* Sidebar width */
49
41
  }
50
42
 
51
43
  /* Responsive Font Sizes – progressively increase root font-size at wider viewports */
@@ -53,8 +45,8 @@
53
45
  :root,
54
46
  :host {
55
47
  --font-size: 106.25%;
56
- --sidebar-width: max(25%, 150px);
57
- --responsive-multiplier: 1.25;
48
+ --sidebar-size: max(25%, 150px);
49
+ --spacing: calc(var(--base-spacing) * 1.25);
58
50
  }
59
51
  }
60
52
 
@@ -62,8 +54,8 @@
62
54
  :root,
63
55
  :host {
64
56
  --font-size: 112.5%;
65
- --sidebar-width: max(22%, 180px);
66
- --responsive-multiplier: 1.5;
57
+ --sidebar-size: max(22%, 180px);
58
+ --spacing: calc(var(--base-spacing) * 1.5);
67
59
  }
68
60
  }
69
61
 
@@ -71,8 +63,8 @@
71
63
  :root,
72
64
  :host {
73
65
  --font-size: 118.75%;
74
- --sidebar-width: max(20%, 200px);
75
- --responsive-multiplier: 1.75;
66
+ --sidebar-size: max(20%, 200px);
67
+ --spacing: calc(var(--base-spacing) * 1.75);
76
68
  }
77
69
  }
78
70
 
@@ -80,8 +72,8 @@
80
72
  :root,
81
73
  :host {
82
74
  --font-size: 125%;
83
- --sidebar-width: max(18%, 220px);
84
- --responsive-multiplier: 2;
75
+ --sidebar-size: max(18%, 220px);
76
+ --spacing: calc(var(--base-spacing) * 2);
85
77
  }
86
78
  }
87
79
 
@@ -89,7 +81,7 @@
89
81
  :root,
90
82
  :host {
91
83
  --font-size: 131.25%;
92
- --sidebar-width: clamp(240px, 16%, 300px);
93
- --responsive-multiplier: 2.25;
84
+ --sidebar-size: clamp(240px, 16%, 300px);
85
+ --spacing: calc(var(--base-spacing) * 2.25);
94
86
  }
95
87
  }
@@ -0,0 +1,306 @@
1
+ /* ======================================================================
2
+ Responsive 12-Column Grid
3
+ -----------------------------------------------------------------------
4
+ Implemented with CSS Flexbox and logical properties.
5
+ Mobile-first: all columns default to full width; size modifiers
6
+ override at their breakpoint. Gutter controlled via --grid-gutter-x.
7
+
8
+ Breakpoints (inherit from src/variables/_breakpoints.css):
9
+ (default) — all widths (no media query)
10
+ sm — min-width: 576px
11
+ md — min-width: 768px
12
+ lg — min-width: 1024px
13
+
14
+ Alignment, ordering, and reversing use existing flexbox utilities:
15
+ .justify-content-* horizontal alignment on .row
16
+ .align-items-* vertical alignment on .row
17
+ .order-first / .order-last column ordering
18
+ .flex-row-reverse reverse column order on .row
19
+ ====================================================================== */
20
+
21
+ /* --- Row -------------------------------------------------------------- */
22
+
23
+ .row {
24
+ display: flex;
25
+ flex-wrap: wrap;
26
+ margin-inline: calc(var(--grid-gutter-x) / -2);
27
+ row-gap: var(--grid-gutter-y);
28
+ }
29
+
30
+ /* --- Column base ------------------------------------------------------ */
31
+ /*
32
+ * All col-* elements default to full width (mobile-first stacking).
33
+ * Responsive size classes and explicit col-N classes override this.
34
+ */
35
+
36
+ [class*="col-"],
37
+ .col {
38
+ box-sizing: border-box;
39
+ flex: 0 0 100%;
40
+ max-width: 100%;
41
+ min-width: 0;
42
+ padding-inline: calc(var(--grid-gutter-x) / 2);
43
+ }
44
+
45
+ /* ======================================================================
46
+ Default — all screen sizes (no media query)
47
+ ====================================================================== */
48
+
49
+ /* Auto-width: equal share of remaining row space */
50
+ .col {
51
+ flex: 1 1 0;
52
+ }
53
+
54
+ /* Fixed-width columns 1–12 */
55
+ .col-1 { flex: 0 0 calc( 1 / 12 * 100%); max-width: calc( 1 / 12 * 100%); }
56
+ .col-2 { flex: 0 0 calc( 2 / 12 * 100%); max-width: calc( 2 / 12 * 100%); }
57
+ .col-3 { flex: 0 0 calc( 3 / 12 * 100%); max-width: calc( 3 / 12 * 100%); }
58
+ .col-4 { flex: 0 0 calc( 4 / 12 * 100%); max-width: calc( 4 / 12 * 100%); }
59
+ .col-5 { flex: 0 0 calc( 5 / 12 * 100%); max-width: calc( 5 / 12 * 100%); }
60
+ .col-6 { flex: 0 0 calc( 6 / 12 * 100%); max-width: calc( 6 / 12 * 100%); }
61
+ .col-7 { flex: 0 0 calc( 7 / 12 * 100%); max-width: calc( 7 / 12 * 100%); }
62
+ .col-8 { flex: 0 0 calc( 8 / 12 * 100%); max-width: calc( 8 / 12 * 100%); }
63
+ .col-9 { flex: 0 0 calc( 9 / 12 * 100%); max-width: calc( 9 / 12 * 100%); }
64
+ .col-10 { flex: 0 0 calc(10 / 12 * 100%); max-width: calc(10 / 12 * 100%); }
65
+ .col-11 { flex: 0 0 calc(11 / 12 * 100%); max-width: calc(11 / 12 * 100%); }
66
+ .col-12 { flex: 0 0 100%; max-width: 100%; }
67
+
68
+ /* Offsets */
69
+ .col-offset-0 { margin-inline-start: 0; }
70
+ .col-offset-1 { margin-inline-start: calc( 1 / 12 * 100%); }
71
+ .col-offset-2 { margin-inline-start: calc( 2 / 12 * 100%); }
72
+ .col-offset-3 { margin-inline-start: calc( 3 / 12 * 100%); }
73
+ .col-offset-4 { margin-inline-start: calc( 4 / 12 * 100%); }
74
+ .col-offset-5 { margin-inline-start: calc( 5 / 12 * 100%); }
75
+ .col-offset-6 { margin-inline-start: calc( 6 / 12 * 100%); }
76
+ .col-offset-7 { margin-inline-start: calc( 7 / 12 * 100%); }
77
+ .col-offset-8 { margin-inline-start: calc( 8 / 12 * 100%); }
78
+ .col-offset-9 { margin-inline-start: calc( 9 / 12 * 100%); }
79
+ .col-offset-10 { margin-inline-start: calc(10 / 12 * 100%); }
80
+ .col-offset-11 { margin-inline-start: calc(11 / 12 * 100%); }
81
+
82
+ /* ======================================================================
83
+ sm — min-width: 576px
84
+ ====================================================================== */
85
+
86
+ @media (--breakpoint-sm) {
87
+ .col-sm {
88
+ flex: 1 1 0;
89
+ max-width: 100%;
90
+ }
91
+
92
+ .col-sm-1 { flex: 0 0 calc( 1 / 12 * 100%); max-width: calc( 1 / 12 * 100%); }
93
+ .col-sm-2 { flex: 0 0 calc( 2 / 12 * 100%); max-width: calc( 2 / 12 * 100%); }
94
+ .col-sm-3 { flex: 0 0 calc( 3 / 12 * 100%); max-width: calc( 3 / 12 * 100%); }
95
+ .col-sm-4 { flex: 0 0 calc( 4 / 12 * 100%); max-width: calc( 4 / 12 * 100%); }
96
+ .col-sm-5 { flex: 0 0 calc( 5 / 12 * 100%); max-width: calc( 5 / 12 * 100%); }
97
+ .col-sm-6 { flex: 0 0 calc( 6 / 12 * 100%); max-width: calc( 6 / 12 * 100%); }
98
+ .col-sm-7 { flex: 0 0 calc( 7 / 12 * 100%); max-width: calc( 7 / 12 * 100%); }
99
+ .col-sm-8 { flex: 0 0 calc( 8 / 12 * 100%); max-width: calc( 8 / 12 * 100%); }
100
+ .col-sm-9 { flex: 0 0 calc( 9 / 12 * 100%); max-width: calc( 9 / 12 * 100%); }
101
+ .col-sm-10 { flex: 0 0 calc(10 / 12 * 100%); max-width: calc(10 / 12 * 100%); }
102
+ .col-sm-11 { flex: 0 0 calc(11 / 12 * 100%); max-width: calc(11 / 12 * 100%); }
103
+ .col-sm-12 { flex: 0 0 100%; max-width: 100%; }
104
+
105
+ .col-offset-sm-0 { margin-inline-start: 0; }
106
+ .col-offset-sm-1 { margin-inline-start: calc( 1 / 12 * 100%); }
107
+ .col-offset-sm-2 { margin-inline-start: calc( 2 / 12 * 100%); }
108
+ .col-offset-sm-3 { margin-inline-start: calc( 3 / 12 * 100%); }
109
+ .col-offset-sm-4 { margin-inline-start: calc( 4 / 12 * 100%); }
110
+ .col-offset-sm-5 { margin-inline-start: calc( 5 / 12 * 100%); }
111
+ .col-offset-sm-6 { margin-inline-start: calc( 6 / 12 * 100%); }
112
+ .col-offset-sm-7 { margin-inline-start: calc( 7 / 12 * 100%); }
113
+ .col-offset-sm-8 { margin-inline-start: calc( 8 / 12 * 100%); }
114
+ .col-offset-sm-9 { margin-inline-start: calc( 9 / 12 * 100%); }
115
+ .col-offset-sm-10 { margin-inline-start: calc(10 / 12 * 100%); }
116
+ .col-offset-sm-11 { margin-inline-start: calc(11 / 12 * 100%); }
117
+ }
118
+
119
+ /* ======================================================================
120
+ md — min-width: 768px
121
+ ====================================================================== */
122
+
123
+ @media (--breakpoint-md) {
124
+ .col-md {
125
+ flex: 1 1 0;
126
+ max-width: 100%;
127
+ }
128
+
129
+ .col-md-1 { flex: 0 0 calc( 1 / 12 * 100%); max-width: calc( 1 / 12 * 100%); }
130
+ .col-md-2 { flex: 0 0 calc( 2 / 12 * 100%); max-width: calc( 2 / 12 * 100%); }
131
+ .col-md-3 { flex: 0 0 calc( 3 / 12 * 100%); max-width: calc( 3 / 12 * 100%); }
132
+ .col-md-4 { flex: 0 0 calc( 4 / 12 * 100%); max-width: calc( 4 / 12 * 100%); }
133
+ .col-md-5 { flex: 0 0 calc( 5 / 12 * 100%); max-width: calc( 5 / 12 * 100%); }
134
+ .col-md-6 { flex: 0 0 calc( 6 / 12 * 100%); max-width: calc( 6 / 12 * 100%); }
135
+ .col-md-7 { flex: 0 0 calc( 7 / 12 * 100%); max-width: calc( 7 / 12 * 100%); }
136
+ .col-md-8 { flex: 0 0 calc( 8 / 12 * 100%); max-width: calc( 8 / 12 * 100%); }
137
+ .col-md-9 { flex: 0 0 calc( 9 / 12 * 100%); max-width: calc( 9 / 12 * 100%); }
138
+ .col-md-10 { flex: 0 0 calc(10 / 12 * 100%); max-width: calc(10 / 12 * 100%); }
139
+ .col-md-11 { flex: 0 0 calc(11 / 12 * 100%); max-width: calc(11 / 12 * 100%); }
140
+ .col-md-12 { flex: 0 0 100%; max-width: 100%; }
141
+
142
+ .col-offset-md-0 { margin-inline-start: 0; }
143
+ .col-offset-md-1 { margin-inline-start: calc( 1 / 12 * 100%); }
144
+ .col-offset-md-2 { margin-inline-start: calc( 2 / 12 * 100%); }
145
+ .col-offset-md-3 { margin-inline-start: calc( 3 / 12 * 100%); }
146
+ .col-offset-md-4 { margin-inline-start: calc( 4 / 12 * 100%); }
147
+ .col-offset-md-5 { margin-inline-start: calc( 5 / 12 * 100%); }
148
+ .col-offset-md-6 { margin-inline-start: calc( 6 / 12 * 100%); }
149
+ .col-offset-md-7 { margin-inline-start: calc( 7 / 12 * 100%); }
150
+ .col-offset-md-8 { margin-inline-start: calc( 8 / 12 * 100%); }
151
+ .col-offset-md-9 { margin-inline-start: calc( 9 / 12 * 100%); }
152
+ .col-offset-md-10 { margin-inline-start: calc(10 / 12 * 100%); }
153
+ .col-offset-md-11 { margin-inline-start: calc(11 / 12 * 100%); }
154
+ }
155
+
156
+ /* ======================================================================
157
+ lg — min-width: 1024px
158
+ ====================================================================== */
159
+
160
+ @media (--breakpoint-lg) {
161
+ .col-lg {
162
+ flex: 1 1 0;
163
+ max-width: 100%;
164
+ }
165
+
166
+ .col-lg-1 { flex: 0 0 calc( 1 / 12 * 100%); max-width: calc( 1 / 12 * 100%); }
167
+ .col-lg-2 { flex: 0 0 calc( 2 / 12 * 100%); max-width: calc( 2 / 12 * 100%); }
168
+ .col-lg-3 { flex: 0 0 calc( 3 / 12 * 100%); max-width: calc( 3 / 12 * 100%); }
169
+ .col-lg-4 { flex: 0 0 calc( 4 / 12 * 100%); max-width: calc( 4 / 12 * 100%); }
170
+ .col-lg-5 { flex: 0 0 calc( 5 / 12 * 100%); max-width: calc( 5 / 12 * 100%); }
171
+ .col-lg-6 { flex: 0 0 calc( 6 / 12 * 100%); max-width: calc( 6 / 12 * 100%); }
172
+ .col-lg-7 { flex: 0 0 calc( 7 / 12 * 100%); max-width: calc( 7 / 12 * 100%); }
173
+ .col-lg-8 { flex: 0 0 calc( 8 / 12 * 100%); max-width: calc( 8 / 12 * 100%); }
174
+ .col-lg-9 { flex: 0 0 calc( 9 / 12 * 100%); max-width: calc( 9 / 12 * 100%); }
175
+ .col-lg-10 { flex: 0 0 calc(10 / 12 * 100%); max-width: calc(10 / 12 * 100%); }
176
+ .col-lg-11 { flex: 0 0 calc(11 / 12 * 100%); max-width: calc(11 / 12 * 100%); }
177
+ .col-lg-12 { flex: 0 0 100%; max-width: 100%; }
178
+
179
+ .col-offset-lg-0 { margin-inline-start: 0; }
180
+ .col-offset-lg-1 { margin-inline-start: calc( 1 / 12 * 100%); }
181
+ .col-offset-lg-2 { margin-inline-start: calc( 2 / 12 * 100%); }
182
+ .col-offset-lg-3 { margin-inline-start: calc( 3 / 12 * 100%); }
183
+ .col-offset-lg-4 { margin-inline-start: calc( 4 / 12 * 100%); }
184
+ .col-offset-lg-5 { margin-inline-start: calc( 5 / 12 * 100%); }
185
+ .col-offset-lg-6 { margin-inline-start: calc( 6 / 12 * 100%); }
186
+ .col-offset-lg-7 { margin-inline-start: calc( 7 / 12 * 100%); }
187
+ .col-offset-lg-8 { margin-inline-start: calc( 8 / 12 * 100%); }
188
+ .col-offset-lg-9 { margin-inline-start: calc( 9 / 12 * 100%); }
189
+ .col-offset-lg-10 { margin-inline-start: calc(10 / 12 * 100%); }
190
+ .col-offset-lg-11 { margin-inline-start: calc(11 / 12 * 100%); }
191
+ }
192
+
193
+ /* ======================================================================
194
+ Gutter classes — control --grid-gutter-x (horizontal) and/or
195
+ --grid-gutter-y (vertical) on a .row.
196
+
197
+ .g-* — both axes
198
+ .gx-* — horizontal axis only
199
+ .gy-* — vertical axis only
200
+
201
+ Scale mirrors the spacing scale (0–5):
202
+ 0 → 0
203
+ 1 → --spacing-1 (× 0.25)
204
+ 2 → --spacing-2 (× 0.5)
205
+ 3 → --spacing-3 (× 1, default horizontal gutter)
206
+ 4 → --spacing-4 (× 1.5)
207
+ 5 → --spacing-5 (× 3)
208
+ ====================================================================== */
209
+
210
+ /* --- Default (all sizes) ---------------------------------------------- */
211
+
212
+ .g-0 { --grid-gutter-x: 0; --grid-gutter-y: 0; }
213
+ .g-1 { --grid-gutter-x: var(--spacing-1); --grid-gutter-y: var(--spacing-1); }
214
+ .g-2 { --grid-gutter-x: var(--spacing-2); --grid-gutter-y: var(--spacing-2); }
215
+ .g-3 { --grid-gutter-x: var(--spacing-3); --grid-gutter-y: var(--spacing-3); }
216
+ .g-4 { --grid-gutter-x: var(--spacing-4); --grid-gutter-y: var(--spacing-4); }
217
+ .g-5 { --grid-gutter-x: var(--spacing-5); --grid-gutter-y: var(--spacing-5); }
218
+
219
+ .gx-0 { --grid-gutter-x: 0; }
220
+ .gx-1 { --grid-gutter-x: var(--spacing-1); }
221
+ .gx-2 { --grid-gutter-x: var(--spacing-2); }
222
+ .gx-3 { --grid-gutter-x: var(--spacing-3); }
223
+ .gx-4 { --grid-gutter-x: var(--spacing-4); }
224
+ .gx-5 { --grid-gutter-x: var(--spacing-5); }
225
+
226
+ .gy-0 { --grid-gutter-y: 0; }
227
+ .gy-1 { --grid-gutter-y: var(--spacing-1); }
228
+ .gy-2 { --grid-gutter-y: var(--spacing-2); }
229
+ .gy-3 { --grid-gutter-y: var(--spacing-3); }
230
+ .gy-4 { --grid-gutter-y: var(--spacing-4); }
231
+ .gy-5 { --grid-gutter-y: var(--spacing-5); }
232
+
233
+ /* --- sm — min-width: 576px -------------------------------------------- */
234
+
235
+ @media (--breakpoint-sm) {
236
+ .g-sm-0 { --grid-gutter-x: 0; --grid-gutter-y: 0; }
237
+ .g-sm-1 { --grid-gutter-x: var(--spacing-1); --grid-gutter-y: var(--spacing-1); }
238
+ .g-sm-2 { --grid-gutter-x: var(--spacing-2); --grid-gutter-y: var(--spacing-2); }
239
+ .g-sm-3 { --grid-gutter-x: var(--spacing-3); --grid-gutter-y: var(--spacing-3); }
240
+ .g-sm-4 { --grid-gutter-x: var(--spacing-4); --grid-gutter-y: var(--spacing-4); }
241
+ .g-sm-5 { --grid-gutter-x: var(--spacing-5); --grid-gutter-y: var(--spacing-5); }
242
+
243
+ .gx-sm-0 { --grid-gutter-x: 0; }
244
+ .gx-sm-1 { --grid-gutter-x: var(--spacing-1); }
245
+ .gx-sm-2 { --grid-gutter-x: var(--spacing-2); }
246
+ .gx-sm-3 { --grid-gutter-x: var(--spacing-3); }
247
+ .gx-sm-4 { --grid-gutter-x: var(--spacing-4); }
248
+ .gx-sm-5 { --grid-gutter-x: var(--spacing-5); }
249
+
250
+ .gy-sm-0 { --grid-gutter-y: 0; }
251
+ .gy-sm-1 { --grid-gutter-y: var(--spacing-1); }
252
+ .gy-sm-2 { --grid-gutter-y: var(--spacing-2); }
253
+ .gy-sm-3 { --grid-gutter-y: var(--spacing-3); }
254
+ .gy-sm-4 { --grid-gutter-y: var(--spacing-4); }
255
+ .gy-sm-5 { --grid-gutter-y: var(--spacing-5); }
256
+ }
257
+
258
+ /* --- md — min-width: 768px -------------------------------------------- */
259
+
260
+ @media (--breakpoint-md) {
261
+ .g-md-0 { --grid-gutter-x: 0; --grid-gutter-y: 0; }
262
+ .g-md-1 { --grid-gutter-x: var(--spacing-1); --grid-gutter-y: var(--spacing-1); }
263
+ .g-md-2 { --grid-gutter-x: var(--spacing-2); --grid-gutter-y: var(--spacing-2); }
264
+ .g-md-3 { --grid-gutter-x: var(--spacing-3); --grid-gutter-y: var(--spacing-3); }
265
+ .g-md-4 { --grid-gutter-x: var(--spacing-4); --grid-gutter-y: var(--spacing-4); }
266
+ .g-md-5 { --grid-gutter-x: var(--spacing-5); --grid-gutter-y: var(--spacing-5); }
267
+
268
+ .gx-md-0 { --grid-gutter-x: 0; }
269
+ .gx-md-1 { --grid-gutter-x: var(--spacing-1); }
270
+ .gx-md-2 { --grid-gutter-x: var(--spacing-2); }
271
+ .gx-md-3 { --grid-gutter-x: var(--spacing-3); }
272
+ .gx-md-4 { --grid-gutter-x: var(--spacing-4); }
273
+ .gx-md-5 { --grid-gutter-x: var(--spacing-5); }
274
+
275
+ .gy-md-0 { --grid-gutter-y: 0; }
276
+ .gy-md-1 { --grid-gutter-y: var(--spacing-1); }
277
+ .gy-md-2 { --grid-gutter-y: var(--spacing-2); }
278
+ .gy-md-3 { --grid-gutter-y: var(--spacing-3); }
279
+ .gy-md-4 { --grid-gutter-y: var(--spacing-4); }
280
+ .gy-md-5 { --grid-gutter-y: var(--spacing-5); }
281
+ }
282
+
283
+ /* --- lg — min-width: 1024px ------------------------------------------- */
284
+
285
+ @media (--breakpoint-lg) {
286
+ .g-lg-0 { --grid-gutter-x: 0; --grid-gutter-y: 0; }
287
+ .g-lg-1 { --grid-gutter-x: var(--spacing-1); --grid-gutter-y: var(--spacing-1); }
288
+ .g-lg-2 { --grid-gutter-x: var(--spacing-2); --grid-gutter-y: var(--spacing-2); }
289
+ .g-lg-3 { --grid-gutter-x: var(--spacing-3); --grid-gutter-y: var(--spacing-3); }
290
+ .g-lg-4 { --grid-gutter-x: var(--spacing-4); --grid-gutter-y: var(--spacing-4); }
291
+ .g-lg-5 { --grid-gutter-x: var(--spacing-5); --grid-gutter-y: var(--spacing-5); }
292
+
293
+ .gx-lg-0 { --grid-gutter-x: 0; }
294
+ .gx-lg-1 { --grid-gutter-x: var(--spacing-1); }
295
+ .gx-lg-2 { --grid-gutter-x: var(--spacing-2); }
296
+ .gx-lg-3 { --grid-gutter-x: var(--spacing-3); }
297
+ .gx-lg-4 { --grid-gutter-x: var(--spacing-4); }
298
+ .gx-lg-5 { --grid-gutter-x: var(--spacing-5); }
299
+
300
+ .gy-lg-0 { --grid-gutter-y: 0; }
301
+ .gy-lg-1 { --grid-gutter-y: var(--spacing-1); }
302
+ .gy-lg-2 { --grid-gutter-y: var(--spacing-2); }
303
+ .gy-lg-3 { --grid-gutter-y: var(--spacing-3); }
304
+ .gy-lg-4 { --grid-gutter-y: var(--spacing-4); }
305
+ .gy-lg-5 { --grid-gutter-y: var(--spacing-5); }
306
+ }