@hawiyah/styles 0.0.0-stage → 0.2.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 (118) hide show
  1. package/LICENSE +73 -0
  2. package/NOTICE +34 -0
  3. package/README.md +246 -2
  4. package/dist/accordion-motion.css +18 -0
  5. package/dist/assets/external-link.svg +1 -0
  6. package/dist/assets/favicon.svg +4 -0
  7. package/dist/assets/fonts/riyal-LICENSE.txt +93 -0
  8. package/dist/assets/fonts/riyal-provenance.json +47 -0
  9. package/dist/assets/fonts/riyal.woff2 +0 -0
  10. package/dist/assets/hawiyah-loader-256.gif +0 -0
  11. package/dist/assets/hawiyah-loader-white-256.gif +0 -0
  12. package/dist/assets/hawiyah-loader-white.gif +0 -0
  13. package/dist/assets/hawiyah-loader.gif +0 -0
  14. package/dist/assets/hawiyah-lockup-ar-mono.svg +4 -0
  15. package/dist/assets/hawiyah-lockup-ar-reverse.svg +4 -0
  16. package/dist/assets/hawiyah-lockup-ar-white.svg +4 -0
  17. package/dist/assets/hawiyah-lockup-ar.svg +4 -0
  18. package/dist/assets/hawiyah-lockup-bilingual-mono.svg +4 -0
  19. package/dist/assets/hawiyah-lockup-bilingual-reverse.svg +4 -0
  20. package/dist/assets/hawiyah-lockup-bilingual-white.svg +4 -0
  21. package/dist/assets/hawiyah-lockup-bilingual.svg +4 -0
  22. package/dist/assets/hawiyah-lockup-en-mono.svg +4 -0
  23. package/dist/assets/hawiyah-lockup-en-reverse.svg +4 -0
  24. package/dist/assets/hawiyah-lockup-en-white.svg +4 -0
  25. package/dist/assets/hawiyah-lockup-en.svg +4 -0
  26. package/dist/assets/hawiyah-pattern.svg +4 -0
  27. package/dist/assets/hawiyah-symbol-mono.svg +4 -0
  28. package/dist/assets/hawiyah-symbol-reverse.svg +4 -0
  29. package/dist/assets/hawiyah-symbol-white.svg +4 -0
  30. package/dist/assets/hawiyah-symbol.svg +4 -0
  31. package/dist/assets/hawiyah-wordmark-loader-256.gif +0 -0
  32. package/dist/assets/hawiyah-wordmark-loader-white-256.gif +0 -0
  33. package/dist/assets/hawiyah-wordmark-loader-white.gif +0 -0
  34. package/dist/assets/hawiyah-wordmark-loader.gif +0 -0
  35. package/dist/assets/hawiyah-wordmark-mono.svg +4 -0
  36. package/dist/assets/hawiyah-wordmark-reverse.svg +4 -0
  37. package/dist/assets/hawiyah-wordmark-white.svg +4 -0
  38. package/dist/assets/hawiyah-wordmark.svg +4 -0
  39. package/dist/assets/icons/LICENSE +21 -0
  40. package/dist/assets/icons/arrow-down-01.svg +3 -0
  41. package/dist/assets/icons/arrow-left-01.svg +3 -0
  42. package/dist/assets/icons/arrow-right-01.svg +3 -0
  43. package/dist/assets/icons/calendar-03.svg +6 -0
  44. package/dist/assets/icons/cancel-01.svg +3 -0
  45. package/dist/assets/icons/checkmark-circle-02.svg +4 -0
  46. package/dist/assets/icons/filter-horizontal.svg +8 -0
  47. package/dist/assets/icons/home-01.svg +3 -0
  48. package/dist/assets/icons/link-04.svg +4 -0
  49. package/dist/assets/icons/lock-password.svg +7 -0
  50. package/dist/assets/icons/menu-01.svg +5 -0
  51. package/dist/assets/icons/provenance.json +202 -0
  52. package/dist/assets/icons/search-01.svg +4 -0
  53. package/dist/assets/icons/sorting-05.svg +8 -0
  54. package/dist/assets/icons/thumbs-down.svg +4 -0
  55. package/dist/assets/icons/thumbs-up.svg +4 -0
  56. package/dist/assets/icons/view-off-slash.svg +5 -0
  57. package/dist/assets/icons/view.svg +4 -0
  58. package/dist/assets/notifications/danger-outline.svg +3 -0
  59. package/dist/assets/notifications/danger.svg +4 -0
  60. package/dist/assets/notifications/info-outline.svg +3 -0
  61. package/dist/assets/notifications/info.svg +4 -0
  62. package/dist/assets/notifications/neutral-outline.svg +3 -0
  63. package/dist/assets/notifications/neutral.svg +4 -0
  64. package/dist/assets/notifications/success-outline.svg +3 -0
  65. package/dist/assets/notifications/success.svg +4 -0
  66. package/dist/assets/notifications/warning-outline.svg +3 -0
  67. package/dist/assets/notifications/warning.svg +4 -0
  68. package/dist/assets/pagination-arrow.svg +1 -0
  69. package/dist/assets/select-down.svg +4 -0
  70. package/dist/assets/select-up.svg +4 -0
  71. package/dist/brand-loader.css +12 -0
  72. package/dist/components.css +335 -0
  73. package/dist/content-navigation.css +44 -0
  74. package/dist/date-picker.css +50 -0
  75. package/dist/dga.css +316 -0
  76. package/dist/direction.css +14 -0
  77. package/dist/extended.css +310 -0
  78. package/dist/feedback.css +48 -0
  79. package/dist/file-upload-list.css +64 -0
  80. package/dist/icons.css +42 -0
  81. package/dist/layout.css +129 -0
  82. package/dist/link-composition.css +10 -0
  83. package/dist/mobile-navigation.css +43 -0
  84. package/dist/mobile-top-bar.css +15 -0
  85. package/dist/navigation-drawer.css +103 -0
  86. package/dist/nic-accordion.css +96 -0
  87. package/dist/nic-avatars.css +33 -0
  88. package/dist/nic-badges.css +56 -0
  89. package/dist/nic-buttons.css +80 -0
  90. package/dist/nic-cards.css +77 -0
  91. package/dist/nic-carousel.css +77 -0
  92. package/dist/nic-choices.css +64 -0
  93. package/dist/nic-footer.css +73 -0
  94. package/dist/nic-foundations.css +115 -0
  95. package/dist/nic-icons.css +72 -0
  96. package/dist/nic-input-groups.css +35 -0
  97. package/dist/nic-links.css +61 -0
  98. package/dist/nic-lists.css +68 -0
  99. package/dist/nic-notification-dialog.css +114 -0
  100. package/dist/nic-notifications.css +124 -0
  101. package/dist/nic-pagination.css +73 -0
  102. package/dist/nic-rating.css +53 -0
  103. package/dist/nic-search.css +70 -0
  104. package/dist/nic-segmented.css +117 -0
  105. package/dist/nic-select.css +51 -0
  106. package/dist/nic-tables.css +68 -0
  107. package/dist/nic-tabs.css +86 -0
  108. package/dist/password-field.css +16 -0
  109. package/dist/portal-branches.css +52 -0
  110. package/dist/portal.css +24 -0
  111. package/dist/reset.css +12 -0
  112. package/dist/riyal.css +32 -0
  113. package/dist/search-field.css +11 -0
  114. package/dist/site-verification.css +36 -0
  115. package/dist/stepper.css +46 -0
  116. package/dist/styles.css +49 -0
  117. package/dist/tooltip-placement.css +65 -0
  118. package/package.json +51 -3
package/dist/dga.css ADDED
@@ -0,0 +1,316 @@
1
+ /* DGA reference profile — supplied local snapshot, 2026-10-29.
2
+ This is a source-informed implementation, not an endorsement or parity claim.
3
+ See docs/dga-reference.md for provenance and accessibility adaptations.
4
+
5
+ Structural options inherit from the nearest theme. Explicit non-DGA themes
6
+ reset them, including when nested inside the default DGA page. The whitespace
7
+ / initial switches select colors at the component itself, so a nested dark
8
+ mode resolves its own semantic colors rather than its ancestor's light ones.
9
+ No @scope or script-driven media measurement is required. */
10
+ :where(:root:not([data-hw-theme]), [data-hw-theme='dga'], [data-hw-theme='custom']) {
11
+ --hw-dga-on: ;
12
+ --hw-dga-off: initial;
13
+ --hw-profile-control-radius: 0.25rem;
14
+ --hw-profile-button-gap: 0.25rem;
15
+ --hw-profile-button-padding-block: 0px;
16
+ --hw-profile-button-padding-lg: 1rem;
17
+ --hw-profile-button-font: 1rem;
18
+ --hw-profile-button-leading: 1.5;
19
+ --hw-profile-field-padding-block: 0.375rem;
20
+ --hw-profile-field-padding-start: 1rem;
21
+ --hw-profile-field-padding-end: 1rem;
22
+ --hw-profile-field-font-lg: 1rem;
23
+ --hw-profile-field-leading: 1.5;
24
+ --hw-profile-field-focus-line: 100% 2px;
25
+ --hw-profile-field-pressed-line: 50% 2px;
26
+ --hw-profile-field-shadow: none;
27
+ --hw-profile-textarea-height: 6rem;
28
+ --hw-profile-textarea-padding: 0.75rem 1rem;
29
+ --hw-profile-label-leading: 1.42857143;
30
+ --hw-profile-label-font: 1rem;
31
+ --hw-profile-header-height: 4.5rem;
32
+ --hw-profile-header-padding: 0px 2rem;
33
+ --hw-profile-header-gap: 1rem;
34
+ --hw-profile-footer-padding: 2.5rem 2rem;
35
+ }
36
+ :where([data-hw-theme]:not([data-hw-theme='dga'], [data-hw-theme='custom'])) {
37
+ --hw-dga-on: initial;
38
+ --hw-dga-off: ;
39
+ --hw-profile-control-radius: initial;
40
+ --hw-profile-button-gap: initial;
41
+ --hw-profile-button-padding-block: initial;
42
+ --hw-profile-button-padding-lg: initial;
43
+ --hw-profile-button-font: initial;
44
+ --hw-profile-button-leading: initial;
45
+ --hw-profile-field-padding-block: initial;
46
+ --hw-profile-field-padding-start: initial;
47
+ --hw-profile-field-padding-end: initial;
48
+ --hw-profile-field-font-lg: initial;
49
+ --hw-profile-field-leading: initial;
50
+ --hw-profile-field-focus-line: initial;
51
+ --hw-profile-field-pressed-line: initial;
52
+ --hw-profile-field-shadow: initial;
53
+ --hw-profile-textarea-height: initial;
54
+ --hw-profile-textarea-padding: initial;
55
+ --hw-profile-label-leading: initial;
56
+ --hw-profile-label-font: initial;
57
+ --hw-profile-header-height: initial;
58
+ --hw-profile-header-padding: initial;
59
+ --hw-profile-header-gap: initial;
60
+ --hw-profile-footer-padding: initial;
61
+ }
62
+
63
+ /* Button symbols form 2:5126 / 2:5246 / 2:5366: 40/32/24px,
64
+ padding 16/12/8px, gap4, radius4. Public comfortable sizes map to
65
+ 40/32/40; compact maps to32/24/40. Density tokens own the heights. */
66
+ .hw-button {
67
+ gap: var(--hw-profile-button-gap, var(--hw-space-2));
68
+ padding-block: var(--hw-profile-button-padding-block, var(--hw-space-2));
69
+ border-radius: var(--hw-profile-control-radius, var(--hw-radius-md));
70
+ font-size: var(--hw-profile-button-font, var(--hw-text-sm));
71
+ line-height: var(--hw-profile-button-leading, var(--hw-leading-heading));
72
+ }
73
+ .hw-button[data-size='sm'] {
74
+ padding-block: var(--hw-profile-button-padding-block, var(--hw-space-1));
75
+ padding-inline: var(--hw-dga-on, var(--hw-space-3)) var(--hw-dga-off, clamp(0.5rem, calc(var(--hw-control-height-sm) - 1.25rem), 0.75rem));
76
+ font-size: var(--hw-dga-on, var(--hw-text-xs)) var(--hw-dga-off, clamp(0.75rem, calc(var(--hw-control-height-sm) - 1.125rem), 0.875rem));
77
+ }
78
+ .hw-button[data-size='lg'] { padding-inline: var(--hw-profile-button-padding-lg, var(--hw-space-6)); font-size: var(--hw-text-md); }
79
+ .hw-button { --hw-button-control-height: var(--hw-control-height); }
80
+ .hw-button[data-size='sm'] { --hw-button-control-height: var(--hw-control-height-sm); }
81
+ .hw-button[data-size='lg'] { --hw-button-control-height: var(--hw-control-height-lg); }
82
+ .hw-button:is(:not([data-size]), [data-size]) { padding-block: clamp(0px, calc((var(--hw-button-control-height) - 1em * var(--hw-profile-button-leading, var(--hw-leading-heading)) - 2px) / 2), var(--hw-profile-button-padding-block, var(--hw-space-2))); }
83
+ .hw-button[data-icon-only], .hw-button.hw-icon-button { padding-inline: 0; }
84
+ .hw-button[data-variant='danger'] {
85
+ --hw-button-bg: var(--hw-color-danger-background, var(--hw-color-danger));
86
+ --hw-button-fg: var(--hw-dga-on, var(--hw-color-surface)) var(--hw-dga-off, #fff);
87
+ }
88
+ .hw-button:not([data-variant], :disabled, [aria-disabled='true']):active,
89
+ .hw-button[data-variant='primary']:not(:disabled, [aria-disabled='true']):active {
90
+ background: var(--hw-color-primary-active);
91
+ }
92
+
93
+ /* Text Input form 43:3717(default),43:3813(hover),43:3912/3919(pressed),
94
+ 43:4026/4034(focus),43:4334(medium),43:3741(error).
95
+ Radius4; comfortable input40; NIC padding16 and label16 supersede the earlier Figma padding8/16 and label14.
96
+ The source's #9DA4AE 1px resting border fails 3:1 on white. We use
97
+ Controls/control-border (#6C737F light, #9DA4AE dark) as an explicit
98
+ accessibility adaptation; the exact source field-border token is retained.
99
+ The focused bottom line is a dark neutral for empty/unvalidated fields.
100
+ Nonempty valid values use green, including prefilled values; user-invalid
101
+ or explicit application errors use danger. Blur hides the active underline.
102
+ It is the DGA focus indicator, without a duplicate
103
+ outer ring. Read-only fields keep a single inset keyboard indicator.
104
+ NIC global.css 2431–2648 supersedes the earlier Figma input timing:
105
+ 500ms ease, pressed line50%, padding16 and no focus shadow. Original
106
+ Figma measurements remain recorded in dga-foundations.json. */
107
+ :is(.hw-input, .hw-textarea, .hw-select) {
108
+ padding-block: var(--hw-profile-field-padding-block, var(--hw-space-2));
109
+ padding-inline: var(--hw-profile-field-padding-start, var(--hw-space-3)) var(--hw-profile-field-padding-end, var(--hw-space-3));
110
+ border-radius: var(--hw-profile-control-radius, var(--hw-radius-md));
111
+ background-color: var(--hw-color-field-background, var(--hw-color-surface));
112
+ background-image: linear-gradient(var(--hw-color-field-active), var(--hw-color-field-active)) var(--_nq-select-image,);
113
+ background-repeat: no-repeat;
114
+ background-position: center bottom var(--_nq-select-position,);
115
+ background-size: 0% 2px var(--_nq-select-size,);
116
+ line-height: var(--hw-profile-field-leading, var(--hw-leading-normal));
117
+ transition: var(--hw-dga-on, border-color var(--hw-duration-input) var(--hw-ease-input), background-color var(--hw-duration-input) var(--hw-ease-input), background-size var(--hw-duration-input) var(--hw-ease-input), box-shadow var(--hw-duration-input) var(--hw-ease-input)) var(--hw-dga-off, background-size var(--hw-duration-input, 500ms) var(--hw-ease-input, ease));
118
+ }
119
+ :is(.hw-input, .hw-textarea)::placeholder { color: var(--hw-color-field-placeholder, var(--hw-color-text-subtle)); }
120
+ :is(.hw-input, .hw-textarea, .hw-select):hover:not(:disabled, [readonly]) { border-color: var(--hw-color-field-hover, var(--hw-color-primary)); }
121
+ :is(.hw-input, .hw-textarea, .hw-select):focus:not(:disabled, [readonly]) {
122
+ border-color: var(--hw-dga-on, var(--hw-color-primary)) var(--hw-dga-off, var(--hw-color-field-active));
123
+ background-size: var(--hw-profile-field-focus-line, 0% 2px) var(--_nq-select-size,);
124
+ box-shadow: var(--hw-profile-field-shadow, none);
125
+ }
126
+ :is(.hw-input, .hw-textarea, .hw-select):active:not(:disabled, [readonly]) {
127
+ background-size: var(--hw-profile-field-pressed-line, 0% 2px) var(--_nq-select-size,);
128
+ background-color: var(--hw-color-field-background);
129
+ }
130
+ :is(.hw-input, .hw-textarea, .hw-select)[data-size='sm'] { padding-block: var(--hw-profile-button-padding-block, var(--hw-space-1)); }
131
+ :is(.hw-input, .hw-textarea, .hw-select)[data-size='lg'] {
132
+ padding-inline: var(--hw-profile-field-padding-start, var(--hw-space-4)) var(--hw-profile-field-padding-end, var(--hw-space-4));
133
+ font-size: var(--hw-profile-field-font-lg, var(--hw-text-lg));
134
+ }
135
+ /* One focus treatment: DGA's active underline, or an inset legacy border.
136
+ Read-only fields have no active underline, so retain an inset focus cue. */
137
+ :is(.hw-input, .hw-textarea, .hw-select):focus-visible {
138
+ outline: var(--hw-dga-on, 2px solid var(--hw-color-focus)) var(--hw-dga-off, none);
139
+ outline-offset: -2px;
140
+ }
141
+ :is(.hw-input, .hw-textarea)[readonly]:focus-visible {
142
+ outline: 2px solid var(--hw-color-focus);
143
+ }
144
+ :is(.hw-input, .hw-textarea, .hw-select)[data-variant='filled'] { background-color: var(--hw-color-surface-muted); background-image: linear-gradient(var(--hw-color-field-active), var(--hw-color-field-active)) var(--_nq-select-image,); background-repeat: no-repeat; background-position: center bottom var(--_nq-select-position,); background-size: 0% 2px var(--_nq-select-size,); }
145
+ :is(.hw-input, .hw-textarea, .hw-select)[data-variant='filled']:focus:not(:disabled, [readonly]) { background-size: var(--hw-profile-field-focus-line, 0% 2px) var(--_nq-select-size,); }
146
+ :is(.hw-input, .hw-textarea, .hw-select)[data-variant='filled']:active:not(:disabled, [readonly]) { background-size: var(--hw-profile-field-pressed-line, 0% 2px) var(--_nq-select-size,); background-color: var(--hw-dga-on, var(--hw-color-field-background)) var(--hw-dga-off, var(--hw-color-surface-muted)); }
147
+ :is(.hw-input, .hw-textarea, .hw-select)[data-variant='filled']:focus-visible { border-color: var(--hw-dga-on, var(--hw-color-border-strong)) var(--hw-dga-off, var(--hw-color-field-active)); }
148
+ /* Presence is adapter-owned; validity stays native. Empty optional fields must
149
+ not imply success. Explicit application errors take precedence below. */
150
+ :is(.hw-input, .hw-textarea, .hw-select):where([data-hw-filled='true']):valid,
151
+ :is(.hw-input, .hw-textarea, .hw-select)[data-variant='filled']:where([data-hw-filled='true']):valid {
152
+ background-image: linear-gradient(var(--hw-color-primary-text, var(--hw-color-primary)), var(--hw-color-primary-text, var(--hw-color-primary))) var(--_nq-select-image,);
153
+ }
154
+ :is(.hw-input, .hw-textarea, .hw-select)[aria-invalid='true'],
155
+ :is(.hw-input, .hw-textarea, .hw-select)[data-variant='filled'][aria-invalid='true'] {
156
+ border-color: var(--hw-color-danger);
157
+ background-image: linear-gradient(var(--hw-color-danger), var(--hw-color-danger)) var(--_nq-select-image,);
158
+ }
159
+ :is(.hw-input, .hw-textarea, .hw-select)[aria-invalid='true']:is(:hover, :focus, :active) { border-color: var(--hw-color-danger); }
160
+ @supports selector(:user-invalid) {
161
+ :is(.hw-input, .hw-textarea, .hw-select):user-invalid,
162
+ :is(.hw-input, .hw-textarea, .hw-select)[data-variant='filled']:user-invalid { border-color: var(--hw-color-danger); background-image: linear-gradient(var(--hw-color-danger), var(--hw-color-danger)) var(--_nq-select-image,); }
163
+ :is(.hw-input, .hw-textarea, .hw-select):user-invalid:is(:hover, :focus, :active) { border-color: var(--hw-color-danger); }
164
+ }
165
+ :is(.hw-input, .hw-textarea, .hw-select):disabled,
166
+ :is(.hw-input, .hw-textarea)[readonly] { background-size: 0% 2px; box-shadow: none; }
167
+ :is(.hw-input, .hw-textarea, .hw-select):disabled { border-color: var(--hw-color-border); background-color: var(--hw-dga-on, var(--hw-color-disabled)) var(--hw-dga-off, transparent); }
168
+ :is(.hw-input, .hw-textarea)[readonly] { background-color: var(--hw-dga-on, var(--hw-color-surface-muted)) var(--hw-dga-off, transparent); }
169
+ /* Textarea form5:47724:96px high, padding12/16. User resizing remains native. */
170
+ .hw-textarea { min-block-size: var(--hw-profile-textarea-height, 7.5rem); padding: var(--hw-profile-textarea-padding, var(--hw-space-2) var(--hw-space-3)); }
171
+ /* Fit the requested density without clipping translated or zoomed text. */
172
+ :is(.hw-input, .hw-select) { --hw-field-height: max(var(--hw-control-height), var(--hw-control-field-min-height, 0px)); }
173
+ :is(.hw-input, .hw-select)[data-size='sm'] { --hw-field-height: max(var(--hw-control-height-sm), var(--hw-control-field-min-height, 0px)); }
174
+ :is(.hw-input, .hw-select)[data-size='lg'] { --hw-field-height: max(var(--hw-control-height-lg), var(--hw-control-field-min-height, 0px)); }
175
+ :is(.hw-input, .hw-select):is(:not([data-size]), [data-size]) { min-block-size: var(--hw-field-height); padding-block: clamp(0px, calc((var(--hw-field-height) - 1em * var(--hw-profile-field-leading, var(--hw-leading-normal)) - 2px) / 2), var(--hw-profile-field-padding-block, var(--hw-space-2))); }
176
+ :is(.hw-input, .hw-select)[data-size='sm'] { line-height: max(1em, min(calc(1em * var(--hw-profile-field-leading, var(--hw-leading-normal))), calc(var(--hw-field-height) - 2px))); }
177
+ .hw-label { font-size: var(--hw-profile-label-font, var(--hw-text-sm)); }
178
+ .hw-label, .hw-hint, .hw-error { line-height: var(--hw-profile-label-leading, var(--hw-leading-normal)); }
179
+ .hw-input-addon { border-radius: var(--hw-profile-control-radius, var(--hw-radius-md)); }
180
+ /* Group corners must win over the later profile radius. */
181
+ .hw-input-group > :not(:first-child) { border-start-start-radius: 0; border-end-start-radius: 0; }
182
+ .hw-input-group > :not(:last-child) { border-start-end-radius: 0; border-end-end-radius: 0; }
183
+
184
+ /* Portal header: form2:38369 and service20:4646, height72, desktop
185
+ inline32; mobile form48:3893 inline16. Header content may wrap when
186
+ translated/zoomed rather than clipping controls. */
187
+ .hw-portal-header {
188
+ gap: var(--hw-profile-header-gap, var(--hw-space-5));
189
+ min-block-size: var(--hw-profile-header-height, 5rem);
190
+ padding: var(--hw-profile-header-padding, var(--hw-space-4) clamp(1rem, 4vw, 3rem));
191
+ }
192
+ .hw-portal-header-inner, .hw-portal-header-main {
193
+ display: flex;
194
+ align-items: center;
195
+ flex-wrap: wrap;
196
+ gap: 1rem;
197
+ inline-size: 100%;
198
+ min-inline-size: 0;
199
+ min-block-size: var(--hw-profile-header-height, auto);
200
+ }
201
+ .hw-portal-header-inner > *, .hw-portal-header-main > * { min-inline-size: 0; }
202
+ .hw-portal-header :is(.hw-portal-actions, .hw-portal-header-actions) { flex-shrink: 0; }
203
+ .hw-portal-header :is(.hw-portal-brand, nav a) { color: var(--hw-color-heading, var(--hw-color-text)); }
204
+ .hw-portal-header nav a { position: relative; padding-inline: 0.5rem; }
205
+ .hw-portal-header nav a[aria-current='page'] { color: var(--hw-color-primary-text); }
206
+ .hw-portal-notice { padding-block: 0.375rem; color: var(--hw-color-text-muted); }
207
+
208
+ /* Footer form2:44049 / service1:52987: background-SA-Flag #074D31
209
+ in light mode, inline32. Height is content-driven, not the fixed frame520.
210
+ Existing simple PortalFooter markup and the composed columns both work. */
211
+ .hw-portal-footer {
212
+ padding: var(--hw-profile-footer-padding, var(--hw-space-8) clamp(1rem, 4vw, 3rem));
213
+ background: var(--hw-dga-on, var(--hw-color-canvas)) var(--hw-dga-off, var(--hw-color-footer));
214
+ color: var(--hw-dga-on, var(--hw-color-text)) var(--hw-dga-off, var(--hw-color-on-footer));
215
+ }
216
+ .hw-portal-footer nav a, .hw-portal-footer > p, .hw-portal-footer > small { color: var(--hw-dga-on, var(--hw-color-primary-text)) var(--hw-dga-off, var(--hw-color-on-footer)); }
217
+ .hw-portal-footer a:focus-visible { outline-color: currentColor; }
218
+ .hw-portal-footer > .hw-service-container { inline-size: min(80rem, 100%); }
219
+ .hw-portal-footer-main { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: 2rem; inline-size: 100%; }
220
+ .hw-portal-footer > .hw-portal-footer-main { flex-basis: 100%; }
221
+ .hw-portal-footer-main > * { min-inline-size: 0; }
222
+ .hw-portal-footer-main :is(h2, h3, h4) { margin: 0 0 1rem; font-size: 1rem; line-height: 1.5; font-weight: var(--hw-weight-semibold); }
223
+ .hw-portal-footer-links, .hw-portal-footer .hw-portal-footer-links { display: flex; flex-direction: column; align-items: start; gap: 0.75rem; margin: 0; padding: 0; list-style: none; }
224
+ .hw-portal-footer .hw-portal-footer-links ul { display: flex; flex-direction: column; align-items: start; gap: 0.75rem; }
225
+ .hw-portal-footer-links a { color: inherit; font-size: 0.875rem; line-height: 1.42857143; text-underline-offset: 0.2em; }
226
+ .hw-portal-footer-bottom { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem 2rem; inline-size: 100%; padding-block-start: 1.5rem; border-block-start: 1px solid currentColor; }
227
+ .hw-portal-footer > .hw-portal-footer-bottom { flex-basis: 100%; }
228
+ .hw-portal-footer-bottom :is(p, small) { margin: 0; font-size: 0.75rem; line-height: 1.5; }
229
+
230
+ /* Service page service1:21393/21394/21435 and form2:17299/17300/17331.
231
+ The desktop reference content is1280 with832main +32gap +416aside.
232
+ 832+32+416=1280. minmax tracks preserve this ratio below the max width.
233
+ Collapse960 and field collapse600 are implementation policies informed by
234
+ the source's mobile composition, not assertions about the Figma frame size. */
235
+ :where(.hw-service-container, .hw-service-layout, .hw-service-main,
236
+ .hw-service-aside, .hw-form-layout, .hw-form-sidebar, .hw-form-main,
237
+ .hw-form-grid, .hw-stepper-responsive, .hw-stepper-mobile,
238
+ .hw-service-metadata) { box-sizing: border-box; min-inline-size: 0; font-family: var(--hw-font-sans); }
239
+ .hw-service-container { inline-size: min(80rem, calc(100% - 2 * var(--hw-content-gutter, 2rem))); margin-inline: auto; }
240
+ .hw-service-layout, .hw-form-layout { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); align-items: start; gap: 2rem; }
241
+ .hw-service-main, .hw-form-main { display: flex; flex-direction: column; gap: 2rem; color: var(--hw-color-text); }
242
+ .hw-service-main { gap: 4rem; }
243
+ .hw-service-main > *, .hw-form-main > *, .hw-service-aside > * { min-inline-size: 0; }
244
+ .hw-service-aside { display: flex; flex-direction: column; gap: 1.5rem; padding: 2.5rem; border: 1px solid var(--hw-color-border); border-radius: 1rem; background: var(--hw-color-surface); color: var(--hw-color-text); overflow-wrap: anywhere; }
245
+ .hw-service-aside :is(h2, h3, p) { margin: 0; }
246
+ .hw-service-aside :is(h2, h3) { color: var(--hw-color-heading); font-size: var(--hw-text-lg); line-height: var(--hw-leading-heading); font-weight: var(--hw-weight-semibold); }
247
+ .hw-service-aside .hw-divider { margin: 0; }
248
+ .hw-service-metadata { display: flex; flex-direction: column; gap: 1rem; margin: 0; }
249
+ .hw-service-metadata > div { display: grid; gap: 0.25rem; }
250
+ .hw-service-metadata dt { color: var(--hw-color-text-muted); font-size: 0.875rem; line-height: 1.42857143; }
251
+ .hw-service-metadata dd { margin: 0; color: var(--hw-color-heading); font-size: 1rem; line-height: 1.5; font-weight: var(--hw-weight-medium); }
252
+ .hw-form-main { grid-column: 1; grid-row: 1 / span 2; }
253
+ .hw-form-layout > .hw-stepper-responsive { grid-column: 2; grid-row: 1; }
254
+ .hw-form-layout > .hw-service-aside { grid-column: 2; grid-row: 2; }
255
+ .hw-form-sidebar { display: flex; flex-direction: column; gap: 2rem; grid-column: 2; grid-row: 1 / span 2; }
256
+ .hw-form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem 2rem; }
257
+ .hw-form-grid > * { min-inline-size: 0; }
258
+ .hw-form-grid > [data-span='full'] { grid-column: 1 / -1; }
259
+
260
+ /* Form progress card desktop2:17331 (40px padding, radius16), mobile
261
+ 2:17587 (16inline/24block). Radial302:28486/28048:64px diameter,
262
+ 88% inner radius (~4px ring), text14/20; summary gap4 and text12/18.
263
+ A visible count/current label is required; the ring itself is decorative. */
264
+ .hw-stepper-responsive { padding: 2.5rem; border-radius: 1rem; background: var(--hw-color-canvas); color: var(--hw-color-heading); }
265
+ .hw-stepper-responsive .hw-stepper { flex-direction: column; gap: 0; }
266
+ .hw-stepper-responsive .hw-step { position: relative; align-items: start; flex: none; min-block-size: 5rem; gap: 1rem; padding-block-end: 1.5rem; line-height: 1.5; }
267
+ .hw-stepper-responsive .hw-step:last-child { min-block-size: 2rem; padding-block-end: 0; }
268
+ .hw-stepper-responsive .hw-step::before { position: relative; z-index: 1; inline-size: 2rem; block-size: 2rem; box-shadow: none; }
269
+ .hw-stepper-responsive .hw-step:not(:last-child)::after { position: absolute; inset-inline-start: calc(1rem - 1px); inset-block: 2rem 0; inline-size: 2px; min-inline-size: 0; block-size: auto; }
270
+ .hw-stepper-responsive .hw-step:is([data-state='complete'], [data-state='completed'])::after { background: var(--hw-color-primary); }
271
+ .hw-stepper-responsive .hw-step:is([data-state='complete'], [data-state='completed'])::before { border-color: var(--hw-color-primary); background: var(--hw-color-primary); color: var(--hw-color-on-primary); }
272
+ .hw-stepper-mobile { display: none; align-items: center; gap: 0.5rem; }
273
+ .hw-stepper-ring { position: relative; isolation: isolate; display: grid; flex: 0 0 4rem; place-items: center; inline-size: 4rem; block-size: 4rem; border-radius: 50%; color: var(--hw-color-text-muted); font-size: 0.875rem; line-height: 1.42857143; font-variant-numeric: tabular-nums; }
274
+ .hw-stepper-ring::before { content: ''; position: absolute; z-index: -1; inset: 0; border-radius: inherit; background: conic-gradient(var(--hw-color-primary) clamp(0%, var(--hw-step-progress, 25%), 100%), var(--hw-color-border) 0); mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 3.5px)); }
275
+ .hw-stepper-summary, .hw-stepper-mobile-content { display: flex; flex-direction: column; gap: 0.25rem; min-inline-size: 0; padding-inline-end: 1rem; }
276
+ :is(.hw-stepper-summary, .hw-stepper-mobile-content) strong { color: var(--hw-color-heading); font-size: 0.875rem; line-height: 1.42857143; font-weight: var(--hw-weight-semibold); }
277
+ :is(.hw-stepper-summary, .hw-stepper-mobile-content) :is(p, small, span) { margin: 0; color: var(--hw-color-text-muted); font-size: 0.75rem; line-height: 1.5; }
278
+
279
+ @media (max-width: 59.999rem) {
280
+ .hw-service-layout, .hw-form-layout { grid-template-columns: minmax(0, 1fr); gap: 2rem; }
281
+ .hw-form-layout { grid-template-areas: 'steps' 'main' 'guidance'; }
282
+ .hw-form-sidebar { display: contents; }
283
+ .hw-form-main { grid-area: main; }
284
+ .hw-form-layout > .hw-stepper-responsive, .hw-form-sidebar > .hw-stepper-responsive { grid-area: steps; }
285
+ .hw-form-layout > .hw-service-aside, .hw-form-sidebar > .hw-service-aside { grid-area: guidance; }
286
+ .hw-stepper-responsive { padding: 1.5rem 1rem; }
287
+ .hw-stepper-responsive .hw-stepper { display: none; }
288
+ .hw-stepper-mobile { display: flex; }
289
+ .hw-service-aside { padding: 1.5rem; }
290
+ .hw-portal-footer-main { grid-template-columns: repeat(2, minmax(0, 1fr)); }
291
+ }
292
+ @media (max-width: 37.499rem) {
293
+ .hw-service-container { inline-size: calc(100% - 2 * var(--hw-content-gutter-mobile, 1rem)); }
294
+ .hw-form-grid { grid-template-columns: minmax(0, 1fr); gap: 1.5rem; }
295
+ .hw-service-main { gap: 2rem; }
296
+ .hw-portal-header { padding-inline: 1rem; }
297
+ .hw-portal-header-inner { gap: 0.75rem; }
298
+ .hw-portal-header-inner > nav { order: 3; flex-basis: 100%; }
299
+ .hw-portal-header-inner > nav ul { flex-direction: column; align-items: stretch; gap: 0.25rem; }
300
+ .hw-portal-header :is(.hw-portal-header-inner, .hw-portal-header-main) > nav[data-open='false'] { display: none; }
301
+ .hw-portal-footer-main { grid-template-columns: minmax(0, 1fr); gap: 2rem; }
302
+ .hw-portal-footer-bottom { align-items: start; flex-direction: column; }
303
+ }
304
+ @media (prefers-reduced-motion: reduce) {
305
+ :is(.hw-input, .hw-textarea, .hw-select) { transition: none; }
306
+ }
307
+ @media (forced-colors: active) {
308
+ :is(.hw-input, .hw-textarea, .hw-select) { border-color: ButtonText; background-image: none; }
309
+ :is(.hw-input, .hw-textarea, .hw-select):focus { border-color: Highlight; box-shadow: none; outline: 2px solid Highlight; outline-offset: -2px; }
310
+ :is(.hw-input, .hw-textarea, .hw-select)[aria-invalid='true'] { border-style: dashed; }
311
+ :is(.hw-input, .hw-textarea, .hw-select):disabled { border-color: GrayText; color: GrayText; }
312
+ .hw-portal-footer { border-block-start: 1px solid CanvasText; }
313
+ .hw-stepper-ring::before { background: none; mask: none; border: 4px solid CanvasText; border-block-start-color: Highlight; }
314
+ .hw-stepper-responsive .hw-step::before { border-color: CanvasText; }
315
+ .hw-stepper-responsive .hw-step[aria-current='step']::before { outline: 2px solid Highlight; outline-offset: 2px; }
316
+ }
@@ -0,0 +1,14 @@
1
+ /* Resolve reading direction at the closest HTML boundary, independent of language.
2
+ The empty RTL marker enables component-specific values through var() fallbacks. */
3
+ :where([dir='ltr'], [dir='auto']) {
4
+ --_nq-inline-sign: 1;
5
+ --_nq-rtl-only: initial;
6
+ }
7
+ :where([dir='rtl']) {
8
+ --_nq-inline-sign: -1;
9
+ --_nq-rtl-only: ;
10
+ }
11
+ /* Scope roots retain the browser's first-strong-text test when CSS is minified. */
12
+ @scope ([dir='auto']:dir(rtl)) {
13
+ :scope { --_nq-inline-sign: -1; --_nq-rtl-only: ; }
14
+ }