@nok-integration/storefront-react 0.17.1 → 0.18.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.
@@ -32,18 +32,41 @@
32
32
  --type-heading-lg-size: 24px;
33
33
  --type-heading-lg-line: 1.2;
34
34
  --type-heading-md-size: 20px;
35
- --type-heading-sm-size: 20px;
36
35
  --type-heading-md-line: 1.25;
36
+ /* `size/heading/sm` + `heading/sm-bold`. This used to read 20px, which is the
37
+ library's heading/md — the two components that want it (the PDP's "Why us" tiles
38
+ and the size guide's "How to measure") both wrote 18 out by hand to work around
39
+ it, and nothing else consumes it. */
40
+ --type-heading-sm-size: 18px;
41
+ --type-heading-sm-line: 1.38;
37
42
  --type-paragraph-size: 16px;
38
43
  --type-paragraph-line: 1.55;
44
+ /*
45
+ * The `trimmed` family is `text-box-trim: trim-both` with a cap-alphabetic edge, which
46
+ * is how nearly every small text layer in this design is drawn. Figma's box therefore
47
+ * stops at the CAP height and a CSS line box does not, so these carry the cap in pixels
48
+ * rather than a ratio: 16px DAZN Oscine caps at 11, 14px at 10, 12px at 9. Rounded by
49
+ * the designer, which is why they are not one ratio.
50
+ *
51
+ * They were all `1` — the right idea, approximated, and 5px out on every 16px label. On
52
+ * the PDP that was the "Color: White" header and the "Size" header, and it compounded:
53
+ * measured at 375, the colour block came out 142 against the frame's 128.
54
+ *
55
+ * Glyphs deliberately overflow a box this short, exactly as they do in Figma. Anything
56
+ * that CLIPS (`overflow: hidden`, for an ellipsis or a line clamp) must add the
57
+ * padding/negative-margin pair — see `CartLineItem.title` and `ProductTile.title` — or
58
+ * it beheads the descenders. `text-box-trim` itself would let us write the design's
59
+ * numbers directly; it is Chrome 133+ and this package still supports the WebView
60
+ * DAZN's React 16 build ships with.
61
+ */
39
62
  --type-trimmed-md-size: 16px;
40
- --type-trimmed-md-line: 1;
63
+ --type-trimmed-md-line: 11px;
41
64
  --type-trimmed-sm-size: 14px;
42
- --type-trimmed-sm-line: 1;
65
+ --type-trimmed-sm-line: 10px;
43
66
  --type-caption-sm-size: 14px;
44
67
  --type-caption-sm-line: 1.5;
45
68
  --type-trimmed-xs-size: 12px;
46
- --type-trimmed-xs-line: 1;
69
+ --type-trimmed-xs-line: 9px;
47
70
 
48
71
  /* ── Colour ───────────────────────────────────────────────────────────── */
49
72
  --color-text-default: #0c161c;
@@ -56,6 +79,13 @@
56
79
  --color-border-default, but a separate token in DAZN's library; keep them separate. */
57
80
  --color-surface-subtle: #dddedf;
58
81
  --color-surface-max: #080e12;
82
+ /* semantic/base/surface/full-color/neutral — the selected half of a segmented
83
+ control and the close disc on a sheet header. `full-color`, so it is the same
84
+ value in both palettes and is not remapped below. */
85
+ --color-surface-neutral: #ced0d2;
86
+ /* semantic/base/surface/bold — the sheet handle, and the ground of a disabled
87
+ `mobile/button`. Static, like the neutral above it. */
88
+ --color-surface-bold: #6d7377;
59
89
  --color-border-default: #dddedf;
60
90
  --color-border-subtle: #ced0d2;
61
91
  /* semantic/base/border/transparent/soft. Alpha rather than a flat grey on purpose: it
@@ -213,7 +243,7 @@
213
243
  background: var(--color-surface-max);
214
244
  color: var(--color-text-strong);
215
245
  }
216
- ._button_tdhm8_1 {
246
+ ._button_1u2uh_1 {
217
247
  display: inline-flex;
218
248
  align-items: center;
219
249
  justify-content: center;
@@ -237,33 +267,54 @@
237
267
  -webkit-tap-highlight-color: transparent;
238
268
  }
239
269
 
240
- ._fullWidth_tdhm8_25 {
270
+ ._fullWidth_1u2uh_25 {
241
271
  width: 100%;
242
272
  }
243
273
 
244
- ._primary_tdhm8_29 {
274
+ ._primary_1u2uh_29 {
245
275
  background: var(--color-surface-max);
246
276
  color: var(--color-text-strong);
247
277
  }
248
278
 
249
- ._secondary_tdhm8_34 {
279
+ ._secondary_1u2uh_34 {
250
280
  background: transparent;
251
281
  color: var(--color-text-default);
252
282
  border-color: var(--color-border-default);
253
283
  }
254
284
 
255
- ._ghost_tdhm8_40 {
285
+ ._ghost_1u2uh_40 {
256
286
  background: transparent;
257
287
  color: var(--color-text-default);
258
288
  border-color: transparent;
259
289
  }
260
290
 
261
- ._button_tdhm8_1:disabled {
291
+ ._button_1u2uh_1:disabled {
262
292
  cursor: not-allowed;
293
+ }
294
+
295
+ /*
296
+ * Figma `mobile/button` state=disabled: a solid `surface/bold` ground with `text/disabled`
297
+ * on it — NOT the filled button at half strength, which is what this used to be.
298
+ *
299
+ * The difference is visible wherever a form gates its own CTA, and the new cancel and
300
+ * return sheets both open in that state, so it is the first thing drawn on either screen.
301
+ * Half-opacity black over white renders a washed grey that changes with whatever is behind
302
+ * it; the design's is one colour that does not.
303
+ *
304
+ * Only the filled variant. `secondary` and `ghost` are outlines rather than grounds, and
305
+ * the DS does not draw a filled disabled state for either — they keep the dimming.
306
+ */
307
+ ._primary_1u2uh_29:disabled {
308
+ background: var(--color-surface-bold);
309
+ color: var(--color-text-disabled);
310
+ }
311
+
312
+ ._secondary_1u2uh_34:disabled,
313
+ ._ghost_1u2uh_40:disabled {
263
314
  opacity: 0.5;
264
315
  }
265
316
 
266
- ._button_tdhm8_1:focus-visible {
317
+ ._button_1u2uh_1:focus-visible {
267
318
  outline: 2px solid var(--color-surface-max);
268
319
  outline-offset: 2px;
269
320
  }
@@ -274,17 +325,17 @@
274
325
  * cta-bar's own note said "annotate in build" — so it was drawn at 16px and the label
275
326
  * was dimmed to carry the busy signal. It has one now, and the spinner carries it alone.
276
327
  */
277
- ._spinner_tdhm8_62 {
328
+ ._spinner_1u2uh_83 {
278
329
  width: 20px;
279
330
  height: 20px;
280
331
  margin: 2px;
281
332
  border-radius: var(--radius-full);
282
333
  border: 2px solid currentColor;
283
334
  border-top-color: transparent;
284
- animation: _spin_tdhm8_62 700ms linear infinite;
335
+ animation: _spin_1u2uh_83 700ms linear infinite;
285
336
  }
286
337
 
287
- @keyframes _spin_tdhm8_62 {
338
+ @keyframes _spin_1u2uh_83 {
288
339
  to {
289
340
  transform: rotate(360deg);
290
341
  }
@@ -491,40 +542,55 @@
491
542
  ._action_ney0g_57 {
492
543
  margin: var(--space-8) var(--space-16) 0;
493
544
  }
494
- ._root_1u83t_1 {
545
+ /*
546
+ * The design's shared empty state, instanced by the cart (Figma 4451:48190) and the orders
547
+ * list (4551:32238). Both frames draw the same block: a 24px heading, a paragraph 6px
548
+ * under it, and the action 24 below the pair.
549
+ */
550
+ ._root_ryf3q_6 {
495
551
  display: flex;
496
552
  flex-direction: column;
497
553
  align-items: center;
498
554
  text-align: center;
499
- gap: var(--space-8);
555
+ gap: var(--space-24);
500
556
  padding: var(--space-32) var(--space-24);
501
557
  }
502
558
 
503
- ._icon_1u83t_10 {
559
+ ._icon_ryf3q_15 {
504
560
  font-size: 32px;
505
561
  line-height: 1;
506
562
  }
507
563
 
508
- ._title_1u83t_15 {
509
- font-size: var(--type-heading-md-size);
510
- line-height: var(--type-heading-md-line);
564
+ /* The heading and the paragraph, 6px apart — `spacer/spacer-xxs`. */
565
+ ._text_ryf3q_21 {
566
+ display: flex;
567
+ flex-direction: column;
568
+ gap: var(--space-6);
569
+ }
570
+
571
+ /*
572
+ * `heading/lg`, 24px, and the 1.32 the design system gives it rather than
573
+ * `--type-heading-lg-line`. That token is 1.2, which is a divergence of its own on every
574
+ * screen that reads it; correcting it there moves the PDP title, the lifestyle copy and
575
+ * the review carousel, so it is written out here and left for a measured pass of its own.
576
+ *
577
+ * Both frames make this line 32px tall, which is 24 x 1.32.
578
+ */
579
+ ._title_ryf3q_35 {
580
+ font-size: var(--type-heading-lg-size);
581
+ line-height: 1.32;
511
582
  }
512
583
 
513
- ._body_1u83t_20 {
584
+ ._body_ryf3q_40 {
514
585
  margin: 0;
515
586
  color: var(--color-text-subtle);
516
587
  font-size: var(--type-paragraph-size);
588
+ line-height: var(--type-paragraph-line);
517
589
  max-width: 34ch;
518
590
  }
519
591
 
520
- /*
521
- * The one place the empty state is drawn is the cart (Figma 4451:48190), and it separates
522
- * the action from the copy far more than it separates the two lines of copy: 24 against 6.
523
- * With the `gap` above, this lands the button 28px below the last line where the frame has
524
- * 28 — it was 20, close enough to the paragraph above to read as part of it.
525
- */
526
- ._action_1u83t_33 {
527
- margin-top: var(--space-16);
592
+ ._action_ryf3q_48 {
593
+ display: flex;
528
594
  }
529
595
  ._root_1lbpx_1 {
530
596
  display: flex;
@@ -795,7 +861,7 @@
795
861
  display: block;
796
862
  flex-shrink: 0;
797
863
  }
798
- ._root_n3nm5_1 {
864
+ ._root_rvfx9_1 {
799
865
  display: inline-flex;
800
866
  align-items: baseline;
801
867
  gap: var(--space-8);
@@ -804,33 +870,54 @@
804
870
 
805
871
  /* Alignment variants. Cards align on the price baseline row with a tight 4px gap; the
806
872
  PDP price row centres the price against its sale badge (6px). */
807
- ._center_n3nm5_10 {
873
+ ._center_rvfx9_10 {
808
874
  align-items: center;
809
875
  gap: var(--space-6);
810
876
  }
811
- ._end_n3nm5_14 {
877
+ ._end_rvfx9_14 {
812
878
  align-items: flex-end;
813
879
  gap: var(--space-4);
814
880
  }
815
881
 
816
- /* Size sets the row's font-size so the price and its struck was-price match (per the
817
- product-card, where both are 16px). */
818
- ._sm_n3nm5_21 {
882
+ /*
883
+ * Size sets the row's font-size so the price and its struck was-price match (per the
884
+ * product-card, where both are 16px), and its cap-trimmed leading.
885
+ *
886
+ * The leading was missing, and on the PDP that made the price row 25 tall against the
887
+ * frame's 20 — which is the whole of the 6px the product-info block was over. Figma sets
888
+ * every amount `text-box-trim: trim-both`, cap-alphabetic, so the row's height comes from
889
+ * the sale badge beside it rather than from the leading of a 16px font.
890
+ */
891
+ ._sm_rvfx9_28 {
819
892
  font-size: var(--type-trimmed-sm-size);
893
+ line-height: var(--type-trimmed-sm-line);
820
894
  }
821
- ._md_n3nm5_24 {
895
+ ._md_rvfx9_32 {
822
896
  font-size: var(--type-trimmed-md-size);
897
+ line-height: var(--type-trimmed-md-line);
823
898
  }
824
- ._lg_n3nm5_27 {
899
+ ._lg_rvfx9_36 {
825
900
  font-size: var(--type-heading-md-size);
901
+ /* 14 of cap on 20px, the same trim one size up. No token: `heading/md` is a display
902
+ size and this is its only trimmed use. */
903
+ line-height: 14px;
904
+ }
905
+
906
+ /*
907
+ * `mobile/pdp/price` is `min-h-[20px]`, and 20 is the sale badge's own height — so the row
908
+ * keeps that height whether or not a discount put a badge in it. Without this a
909
+ * full-price PDP would sit 9px tighter than a discounted one.
910
+ */
911
+ ._badge_rvfx9_48 {
912
+ min-height: 20px;
826
913
  }
827
914
 
828
- ._price_n3nm5_31 {
915
+ ._price_rvfx9_52 {
829
916
  font-weight: var(--font-weight-bold);
830
917
  color: var(--color-text-default);
831
918
  }
832
919
 
833
- ._compareAt_n3nm5_36 {
920
+ ._compareAt_rvfx9_57 {
834
921
  color: var(--color-text-disabled);
835
922
  text-decoration: line-through;
836
923
  font-weight: var(--font-weight-regular);
@@ -838,7 +925,7 @@
838
925
 
839
926
  /* On a product card the struck price carries the same weight as the live one (Figma
840
927
  `mobile/product-card`). Scoped to the card variant so the PDP's row is untouched. */
841
- ._strikethrough_n3nm5_44 ._compareAt_n3nm5_36 {
928
+ ._strikethrough_rvfx9_65 ._compareAt_rvfx9_57 {
842
929
  font-weight: var(--font-weight-bold);
843
930
  }
844
931
  /*
@@ -1057,158 +1144,40 @@
1057
1144
  ._row_1hsxt_16._discount_1hsxt_69 dd {
1058
1145
  color: var(--color-state-text-success);
1059
1146
  }
1060
- ._page_1eqkm_1 {
1061
- display: flex;
1062
- flex-direction: column;
1063
- gap: var(--space-24);
1064
- padding: var(--space-24) var(--space-16);
1065
- }
1066
-
1067
- /* ── Status + timeline ─────────────────────────────────────────────────────── */
1068
-
1069
- ._status_1eqkm_10 {
1070
- display: flex;
1071
- flex-direction: column;
1072
- gap: var(--space-24);
1073
- }
1074
-
1075
- /* The timeline and its button are one block in the design — 16px apart, 24px from the
1076
- heading above them. */
1077
- ._widget_1eqkm_18 {
1078
- display: flex;
1079
- flex-direction: column;
1080
- gap: var(--space-16);
1081
- }
1082
-
1083
- ._title_1eqkm_24 {
1084
- display: flex;
1085
- flex-direction: column;
1086
- gap: var(--space-12);
1087
- }
1088
-
1089
- ._headline_1eqkm_30 {
1090
- margin: 0;
1091
- font-size: var(--type-heading-md-size);
1092
- line-height: 1.32;
1093
- font-weight: var(--font-weight-bold);
1094
- }
1095
-
1096
- ._subtitle_1eqkm_37 {
1097
- margin: 0;
1098
- display: flex;
1099
- align-items: center;
1100
- gap: var(--space-8);
1101
- flex-wrap: wrap;
1102
- font-size: var(--type-paragraph-size);
1103
- font-weight: var(--font-weight-regular);
1104
- color: var(--color-text-subtle);
1105
- }
1106
-
1107
- ._dot_1eqkm_48 {
1108
- width: 4px;
1109
- height: 4px;
1110
- border-radius: var(--radius-full);
1111
- background: currentColor;
1112
- flex-shrink: 0;
1113
- }
1114
-
1115
- /* Figma `mobile/button`, as an anchor: the destination is the carrier's own site, so this
1116
- is a link and has to behave like one — middle-click, long-press, open in new tab. */
1117
- ._trackButton_1eqkm_58 {
1118
- display: flex;
1119
- align-items: center;
1120
- justify-content: center;
1121
- min-height: 48px;
1122
- padding: var(--space-12);
1123
- border-radius: var(--radius-8);
1124
- background: var(--color-surface-max);
1125
- color: var(--color-text-strong);
1126
- font-size: var(--type-trimmed-md-size);
1127
- font-weight: var(--font-weight-bold);
1128
- text-align: center;
1129
- text-decoration: none;
1130
- }
1131
-
1132
- ._trackButton_1eqkm_58:focus-visible {
1133
- outline: none;
1134
- box-shadow: var(--focus-ring);
1135
- }
1136
-
1137
- ._srOnly_1eqkm_78 {
1138
- position: absolute;
1139
- width: 1px;
1140
- height: 1px;
1141
- padding: 0;
1142
- margin: -1px;
1143
- overflow: hidden;
1144
- clip: rect(0, 0, 0, 0);
1145
- white-space: nowrap;
1146
- border: 0;
1147
- }
1148
-
1149
- /* ── Items card ────────────────────────────────────────────────────────────── */
1150
-
1151
- ._itemsCard_1eqkm_92 {
1152
- display: flex;
1153
- flex-direction: column;
1154
- border: 1px solid var(--color-border-transparent-soft);
1155
- border-radius: var(--radius-18);
1156
- overflow: hidden;
1157
- }
1158
-
1159
- ._cardHeader_1eqkm_100 {
1160
- display: flex;
1161
- align-items: center;
1162
- gap: var(--space-12);
1163
- min-height: 60px;
1164
- padding: 0 var(--space-16);
1165
- }
1166
-
1167
- ._cardTitle_1eqkm_108 {
1168
- margin: 0;
1169
- font-size: var(--type-heading-md-size);
1170
- line-height: 1.38;
1171
- font-weight: var(--font-weight-bold);
1172
- }
1147
+ /*
1148
+ * The blocks the confirmation (Figma 5295:74053) and the tracking screen (5479:132209)
1149
+ * both draw: the item rows, then the two cards. Written once because the frames instance
1150
+ * one set of components, and measured against both.
1151
+ */
1173
1152
 
1174
- ._count_1eqkm_115 {
1175
- display: inline-flex;
1176
- align-items: center;
1177
- justify-content: center;
1178
- min-width: 16px;
1179
- height: 16px;
1180
- padding: 0 var(--space-4);
1181
- border-radius: var(--radius-full);
1182
- background: var(--color-surface-subtle);
1183
- font-size: var(--type-trimmed-xs-size);
1184
- font-weight: var(--font-weight-bold);
1185
- letter-spacing: 0.12px;
1186
- font-variant-numeric: tabular-nums;
1187
- }
1153
+ /* ── Lines ─────────────────────────────────────────────────────────────────── */
1188
1154
 
1189
- ._lines_1eqkm_130 {
1155
+ /*
1156
+ * `mobile/checkout/cart-row`, and deliberately NOT inside a card.
1157
+ *
1158
+ * Both frames lay the rows straight on the page between the widget and the address. The
1159
+ * tracking screen used to draw a bordered "Items" card with a count instead, off a frame
1160
+ * that has since been redrawn; nothing draws that card now.
1161
+ *
1162
+ * `CartLineItem` is left alone: its copy of this component carries a quantity stepper and
1163
+ * a remove control that a receipt must not have.
1164
+ */
1165
+ ._lines_7mr8w_19 {
1190
1166
  list-style: none;
1191
1167
  margin: 0;
1192
1168
  padding: 0;
1193
1169
  display: flex;
1194
1170
  flex-direction: column;
1195
- border-top: 1px solid var(--color-border-default);
1171
+ gap: var(--space-16);
1196
1172
  }
1197
1173
 
1198
- ._line_1eqkm_130 {
1174
+ ._line_7mr8w_19 {
1199
1175
  display: flex;
1200
1176
  align-items: center;
1201
1177
  gap: var(--space-12);
1202
- padding: var(--space-12) var(--space-16);
1203
1178
  }
1204
1179
 
1205
- /* Between lines only — a rule under the last one would float above the card's edge. The
1206
- 12px either side of it comes from the rows' own padding. */
1207
- ._line_1eqkm_130 + ._line_1eqkm_130 {
1208
- border-top: 1px solid var(--color-border-default);
1209
- }
1210
-
1211
- ._thumb_1eqkm_152 {
1180
+ ._thumb_7mr8w_34 {
1212
1181
  position: relative;
1213
1182
  flex-shrink: 0;
1214
1183
  width: 48px;
@@ -1218,228 +1187,995 @@
1218
1187
  background: var(--color-surface-soft);
1219
1188
  }
1220
1189
 
1221
- ._image_1eqkm_162 {
1190
+ ._image_7mr8w_44 {
1222
1191
  object-fit: cover;
1223
1192
  }
1224
1193
 
1225
- ._placeholder_1eqkm_166 {
1194
+ ._placeholder_7mr8w_48 {
1226
1195
  width: 100%;
1227
1196
  height: 100%;
1228
1197
  }
1229
1198
 
1230
- /* Title and price share a top edge; the thumbnail centres against the pair. */
1231
- ._lineBody_1eqkm_172 {
1199
+ ._lineBody_7mr8w_53 {
1232
1200
  display: flex;
1233
1201
  align-items: flex-start;
1234
1202
  justify-content: space-between;
1203
+ gap: var(--space-16);
1235
1204
  flex: 1 1 0;
1236
1205
  min-width: 0;
1237
1206
  }
1238
1207
 
1239
- ._lineText_1eqkm_180 {
1208
+ ._lineText_7mr8w_62 {
1240
1209
  display: flex;
1241
1210
  flex-direction: column;
1242
1211
  gap: var(--space-12);
1243
1212
  flex: 1 1 0;
1244
1213
  min-width: 0;
1245
- padding-right: var(--space-16);
1246
1214
  }
1247
1215
 
1248
- ._lineTitle_1eqkm_189 {
1216
+ /* Cap-trimmed to the frame's 11, with the same descender protection as the subtitle —
1217
+ this one is ellipsised too, and a `p` or a `g` in a product name is not unusual. */
1218
+ ._lineTitle_7mr8w_72 {
1219
+ margin: -6px 0;
1220
+ padding: 6px 0;
1249
1221
  font-size: var(--type-trimmed-sm-size);
1222
+ line-height: 11px;
1250
1223
  font-weight: var(--font-weight-bold);
1251
1224
  white-space: nowrap;
1252
1225
  overflow: hidden;
1253
1226
  text-overflow: ellipsis;
1254
1227
  }
1255
1228
 
1256
- ._lineDetails_1eqkm_197 {
1229
+ /*
1230
+ * The variant, then the sale badge beside it — 12px apart, vertically centred on it.
1231
+ *
1232
+ * Cap-trimmed like the title above, which is what leaves the badge as the tallest thing in
1233
+ * the row and holds it to the 20px the frame gives it. Untrimmed the text alone was 22, so
1234
+ * the row stood 55 against the frame's 48 and the thumbnail stopped being what sets the
1235
+ * row's height.
1236
+ */
1237
+ ._lineMeta_7mr8w_91 {
1257
1238
  display: flex;
1239
+ align-items: center;
1258
1240
  gap: var(--space-12);
1241
+ min-width: 0;
1259
1242
  font-size: var(--type-trimmed-sm-size);
1243
+ line-height: 11px;
1260
1244
  color: var(--color-text-subtle);
1261
- min-width: 0;
1262
1245
  }
1263
1246
 
1264
- ._linePrice_1eqkm_205 {
1247
+ /*
1248
+ * Stacked, not in a row: the frame puts what was paid above what it would have cost, at
1249
+ * two different sizes. That is why this is written here rather than with `PriceBlock`,
1250
+ * which lays the pair out inline at one size for the product card and the PDP.
1251
+ */
1252
+ ._linePrice_7mr8w_106 {
1253
+ display: flex;
1254
+ flex-direction: column;
1255
+ align-items: flex-end;
1256
+ gap: var(--space-6);
1265
1257
  flex-shrink: 0;
1266
- font-size: var(--type-trimmed-md-size);
1267
- font-weight: var(--font-weight-bold);
1268
1258
  white-space: nowrap;
1269
1259
  font-variant-numeric: tabular-nums;
1270
1260
  }
1271
1261
 
1272
- /* ── Address + payment ─────────────────────────────────────────────────────── */
1273
-
1274
- ._details_1eqkm_215 {
1275
- display: flex;
1276
- flex-direction: column;
1277
- gap: var(--space-16);
1278
- padding: var(--space-16);
1279
- background: var(--color-surface-soft);
1280
- border: 1px solid var(--color-border-default);
1281
- border-radius: var(--radius-18);
1282
- /* The design nests this card inside a second, one-step-darker ring. Drawn as a shadow
1283
- rather than a wrapper element: the two borders are coincident, so it renders the same. */
1284
- box-shadow: 0 0 0 1px var(--color-border-subtle);
1285
- }
1286
-
1287
- ._detailBlock_1eqkm_228 {
1288
- display: flex;
1289
- flex-direction: column;
1290
- gap: var(--space-8);
1291
- }
1292
-
1293
- /* The payment block sits a step looser than the address one. */
1294
- ._detailBlock_1eqkm_228._payment_1eqkm_235 {
1295
- gap: var(--space-12);
1296
- }
1297
-
1298
- ._detailLabel_1eqkm_239 {
1299
- margin: 0;
1300
- font-size: var(--type-trimmed-sm-size);
1262
+ /* Cap-trimmed like everything else in this row: 11 on 16px, 10 on 14px. Untrimmed the
1263
+ pair stood 52 tall and became what set the row's height, against a 48px thumbnail. */
1264
+ ._paid_7mr8w_118 {
1265
+ font-size: var(--type-trimmed-md-size);
1266
+ line-height: 11px;
1301
1267
  font-weight: var(--font-weight-bold);
1302
1268
  }
1303
1269
 
1304
- ._detailValue_1eqkm_245 {
1305
- margin: 0;
1306
- display: flex;
1307
- align-items: center;
1308
- gap: var(--space-8);
1270
+ ._was_7mr8w_124 {
1309
1271
  font-size: var(--type-trimmed-sm-size);
1310
- line-height: var(--type-caption-sm-line);
1311
- color: var(--color-text-subtle);
1312
- }
1313
-
1314
- /* The masked digits carry the same weight as the brand beside them. */
1315
- ._last4_1eqkm_256 {
1316
- font-weight: var(--font-weight-bold);
1317
- }
1318
-
1319
- /* The brand as DAZN send it — lowercase on the wire, capitalised for display rather than
1320
- matched against a list, so an unfamiliar one still renders properly. */
1321
- ._brand_1eqkm_262 {
1322
- text-transform: capitalize;
1323
- font-weight: var(--font-weight-bold);
1324
- color: var(--color-text-default);
1325
- }
1326
-
1327
- ._divider_1eqkm_268 {
1328
- height: 1px;
1329
- background: var(--color-border-default);
1272
+ line-height: 10px;
1273
+ font-weight: var(--font-weight-regular);
1274
+ color: var(--color-text-disabled);
1275
+ text-decoration: line-through;
1330
1276
  }
1331
1277
 
1332
- /* ── Order summary ─────────────────────────────────────────────────────────── */
1278
+ /* ── Cards ─────────────────────────────────────────────────────────────────── */
1333
1279
 
1334
- ._summaryCard_1eqkm_275 {
1280
+ /*
1281
+ * The address and summary cards are one shape: a 60px titled header, a hairline, and a
1282
+ * body. They differ only in ground, which is what `.summaryCard` below changes.
1283
+ *
1284
+ * The ring is an inset shadow rather than a border, and that is a measurement rather than
1285
+ * a preference. Figma draws a frame's stroke INSIDE its box, so the address card is 113
1286
+ * tall with its outline in that 113 — 60 of header and 53 of body. A CSS border sits
1287
+ * outside the content and makes the same card 115. An inset shadow paints the same
1288
+ * hairline and occupies no layout, so the card lands on the design's own number.
1289
+ */
1290
+ ._card_7mr8w_144 {
1335
1291
  display: flex;
1336
1292
  flex-direction: column;
1337
- background: var(--color-surface-soft);
1338
- border: 1px solid var(--color-border-default);
1293
+ box-shadow: inset 0 0 0 1px var(--color-border-default);
1339
1294
  border-radius: var(--radius-18);
1340
1295
  overflow: hidden;
1341
1296
  }
1342
1297
 
1343
- ._summaryCard_1eqkm_275 ._cardTitle_1eqkm_108 {
1298
+ ._cardTitle_7mr8w_152 {
1344
1299
  display: flex;
1345
1300
  align-items: center;
1301
+ margin: 0;
1346
1302
  min-height: 60px;
1347
1303
  padding: 0 var(--space-16);
1304
+ border-bottom: 1px solid var(--color-border-default);
1305
+ font-size: var(--type-heading-md-size);
1306
+ line-height: 1.38;
1307
+ font-weight: var(--font-weight-bold);
1348
1308
  }
1349
1309
 
1350
- /* The shared summary rows are drawn edge-to-edge in the cart; inside this card they need
1351
- the card's own gutter. */
1352
- ._summaryCard_1eqkm_275 > :last-child {
1353
- padding: 0 var(--space-16);
1354
- }
1355
- /*
1356
- * Figma `5295:74053`. The page's own block starts at y=118 — under the 64px bar and the
1357
- * 54px status bar the device draws above it with 20px above the first heading, 24px
1358
- * below the last control, and 32px between the five blocks.
1310
+ ._cardBody_7mr8w_164 {
1311
+ margin: 0;
1312
+ padding: var(--space-16);
1313
+ font-size: var(--type-trimmed-sm-size);
1314
+ line-height: 1.5;
1315
+ }
1316
+
1317
+ /* `surface/full-color/soft` the summary is the one card the design fills. */
1318
+ ._summaryCard_7mr8w_136 {
1319
+ background: var(--color-surface-soft);
1320
+ }
1321
+
1322
+ /* The shared summary rows are drawn edge-to-edge in the cart; here they take the card's
1323
+ own gutter, as they do on the tracking screen. */
1324
+ ._summaryCard_7mr8w_136 > :last-child {
1325
+ padding: 0 var(--space-16);
1326
+ }
1327
+ /*
1328
+ * Figma `.sheet-header` (404:5379) — 48 tall, three slots.
1329
+ *
1330
+ * Extracted from the size guide when the cancel and return sheets turned out to instance
1331
+ * the same component. One copy, so the handle cannot end up 4px off on one screen.
1332
+ */
1333
+ ._header_1f3nh_7 {
1334
+ display: flex;
1335
+ align-items: flex-start;
1336
+ justify-content: space-between;
1337
+ }
1338
+
1339
+ /* The empty left slot. It exists to balance the close control so the handle is centred on
1340
+ the sheet rather than on what is left of it. */
1341
+ ._slot_1f3nh_15 {
1342
+ flex-shrink: 0;
1343
+ width: 48px;
1344
+ height: 48px;
1345
+ }
1346
+
1347
+ /* `self-stretch` with 12 of padding: the handle sits 12 from the top of the 48, not
1348
+ centred in it. */
1349
+ ._handleSlot_1f3nh_23 {
1350
+ align-self: stretch;
1351
+ padding: var(--space-12);
1352
+ }
1353
+
1354
+ ._handle_1f3nh_23 {
1355
+ width: 44px;
1356
+ height: 4px;
1357
+ border-radius: var(--radius-full);
1358
+ background: var(--color-surface-bold);
1359
+ }
1360
+
1361
+ ._closeSlot_1f3nh_35 {
1362
+ display: inline-flex;
1363
+ align-items: center;
1364
+ justify-content: center;
1365
+ flex-shrink: 0;
1366
+ width: 48px;
1367
+ height: 48px;
1368
+ padding: var(--space-12);
1369
+ border: 0;
1370
+ background: none;
1371
+ color: var(--color-text-default);
1372
+ cursor: pointer;
1373
+ }
1374
+
1375
+ ._closeSlot_1f3nh_35:focus-visible {
1376
+ outline: none;
1377
+ box-shadow: var(--focus-ring);
1378
+ border-radius: var(--radius-4);
1379
+ }
1380
+
1381
+ /* `across-platform/icon-button`, fill: a 24 disc around the 16px cross box. */
1382
+ ._close_1f3nh_35 {
1383
+ display: inline-flex;
1384
+ align-items: center;
1385
+ justify-content: center;
1386
+ width: 24px;
1387
+ height: 24px;
1388
+ border-radius: var(--radius-full);
1389
+ background: var(--color-surface-neutral);
1390
+ }
1391
+ /*
1392
+ * Figma `Reason for cancelling` (4632:17129) and `Reason for return`.
1393
+ *
1394
+ * A 48 header, a body of 24-gap blocks inset 16, and the sheet footer. Radius 12 at the
1395
+ * top — NOT the size guide's 16. The two sheets are drawn with different corners in the
1396
+ * file and each follows its own.
1397
+ */
1398
+ ._scrim_7on4q_8 {
1399
+ position: fixed;
1400
+ inset: 0;
1401
+ z-index: 60;
1402
+ display: flex;
1403
+ align-items: flex-end;
1404
+ justify-content: center;
1405
+ /* `semantic/base/surface/backdrop`. */
1406
+ background: rgba(12, 22, 28, 0.32);
1407
+ animation: _fade_7on4q_1 160ms ease-out;
1408
+ }
1409
+
1410
+ ._sheet_7on4q_20 {
1411
+ display: flex;
1412
+ flex-direction: column;
1413
+ width: 100%;
1414
+ max-width: 480px;
1415
+ max-height: 90dvh;
1416
+ overflow: hidden;
1417
+ border-radius: var(--radius-12) var(--radius-12) 0 0;
1418
+ background: var(--color-surface-default);
1419
+ animation: _rise_7on4q_1 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
1420
+ }
1421
+
1422
+ ._body_7on4q_32 {
1423
+ flex: 1 1 auto;
1424
+ overflow-y: auto;
1425
+ display: flex;
1426
+ flex-direction: column;
1427
+ gap: var(--space-16);
1428
+ padding: 0 var(--space-16);
1429
+ }
1430
+
1431
+ ._body_7on4q_32 > * {
1432
+ flex-shrink: 0;
1433
+ }
1434
+
1435
+ /* `heading/md` at the library's 1.32, not our 1.25 base. */
1436
+ ._title_7on4q_46 {
1437
+ margin: 0;
1438
+ font-size: var(--type-heading-md-size);
1439
+ line-height: 1.32;
1440
+ font-weight: var(--font-weight-bold);
1441
+ color: var(--color-text-default);
1442
+ }
1443
+
1444
+ ._options_7on4q_54 {
1445
+ display: flex;
1446
+ flex-direction: column;
1447
+ gap: var(--space-6);
1448
+ }
1449
+
1450
+ /*
1451
+ * Each reason is a filled card, not a bare radio: 12 of padding on a `soft` ground at
1452
+ * radius 12, which makes the whole row the target rather than the 20px circle.
1359
1453
  */
1360
- ._page_8yxu9_6 {
1454
+ ._option_7on4q_54 {
1455
+ display: flex;
1456
+ align-items: center;
1457
+ gap: var(--space-8);
1458
+ width: 100%;
1459
+ padding: var(--space-12);
1460
+ border: 0;
1461
+ border-radius: var(--radius-12);
1462
+ background: var(--color-surface-soft);
1463
+ color: var(--color-text-subtle);
1464
+ font-family: inherit;
1465
+ text-align: left;
1466
+ cursor: pointer;
1467
+ }
1468
+
1469
+ ._option_7on4q_54:focus-visible {
1470
+ outline: none;
1471
+ box-shadow: var(--focus-ring);
1472
+ }
1473
+
1474
+ /*
1475
+ * The frame's `Checkbox`: a 24 box holding a 20 circle, so the ring sits 2 in from each
1476
+ * edge and the row's 8 gap measures from the box rather than the circle.
1477
+ */
1478
+ ._radio_7on4q_88 {
1479
+ position: relative;
1480
+ display: inline-flex;
1481
+ align-items: center;
1482
+ justify-content: center;
1483
+ flex-shrink: 0;
1484
+ width: 24px;
1485
+ height: 24px;
1486
+ color: var(--color-surface-max);
1487
+ }
1488
+
1489
+ /* Unselected is an empty ring; the filled disc and tick are drawn only when chosen. */
1490
+ ._radio_7on4q_88::before {
1491
+ content: '';
1492
+ position: absolute;
1493
+ width: 20px;
1494
+ height: 20px;
1495
+ border: 1px solid var(--color-border-default);
1496
+ border-radius: var(--radius-full);
1497
+ }
1498
+
1499
+ ._option_7on4q_54[aria-checked='true'] ._radio_7on4q_88::before {
1500
+ border-color: transparent;
1501
+ }
1502
+
1503
+ ._radio_7on4q_88 svg {
1504
+ position: relative;
1505
+ }
1506
+
1507
+ /* 16px, cap-trimmed to 11 — `trimmed/md`, the same face the size chips use. */
1508
+ ._label_7on4q_118 {
1509
+ font-size: var(--type-trimmed-md-size);
1510
+ line-height: 11px;
1511
+ font-weight: var(--font-weight-regular);
1512
+ padding: 5px 0;
1513
+ margin: -5px 0;
1514
+ }
1515
+
1516
+ /* `.bottomsheet-footer`: no top padding, 24 below, inset 16. */
1517
+ ._footer_7on4q_127 {
1518
+ flex-shrink: 0;
1519
+ display: flex;
1520
+ flex-direction: column;
1521
+ gap: var(--space-12);
1522
+ padding: var(--space-16) var(--space-16) calc(var(--space-24) + var(--safe-area-bottom));
1523
+ }
1524
+
1525
+ ._error_7on4q_135 {
1526
+ margin: 0;
1527
+ font-size: var(--type-trimmed-sm-size);
1528
+ line-height: 1.4;
1529
+ color: var(--color-state-text-critical);
1530
+ }
1531
+
1532
+ @keyframes _fade_7on4q_1 {
1533
+ from {
1534
+ opacity: 0;
1535
+ }
1536
+ to {
1537
+ opacity: 1;
1538
+ }
1539
+ }
1540
+
1541
+ @keyframes _rise_7on4q_1 {
1542
+ from {
1543
+ transform: translateY(12%);
1544
+ }
1545
+ to {
1546
+ transform: translateY(0);
1547
+ }
1548
+ }
1549
+
1550
+ @media (prefers-reduced-motion: reduce) {
1551
+ ._scrim_7on4q_8,
1552
+ ._sheet_7on4q_20 {
1553
+ animation: none;
1554
+ }
1555
+ }
1556
+ /*
1557
+ * Figma `order stats` (5479:132209), whose three states differ only inside the widget.
1558
+ *
1559
+ * The page's own block starts at y=138 — 20 under the 118 of status bar and header — and
1560
+ * everything below it is 32 apart: widget, rule, rows, address, summary. Same rhythm and
1561
+ * same padding as the confirmation, which is the same page from the fold down.
1562
+ */
1563
+ ._page_opefg_8 {
1361
1564
  display: flex;
1362
1565
  flex-direction: column;
1363
1566
  gap: var(--space-32);
1364
1567
  padding: var(--space-20) var(--space-16) var(--space-24);
1365
1568
  }
1366
1569
 
1367
- /* ── Confirmation + timeline ───────────────────────────────────────────────── */
1570
+ /* ── Order number + timeline ───────────────────────────────────────────────── */
1571
+
1572
+ /* `mobile/order/delivery-widget`: the title row, then the steps, 32 apart. */
1573
+ ._widget_opefg_18 {
1574
+ display: flex;
1575
+ flex-direction: column;
1576
+ gap: var(--space-32);
1577
+ }
1578
+
1579
+ /* The number on the left, the carrier link hard right — and nothing between them, so a
1580
+ long reference runs into the space the link is not using rather than under it. */
1581
+ ._titleRow_opefg_26 {
1582
+ display: flex;
1583
+ align-items: center;
1584
+ justify-content: space-between;
1585
+ gap: var(--space-12);
1586
+ }
1587
+
1588
+ /*
1589
+ * `line-height: 14px` on 20px text, which is the frame's own number rather than a squeeze:
1590
+ * every text layer here is `text-box-trim: trim-both` with a cap-alphabetic edge, so
1591
+ * Figma's box stops at the cap height and its 14 is 14 of visible letter. A CSS line box
1592
+ * carries the font's leading above and below, which renders the same heading as 26 and
1593
+ * pushes everything below it down by the difference.
1594
+ *
1595
+ * Nothing clips it, so the cap-height box needs no descender protection.
1596
+ */
1597
+ ._headline_opefg_42 {
1598
+ margin: 0;
1599
+ min-width: 0;
1600
+ font-size: var(--type-heading-md-size);
1601
+ line-height: 14px;
1602
+ font-weight: var(--font-weight-bold);
1603
+ overflow: hidden;
1604
+ text-overflow: ellipsis;
1605
+ white-space: nowrap;
1606
+ }
1607
+
1608
+ /*
1609
+ * The carrier link: a text link with the design's `redirect-link` mark, not the 48px
1610
+ * button this used to be. The frame puts it on the title's own line, right-aligned, at the
1611
+ * same 16px as a timeline label.
1612
+ *
1613
+ * An anchor rather than a button because the destination is a real page on somebody else's
1614
+ * site, and it has to behave like one: middle-click, long-press, open in a new tab.
1615
+ */
1616
+ ._track_opefg_61 {
1617
+ display: inline-flex;
1618
+ align-items: center;
1619
+ gap: var(--space-6);
1620
+ flex-shrink: 0;
1621
+ font-size: var(--type-trimmed-md-size);
1622
+ line-height: 14px;
1623
+ font-weight: var(--font-weight-bold);
1624
+ color: var(--color-text-default);
1625
+ text-decoration: none;
1626
+ }
1627
+
1628
+ ._track_opefg_61:focus-visible {
1629
+ outline: none;
1630
+ box-shadow: var(--focus-ring);
1631
+ border-radius: var(--radius-4);
1632
+ }
1633
+
1634
+ /*
1635
+ * The frame's `Line 11`, between the widget and the receipt.
1636
+ *
1637
+ * A Figma line has no height — 32 above it and 32 below it means 64 between the blocks it
1638
+ * separates, with the hairline drawn on that boundary. The negative margin takes the
1639
+ * pixel back out of the layout so the two gaps stay 32 rather than becoming 32 and 33.
1640
+ */
1641
+ ._rule_opefg_86 {
1642
+ height: 1px;
1643
+ margin: 0 0 -1px;
1644
+ border: 0;
1645
+ background: var(--color-border-default);
1646
+ }
1647
+
1648
+ /* ── Need help? ────────────────────────────────────────────────────────────── */
1649
+
1650
+ /* `mobile/explore`: the heading, then the rows, 6 apart. */
1651
+ ._help_opefg_96 {
1652
+ display: flex;
1653
+ flex-direction: column;
1654
+ gap: var(--space-6);
1655
+ }
1656
+
1657
+ ._helpTitle_opefg_102 {
1658
+ margin: 0;
1659
+ font-size: var(--type-heading-md-size);
1660
+ line-height: 1.32;
1661
+ font-weight: var(--font-weight-bold);
1662
+ }
1663
+
1664
+ ._helpRows_opefg_109 {
1665
+ display: flex;
1666
+ flex-direction: column;
1667
+ }
1668
+
1669
+ /*
1670
+ * 48 tall: 16 of padding either side of a 16px chevron, which is what sets the height. The
1671
+ * label is cap-trimmed to 10 and is shorter than the mark beside it.
1672
+ */
1673
+ ._helpRow_opefg_109 {
1674
+ display: flex;
1675
+ align-items: center;
1676
+ justify-content: space-between;
1677
+ gap: var(--space-12);
1678
+ width: 100%;
1679
+ padding: var(--space-16) 0;
1680
+ border: 0;
1681
+ border-radius: var(--radius-8);
1682
+ background: none;
1683
+ color: var(--color-text-default);
1684
+ font-family: inherit;
1685
+ font-size: var(--type-trimmed-sm-size);
1686
+ line-height: 10px;
1687
+ font-weight: var(--font-weight-bold);
1688
+ text-align: left;
1689
+ cursor: pointer;
1690
+ }
1691
+
1692
+ /*
1693
+ * `border/full-color/subtle`, one step darker than the hairline the cards are drawn with,
1694
+ * and between the rows only — a rule under the last one would leave the block underlined.
1695
+ *
1696
+ * After `.helpRow` and not before it: that rule sets `border: 0` and its own padding, and
1697
+ * at equal specificity the later one wins. Written first, this drew no line at all.
1698
+ *
1699
+ * Nothing gives the pixel back, because nothing takes it: the row's height comes from its
1700
+ * padding and its 16px chevron rather than from a `height`, so the hairline adds to the
1701
+ * row instead of eating into it. 48, the line, then 48 — the frame's own 97 for the pair.
1702
+ */
1703
+ ._helpRow_opefg_109 + ._helpRow_opefg_109 {
1704
+ border-top: 1px solid var(--color-border-subtle);
1705
+ }
1706
+
1707
+ ._helpRow_opefg_109:focus-visible {
1708
+ outline: none;
1709
+ box-shadow: var(--focus-ring);
1710
+ }
1711
+
1712
+ /* ── Cancel, and the cancelled order ───────────────────────────────────────── */
1713
+
1714
+ /*
1715
+ * Figma `Cancel flow` (4551:32251) screen 1: a destructive action on a pale critical
1716
+ * ground, at the foot of the screen below the summary.
1717
+ *
1718
+ * Not a `Button` variant. The design system has no destructive button and inventing one
1719
+ * would put a fourth variant in the primitive for a single use — this is the one control
1720
+ * in the package drawn this way, so it is drawn here.
1721
+ */
1722
+ ._cancel_opefg_167 {
1723
+ display: inline-flex;
1724
+ align-items: center;
1725
+ justify-content: center;
1726
+ width: 100%;
1727
+ min-height: var(--control-height);
1728
+ padding: 0 var(--space-20);
1729
+ border: 0;
1730
+ border-radius: var(--radius-8);
1731
+ background: var(--color-state-surface-critical-soft);
1732
+ color: var(--color-state-text-critical);
1733
+ font-family: inherit;
1734
+ font-size: var(--type-trimmed-md-size);
1735
+ line-height: 11px;
1736
+ font-weight: var(--font-weight-bold);
1737
+ cursor: pointer;
1738
+ }
1739
+
1740
+ ._cancel_opefg_167:focus-visible {
1741
+ outline: none;
1742
+ box-shadow: var(--focus-ring);
1743
+ }
1744
+
1745
+ /* Screen 3. The head is a title and one meta line, 8 apart. */
1746
+ ._cancelledHead_opefg_191 {
1747
+ display: flex;
1748
+ flex-direction: column;
1749
+ gap: var(--space-8);
1750
+ }
1751
+
1752
+ ._cancelledTitle_opefg_197 {
1753
+ margin: 0;
1754
+ font-size: var(--type-heading-md-size);
1755
+ line-height: 1.32;
1756
+ font-weight: var(--font-weight-bold);
1757
+ color: var(--color-text-default);
1758
+ }
1759
+
1760
+ /* The reference and the date it was placed, cap-trimmed to 10 on 14. */
1761
+ ._cancelledMeta_opefg_206 {
1762
+ font-size: var(--type-trimmed-sm-size);
1763
+ line-height: 10px;
1764
+ padding: 5px 0;
1765
+ margin: -5px 0;
1766
+ color: var(--color-text-subtle);
1767
+ }
1768
+ /*
1769
+ * Figma `Return flow` (4551:32294), the item-selection screen (4632:17780).
1770
+ *
1771
+ * 20 of padding top and bottom, 16 either side, and 24 between the title block, the list
1772
+ * and the button. The cards are 12 apart inside the list.
1773
+ */
1774
+ ._page_1c7ro_7 {
1775
+ display: flex;
1776
+ flex-direction: column;
1777
+ gap: var(--space-24);
1778
+ padding: var(--space-20) var(--space-16);
1779
+ background: var(--color-surface-default);
1780
+ }
1781
+
1782
+ ._titles_1c7ro_15 {
1783
+ display: flex;
1784
+ flex-direction: column;
1785
+ gap: var(--space-8);
1786
+ }
1787
+
1788
+ ._title_1c7ro_15 {
1789
+ margin: 0;
1790
+ font-size: var(--type-heading-md-size);
1791
+ line-height: 1.32;
1792
+ font-weight: var(--font-weight-bold);
1793
+ color: var(--color-text-default);
1794
+ }
1795
+
1796
+ /* 14 cap-trimmed to 10, like every small label in this package. */
1797
+ ._subtitle_1c7ro_30 {
1798
+ font-size: var(--type-trimmed-sm-size);
1799
+ line-height: 10px;
1800
+ padding: 5px 0;
1801
+ margin: -5px 0;
1802
+ color: var(--color-text-subtle);
1803
+ }
1804
+
1805
+ ._list_1c7ro_38 {
1806
+ display: flex;
1807
+ flex-direction: column;
1808
+ gap: var(--space-12);
1809
+ }
1810
+
1811
+ /*
1812
+ * A filled card at radius 18 — the largest corner in the scale, and the one the frame
1813
+ * uses for a block a fan acts on rather than merely reads.
1814
+ */
1815
+ ._card_1c7ro_48 {
1816
+ display: flex;
1817
+ align-items: flex-start;
1818
+ gap: var(--space-12);
1819
+ padding: var(--space-20) var(--space-16);
1820
+ border-radius: var(--radius-18);
1821
+ background: var(--color-surface-soft);
1822
+ }
1823
+
1824
+ /*
1825
+ * The checkbox sits 12 down from the top of the card rather than centred on the row: the
1826
+ * card grows when a reason is chosen, and a centred control would drift down with it.
1827
+ */
1828
+ ._checkSlot_1c7ro_61 {
1829
+ display: inline-flex;
1830
+ align-items: flex-start;
1831
+ flex-shrink: 0;
1832
+ padding: var(--space-12) 0 0;
1833
+ border: 0;
1834
+ background: none;
1835
+ color: var(--color-surface-max);
1836
+ cursor: pointer;
1837
+ }
1838
+
1839
+ ._checkSlot_1c7ro_61:focus-visible {
1840
+ outline: none;
1841
+ box-shadow: var(--focus-ring);
1842
+ border-radius: var(--radius-4);
1843
+ }
1844
+
1845
+ /* A 24 box holding a 20 mark, so the row's 12 gap measures from the box. */
1846
+ ._check_1c7ro_61 {
1847
+ position: relative;
1848
+ display: inline-flex;
1849
+ align-items: center;
1850
+ justify-content: center;
1851
+ width: 24px;
1852
+ height: 24px;
1853
+ }
1854
+
1855
+ ._check_1c7ro_61::before {
1856
+ content: '';
1857
+ position: absolute;
1858
+ width: 20px;
1859
+ height: 20px;
1860
+ border: 1px solid var(--color-border-default);
1861
+ border-radius: var(--radius-full);
1862
+ }
1863
+
1864
+ ._checkSlot_1c7ro_61[aria-checked='true'] ._check_1c7ro_61::before {
1865
+ border-color: transparent;
1866
+ }
1867
+
1868
+ ._check_1c7ro_61 svg {
1869
+ position: relative;
1870
+ }
1871
+
1872
+ ._row_1c7ro_105 {
1873
+ display: flex;
1874
+ flex-direction: column;
1875
+ gap: var(--space-12);
1876
+ flex: 1 1 0;
1877
+ min-width: 0;
1878
+ }
1879
+
1880
+ ._line_1c7ro_113 {
1881
+ display: flex;
1882
+ align-items: center;
1883
+ gap: var(--space-12);
1884
+ }
1885
+
1886
+ ._thumb_1c7ro_119 {
1887
+ position: relative;
1888
+ flex-shrink: 0;
1889
+ width: 48px;
1890
+ height: 48px;
1891
+ border-radius: var(--radius-6);
1892
+ overflow: hidden;
1893
+ background: var(--color-surface-subtle);
1894
+ }
1895
+
1896
+ ._img_1c7ro_129 {
1897
+ object-fit: cover;
1898
+ }
1368
1899
 
1369
- /* `mobile/order/delivery-widget`: the heading pair, then the timeline, 24px apart. */
1370
- ._confirmed_8yxu9_16 {
1900
+ ._placeholder_1c7ro_133 {
1901
+ width: 100%;
1902
+ height: 100%;
1903
+ }
1904
+
1905
+ ._meta_1c7ro_138 {
1371
1906
  display: flex;
1372
1907
  flex-direction: column;
1373
- gap: var(--space-24);
1908
+ gap: var(--space-12);
1909
+ flex: 1 1 0;
1910
+ min-width: 0;
1911
+ }
1912
+
1913
+ /* 14 bold, cap-trimmed to 10 and clipped to one line. */
1914
+ ._name_1c7ro_147 {
1915
+ font-size: var(--type-trimmed-sm-size);
1916
+ line-height: 10px;
1917
+ padding: 5px 0;
1918
+ margin: -5px 0;
1919
+ font-weight: var(--font-weight-bold);
1920
+ color: var(--color-text-default);
1921
+ overflow: hidden;
1922
+ text-overflow: ellipsis;
1923
+ white-space: nowrap;
1924
+ }
1925
+
1926
+ ._attrs_1c7ro_159 {
1927
+ font-size: var(--type-trimmed-sm-size);
1928
+ line-height: 10px;
1929
+ padding: 5px 0;
1930
+ margin: -5px 0;
1931
+ color: var(--color-text-subtle);
1374
1932
  }
1375
1933
 
1376
- ._title_8yxu9_22 {
1934
+ ._price_1c7ro_167 {
1377
1935
  display: flex;
1378
1936
  flex-direction: column;
1379
- gap: var(--space-12);
1937
+ align-items: flex-end;
1938
+ gap: var(--space-6);
1939
+ flex-shrink: 0;
1940
+ text-align: right;
1941
+ }
1942
+
1943
+ ._paid_1c7ro_176 {
1944
+ font-size: var(--type-trimmed-md-size);
1945
+ line-height: 11px;
1946
+ font-weight: var(--font-weight-bold);
1947
+ color: var(--color-text-default);
1948
+ font-variant-numeric: tabular-nums;
1949
+ }
1950
+
1951
+ ._was_1c7ro_184 {
1952
+ font-size: var(--type-trimmed-sm-size);
1953
+ line-height: 10px;
1954
+ color: var(--color-text-disabled);
1955
+ text-decoration: line-through;
1956
+ font-variant-numeric: tabular-nums;
1380
1957
  }
1381
1958
 
1382
1959
  /*
1383
- * Green, and the only green heading in the storefront: `semantic/state/text/success`
1384
- * rather than `text/default`, which is the design saying this line is a result and not a
1385
- * label. It is the same token the discount row and the "Free" shipping figure take, so
1386
- * the screen has one success tone rather than three.
1960
+ * The frame's `drop-menu`: a fixed 154 x 32 outlined control, padded 12 on the left and 8
1961
+ * on the right so the chevron sits closer to the edge than the label does.
1387
1962
  *
1388
- * `line-height: 14px` on 20px text, and that is the frame's own number rather than a
1389
- * squeeze: every text layer here is `text-box-trim: trim-both` with a cap-alphabetic
1390
- * edge, so Figma's boxes stop at the cap height and its 14 is 14 of visible letter. A CSS
1391
- * line box carries the font's leading above and below, which renders the same heading as
1392
- * 26 and pushes all four blocks below it down by the difference.
1393
- *
1394
- * `text-box-trim` would let us write the design's own number and is Chrome 133+ only; this
1395
- * package still supports the WebView in React 16-era DAZN builds. `OrderTimeline` and
1396
- * `ProductTile` carry the same approximation for the same reason.
1397
- *
1398
- * Nothing clips it, so the cap-height box needs no descender protection — unlike the
1399
- * subtitle below, which the design truncates.
1963
+ * Disabled-coloured while it still says "Select reason" the label is a prompt at that
1964
+ * point, not a value, and the design greys it to say so. It is a live control either way.
1400
1965
  */
1401
- ._headline_8yxu9_47 {
1402
- margin: 0;
1403
- font-size: var(--type-heading-md-size);
1404
- line-height: 14px;
1966
+ ._reason_1c7ro_199 {
1967
+ display: inline-flex;
1968
+ align-items: center;
1969
+ justify-content: space-between;
1970
+ width: 154px;
1971
+ height: 32px;
1972
+ padding: var(--space-4) var(--space-8) var(--space-4) var(--space-12);
1973
+ border: 1px solid var(--color-border-default);
1974
+ border-radius: var(--radius-6);
1975
+ background: none;
1976
+ color: var(--color-text-disabled);
1977
+ font-family: inherit;
1978
+ font-size: var(--type-trimmed-sm-size);
1979
+ line-height: 10px;
1405
1980
  font-weight: var(--font-weight-bold);
1406
- color: var(--color-state-text-success);
1981
+ cursor: pointer;
1407
1982
  }
1408
1983
 
1984
+ ._reasonSet_1c7ro_217 {
1985
+ color: var(--color-text-default);
1986
+ }
1987
+
1988
+ ._reason_1c7ro_199:focus-visible {
1989
+ outline: none;
1990
+ box-shadow: var(--focus-ring);
1991
+ }
1409
1992
  /*
1410
- * 11px on 16px text, the same cap-height trim as the heading, and one line: the design's
1411
- * own text layer is `overflow-hidden` with `text-ellipsis`, which is how it holds an
1412
- * address of unknown length to a single row.
1993
+ * Figma `Return flow` (4551:32294), screen 5 the label and its instructions.
1413
1994
  *
1414
- * The padding is what the trim costs. Clipping cuts in both directions, and an 11px box
1415
- * beheads every descender including the `g` in the `@gmail.com` the frame itself shows.
1416
- * The padding gives the glyphs somewhere to go and the equal negative margin takes it back
1417
- * out of the layout, leaving the box 11px and the letters whole.
1995
+ * The intro block, then a bordered card holding two numbered steps, then "Done". The card
1996
+ * is padded 16 with 24 between its steps; the steps themselves are 16 and 8 internally.
1418
1997
  */
1419
- ._subtitle_8yxu9_65 {
1420
- margin: -6px 0;
1421
- padding: 6px 0;
1422
- font-size: var(--type-paragraph-size);
1998
+ ._page_1r0ea_7 {
1999
+ display: flex;
2000
+ flex-direction: column;
2001
+ gap: var(--space-24);
2002
+ padding: var(--space-20) var(--space-16);
2003
+ background: var(--color-surface-default);
2004
+ }
2005
+
2006
+ ._intro_1r0ea_15 {
2007
+ display: flex;
2008
+ flex-direction: column;
2009
+ gap: var(--space-8);
2010
+ }
2011
+
2012
+ /* `trimmed/md` bold, cap-trimmed to 11 — the frame's heading here is 16, not 20. */
2013
+ ._title_1r0ea_22 {
2014
+ font-size: var(--type-trimmed-md-size);
1423
2015
  line-height: 11px;
1424
- font-weight: var(--font-weight-regular);
2016
+ padding: 5px 0;
2017
+ margin: -5px 0;
2018
+ font-weight: var(--font-weight-bold);
2019
+ color: var(--color-text-default);
2020
+ }
2021
+
2022
+ ._subtitle_1r0ea_31 {
2023
+ margin: 0;
2024
+ font-size: var(--type-caption-sm-size);
2025
+ line-height: var(--type-caption-sm-line);
1425
2026
  color: var(--color-text-subtle);
1426
- overflow: hidden;
1427
- text-overflow: ellipsis;
1428
- white-space: nowrap;
1429
2027
  }
1430
2028
 
1431
- /* ── Lines ─────────────────────────────────────────────────────────────────── */
2029
+ /* radius-xxl in the DS — 18 here, the same corner the return cards take. */
2030
+ ._card_1r0ea_39 {
2031
+ display: flex;
2032
+ flex-direction: column;
2033
+ gap: var(--space-24);
2034
+ padding: var(--space-16);
2035
+ border: 1px solid var(--color-border-default);
2036
+ border-radius: var(--radius-18);
2037
+ }
2038
+
2039
+ /* Step one carries a button and a note, so its parts are 16 apart. */
2040
+ ._step_1r0ea_49 {
2041
+ display: flex;
2042
+ flex-direction: column;
2043
+ gap: var(--space-16);
2044
+ }
2045
+
2046
+ /* Step two is a heading and a paragraph, at 8. */
2047
+ ._step2_1r0ea_56 {
2048
+ display: flex;
2049
+ flex-direction: column;
2050
+ gap: var(--space-8);
2051
+ }
2052
+
2053
+ ._stepHead_1r0ea_62 {
2054
+ display: flex;
2055
+ align-items: center;
2056
+ gap: var(--space-8);
2057
+ }
2058
+
2059
+ /* A 24 square at radius 6 on the soft ground — a marker, not a circle. */
2060
+ ._number_1r0ea_69 {
2061
+ display: inline-flex;
2062
+ align-items: center;
2063
+ justify-content: center;
2064
+ flex-shrink: 0;
2065
+ width: 24px;
2066
+ height: 24px;
2067
+ border-radius: var(--radius-6);
2068
+ background: var(--color-surface-soft);
2069
+ font-size: var(--type-caption-sm-size);
2070
+ line-height: 1.5;
2071
+ font-weight: var(--font-weight-bold);
2072
+ color: var(--color-text-default);
2073
+ }
2074
+
2075
+ ._stepTitle_1r0ea_84 {
2076
+ flex: 1 1 0;
2077
+ min-width: 0;
2078
+ font-size: var(--type-trimmed-md-size);
2079
+ line-height: 11px;
2080
+ padding: 5px 0;
2081
+ margin: -5px 0;
2082
+ font-weight: var(--font-weight-bold);
2083
+ color: var(--color-text-default);
2084
+ }
2085
+
2086
+ ._body_1r0ea_95 {
2087
+ margin: 0;
2088
+ font-size: var(--type-caption-sm-size);
2089
+ line-height: var(--type-caption-sm-line);
2090
+ color: var(--color-text-default);
2091
+ }
2092
+
2093
+ /* The frame gives this paragraph 4 of spacing between its two lines. */
2094
+ ._body2_1r0ea_103 {
2095
+ margin: 0;
2096
+ font-size: var(--type-caption-sm-size);
2097
+ line-height: var(--type-caption-sm-line);
2098
+ color: var(--color-text-default);
2099
+ }
2100
+
2101
+ ._body2_1r0ea_103 br {
2102
+ content: '';
2103
+ display: block;
2104
+ margin-bottom: var(--space-4);
2105
+ }
1432
2106
 
1433
2107
  /*
1434
- * `mobile/checkout/cart-row`, and deliberately NOT inside a card.
2108
+ * `mobile/button` at the small size: 40 rather than 48, outlined in the static dark
2109
+ * border, and 14 rather than 16. It is a secondary action inside a card, not the screen's
2110
+ * own call to action — the frame keeps "Done" for that.
2111
+ */
2112
+ ._download_1r0ea_121 {
2113
+ display: inline-flex;
2114
+ align-items: center;
2115
+ justify-content: center;
2116
+ gap: var(--space-8);
2117
+ min-height: 40px;
2118
+ padding: var(--space-6) var(--space-8);
2119
+ border: 1px solid var(--color-surface-max);
2120
+ border-radius: var(--radius-8);
2121
+ color: var(--color-text-default);
2122
+ font-size: var(--type-trimmed-sm-size);
2123
+ line-height: 10px;
2124
+ font-weight: var(--font-weight-bold);
2125
+ text-decoration: none;
2126
+ }
2127
+
2128
+ ._download_1r0ea_121:focus-visible {
2129
+ outline: none;
2130
+ box-shadow: var(--focus-ring);
2131
+ }
2132
+
2133
+ /* 12 with the library's 1% tracking. */
2134
+ ._note_1r0ea_143 {
2135
+ margin: 0;
2136
+ font-size: var(--type-trimmed-xs-size);
2137
+ line-height: 1.5;
2138
+ letter-spacing: 0.12px;
2139
+ color: var(--color-text-default);
2140
+ }
2141
+ /*
2142
+ * Figma `Return flow` (4551:32294), screens 6 to 8 — "Return in progress".
1435
2143
  *
1436
- * The tracking screen puts its items in a bordered "Items" card with a count; this frame
1437
- * lays them straight on the page between the timeline and the address. The same data, and
1438
- * two designs so the row is written here rather than either screen being bent to fit the
1439
- * other, and `CartLineItem` is left alone because its copy of this component carries a
1440
- * quantity stepper and a remove control that a receipt must not have.
2144
+ * The title block, the three-step timeline, then the lines coming back. Same 20/16
2145
+ * padding and same rhythm as the order tracking screen, because it is the same screen
2146
+ * with a different subject.
1441
2147
  */
1442
- ._lines_8yxu9_88 {
2148
+ ._page_o44fl_8 {
2149
+ display: flex;
2150
+ flex-direction: column;
2151
+ gap: var(--space-24);
2152
+ padding: var(--space-20) var(--space-16) var(--space-24);
2153
+ }
2154
+
2155
+ ._titles_o44fl_15 {
2156
+ display: flex;
2157
+ flex-direction: column;
2158
+ gap: var(--space-8);
2159
+ }
2160
+
2161
+ ._title_o44fl_15 {
2162
+ margin: 0;
2163
+ font-size: var(--type-heading-md-size);
2164
+ line-height: 1.32;
2165
+ font-weight: var(--font-weight-bold);
2166
+ color: var(--color-text-default);
2167
+ }
2168
+
2169
+ /* 14 cap-trimmed to 10 — the reference and the reported date on one line. */
2170
+ ._subtitle_o44fl_30 {
2171
+ font-size: var(--type-trimmed-sm-size);
2172
+ line-height: 10px;
2173
+ padding: 5px 0;
2174
+ margin: -5px 0;
2175
+ color: var(--color-text-subtle);
2176
+ }
2177
+
2178
+ ._items_o44fl_38 {
1443
2179
  list-style: none;
1444
2180
  margin: 0;
1445
2181
  padding: 0;
@@ -1448,41 +2184,32 @@
1448
2184
  gap: var(--space-16);
1449
2185
  }
1450
2186
 
1451
- ._line_8yxu9_88 {
2187
+ ._item_o44fl_38 {
1452
2188
  display: flex;
1453
2189
  align-items: center;
1454
2190
  gap: var(--space-12);
1455
2191
  }
1456
2192
 
1457
- ._thumb_8yxu9_103 {
2193
+ ._thumb_o44fl_53 {
1458
2194
  position: relative;
1459
2195
  flex-shrink: 0;
1460
2196
  width: 48px;
1461
2197
  height: 48px;
1462
- border-radius: var(--radius-8);
2198
+ border-radius: var(--radius-6);
1463
2199
  overflow: hidden;
1464
- background: var(--color-surface-soft);
2200
+ background: var(--color-surface-subtle);
1465
2201
  }
1466
2202
 
1467
- ._image_8yxu9_113 {
2203
+ ._img_o44fl_63 {
1468
2204
  object-fit: cover;
1469
2205
  }
1470
2206
 
1471
- ._placeholder_8yxu9_117 {
2207
+ ._placeholder_o44fl_67 {
1472
2208
  width: 100%;
1473
2209
  height: 100%;
1474
2210
  }
1475
2211
 
1476
- ._lineBody_8yxu9_122 {
1477
- display: flex;
1478
- align-items: flex-start;
1479
- justify-content: space-between;
1480
- gap: var(--space-16);
1481
- flex: 1 1 0;
1482
- min-width: 0;
1483
- }
1484
-
1485
- ._lineText_8yxu9_131 {
2212
+ ._meta_o44fl_72 {
1486
2213
  display: flex;
1487
2214
  flex-direction: column;
1488
2215
  gap: var(--space-12);
@@ -1490,116 +2217,139 @@
1490
2217
  min-width: 0;
1491
2218
  }
1492
2219
 
1493
- /* Cap-trimmed to the frame's 11, with the same descender protection as the subtitle —
1494
- this one is ellipsised too, and a `p` or a `g` in a product name is not unusual. */
1495
- ._lineTitle_8yxu9_141 {
1496
- margin: -6px 0;
1497
- padding: 6px 0;
2220
+ ._name_o44fl_80 {
1498
2221
  font-size: var(--type-trimmed-sm-size);
1499
- line-height: 11px;
2222
+ line-height: 10px;
2223
+ padding: 5px 0;
2224
+ margin: -5px 0;
1500
2225
  font-weight: var(--font-weight-bold);
1501
- white-space: nowrap;
2226
+ color: var(--color-text-default);
1502
2227
  overflow: hidden;
1503
2228
  text-overflow: ellipsis;
2229
+ white-space: nowrap;
1504
2230
  }
1505
2231
 
1506
2232
  /*
1507
- * The variant, then the sale badge beside it 12px apart, vertically centred on it.
2233
+ * "Size: M" and the sale badge on one row, as the frame has them. `align-items: center`
2234
+ * rather than baseline: the badge is a 20px box and its text is 12px, so a baseline would
2235
+ * hang it below the size it sits beside.
1508
2236
  *
1509
- * Cap-trimmed like the title above, which is what leaves the badge as the tallest thing in
1510
- * the row and holds it to the 20px the frame gives it. Untrimmed the text alone was 22, so
1511
- * the row stood 55 against the frame's 48 and the thumbnail stopped being what sets the
1512
- * row's height.
2237
+ * The trim pair stays on the TEXT, not on the row the badge brings its own height, and
2238
+ * a negative margin on the flex container would eat into the gap above it.
1513
2239
  */
1514
- ._lineMeta_8yxu9_160 {
2240
+ ._attrs_o44fl_100 {
2241
+ margin: 0;
1515
2242
  display: flex;
1516
- align-items: center;
1517
- gap: var(--space-12);
1518
- min-width: 0;
1519
- font-size: var(--type-trimmed-sm-size);
1520
- line-height: 11px;
2243
+ align-items: center;
2244
+ gap: var(--space-8);
1521
2245
  color: var(--color-text-subtle);
1522
2246
  }
1523
2247
 
1524
- /*
1525
- * Stacked, not in a row: the frame puts what was paid above what it would have cost, at
1526
- * two different sizes. That is why this is written here rather than with `PriceBlock`,
1527
- * which lays the pair out inline at one size for the product card and the PDP.
1528
- */
1529
- ._linePrice_8yxu9_175 {
2248
+ ._attrs_o44fl_100 > span {
2249
+ font-size: var(--type-trimmed-sm-size);
2250
+ line-height: 10px;
2251
+ padding: 5px 0;
2252
+ margin: -5px 0;
2253
+ }
2254
+
2255
+ ._price_o44fl_115 {
1530
2256
  display: flex;
1531
2257
  flex-direction: column;
1532
2258
  align-items: flex-end;
1533
2259
  gap: var(--space-6);
1534
2260
  flex-shrink: 0;
1535
- white-space: nowrap;
1536
- font-variant-numeric: tabular-nums;
2261
+ text-align: right;
1537
2262
  }
1538
2263
 
1539
- /* Cap-trimmed like everything else in this row: 11 on 16px, 10 on 14px. Untrimmed the
1540
- pair stood 52 tall and became what set the row's height, against a 48px thumbnail. */
1541
- ._paid_8yxu9_187 {
2264
+ ._paid_o44fl_124 {
1542
2265
  font-size: var(--type-trimmed-md-size);
1543
2266
  line-height: 11px;
1544
2267
  font-weight: var(--font-weight-bold);
2268
+ color: var(--color-text-default);
2269
+ font-variant-numeric: tabular-nums;
1545
2270
  }
1546
2271
 
1547
- ._was_8yxu9_193 {
2272
+ ._was_o44fl_132 {
1548
2273
  font-size: var(--type-trimmed-sm-size);
1549
2274
  line-height: 10px;
1550
- font-weight: var(--font-weight-regular);
1551
2275
  color: var(--color-text-disabled);
1552
2276
  text-decoration: line-through;
2277
+ font-variant-numeric: tabular-nums;
1553
2278
  }
1554
-
1555
- /* ── Cards ─────────────────────────────────────────────────────────────────── */
1556
-
1557
2279
  /*
1558
- * The address and summary cards are one shape: a 60px titled header, a hairline, and a
1559
- * body. They differ only in ground, which is what `.summaryCard` below changes.
1560
- *
1561
- * The ring is an inset shadow rather than a border, and that is a measurement rather than
1562
- * a preference. Figma draws a frame's stroke INSIDE its box, so the address card is 113
1563
- * tall with its outline in that 113 — 60 of header and 53 of body. A CSS border sits
1564
- * outside the content and makes the same card 115. An inset shadow paints the same
1565
- * hairline and occupies no layout, so the card lands on the design's own number.
2280
+ * Figma `5295:74053`. The page's own block starts at y=118 under the 64px bar and the
2281
+ * 54px status bar the device draws above it with 20px above the first heading, 24px
2282
+ * below the last control, and 32px between the five blocks.
1566
2283
  */
1567
- ._card_8yxu9_213 {
2284
+ ._page_1s8l9_6 {
1568
2285
  display: flex;
1569
2286
  flex-direction: column;
1570
- box-shadow: inset 0 0 0 1px var(--color-border-default);
1571
- border-radius: var(--radius-18);
1572
- overflow: hidden;
2287
+ gap: var(--space-32);
2288
+ padding: var(--space-20) var(--space-16) var(--space-24);
1573
2289
  }
1574
2290
 
1575
- ._cardTitle_8yxu9_221 {
2291
+ /* ── Confirmation + timeline ───────────────────────────────────────────────── */
2292
+
2293
+ /* `mobile/order/delivery-widget`: the heading pair, then the timeline, 24px apart. */
2294
+ ._confirmed_1s8l9_16 {
1576
2295
  display: flex;
1577
- align-items: center;
1578
- margin: 0;
1579
- min-height: 60px;
1580
- padding: 0 var(--space-16);
1581
- border-bottom: 1px solid var(--color-border-default);
1582
- font-size: var(--type-heading-md-size);
1583
- line-height: 1.38;
1584
- font-weight: var(--font-weight-bold);
2296
+ flex-direction: column;
2297
+ gap: var(--space-24);
1585
2298
  }
1586
2299
 
1587
- ._cardBody_8yxu9_233 {
1588
- margin: 0;
1589
- padding: var(--space-16);
1590
- font-size: var(--type-trimmed-sm-size);
1591
- line-height: 1.5;
2300
+ ._title_1s8l9_22 {
2301
+ display: flex;
2302
+ flex-direction: column;
2303
+ gap: var(--space-12);
1592
2304
  }
1593
2305
 
1594
- /* `surface/full-color/soft` — the summary is the one card the design fills. */
1595
- ._summaryCard_8yxu9_205 {
1596
- background: var(--color-surface-soft);
2306
+ /*
2307
+ * Green, and the only green heading in the storefront: `semantic/state/text/success`
2308
+ * rather than `text/default`, which is the design saying this line is a result and not a
2309
+ * label. It is the same token the discount row and the "Free" shipping figure take, so
2310
+ * the screen has one success tone rather than three.
2311
+ *
2312
+ * `line-height: 14px` on 20px text, and that is the frame's own number rather than a
2313
+ * squeeze: every text layer here is `text-box-trim: trim-both` with a cap-alphabetic
2314
+ * edge, so Figma's boxes stop at the cap height and its 14 is 14 of visible letter. A CSS
2315
+ * line box carries the font's leading above and below, which renders the same heading as
2316
+ * 26 and pushes all four blocks below it down by the difference.
2317
+ *
2318
+ * `text-box-trim` would let us write the design's own number and is Chrome 133+ only; this
2319
+ * package still supports the WebView in React 16-era DAZN builds. `OrderTimeline` and
2320
+ * `ProductTile` carry the same approximation for the same reason.
2321
+ *
2322
+ * Nothing clips it, so the cap-height box needs no descender protection — unlike the
2323
+ * subtitle below, which the design truncates.
2324
+ */
2325
+ ._headline_1s8l9_47 {
2326
+ margin: 0;
2327
+ font-size: var(--type-heading-md-size);
2328
+ line-height: 14px;
2329
+ font-weight: var(--font-weight-bold);
2330
+ color: var(--color-state-text-success);
1597
2331
  }
1598
2332
 
1599
- /* The shared summary rows are drawn edge-to-edge in the cart; here they take the card's
1600
- own gutter, as they do on the tracking screen. */
1601
- ._summaryCard_8yxu9_205 > :last-child {
1602
- padding: 0 var(--space-16);
2333
+ /*
2334
+ * 11px on 16px text, the same cap-height trim as the heading, and one line: the design's
2335
+ * own text layer is `overflow-hidden` with `text-ellipsis`, which is how it holds an
2336
+ * address of unknown length to a single row.
2337
+ *
2338
+ * The padding is what the trim costs. Clipping cuts in both directions, and an 11px box
2339
+ * beheads every descender — including the `g` in the `@gmail.com` the frame itself shows.
2340
+ * The padding gives the glyphs somewhere to go and the equal negative margin takes it back
2341
+ * out of the layout, leaving the box 11px and the letters whole.
2342
+ */
2343
+ ._subtitle_1s8l9_65 {
2344
+ margin: -6px 0;
2345
+ padding: 6px 0;
2346
+ font-size: var(--type-paragraph-size);
2347
+ line-height: 11px;
2348
+ font-weight: var(--font-weight-regular);
2349
+ color: var(--color-text-subtle);
2350
+ overflow: hidden;
2351
+ text-overflow: ellipsis;
2352
+ white-space: nowrap;
1603
2353
  }
1604
2354
 
1605
2355
  /* ── Done ──────────────────────────────────────────────────────────────────── */
@@ -1612,7 +2362,7 @@
1612
2362
  * which is what "max" means, and taking it from that token keeps the two in step if the
1613
2363
  * palette ever moves.
1614
2364
  */
1615
- ._done_8yxu9_261 {
2365
+ ._done_1s8l9_87 {
1616
2366
  border-color: var(--color-surface-max);
1617
2367
  }
1618
2368
  /*
@@ -1650,8 +2400,8 @@
1650
2400
  background: var(--color-state-surface-critical-soft);
1651
2401
  color: var(--color-state-text-critical);
1652
2402
  }
1653
- /* Figma `mobile/order/list` (4024:58594). */
1654
- ._page_y686q_2 {
2403
+ /* Figma `mobile/order/list` (4551:32241, in the `my orders` section 4551:32237). */
2404
+ ._page_6xodo_2 {
1655
2405
  list-style: none;
1656
2406
  margin: 0;
1657
2407
  display: flex;
@@ -1660,18 +2410,28 @@
1660
2410
  padding: var(--space-16) var(--space-16) var(--space-24);
1661
2411
  }
1662
2412
 
1663
- ._empty_y686q_11 {
2413
+ /*
2414
+ * The design centres the empty state in the whole screen below the header, not at the top
2415
+ * of an otherwise blank page: the block runs from the bar's bottom edge to 32px above the
2416
+ * foot of the display, with its contents centred inside that.
2417
+ *
2418
+ * The frame's own numbers are 96 to 780 of 812, and 96 is where the bar ended when this
2419
+ * screen was drawn — the cart's empty frame (4451:48190) has the same block at the same
2420
+ * two numbers under a 96px header. The bar is 118 with the status bar now, so following
2421
+ * the frame's literal 96 would tuck the heading under it. Measuring from the bar instead
2422
+ * keeps the intent and lands the block 11px lower than the export.
2423
+ */
2424
+ ._empty_6xodo_22 {
1664
2425
  display: flex;
1665
2426
  align-items: center;
1666
2427
  justify-content: center;
1667
- /* The design centres the empty state in the whole screen below the header, not at the
1668
- top of an otherwise blank page. */
1669
- min-height: 60dvh;
2428
+ min-height: calc(100dvh - var(--header-height) - var(--space-32));
2429
+ padding-bottom: var(--space-32);
1670
2430
  }
1671
2431
 
1672
2432
  /* `mobile/button`, the design's own dark CTA. Not the shared `Button` primary, whose
1673
2433
  shape is the cart's; this one is content-width with a 48px floor. */
1674
- ._cta_y686q_22 {
2434
+ ._cta_6xodo_32 {
1675
2435
  display: inline-flex;
1676
2436
  align-items: center;
1677
2437
  justify-content: center;
@@ -1689,12 +2449,12 @@
1689
2449
  cursor: pointer;
1690
2450
  }
1691
2451
 
1692
- ._cta_y686q_22:focus-visible {
2452
+ ._cta_6xodo_32:focus-visible {
1693
2453
  outline: none;
1694
2454
  box-shadow: var(--focus-ring);
1695
2455
  }
1696
2456
 
1697
- ._card_y686q_45 {
2457
+ ._card_6xodo_55 {
1698
2458
  display: flex;
1699
2459
  flex-direction: column;
1700
2460
  gap: var(--space-24);
@@ -1709,16 +2469,16 @@
1709
2469
  overflow: hidden;
1710
2470
  }
1711
2471
 
1712
- ._tappable_y686q_60 {
2472
+ ._tappable_6xodo_70 {
1713
2473
  cursor: pointer;
1714
2474
  }
1715
2475
 
1716
- ._tappable_y686q_60:focus-visible {
2476
+ ._tappable_6xodo_70:focus-visible {
1717
2477
  outline: none;
1718
2478
  box-shadow: var(--focus-ring);
1719
2479
  }
1720
2480
 
1721
- ._head_y686q_69 {
2481
+ ._head_6xodo_79 {
1722
2482
  display: flex;
1723
2483
  align-items: flex-start;
1724
2484
  justify-content: space-between;
@@ -1726,7 +2486,7 @@
1726
2486
  width: 100%;
1727
2487
  }
1728
2488
 
1729
- ._heading_y686q_77 {
2489
+ ._heading_6xodo_87 {
1730
2490
  display: flex;
1731
2491
  flex: 1 1 auto;
1732
2492
  flex-direction: column;
@@ -1735,7 +2495,7 @@
1735
2495
  color: var(--color-text-default);
1736
2496
  }
1737
2497
 
1738
- ._title_y686q_86 {
2498
+ ._title_6xodo_96 {
1739
2499
  font-size: var(--type-heading-md-size);
1740
2500
  font-weight: var(--font-weight-bold);
1741
2501
  /* The frame's own 1.32, not the token's 1.25 — that value was set from a different
@@ -1746,12 +2506,20 @@
1746
2506
  white-space: nowrap;
1747
2507
  }
1748
2508
 
1749
- ._date_y686q_97 {
2509
+ /*
2510
+ * 10px on 14px text: the date is `text-box-trim: trim-both` with a cap-alphabetic edge, so
2511
+ * Figma's box stops at the cap height. The row's own height depends on it — untrimmed the
2512
+ * card stood 160 against the frame's 156, and every card below it inherited the drift.
2513
+ *
2514
+ * Nothing clips this one, so it needs no descender protection: the comma and a Spanish
2515
+ * "sept" hang below the box and are drawn, as they are in the frame.
2516
+ */
2517
+ ._date_6xodo_115 {
1750
2518
  font-size: var(--type-trimmed-sm-size);
1751
- line-height: 1;
2519
+ line-height: 10px;
1752
2520
  }
1753
2521
 
1754
- ._bottom_y686q_102 {
2522
+ ._bottom_6xodo_120 {
1755
2523
  display: flex;
1756
2524
  align-items: center;
1757
2525
  justify-content: space-between;
@@ -1759,12 +2527,12 @@
1759
2527
  width: 100%;
1760
2528
  }
1761
2529
 
1762
- ._strip_y686q_110 {
2530
+ ._strip_6xodo_128 {
1763
2531
  display: flex;
1764
2532
  gap: var(--space-6);
1765
2533
  }
1766
2534
 
1767
- ._tile_y686q_115 {
2535
+ ._tile_6xodo_133 {
1768
2536
  position: relative;
1769
2537
  flex: 0 0 56px;
1770
2538
  width: 56px;
@@ -1774,18 +2542,18 @@
1774
2542
  background: var(--color-surface-subtle);
1775
2543
  }
1776
2544
 
1777
- ._image_y686q_125 {
2545
+ ._image_6xodo_143 {
1778
2546
  object-fit: cover;
1779
2547
  }
1780
2548
 
1781
- ._placeholder_y686q_129 {
2549
+ ._placeholder_6xodo_147 {
1782
2550
  /* No picture resolved for any line. A flat tile keeps the row's rhythm rather than
1783
2551
  collapsing the strip and shifting the chevron. */
1784
2552
  background: var(--color-surface-subtle);
1785
2553
  }
1786
2554
 
1787
2555
  /* The "+N" tile: the last thumbnail, dimmed, with the count over it. */
1788
- ._more_y686q_136 {
2556
+ ._more_6xodo_154 {
1789
2557
  position: absolute;
1790
2558
  inset: 0;
1791
2559
  display: flex;
@@ -1798,24 +2566,28 @@
1798
2566
  line-height: 1;
1799
2567
  }
1800
2568
 
1801
- ._chevron_y686q_149 {
2569
+ ._chevron_6xodo_167 {
1802
2570
  display: inline-flex;
1803
2571
  flex: 0 0 24px;
1804
2572
  width: 24px;
1805
2573
  height: 24px;
1806
2574
  color: var(--color-text-default);
1807
2575
  }
1808
- /* 8 where Figma declares 12, for the reason set out on `.titlePrice` below: the gap sits
1809
- against a text layer whose CSS line box carries leading that Figma's does not. */
1810
- ._tile_1u9l8_3 {
2576
+ /*
2577
+ * The frame's own 12, now that the text below it is trimmed to its cap height like the
2578
+ * frame's. This was 8 — half the declared number — which put the glyphs in the right place
2579
+ * and left the card 11px taller than the frame, because the compensation was in the gap
2580
+ * rather than in the box that was wrong. See `.title`.
2581
+ */
2582
+ ._tile_1io44_7 {
1811
2583
  display: flex;
1812
2584
  flex-direction: column;
1813
- gap: var(--space-8);
2585
+ gap: var(--space-12);
1814
2586
  text-decoration: none;
1815
2587
  color: inherit;
1816
2588
  }
1817
2589
 
1818
- ._media_1u9l8_11 {
2590
+ ._media_1io44_15 {
1819
2591
  position: relative;
1820
2592
  width: 100%;
1821
2593
  /* Product-card image is 165:220 (3:4), radius-6 (Figma), sharp not pill-round. */
@@ -1825,11 +2597,11 @@
1825
2597
  background: var(--color-surface-soft);
1826
2598
  }
1827
2599
 
1828
- ._image_1u9l8_21 {
2600
+ ._image_1io44_25 {
1829
2601
  object-fit: cover;
1830
2602
  }
1831
2603
 
1832
- ._placeholder_1u9l8_25 {
2604
+ ._placeholder_1io44_29 {
1833
2605
  width: 100%;
1834
2606
  height: 100%;
1835
2607
  background: var(--color-surface-soft);
@@ -1837,7 +2609,7 @@
1837
2609
 
1838
2610
  /* TOP PICK flag — top-left over the image, white surface, radius-2, uppercase. Fixed
1839
2611
  colours (not theme tokens): it always sits over a light product image. */
1840
- ._topBadge_1u9l8_33 {
2612
+ ._topBadge_1io44_37 {
1841
2613
  position: absolute;
1842
2614
  top: var(--space-8);
1843
2615
  left: var(--space-8);
@@ -1848,7 +2620,13 @@
1848
2620
  max-width: calc(100% - var(--space-8) * 2);
1849
2621
  overflow: hidden;
1850
2622
  text-overflow: ellipsis;
1851
- padding: var(--space-4) var(--space-6);
2623
+ /* `mobile/badge/top-pick` fixes the box at 20 — it does not hug its leading. That was
2624
+ invisible while `--type-trimmed-xs-line` was `1`, because 4 + 12 + 4 happened to come
2625
+ to 20; with the token carrying the real cap (9) it would have shrunk to 17. */
2626
+ display: inline-flex;
2627
+ align-items: center;
2628
+ height: 20px;
2629
+ padding: 0 var(--space-6);
1852
2630
  border-radius: var(--radius-2);
1853
2631
  background: #f9fafa;
1854
2632
  color: #0c161c;
@@ -1860,14 +2638,27 @@
1860
2638
  white-space: nowrap;
1861
2639
  }
1862
2640
 
1863
- ._saleBadge_1u9l8_56 {
2641
+ /*
2642
+ * `display: block` is not decoration. The wrapper is a `span`, so as an inline box it
2643
+ * reserves room for the font's descenders around the 20px badge inside it — measured 25,
2644
+ * which pushed the badge 2.5px off the 8px inset the frame draws it at.
2645
+ */
2646
+ /*
2647
+ * `display: flex`, and it is load-bearing. The wrapper is a `span`, so left inline — or
2648
+ * even as a `block` — it builds a LINE box around the 20px badge and reserves the font's
2649
+ * descender room under it: measured 25 against the badge's 20, which put the badge 13px
2650
+ * above the image's edge where the frame draws it 8. A flex container makes the badge a
2651
+ * flex item, and a flex item has no line box.
2652
+ */
2653
+ ._saleBadge_1io44_78 {
1864
2654
  position: absolute;
2655
+ display: flex;
1865
2656
  bottom: var(--space-8);
1866
2657
  left: var(--space-8);
1867
2658
  }
1868
2659
 
1869
2660
  /* Scrim over the whole image, not a corner flag (Figma out-of-stock state). */
1870
- ._oos_1u9l8_63 {
2661
+ ._oos_1io44_86 {
1871
2662
  position: absolute;
1872
2663
  inset: 0;
1873
2664
  display: flex;
@@ -1881,32 +2672,57 @@
1881
2672
  }
1882
2673
 
1883
2674
  /*
1884
- * 8, where Figma declares 16 — and this is not a drift, so please do not "correct" it.
2675
+ * Figma's own 16, both here and on `.titlePrice`.
1885
2676
  *
1886
- * Every text layer in this card is `text-box-trim: trim-both` with a cap-alphabetic edge:
1887
- * Figma's boxes stop at the cap height and the baseline, so its 16 is 16 of visible white.
1888
- * A CSS line box carries the font's leading above and below the glyphs, so the same 16
1889
- * renders as 23 measured off both, title glyph bottom to price glyph top: Figma 15, ours
1890
- * 23. Halving the declared gap puts ours at 15.
2677
+ * These were 8 half the declared number and the halving was right about the cause and
2678
+ * wrong about the cure. Every text layer in this card is `text-box-trim: trim-both` with a
2679
+ * cap-alphabetic edge, so Figma's boxes stop at the cap height and its 16 is 16 of visible
2680
+ * white, where a CSS line box carries the font's leading and renders the same 16 as 23.
2681
+ * Halving the gap put the glyphs in the right place and left the BOX 11px too tall, which
2682
+ * is invisible on one card and is the whole page by the bottom of the PCP: measured at
2683
+ * 375, ours ran 3776 against the frame's 3384.
1891
2684
  *
1892
- * `text-box-trim` would let us write the design's own number, and it is Chrome 133+ only.
1893
- * This package still supports the WebView that ships with React 16-era DAZN builds.
2685
+ * The trim now lives on the text, as it does on the order screens, so the gaps can be the
2686
+ * design's own numbers again.
1894
2687
  */
1895
- ._bottom_1u9l8_88 {
2688
+ ._bottom_1io44_113 {
1896
2689
  display: flex;
1897
2690
  flex-direction: column;
1898
- gap: var(--space-8);
2691
+ gap: var(--space-16);
1899
2692
  }
1900
2693
 
1901
- ._titlePrice_1u9l8_1 {
2694
+ ._titlePrice_1io44_100 {
1902
2695
  display: flex;
1903
2696
  flex-direction: column;
1904
- gap: var(--space-8);
2697
+ gap: var(--space-16);
1905
2698
  }
1906
2699
 
1907
- ._title_1u9l8_1 {
2700
+ /*
2701
+ * Trimmed to the cap height, in the only way that also keeps the leading BETWEEN two
2702
+ * lines: `line-height` carries the design's line-to-line distance (11 of cap + 10 of
2703
+ * leading = 21), and the padding/negative-margin pair takes the outer half-leading back
2704
+ * out of the layout. The frame's two-line name box is 32 — 11 + 10 + 11 — and so is this.
2705
+ *
2706
+ * The padding is not decoration: `-webkit-line-clamp` needs `overflow: hidden`, which
2707
+ * clips in both directions, and an 11px box beheads every descender — the `p` in
2708
+ * "Zip-Up", the `y` in "Everyday". The padding gives them room inside the clip box and
2709
+ * the margin removes it from the layout.
2710
+ *
2711
+ * `text-box-trim` would let us write the design's numbers directly; it is Chrome 133+ and
2712
+ * this package still supports the WebView that ships with React 16-era DAZN builds.
2713
+ */
2714
+ ._title_1io44_5 {
1908
2715
  font-size: var(--type-paragraph-size);
1909
- line-height: 1.3;
2716
+ line-height: 21px;
2717
+ padding: 5px 0;
2718
+ /*
2719
+ * Ten, not five: the margin has two jobs. Five cancels the padding above, which exists
2720
+ * only to keep the clip box off the descenders; the other five is the half-leading the
2721
+ * trim removes — (21 - 11) / 2 — above the first line and below the last. A single
2722
+ * two-line name is then 32 in the layout and 52 on screen, which is where the padding
2723
+ * went.
2724
+ */
2725
+ margin: -10px 0;
1910
2726
  font-weight: var(--font-weight-regular);
1911
2727
  color: var(--color-text-default);
1912
2728
  display: -webkit-box;
@@ -1917,30 +2733,46 @@
1917
2733
  /* Reserve both lines rather than only capping at two. The clamp stops a long title
1918
2734
  overflowing but lets a short one collapse to one line, and in a two-column grid that
1919
2735
  pulls its price up level with the neighbour's title — a ragged price baseline across
1920
- the row, which reads as broken alignment rather than as varying title lengths. */
1921
- min-height: calc(2 * 1.3em);
2736
+ the row, which reads as broken alignment rather than as varying title lengths.
2737
+ Two line boxes, which the margins above bring back to the frame's 32. */
2738
+ min-height: calc(2 * 21px + 10px);
2739
+ }
2740
+
2741
+ /*
2742
+ * The price row, trimmed to its own cap: 11 on 16px, which is what makes the card's text
2743
+ * block 32 + 16 + 11 = 59, as the frame draws it.
2744
+ *
2745
+ * Scoped here rather than set on `PriceBlock` itself, which the PDP also renders — its
2746
+ * row is measured against a different frame and must not move with this one.
2747
+ */
2748
+ ._titlePrice_1io44_100 > :last-child {
2749
+ line-height: 11px;
1922
2750
  }
1923
2751
 
1924
2752
  /* Colour swatches (Figma product-card): 0.5px-bordered boxes with a 14px colour square;
1925
2753
  the first reads as selected (dark border). */
1926
- ._swatches_1u9l8_119 {
2754
+ ._swatches_1io44_179 {
1927
2755
  display: flex;
1928
2756
  gap: var(--space-4);
1929
2757
  align-items: center;
1930
2758
  }
1931
2759
 
1932
- ._swatch_1u9l8_119 {
2760
+ /*
2761
+ * 18 on the nose: 14 of colour with 2 either side, and the outline drawn INSIDE that,
2762
+ * which is where Figma draws a stroke. As a `border` it sat outside and made the box 19.
2763
+ */
2764
+ ._swatch_1io44_179 {
1933
2765
  display: inline-flex;
1934
2766
  padding: 2px;
1935
- border: 0.5px solid var(--color-border-subtle);
2767
+ box-shadow: inset 0 0 0 0.5px var(--color-border-subtle);
1936
2768
  border-radius: var(--radius-2);
1937
2769
  }
1938
2770
 
1939
- ._swatchActive_1u9l8_132 {
1940
- border-color: var(--color-surface-max);
2771
+ ._swatchActive_1io44_196 {
2772
+ box-shadow: inset 0 0 0 0.5px var(--color-surface-max);
1941
2773
  }
1942
2774
 
1943
- ._swatchDot_1u9l8_136 {
2775
+ ._swatchDot_1io44_200 {
1944
2776
  display: block;
1945
2777
  width: 14px;
1946
2778
  height: 14px;
@@ -1951,11 +2783,11 @@
1951
2783
  * Spotlight card (Figma `size=large`, 3668:12485). Full-bleed with its own 16px gutter —
1952
2784
  * the block that places it adds none — a taller 343:457 image and an 18px title.
1953
2785
  */
1954
- ._large_1u9l8_147 {
2786
+ ._large_1io44_211 {
1955
2787
  padding: 0 var(--space-16);
1956
2788
  }
1957
2789
 
1958
- ._large_1u9l8_147 ._media_1u9l8_11 {
2790
+ ._large_1io44_211 ._media_1io44_15 {
1959
2791
  aspect-ratio: 343 / 457;
1960
2792
  }
1961
2793
 
@@ -1964,11 +2796,181 @@
1964
2796
  * keep their prices on one baseline, and the spotlight card is alone on its row — there is
1965
2797
  * nothing to line up with, so all it reserves is empty space under a one-line title.
1966
2798
  * Figma's note on this variant is "height hugs".
2799
+ *
2800
+ * 23 = the cap of 18px text (13) plus the same 10 of leading, so the margins above leave a
2801
+ * one-line name 13 tall — the frame's number for this variant.
1967
2802
  */
1968
- ._large_1u9l8_147 ._title_1u9l8_1 {
2803
+ ._large_1io44_211 ._title_1io44_5 {
1969
2804
  font-size: 18px;
2805
+ line-height: 23px;
1970
2806
  min-height: 0;
1971
2807
  }
2808
+
2809
+ /*
2810
+ * The colours row is the spotlight card's alone.
2811
+ *
2812
+ * `mobile/product-card` carries one in every variant and **hides it on the small card**:
2813
+ * the rail's instances and the grid's all draw the frame `hidden`, and only the 375-wide
2814
+ * spotlight shows two swatches under its price. Drawn on a 165px card it also cost 34 of
2815
+ * the 291 the card is given, which is why the rail ran 55 long before this.
2816
+ */
2817
+ ._tile_1io44_7:not(._large_1io44_211) ._swatches_1io44_179 {
2818
+ display: none;
2819
+ }
2820
+ /*
2821
+ * Figma `mobile/limited edition` (5304:77067), 360 tall at 375:
2822
+ * 24 above the heading, 28 of heading, 12, a 220 row, 12, a 40 caption, 24 below.
2823
+ */
2824
+ ._section_1n5an_5 {
2825
+ display: flex;
2826
+ flex-direction: column;
2827
+ gap: var(--space-12);
2828
+ padding: var(--space-24) 0;
2829
+ }
2830
+
2831
+ /*
2832
+ * `heading/md` at 1.38, which is the rail's own heading rule — the two blocks instance the
2833
+ * same 206x28 `header` frame, so they have to measure the same. (`ExploreList`'s heading
2834
+ * is the same 20px face in a 26 box; the frames differ, and each follows its own.)
2835
+ */
2836
+ ._title_1n5an_17 {
2837
+ margin: 0;
2838
+ padding: 0 var(--space-16);
2839
+ font-size: var(--type-heading-md-size);
2840
+ line-height: 1.38;
2841
+ font-weight: var(--font-weight-bold);
2842
+ color: var(--color-text-default);
2843
+ }
2844
+
2845
+ ._link_1n5an_26 {
2846
+ display: flex;
2847
+ flex-direction: column;
2848
+ gap: var(--space-12);
2849
+ text-decoration: none;
2850
+ color: inherit;
2851
+ }
2852
+
2853
+ /*
2854
+ * The row scrolls, and the third picture peeks past the fold exactly as the frame draws
2855
+ * it: two 165s and a 12 gutter fill the 343 content width, and the next one starts at 354.
2856
+ */
2857
+ ._track_1n5an_38 {
2858
+ display: flex;
2859
+ gap: var(--space-12);
2860
+ list-style: none;
2861
+ margin: 0;
2862
+ padding: 0 var(--space-16);
2863
+ overflow-x: auto;
2864
+ scroll-snap-type: x mandatory;
2865
+ /* Keeps the 16px inset under mandatory snap: without it the first frame snaps to x=0
2866
+ and the padding is scrolled away, so the row stops lining up with its heading. */
2867
+ scroll-padding-inline: var(--space-16);
2868
+ -webkit-overflow-scrolling: touch;
2869
+ /* The row is its own indicator — a native scrollbar under it is not in the frame. */
2870
+ scrollbar-width: none;
2871
+ }
2872
+
2873
+ ._track_1n5an_38::-webkit-scrollbar {
2874
+ display: none;
2875
+ }
2876
+
2877
+ ._frame_1n5an_58 {
2878
+ position: relative;
2879
+ flex: 0 0 auto;
2880
+ width: 165px;
2881
+ height: 220px;
2882
+ border-radius: var(--radius-6);
2883
+ overflow: hidden;
2884
+ background: var(--color-surface-soft);
2885
+ scroll-snap-align: start;
2886
+ }
2887
+
2888
+ ._image_1n5an_69 {
2889
+ object-fit: cover;
2890
+ }
2891
+
2892
+ ._placeholder_1n5an_73 {
2893
+ width: 100%;
2894
+ height: 100%;
2895
+ }
2896
+
2897
+ /*
2898
+ * `display: flex`, and it is load-bearing. The wrapper is a `span`, so left inline — or
2899
+ * even as a `block` — it builds a LINE box around the 20px badge and reserves the font's
2900
+ * descender room under it: measured 25 against the badge's 20, which put the badge 13px
2901
+ * above the image's edge where the frame draws it 8. A flex container makes the badge a
2902
+ * flex item, and a flex item has no line box.
2903
+ */
2904
+ ._saleBadge_1n5an_85 {
2905
+ position: absolute;
2906
+ display: flex;
2907
+ bottom: var(--space-8);
2908
+ left: var(--space-8);
2909
+ }
2910
+
2911
+ /* The whole picture dims, as it does on a product card — not a corner flag. */
2912
+ ._oos_1n5an_93 {
2913
+ position: absolute;
2914
+ inset: 0;
2915
+ display: flex;
2916
+ align-items: center;
2917
+ justify-content: center;
2918
+ background: rgba(0, 0, 0, 0.45);
2919
+ color: #ffffff;
2920
+ font-size: var(--type-trimmed-sm-size);
2921
+ font-weight: var(--font-weight-bold);
2922
+ }
2923
+
2924
+ /*
2925
+ * One caption for the row: the frame's `bottom` is 40 — a 13px name, 16, an 11px price —
2926
+ * because the pictures above it are all the same garment.
2927
+ */
2928
+ ._caption_1n5an_109 {
2929
+ display: flex;
2930
+ flex-direction: column;
2931
+ gap: var(--space-16);
2932
+ padding: 0 var(--space-16);
2933
+ }
2934
+
2935
+ /*
2936
+ * Trimmed to the cap, as every text layer in this block is: 23 carries the design's
2937
+ * leading over an 18px face, the padding keeps the ellipsis off the descenders, and the
2938
+ * margin takes back both that padding and the half-leading the trim removes. The frame's
2939
+ * name box is 13.
2940
+ */
2941
+ ._name_1n5an_122 {
2942
+ font-size: 18px;
2943
+ line-height: 23px;
2944
+ padding: 5px 0;
2945
+ margin: -10px 0;
2946
+ font-weight: var(--font-weight-regular);
2947
+ color: var(--color-text-default);
2948
+ overflow: hidden;
2949
+ text-overflow: ellipsis;
2950
+ white-space: nowrap;
2951
+ }
2952
+
2953
+ /* 11 on 16px, the same cap the product card's price row takes. */
2954
+ ._price_1n5an_135 {
2955
+ display: flex;
2956
+ align-items: baseline;
2957
+ gap: var(--space-4);
2958
+ font-size: var(--type-trimmed-md-size);
2959
+ line-height: 11px;
2960
+ font-variant-numeric: tabular-nums;
2961
+ }
2962
+
2963
+ ._paid_1n5an_144 {
2964
+ font-weight: var(--font-weight-bold);
2965
+ color: var(--color-text-default);
2966
+ }
2967
+
2968
+ /* Struck, and at the same weight as the live price — `mobile/product-card` again. */
2969
+ ._was_1n5an_150 {
2970
+ font-weight: var(--font-weight-bold);
2971
+ color: var(--color-text-disabled);
2972
+ text-decoration: line-through;
2973
+ }
1972
2974
  ._bar_fn0g9_1 {
1973
2975
  display: flex;
1974
2976
  align-items: center;
@@ -2030,33 +3032,38 @@
2030
3032
  gap: var(--space-16);
2031
3033
  }
2032
3034
  /* The block owns its vertical rhythm (Figma padding 24/16) — the page stacks blocks flush. */
2033
- ._rail_5z5e9_2 {
3035
+ /*
3036
+ * 24 above and 16 below, where the frame says 24 and 24 — because the track below carries
3037
+ * 8 of its own so a focused card's ring is not clipped by its scroller. 24 + 28 + 12 +
3038
+ * 291 + 8 + 16 is the frame's 379; leaving both at 24 made the block 387.
3039
+ */
3040
+ ._rail_11l7h_7 {
2034
3041
  display: flex;
2035
3042
  flex-direction: column;
2036
3043
  gap: var(--space-12);
2037
- padding: var(--space-24) 0;
3044
+ padding: var(--space-24) 0 var(--space-16);
2038
3045
  }
2039
3046
 
2040
- ._header_5z5e9_9 {
3047
+ ._header_11l7h_14 {
2041
3048
  display: flex;
2042
3049
  align-items: baseline;
2043
3050
  justify-content: space-between;
2044
3051
  padding: 0 var(--space-16);
2045
3052
  }
2046
3053
 
2047
- ._title_5z5e9_16 {
3054
+ ._title_11l7h_21 {
2048
3055
  font-size: var(--type-heading-md-size);
2049
3056
  /* Figma rail header: 20px, line-height 1.38. */
2050
3057
  line-height: 1.38;
2051
3058
  }
2052
3059
 
2053
- ._seeAll_5z5e9_22 {
3060
+ ._seeAll_11l7h_27 {
2054
3061
  font-size: var(--type-trimmed-sm-size);
2055
3062
  color: var(--color-text-subtle);
2056
3063
  text-decoration: none;
2057
3064
  }
2058
3065
 
2059
- ._track_5z5e9_28 {
3066
+ ._track_11l7h_33 {
2060
3067
  display: flex;
2061
3068
  gap: var(--space-12);
2062
3069
  list-style: none;
@@ -2073,7 +3080,7 @@
2073
3080
 
2074
3081
  /* Fixed 165px, as the card is drawn. At 375 two fit the 343 content width and the third
2075
3082
  peeks, which is the signal the design asks for. */
2076
- ._item_5z5e9_45 {
3083
+ ._item_11l7h_50 {
2077
3084
  flex: 0 0 auto;
2078
3085
  width: 165px;
2079
3086
  scroll-snap-align: start;
@@ -2085,11 +3092,11 @@
2085
3092
  * parent supplies the 16px inset, so the header/track add none of their own, and tiles
2086
3093
  * size to show exactly two across the content width (per the PDP design: rail x16 w343).
2087
3094
  */
2088
- ._inset_5z5e9_57 ._header_5z5e9_9 {
3095
+ ._inset_11l7h_62 ._header_11l7h_14 {
2089
3096
  padding: 0;
2090
3097
  }
2091
3098
 
2092
- ._inset_5z5e9_57 ._track_5z5e9_28 {
3099
+ ._inset_11l7h_62 ._track_11l7h_33 {
2093
3100
  padding-left: 0;
2094
3101
  padding-right: 0;
2095
3102
  scroll-padding-inline: 0;
@@ -2100,11 +3107,11 @@
2100
3107
  * can sit between flush blocks on the home screen; the PDP content column already spaces
2101
3108
  * its blocks 32px apart, so keeping it here made the gap above the rail 56px.
2102
3109
  */
2103
- ._inset_5z5e9_57 {
3110
+ ._inset_11l7h_62 {
2104
3111
  padding: 0;
2105
3112
  }
2106
3113
 
2107
- ._inset_5z5e9_57 ._item_5z5e9_45 {
3114
+ ._inset_11l7h_62 ._item_11l7h_50 {
2108
3115
  /* Fixed 165px cards (Figma product-card size=default). At 375 two fit the 343 content
2109
3116
  width exactly; more scroll horizontally. */
2110
3117
  width: 165px;
@@ -2261,17 +3268,55 @@
2261
3268
  color: var(--color-text-default);
2262
3269
  font-variant-numeric: tabular-nums;
2263
3270
  }
2264
- ._row_1xbbn_1 {
3271
+ /*
3272
+ * The line is a COLUMN now: the media/detail row, and under it the `Labels` row Figma's
3273
+ * low-stock state adds (4693:67094). `spacer/spacer-xxs` between them, which is what
3274
+ * takes the line from 100 to 130 in the frame.
3275
+ */
3276
+ ._line_1s2s6_6 {
3277
+ display: flex;
3278
+ flex-direction: column;
3279
+ gap: var(--space-6);
3280
+ }
3281
+
3282
+ ._row_1s2s6_12 {
2265
3283
  display: flex;
2266
3284
  gap: var(--space-16);
2267
3285
  align-items: center;
2268
3286
  }
2269
3287
 
2270
- ._pending_1xbbn_7 {
3288
+ ._pending_1s2s6_18 {
2271
3289
  opacity: 0.6;
2272
3290
  }
2273
3291
 
2274
- ._media_1xbbn_11 {
3292
+ /* Full width and its own row, so the label sits under the thumbnail as well as the
3293
+ detail column — not tucked inside the stepper's column, where it used to be. */
3294
+ ._labels_1s2s6_24 {
3295
+ display: flex;
3296
+ align-items: center;
3297
+ gap: var(--space-4);
3298
+ }
3299
+
3300
+ /*
3301
+ * "Only 2 left", in the warning tone. 24px tall: `py-7` around a cap-trimmed 14px line,
3302
+ * which is 7 + 10 + 7. The cap height is stated as the line-height for the same reason it
3303
+ * is everywhere else in this package — Figma's box stops at the cap and a CSS line box
3304
+ * does not.
3305
+ *
3306
+ * Warning, not subtle grey. Scarcity is the one thing on a cart line the fan is meant to
3307
+ * notice before they leave the screen, and it was previously set to be ignored.
3308
+ */
3309
+ ._lowStock_1s2s6_39 {
3310
+ display: inline-flex;
3311
+ align-items: center;
3312
+ padding: 7px 0;
3313
+ font-size: var(--type-trimmed-sm-size);
3314
+ font-weight: var(--font-weight-bold);
3315
+ line-height: 10px;
3316
+ color: var(--color-state-text-warning);
3317
+ }
3318
+
3319
+ ._media_1s2s6_49 {
2275
3320
  position: relative;
2276
3321
  flex-shrink: 0;
2277
3322
  width: 100px;
@@ -2281,18 +3326,26 @@
2281
3326
  background: var(--color-surface-soft);
2282
3327
  }
2283
3328
 
2284
- ._image_1xbbn_21 {
3329
+ ._image_1s2s6_59 {
2285
3330
  object-fit: cover;
2286
3331
  }
2287
3332
 
2288
- ._placeholder_1xbbn_25 {
3333
+ ._placeholder_1s2s6_63 {
2289
3334
  width: 100%;
2290
3335
  height: 100%;
2291
3336
  }
2292
3337
 
2293
3338
  /* Bottom-left over the thumbnail, per the design. */
2294
- ._saleBadge_1xbbn_31 {
3339
+ /*
3340
+ * `display: flex`, and it is load-bearing. The wrapper is a `span`, so left inline — or
3341
+ * even as a `block` — it builds a LINE box around the 20px badge and reserves the font's
3342
+ * descender room under it: measured 25 against the badge's 20, which put the badge 13px
3343
+ * above the image's edge where the frame draws it 6. A flex container makes the badge a
3344
+ * flex item, and a flex item has no line box.
3345
+ */
3346
+ ._saleBadge_1s2s6_76 {
2295
3347
  position: absolute;
3348
+ display: flex;
2296
3349
  left: var(--space-6);
2297
3350
  bottom: var(--space-6);
2298
3351
  }
@@ -2305,7 +3358,7 @@
2305
3358
  *
2306
3359
  * Radius matches the 8px thumbnail rather than the card's 6.
2307
3360
  */
2308
- ._oos_1xbbn_45 {
3361
+ ._oos_1s2s6_91 {
2309
3362
  position: absolute;
2310
3363
  inset: 0;
2311
3364
  display: flex;
@@ -2318,7 +3371,7 @@
2318
3371
  font-weight: var(--font-weight-bold);
2319
3372
  }
2320
3373
 
2321
- ._info_1xbbn_58 {
3374
+ ._info_1s2s6_104 {
2322
3375
  display: flex;
2323
3376
  flex-direction: column;
2324
3377
  gap: var(--space-16);
@@ -2326,47 +3379,66 @@
2326
3379
  min-width: 0;
2327
3380
  }
2328
3381
 
2329
- ._head_1xbbn_66 {
3382
+ ._head_1s2s6_112 {
2330
3383
  display: flex;
2331
3384
  align-items: flex-start;
2332
3385
  justify-content: space-between;
2333
3386
  gap: var(--space-8);
2334
3387
  }
2335
3388
 
2336
- ._meta_1xbbn_73 {
3389
+ ._meta_1s2s6_119 {
2337
3390
  display: flex;
2338
3391
  flex-direction: column;
2339
3392
  gap: var(--space-12);
2340
3393
  min-width: 0;
2341
3394
  }
2342
3395
 
2343
- ._title_1xbbn_80 {
3396
+ /*
3397
+ * ONE line, ellipsised, and trimmed to the cap.
3398
+ *
3399
+ * Figma's `Product info` sets `whitespace-nowrap` and the title `text-ellipsis`, so a long
3400
+ * catalogue name is cut rather than wrapped. Ours clamped to two lines, and the second
3401
+ * line is what made every cart line 6.5px taller than the frame draws it — the detail
3402
+ * column overflowed the 100px thumbnail that is supposed to set the row's height.
3403
+ *
3404
+ * The cap-trim pair is the idiom this package uses everywhere (see `ProductTile.title`):
3405
+ * `line-height` is the design's box — 11 of cap on 16px text — and the padding gives the
3406
+ * descenders room inside the clip box that `text-overflow` needs, while the negative
3407
+ * margin takes that room back out of the layout. Measured in a browser at 375: title box
3408
+ * 24.8 -> 11, and the line 106.5 -> 100.
3409
+ */
3410
+ ._title_1s2s6_134 {
2344
3411
  font-size: var(--type-trimmed-md-size);
2345
3412
  font-weight: var(--font-weight-bold);
2346
- /* Product titles are catalogue copy and can run long; unbounded, the title pushes the
2347
- price out of alignment down the list. */
2348
- display: -webkit-box;
2349
- -webkit-line-clamp: 2;
2350
- -webkit-box-orient: vertical;
3413
+ line-height: 11px;
3414
+ padding: 7px 0;
3415
+ margin: -7px 0;
2351
3416
  overflow: hidden;
3417
+ text-overflow: ellipsis;
3418
+ white-space: nowrap;
2352
3419
  }
2353
3420
 
2354
3421
  /* "Color: White Size: M" */
2355
- ._details_1xbbn_92 {
3422
+ ._details_1s2s6_152 {
2356
3423
  display: flex;
2357
3424
  flex-wrap: wrap;
2358
3425
  gap: var(--space-6);
2359
3426
  min-width: 0;
2360
3427
  }
2361
3428
 
2362
- ._detail_1xbbn_92 {
3429
+ /* 10 of cap on 14px, same trim. Nothing clips these, so the descenders simply hang out
3430
+ of the box and are drawn — exactly as they are in the frame. */
3431
+ ._detail_1s2s6_152 {
2363
3432
  font-size: var(--type-trimmed-sm-size);
2364
3433
  font-weight: var(--font-weight-regular);
3434
+ line-height: 10px;
3435
+ padding: 6px 0;
3436
+ margin: -6px 0;
2365
3437
  color: var(--color-text-subtle);
2366
3438
  white-space: nowrap;
2367
3439
  }
2368
3440
 
2369
- ._price_1xbbn_106 {
3441
+ ._price_1s2s6_171 {
2370
3442
  display: flex;
2371
3443
  flex-direction: column;
2372
3444
  align-items: flex-end;
@@ -2374,15 +3446,21 @@
2374
3446
  flex-shrink: 0;
2375
3447
  }
2376
3448
 
2377
- ._amount_1xbbn_114 {
3449
+ ._amount_1s2s6_179 {
2378
3450
  font-size: var(--type-trimmed-md-size);
2379
3451
  font-weight: var(--font-weight-bold);
3452
+ line-height: 11px;
3453
+ padding: 7px 0;
3454
+ margin: -7px 0;
2380
3455
  white-space: nowrap;
2381
3456
  }
2382
3457
 
2383
- ._was_1xbbn_120 {
3458
+ ._was_1s2s6_188 {
2384
3459
  font-size: var(--type-trimmed-sm-size);
2385
3460
  font-weight: var(--font-weight-regular);
3461
+ line-height: 10px;
3462
+ padding: 6px 0;
3463
+ margin: -6px 0;
2386
3464
  color: var(--color-text-disabled);
2387
3465
  text-decoration: line-through;
2388
3466
  white-space: nowrap;
@@ -2556,49 +3634,56 @@
2556
3634
  gap: var(--space-20);
2557
3635
  }
2558
3636
 
2559
- ._gallery_1e69n_1 {
3637
+ ._gallery_10mch_1 {
2560
3638
  position: relative;
2561
3639
  display: flex;
2562
3640
  flex-direction: column;
2563
3641
  gap: var(--space-12);
2564
3642
  }
2565
3643
 
2566
- ._track_1e69n_8 {
3644
+ ._track_10mch_8 {
2567
3645
  display: flex;
2568
3646
  overflow-x: auto;
2569
3647
  scroll-snap-type: x mandatory;
2570
3648
  -webkit-overflow-scrolling: touch;
2571
- /* Hero media is 375×485 (portrait) and fully sharp (no rounded corners) — it sits
2572
- edge-to-edge and flush under the header. */
2573
- aspect-ratio: 375 / 485;
3649
+ /*
3650
+ * Hero media is 375x475 (portrait) and fully sharp (no rounded corners) — it sits
3651
+ * edge-to-edge and flush under the header.
3652
+ *
3653
+ * 475, not the 485 this had. That number came from `pdp` (3601:2479), which ADR-0022
3654
+ * superseded: every frame in the design of record puts the `img` at 375x475 — `full
3655
+ * PDP`, all three `States > PDP` frames, and the scrolled one. Ten pixels, on the
3656
+ * tallest element of the tallest screen, and everything below it moved with it.
3657
+ */
3658
+ aspect-ratio: 375 / 475;
2574
3659
  background: var(--color-surface-soft);
2575
3660
  /* Same as the review carousel: the dots below are the indicator. */
2576
3661
  scrollbar-width: none;
2577
3662
  }
2578
3663
 
2579
- ._track_1e69n_8::-webkit-scrollbar {
3664
+ ._track_10mch_8::-webkit-scrollbar {
2580
3665
  display: none;
2581
3666
  }
2582
3667
 
2583
- ._slide_1e69n_25 {
3668
+ ._slide_10mch_32 {
2584
3669
  position: relative;
2585
3670
  flex: 0 0 100%;
2586
3671
  scroll-snap-align: center;
2587
- aspect-ratio: 375 / 485;
3672
+ aspect-ratio: 375 / 475;
2588
3673
  }
2589
3674
 
2590
- ._image_1e69n_32 {
3675
+ ._image_10mch_39 {
2591
3676
  object-fit: cover;
2592
3677
  }
2593
3678
 
2594
- ._placeholder_1e69n_36 {
3679
+ ._placeholder_10mch_43 {
2595
3680
  width: 100%;
2596
- aspect-ratio: 375 / 485;
3681
+ aspect-ratio: 375 / 475;
2597
3682
  background: var(--color-surface-soft);
2598
3683
  }
2599
3684
 
2600
3685
  /* Share button — top-right chrome over the image (mobile/button: 32px, soft, radius-8). */
2601
- ._share_1e69n_43 {
3686
+ ._share_10mch_50 {
2602
3687
  position: absolute;
2603
3688
  top: var(--space-16);
2604
3689
  right: var(--space-16);
@@ -2615,13 +3700,13 @@
2615
3700
  cursor: pointer;
2616
3701
  }
2617
3702
 
2618
- ._dots_1e69n_60 {
3703
+ ._dots_10mch_67 {
2619
3704
  display: flex;
2620
3705
  justify-content: center;
2621
3706
  gap: var(--space-6);
2622
3707
  }
2623
3708
 
2624
- ._dot_1e69n_60 {
3709
+ ._dot_10mch_67 {
2625
3710
  width: 8px;
2626
3711
  height: 8px;
2627
3712
  padding: 0;
@@ -2633,131 +3718,387 @@
2633
3718
  position: relative;
2634
3719
  }
2635
3720
 
2636
- ._dot_1e69n_60::after {
3721
+ ._dot_10mch_67::after {
2637
3722
  content: '';
2638
3723
  position: absolute;
2639
3724
  inset: -18px;
2640
3725
  }
2641
3726
 
2642
- ._dotActive_1e69n_84 {
3727
+ ._dotActive_10mch_91 {
2643
3728
  background: var(--color-surface-max);
2644
3729
  }
2645
3730
  /*
2646
- * Size-guide bottom sheet. Uses the same scrim + rounded-top surface as the other PDP
2647
- * overlays so it reads as one system. Fixed light surface: the PDP is light in every
2648
- * theme, and an inverted sheet over a light page would be jarring.
3731
+ * Figma `size-guide` (4882:58365): a bottom sheet over the PDP a 48 `.sheet-header`,
3732
+ * then `mobile/size-guide`, which is 806 tall at 375 for the hoodie chart.
3733
+ *
3734
+ * The body's blocks are all 20 apart: title, unit control, table, note, "How to measure",
3735
+ * fabric. Everything below is that rhythm and the geometry inside each block.
2649
3736
  */
2650
- ._scrim_8wz6r_6 {
3737
+ ._scrim_ddqa4_8 {
2651
3738
  position: fixed;
2652
3739
  inset: 0;
2653
3740
  z-index: 60;
2654
3741
  display: flex;
2655
3742
  align-items: flex-end;
2656
3743
  justify-content: center;
2657
- background: rgba(8, 14, 18, 0.5);
2658
- animation: _fade_8wz6r_1 160ms ease-out;
3744
+ /* `semantic/base/surface/backdrop` #0c161c at 32%, which is lighter than the 50% the
3745
+ cart and menu sheets are drawn over. Theirs are literals of the same intent written
3746
+ before the variable was published; this one follows the variable. */
3747
+ background: rgba(12, 22, 28, 0.32);
3748
+ animation: _fade_ddqa4_1 160ms ease-out;
2659
3749
  }
2660
3750
 
2661
- ._sheet_8wz6r_17 {
3751
+ ._sheet_ddqa4_2 {
3752
+ display: flex;
3753
+ flex-direction: column;
2662
3754
  width: 100%;
2663
3755
  max-width: 480px;
2664
- max-height: 80vh;
2665
- overflow-y: auto;
2666
- padding: var(--space-8) var(--space-16) var(--space-24);
2667
- border-radius: var(--radius-18) var(--radius-18) 0 0;
3756
+ max-height: 90dvh;
3757
+ /* Clips the body's scroll to the rounded corners, so a chart scrolled to the top does
3758
+ not square them off. */
3759
+ overflow: hidden;
3760
+ /* 16, and a literal because the design draws one: the library's radii here are `full`
3761
+ and `xs`, and this corner is neither. */
3762
+ border-radius: 16px 16px 0 0;
2668
3763
  background: #ffffff;
2669
- color: #16181a;
2670
- animation: _rise_8wz6r_1 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
3764
+ animation: _rise_ddqa4_1 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
2671
3765
  }
2672
3766
 
2673
- ._grabber_8wz6r_29 {
2674
- width: 40px;
2675
- height: 4px;
2676
- margin: 0 auto var(--space-12);
2677
- border-radius: 2px;
2678
- background: #d8dcde;
3767
+ /* ── Body ──────────────────────────────────────────────────────────────────── */
3768
+
3769
+ ._body_ddqa4_40 {
3770
+ flex: 1 1 auto;
3771
+ overflow-y: auto;
3772
+ display: flex;
3773
+ flex-direction: column;
3774
+ gap: var(--space-20);
3775
+ padding: 0 var(--space-16) calc(var(--space-24) + var(--safe-area-bottom));
3776
+ background: var(--color-surface-default);
3777
+ }
3778
+
3779
+ /*
3780
+ * A long guide is taller than 90dvh and the body scrolls — but a column flex container
3781
+ * shrinks its items to fit before it will overflow, so every block lost a share of the
3782
+ * excess and the chart came out 14 short of the 256 the design draws. The body scrolls;
3783
+ * its blocks keep their size.
3784
+ */
3785
+ ._body_ddqa4_40 > * {
3786
+ flex-shrink: 0;
2679
3787
  }
2680
3788
 
2681
- ._header_8wz6r_37 {
3789
+ ._titles_ddqa4_60 {
2682
3790
  display: flex;
2683
- align-items: center;
2684
- justify-content: space-between;
2685
- gap: var(--space-12);
2686
- margin-bottom: var(--space-16);
3791
+ flex-direction: column;
3792
+ gap: var(--space-2);
2687
3793
  }
2688
3794
 
2689
- ._title_8wz6r_45 {
3795
+ /* `heading/md` at 1.32 — the library's 1.32, not our `--type-heading-md-line`, which is
3796
+ 1.25 and is the base h2 default the whole package inherits. */
3797
+ ._title_ddqa4_60 {
2690
3798
  margin: 0;
2691
- font-size: var(--type-heading-sm-size, 20px);
3799
+ font-size: var(--type-heading-md-size);
3800
+ line-height: 1.32;
2692
3801
  font-weight: var(--font-weight-bold);
3802
+ color: var(--color-text-default);
3803
+ }
3804
+
3805
+ ._subtitle_ddqa4_76 {
3806
+ margin: 0;
3807
+ font-size: var(--type-caption-sm-size);
3808
+ line-height: var(--type-caption-sm-line);
3809
+ color: var(--color-text-subtle);
3810
+ }
3811
+
3812
+ /* ── cm / inches ───────────────────────────────────────────────────────────── */
3813
+
3814
+ /*
3815
+ * `Segmented Control` (4882:56556): 190 x 40, a 9 radius the scale does not carry, and 4
3816
+ * of horizontal padding around two halves.
3817
+ */
3818
+ ._units_ddqa4_89 {
3819
+ display: flex;
3820
+ align-items: center;
3821
+ width: 190px;
3822
+ height: 40px;
3823
+ padding: var(--space-2) var(--space-4);
3824
+ border-radius: 9px;
3825
+ background: var(--color-surface-soft);
2693
3826
  }
2694
3827
 
2695
- ._close_8wz6r_51 {
3828
+ /*
3829
+ * 10 on 14px text: `text-box-trim: trim-both`, cap-alphabetic. The pill's height is fixed
3830
+ * and its content centred, so the trim is what decides whether the CAP box or the line box
3831
+ * is the thing being centred — and the design centres the cap.
3832
+ */
3833
+ ._unit_ddqa4_89 {
3834
+ flex: 1 1 0;
2696
3835
  display: inline-flex;
2697
3836
  align-items: center;
2698
3837
  justify-content: center;
2699
- width: 32px;
2700
- height: 32px;
2701
- flex-shrink: 0;
2702
- border: none;
2703
- border-radius: 50%;
2704
- background: #f2f4f5;
2705
- color: #16181a;
3838
+ height: 36px;
3839
+ padding: 0 var(--space-8);
3840
+ border: 0;
3841
+ border-radius: var(--radius-6);
3842
+ background: none;
3843
+ color: var(--color-text-default);
3844
+ font-family: inherit;
3845
+ font-size: var(--type-trimmed-sm-size);
3846
+ line-height: 10px;
2706
3847
  cursor: pointer;
2707
3848
  }
2708
- ._close_8wz6r_51:focus-visible {
2709
- outline: 2px solid #16181a;
2710
- outline-offset: 2px;
3849
+
3850
+ /* Four shorter than its neighbour, and that is the component rather than a slip: the
3851
+ selected half carries its own 2 of vertical padding inside the track's 36. */
3852
+ ._unitOn_ddqa4_123 {
3853
+ height: 32px;
3854
+ background: var(--color-surface-neutral);
3855
+ font-weight: var(--font-weight-bold);
3856
+ }
3857
+
3858
+ /* A half-pixel hairline drawn INSIDE the pill, as every Figma stroke is — hence `inset`
3859
+ rather than a border, which CSS would draw around it and make the pill 37 tall. */
3860
+ ._unitOff_ddqa4_131 {
3861
+ box-shadow: inset 0 0 0 0.5px rgba(0, 0, 0, 0.04);
3862
+ font-weight: var(--font-weight-regular);
2711
3863
  }
2712
3864
 
2713
- /* The chart can be wider than the sheet, so it scrolls inside its own container
2714
- rather than making the sheet scroll sideways. */
2715
- ._tableWrap_8wz6r_71 {
3865
+ /* ── The chart ─────────────────────────────────────────────────────────────── */
3866
+
3867
+ /* Wider than the sheet on a narrow phone or a long chart, so it scrolls inside its own
3868
+ container rather than making the sheet scroll sideways. */
3869
+ ._tableWrap_ddqa4_140 {
2716
3870
  overflow-x: auto;
2717
- margin-bottom: var(--space-16);
2718
3871
  }
2719
3872
 
2720
- ._table_8wz6r_71 {
3873
+ ._table_ddqa4_140 {
2721
3874
  width: 100%;
2722
- border-collapse: collapse;
2723
- font-size: var(--type-trimmed-sm-size, 14px);
3875
+ /* `separate` with no spacing, not `collapse`: collapsed borders cannot carry the
3876
+ header's rounded top corners. */
3877
+ border-collapse: separate;
3878
+ border-spacing: 0;
3879
+ table-layout: fixed;
2724
3880
  }
2725
3881
 
2726
- ._table_8wz6r_71 th,
2727
- ._table_8wz6r_71 td {
2728
- padding: var(--space-8) var(--space-12);
3882
+ /*
3883
+ * The frame's five columns are equal at 63.8 across 343, and the table's 12 of inset lives
3884
+ * INSIDE the first and last of them (75.8 = 63.8 + 12). Declared on the columns rather
3885
+ * than as padding on every cell so that the centred headings land where the design puts
3886
+ * them: as cell padding, the last column's centre drifts 4 left.
3887
+ *
3888
+ * Two mutually exclusive classes rather than a `col` rule plus an override for the edges.
3889
+ * `.table col` is specificity (0,1,1) and a module class is (0,1,0), so the descendant
3890
+ * selector won wherever the two met and every column came out 18.6006% — which sums to
3891
+ * 93%, and Chrome scaled all five back up to an equal fifth. Same trap `ShopSurface`
3892
+ * documents on its base headings.
3893
+ */
3894
+ ._col_ddqa4_165 {
3895
+ width: 18.6006%;
3896
+ }
3897
+
3898
+ ._colEdge_ddqa4_169 {
3899
+ width: 22.0991%;
3900
+ }
3901
+
3902
+ /*
3903
+ * 12 bold with the library's 1% tracking, cap-trimmed to 9 in a 36 row. `#f5f5f5` and
3904
+ * `#6b6b6b` are literals because the designer drew them as literals — there is no library
3905
+ * variable behind either, and `border/soft` and `text/subtle` are visibly different
3906
+ * greys.
3907
+ */
3908
+ ._table_ddqa4_140 thead th {
3909
+ height: 36px;
3910
+ padding: 0;
3911
+ background: #f5f5f5;
3912
+ color: #6b6b6b;
3913
+ font-size: var(--type-trimmed-xs-size);
3914
+ line-height: 9px;
3915
+ font-weight: var(--font-weight-bold);
3916
+ letter-spacing: 0.12px;
3917
+ text-align: center;
3918
+ }
3919
+
3920
+ ._table_ddqa4_140 thead th:first-child {
3921
+ padding-left: var(--space-12);
3922
+ border-top-left-radius: var(--radius-8);
2729
3923
  text-align: left;
2730
- border-bottom: 1px solid #e2e6e8;
2731
- white-space: nowrap;
2732
3924
  }
2733
3925
 
2734
- ._table_8wz6r_71 thead th {
3926
+ ._table_ddqa4_140 thead th:last-child {
3927
+ padding-right: var(--space-12);
3928
+ border-top-right-radius: var(--radius-8);
3929
+ }
3930
+
3931
+ /* 13px, which is not on the type scale — the design uses a detached style here rather
3932
+ than a token, and 12 or 14 both miss the row. */
3933
+ ._table_ddqa4_140 tbody th,
3934
+ ._table_ddqa4_140 tbody td {
3935
+ height: 44px;
3936
+ padding: 0;
3937
+ border-bottom: 1px solid var(--color-surface-soft);
3938
+ color: #0d0d0d;
3939
+ font-size: 13px;
3940
+ line-height: 17px;
3941
+ font-weight: var(--font-weight-regular);
3942
+ text-align: center;
3943
+ }
3944
+
3945
+ ._table_ddqa4_140 tbody th {
3946
+ padding-left: var(--space-12);
3947
+ font-weight: var(--font-weight-bold);
3948
+ text-align: left;
3949
+ }
3950
+
3951
+ ._table_ddqa4_140 tbody td:last-child {
3952
+ padding-right: var(--space-12);
3953
+ }
3954
+
3955
+ /* No rule under the last row: the table would otherwise be underlined, and the note that
3956
+ follows is a separate block with its own ground. */
3957
+ ._table_ddqa4_140 tbody tr:last-child th,
3958
+ ._table_ddqa4_140 tbody tr:last-child td {
3959
+ border-bottom: 0;
3960
+ }
3961
+
3962
+ /* ── The note under the chart ──────────────────────────────────────────────── */
3963
+
3964
+ /* `caption/xs` — the same 12px face as `trimmed/xs` on a 1.52 leading rather than a
3965
+ trimmed box, which is why the line-height is written out. */
3966
+ ._note_ddqa4_237 {
3967
+ margin: 0;
3968
+ padding: var(--space-8) var(--space-12);
3969
+ border-radius: var(--radius-8);
3970
+ background: var(--color-surface-soft);
3971
+ color: var(--color-text-subtle);
3972
+ font-size: var(--type-trimmed-xs-size);
3973
+ line-height: 1.52;
3974
+ }
3975
+
3976
+ /* ── How to measure ────────────────────────────────────────────────────────── */
3977
+
3978
+ ._how_ddqa4_249 {
3979
+ display: flex;
3980
+ flex-direction: column;
3981
+ gap: var(--space-16);
3982
+ }
3983
+
3984
+ ._howTitle_ddqa4_255 {
3985
+ margin: 0;
3986
+ font-size: var(--type-heading-sm-size);
3987
+ line-height: var(--type-heading-sm-line);
3988
+ font-weight: var(--font-weight-bold);
3989
+ color: #0d0d0d;
3990
+ }
3991
+
3992
+ ._howList_ddqa4_263 {
3993
+ margin: 0;
3994
+ display: flex;
3995
+ flex-direction: column;
3996
+ gap: var(--space-8);
3997
+ }
3998
+
3999
+ ._howItem_ddqa4_270 {
4000
+ display: flex;
4001
+ flex-direction: column;
4002
+ gap: var(--space-8);
4003
+ }
4004
+
4005
+ /*
4006
+ * The frame's `Line 9`, between rows and never under the last one.
4007
+ *
4008
+ * A Figma line has no height, so 8 above it and 8 below it means 16 between the rows it
4009
+ * separates with the hairline drawn on that boundary — the negative margin takes the pixel
4010
+ * back out of the layout so the pair stays 16 rather than becoming 17.
4011
+ */
4012
+ ._howItem_ddqa4_270 + ._howItem_ddqa4_270 {
4013
+ margin-top: -1px;
4014
+ padding-top: var(--space-8);
4015
+ border-top: 1px solid var(--color-surface-soft);
4016
+ }
4017
+
4018
+ /*
4019
+ * Cap-trimmed to 9 on a 12px face. Unlike the table header this box is content-sized, so
4020
+ * the trim has to come off the text itself: the padding keeps the descenders of "Body
4021
+ * length" clear of anything that clips, and the margin takes that padding back out of the
4022
+ * layout so the box measures the 9 the frame gives it.
4023
+ */
4024
+ ._howLabel_ddqa4_295 {
4025
+ padding: 5px 0;
4026
+ margin: -5px 0;
4027
+ font-size: var(--type-trimmed-xs-size);
4028
+ line-height: 9px;
4029
+ font-weight: var(--font-weight-bold);
4030
+ letter-spacing: 0.12px;
4031
+ color: #0d0d0d;
4032
+ }
4033
+
4034
+ ._howText_ddqa4_305 {
4035
+ margin: 0;
4036
+ font-size: var(--type-trimmed-xs-size);
4037
+ line-height: 1.52;
4038
+ color: #6b6b6b;
4039
+ }
4040
+
4041
+ /* ── Fabric ────────────────────────────────────────────────────────────────── */
4042
+
4043
+ ._fabric_ddqa4_314 {
4044
+ display: flex;
4045
+ flex-direction: column;
4046
+ gap: var(--space-2);
4047
+ }
4048
+
4049
+ /* `caption/xs-bold`, not the trimmed style the "How to measure" labels use: the frame's
4050
+ box is 18, which is the full 1.52 line rather than a cap. */
4051
+ ._fabricLabel_ddqa4_322 {
4052
+ margin: 0;
4053
+ font-size: var(--type-trimmed-xs-size);
4054
+ line-height: 1.52;
2735
4055
  font-weight: var(--font-weight-bold);
2736
- background: #f7f8f9;
4056
+ color: #0d0d0d;
4057
+ }
4058
+
4059
+ ._fabricText_ddqa4_330 {
4060
+ margin: 0;
4061
+ font-size: var(--type-trimmed-xs-size);
4062
+ line-height: 1.52;
4063
+ color: #6b6b6b;
2737
4064
  }
2738
4065
 
2739
- ._notes_8wz6r_95 {
4066
+ /* ── Fit notes ─────────────────────────────────────────────────────────────── */
4067
+
4068
+ /* Not in the frame. Guides carried these before there was a chart to carry instead, and a
4069
+ payload that still has them is still worth drawing. */
4070
+ ._notes_ddqa4_341 {
2740
4071
  margin: 0;
2741
4072
  padding-left: var(--space-16);
2742
4073
  display: flex;
2743
4074
  flex-direction: column;
2744
4075
  gap: var(--space-6);
2745
- font-size: var(--type-trimmed-sm-size, 14px);
2746
- color: #4a5257;
4076
+ font-size: var(--type-caption-sm-size);
4077
+ line-height: var(--type-caption-sm-line);
4078
+ color: var(--color-text-subtle);
2747
4079
  }
2748
4080
 
2749
- @keyframes _fade_8wz6r_1 {
2750
- from { opacity: 0; }
2751
- to { opacity: 1; }
4081
+ @keyframes _fade_ddqa4_1 {
4082
+ from {
4083
+ opacity: 0;
4084
+ }
4085
+ to {
4086
+ opacity: 1;
4087
+ }
2752
4088
  }
2753
- @keyframes _rise_8wz6r_1 {
2754
- from { transform: translateY(12%); }
2755
- to { transform: translateY(0); }
4089
+
4090
+ @keyframes _rise_ddqa4_1 {
4091
+ from {
4092
+ transform: translateY(12%);
4093
+ }
4094
+ to {
4095
+ transform: translateY(0);
4096
+ }
2756
4097
  }
2757
4098
 
2758
4099
  @media (prefers-reduced-motion: reduce) {
2759
- ._scrim_8wz6r_6,
2760
- ._sheet_8wz6r_17 {
4100
+ ._scrim_ddqa4_8,
4101
+ ._sheet_ddqa4_2 {
2761
4102
  animation: none;
2762
4103
  }
2763
4104
  }
@@ -2848,30 +4189,34 @@
2848
4189
  ._chevron_9zj90_85 {
2849
4190
  display: block;
2850
4191
  }
2851
- ._root_1j4n8_1 {
4192
+ ._root_1h4ny_1 {
2852
4193
  display: flex;
2853
4194
  flex-direction: column;
2854
4195
  gap: var(--space-12);
2855
4196
  }
2856
4197
 
2857
- ._header_1j4n8_7 {
4198
+ /* "Color: White" — cap-trimmed like every label in this column, so the block measures the
4199
+ frame's 128 rather than 142. */
4200
+ ._header_1h4ny_9 {
2858
4201
  margin: 0;
2859
4202
  display: flex;
4203
+ align-items: center;
2860
4204
  gap: var(--space-4);
2861
4205
  font-size: var(--type-trimmed-md-size);
4206
+ line-height: var(--type-trimmed-md-line);
2862
4207
  }
2863
4208
 
2864
- ._title_1j4n8_14 {
4209
+ ._title_1h4ny_18 {
2865
4210
  font-weight: var(--font-weight-bold);
2866
4211
  color: var(--color-text-default);
2867
4212
  }
2868
4213
 
2869
- ._value_1j4n8_19 {
4214
+ ._value_1h4ny_23 {
2870
4215
  font-weight: var(--font-weight-regular);
2871
4216
  color: var(--color-text-subtle);
2872
4217
  }
2873
4218
 
2874
- ._tiles_1j4n8_24 {
4219
+ ._tiles_1h4ny_28 {
2875
4220
  display: flex;
2876
4221
  flex-wrap: wrap;
2877
4222
  gap: var(--space-8);
@@ -2882,7 +4227,7 @@
2882
4227
  * overhanging the top edge, so clipping here would shave it in half. `.media` is the
2883
4228
  * clipped box instead, which keeps the image inside the radius.
2884
4229
  */
2885
- ._tile_1j4n8_24 {
4230
+ ._tile_1h4ny_28 {
2886
4231
  position: relative;
2887
4232
  width: 79px;
2888
4233
  height: 105px;
@@ -2895,11 +4240,11 @@
2895
4240
  cursor: pointer;
2896
4241
  }
2897
4242
 
2898
- ._selected_1j4n8_48 {
4243
+ ._selected_1h4ny_52 {
2899
4244
  border-color: var(--color-surface-max);
2900
4245
  }
2901
4246
 
2902
- ._media_1j4n8_32 {
4247
+ ._media_1h4ny_36 {
2903
4248
  position: absolute;
2904
4249
  inset: 0;
2905
4250
  border-radius: var(--radius-8);
@@ -2907,11 +4252,11 @@
2907
4252
  background: var(--color-surface-soft);
2908
4253
  }
2909
4254
 
2910
- ._image_1j4n8_60 {
4255
+ ._image_1h4ny_64 {
2911
4256
  object-fit: cover;
2912
4257
  }
2913
4258
 
2914
- ._placeholder_1j4n8_64 {
4259
+ ._placeholder_1h4ny_68 {
2915
4260
  position: absolute;
2916
4261
  inset: 0;
2917
4262
  background: var(--color-surface-soft);
@@ -2919,7 +4264,7 @@
2919
4264
 
2920
4265
  /* Sold-out: full dark scrim with white label (Figma color/tile state=sold-out). The tile
2921
4266
  stays tappable — see the component docblock. */
2922
- ._scrim_1j4n8_72 {
4267
+ ._scrim_1h4ny_76 {
2923
4268
  position: absolute;
2924
4269
  inset: 0;
2925
4270
  display: flex;
@@ -2938,7 +4283,7 @@
2938
4283
  * proud of the top edge — so it reads as a tag pinned to the tile rather than a label
2939
4284
  * inside it. `pointer-events: none` keeps it from swallowing taps meant for the tile.
2940
4285
  */
2941
- ._stockBadge_1j4n8_91 {
4286
+ ._stockBadge_1h4ny_95 {
2942
4287
  position: absolute;
2943
4288
  top: -10px;
2944
4289
  left: 50px;
@@ -3407,14 +4752,14 @@
3407
4752
  ._dotActive_9mquf_63 {
3408
4753
  background: #f9fafa;
3409
4754
  }
3410
- ._section_n8xka_1 {
4755
+ ._section_kdf3c_1 {
3411
4756
  display: flex;
3412
4757
  flex-direction: column;
3413
4758
  gap: var(--space-12);
3414
4759
  padding: var(--space-24) 0 var(--space-16);
3415
4760
  }
3416
4761
 
3417
- ._track_n8xka_8 {
4762
+ ._track_kdf3c_8 {
3418
4763
  display: flex;
3419
4764
  gap: var(--space-12);
3420
4765
  list-style: none;
@@ -3429,7 +4774,7 @@
3429
4774
  scrollbar-width: none;
3430
4775
  }
3431
4776
 
3432
- ._track_n8xka_8::-webkit-scrollbar {
4777
+ ._track_kdf3c_8::-webkit-scrollbar {
3433
4778
  display: none;
3434
4779
  }
3435
4780
 
@@ -3444,7 +4789,7 @@
3444
4789
  * is raised with DAZN's designers, and the card flips the moment they retune the token.
3445
4790
  * Everything else on this block follows Figma exactly.
3446
4791
  */
3447
- ._card_n8xka_38 {
4792
+ ._card_kdf3c_38 {
3448
4793
  flex: 0 0 323px;
3449
4794
  max-width: calc(100% - var(--space-20));
3450
4795
  scroll-snap-align: start;
@@ -3456,7 +4801,7 @@
3456
4801
  background: #f9fafa;
3457
4802
  }
3458
4803
 
3459
- ._quote_n8xka_50 {
4804
+ ._quote_kdf3c_50 {
3460
4805
  margin: 0;
3461
4806
  font-size: var(--type-heading-lg-size);
3462
4807
  line-height: 1.2;
@@ -3464,38 +4809,46 @@
3464
4809
  color: #0c161c;
3465
4810
  }
3466
4811
 
3467
- ._author_n8xka_58 {
4812
+ ._author_kdf3c_58 {
3468
4813
  margin: 0;
3469
4814
  font-size: var(--type-trimmed-sm-size);
3470
4815
  color: #3d4549;
3471
4816
  }
3472
4817
 
3473
- ._dots_n8xka_64 {
4818
+ /*
4819
+ * `.slide-dots` is a 32-tall band in the frame, sitting straight under the quotes with no
4820
+ * gap of its own — the dots are centred inside it. Ours was an 8px row 12 below the track,
4821
+ * which put it 12 too close to the quote and 12 too far from the bottom of the block.
4822
+ */
4823
+ ._dots_kdf3c_69 {
3474
4824
  display: flex;
4825
+ align-items: center;
3475
4826
  justify-content: center;
4827
+ height: 32px;
4828
+ margin-top: calc(-1 * var(--space-12));
3476
4829
  gap: var(--space-8);
3477
4830
  }
3478
4831
 
3479
- ._dot_n8xka_64 {
4832
+ ._dot_kdf3c_69 {
3480
4833
  width: 8px;
3481
4834
  height: 8px;
3482
4835
  border-radius: var(--radius-full);
3483
4836
  background: #9ea2a4;
3484
4837
  }
3485
4838
 
3486
- ._dotActive_n8xka_77 {
4839
+ ._dotActive_kdf3c_85 {
3487
4840
  background: #f9fafa;
3488
4841
  }
3489
4842
 
3490
4843
  /* Quiet, but present. Not in the Figma frame — the component's own note makes it
3491
4844
  mandatory, and staff quotes shown as reviews without one is the failure it guards. */
3492
- ._disclaimer_n8xka_83 {
4845
+ ._disclaimer_kdf3c_91 {
3493
4846
  margin: 0;
3494
4847
  padding: 0 var(--space-16);
3495
4848
  font-size: var(--type-trimmed-xs-size);
3496
4849
  color: var(--color-text-subtle);
3497
4850
  }
3498
- ._section_145t0_1 {
4851
+ ._section_1tevp_1 {
3499
4852
  display: flex;
3500
4853
  flex-direction: column;
3501
4854
  gap: var(--space-12);
@@ -3503,7 +4856,7 @@
3503
4856
  }
3504
4857
 
3505
4858
  /* Each benefit is a filled tile, not a bare row (Figma `mobile/why-us`). */
3506
- ._row_145t0_9 {
4859
+ ._row_1tevp_9 {
3507
4860
  display: flex;
3508
4861
  flex-direction: column;
3509
4862
  gap: var(--space-8);
@@ -3512,48 +4865,64 @@
3512
4865
  background: var(--color-surface-soft);
3513
4866
  }
3514
4867
 
3515
- /* Figma `size/heading/sm`. Written out rather than taken from
3516
- `--type-heading-sm-size`, which is 20px here and 18px in the library — the token is
3517
- wrong and correcting it would move the PDP's size guide, which has its own design. */
3518
- ._title_145t0_21 {
4868
+ /* Figma `size/heading/sm`. This used to be written out because the token read 20px, the
4869
+ library's heading/md; it is 18 now, and the size guide — the only other consumer, and
4870
+ the reason the token was left wrong asks for the same 18. */
4871
+ ._title_1tevp_21 {
3519
4872
  margin: 0;
3520
- font-size: 18px;
3521
- line-height: 1.38;
4873
+ font-size: var(--type-heading-sm-size);
4874
+ line-height: var(--type-heading-sm-line);
3522
4875
  font-weight: var(--font-weight-bold);
3523
4876
  color: var(--color-text-default);
3524
4877
  }
3525
4878
 
3526
- ._body_145t0_29 {
4879
+ /*
4880
+ * 10 on 14px text: `text-box-trim: trim-both`, cap-alphabetic, as every small text layer
4881
+ * in this file is. The frame's tile is 83 — 20 of padding, a 25px title, 8, this line, 20
4882
+ * — and at a natural line box it was 21 rather than 10, which made every tile 11 too tall
4883
+ * and the block 226 → 249.
4884
+ *
4885
+ * Nothing clips this one, so the descenders hang out of the box and are drawn, exactly as
4886
+ * they are in the frame.
4887
+ */
4888
+ ._body_1tevp_38 {
3527
4889
  margin: 0;
3528
4890
  font-size: var(--type-trimmed-sm-size);
4891
+ line-height: 10px;
3529
4892
  color: var(--color-text-subtle);
3530
4893
  }
3531
- ._section_opjfc_1 {
4894
+ ._section_snuuj_1 {
3532
4895
  display: flex;
3533
4896
  flex-direction: column;
3534
4897
  gap: var(--space-16);
3535
4898
  padding: var(--space-16) var(--space-16) var(--space-24);
3536
4899
  }
3537
4900
 
3538
- ._title_opjfc_8 {
4901
+ /* 1.32, the design system's own figure for `heading/md`, which makes this line the
4902
+ frame's 26 rather than the 25 the token's 1.25 gives. */
4903
+ ._title_snuuj_10 {
3539
4904
  font-size: var(--type-heading-md-size);
3540
- line-height: var(--type-heading-md-line);
4905
+ line-height: 1.32;
3541
4906
  font-weight: var(--font-weight-bold);
3542
4907
  color: var(--color-text-default);
3543
4908
  }
3544
4909
 
3545
- ._list_opjfc_15 {
4910
+ ._list_snuuj_17 {
3546
4911
  list-style: none;
3547
4912
  margin: 0;
3548
4913
  padding: 0;
3549
4914
  }
3550
4915
 
3551
4916
  /*
3552
- * 16px above and below a 14px label clears the 44px tap target on its own, so there is no
3553
- * explicit floor here. That holds because of the type size a smaller label would need
3554
- * the min-height back.
4917
+ * 48 tall, which the 16px chevron sets rather than the label: 16 of padding, the mark, 16.
4918
+ * That only holds with the label trimmed to its cap (10 on 14px, as the frame draws it) —
4919
+ * at a natural line box the text was the taller of the two and made the row 54.
4920
+ *
4921
+ * 16 above and below still clears the 44px tap target on its own, so there is no explicit
4922
+ * floor here. That holds because of the type size and the mark beside it; a smaller label
4923
+ * with no chevron would need the min-height back.
3555
4924
  */
3556
- ._row_opjfc_26 {
4925
+ ._row_snuuj_32 {
3557
4926
  display: flex;
3558
4927
  align-items: center;
3559
4928
  justify-content: space-between;
@@ -3561,15 +4930,16 @@
3561
4930
  text-decoration: none;
3562
4931
  color: var(--color-text-default);
3563
4932
  font-size: var(--type-trimmed-sm-size);
4933
+ line-height: 10px;
3564
4934
  font-weight: var(--font-weight-bold);
3565
4935
  }
3566
4936
 
3567
4937
  /* Between rows only — a rule under the last one reads as a cut-off list. */
3568
- ._list_opjfc_15 li + li ._row_opjfc_26 {
4938
+ ._list_snuuj_17 li + li ._row_snuuj_32 {
3569
4939
  border-top: 1px solid var(--color-border-transparent-soft);
3570
4940
  }
3571
4941
 
3572
- ._row_opjfc_26 svg {
4942
+ ._row_snuuj_32 svg {
3573
4943
  flex-shrink: 0;
3574
4944
  color: var(--color-text-default);
3575
4945
  }