@oslokommune/punkt-css 16.26.3 → 17.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 (75) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/dist/css/components/accordion.css +27 -5
  3. package/dist/css/components/accordion.min.css +1 -1
  4. package/dist/css/components/alert.css +37 -3
  5. package/dist/css/components/alert.min.css +1 -1
  6. package/dist/css/components/calendar.css +4 -0
  7. package/dist/css/components/calendar.min.css +1 -1
  8. package/dist/css/components/combobox.css +82 -0
  9. package/dist/css/components/combobox.min.css +1 -1
  10. package/dist/css/components/datepicker.css +82 -3
  11. package/dist/css/components/datepicker.min.css +1 -1
  12. package/dist/css/components/footer.css +232 -108
  13. package/dist/css/components/footer.min.css +1 -1
  14. package/dist/css/components/header-global.css +287 -0
  15. package/dist/css/components/header-global.min.css +1 -0
  16. package/dist/css/components/header-menu.css +364 -123
  17. package/dist/css/components/header-menu.min.css +1 -1
  18. package/dist/css/components/header-service-mobile.css +71 -22
  19. package/dist/css/components/header-service-mobile.min.css +1 -1
  20. package/dist/css/components/header-service.css +68 -14
  21. package/dist/css/components/header-service.min.css +1 -1
  22. package/dist/css/components/header-shared.css +49 -0
  23. package/dist/css/components/header-shared.min.css +0 -0
  24. package/dist/css/components/inputwrapper.css +58 -4
  25. package/dist/css/components/inputwrapper.min.css +1 -1
  26. package/dist/css/components/modal.css +0 -5
  27. package/dist/css/components/modal.min.css +1 -1
  28. package/dist/css/components/searchinput.css +71 -2
  29. package/dist/css/components/searchinput.min.css +1 -1
  30. package/dist/css/components/textarea.css +41 -0
  31. package/dist/css/components/textarea.min.css +1 -0
  32. package/dist/css/components/textinput.css +126 -6
  33. package/dist/css/components/textinput.min.css +1 -1
  34. package/dist/css/components/timepicker.css +133 -38
  35. package/dist/css/components/timepicker.min.css +1 -1
  36. package/dist/css/elements/button.css +20 -4
  37. package/dist/css/elements/button.min.css +1 -1
  38. package/dist/css/elements/checkbox-radio.css +3 -3
  39. package/dist/css/elements/checkbox-radio.min.css +1 -1
  40. package/dist/css/elements/input.css +121 -6
  41. package/dist/css/elements/input.min.css +1 -1
  42. package/dist/css/elements/select.css +137 -9
  43. package/dist/css/elements/select.min.css +1 -1
  44. package/dist/css/pkt-base.css +434 -1
  45. package/dist/css/pkt-base.min.css +1 -1
  46. package/dist/css/pkt-components.css +1595 -342
  47. package/dist/css/pkt-components.min.css +1 -1
  48. package/dist/css/pkt-docs.css +2077 -358
  49. package/dist/css/pkt-docs.min.css +1 -1
  50. package/dist/css/pkt-elements.css +160 -16
  51. package/dist/css/pkt-elements.min.css +1 -1
  52. package/dist/css/pkt.css +2077 -358
  53. package/dist/css/pkt.min.css +1 -1
  54. package/dist/scss/abstracts/variables/_index.scss +1 -1
  55. package/dist/scss/abstracts/variables/_spacing.scss +1 -0
  56. package/dist/scss/components/_accordion.scss +7 -11
  57. package/dist/scss/components/_alert.scss +34 -4
  58. package/dist/scss/components/_calendar.scss +3 -0
  59. package/dist/scss/components/_combobox.scss +74 -0
  60. package/dist/scss/components/_datepicker.scss +75 -8
  61. package/dist/scss/components/_footer.scss +149 -123
  62. package/dist/scss/components/_header-global.scss +192 -0
  63. package/dist/scss/components/_header-menu.scss +30 -31
  64. package/dist/scss/components/_header-service-mobile.scss +4 -28
  65. package/dist/scss/components/_header-service.scss +4 -21
  66. package/dist/scss/components/_header-shared.scss +190 -0
  67. package/dist/scss/components/_index.scss +2 -0
  68. package/dist/scss/components/_inputwrapper.scss +62 -6
  69. package/dist/scss/components/_modal.scss +1 -5
  70. package/dist/scss/components/_searchinput.scss +58 -2
  71. package/dist/scss/components/_textarea.scss +48 -0
  72. package/dist/scss/components/_timepicker.scss +95 -34
  73. package/dist/scss/elements/_button.scss +12 -3
  74. package/dist/scss/elements/_input.scss +141 -7
  75. package/package.json +3 -3
@@ -0,0 +1,192 @@
1
+ /*
2
+ * HeaderGlobal component
3
+ */
4
+
5
+ @use 'sass:map';
6
+ @use '../abstracts/variables';
7
+ @use '../abstracts/mixins/breakpoints' as *;
8
+ @use '../abstracts/mixins/' as *;
9
+ @use 'header-shared' as shared;
10
+
11
+ .pkt-header-global-spacer {
12
+ height: map.get(variables.$spacing, 'size-104');
13
+
14
+ &--tablet {
15
+ height: map.get(variables.$spacing, 'size-88');
16
+ }
17
+
18
+ &--mobile {
19
+ height: map.get(variables.$spacing, 'size-88');
20
+ }
21
+
22
+ &--mobile#{&}--has-user {
23
+ height: calc(#{map.get(variables.$spacing, 'size-88')} + #{map.get(variables.$spacing, 'size-56')});
24
+ }
25
+ }
26
+
27
+ .pkt-header-global {
28
+ @include shared.header-chrome;
29
+ @include shared.header-grid('pkt-header-global', map.get(variables.$spacing, 'size-88'));
30
+
31
+ &__logo-area {
32
+ align-items: center;
33
+ display: inline-flex;
34
+ padding-left: map.get(variables.$spacing, 'size-32');
35
+
36
+ .pkt-header-global--tablet & {
37
+ padding-left: map.get(variables.$spacing, 'size-16');
38
+ }
39
+
40
+ .pkt-header-global--mobile & {
41
+ padding-left: map.get(variables.$spacing, 'size-8');
42
+ }
43
+ }
44
+
45
+ &__content,
46
+ &__user {
47
+ align-items: center;
48
+ display: inline-flex;
49
+ min-width: 0;
50
+ }
51
+
52
+ &__content {
53
+ column-gap: map.get(variables.$spacing, 'size-24');
54
+
55
+ .pkt-header-global--tablet & {
56
+ column-gap: map.get(variables.$spacing, 'size-8');
57
+ }
58
+
59
+ .pkt-header-global--mobile & {
60
+ column-gap: map.get(variables.$spacing, 'size-8');
61
+ padding-right: map.get(variables.$spacing, 'size-8');
62
+ }
63
+ }
64
+
65
+ &__menu-toggle,
66
+ &__contact {
67
+ flex: 0 0 auto;
68
+ }
69
+
70
+ &__user {
71
+ justify-self: end;
72
+ padding-right: map.get(variables.$spacing, 'size-32');
73
+
74
+ .pkt-header-global--tablet:not(.pkt-header-global--mobile) & {
75
+ padding-right: map.get(variables.$spacing, 'size-16');
76
+ }
77
+ }
78
+
79
+ &__user-container {
80
+ position: relative;
81
+ flex: 0 0 auto;
82
+
83
+ &.is-open {
84
+ z-index: 100;
85
+ }
86
+ }
87
+
88
+ @include shared.header-logo(3.2rem);
89
+
90
+ &__search {
91
+ flex: 0 1 auto;
92
+ width: 22rem;
93
+ max-width: 100%;
94
+ min-width: 0;
95
+
96
+ .pkt-searchinput,
97
+ .pkt-searchinput__field {
98
+ width: 100%;
99
+ }
100
+ }
101
+
102
+ &__contact {
103
+ flex: 0 0 auto;
104
+ white-space: nowrap;
105
+ }
106
+
107
+ &__user-button {
108
+ max-width: 20rem;
109
+
110
+ .pkt-btn__text {
111
+ overflow: hidden;
112
+ text-overflow: ellipsis;
113
+ white-space: nowrap;
114
+ min-width: 0;
115
+ flex: 1 1 auto;
116
+ }
117
+ }
118
+
119
+ &__user-menu {
120
+ position: absolute;
121
+ right: 0;
122
+ width: max(15.5rem, 100%);
123
+ max-width: min(32rem, 90vw);
124
+
125
+ &.is-open {
126
+ z-index: 100;
127
+ }
128
+ }
129
+
130
+ &__search-toggle {
131
+ &,
132
+ & button {
133
+ flex: 0 0 auto;
134
+ border-radius: 50%;
135
+ }
136
+ }
137
+
138
+ &--mobile &__menu-toggle {
139
+ &,
140
+ & button {
141
+ border-radius: 50%;
142
+ }
143
+ }
144
+
145
+ &__menu,
146
+ &__search-panel {
147
+ position: fixed;
148
+ top: max(0px, calc(var(--pkt-header-global-top, 0px) + #{map.get(variables.$spacing, 'size-104')}));
149
+ left: 0;
150
+ right: 0;
151
+ bottom: 0;
152
+ z-index: 90;
153
+ background-color: rgba(0, 0, 0, 0.55);
154
+ overflow-y: auto;
155
+ overscroll-behavior: contain;
156
+ -webkit-overflow-scrolling: touch;
157
+
158
+ &--tablet,
159
+ &--mobile {
160
+ top: max(0px, calc(var(--pkt-header-global-top, 0px) + #{map.get(variables.$spacing, 'size-88')}));
161
+ }
162
+ }
163
+
164
+ &__menu .pkt-header-menu {
165
+ width: min(var(--pkt-header-global-width, 100%), 75rem);
166
+ margin: 0 0 0
167
+ calc(var(--pkt-header-global-left, 0px) + max(0px, (var(--pkt-header-global-width, 100%) - 75rem) / 2));
168
+ box-shadow:
169
+ 0px 4px 6px -1px rgba(0, 0, 0, 0.1),
170
+ 0px 2px 4px -2px rgba(0, 0, 0, 0.1);
171
+ }
172
+
173
+ &__search-panel-inner {
174
+ margin-left: var(--pkt-header-global-left, 0px);
175
+ width: var(--pkt-header-global-width, 100%);
176
+ background-color: var(--pkt-color-background-default);
177
+ border-bottom: 1px solid var(--pkt-color-border-subtle);
178
+ box-shadow:
179
+ 0px 4px 6px -1px rgba(0, 0, 0, 0.1),
180
+ 0px 2px 4px -2px rgba(0, 0, 0, 0.1);
181
+ padding: map.get(variables.$spacing, 'size-16');
182
+
183
+ .pkt-searchinput,
184
+ .pkt-searchinput__field {
185
+ width: 100%;
186
+ }
187
+ }
188
+ }
189
+
190
+ .pkt-header-global.pkt-header-global--mobile {
191
+ @include shared.header-mobile-user-bar('pkt-header-global');
192
+ }
@@ -4,18 +4,18 @@
4
4
 
5
5
  @use 'sass:map';
6
6
  @use '../abstracts/variables';
7
- @use '../abstracts/mixins/breakpoints' as *;
7
+ @use '../abstracts/mixins/container-queries' as *;
8
8
  @use '../abstracts/mixins/typography';
9
9
 
10
10
  $pkt-header-menu-breakpoint: 48rem;
11
11
 
12
12
  @mixin pkt-header-menu-region-inner {
13
- max-width: 75.25rem;
13
+ max-width: 75rem;
14
14
  margin: 0 auto;
15
15
  padding-top: map.get(variables.$spacing, 'size-32');
16
16
  padding-bottom: map.get(variables.$spacing, 'size-16');
17
17
 
18
- @include bp('tablet-up') {
18
+ @include cq('pkt-header-menu', $cq-bp-tablet) {
19
19
  padding: map.get(variables.$spacing, 'size-52');
20
20
  }
21
21
  }
@@ -25,11 +25,8 @@ $pkt-header-menu-breakpoint: 48rem;
25
25
  background-color: var(--pkt-color-background-default);
26
26
  color: var(--pkt-color-text-body-default);
27
27
  width: 100%;
28
- padding-bottom: map.get(variables.$spacing, 'size-32');
29
-
30
- @include bp('tablet-up') {
31
- padding-bottom: 0;
32
- }
28
+ container-type: inline-size;
29
+ container-name: pkt-header-menu;
33
30
 
34
31
  &--open {
35
32
  display: block;
@@ -45,11 +42,11 @@ $pkt-header-menu-breakpoint: 48rem;
45
42
  margin: 0 0 map.get(variables.$spacing, 'size-32');
46
43
  display: none;
47
44
 
48
- @include bp('tablet-up') {
45
+ @include cq('pkt-header-menu', $cq-bp-tablet) {
49
46
  display: block;
50
47
  }
51
48
 
52
- @include bp('tablet-big-up') {
49
+ @include cq('pkt-header-menu', $cq-bp-tablet-big) {
53
50
  @include typography.get-text('pkt-txt-22-medium');
54
51
  }
55
52
  }
@@ -66,7 +63,7 @@ $pkt-header-menu-breakpoint: 48rem;
66
63
  grid-template-columns: 1fr;
67
64
  gap: map.get(variables.$spacing, 'size-20');
68
65
 
69
- @include bp('tablet-up') {
66
+ @include cq('pkt-header-menu', $cq-bp-tablet) {
70
67
  grid-template-columns: repeat(4, 1fr);
71
68
  row-gap: map.get(variables.$spacing, 'size-40');
72
69
  }
@@ -76,15 +73,14 @@ $pkt-header-menu-breakpoint: 48rem;
76
73
  display: none;
77
74
 
78
75
  @include pkt-header-menu-region-inner;
79
- @include bp('tablet-up') {
76
+ @include cq('pkt-header-menu', $cq-bp-tablet) {
80
77
  display: flex;
81
78
  gap: map.get(variables.$spacing, 'size-16');
82
79
  flex-wrap: wrap;
83
80
  padding-top: 0;
84
81
  }
85
82
 
86
- // Step the button label up at the same breakpoint as the link text.
87
- @include bp('tablet-big-up') {
83
+ @include cq('pkt-header-menu', $cq-bp-tablet-big) {
88
84
  .pkt-btn__text {
89
85
  @include typography.get-text('pkt-txt-18-medium');
90
86
  }
@@ -95,13 +91,13 @@ $pkt-header-menu-breakpoint: 48rem;
95
91
  padding: 0 map.get(variables.$spacing, 'size-16');
96
92
  display: flex;
97
93
 
98
- @include bp('tablet-up') {
94
+ @include cq('pkt-header-menu', $cq-bp-tablet) {
99
95
  display: none;
100
96
  }
101
97
  }
102
98
 
103
99
  &__sections {
104
- @include bp('tablet-up') {
100
+ @include cq('pkt-header-menu', $cq-bp-tablet) {
105
101
  background-color: var(--pkt-color-surface-strong-gray);
106
102
  [data-mode='dark'] & {
107
103
  background-color: var(--pkt-color-background-default);
@@ -112,7 +108,7 @@ $pkt-header-menu-breakpoint: 48rem;
112
108
  &__sections-inner {
113
109
  @include pkt-header-menu-region-inner;
114
110
 
115
- @include bp('tablet-up') {
111
+ @include cq('pkt-header-menu', $cq-bp-tablet) {
116
112
  display: grid;
117
113
  grid-template-columns: repeat(4, 1fr);
118
114
  gap: map.get(variables.$spacing, 'size-32');
@@ -120,11 +116,9 @@ $pkt-header-menu-breakpoint: 48rem;
120
116
  }
121
117
 
122
118
  &__section {
123
- @include bp('mobile-to-tablet') {
124
- .pkt-accordion-item__title {
125
- @include typography.get-text('pkt-txt-18-medium');
126
- padding: map.get(variables.$spacing, 'size-16') 0;
127
- }
119
+ .pkt-accordion-item__title {
120
+ @include typography.get-text('pkt-txt-18-medium');
121
+ padding: map.get(variables.$spacing, 'size-8') map.get(variables.$spacing, 'size-16');
128
122
  }
129
123
  }
130
124
 
@@ -135,7 +129,7 @@ $pkt-header-menu-breakpoint: 48rem;
135
129
  display: flex;
136
130
  flex-direction: column;
137
131
  gap: map.get(variables.$spacing, 'size-16');
138
- @include bp('tablet-up') {
132
+ @include cq('pkt-header-menu', $cq-bp-tablet) {
139
133
  row-gap: map.get(variables.$spacing, 'size-16');
140
134
  }
141
135
  }
@@ -148,7 +142,7 @@ $pkt-header-menu-breakpoint: 48rem;
148
142
  text-underline-position: from-font;
149
143
  line-height: 1.5;
150
144
 
151
- @include bp('tablet-big-up') {
145
+ @include cq('pkt-header-menu', $cq-bp-tablet-big) {
152
146
  @include typography.get-text('pkt-txt-18-light');
153
147
  }
154
148
 
@@ -171,7 +165,7 @@ $pkt-header-menu-breakpoint: 48rem;
171
165
 
172
166
  @include typography.get-text('pkt-txt-16-light');
173
167
 
174
- @include bp('tablet-big-up') {
168
+ @include cq('pkt-header-menu', $cq-bp-tablet-big) {
175
169
  @include typography.get-text('pkt-txt-18-light');
176
170
  }
177
171
 
@@ -190,7 +184,7 @@ $pkt-header-menu-breakpoint: 48rem;
190
184
  width: map.get(variables.$spacing, 'size-24');
191
185
  height: map.get(variables.$spacing, 'size-24');
192
186
 
193
- @include bp('tablet-up') {
187
+ @include cq('pkt-header-menu', $cq-bp-tablet) {
194
188
  width: map.get(variables.$spacing, 'size-32');
195
189
  height: map.get(variables.$spacing, 'size-32');
196
190
  }
@@ -208,12 +202,12 @@ $pkt-header-menu-breakpoint: 48rem;
208
202
  &__footer {
209
203
  @include pkt-header-menu-region-inner;
210
204
  padding: map.get(variables.$spacing, 'size-24') map.get(variables.$spacing, 'size-16')
211
- map.get(variables.$spacing, 'size-16');
205
+ map.get(variables.$spacing, 'size-48');
212
206
  display: flex;
213
207
  flex-direction: column;
214
208
  gap: map.get(variables.$spacing, 'size-24');
215
209
 
216
- @include bp('tablet-up') {
210
+ @include cq('pkt-header-menu', $cq-bp-tablet) {
217
211
  flex-direction: row;
218
212
  justify-content: space-between;
219
213
  align-items: center;
@@ -229,7 +223,7 @@ $pkt-header-menu-breakpoint: 48rem;
229
223
  flex-direction: column;
230
224
  gap: map.get(variables.$spacing, 'size-12');
231
225
 
232
- @include bp('tablet-up') {
226
+ @include cq('pkt-header-menu', $cq-bp-tablet) {
233
227
  flex-direction: row;
234
228
  gap: map.get(variables.$spacing, 'size-0');
235
229
  &:not(.pkt-header-menu__footer-list--social) {
@@ -253,7 +247,7 @@ $pkt-header-menu-breakpoint: 48rem;
253
247
  flex-direction: row;
254
248
  gap: map.get(variables.$spacing, 'size-16');
255
249
 
256
- @include bp('tablet-up') {
250
+ @include cq('pkt-header-menu', $cq-bp-tablet) {
257
251
  gap: map.get(variables.$spacing, 'size-32');
258
252
  }
259
253
  }
@@ -263,7 +257,7 @@ $pkt-header-menu-breakpoint: 48rem;
263
257
  color: var(--pkt-color-text-body-default);
264
258
  text-decoration: none;
265
259
 
266
- @include bp('tablet-big-up') {
260
+ @include cq('pkt-header-menu', $cq-bp-tablet-big) {
267
261
  @include typography.get-text('pkt-txt-18-light');
268
262
  }
269
263
 
@@ -291,5 +285,10 @@ $pkt-header-menu-breakpoint: 48rem;
291
285
  @include pkt-header-menu-region-inner;
292
286
  text-align: center;
293
287
  color: var(--pkt-color-text-body-default);
288
+ padding-bottom: map.get(variables.$spacing, 'size-48');
289
+
290
+ @include cq('pkt-header-menu', $cq-bp-tablet) {
291
+ padding-bottom: map.get(variables.$spacing, 'size-52');
292
+ }
294
293
  }
295
294
  }
@@ -2,6 +2,7 @@
2
2
  @use '../abstracts/variables';
3
3
  @use '../abstracts/mixins/breakpoints' as *;
4
4
  @use '../abstracts/mixins/' as *;
5
+ @use 'header-shared' as shared;
5
6
 
6
7
  .pkt-header-service.pkt-header-service--mobile {
7
8
  grid-template-rows: map.get(variables.$spacing, 'size-64') auto;
@@ -11,6 +12,9 @@
11
12
  grid-template-rows: map.get(variables.$spacing, 'size-72') auto;
12
13
  }
13
14
 
15
+ // Full-width user bar + in-flow user menu (shared with the global header).
16
+ @include shared.header-mobile-user-bar('pkt-header-service');
17
+
14
18
  .pkt-header-service {
15
19
  &--compact {
16
20
  grid-template-rows: map.get(variables.$spacing, 'size-64') auto;
@@ -54,34 +58,6 @@
54
58
  background-color: var(--pkt-color-background-default);
55
59
  }
56
60
 
57
- &__user-container {
58
- background-color: var(--pkt-color-background-default);
59
- height: map.get(variables.$spacing, 'size-56');
60
- width: 100%;
61
- z-index: 99;
62
- }
63
-
64
- &__user-button {
65
- &:is(button),
66
- & button {
67
- height: 100%;
68
- padding: 0 map.get(variables.$spacing, 'size-24');
69
- width: 100%;
70
- max-width: 100%;
71
- border: none;
72
- border-top: 1px solid var(--pkt-color-border-subtle, #f2f2f2);
73
- border-bottom: 1px solid var(--pkt-color-border-subtle, #f2f2f2);
74
- }
75
- &:not(button) {
76
- display: contents;
77
- }
78
- }
79
-
80
- &__user-menu {
81
- max-width: 100%;
82
- position: unset;
83
- }
84
-
85
61
  &__slot-content {
86
62
  display: none;
87
63
  }
@@ -23,6 +23,7 @@
23
23
  @use '../abstracts/variables';
24
24
  @use '../abstracts/mixins/breakpoints' as *;
25
25
  @use '../abstracts/mixins/' as *;
26
+ @use 'header-shared' as shared;
26
27
 
27
28
  .pkt-header-service-spacer {
28
29
  height: map.get(variables.$spacing, 'size-104');
@@ -95,10 +96,8 @@
95
96
  }
96
97
  }
97
98
 
98
- position: relative;
99
- z-index: 10;
100
- background-color: var(--pkt-color-background-default);
101
- border-bottom: 1px solid var(--pkt-color-border-subtle);
99
+ @include shared.header-chrome;
100
+
102
101
  display: grid;
103
102
  align-items: center;
104
103
  grid-template-columns: 1fr auto auto;
@@ -119,22 +118,6 @@
119
118
  grid-template-rows: map.get(variables.$spacing, 'size-72') auto;
120
119
  }
121
120
 
122
- &--fixed {
123
- width: 100vw;
124
- position: fixed;
125
- top: 0;
126
- left: 0;
127
- }
128
-
129
- &--scroll-to-hide {
130
- transform: translate3d(0, 0, 0);
131
- transition: 0.5s transform ease-in-out;
132
- }
133
-
134
- &--hidden {
135
- transform: translate3d(0, -100%, 0);
136
- }
137
-
138
121
  &__logo-area,
139
122
  &__content,
140
123
  &__user {
@@ -311,7 +294,7 @@
311
294
  }
312
295
 
313
296
  &__user-button {
314
- max-width: 28.5rem;
297
+ max-width: 22.5rem;
315
298
 
316
299
  .pkt-btn__text {
317
300
  overflow: hidden;
@@ -0,0 +1,190 @@
1
+ /*
2
+ * Shared header patterns
3
+ *
4
+ * Mixins shared by the header variants (`pkt-header-service` and
5
+ * `pkt-header-global`). The service header is the source of truth — these
6
+ * mixins are extracted from it so the global header stays aligned.
7
+ *
8
+ * This file only defines mixins; it emits no CSS on its own and therefore
9
+ * is not `@forward`ed from the component index.
10
+ */
11
+
12
+ @use 'sass:map';
13
+ @use '../abstracts/variables';
14
+
15
+ /**
16
+ * Header chrome shared by every variant: base positioning plus the
17
+ * `--fixed`, `--sticky`, `--scroll-to-hide` and `--hidden` modifier states.
18
+ *
19
+ * Call inside a header base block; `&` resolves to the calling class
20
+ * (`.pkt-header-service` or `.pkt-header-global`).
21
+ */
22
+ @mixin header-chrome {
23
+ position: relative;
24
+ z-index: 10;
25
+ background-color: var(--pkt-color-background-default);
26
+ border-bottom: 1px solid var(--pkt-color-border-subtle);
27
+
28
+ &--fixed {
29
+ width: 100vw;
30
+ position: fixed;
31
+ top: 0;
32
+ left: 0;
33
+ }
34
+
35
+ // Stays in the document flow (no spacer needed) but pins to the top of the
36
+ // viewport while its container is scrolled past.
37
+ &--sticky {
38
+ position: sticky;
39
+ top: 0;
40
+ }
41
+
42
+ &--scroll-to-hide {
43
+ transform: translate3d(0, 0, 0);
44
+ transition: 0.5s transform ease-in-out;
45
+ }
46
+
47
+ &--hidden {
48
+ transform: translate3d(0, -100%, 0);
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Mobile user area shared by every variant: on small screens the user
54
+ * button becomes a full-width bar with top/bottom borders and the user
55
+ * menu renders in flow directly below it (rather than as a floating
56
+ * dropdown). Placement of the user area into its own row is left to the
57
+ * caller (grid row for the service header, a flex row for the global
58
+ * header).
59
+ *
60
+ * `$base` is the variant's BEM block, e.g. `pkt-header-service`.
61
+ */
62
+ /**
63
+ * Shared header grid. Logo (col 1), a flexible content cell (col 2,
64
+ * right-aligned) and the user cell (col 3). Row height follows
65
+ * `--pkt-header-height`, which steps down at the tablet and mobile
66
+ * breakpoints. On mobile the grid collapses to two columns and the user
67
+ * cell drops to a full-width second row — the same layout the service
68
+ * header uses.
69
+ *
70
+ * Call inside a header base block. `$base` is the variant's BEM block.
71
+ * `$mobile-height` lets a variant keep a taller bar on mobile (the service
72
+ * header drops to 64px, the global header stays at 88px).
73
+ */
74
+ @mixin header-grid($base, $mobile-height: map.get(variables.$spacing, 'size-64')) {
75
+ --pkt-header-height: #{map.get(variables.$spacing, 'size-104')};
76
+
77
+ &--tablet {
78
+ --pkt-header-height: #{map.get(variables.$spacing, 'size-88')};
79
+ }
80
+
81
+ &--mobile {
82
+ --pkt-header-height: #{$mobile-height};
83
+ }
84
+
85
+ display: grid;
86
+ align-items: center;
87
+ grid-template-columns: auto minmax(0, 1fr) auto;
88
+ grid-template-rows: var(--pkt-header-height) auto;
89
+ column-gap: map.get(variables.$spacing, 'size-24');
90
+
91
+ &--tablet {
92
+ column-gap: map.get(variables.$spacing, 'size-16');
93
+ }
94
+
95
+ &--mobile {
96
+ grid-template-columns: auto minmax(0, 1fr);
97
+ column-gap: map.get(variables.$spacing, 'size-8');
98
+ }
99
+
100
+ &__logo-area {
101
+ grid-column: 1;
102
+ grid-row: 1;
103
+ }
104
+
105
+ &__content {
106
+ grid-column: 2;
107
+ grid-row: 1;
108
+ justify-self: end;
109
+ max-width: 100%;
110
+ }
111
+
112
+ &__user {
113
+ grid-column: 3;
114
+ grid-row: 1;
115
+ }
116
+
117
+ // On mobile the user cell drops to its own full-width row below the bar.
118
+ &--mobile {
119
+ .#{$base}__user {
120
+ grid-column: 1 / -1;
121
+ grid-row: 2;
122
+ justify-self: stretch;
123
+ padding: 0;
124
+ }
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Standalone Oslo logo sizing shared by header variants: 64px on
130
+ * desktop/tablet, shrinking to 32px on mobile (the same sizes the service
131
+ * header uses for its logo without a service name).
132
+ *
133
+ * Call inside a header base block; `&` resolves to the calling class.
134
+ * `$mobile-height` is the logo height on mobile (the service header drops to
135
+ * 32px, the global header to 3.2rem).
136
+ */
137
+ @mixin header-logo($mobile-height: map.get(variables.$spacing, 'size-32')) {
138
+ &__logo {
139
+ --fg-color: var(--pkt-color-text-body-default);
140
+ flex: 0 0 auto;
141
+ display: flex;
142
+ align-items: center;
143
+
144
+ a,
145
+ button {
146
+ display: flex;
147
+ align-items: center;
148
+ }
149
+
150
+ svg {
151
+ aspect-ratio: 6 / 3;
152
+ height: map.get(variables.$spacing, 'size-64');
153
+ }
154
+ }
155
+
156
+ &--mobile &__logo svg {
157
+ height: #{$mobile-height};
158
+ }
159
+ }
160
+
161
+ @mixin header-mobile-user-bar($base) {
162
+ .#{$base}__user-container {
163
+ background-color: var(--pkt-color-background-default);
164
+ height: map.get(variables.$spacing, 'size-56');
165
+ width: 100%;
166
+ z-index: 99;
167
+ }
168
+
169
+ .#{$base}__user-button {
170
+ &:is(button),
171
+ & button {
172
+ height: 100%;
173
+ padding: 0 map.get(variables.$spacing, 'size-24');
174
+ width: 100%;
175
+ max-width: 100%;
176
+ border: none;
177
+ border-top: 1px solid var(--pkt-color-border-subtle, #f2f2f2);
178
+ border-bottom: 1px solid var(--pkt-color-border-subtle, #f2f2f2);
179
+ }
180
+
181
+ &:not(button) {
182
+ display: contents;
183
+ }
184
+ }
185
+
186
+ .#{$base}__user-menu {
187
+ max-width: 100%;
188
+ position: unset;
189
+ }
190
+ }
@@ -11,6 +11,7 @@
11
11
  @forward 'fileupload';
12
12
  @forward 'footer';
13
13
  @forward 'header';
14
+ @forward 'header-global';
14
15
  @forward 'header-menu';
15
16
  @forward 'header-service';
16
17
  @forward 'header-service-mobile';
@@ -33,4 +34,5 @@
33
34
  @forward 'tag';
34
35
  @forward 'teaserlist';
35
36
  @forward 'textinput';
37
+ @forward 'textarea';
36
38
  @forward 'timepicker';