maverick-wave 5.22.0 → 5.23.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.
@@ -0,0 +1,29 @@
1
+ @use '../abstracts' as *;
2
+
3
+ @layer mw.components {
4
+ // The block that says how to reach someone - postal address, phone, mail.
5
+ // Belongs on an <address>, which is what the one font-style is for: the
6
+ // element is italic by default, and nobody sets an address in italics.
7
+ .mw-contact {
8
+ font-style: normal;
9
+ display: grid;
10
+ gap: spacing('3');
11
+
12
+ > * {
13
+ margin: 0;
14
+ }
15
+
16
+ &-row {
17
+ display: flex;
18
+ flex-wrap: wrap;
19
+ gap: spacing('1') spacing('4');
20
+ }
21
+
22
+ // Sized rather than auto, so the values line up under each other however
23
+ // long the words in front of them are
24
+ &-label {
25
+ flex: 0 0 5rem;
26
+ color: var(--mw-text-muted-color);
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,141 @@
1
+ @use '../abstracts' as *;
2
+
3
+ @layer mw.components {
4
+ // Every fluid value here runs the same ramp: from the width the two-column
5
+ // layout starts at to the width a day card stops growing at. Against the
6
+ // container, not the viewport - the layout switch below is a container query,
7
+ // and sizing off vw would hand a narrow card in a wide window the
8
+ // measurements of a wide one.
9
+ @function _stamp-ramp($min, $max) {
10
+ @return fluid-container($min, $max, $mw-card-wide, 900px);
11
+ }
12
+
13
+ // Named because the today fill cancels the paddings to reach the card border,
14
+ // and the price variant repeats the track list - two copies would drift apart.
15
+ $_mw-date-stamp-pad-top: _stamp-ramp(spacing('4'), spacing('6'));
16
+ $_mw-date-stamp-pad-bottom: _stamp-ramp(spacing('3'), spacing('5'));
17
+ $_mw-date-stamp-day-col: _stamp-ramp(4.25rem, 7rem);
18
+ $_mw-date-stamp-gap: _stamp-ramp(spacing('4'), spacing('7'));
19
+ $_mw-date-stamp-day-size: _stamp-ramp('xl', '3xl');
20
+
21
+ // The date on a dated card - an event, a changelog entry, a day on a menu.
22
+ // Narrow, it is a line above the title. Wide, it turns into a column beside
23
+ // the content, which is the only thing that fills the right half of a card
24
+ // that has a whole row to itself.
25
+ .mw-date-stamp {
26
+ display: flex;
27
+ align-items: baseline;
28
+ gap: spacing('3');
29
+ margin-bottom: spacing('4');
30
+ color: var(--mw-text-muted-color);
31
+
32
+ &-day {
33
+ font-size: font-size('sm');
34
+ font-weight: font-weight('bold');
35
+ text-transform: uppercase;
36
+ letter-spacing: 0.08em;
37
+ }
38
+
39
+ &-date {
40
+ font-size: font-size('sm');
41
+ font-variant-numeric: tabular-nums;
42
+ }
43
+
44
+ // A fill, not a text colour: the price on the same card is already primary,
45
+ // and two blues compete where one would point. The padding is pulled back
46
+ // out again so the fill bleeds around the line instead of indenting it.
47
+ &-today {
48
+ padding: spacing('2') spacing('3');
49
+ margin-inline: spacing('-3');
50
+ margin-block-start: spacing('-2');
51
+ border-radius: radius('sm') radius('lg') radius('sm') radius('lg');
52
+ background: var(--mw-primary-color);
53
+ color: var(--mw-primary-accent-text-color);
54
+ }
55
+ }
56
+
57
+ // No box of its own until there are two columns to be one of, so the card body
58
+ // keeps seeing the title, the text and the price as its own children - which
59
+ // is what mw-offer and mw-card-body's last-child rule both select on
60
+ .mw-date-stamp-body {
61
+ display: contents;
62
+ }
63
+
64
+ @container mw-card (width >= #{$mw-card-wide}) {
65
+ // The rule sits here and not in _cards.scss because the stamp is the guest -
66
+ // the card body's own single column is right for everything that is not one
67
+ .mw-card-body:has(> .mw-date-stamp) {
68
+ display: grid;
69
+ grid-template-columns: $_mw-date-stamp-day-col minmax(0, 1fr);
70
+ // On the same curve as the column, so the dish keeps the width the day
71
+ // and the price give up rather than losing it again to the gutters
72
+ column-gap: $_mw-date-stamp-gap;
73
+ padding-block: $_mw-date-stamp-pad-top $_mw-date-stamp-pad-bottom;
74
+ }
75
+
76
+ // A third track, for the one price that covers the whole day - it is what the
77
+ // right half of a wide card is otherwise spent on. Only when there is a
78
+ // price: with a dish per row it travels with its dish, and an empty track
79
+ // would still charge the card a gap.
80
+ .mw-card-body:has(> .mw-date-stamp):has(> .mw-price) {
81
+ grid-template-columns: $_mw-date-stamp-day-col minmax(0, 1fr) auto;
82
+ }
83
+
84
+ // The row is left to stretch to the body, so a today fill can span the whole
85
+ // card - which means each column has to centre its own content instead
86
+ .mw-date-stamp-body {
87
+ display: flex;
88
+ flex-direction: column;
89
+ justify-content: center;
90
+ }
91
+
92
+ // The card body zeroes its own last child, but the wrapper hides ours from
93
+ // that rule - without this a trailing tag row adds a paragraph margin
94
+ .mw-date-stamp-body > *:last-child {
95
+ margin-bottom: spacing('0');
96
+ }
97
+
98
+ // Beside the dish it prices, not under the description that follows it. The
99
+ // second selector only exists to outrank mw-offer, which pushes a price to
100
+ // the bottom of the card and ties with the first on specificity alone.
101
+ .mw-card-body:has(> .mw-date-stamp) > .mw-price,
102
+ .mw-offer > .mw-card-body:has(> .mw-date-stamp) > .mw-price {
103
+ align-self: center;
104
+ justify-self: end;
105
+ margin-top: spacing('0');
106
+ padding-top: spacing('0');
107
+ text-align: right;
108
+ }
109
+
110
+ .mw-date-stamp {
111
+ flex-direction: column;
112
+ align-items: flex-start;
113
+ // Stretched to the row, so the day and the date centre against the title
114
+ // and description beside them rather than hanging off the first line
115
+ justify-content: center;
116
+ gap: spacing('2');
117
+ margin-bottom: spacing('0');
118
+ }
119
+
120
+ // Top edge of the card to its bottom one: the body's padding is handed back
121
+ // so the fill reaches the border. Only the two left corners are rounded, and
122
+ // to the card's own arc less the 1px it sits inside - the right edge is an
123
+ // inside edge and a cut is what reads as one.
124
+ .mw-date-stamp-today {
125
+ margin-block: calc(-1 * #{$_mw-date-stamp-pad-top})
126
+ calc(-1 * #{$_mw-date-stamp-pad-bottom});
127
+ margin-inline: calc(-1 * #{spacing('5')}) 0;
128
+ padding-block: $_mw-date-stamp-pad-top $_mw-date-stamp-pad-bottom;
129
+ padding-inline: spacing('5');
130
+ border-radius: calc(#{radius-sharp()} - 1px) 0 0
131
+ calc(#{radius('xl')} - 1px);
132
+ }
133
+
134
+ .mw-date-stamp-day {
135
+ // Tracks the column it sits in, or it would outgrow it on the way down
136
+ font-size: $_mw-date-stamp-day-size;
137
+ line-height: 1;
138
+ letter-spacing: 0.02em;
139
+ }
140
+ }
141
+ }
@@ -11,7 +11,9 @@
11
11
  @forward 'cards';
12
12
  @forward 'code';
13
13
  @forward 'coming-soon';
14
+ @forward 'contact';
14
15
  @forward 'content-slider';
16
+ @forward 'date-stamp';
15
17
  @forward 'divider';
16
18
  @forward 'dropdown';
17
19
  @forward 'empty-state';
@@ -21,6 +23,7 @@
21
23
  @forward 'kanban';
22
24
  @forward 'kbd';
23
25
  @forward 'lang-switch';
26
+ @forward 'leader-row';
24
27
  @forward 'links';
25
28
  @forward 'lists';
26
29
  @forward 'localhost-indicator';
@@ -0,0 +1,89 @@
1
+ @use '../abstracts' as *;
2
+
3
+ @layer mw.components {
4
+ // Dots on the baseline, not under the descenders; em so they follow font-size
5
+ $_mw-leader-baseline-lift: 0.34em;
6
+
7
+ // A label on the left, its value on the right, a dotted line bridging the
8
+ // gap. The line is the whole point: over a wide row the eye loses track of
9
+ // which value belongs to which label, which is why every printed menu, index
10
+ // and invoice draws one.
11
+ //
12
+ // The leader is the row's own ::before rather than an element in the markup.
13
+ // A generated box on a flex container is a flex item, so "order" can place it
14
+ // between the two spans - and generated content stays out of the
15
+ // accessibility tree, where a filler element would need aria-hidden.
16
+ .mw-leader-row {
17
+ --mw-leader-row-style: dotted;
18
+ --mw-leader-row-width: 2px;
19
+ --mw-leader-row-color: var(--mw-border);
20
+
21
+ display: flex;
22
+ // The values never shrink, so without a wrap the label is the only thing
23
+ // left to give - and it gives until it is one letter per line
24
+ flex-wrap: wrap;
25
+ align-items: flex-end;
26
+ gap: spacing('3');
27
+ margin: 0;
28
+
29
+ &::before {
30
+ content: '';
31
+ order: 1;
32
+ flex: 1 1 auto;
33
+ // Keeps a stub of line visible when label and value nearly fill the row
34
+ min-width: spacing('6');
35
+ border-bottom: var(--mw-leader-row-width) var(--mw-leader-row-style)
36
+ var(--mw-leader-row-color);
37
+ margin-bottom: $_mw-leader-baseline-lift;
38
+ }
39
+
40
+ &-label {
41
+ order: 0;
42
+ // No min-width override: the default floor is the longest word, so the
43
+ // label wraps between words and stops there instead of going to nothing.
44
+ // Past that floor the row wraps rather than the label shrinking further.
45
+ //
46
+ // The row also works as a dl group, and a dd carries 40px of browser margin
47
+ margin: 0;
48
+ }
49
+
50
+ &-value {
51
+ order: 2;
52
+ flex-shrink: 0;
53
+ margin: 0;
54
+ // A price or a page number must not break, and a column of them only
55
+ // lines up with tabular figures.
56
+ white-space: nowrap;
57
+ font-variant-numeric: tabular-nums;
58
+ }
59
+
60
+ // Two values in one row read as a single long range with only a gap between
61
+ // them. The mark takes the leader's colour, so retuning a row moves both.
62
+ // It hangs off the first of the pair, not the second: once the row wraps, a
63
+ // trailing mark reads as "continues below" and a leading one as a slip.
64
+ &-value:has(+ &-value)::after {
65
+ content: '|';
66
+ margin-left: spacing('3');
67
+ color: var(--mw-leader-row-color);
68
+ }
69
+
70
+ &-dashed {
71
+ --mw-leader-row-style: dashed;
72
+ }
73
+
74
+ &-solid {
75
+ --mw-leader-row-style: solid;
76
+ --mw-leader-row-width: 1px;
77
+ }
78
+
79
+ &-top {
80
+ align-items: flex-start;
81
+
82
+ &::before {
83
+ // flex-start pins the leader to the top edge, so it drops to the first
84
+ // line's baseline itself instead of being lifted off the last one
85
+ margin: calc(1lh - #{$_mw-leader-baseline-lift}) 0 0;
86
+ }
87
+ }
88
+ }
89
+ }
@@ -91,6 +91,10 @@
91
91
  }
92
92
 
93
93
  // Size. Only the token moves - see the `em` above.
94
+ .mw-price-xs {
95
+ --mw-price-size: #{font-size('lg')};
96
+ }
97
+
94
98
  .mw-price-sm {
95
99
  --mw-price-size: #{font-size('xl')};
96
100
  }
@@ -159,6 +159,12 @@ $_column-steps-lg: (
159
159
  grid-template-columns: repeat(auto-fill, minmax(min(350px, 100%), 1fr));
160
160
  }
161
161
 
162
+ // Every row as tall as the tallest rather than as tall as its own contents.
163
+ // A modifier, not a grid of its own - it needs one of the above to size.
164
+ .mw-grid-even {
165
+ grid-auto-rows: 1fr;
166
+ }
167
+
162
168
  .mw-grid-lg {
163
169
  @extend %grid-base-lg;
164
170
  }
@@ -10,6 +10,22 @@
10
10
  flex-direction: column;
11
11
  }
12
12
 
13
+ // Set in from the container it sits in, and giving that back a step at a time
14
+ // as the screen shrinks. For a column of full-width cards, which at 1200px
15
+ // leaves more empty card than content.
16
+ .mw-container-narrow {
17
+ width: 80%;
18
+ margin-inline: auto;
19
+
20
+ @include media-down('lg') {
21
+ width: 90%;
22
+ }
23
+
24
+ @include media-down('md') {
25
+ width: 100%;
26
+ }
27
+ }
28
+
13
29
  .mw-container {
14
30
  width: var(--mw-container-width);
15
31
  margin: spacing('0') auto;