svelte-readme 4.0.1 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/style.css CHANGED
@@ -1,65 +1,105 @@
1
1
  /**
2
- * Adapted from github-markdown-css (MIT License)
3
- * https://github.com/sindresorhus/github-markdown-css
4
- *
5
- * Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
6
- *
7
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this
8
- * software and associated documentation files (the "Software"), to deal in the Software
9
- * without restriction, including without limitation the rights to use, copy, modify,
10
- * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
11
- * permit persons to whom the Software is furnished to do so, subject to the following
12
- * conditions:
13
- *
14
- * The above copyright notice and this permission notice shall be included in all copies
15
- * or substantial portions of the Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18
- * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
19
- * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
21
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
- *
24
- * Selectors were rescoped from `.markdown-body` to `main`, and rules specific to
25
- * GitHub's own chrome (diff/blob/octicon/utility classes) were dropped since they never
26
- * match rendered README markup. The trailing `p`/`pre` rules below are this project's
27
- * own spacing overrides, not from the upstream stylesheet.
2
+ * Base markdown rendering styles (scoped to `main`) plus the default code-fence
3
+ * button styling — both are part of the same opt-out-able default look (see
4
+ * `disableDefaultCSS` in `svelteReadme.ts`), so they live in one file.
28
5
  *
29
6
  * Colors, font stacks, and the block-spacing unit are pulled out as custom properties
30
7
  * so a consumer can retheme this (e.g. dark mode, brand colors) by overriding them on
31
8
  * `:root` or `main`, without having to override individual rules.
9
+ *
10
+ * Sizes are in `rem` (assuming the standard 16px browser default) rather than `px`
11
+ * wherever the value is typographic or a layout measurement, so the page scales with
12
+ * a user's root font-size preference/zoom. Border widths and shadow offsets stay in
13
+ * `px` — hairlines and shadow "feel" aren't meant to scale with text size.
32
14
  **/
33
15
 
34
16
  :root {
35
- --gh-font-sans: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;
36
- --gh-font-mono: SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;
37
-
38
- --gh-color-fg: #24292e;
39
- --gh-color-fg-muted: #6a737d;
40
- --gh-color-fg-subtle: #444d56;
41
- --gh-color-link: #0366d6;
42
-
43
- --gh-color-canvas: #fff;
44
- --gh-color-canvas-subtle: #f6f8fa;
45
- --gh-color-kbd-bg: #fafbfc;
46
- --gh-color-code-bg: rgba(27,31,35,.05);
47
-
48
- --gh-color-border: #dfe2e5;
49
- --gh-color-border-muted: #eaecef;
50
- --gh-color-border-kbd: #d1d5da;
51
- --gh-color-border-table: #c6cbd1;
52
- --gh-color-hr: #e1e4e8;
53
-
54
- --gh-spacing: 16px;
55
- --gh-spacing-lg: 24px;
17
+ --sr-font-sans:
18
+ system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;
19
+ --sr-font-mono:
20
+ ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono,
21
+ monospace;
22
+
23
+ --sr-color-fg: #18181b;
24
+ --sr-color-fg-muted: #71717a;
25
+ --sr-color-fg-subtle: #52525b;
26
+ --sr-color-link: #4f46e5;
27
+
28
+ --sr-color-canvas: #fff;
29
+ --sr-color-canvas-subtle: #f4f4f5;
30
+ --sr-color-kbd-bg: #fafafa;
31
+ --sr-color-code-bg: rgba(24, 24, 27, 0.06);
32
+
33
+ --sr-color-border: #e4e4e7;
34
+ --sr-color-border-muted: #ececef;
35
+ --sr-color-border-kbd: #d4d4d8;
36
+ --sr-color-border-table: #d4d4d8;
37
+ --sr-color-hr: #e4e4e7;
38
+
39
+ /* Glossy top-edge highlight on the code-fence/copy button and `summary`'s bevel
40
+ (see `.code-fence button`/`summary` below) — a fixed white reads as a subtle sheen
41
+ on the light canvas but as a harsh glowing line once the surface behind it goes
42
+ dark, so it's a variable rather than a literal `rgba(255, 255, 255, 0.6)`. */
43
+ --sr-color-bevel-highlight: rgba(255, 255, 255, 0.6);
44
+
45
+ --sr-spacing: 1.5rem;
46
+ --sr-spacing-lg: 2.5rem;
47
+ --sr-spacing-xl: 4rem;
48
+ --sr-box-padding: 1rem;
49
+
50
+ --sr-text-2xs: 0.6875rem;
51
+ --sr-text-xs: 0.75rem;
52
+ --sr-text-sm: 0.8125rem;
53
+ --sr-text-base: 0.875rem;
54
+ --sr-text-lg: 1.125rem;
55
+ --sr-text-xl: 1.375rem;
56
+ --sr-text-2xl: 1.75rem;
57
+ --sr-text-3xl: 2.5rem;
58
+
59
+ /* Declared here (rather than on `body`) so `purgeUnusedCss` — which only checks
60
+ tags/classes/attrs actually present in the server-rendered markup — has no reason
61
+ to strip it: `:root` has no selector to verify and is always kept, while `body`
62
+ never literally appears in Svelte's SSR output (which renders only what's inside
63
+ it). `<html>`'s background still paints the full viewport per the CSS spec's
64
+ canvas-background propagation, same as if this were set on `body`. */
65
+ background-color: var(--sr-color-canvas);
66
+
67
+ /* Tells the browser which palette this page actually uses, so native chrome that
68
+ isn't styled by the rules below — form controls, the scrollbar, `<select>`
69
+ dropdowns — switches to match instead of rendering a light widget on a dark page. */
70
+ color-scheme: light;
71
+ }
72
+
73
+ /* Set on `<html>` before first paint by the inline script in the HTML template
74
+ (see `THEME_INIT_SCRIPT` in `svelteReadme.ts`), so this never flashes the light
75
+ palette before switching to dark. */
76
+ :root[data-sr-theme="dark"] {
77
+ --sr-color-fg: #e4e4e7;
78
+ --sr-color-fg-muted: #a1a1aa;
79
+ --sr-color-fg-subtle: #d4d4d8;
80
+ --sr-color-link: #a5b4fc;
81
+
82
+ --sr-color-canvas: #18181b;
83
+ --sr-color-canvas-subtle: #27272a;
84
+ --sr-color-kbd-bg: #26262b;
85
+ --sr-color-code-bg: rgba(255, 255, 255, 0.08);
86
+
87
+ --sr-color-border: #3f3f46;
88
+ --sr-color-border-muted: #313136;
89
+ --sr-color-border-kbd: #52525b;
90
+ --sr-color-border-table: #52525b;
91
+ --sr-color-hr: #3f3f46;
92
+
93
+ --sr-color-bevel-highlight: rgba(255, 255, 255, 0.06);
94
+
95
+ color-scheme: dark;
56
96
  }
57
97
 
58
98
  .anchor {
59
99
  float: left;
60
100
  line-height: 1;
61
- margin-left: -20px;
62
- padding-right: 4px;
101
+ margin-left: -1.25rem;
102
+ padding-right: 0.25rem;
63
103
  }
64
104
 
65
105
  .anchor:focus {
@@ -79,9 +119,9 @@ main {
79
119
  -ms-text-size-adjust: 100%;
80
120
  -webkit-text-size-adjust: 100%;
81
121
  line-height: 1.5;
82
- color: var(--gh-color-fg);
83
- font-family: var(--gh-font-sans);
84
- font-size: 16px;
122
+ color: var(--sr-color-fg);
123
+ font-family: var(--sr-font-sans);
124
+ font-size: var(--sr-text-base);
85
125
  word-wrap: break-word;
86
126
  }
87
127
 
@@ -103,15 +143,9 @@ a:hover {
103
143
  }
104
144
 
105
145
  strong {
106
- font-weight: inherit;
107
146
  font-weight: bolder;
108
147
  }
109
148
 
110
- h1 {
111
- font-size: 2em;
112
- margin: .67em 0;
113
- }
114
-
115
149
  img {
116
150
  border-style: none;
117
151
  }
@@ -119,7 +153,7 @@ img {
119
153
  code,
120
154
  kbd,
121
155
  pre {
122
- font-family: monospace,monospace;
156
+ font-family: monospace;
123
157
  font-size: 1em;
124
158
  }
125
159
 
@@ -138,7 +172,7 @@ input {
138
172
  overflow: visible;
139
173
  }
140
174
 
141
- [type=checkbox] {
175
+ [type="checkbox"] {
142
176
  box-sizing: border-box;
143
177
  padding: 0;
144
178
  }
@@ -154,7 +188,7 @@ input {
154
188
  }
155
189
 
156
190
  a {
157
- color: var(--gh-color-link);
191
+ color: var(--sr-color-link);
158
192
  text-decoration: none;
159
193
  }
160
194
 
@@ -168,11 +202,11 @@ strong {
168
202
 
169
203
  hr {
170
204
  height: 0;
171
- margin: 15px 0;
205
+ margin: 0.9375rem 0;
172
206
  overflow: hidden;
173
207
  background: transparent;
174
208
  border: 0;
175
- border-bottom: 1px solid var(--gh-color-border);
209
+ border-bottom: 1px solid var(--sr-color-border);
176
210
  }
177
211
 
178
212
  hr:after,
@@ -201,69 +235,20 @@ details summary {
201
235
 
202
236
  kbd {
203
237
  display: inline-block;
204
- padding: 3px 5px;
205
- font: 11px var(--gh-font-mono);
206
- line-height: 10px;
207
- color: var(--gh-color-fg-subtle);
238
+ padding: 0.1875rem 0.3125rem;
239
+ font: var(--sr-text-2xs) var(--sr-font-mono);
240
+ line-height: 0.625rem;
241
+ color: var(--sr-color-fg-subtle);
208
242
  vertical-align: middle;
209
- background-color: var(--gh-color-kbd-bg);
210
- border: 1px solid var(--gh-color-border-kbd);
211
- border-radius: 3px;
212
- box-shadow: inset 0 -1px 0 var(--gh-color-border-kbd);
213
- }
214
-
215
- h1,
216
- h2,
217
- h3,
218
- h4,
219
- h5,
220
- h6 {
221
- margin-top: 0;
222
- margin-bottom: 0;
223
- }
224
-
225
- h1 {
226
- font-size: 32px;
227
- }
228
-
229
- h1,
230
- h2 {
231
- font-weight: 600;
232
- }
233
-
234
- h2 {
235
- font-size: 24px;
236
- }
237
-
238
- h3 {
239
- font-size: 20px;
240
- }
241
-
242
- h3,
243
- h4 {
244
- font-weight: 600;
245
- }
246
-
247
- h4 {
248
- font-size: 16px;
249
- }
250
-
251
- h5 {
252
- font-size: 14px;
253
- }
254
-
255
- h5,
256
- h6 {
257
- font-weight: 600;
258
- }
259
-
260
- h6 {
261
- font-size: 12px;
243
+ background-color: var(--sr-color-kbd-bg);
244
+ border: 1px solid var(--sr-color-border-kbd);
245
+ border-radius: 0.1875rem;
246
+ box-shadow: inset 0 -1px 0 var(--sr-color-border-kbd);
262
247
  }
263
248
 
264
249
  p {
265
250
  margin-top: 0;
266
- margin-bottom: 10px;
251
+ margin-bottom: 0.625rem;
267
252
  }
268
253
 
269
254
  blockquote {
@@ -295,8 +280,7 @@ dd {
295
280
 
296
281
  code,
297
282
  pre {
298
- font-family: var(--gh-font-mono);
299
- font-size: 12px;
283
+ font-family: var(--sr-font-mono);
300
284
  }
301
285
 
302
286
  pre {
@@ -311,18 +295,18 @@ input::-webkit-outer-spin-button {
311
295
  appearance: none;
312
296
  }
313
297
 
314
- :checked+.radio-label {
298
+ :checked + .radio-label {
315
299
  position: relative;
316
300
  z-index: 1;
317
- border-color: var(--gh-color-link);
301
+ border-color: var(--sr-color-link);
318
302
  }
319
303
 
320
304
  hr {
321
- border-bottom-color: #eee;
305
+ border-bottom-color: var(--sr-color-border-muted);
322
306
  }
323
307
 
324
- main:after,
325
- .markdown-body:before {
308
+ main:before,
309
+ main:after {
326
310
  display: table;
327
311
  content: "";
328
312
  }
@@ -331,12 +315,14 @@ main:after {
331
315
  clear: both;
332
316
  }
333
317
 
334
- main>:first-child {
335
- margin-top: 0!important;
318
+ main > :first-child {
319
+ /* biome-ignore lint/complexity/noImportantStyles: must win over arbitrary user-authored margins on the README's first/last rendered element */
320
+ margin-top: 0 !important;
336
321
  }
337
322
 
338
- main>:last-child {
339
- margin-bottom: 0!important;
323
+ main > :last-child {
324
+ /* biome-ignore lint/complexity/noImportantStyles: must win over arbitrary user-authored margins on the README's first/last rendered element */
325
+ margin-bottom: 0 !important;
340
326
  }
341
327
 
342
328
  a:not([href]) {
@@ -353,28 +339,28 @@ pre,
353
339
  table,
354
340
  ul {
355
341
  margin-top: 0;
356
- margin-bottom: var(--gh-spacing);
342
+ margin-bottom: var(--sr-spacing);
357
343
  }
358
344
 
359
345
  hr {
360
- height: .25em;
346
+ height: 0.25em;
361
347
  padding: 0;
362
- margin: var(--gh-spacing-lg) 0;
363
- background-color: var(--gh-color-hr);
348
+ margin: var(--sr-spacing-lg) 0;
349
+ background-color: var(--sr-color-hr);
364
350
  border: 0;
365
351
  }
366
352
 
367
353
  blockquote {
368
354
  padding: 0 1em;
369
- color: var(--gh-color-fg-muted);
370
- border-left: .25em solid var(--gh-color-border);
355
+ color: var(--sr-color-fg-muted);
356
+ border-left: 0.25em solid var(--sr-color-border);
371
357
  }
372
358
 
373
- blockquote>:first-child {
359
+ blockquote > :first-child {
374
360
  margin-top: 0;
375
361
  }
376
362
 
377
- blockquote>:last-child {
363
+ blockquote > :last-child {
378
364
  margin-bottom: 0;
379
365
  }
380
366
 
@@ -384,41 +370,36 @@ h3,
384
370
  h4,
385
371
  h5,
386
372
  h6 {
387
- margin-top: var(--gh-spacing-lg);
388
- margin-bottom: var(--gh-spacing);
373
+ margin-top: var(--sr-spacing-lg);
374
+ margin-bottom: var(--sr-spacing);
389
375
  font-weight: 600;
390
376
  line-height: 1.25;
391
377
  }
392
378
 
393
379
  h1 {
394
- font-size: 2em;
395
- }
396
-
397
- h1,
398
- h2 {
399
- padding-bottom: .3em;
400
- border-bottom: 1px solid var(--gh-color-border-muted);
380
+ font-size: var(--sr-text-3xl);
401
381
  }
402
382
 
403
383
  h2 {
404
- font-size: 1.5em;
384
+ margin-top: var(--sr-spacing-xl);
385
+ font-size: var(--sr-text-2xl);
405
386
  }
406
387
 
407
388
  h3 {
408
- font-size: 1.25em;
389
+ font-size: var(--sr-text-xl);
409
390
  }
410
391
 
411
392
  h4 {
412
- font-size: 1em;
393
+ font-size: var(--sr-text-lg);
413
394
  }
414
395
 
415
396
  h5 {
416
- font-size: .875em;
397
+ font-size: var(--sr-text-sm);
417
398
  }
418
399
 
419
400
  h6 {
420
- font-size: .85em;
421
- color: var(--gh-color-fg-muted);
401
+ font-size: var(--sr-text-xs);
402
+ color: var(--sr-color-fg-muted);
422
403
  }
423
404
 
424
405
  ol,
@@ -427,23 +408,30 @@ ul {
427
408
  }
428
409
 
429
410
  ol ol,
430
- ol ul,
411
+ ol ul {
412
+ margin-top: 0;
413
+ margin-bottom: 0;
414
+ }
415
+
416
+ /* A numbered sub-list (above) reads as a continuation of its parent's sequence —
417
+ tight to its own numbering flow. A bulleted sub-list is a categorical grouping,
418
+ so it gets the extra bottom margin to set it apart from the next category. */
431
419
  ul ol,
432
420
  ul ul {
433
421
  margin-top: 0;
434
- margin-bottom: 0;
422
+ margin-bottom: var(--sr-spacing);
435
423
  }
436
424
 
437
425
  li {
438
426
  word-wrap: break-all;
439
427
  }
440
428
 
441
- li>p {
442
- margin-top: var(--gh-spacing);
429
+ li > p {
430
+ margin-top: var(--sr-spacing);
443
431
  }
444
432
 
445
- li+li {
446
- margin-top: .25em;
433
+ li + li {
434
+ margin-top: 0.25em;
447
435
  }
448
436
 
449
437
  dl {
@@ -452,21 +440,24 @@ dl {
452
440
 
453
441
  dl dt {
454
442
  padding: 0;
455
- margin-top: var(--gh-spacing);
443
+ margin-top: var(--sr-spacing);
456
444
  font-size: 1em;
457
445
  font-style: italic;
458
446
  font-weight: 600;
459
447
  }
460
448
 
461
449
  dl dd {
462
- padding: 0 var(--gh-spacing);
463
- margin-bottom: var(--gh-spacing);
450
+ padding: 0 var(--sr-spacing);
451
+ margin-bottom: var(--sr-spacing);
464
452
  }
465
453
 
466
454
  table {
467
455
  display: block;
468
- width: 100%;
456
+ width: fit-content;
457
+ margin-right: -0.8125rem;
458
+ margin-left: -0.8125rem;
469
459
  overflow: auto;
460
+ font-size: var(--sr-text-sm);
470
461
  }
471
462
 
472
463
  table th {
@@ -475,46 +466,41 @@ table th {
475
466
 
476
467
  table td,
477
468
  table th {
478
- padding: 6px 13px;
479
- border: 1px solid var(--gh-color-border);
469
+ padding: 0.375rem 0.8125rem;
470
+ border: 1px solid var(--sr-color-border);
480
471
  }
481
472
 
482
473
  table tr {
483
- background-color: var(--gh-color-canvas);
484
- border-top: 1px solid var(--gh-color-border-table);
485
- }
486
-
487
- table tr:nth-child(2n) {
488
- background-color: var(--gh-color-canvas-subtle);
474
+ background-color: var(--sr-color-canvas);
475
+ border-top: 1px solid var(--sr-color-border-table);
489
476
  }
490
477
 
491
478
  img {
492
479
  max-width: 100%;
493
480
  box-sizing: initial;
494
- background-color: var(--gh-color-canvas);
481
+ background-color: var(--sr-color-canvas);
495
482
  }
496
483
 
497
- img[align=right] {
498
- padding-left: 20px;
484
+ img[align="right"] {
485
+ padding-left: 1.25rem;
499
486
  }
500
487
 
501
- img[align=left] {
502
- padding-right: 20px;
488
+ img[align="left"] {
489
+ padding-right: 1.25rem;
503
490
  }
504
491
 
505
492
  code {
506
- padding: .2em .4em;
493
+ padding: 0.2em 0.4em;
507
494
  margin: 0;
508
495
  font-size: 85%;
509
- background-color: var(--gh-color-code-bg);
510
- border-radius: 3px;
496
+ background-color: var(--sr-color-code-bg);
511
497
  }
512
498
 
513
499
  pre {
514
500
  word-wrap: normal;
515
501
  }
516
502
 
517
- pre>code {
503
+ pre > code {
518
504
  padding: 0;
519
505
  margin: 0;
520
506
  font-size: 100%;
@@ -525,7 +511,7 @@ pre>code {
525
511
  }
526
512
 
527
513
  .highlight {
528
- margin-bottom: var(--gh-spacing);
514
+ margin-bottom: var(--sr-spacing);
529
515
  }
530
516
 
531
517
  .highlight pre {
@@ -535,12 +521,13 @@ pre>code {
535
521
 
536
522
  .highlight pre,
537
523
  pre {
538
- padding: var(--gh-spacing);
524
+ padding: var(--sr-box-padding);
525
+ margin-right: calc(var(--sr-box-padding) * -1);
526
+ margin-left: calc(var(--sr-box-padding) * -1);
539
527
  overflow: auto;
540
- font-size: 85%;
541
- line-height: 1.45;
542
- background-color: var(--gh-color-canvas-subtle);
543
- border-radius: 3px;
528
+ font-size: var(--sr-text-xs);
529
+ line-height: 1.4;
530
+ background-color: var(--sr-color-canvas-subtle);
544
531
  }
545
532
 
546
533
  pre code {
@@ -555,11 +542,204 @@ pre code {
555
542
  border: 0;
556
543
  }
557
544
 
558
- /* Overrides to keep spacing consistent with our own layout, not GitHub's. */
545
+ /* Overrides to keep spacing consistent with our own layout. */
559
546
 
560
547
  p {
561
- min-height: 28px;
548
+ min-height: 1.75rem;
562
549
  }
563
550
  pre {
564
- margin-bottom: 48px;
551
+ margin-bottom: var(--sr-spacing-xl);
552
+ }
553
+
554
+ /* Default code-fence button styling (formerly `button.css`). */
555
+
556
+ .code-fence button {
557
+ font-family: inherit;
558
+ text-transform: none;
559
+ position: relative;
560
+ display: inline-block;
561
+ padding: 0.1875rem 0.625rem;
562
+ font-size: var(--sr-text-xs);
563
+ font-weight: 500;
564
+ line-height: 1rem;
565
+ white-space: nowrap;
566
+ vertical-align: middle;
567
+ cursor: pointer;
568
+ user-select: none;
569
+ border: 1px solid var(--sr-color-border);
570
+ border-radius: 0.375rem;
571
+ appearance: none;
572
+ color: var(--sr-color-fg);
573
+ background: linear-gradient(
574
+ 180deg,
575
+ var(--sr-color-kbd-bg),
576
+ var(--sr-color-canvas-subtle)
577
+ );
578
+ box-shadow:
579
+ 0 1px 0 rgba(24, 24, 27, 0.04),
580
+ inset 0 1px 0 var(--sr-color-bevel-highlight);
581
+ transition:
582
+ background 0.2s cubic-bezier(0.3, 0, 0.5, 1),
583
+ box-shadow 0.15s;
584
+ }
585
+
586
+ .code-fence button:hover {
587
+ background: linear-gradient(
588
+ 180deg,
589
+ var(--sr-color-canvas-subtle),
590
+ var(--sr-color-border)
591
+ );
592
+ }
593
+
594
+ .code-fence button:active {
595
+ background: var(--sr-color-canvas-subtle);
596
+ box-shadow: inset 0 1px 2px rgba(24, 24, 27, 0.08);
597
+ }
598
+
599
+ /* Copy-to-clipboard button rendered as the last child of each code snippet's `<pre>`
600
+ (see `COPY_BUTTON_MARKUP` in `preprocessReadme.ts`) and overlaid on its corner via
601
+ `position: absolute`. Anchored against `.sr-code-block` (a non-scrolling wrapper
602
+ `preprocessReadme.ts` adds around every highlighted `<pre>`) rather than `<pre>`
603
+ itself — `<pre>` has its own `overflow: auto` for long lines, and a `right`-anchored
604
+ absolute child of a scrolling box drifts with that box's horizontal scroll.
605
+
606
+ The bleed (negative margin equal to `pre`'s own padding, same technique as the
607
+ table/details bleed above) moves from `pre` to `.sr-code-block` here, with `pre`'s
608
+ own margin canceled below — otherwise `.sr-code-block`'s box (what the button is
609
+ positioned against) would stop short of `pre`'s bled edge, leaving the button
610
+ inset from the visible corner by the full bleed amount. */
611
+
612
+ .sr-code-block {
613
+ position: relative;
614
+ margin-right: calc(var(--sr-box-padding) * -1);
615
+ margin-left: calc(var(--sr-box-padding) * -1);
616
+ }
617
+
618
+ .sr-code-block pre {
619
+ margin-right: 0;
620
+ margin-left: 0;
621
+ }
622
+
623
+ .sr-copy-button {
624
+ position: absolute;
625
+ top: 0.5rem;
626
+ right: 0.5rem;
627
+ display: flex;
628
+ align-items: center;
629
+ justify-content: center;
630
+ padding: 0.25rem;
631
+ color: var(--sr-color-fg-muted);
632
+ cursor: pointer;
633
+ appearance: none;
634
+ background-color: var(--sr-color-canvas);
635
+ border: 1px solid var(--sr-color-border);
636
+ border-radius: 0.375rem;
637
+ }
638
+
639
+ /* Hidden until hover/focus so it doesn't clutter every code block at rest — but
640
+ only on devices that actually have a hover affordance. On touch-only devices
641
+ `(hover: none)` there's no hover to reveal it, so it stays visible instead. */
642
+ @media (hover: hover) {
643
+ .sr-copy-button {
644
+ opacity: 0;
645
+ transition: opacity 0.15s;
646
+ }
647
+
648
+ .sr-code-block:hover .sr-copy-button,
649
+ .sr-copy-button:focus-visible,
650
+ .sr-copy-button.sr-copy-copied {
651
+ opacity: 1;
652
+ }
653
+ }
654
+
655
+ /* Same specificity as `.sr-copy-check` below (one class each) so source order
656
+ decides the default state — a `.sr-copy-button svg` selector here would win on
657
+ specificity regardless of order and defeat that rule's `display: none`. */
658
+ .sr-copy-icon,
659
+ .sr-copy-check {
660
+ display: block;
661
+ fill: currentColor;
662
+ }
663
+
664
+ /* `.sr-copy-copied` is toggled client-side by the copy-button script for 2s of
665
+ feedback after a successful copy — never present in server-rendered markup. */
666
+ .sr-copy-check {
667
+ display: none;
668
+ }
669
+
670
+ .sr-copy-button.sr-copy-copied .sr-copy-icon {
671
+ display: none;
672
+ }
673
+
674
+ .sr-copy-button.sr-copy-copied .sr-copy-check {
675
+ display: block;
676
+ }
677
+
678
+ /* `details`/`summary`, styled with the same clickable material as the code-fence
679
+ button above. `summary` bleeds out to the `details` border via a negative
680
+ margin (same technique as the table/pre bleed) so its background spans the
681
+ full box edge-to-edge, rather than sitting inset with the revealed content. */
682
+
683
+ details {
684
+ padding: 0 var(--sr-box-padding);
685
+ margin-right: calc(var(--sr-box-padding) * -1);
686
+ margin-left: calc(var(--sr-box-padding) * -1);
687
+ border: 1px solid var(--sr-color-border-muted);
688
+ }
689
+
690
+ /* Bottom padding only applies once there's revealed content to pad — otherwise
691
+ (closed, just the summary bar) it'd reserve empty space below the summary,
692
+ showing as a hollow gap before the box's own bottom border. */
693
+ details[open] {
694
+ padding-bottom: var(--sr-spacing);
695
+ }
696
+
697
+ summary {
698
+ padding: 0.75rem var(--sr-box-padding);
699
+ margin: 0 calc(var(--sr-box-padding) * -1);
700
+ font-weight: 500;
701
+ color: var(--sr-color-fg);
702
+ background: linear-gradient(
703
+ 180deg,
704
+ var(--sr-color-kbd-bg),
705
+ var(--sr-color-canvas-subtle)
706
+ );
707
+ box-shadow:
708
+ 0 1px 0 rgba(24, 24, 27, 0.04),
709
+ inset 0 1px 0 var(--sr-color-bevel-highlight);
710
+ transition:
711
+ background 0.2s cubic-bezier(0.3, 0, 0.5, 1),
712
+ box-shadow 0.15s;
713
+ }
714
+
715
+ summary:hover {
716
+ background: linear-gradient(
717
+ 180deg,
718
+ var(--sr-color-canvas-subtle),
719
+ var(--sr-color-border)
720
+ );
721
+ }
722
+
723
+ summary:active {
724
+ background: var(--sr-color-canvas-subtle);
725
+ box-shadow: inset 0 1px 2px rgba(24, 24, 27, 0.08);
726
+ }
727
+
728
+ details[open] > summary {
729
+ border-bottom: 1px solid var(--sr-color-border-muted);
730
+ }
731
+
732
+ summary + * {
733
+ margin-top: var(--sr-spacing);
734
+ }
735
+
736
+ /* Adjacent `details` conjoin into a single accordion: no gap and no doubled
737
+ border at the seam between them. */
738
+ details + details {
739
+ margin-top: 0;
740
+ border-top: 0;
741
+ }
742
+
743
+ details:has(+ details) {
744
+ margin-bottom: 0;
565
745
  }