@abreen/tada 1.9.0 → 1.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +24 -34
  2. package/bin/tada.ts +1 -1
  3. package/build/apply-base-path-plugin.ts +79 -17
  4. package/build/bundle.ts +9 -1
  5. package/build/content-watch.ts +3 -3
  6. package/build/copy.ts +30 -0
  7. package/build/generate-content-assets.ts +45 -59
  8. package/build/globals.ts +1 -1
  9. package/build/pagefind.ts +0 -7
  10. package/build/serve.ts +4 -0
  11. package/build/types.d.ts +19 -1
  12. package/build/util.ts +3 -0
  13. package/build/utils/content-files.ts +98 -0
  14. package/build/utils/include.ts +4 -0
  15. package/build/utils/python-runner/trace_runner.py +272 -0
  16. package/build/utils/render.ts +34 -8
  17. package/build/utils/trace-core.ts +203 -0
  18. package/build/utils/trace-java.ts +132 -0
  19. package/build/utils/trace-layout.ts +31 -3
  20. package/build/utils/trace-python.ts +26 -0
  21. package/build/utils/trace.ts +174 -294
  22. package/build/validate-internal-links-plugin.ts +16 -4
  23. package/build/watch/assets.ts +111 -0
  24. package/build/watch/build-full.ts +124 -0
  25. package/build/watch/build-incremental.ts +139 -0
  26. package/build/watch/compiler-types.d.ts +19 -0
  27. package/build/watch/compiler.ts +112 -0
  28. package/build/watch/index.ts +22 -0
  29. package/build/watch/mutations.ts +75 -0
  30. package/build/watch/planner.ts +230 -0
  31. package/build/watch/records.ts +190 -0
  32. package/build/watch/runtime.ts +143 -0
  33. package/build/watch/snapshot.ts +602 -0
  34. package/build/watch/validation.ts +36 -0
  35. package/build/watch-reload-client.ts +10 -5
  36. package/init/content/labs/01/index.md +6 -0
  37. package/init/content/labs/01/trace_demo.py +16 -0
  38. package/package.json +47 -24
  39. package/python/command.ts +95 -0
  40. package/python/module.ts +18 -0
  41. package/src/_alerts.scss +11 -8
  42. package/src/_base.scss +25 -29
  43. package/src/_layout.scss +17 -14
  44. package/src/_mixins.scss +10 -9
  45. package/src/anchor/style.scss +4 -2
  46. package/src/code/index.ts +9 -2
  47. package/src/code/style.scss +14 -13
  48. package/src/code.scss +14 -13
  49. package/src/header/_base.scss +21 -24
  50. package/src/header/style.scss +16 -12
  51. package/src/index.ts +3 -0
  52. package/src/literate/style.scss +4 -4
  53. package/src/navigate/index.ts +43 -279
  54. package/src/navigate/lifecycle.ts +1 -1
  55. package/src/navigate/runtime.ts +341 -0
  56. package/src/page-update/README.md +4 -0
  57. package/src/page-update/index.ts +280 -0
  58. package/src/page-update/style.scss +53 -0
  59. package/src/print/style.scss +4 -4
  60. package/src/question/style.scss +10 -6
  61. package/src/search/index.ts +9 -12
  62. package/src/search/style.scss +44 -42
  63. package/src/style.scss +63 -58
  64. package/src/timezone/index.ts +13 -3
  65. package/src/timezone/style.scss +11 -5
  66. package/src/toc/style.scss +17 -16
  67. package/src/trace/style.scss +27 -27
  68. package/src/validators.ts +45 -0
  69. package/templates/_footer.html +1 -1
  70. package/templates/_theme.scss +8 -19
  71. package/watch/engine.ts +296 -0
  72. package/watch/events.ts +10 -0
  73. package/watch/fs-commit.ts +102 -0
  74. package/watch/types.d.ts +103 -0
  75. package/build/watch.ts +0 -493
package/src/style.scss CHANGED
@@ -5,36 +5,36 @@
5
5
  @use 'alerts';
6
6
 
7
7
  @font-face {
8
- font-family: 'Inter';
8
+ font-family: Inter;
9
9
  font-style: normal;
10
10
  font-weight: 100 900;
11
- font-display: swap;
12
11
  src: url('inter/InterVariable.woff2') format('woff2');
12
+ font-display: swap;
13
13
  }
14
14
 
15
15
  @font-face {
16
- font-family: 'Inter';
16
+ font-family: Inter;
17
17
  font-style: italic;
18
18
  font-weight: 100 900;
19
- font-display: swap;
20
19
  src: url('inter/InterVariable-Italic.woff2') format('woff2');
20
+ font-display: swap;
21
21
  }
22
22
 
23
23
  @font-face {
24
24
  font-family: 'Google Sans Code';
25
25
  font-style: normal;
26
26
  font-weight: 300 800;
27
- font-display: swap;
28
27
  src: url('google-sans-code/GoogleSansCodeVariable.woff2') format('woff2');
28
+ font-display: swap;
29
29
  }
30
30
 
31
31
  @font-face {
32
32
  font-family: 'Google Sans Code';
33
33
  font-style: italic;
34
34
  font-weight: 300 800;
35
- font-display: swap;
36
35
  src: url('google-sans-code/GoogleSansCodeVariable-Italic.woff2')
37
36
  format('woff2');
37
+ font-display: swap;
38
38
  }
39
39
 
40
40
  ::selection {
@@ -66,25 +66,27 @@ a.disabled {
66
66
 
67
67
  .external-link-tail::after,
68
68
  a.external:not(:has(.external-link-tail))::after {
69
- content: '';
70
69
  display: inline-block;
71
70
  width: 1em;
72
71
  height: 1em;
73
72
  vertical-align: middle;
73
+ content: '';
74
+
74
75
  @include contained-mask(var(--icon-external-link));
75
76
  }
76
77
 
77
78
  .footnotes {
78
- margin-top: calc(var(--thematic-break-margin) / 2);
79
79
  padding-top: 32px;
80
- border-top: 3px solid var(--bg2-color);
80
+ margin-top: calc(var(--thematic-break-margin) / 2);
81
81
  font-size: 0.9em;
82
+ border-top: 3px solid var(--bg2-color);
82
83
  }
83
84
 
84
85
  .footnotes .title {
85
86
  @include user-select(none);
86
- font-weight: 700;
87
+
87
88
  font-size: larger;
89
+ font-weight: 700;
88
90
  }
89
91
 
90
92
  .footnotes p {
@@ -92,8 +94,8 @@ a.external:not(:has(.external-link-tail))::after {
92
94
  }
93
95
 
94
96
  .footnotes ol {
95
- list-style: none;
96
97
  padding-left: 0;
98
+ list-style: none;
97
99
  }
98
100
 
99
101
  .footnotes li {
@@ -103,16 +105,17 @@ a.external:not(:has(.external-link-tail))::after {
103
105
  }
104
106
 
105
107
  a.footnote-ref {
106
- vertical-align: text-bottom;
107
108
  font-size: 0.8em;
108
109
  font-weight: 600;
110
+ vertical-align: text-bottom;
109
111
  }
110
112
 
111
113
  .footnote-marker {
112
114
  @include user-select(none);
115
+
113
116
  position: absolute;
114
- left: 0;
115
117
  top: 0;
118
+ left: 0;
116
119
  font-weight: 500;
117
120
  }
118
121
 
@@ -134,62 +137,63 @@ a.footnote-ref {
134
137
 
135
138
  .footnotes .footnote-backref {
136
139
  display: inline-block;
140
+
137
141
  @include user-select(none);
138
142
  }
139
143
 
140
144
  hr {
141
- border: none;
142
- height: 32px;
143
- margin: var(--section-padding) 0;
144
145
  display: flex;
145
146
  align-items: center;
146
147
  justify-content: center;
148
+ height: 32px;
149
+ margin: var(--section-padding) 0;
150
+ border: none;
147
151
  }
148
152
 
149
153
  hr::after {
150
- content: '';
151
154
  display: block;
152
155
  width: 160px;
153
156
  height: 12px;
157
+ content: '';
154
158
  background-color: var(--fg2-color);
155
159
  mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 12'><rect x='0' y='5.5' width='96' height='1' fill='black'/><path d='M 64,6 C 71,6 80,4.5 80,1 C 80,4.5 89,6 96,6 C 89,6 80,7.5 80,11 C 80,7.5 71,6 64,6 Z' fill='black'/><rect x='64' y='5.5' width='96' height='1' fill='black'/></svg>");
156
- mask-size: 100% 100%;
157
160
  mask-repeat: no-repeat;
161
+ mask-size: 100% 100%;
158
162
  }
159
163
 
160
164
  button,
161
165
  a.button,
162
166
  input[type='submit'] {
163
- background: var(--bg-color);
164
- color: var(--fg-color);
165
167
  padding: 0.25em 0.66em;
166
- border: var(--control-border-width) solid var(--fg2-color);
167
- border-radius: var(--border-radius);
168
- font-size: var(--font-size-small);
169
168
  font-family: var(--font);
169
+ font-size: var(--font-size-small);
170
170
  font-weight: 500;
171
+ color: var(--fg-color);
171
172
  text-decoration: none;
173
+ background: var(--bg-color);
174
+ border: var(--control-border-width) solid var(--fg2-color);
175
+ border-radius: var(--border-radius);
172
176
  }
173
177
 
174
178
  button:disabled,
175
179
  input[type='submit']:disabled {
176
- opacity: 0.4;
177
180
  cursor: not-allowed;
181
+ opacity: 0.4;
178
182
  }
179
183
 
180
184
  button:active:not(:disabled),
181
185
  a.button:not(.disabled):active,
182
186
  input[type='submit']:active:not(:disabled) {
183
- background: var(--link-active-color) !important;
184
187
  color: var(--bg-color) !important;
188
+ background: var(--link-active-color) !important;
185
189
  }
186
190
 
187
191
  @media (hover: hover) {
188
192
  button:hover:not(:disabled),
189
193
  a.button:not(.disabled):hover,
190
194
  input[type='submit']:hover:not(:disabled) {
191
- background: var(--bg2-color);
192
195
  cursor: pointer;
196
+ background: var(--bg2-color);
193
197
  }
194
198
  }
195
199
 
@@ -201,8 +205,8 @@ input[type='search']:focus,
201
205
  select:focus {
202
206
  outline: 2px solid var(--theme-color);
203
207
  outline-offset: 1px;
204
- border-color: var(--fg-color);
205
208
  background-color: var(--bg2-color);
209
+ border-color: var(--fg-color);
206
210
  }
207
211
 
208
212
  button.icon-button {
@@ -211,12 +215,12 @@ button.icon-button {
211
215
  justify-content: center;
212
216
  width: 30px;
213
217
  height: 30px;
214
- border-radius: 999px;
215
218
  padding: 0;
216
- border: none;
217
- font-weight: 400;
218
219
  font-style: normal;
220
+ font-weight: 400;
219
221
  vertical-align: top;
222
+ border: none;
223
+ border-radius: 999px;
220
224
  }
221
225
 
222
226
  button.icon-button:focus {
@@ -225,8 +229,8 @@ button.icon-button:focus {
225
229
 
226
230
  ol.styled-list,
227
231
  ul.styled-list {
228
- color: var(--theme-color-text);
229
232
  font-weight: 700;
233
+ color: var(--theme-color-text);
230
234
  }
231
235
 
232
236
  ul.styled-list {
@@ -236,9 +240,9 @@ ul.styled-list {
236
240
 
237
241
  ol li .styled-list-item,
238
242
  ul li .styled-list-item {
239
- color: var(--fg-color);
240
- font-weight: var(--font-weight);
241
243
  font-size: 1rem;
244
+ font-weight: var(--font-weight);
245
+ color: var(--fg-color);
242
246
  }
243
247
 
244
248
  ul {
@@ -278,10 +282,10 @@ ol ol ol ol ol {
278
282
  }
279
283
 
280
284
  table {
285
+ margin: 1rem 0;
286
+ overflow: scroll;
281
287
  font-size: var(--font-size-smaller);
282
288
  border-collapse: collapse;
283
- overflow: scroll;
284
- margin: 1rem 0;
285
289
  }
286
290
 
287
291
  thead {
@@ -301,8 +305,8 @@ th {
301
305
  th,
302
306
  td {
303
307
  padding: var(--table-padding) var(--table-padding) var(--table-padding) 0;
304
- text-align: left;
305
308
  vertical-align: top;
309
+ text-align: left;
306
310
  }
307
311
 
308
312
  tbody tr:last-child td {
@@ -310,6 +314,8 @@ tbody tr:last-child td {
310
314
  }
311
315
 
312
316
  section {
317
+ padding: calc(5 * var(--gap)) calc(2 * var(--gap));
318
+ margin: 0 calc(-1 * var(--gap)) 2rem;
313
319
  background: linear-gradient(
314
320
  0deg,
315
321
  transparent 0,
@@ -317,8 +323,6 @@ section {
317
323
  var(--bg2-color) calc(100% - 3rem),
318
324
  transparent 100%
319
325
  );
320
- padding: calc(5 * var(--gap)) calc(2 * var(--gap));
321
- margin: 0 calc(-1 * var(--gap)) 2rem calc(-1 * var(--gap));
322
326
 
323
327
  .alert {
324
328
  background: var(--bg-color);
@@ -344,9 +348,9 @@ section > h2 + p {
344
348
  }
345
349
 
346
350
  blockquote {
347
- color: var(--fg-color);
348
- font-style: italic;
349
351
  font-size: 1.2em;
352
+ font-style: italic;
353
+ color: var(--fg-color);
350
354
  }
351
355
 
352
356
  .heading-subtitle {
@@ -367,16 +371,16 @@ h3.has-subtitle,
367
371
  h4.has-subtitle,
368
372
  h5.has-subtitle,
369
373
  h6.has-subtitle {
370
- margin-top: 6rem;
371
- border-bottom: 1px solid var(--fg-color);
372
374
  padding-bottom: 0.5em;
375
+ margin-top: 6rem;
373
376
  margin-bottom: 0.5em;
377
+ border-bottom: 1px solid var(--fg-color);
374
378
  }
375
379
 
376
380
  .small-caps {
377
- text-transform: uppercase;
378
- font-weight: 600;
379
381
  font-size: 0.9em;
382
+ font-weight: 600;
383
+ text-transform: uppercase;
380
384
  }
381
385
 
382
386
  dl {
@@ -391,9 +395,9 @@ dl {
391
395
  }
392
396
 
393
397
  dfn {
398
+ font-style: italic;
394
399
  font-weight: 500;
395
400
  color: var(--theme-color-text);
396
- font-style: italic;
397
401
  }
398
402
 
399
403
  a.breadcrumb {
@@ -401,11 +405,12 @@ a.breadcrumb {
401
405
  @include subdued-link;
402
406
 
403
407
  &::after {
404
- content: '';
405
408
  display: inline-block;
406
409
  width: 1em;
407
410
  height: 1em;
408
411
  vertical-align: middle;
412
+ content: '';
413
+
409
414
  @include contained-mask(var(--icon-breadcrumb));
410
415
  }
411
416
  }
@@ -415,54 +420,54 @@ img {
415
420
  }
416
421
 
417
422
  .avatar {
418
- aspect-ratio: 1 / 1;
419
423
  max-width: 100px;
420
- border-radius: 999px;
424
+ aspect-ratio: 1 / 1;
421
425
  object-fit: cover;
426
+ border-radius: 999px;
422
427
  }
423
428
 
424
429
  figure.bio {
425
430
  float: left;
426
- margin: 1rem 1rem 1rem 0;
427
431
  max-width: 125px;
432
+ margin: 1rem 1rem 1rem 0;
428
433
 
429
434
  @media (width > 540px) {
430
435
  max-width: 200px;
431
436
  }
432
437
 
433
438
  .avatar {
434
- max-width: 100%;
435
- width: 100%;
436
439
  display: block;
440
+ width: 100%;
441
+ max-width: 100%;
437
442
  }
438
443
 
439
444
  figcaption {
440
- text-align: center;
441
445
  margin-top: var(--gap);
442
446
  font-style: italic;
447
+ text-align: center;
443
448
  }
444
449
  }
445
450
 
446
451
  kbd {
447
452
  display: inline-block;
448
453
  padding: 1px 5px;
449
- border: 1px solid var(--fg-color);
450
- border-radius: 4px;
451
- box-shadow: 0 2px 0 var(--fg-color);
452
454
  font-family: var(--font);
453
455
  font-size: var(--font-size-small);
454
456
  font-weight: 500;
457
+ border: 1px solid var(--fg-color);
458
+ border-radius: 4px;
459
+ box-shadow: 0 2px 0 var(--fg-color);
455
460
  }
456
461
 
457
462
  select {
463
+ position: relative;
464
+ padding: 4px;
458
465
  font-family: var(--font);
466
+ font-size: inherit;
459
467
  color: var(--fg-color);
460
468
  background: var(--bg-color);
461
469
  border: var(--control-border-width) solid var(--fg2-color);
462
470
  border-radius: var(--border-radius);
463
- padding: 4px;
464
- position: relative;
465
- font-size: inherit;
466
471
  }
467
472
 
468
473
  // Shiki dual-theme support (defaultColor: false, CSS custom properties only,
@@ -1,4 +1,5 @@
1
1
  const STORAGE_KEY = 'timezoneSelection';
2
+ const TIMEZONE_SELECT_LABEL = 'Time zone';
2
3
 
3
4
  type PeriodStyle = [am: string, pm: string];
4
5
 
@@ -112,6 +113,13 @@ function init(element: HTMLSelectElement, selectedTz: string) {
112
113
  element.value = selectedTz;
113
114
  element.hidden = false;
114
115
  element.disabled = false;
116
+ if (
117
+ !element.hasAttribute('aria-label') &&
118
+ !element.hasAttribute('aria-labelledby') &&
119
+ (element.labels?.length ?? 0) === 0
120
+ ) {
121
+ element.setAttribute('aria-label', TIMEZONE_SELECT_LABEL);
122
+ }
115
123
  }
116
124
 
117
125
  function dominantPeriodStyle(
@@ -236,7 +244,7 @@ export default (window: Window) => {
236
244
  const resetBtn = window.document.createElement('button');
237
245
  resetBtn.type = 'button';
238
246
  resetBtn.innerHTML =
239
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">' +
247
+ '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" focusable="false">' +
240
248
  '<line x1="18" y1="6" x2="6" y2="18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>' +
241
249
  '<line x1="6" y1="6" x2="18" y2="18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>' +
242
250
  '</svg>';
@@ -254,8 +262,10 @@ export default (window: Window) => {
254
262
  const sync = (val: string) => {
255
263
  selectEl.value = val;
256
264
  const isDefault = val === defaultTz.value;
257
- resetBtn.style.opacity = isDefault ? '0' : '1';
258
- resetBtn.style.pointerEvents = isDefault ? 'none' : '';
265
+ resetBtn.classList.toggle('is-hidden', isDefault);
266
+ resetBtn.disabled = isDefault;
267
+ resetBtn.tabIndex = isDefault ? -1 : 0;
268
+ resetBtn.setAttribute('aria-hidden', String(isDefault));
259
269
  };
260
270
 
261
271
  choosers.push({ sync });
@@ -5,14 +5,20 @@ time[datetime] {
5
5
  }
6
6
 
7
7
  span.next-prev-day {
8
- color: var(--fg2-color);
9
8
  font-style: italic;
9
+ color: var(--fg2-color);
10
10
  }
11
11
 
12
12
  .timezone-wrapper {
13
13
  display: inline-flex;
14
- align-items: center;
15
14
  gap: 4px;
15
+ align-items: center;
16
+
17
+ .icon-button.is-hidden {
18
+ visibility: hidden;
19
+ pointer-events: none;
20
+ opacity: 0;
21
+ }
16
22
  }
17
23
 
18
24
  @media print {
@@ -21,12 +27,12 @@ span.next-prev-day {
21
27
  }
22
28
 
23
29
  select.time-zone {
24
- appearance: none;
25
- border: none;
26
- background: none;
27
30
  padding: 0;
28
31
  font: inherit;
29
32
  color: inherit;
33
+ appearance: none;
34
+ background: none;
35
+ border: none;
30
36
 
31
37
  option {
32
38
  display: none;
@@ -3,6 +3,7 @@
3
3
  :root {
4
4
  --highlight-hue: 59deg;
5
5
  --highlight-color: hsl(var(--highlight-hue) 100% 50% / 50%);
6
+
6
7
  // For animations
7
8
  --highlight-color-transparent: hsl(var(--highlight-hue) 50% 90% / 0%);
8
9
  }
@@ -19,37 +20,37 @@ body.code .toc ol li:has(a) {
19
20
  }
20
21
 
21
22
  body.code .toc ol a {
22
- white-space: nowrap;
23
23
  overflow: hidden;
24
24
  text-overflow: ellipsis;
25
+ white-space: nowrap;
25
26
  }
26
27
 
27
28
  .toc ol::before {
28
- content: 'On this page';
29
29
  display: block;
30
30
  font-family: var(--mono-font);
31
- font-style: italic;
32
31
  font-size: var(--font-size-small);
32
+ font-style: italic;
33
33
  text-align: center;
34
+ content: 'On this page';
34
35
  }
35
36
 
36
37
  .toc ol {
37
- margin: 0;
38
38
  padding: 0;
39
+ margin: 0;
39
40
  }
40
41
 
41
42
  .toc ol li {
42
- list-style-type: none;
43
- overflow-wrap: break-word;
44
43
  margin-bottom: 0;
44
+ overflow-wrap: break-word;
45
+ list-style-type: none;
45
46
  }
46
47
 
47
48
  .toc ol a {
48
- text-decoration: none;
49
- border: none;
50
49
  display: block;
51
50
  padding: 4px 6px;
52
51
  color: var(--fg-color);
52
+ text-decoration: none;
53
+ border: none;
53
54
 
54
55
  &:focus-visible {
55
56
  outline-offset: -2px;
@@ -68,7 +69,7 @@ body.code .toc ol a {
68
69
  color: var(--link-active-color);
69
70
  }
70
71
 
71
- @media (min-width: 900px) {
72
+ @media (width >= 900px) {
72
73
  .toc ol li.current a {
73
74
  background: var(--bg2-color);
74
75
  }
@@ -92,26 +93,26 @@ body.code .toc ol a {
92
93
  }
93
94
 
94
95
  .toc ol li.level3 {
95
- font-size: var(--font-size-smaller);
96
96
  margin-left: 10px;
97
+ font-size: var(--font-size-smaller);
97
98
  }
98
99
 
99
100
  .toc ol li.level4 {
101
+ margin-left: 18px;
100
102
  font-size: var(--font-size-small);
101
103
  font-weight: 450;
102
- margin-left: 18px;
103
104
  }
104
105
 
105
106
  .toc ol li.level5 {
107
+ margin-left: 24px;
106
108
  font-size: var(--font-size-small);
107
109
  font-weight: 450;
108
- margin-left: 24px;
109
110
  }
110
111
 
111
112
  .toc ol li.level6 {
113
+ margin-left: 32px;
112
114
  font-size: var(--font-size-small);
113
115
  font-weight: 450;
114
- margin-left: 32px;
115
116
  }
116
117
 
117
118
  .toc ol li.dinkus-item {
@@ -120,8 +121,8 @@ body.code .toc ol a {
120
121
  pointer-events: none;
121
122
  background-color: var(--fg2-color);
122
123
  mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 12'><rect x='0' y='5.5' width='96' height='1' fill='black'/><path d='M 64,6 C 71,6 80,4.5 80,1 C 80,4.5 89,6 96,6 C 89,6 80,7.5 80,11 C 80,7.5 71,6 64,6 Z' fill='black'/><rect x='64' y='5.5' width='96' height='1' fill='black'/></svg>");
123
- mask-size: 100% 100%;
124
124
  mask-repeat: no-repeat;
125
+ mask-size: 100% 100%;
125
126
  }
126
127
 
127
128
  .toc ol li.alert-item {
@@ -130,12 +131,12 @@ body.code .toc ol a {
130
131
 
131
132
  .toc ol li.alert-item.warning a::before,
132
133
  .toc ol li.alert-item.note a::before {
133
- content: '';
134
134
  display: inline-block;
135
135
  width: 20px;
136
136
  height: 20px;
137
- vertical-align: bottom;
138
137
  margin-right: 4px;
138
+ vertical-align: bottom;
139
+ content: '';
139
140
  }
140
141
 
141
142
  .toc ol li.alert-item.warning a::before {