@webority/theme 0.7.2 → 0.7.4

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.
@@ -11,14 +11,16 @@
11
11
  // ---- Brand colors ---------------------------------------------------
12
12
  // Neutral indigo default. The full ramp lives in _tokens.scss as CSS
13
13
  // variables since Bootstrap only consumes the named theme colors.
14
- $primary: #4F46E5;
15
- $secondary: #4B5675; // foreground-3 — quiet text + secondary buttons
16
- $success: #04B440;
17
- $info: #056EE9;
18
- $warning: #DFA000;
19
- $danger: #E82646;
20
- $light: #F9FBFC; // surface-mute
21
- $dark: #071437; // text-heading
14
+ // `!default` so a product that sets these in its own _variables BEFORE importing this file
15
+ // (the documented override path) wins — a plain assignment here would clobber the brand.
16
+ $primary: #4F46E5 !default;
17
+ $secondary: #4B5675 !default; // foreground-3 — quiet text + secondary buttons
18
+ $success: #04B440 !default;
19
+ $info: #056EE9 !default;
20
+ $warning: #DFA000 !default;
21
+ $danger: #E82646 !default;
22
+ $light: #F9FBFC !default; // surface-mute
23
+ $dark: #071437 !default; // text-heading
22
24
 
23
25
  // Override `$theme-colors` so Bootstrap's $theme-colors map includes
24
26
  // our brand. Anything we add here gets utility classes generated
@@ -35,9 +37,9 @@ $theme-colors: (
35
37
  );
36
38
 
37
39
  // Brand helper — set a product's primary ONCE and have the theme-colour map
38
- // (so every .btn-primary / .bg-primary / .text-primary utility) and $link-color
39
- // follow, instead of overriding each in turn. Call it in the product's
40
- // pre-bootstrap variables, BEFORE the `bootstrap/scss/bootstrap` import, e.g.:
40
+ // (so every .btn-primary / .bg-primary / .text-primary utility), $link-color,
41
+ // and $link-hover-color follow, instead of overriding each in turn. Call it in
42
+ // the product's pre-bootstrap variables, BEFORE `bootstrap/scss/bootstrap`, e.g.:
41
43
  //
42
44
  // @include wui-brand-primary(#0EA5E9);
43
45
  // @import "bootstrap/scss/bootstrap";
@@ -49,12 +51,13 @@ $theme-colors: (
49
51
  $primary: $primary !global;
50
52
  $theme-colors: map-merge($theme-colors, ("primary": $primary)) !global;
51
53
  $link-color: $primary !global;
54
+ $link-hover-color: mix(black, $primary, 12%) !global;
52
55
  }
53
56
 
54
57
 
55
58
  // ---- Body / text ----------------------------------------------------
59
+ // $body-bg left at Bootstrap's $white — do not restate pure defaults here.
56
60
  $body-color: #252F4A; // text-1 from locked palette
57
- $body-bg: #FFFFFF;
58
61
  $body-secondary-color: #4B5675;
59
62
  $body-tertiary-color: #687088; // AA on white (matches --wui-text-3); #78829D was only 3.5:1
60
63
  $body-secondary-bg: #F9FBFC;
@@ -68,81 +71,71 @@ $border-color-translucent: rgba(13, 24, 43, 0.08);
68
71
  // One ladder; every component derives from it (Bootstrap's own model). Set a
69
72
  // component's radius by pointing it at a rung, never by hardcoding a px value —
70
73
  // that is what let buttons drift to ~3x Bootstrap's.
71
- $border-radius: 0.5rem; // 8px — buttons, inputs, dropdowns
72
- $border-radius-sm: 0.375rem; // 6px
73
- $border-radius-lg: 0.75rem; // 12px — cards, toasts
74
- $border-radius-xl: 1rem; // 16px — modals
75
- $border-radius-2xl: 1.5rem; // 24px
76
- $border-radius-pill: 9999px;
74
+ // Only rungs that DIFFER from Bootstrap 5.3 are set: BS is 0.375/0.25/0.5/1/2rem;
75
+ // $border-radius-xl (1rem) and the font-weight ladder match BS and are left alone.
76
+ $border-radius: 0.5rem; // 8px — buttons, inputs, dropdowns (BS 0.375)
77
+ $border-radius-sm: 0.375rem; // 6px (BS 0.25)
78
+ $border-radius-lg: 0.75rem; // 12px — cards, toasts (BS 0.5)
79
+ $border-radius-2xl: 1.5rem; // 24px (BS 2rem via $border-radius-xxl)
80
+ $border-radius-pill: 9999px; // same visual as BS 50rem; explicit for token clarity
77
81
 
78
82
 
79
83
  // ---- Typography -----------------------------------------------------
84
+ // Font-size base (1rem) and font-weight 300–700 match Bootstrap — not restated.
85
+ // h1/h2/h6 match Bootstrap's $font-size-base multipliers at 1rem — not restated;
86
+ // only h3–h5 are tighter than Bootstrap's scale.
80
87
  $font-family-sans-serif: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
81
88
  $font-family-monospace: 'JetBrains Mono', SFMono-Regular, Menlo, Monaco, Consolas, monospace;
82
89
 
83
- $font-size-base: 1rem; // 16px
84
- $line-height-base: 1.55;
90
+ $line-height-base: 1.55; // BS 1.5
85
91
 
86
- $font-weight-light: 300;
87
- $font-weight-normal: 400;
88
- $font-weight-medium: 500;
89
- $font-weight-semibold: 600;
90
- $font-weight-bold: 700;
91
-
92
- $headings-font-weight: 600;
93
- $headings-line-height: 1.2;
92
+ $headings-font-weight: 600; // BS 500
94
93
  $headings-letter-spacing: -0.02em;
95
94
  $headings-color: #071437;
96
95
 
97
96
  $display-font-weight: 500;
98
97
  $display-line-height: 1.05;
99
98
 
100
- $h1-font-size: 2.5rem; // 40px
101
- $h2-font-size: 2rem; // 32px
102
- $h3-font-size: 1.5rem; // 24px
103
- $h4-font-size: 1.25rem; // 20px
104
- $h5-font-size: 1.125rem; // 18px
105
- $h6-font-size: 1rem; // 16px
99
+ $h3-font-size: 1.5rem; // 24px (BS 1.75rem)
100
+ $h4-font-size: 1.25rem; // 20px (BS 1.5rem)
101
+ $h5-font-size: 1.125rem; // 18px (BS 1.25rem)
106
102
 
107
103
 
108
104
  // ---- Spacing --------------------------------------------------------
109
- // Bootstrap default ladder is 0/.25/.5/1/1.5/3rem. We add 6/8/10/12
110
- // for hero / section padding so utility classes like `py-8` exist.
111
- $spacer: 1rem;
105
+ // Bootstrap ladder is 0/.25/.5/1/1.5/3rem ($spacer = 1rem). We replace the map
106
+ // with the same 0–5 rungs plus 6/7/8/10/12 for hero / section padding so
107
+ // utilities like `py-8` exist. No need to restate $spacer itself.
112
108
  $spacers: (
113
109
  0: 0,
114
- 1: $spacer * 0.25, // 4px
115
- 2: $spacer * 0.5, // 8px
116
- 3: $spacer, // 16px
117
- 4: $spacer * 1.5, // 24px
118
- 5: $spacer * 3, // 48px
119
- 6: $spacer * 4.5, // 72px
120
- 7: $spacer * 5, // 80px
121
- 8: $spacer * 6, // 96px
122
- 10: $spacer * 8, // 128px
123
- 12: $spacer * 10, // 160px
110
+ 1: 0.25rem, // 4px
111
+ 2: 0.5rem, // 8px
112
+ 3: 1rem, // 16px
113
+ 4: 1.5rem, // 24px
114
+ 5: 3rem, // 48px
115
+ 6: 4.5rem, // 72px
116
+ 7: 5rem, // 80px
117
+ 8: 6rem, // 96px
118
+ 10: 8rem, // 128px
119
+ 12: 10rem, // 160px
124
120
  );
125
121
 
126
-
127
- // ---- Container widths -----------------------------------------------
128
- // The locked design uses a wider canvas (1512px max) with generous side
129
- // padding. Override Bootstrap's narrower default so marketing layouts
130
- // breathe properly on large monitors.
131
- $container-max-widths: (
132
- sm: 540px,
133
- md: 720px,
134
- lg: 960px,
135
- xl: 1140px,
136
- xxl: 1320px,
137
- );
122
+ // $container-max-widths is intentionally NOT overridden — Bootstrap's
123
+ // 540/720/960/1140/1320 map is already what we want. The wider marketing
124
+ // canvas (1512px) is `.container-cloves` + `--wui-container-max` in tokens,
125
+ // not Bootstrap's stepped `.container`.
138
126
 
139
127
 
140
128
  // ---- Shadows --------------------------------------------------------
141
- // Mirrors the `card / card-lifted / card-lifted-hover` shadow tokens
142
- // from the locked design.
143
- $box-shadow-sm: 0 1px 2px rgba(7, 20, 55, 0.04), 0 4px 12px rgba(7, 20, 55, 0.06);
144
- $box-shadow: 0 0 2px 0 rgba(145, 158, 171, 0.20), 0 12px 24px -4px rgba(145, 158, 171, 0.12);
145
- $box-shadow-lg: 0 0 2px 0 rgba(145, 158, 171, 0.20), 0 20px 40px -4px rgba(145, 158, 171, 0.20);
129
+ // Elevation rule (TASK-06080): in-page surfaces are FLAT (borders only).
130
+ // Bootstrap utility ladder (.shadow / .shadow-sm / .shadow-lg) is zeroed so
131
+ // products cannot reintroduce random depth. Floating UI (dropdown / modal /
132
+ // toast) uses the overlay rungs — same values as --wui-shadow-overlay* in tokens.
133
+ $wui-shadow-overlay: 0 8px 28px -6px rgba(7, 20, 55, 0.14);
134
+ $wui-shadow-overlay-lg: 0 24px 60px -16px rgba(7, 20, 55, 0.28);
135
+
136
+ $box-shadow-sm: none;
137
+ $box-shadow: none;
138
+ $box-shadow-lg: none;
146
139
 
147
140
 
148
141
  // ---- Buttons --------------------------------------------------------
@@ -160,34 +153,29 @@ $btn-transition: color 0.15s ease, background-color 0.15s ease, border-c
160
153
 
161
154
 
162
155
  // ---- Forms ----------------------------------------------------------
163
- // Matches the reference `<Input>` component spec (5 locked states:
164
- // default / hover / focus / disabled / error). The border itself is the
165
- // focus cue — no separate box-shadow glow. Disabled gets a muted bg.
166
- // Error is driven by `aria-invalid="true"` (no separate .is-invalid
167
- // class needed for the visual change).
156
+ // Bootstrap `.form-control` is the field skin; post-CSS in wui/_controls.scss
157
+ // layers shared height / hover / focus / invalid on `.form-control` and the
158
+ // `.input` alias together (TASK-06079). Here only $input-* BS vars.
168
159
  $input-bg: #FFFFFF;
169
160
  $input-disabled-bg: #F5F6FA; // --wui-bg-muted
170
161
  $input-border-color: $border-color;
171
162
  // $input-focus-border-color is intentionally NOT overridden. Setting it to $primary here
172
163
  // captures the LIBRARY's $primary (this file compiles before a product's brand override),
173
- // leaking indigo into every product's raw .form-control focus. Bootstrap's !default derives
174
- // it from the brand $primary after the override; the library's own .input:focus uses
175
- // var(--wui-primary), which the product overrides at runtime.
164
+ // leaking indigo into every product. Bootstrap's !default derives it from brand $primary;
165
+ // post-CSS focus uses var(--color-primary) so runtime rebrand tracks.
176
166
  $input-focus-box-shadow: none; // border IS the focus cue
177
167
  $input-focus-color: $body-color;
178
- $input-padding-y: 0.5rem; // 8px → 40px total height with 1rem font + 1.5 line-height
179
- $input-padding-x: 0.875rem; // 14px — comfortable inset for leading icon space
180
- $input-border-radius: $border-radius; // 8px — matches buttons; controls share one corner
168
+ $input-padding-y: 0.5rem; // filler inside --wui-control-height (44px)
169
+ $input-padding-x: 0.875rem; // 14px
170
+ $input-border-radius: $border-radius;
181
171
  $input-placeholder-color: #99A1B7; // --wui-text-4
182
172
 
183
173
 
184
174
  // ---- Cards ----------------------------------------------------------
185
175
  $card-border-color: $border-color;
186
176
  $card-border-radius: $border-radius-lg;
187
- // Flat surfaces — no drop shadow on default .card. Depth is conveyed
188
- // via background tint + hairline border instead. Use .card-lifted
189
- // utility (in _components.scss) only when a card legitimately
190
- // needs to sit "above" the page (currently disabled — set to `none`).
177
+ // Flat surfaces — no drop shadow on default .card. Depth is border + tint.
178
+ // `.card-lifted` is a 1px hover translate only (not a shadow).
191
179
  $card-box-shadow: none;
192
180
  $card-spacer-y: 1.5rem;
193
181
  $card-spacer-x: 1.5rem;
@@ -197,23 +185,26 @@ $card-spacer-x: 1.5rem;
197
185
  $nav-link-font-weight: 500;
198
186
  $dropdown-border-color: $border-color;
199
187
  $dropdown-border-radius: $border-radius;
200
- $dropdown-box-shadow: $box-shadow-lg;
188
+ $dropdown-box-shadow: $wui-shadow-overlay;
201
189
 
202
190
 
203
191
  // ---- Modals + toasts ------------------------------------------------
204
192
  $modal-content-border-color: $border-color;
205
- $modal-content-border-radius: $border-radius-xl;
206
- $modal-content-box-shadow-xs: $box-shadow-lg;
193
+ $modal-content-border-radius: 1rem; // BS $border-radius-xl (1rem) — literal because we do not restate that rung
194
+ $modal-content-box-shadow-xs: $wui-shadow-overlay-lg;
207
195
 
208
196
  $toast-border-color: $border-color;
209
197
  $toast-border-radius: $border-radius-lg;
210
- $toast-box-shadow: $box-shadow-lg;
198
+ $toast-box-shadow: $wui-shadow-overlay-lg;
211
199
 
212
200
 
213
201
  // ---- Links ----------------------------------------------------------
214
- $link-color: $primary;
215
- $link-hover-color: #4338CA; // accent-dark (primary pressed)
216
- $link-decoration: none;
202
+ // $link-color left at Bootstrap's default ($primary) so it tracks brand $primary.
203
+ // Hover is a darkened mix of $primary — never a hard-coded indigo — so a product
204
+ // that sets $primary (or calls wui-brand-primary) gets a matching hover. Approximate
205
+ // of Bootstrap's shift-color($link-color, 20%) without importing BS functions here.
206
+ $link-hover-color: mix(black, $primary, 12%);
207
+ $link-decoration: none; // BS default is underline
217
208
  $link-hover-decoration: underline;
218
209
 
219
210
 
@@ -222,8 +213,8 @@ $link-hover-decoration: underline;
222
213
  // LIBRARY's $primary (this file compiles before a product's brand override), so the ring
223
214
  // leaked indigo into every product. Bootstrap's !default `rgba($primary, $focus-ring-opacity)`
224
215
  // is evaluated after the brand override, so it tracks the brand correctly.
225
- $focus-ring-width: 3px;
226
- $focus-ring-blur: 0;
216
+ // $focus-ring-blur matches BS (0) — not restated.
217
+ $focus-ring-width: 3px; // BS 0.25rem (4px)
227
218
 
228
219
 
229
220
  // ---- Table ----------------------------------------------------------
@@ -97,7 +97,8 @@
97
97
  --color-scrim: color-mix(in srgb, var(--wui-text-heading) 62%, transparent);
98
98
  --color-on-scrim: var(--wui-bg-light);
99
99
 
100
- // Elevation — in-page surfaces flat (borders only); floating overlays lift.
100
+ // Elevation — in-page flat; only floating overlays lift (matches zeroed BS
101
+ // $box-shadow* utilities and --wui-shadow-card* none — TASK-06080).
101
102
  --shadow-sm: none;
102
103
  --shadow-md: none;
103
104
  --shadow-lg: none;
@@ -318,7 +318,7 @@
318
318
  // scrollable modal / table card. Sits above the modal layer.
319
319
  .search-select-menu-fixed {
320
320
  position: fixed;
321
- z-index: 1600;
321
+ z-index: var(--wui-z-menu);
322
322
  right: auto;
323
323
  top: auto;
324
324
  left: auto;
@@ -483,7 +483,7 @@
483
483
  // sits above the modal layer.
484
484
  .datepicker-pop {
485
485
  position: fixed;
486
- z-index: 1600;
486
+ z-index: var(--wui-z-menu);
487
487
  width: 312px;
488
488
  max-width: calc(100vw - 16px);
489
489
  padding: 18px;
@@ -801,7 +801,7 @@ button.datepicker-month:hover {
801
801
  }
802
802
  .daterange-pop {
803
803
  position: fixed;
804
- z-index: 1600;
804
+ z-index: var(--wui-z-menu);
805
805
  width: 620px;
806
806
  max-width: calc(100vw - 16px);
807
807
  padding: 18px;
@@ -998,7 +998,7 @@ button.datepicker-month:hover {
998
998
  // modal layer, matching .search-select-menu-fixed and .datepicker-pop.
999
999
  .country-dropdown-menu {
1000
1000
  position: fixed;
1001
- z-index: 1600;
1001
+ z-index: var(--wui-z-menu);
1002
1002
  width: 320px;
1003
1003
  max-width: calc(100vw - 16px);
1004
1004
  padding: 4px;