encre_css_typography/
lib.rs

1//! Define beautiful typographic defaults for HTML you don't control.
2//!
3/// CSS Styles are derived from TailwindCSS' typography plugin (https://github.com/tailwindlabs/tailwindcss-typography/blob/master/src/styles.js),
4/// under the MIT license.
5use encre_css::{
6    generator::{
7        generate_at_rules, generate_class, generate_wrapper, ContextCanHandle, ContextHandle,
8    },
9    plugins::Plugin,
10    selector::{Modifier, Variant},
11    Config,
12};
13use std::borrow::Cow;
14
15const PROSE_DEFAULT_CSS: &str = r#".prose {
16  color: var(--en-prose-body);
17  max-width: 65ch;
18}
19
20.prose :where([class~="lead"]):not(:where([class~="not-prose"] *)) {
21  color: var(--en-prose-lead);
22  font-size: 1.25em;
23  line-height: 1.6;
24  margin-top: 1.2em;
25  margin-bottom: 1.2em;
26}
27
28.prose :where(a):not(:where([class~="not-prose"] *)) {
29  color: var(--en-prose-links);
30  text-decoration: underline;
31  font-weight: 500;
32}
33
34.prose :where(strong):not(:where([class~="not-prose"] *)) {
35  color: var(--en-prose-bold);
36  font-weight: 600;
37}
38
39.prose :where(a strong):not(:where([class~="not-prose"] *)) {
40  color: inherit;
41}
42
43.prose :where(blockquote strong):not(:where([class~="not-prose"] *)) {
44  color: inherit;
45}
46
47.prose :where(thead th strong):not(:where([class~="not-prose"] *)) {
48  color: inherit;
49}
50
51.prose :where(ol):not(:where([class~="not-prose"] *)) {
52  list-style-type: decimal;
53  margin-top: 1.25em;
54  margin-bottom: 1.25em;
55  padding-left: 1.625em;
56}
57
58.prose :where(ol[type="A"]):not(:where([class~="not-prose"] *)) {
59  list-style-type: upper-alpha;
60}
61
62.prose :where(ol[type="a"]):not(:where([class~="not-prose"] *)) {
63  list-style-type: lower-alpha;
64}
65
66.prose :where(ol[type="A" s]):not(:where([class~="not-prose"] *)) {
67  list-style-type: upper-alpha;
68}
69
70.prose :where(ol[type="a" s]):not(:where([class~="not-prose"] *)) {
71  list-style-type: lower-alpha;
72}
73
74.prose :where(ol[type="I"]):not(:where([class~="not-prose"] *)) {
75  list-style-type: upper-roman;
76}
77
78.prose :where(ol[type="i"]):not(:where([class~="not-prose"] *)) {
79  list-style-type: lower-roman;
80}
81
82.prose :where(ol[type="I" s]):not(:where([class~="not-prose"] *)) {
83  list-style-type: upper-roman;
84}
85
86.prose :where(ol[type="i" s]):not(:where([class~="not-prose"] *)) {
87  list-style-type: lower-roman;
88}
89
90.prose :where(ol[type="1"]):not(:where([class~="not-prose"] *)) {
91  list-style-type: decimal;
92}
93
94.prose :where(ul):not(:where([class~="not-prose"] *)) {
95  list-style-type: disc;
96  margin-top: 1.25em;
97  margin-bottom: 1.25em;
98  padding-left: 1.625em;
99}
100
101.prose :where(ol > li):not(:where([class~="not-prose"] *))::marker {
102  font-weight: 400;
103  color: var(--en-prose-counters);
104}
105
106.prose :where(ul > li):not(:where([class~="not-prose"] *))::marker {
107  color: var(--en-prose-bullets);
108}
109
110.prose :where(hr):not(:where([class~="not-prose"] *)) {
111  border-color: var(--en-prose-hr);
112  border-top-width: 1px;
113  margin-top: 3em;
114  margin-bottom: 3em;
115}
116
117.prose :where(blockquote):not(:where([class~="not-prose"] *)) {
118  font-weight: 500;
119  font-style: italic;
120  color: var(--en-prose-quotes);
121  border-left-width: 0.25rem;
122  border-left-color: var(--en-prose-quote-borders);
123  quotes: "\201C""\201D""\2018""\2019";
124  margin-top: 1.6em;
125  margin-bottom: 1.6em;
126  padding-left: 1em;
127}
128
129.prose :where(blockquote p:first-of-type):not(:where([class~="not-prose"] *))::before {
130  content: open-quote;
131}
132
133.prose :where(blockquote p:last-of-type):not(:where([class~="not-prose"] *))::after {
134  content: close-quote;
135}
136
137.prose :where(h1):not(:where([class~="not-prose"] *)) {
138  color: var(--en-prose-headings);
139  font-weight: 800;
140  font-size: 2.25em;
141  margin-top: 0;
142  margin-bottom: 0.8888889em;
143  line-height: 1.1111111;
144}
145
146.prose :where(h1 strong):not(:where([class~="not-prose"] *)) {
147  font-weight: 900;
148  color: inherit;
149}
150
151.prose :where(h2):not(:where([class~="not-prose"] *)) {
152  color: var(--en-prose-headings);
153  font-weight: 700;
154  font-size: 1.5em;
155  margin-top: 2em;
156  margin-bottom: 1em;
157  line-height: 1.3333333;
158}
159
160.prose :where(h2 strong):not(:where([class~="not-prose"] *)) {
161  font-weight: 800;
162  color: inherit;
163}
164
165.prose :where(h3):not(:where([class~="not-prose"] *)) {
166  color: var(--en-prose-headings);
167  font-weight: 600;
168  font-size: 1.25em;
169  margin-top: 1.6em;
170  margin-bottom: 0.6em;
171  line-height: 1.6;
172}
173
174.prose :where(h3 strong):not(:where([class~="not-prose"] *)) {
175  font-weight: 700;
176  color: inherit;
177}
178
179.prose :where(h4):not(:where([class~="not-prose"] *)) {
180  color: var(--en-prose-headings);
181  font-weight: 600;
182  margin-top: 1.5em;
183  margin-bottom: 0.5em;
184  line-height: 1.5;
185}
186
187.prose :where(h4 strong):not(:where([class~="not-prose"] *)) {
188  font-weight: 700;
189  color: inherit;
190}
191
192.prose :where(img):not(:where([class~="not-prose"] *)) {
193  margin-top: 2em;
194  margin-bottom: 2em;
195}
196
197.prose :where(figure > *):not(:where([class~="not-prose"] *)) {
198  margin-top: 0;
199  margin-bottom: 0;
200}
201
202.prose :where(figcaption):not(:where([class~="not-prose"] *)) {
203  color: var(--en-prose-captions);
204  font-size: 0.875em;
205  line-height: 1.4285714;
206  margin-top: 0.8571429em;
207}
208
209.prose :where(code):not(:where([class~="not-prose"] *)) {
210  color: var(--en-prose-code);
211  font-weight: 600;
212  font-size: 0.875em;
213}
214
215.prose :where(code):not(:where([class~="not-prose"] *))::before {
216  content: "`";
217}
218
219.prose :where(code):not(:where([class~="not-prose"] *))::after {
220  content: "`";
221}
222
223.prose :where(a code):not(:where([class~="not-prose"] *)) {
224  color: inherit;
225}
226
227.prose :where(h1 code):not(:where([class~="not-prose"] *)) {
228  color: inherit;
229}
230
231.prose :where(h2 code):not(:where([class~="not-prose"] *)) {
232  color: inherit;
233  font-size: 0.875em;
234}
235
236.prose :where(h3 code):not(:where([class~="not-prose"] *)) {
237  color: inherit;
238  font-size: 0.9em;
239}
240
241.prose :where(h4 code):not(:where([class~="not-prose"] *)) {
242  color: inherit;
243}
244
245.prose :where(blockquote code):not(:where([class~="not-prose"] *)) {
246  color: inherit;
247}
248
249.prose :where(thead th code):not(:where([class~="not-prose"] *)) {
250  color: inherit;
251}
252
253.prose :where(pre):not(:where([class~="not-prose"] *)) {
254  color: var(--en-prose-pre-code);
255  background-color: var(--en-prose-pre-bg);
256  overflow-x: auto;
257  font-weight: 400;
258  font-size: 0.875em;
259  line-height: 1.7142857;
260  margin-top: 1.7142857em;
261  margin-bottom: 1.7142857em;
262  border-radius: 0.375rem;
263  padding-top: 0.8571429em;
264  padding-right: 1.1428571em;
265  padding-bottom: 0.8571429em;
266  padding-left: 1.1428571em;
267}
268
269.prose :where(pre code):not(:where([class~="not-prose"] *)) {
270  background-color: transparent;
271  border-width: 0;
272  border-radius: 0;
273  padding: 0;
274  font-weight: inherit;
275  color: inherit;
276  font-size: inherit;
277  font-family: inherit;
278  line-height: inherit;
279}
280
281.prose :where(pre code):not(:where([class~="not-prose"] *))::before {
282  content: none;
283}
284
285.prose :where(pre code):not(:where([class~="not-prose"] *))::after {
286  content: none;
287}
288
289.prose :where(table):not(:where([class~="not-prose"] *)) {
290  width: 100%;
291  table-layout: auto;
292  text-align: left;
293  margin-top: 2em;
294  margin-bottom: 2em;
295  font-size: 0.875em;
296  line-height: 1.7142857;
297}
298
299.prose :where(thead):not(:where([class~="not-prose"] *)) {
300  border-bottom-width: 1px;
301  border-bottom-color: var(--en-prose-th-borders);
302}
303
304.prose :where(thead th):not(:where([class~="not-prose"] *)) {
305  color: var(--en-prose-headings);
306  font-weight: 600;
307  vertical-align: bottom;
308  padding-right: 0.5714286em;
309  padding-bottom: 0.5714286em;
310  padding-left: 0.5714286em;
311}
312
313.prose :where(tbody tr):not(:where([class~="not-prose"] *)) {
314  border-bottom-width: 1px;
315  border-bottom-color: var(--en-prose-td-borders);
316}
317
318.prose :where(tbody tr:last-child):not(:where([class~="not-prose"] *)) {
319  border-bottom-width: 0;
320}
321
322.prose :where(tbody td):not(:where([class~="not-prose"] *)) {
323  vertical-align: baseline;
324}
325
326.prose :where(tfoot):not(:where([class~="not-prose"] *)) {
327  border-top-width: 1px;
328  border-top-color: var(--en-prose-th-borders);
329}
330
331.prose :where(tfoot td):not(:where([class~="not-prose"] *)) {
332  vertical-align: top;
333}
334
335.prose :where(p):not(:where([class~="not-prose"] *)) {
336  margin-top: 1.25em;
337  margin-bottom: 1.25em;
338}
339
340.prose :where(video):not(:where([class~="not-prose"] *)) {
341  margin-top: 2em;
342  margin-bottom: 2em;
343}
344
345.prose :where(figure):not(:where([class~="not-prose"] *)) {
346  margin-top: 2em;
347  margin-bottom: 2em;
348}
349
350.prose :where(li):not(:where([class~="not-prose"] *)) {
351  margin-top: 0.5em;
352  margin-bottom: 0.5em;
353}
354
355.prose :where(ol > li):not(:where([class~="not-prose"] *)) {
356  padding-left: 0.375em;
357}
358
359.prose :where(ul > li):not(:where([class~="not-prose"] *)) {
360  padding-left: 0.375em;
361}
362
363.prose :where(.prose > ul > li p):not(:where([class~="not-prose"] *)) {
364  margin-top: 0.75em;
365  margin-bottom: 0.75em;
366}
367
368.prose :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *)) {
369  margin-top: 1.25em;
370}
371
372.prose :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *)) {
373  margin-bottom: 1.25em;
374}
375
376.prose :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *)) {
377  margin-top: 1.25em;
378}
379
380.prose :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *)) {
381  margin-bottom: 1.25em;
382}
383
384.prose :where(ul ul, ul ol, ol ul, ol ol):not(:where([class~="not-prose"] *)) {
385  margin-top: 0.75em;
386  margin-bottom: 0.75em;
387}
388
389.prose :where(hr + *):not(:where([class~="not-prose"] *)) {
390  margin-top: 0;
391}
392
393.prose :where(h2 + *):not(:where([class~="not-prose"] *)) {
394  margin-top: 0;
395}
396
397.prose :where(h3 + *):not(:where([class~="not-prose"] *)) {
398  margin-top: 0;
399}
400
401.prose :where(h4 + *):not(:where([class~="not-prose"] *)) {
402  margin-top: 0;
403}
404
405.prose :where(thead th:first-child):not(:where([class~="not-prose"] *)) {
406  padding-left: 0;
407}
408
409.prose :where(thead th:last-child):not(:where([class~="not-prose"] *)) {
410  padding-right: 0;
411}
412
413.prose :where(tbody td, tfoot td):not(:where([class~="not-prose"] *)) {
414  padding-top: 0.5714286em;
415  padding-right: 0.5714286em;
416  padding-bottom: 0.5714286em;
417  padding-left: 0.5714286em;
418}
419
420.prose :where(tbody td:first-child, tfoot td:first-child):not(:where([class~="not-prose"] *)) {
421  padding-left: 0;
422}
423
424.prose :where(tbody td:last-child, tfoot td:last-child):not(:where([class~="not-prose"] *)) {
425  padding-right: 0;
426}
427
428.prose :where(:not(kbd) > kbd):not(:where([class~="not-prose"] *)) {
429  background-color: var(--en-prose-kbd-bg);
430  color: var(--en-prose-kbd-text);
431  padding: 0.2em 0.3em;
432  border-radius: 0.4em;
433}
434
435.prose :where(.prose > :first-child):not(:where([class~="not-prose"] *)) {
436  margin-top: 0;
437}
438
439.prose :where(.prose > :last-child):not(:where([class~="not-prose"] *)) {
440  margin-bottom: 0;
441}
442
443.prose {
444  --en-prose-body: #374151;
445  --en-prose-headings: #111827;
446  --en-prose-lead: #4b5563;
447  --en-prose-links: #111827;
448  --en-prose-bold: #111827;
449  --en-prose-counters: #6b7280;
450  --en-prose-bullets: #d1d5db;
451  --en-prose-hr: #e5e7eb;
452  --en-prose-quotes: #111827;
453  --en-prose-quote-borders: #e5e7eb;
454  --en-prose-captions: #6b7280;
455  --en-prose-code: #111827;
456  --en-prose-pre-code: #e5e7eb;
457  --en-prose-pre-bg: #1f2937;
458  --en-prose-th-borders: #d1d5db;
459  --en-prose-td-borders: #e5e7eb;
460  --en-prose-kbd-text: #e5e7eb;
461  --en-prose-kbd-bg: #1f2937;
462  --en-prose-invert-body: #d1d5db;
463  --en-prose-invert-headings: #fff;
464  --en-prose-invert-lead: #9ca3af;
465  --en-prose-invert-links: #fff;
466  --en-prose-invert-bold: #fff;
467  --en-prose-invert-counters: #9ca3af;
468  --en-prose-invert-bullets: #4b5563;
469  --en-prose-invert-hr: #374151;
470  --en-prose-invert-quotes: #f3f4f6;
471  --en-prose-invert-quote-borders: #374151;
472  --en-prose-invert-captions: #9ca3af;
473  --en-prose-invert-code: #fff;
474  --en-prose-invert-pre-code: #d1d5db;
475  --en-prose-invert-pre-bg: rgb(0 0 0 / 50%);
476  --en-prose-invert-th-borders: #4b5563;
477  --en-prose-invert-td-borders: #374151;
478  --en-prose-invert-kbd-text: #d1d5db;
479  --en-prose-invert-kbd-bg: rgb(0 0 0 / 50%);
480  font-size: 1rem;
481  line-height: 1.75;
482}
483
484.prose-sm :where(.prose > ul > li p):not(:where([class~="not-prose"] *)) {
485  margin-top: 0.5714286em;
486  margin-bottom: 0.5714286em;
487}
488
489.prose-sm :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *)) {
490  margin-top: 1.1428571em;
491}
492
493.prose-sm :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *)) {
494  margin-bottom: 1.1428571em;
495}
496
497.prose-sm :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *)) {
498  margin-top: 1.1428571em;
499}
500
501.prose-sm :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *)) {
502  margin-bottom: 1.1428571em;
503}
504
505.prose-sm :where(.prose > :first-child):not(:where([class~="not-prose"] *)) {
506  margin-top: 0;
507}
508
509.prose-sm :where(.prose > :last-child):not(:where([class~="not-prose"] *)) {
510  margin-bottom: 0;
511}
512
513.prose-base :where(.prose > ul > li p):not(:where([class~="not-prose"] *)) {
514  margin-top: 0.75em;
515  margin-bottom: 0.75em;
516}
517
518.prose-base :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *)) {
519  margin-top: 1.25em;
520}
521
522.prose-base :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *)) {
523  margin-bottom: 1.25em;
524}
525
526.prose-base :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *)) {
527  margin-top: 1.25em;
528}
529
530.prose-base :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *)) {
531  margin-bottom: 1.25em;
532}
533
534.prose-base :where(.prose > :first-child):not(:where([class~="not-prose"] *)) {
535  margin-top: 0;
536}
537
538.prose-base :where(.prose > :last-child):not(:where([class~="not-prose"] *)) {
539  margin-bottom: 0;
540}
541
542.prose-lg :where(.prose > ul > li p):not(:where([class~="not-prose"] *)) {
543  margin-top: 0.8888889em;
544  margin-bottom: 0.8888889em;
545}
546
547.prose-lg :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *)) {
548  margin-top: 1.3333333em;
549}
550
551.prose-lg :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *)) {
552  margin-bottom: 1.3333333em;
553}
554
555.prose-lg :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *)) {
556  margin-top: 1.3333333em;
557}
558
559.prose-lg :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *)) {
560  margin-bottom: 1.3333333em;
561}
562
563.prose-lg :where(.prose > :first-child):not(:where([class~="not-prose"] *)) {
564  margin-top: 0;
565}
566
567.prose-lg :where(.prose > :last-child):not(:where([class~="not-prose"] *)) {
568  margin-bottom: 0;
569}
570
571.prose-xl :where(.prose > ul > li p):not(:where([class~="not-prose"] *)) {
572  margin-top: 0.8em;
573  margin-bottom: 0.8em;
574}
575
576.prose-xl :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *)) {
577  margin-top: 1.2em;
578}
579
580.prose-xl :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *)) {
581  margin-bottom: 1.2em;
582}
583
584.prose-xl :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *)) {
585  margin-top: 1.2em;
586}
587
588.prose-xl :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *)) {
589  margin-bottom: 1.2em;
590}
591
592.prose-xl :where(.prose > :first-child):not(:where([class~="not-prose"] *)) {
593  margin-top: 0;
594}
595
596.prose-xl :where(.prose > :last-child):not(:where([class~="not-prose"] *)) {
597  margin-bottom: 0;
598}
599
600.prose-2xl :where(.prose > ul > li p):not(:where([class~="not-prose"] *)) {
601  margin-top: 0.8333333em;
602  margin-bottom: 0.8333333em;
603}
604
605.prose-2xl :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *)) {
606  margin-top: 1.3333333em;
607}
608
609.prose-2xl :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *)) {
610  margin-bottom: 1.3333333em;
611}
612
613.prose-2xl :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *)) {
614  margin-top: 1.3333333em;
615}
616
617.prose-2xl :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *)) {
618  margin-bottom: 1.3333333em;
619}
620
621.prose-2xl :where(.prose > :first-child):not(:where([class~="not-prose"] *)) {
622  margin-top: 0;
623}
624
625.prose-2xl :where(.prose > :last-child):not(:where([class~="not-prose"] *)) {
626  margin-bottom: 0;
627}"#;
628
629const PROSE_SLATE_CSS: &str = "--en-prose-body: #334155;
630--en-prose-headings: #0f172a;
631--en-prose-lead: #475569;
632--en-prose-links: #0f172a;
633--en-prose-bold: #0f172a;
634--en-prose-counters: #64748b;
635--en-prose-bullets: #cbd5e1;
636--en-prose-hr: #e2e8f0;
637--en-prose-quotes: #0f172a;
638--en-prose-quote-borders: #e2e8f0;
639--en-prose-captions: #64748b;
640--en-prose-code: #0f172a;
641--en-prose-pre-code: #e2e8f0;
642--en-prose-pre-bg: #1e293b;
643--en-prose-th-borders: #cbd5e1;
644--en-prose-td-borders: #e2e8f0;
645--en-prose-kbd-text: #e2e8f0;
646--en-prose-kbd-bg: #1e293b;
647--en-prose-invert-body: #cbd5e1;
648--en-prose-invert-headings: #fff;
649--en-prose-invert-lead: #94a3b8;
650--en-prose-invert-links: #fff;
651--en-prose-invert-bold: #fff;
652--en-prose-invert-counters: #94a3b8;
653--en-prose-invert-bullets: #475569;
654--en-prose-invert-hr: #334155;
655--en-prose-invert-quotes: #f1f5f9;
656--en-prose-invert-quote-borders: #334155;
657--en-prose-invert-captions: #94a3b8;
658--en-prose-invert-code: #fff;
659--en-prose-invert-pre-code: #cbd5e1;
660--en-prose-invert-pre-bg: rgb(0 0 0 / 50%);
661--en-prose-invert-th-borders: #475569;
662--en-prose-invert-td-borders: #334155;
663--en-prose-invert-kbd-text: #cbd5e1;
664--en-prose-invert-kbd-bg: rgb(0 0 0 / 50%);";
665
666const PROSE_GRAY_CSS: &str = "--en-prose-body: #374151;
667--en-prose-headings: #111827;
668--en-prose-lead: #4b5563;
669--en-prose-links: #111827;
670--en-prose-bold: #111827;
671--en-prose-counters: #6b7280;
672--en-prose-bullets: #d1d5db;
673--en-prose-hr: #e5e7eb;
674--en-prose-quotes: #111827;
675--en-prose-quote-borders: #e5e7eb;
676--en-prose-captions: #6b7280;
677--en-prose-code: #111827;
678--en-prose-pre-code: #e5e7eb;
679--en-prose-pre-bg: #1f2937;
680--en-prose-th-borders: #d1d5db;
681--en-prose-td-borders: #e5e7eb;
682--en-prose-kbd-text: #e5e7eb;
683--en-prose-kbd-bg: #1f2937;
684--en-prose-invert-body: #d1d5db;
685--en-prose-invert-headings: #fff;
686--en-prose-invert-lead: #9ca3af;
687--en-prose-invert-links: #fff;
688--en-prose-invert-bold: #fff;
689--en-prose-invert-counters: #9ca3af;
690--en-prose-invert-bullets: #4b5563;
691--en-prose-invert-hr: #374151;
692--en-prose-invert-quotes: #f3f4f6;
693--en-prose-invert-quote-borders: #374151;
694--en-prose-invert-captions: #9ca3af;
695--en-prose-invert-code: #fff;
696--en-prose-invert-pre-code: #d1d5db;
697--en-prose-invert-pre-bg: rgb(0 0 0 / 50%);
698--en-prose-invert-th-borders: #4b5563;
699--en-prose-invert-td-borders: #374151;
700--en-prose-invert-kbd-text: #d1d5db;
701--en-prose-invert-kbd-bg: rgb(0 0 0 / 50%);";
702
703const PROSE_ZINC_CSS: &str = "--en-prose-body: #3f3f46;
704--en-prose-headings: #18181b;
705--en-prose-lead: #52525b;
706--en-prose-links: #18181b;
707--en-prose-bold: #18181b;
708--en-prose-counters: #71717a;
709--en-prose-bullets: #d4d4d8;
710--en-prose-hr: #e4e4e7;
711--en-prose-quotes: #18181b;
712--en-prose-quote-borders: #e4e4e7;
713--en-prose-captions: #71717a;
714--en-prose-code: #18181b;
715--en-prose-pre-code: #e4e4e7;
716--en-prose-pre-bg: #27272a;
717--en-prose-th-borders: #d4d4d8;
718--en-prose-td-borders: #e4e4e7;
719--en-prose-kbd-text: #e4e4e7;
720--en-prose-kbd-bg: #27272a;
721--en-prose-invert-body: #d4d4d8;
722--en-prose-invert-headings: #fff;
723--en-prose-invert-lead: #a1a1aa;
724--en-prose-invert-links: #fff;
725--en-prose-invert-bold: #fff;
726--en-prose-invert-counters: #a1a1aa;
727--en-prose-invert-bullets: #52525b;
728--en-prose-invert-hr: #3f3f46;
729--en-prose-invert-quotes: #f4f4f5;
730--en-prose-invert-quote-borders: #3f3f46;
731--en-prose-invert-captions: #a1a1aa;
732--en-prose-invert-code: #fff;
733--en-prose-invert-pre-code: #d4d4d8;
734--en-prose-invert-pre-bg: rgb(0 0 0 / 50%);
735--en-prose-invert-th-borders: #52525b;
736--en-prose-invert-td-borders: #3f3f46;
737--en-prose-invert-kbd-text: #d4d4d8;
738--en-prose-invert-kbd-bg: rgb(0 0 0 / 50%);";
739
740const PROSE_NEUTRAL_CSS: &str = "--en-prose-body: #404040;
741--en-prose-headings: #171717;
742--en-prose-lead: #525252;
743--en-prose-links: #171717;
744--en-prose-bold: #171717;
745--en-prose-counters: #737373;
746--en-prose-bullets: #d4d4d4;
747--en-prose-hr: #e5e5e5;
748--en-prose-quotes: #171717;
749--en-prose-quote-borders: #e5e5e5;
750--en-prose-captions: #737373;
751--en-prose-code: #171717;
752--en-prose-pre-code: #e5e5e5;
753--en-prose-pre-bg: #262626;
754--en-prose-th-borders: #d4d4d4;
755--en-prose-td-borders: #e5e5e5;
756--en-prose-kbd-text: #e5e5e5;
757--en-prose-kbd-bg: #262626;
758--en-prose-invert-body: #d4d4d4;
759--en-prose-invert-headings: #fff;
760--en-prose-invert-lead: #a3a3a3;
761--en-prose-invert-links: #fff;
762--en-prose-invert-bold: #fff;
763--en-prose-invert-counters: #a3a3a3;
764--en-prose-invert-bullets: #525252;
765--en-prose-invert-hr: #404040;
766--en-prose-invert-quotes: #f5f5f5;
767--en-prose-invert-quote-borders: #404040;
768--en-prose-invert-captions: #a3a3a3;
769--en-prose-invert-code: #fff;
770--en-prose-invert-pre-code: #d4d4d4;
771--en-prose-invert-pre-bg: rgb(0 0 0 / 50%);
772--en-prose-invert-th-borders: #525252;
773--en-prose-invert-td-borders: #404040;
774--en-prose-invert-kbd-text: #d4d4d4;
775--en-prose-invert-kbd-bg: #rgb(0 0 0 / 50%);";
776
777const PROSE_STONE_CSS: &str = "--en-prose-body: #44403c;
778--en-prose-headings: #1c1917;
779--en-prose-lead: #57534e;
780--en-prose-links: #1c1917;
781--en-prose-bold: #1c1917;
782--en-prose-counters: #78716c;
783--en-prose-bullets: #d6d3d1;
784--en-prose-hr: #e7e5e4;
785--en-prose-quotes: #1c1917;
786--en-prose-quote-borders: #e7e5e4;
787--en-prose-captions: #78716c;
788--en-prose-code: #1c1917;
789--en-prose-pre-code: #e7e5e4;
790--en-prose-pre-bg: #292524;
791--en-prose-th-borders: #d6d3d1;
792--en-prose-td-borders: #e7e5e4;
793--en-prose-kbd-text: #e7e5e4;
794--en-prose-kbd-bg: #292524;
795--en-prose-invert-body: #d6d3d1;
796--en-prose-invert-headings: #fff;
797--en-prose-invert-lead: #a8a29e;
798--en-prose-invert-links: #fff;
799--en-prose-invert-bold: #fff;
800--en-prose-invert-counters: #a8a29e;
801--en-prose-invert-bullets: #57534e;
802--en-prose-invert-hr: #44403c;
803--en-prose-invert-quotes: #f5f5f4;
804--en-prose-invert-quote-borders: #44403c;
805--en-prose-invert-captions: #a8a29e;
806--en-prose-invert-code: #fff;
807--en-prose-invert-pre-code: #d6d3d1;
808--en-prose-invert-pre-bg: rgb(0 0 0 / 50%);
809--en-prose-invert-th-borders: #57534e;
810--en-prose-invert-td-borders: #44403c;
811--en-prose-invert-kbd-text: #d6d3d1;
812--en-prose-invert-kbd-bg: rgb(0 0 0 / 50%);";
813
814const PROSE_SM_CSS: &[(&str, &str)] = &[
815    (r#""#, "font-size: 0.875rem;\nline-height: 1.7142857;"),
816    (r#" :where(p):not(:where([class~="not-prose"] *))"#, "margin-top: 1.1428571em;\nmargin-bottom: 1.1428571em;"),
817    (r#" :where([class~="lead"]):not(:where([class~="not-prose"] *))"#, "font-size: 1.2857143em;\nline-height: 1.5555556;\nmargin-top: 0.8888889em;\nmargin-bottom: 0.8888889em;"),
818    (r#" :where(blockquote):not(:where([class~="not-prose"] *))"#, "margin-top: 1.3333333em;\nmargin-bottom: 1.3333333em;\npadding-left: 1.1111111em;"),
819    (r#" :where(h1):not(:where([class~="not-prose"] *))"#, "font-size: 2.1428571em;\nmargin-top: 0;\nmargin-bottom: 0.8em;\nline-height: 1.2;"),
820    (r#" :where(h2):not(:where([class~="not-prose"] *))"#, "font-size: 1.4285714em;\nmargin-top: 1.6em;\nmargin-bottom: 0.8em;\nline-height: 1.4;"),
821    (r#" :where(h3):not(:where([class~="not-prose"] *))"#, "font-size: 1.2857143em;\nmargin-top: 1.5555556em;\nmargin-bottom: 0.4444444em;\nline-height: 1.5555556;"),
822    (r#" :where(h4):not(:where([class~="not-prose"] *))"#, "margin-top: 1.4285714em;\nmargin-bottom: 0.5714286em;\nline-height: 1.4285714;"),
823    (r#" :where(img):not(:where([class~="not-prose"] *))"#, "margin-top: 1.7142857em;\nmargin-bottom: 1.7142857em;"),
824    (r#" :where(video):not(:where([class~="not-prose"] *))"#, "margin-top: 1.7142857em;\nmargin-bottom: 1.7142857em;"),
825    (r#" :where(figure):not(:where([class~="not-prose"] *))"#, "margin-top: 1.7142857em;\nmargin-bottom: 1.7142857em;"),
826    (r#" :where(figure > *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;\nmargin-bottom: 0;"),
827    (r#" :where(figcaption):not(:where([class~="not-prose"] *))"#, "font-size: 0.8571429em;\nline-height: 1.3333333;\nmargin-top: 0.6666667em;"),
828    (r#" :where(code):not(:where([class~="not-prose"] *))"#, "font-size: 0.8571429em;"),
829    (r#" :where(h2 code):not(:where([class~="not-prose"] *))"#, "font-size: 0.9em;"),
830    (r#" :where(h3 code):not(:where([class~="not-prose"] *))"#, "font-size: 0.8888889em;"),
831    (r#" :where(pre):not(:where([class~="not-prose"] *))"#, "font-size: 0.8571429em;\nline-height: 1.6666667;\nmargin-top: 1.6666667em;\nmargin-bottom: 1.6666667em;\nborder-radius: 0.25rem;\npadding-top: 0.6666667em;\npadding-right: 1em;\npadding-bottom: 0.6666667em;\npadding-left: 1em;"),
832    (r#" :where(ol):not(:where([class~="not-prose"] *))"#, "margin-top: 1.1428571em;\nmargin-bottom: 1.1428571em;\npadding-left: 1.5714286em;"),
833    (r#" :where(ul):not(:where([class~="not-prose"] *))"#, "margin-top: 1.1428571em;\nmargin-bottom: 1.1428571em;\npadding-left: 1.5714286em;"),
834    (r#" :where(li):not(:where([class~="not-prose"] *))"#, "margin-top: 0.2857143em;\nmargin-bottom: 0.2857143em;"),
835    (r#" :where(ol > li):not(:where([class~="not-prose"] *))"#, "padding-left: 0.4285714em;"),
836    (r#" :where(ul > li):not(:where([class~="not-prose"] *))"#, "padding-left: 0.4285714em;"),
837    (r#" :where(.prose > ul > li p):not(:where([class~="not-prose"] *))"#, "margin-top: 0.5714286em;\nmargin-bottom: 0.5714286em;"),
838    (r#" :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *))"#, "margin-top: 1.1428571em;"),
839    (r#" :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *))"#, "margin-bottom: 1.1428571em;"),
840    (r#" :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *))"#, "margin-top: 1.1428571em;"),
841    (r#" :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *))"#, "margin-bottom: 1.1428571em;"),
842    (r#" :where(ul ul, ul ol, ol ul, ol ol):not(:where([class~="not-prose"] *))"#, "margin-top: 0.5714286em;\nmargin-bottom: 0.5714286em;"),
843    (r#" :where(hr):not(:where([class~="not-prose"] *))"#, "margin-top: 2.8571429em;\nmargin-bottom: 2.8571429em;"),
844    (r#" :where(hr + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
845    (r#" :where(h2 + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
846    (r#" :where(h3 + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
847    (r#" :where(h4 + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
848    (r#" :where(table):not(:where([class~="not-prose"] *))"#, "font-size: 0.8571429em;\nline-height: 1.5;"),
849    (r#" :where(thead th):not(:where([class~="not-prose"] *))"#, "padding-right: 1em;\npadding-bottom: 0.6666667em;\npadding-left: 1em;"),
850    (r#" :where(thead th:first-child):not(:where([class~="not-prose"] *))"#, "padding-left: 0;"),
851    (r#" :where(thead th:last-child):not(:where([class~="not-prose"] *))"#, "padding-right: 0;"),
852    (r#" :where(tbody td, tfoot td):not(:where([class~="not-prose"] *))"#, "padding-top: 0.6666667em;\npadding-right: 1em;\npadding-bottom: 0.6666667em;\npadding-left: 1em;"),
853    (r#" :where(tbody td:first-child, tfoot td:first-child):not(:where([class~="not-prose"] *))"#, "padding-left: 0;"),
854    (r#" :where(tbody td:last-child, tfoot td:last-child):not(:where([class~="not-prose"] *))"#, "padding-right: 0;"),
855    (r#" :where(:not(kbd) > kbd):not(:where([class~="not-prose"] *))"#, "background-color: var(--en-prose-kbd-bg);\ncolor: var(--en-prose-kbd-text);\npadding: 0.1em 0.2em;\nborder-radius: 0.4em;"),
856    (r#" :where(.prose > :first-child):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
857    (r#" :where(.prose > :last-child):not(:where([class~="not-prose"] *))"#, "margin-bottom: 0;"),
858];
859
860const PROSE_BASE_CSS: &[(&str, &str)] = &[
861    (r#""#, "font-size: 1rem;\nline-height: 1.75;"),
862    (r#" :where(p):not(:where([class~="not-prose"] *))"#, "margin-top: 1.25em;\nmargin-bottom: 1.25em;"),
863    (r#" :where([class~="lead"]):not(:where([class~="not-prose"] *))"#, "font-size: 1.25em;\nline-height: 1.6;\nmargin-top: 1.2em;\nmargin-bottom: 1.2em;"),
864    (r#" :where(blockquote):not(:where([class~="not-prose"] *))"#, "margin-top: 1.6em;\nmargin-bottom: 1.6em;\npadding-left: 1em;"),
865    (r#" :where(h1):not(:where([class~="not-prose"] *))"#, "font-size: 2.25em;\nmargin-top: 0;\nmargin-bottom: 0.8888889em;\nline-height: 1.1111111;"),
866    (r#" :where(h2):not(:where([class~="not-prose"] *))"#, "font-size: 1.5em;\nmargin-top: 2em;\nmargin-bottom: 1em;\nline-height: 1.3333333;"),
867    (r#" :where(h3):not(:where([class~="not-prose"] *))"#, "font-size: 1.25em;\nmargin-top: 1.6em;\nmargin-bottom: 0.6em;\nline-height: 1.6;"),
868    (r#" :where(h4):not(:where([class~="not-prose"] *))"#, "margin-top: 1.5em;\nmargin-bottom: 0.5em;\nline-height: 1.5;"),
869    (r#" :where(img):not(:where([class~="not-prose"] *))"#, "margin-top: 2em;\nmargin-bottom: 2em;"),
870    (r#" :where(video):not(:where([class~="not-prose"] *))"#, "margin-top: 2em;\nmargin-bottom: 2em;"),
871    (r#" :where(figure):not(:where([class~="not-prose"] *))"#, "margin-top: 2em;\nmargin-bottom: 2em;"),
872    (r#" :where(figure > *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;\nmargin-bottom: 0;"),
873    (r#" :where(figcaption):not(:where([class~="not-prose"] *))"#, "font-size: 0.875em;\nline-height: 1.4285714;\nmargin-top: 0.8571429em;"),
874    (r#" :where(code):not(:where([class~="not-prose"] *))"#, "font-size: 0.875em;"),
875    (r#" :where(h2 code):not(:where([class~="not-prose"] *))"#, "font-size: 0.875em;"),
876    (r#" :where(h3 code):not(:where([class~="not-prose"] *))"#, "font-size: 0.9em;"),
877    (r#" :where(pre):not(:where([class~="not-prose"] *))"#, "font-size: 0.875em;\nline-height: 1.7142857;\nmargin-top: 1.7142857em;\nmargin-bottom: 1.7142857em;\nborder-radius: 0.375rem;\npadding-top: 0.8571429em;\npadding-right: 1.1428571em;\npadding-bottom: 0.8571429em;\npadding-left: 1.1428571em;"),
878    (r#" :where(ol):not(:where([class~="not-prose"] *))"#, "margin-top: 1.25em;\nmargin-bottom: 1.25em;\npadding-left: 1.625em;"),
879    (r#" :where(ul):not(:where([class~="not-prose"] *))"#, "margin-top: 1.25em;\nmargin-bottom: 1.25em;\npadding-left: 1.625em;"),
880    (r#" :where(li):not(:where([class~="not-prose"] *))"#, "margin-top: 0.5em;\nmargin-bottom: 0.5em;"),
881    (r#" :where(ol > li):not(:where([class~="not-prose"] *))"#, "padding-left: 0.375em;"),
882    (r#" :where(ul > li):not(:where([class~="not-prose"] *))"#, "padding-left: 0.375em;"),
883    (r#" :where(.prose > ul > li p):not(:where([class~="not-prose"] *))"#, "margin-top: 0.75em;\nmargin-bottom: 0.75em;"),
884    (r#" :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *))"#, "margin-top: 1.25em;"),
885    (r#" :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *))"#, "margin-bottom: 1.25em;"),
886    (r#" :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *))"#, "margin-top: 1.25em;"),
887    (r#" :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *))"#, "margin-bottom: 1.25em;"),
888    (r#" :where(ul ul, ul ol, ol ul, ol ol):not(:where([class~="not-prose"] *))"#, "margin-top: 0.75em;\nmargin-bottom: 0.75em;"),
889    (r#" :where(hr):not(:where([class~="not-prose"] *))"#, "margin-top: 3em;\nmargin-bottom: 3em;"),
890    (r#" :where(hr + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
891    (r#" :where(h2 + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
892    (r#" :where(h3 + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
893    (r#" :where(h4 + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
894    (r#" :where(table):not(:where([class~="not-prose"] *))"#, "font-size: 0.875em;\nline-height: 1.7142857;"),
895    (r#" :where(thead th):not(:where([class~="not-prose"] *))"#, "padding-right: 0.5714286em;\npadding-bottom: 0.5714286em;\npadding-left: 0.5714286em;"),
896    (r#" :where(thead th:first-child):not(:where([class~="not-prose"] *))"#, "padding-left: 0;"),
897    (r#" :where(thead th:last-child):not(:where([class~="not-prose"] *))"#, "padding-right: 0;"),
898    (r#" :where(tbody td, tfoot td):not(:where([class~="not-prose"] *))"#, "padding-top: 0.5714286em;\npadding-right: 0.5714286em;\npadding-bottom: 0.5714286em;\npadding-left: 0.5714286em;"),
899    (r#" :where(tbody td:first-child, tfoot td:first-child):not(:where([class~="not-prose"] *))"#, "padding-left: 0;"),
900    (r#" :where(tbody td:last-child, tfoot td:last-child):not(:where([class~="not-prose"] *))"#, "padding-right: 0;"),
901    (r#" :where(:not(kbd) > kbd):not(:where([class~="not-prose"] *))"#, "background-color: var(--en-prose-kbd-bg);\ncolor: var(--en-prose-kbd-text);\npadding: 0.2em 0.3em;\nborder-radius: 0.4em;"),
902    (r#" :where(.prose > :first-child):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
903    (r#" :where(.prose > :last-child):not(:where([class~="not-prose"] *))"#, "margin-bottom: 0;"),
904];
905
906const PROSE_LG_CSS: &[(&str, &str)] = &[
907    (r#""#, "font-size: 1.125rem;\nline-height: 1.7777778;"),
908    (r#" :where(p):not(:where([class~="not-prose"] *))"#, "margin-top: 1.3333333em;\nmargin-bottom: 1.3333333em;"),
909    (r#" :where([class~="lead"]):not(:where([class~="not-prose"] *))"#, "font-size: 1.2222222em;\nline-height: 1.4545455;\nmargin-top: 1.0909091em;\nmargin-bottom: 1.0909091em;"),
910    (r#" :where(blockquote):not(:where([class~="not-prose"] *))"#, "margin-top: 1.6666667em;\nmargin-bottom: 1.6666667em;\npadding-left: 1em;"),
911    (r#" :where(h1):not(:where([class~="not-prose"] *))"#, "font-size: 2.6666667em;\nmargin-top: 0;\nmargin-bottom: 0.8333333em;\nline-height: 1;"),
912    (r#" :where(h2):not(:where([class~="not-prose"] *))"#, "font-size: 1.6666667em;\nmargin-top: 1.8666667em;\nmargin-bottom: 1.0666667em;\nline-height: 1.3333333;"),
913    (r#" :where(h3):not(:where([class~="not-prose"] *))"#, "font-size: 1.3333333em;\nmargin-top: 1.6666667em;\nmargin-bottom: 0.6666667em;\nline-height: 1.5;"),
914    (r#" :where(h4):not(:where([class~="not-prose"] *))"#, "margin-top: 1.7777778em;\nmargin-bottom: 0.4444444em;\nline-height: 1.5555556;"),
915    (r#" :where(img):not(:where([class~="not-prose"] *))"#, "margin-top: 1.7777778em;\nmargin-bottom: 1.7777778em;"),
916    (r#" :where(video):not(:where([class~="not-prose"] *))"#, "margin-top: 1.7777778em;\nmargin-bottom: 1.7777778em;"),
917    (r#" :where(figure):not(:where([class~="not-prose"] *))"#, "margin-top: 1.7777778em;\nmargin-bottom: 1.7777778em;"),
918    (r#" :where(figure > *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;\nmargin-bottom: 0;"),
919    (r#" :where(figcaption):not(:where([class~="not-prose"] *))"#, "font-size: 0.8888889em;\nline-height: 1.5;\nmargin-top: 1em;"),
920    (r#" :where(code):not(:where([class~="not-prose"] *))"#, "font-size: 0.8888889em;"),
921    (r#" :where(h2 code):not(:where([class~="not-prose"] *))"#, "font-size: 0.8666667em;"),
922    (r#" :where(h3 code):not(:where([class~="not-prose"] *))"#, "font-size: 0.875em;"),
923    (r#" :where(pre):not(:where([class~="not-prose"] *))"#, "font-size: 0.8888889em;\nline-height: 1.75;\nmargin-top: 2em;\nmargin-bottom: 2em;\nborder-radius: 0.375rem;\npadding-top: 1em;\npadding-right: 1.5em;\npadding-bottom: 1em;\npadding-left: 1.5em;"),
924    (r#" :where(ol):not(:where([class~="not-prose"] *))"#, "margin-top: 1.3333333em;\nmargin-bottom: 1.3333333em;\npadding-left: 1.5555556em;"),
925    (r#" :where(ul):not(:where([class~="not-prose"] *))"#, "margin-top: 1.3333333em;\nmargin-bottom: 1.3333333em;\npadding-left: 1.5555556em;"),
926    (r#" :where(li):not(:where([class~="not-prose"] *))"#, "margin-top: 0.6666667em;\nmargin-bottom: 0.6666667em;"),
927    (r#" :where(ol > li):not(:where([class~="not-prose"] *))"#, "padding-left: 0.4444444em;"),
928    (r#" :where(ul > li):not(:where([class~="not-prose"] *))"#, "padding-left: 0.4444444em;"),
929    (r#" :where(.prose > ul > li p):not(:where([class~="not-prose"] *))"#, "margin-top: 0.8888889em;\nmargin-bottom: 0.8888889em;"),
930    (r#" :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *))"#, "margin-top: 1.3333333em;"),
931    (r#" :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *))"#, "margin-bottom: 1.3333333em;"),
932    (r#" :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *))"#, "margin-top: 1.3333333em;"),
933    (r#" :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *))"#, "margin-bottom: 1.3333333em;"),
934    (r#" :where(ul ul, ul ol, ol ul, ol ol):not(:where([class~="not-prose"] *))"#, "margin-top: 0.8888889em;\nmargin-bottom: 0.8888889em;"),
935    (r#" :where(hr):not(:where([class~="not-prose"] *))"#, "margin-top: 3.1111111em;\nmargin-bottom: 3.1111111em;"),
936    (r#" :where(hr + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
937    (r#" :where(h2 + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
938    (r#" :where(h3 + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
939    (r#" :where(h4 + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
940    (r#" :where(table):not(:where([class~="not-prose"] *))"#, "font-size: 0.8888889em;\nline-height: 1.5;"),
941    (r#" :where(thead th):not(:where([class~="not-prose"] *))"#, "padding-right: 0.75em;\npadding-bottom: 0.75em;\npadding-left: 0.75em;"),
942    (r#" :where(thead th:first-child):not(:where([class~="not-prose"] *))"#, "padding-left: 0;"),
943    (r#" :where(thead th:last-child):not(:where([class~="not-prose"] *))"#, "padding-right: 0;"),
944    (r#" :where(tbody td, tfoot td):not(:where([class~="not-prose"] *))"#, "padding-top: 0.75em;\npadding-right: 0.75em;\npadding-bottom: 0.75em;\npadding-left: 0.75em;"),
945    (r#" :where(tbody td:first-child, tfoot td:first-child):not(:where([class~="not-prose"] *))"#, "padding-left: 0;"),
946    (r#" :where(tbody td:last-child, tfoot td:last-child):not(:where([class~="not-prose"] *))"#, "padding-right: 0;"),
947    (r#" :where(:not(kbd) > kbd):not(:where([class~="not-prose"] *))"#, "background-color: var(--en-prose-kbd-bg);\ncolor: var(--en-prose-kbd-text);\npadding: 0.3em 0.4em;\nborder-radius: 0.4em;"),
948    (r#" :where(.prose > :first-child):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
949    (r#" :where(.prose > :last-child):not(:where([class~="not-prose"] *))"#, "margin-bottom: 0;"),
950];
951
952const PROSE_XL_CSS: &[(&str, &str)] = &[
953    (r#""#, "font-size: 1.25rem;\nline-height: 1.8;"),
954    (r#" :where(p):not(:where([class~="not-prose"] *))"#, "margin-top: 1.2em;\nmargin-bottom: 1.2em;"),
955    (r#" :where([class~="lead"]):not(:where([class~="not-prose"] *))"#, "font-size: 1.2em;\nline-height: 1.5;\nmargin-top: 1em;\nmargin-bottom: 1em;"),
956    (r#" :where(blockquote):not(:where([class~="not-prose"] *))"#, "margin-top: 1.6em;\nmargin-bottom: 1.6em;\npadding-left: 1.0666667em;"),
957    (r#" :where(h1):not(:where([class~="not-prose"] *))"#, "font-size: 2.8em;\nmargin-top: 0;\nmargin-bottom: 0.8571429em;\nline-height: 1;"),
958    (r#" :where(h2):not(:where([class~="not-prose"] *))"#, "font-size: 1.8em;\nmargin-top: 1.5555556em;\nmargin-bottom: 0.8888889em;\nline-height: 1.1111111;"),
959    (r#" :where(h3):not(:where([class~="not-prose"] *))"#, "font-size: 1.5em;\nmargin-top: 1.6em;\nmargin-bottom: 0.6666667em;\nline-height: 1.3333333;"),
960    (r#" :where(h4):not(:where([class~="not-prose"] *))"#, "margin-top: 1.8em;\nmargin-bottom: 0.6em;\nline-height: 1.6;"),
961    (r#" :where(img):not(:where([class~="not-prose"] *))"#, "margin-top: 2em;\nmargin-bottom: 2em;"),
962    (r#" :where(video):not(:where([class~="not-prose"] *))"#, "margin-top: 2em;\nmargin-bottom: 2em;"),
963    (r#" :where(figure):not(:where([class~="not-prose"] *))"#, "margin-top: 2em;\nmargin-bottom: 2em;"),
964    (r#" :where(figure > *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;\nmargin-bottom: 0;"),
965    (r#" :where(figcaption):not(:where([class~="not-prose"] *))"#, "font-size: 0.9em;\nline-height: 1.5555556;\nmargin-top: 1em;"),
966    (r#" :where(code):not(:where([class~="not-prose"] *))"#, "font-size: 0.9em;"),
967    (r#" :where(h2 code):not(:where([class~="not-prose"] *))"#, "font-size: 0.8611111em;"),
968    (r#" :where(h3 code):not(:where([class~="not-prose"] *))"#, "font-size: 0.9em;"),
969    (r#" :where(pre):not(:where([class~="not-prose"] *))"#, "font-size: 0.9em;\nline-height: 1.7777778;\nmargin-top: 2em;\nmargin-bottom: 2em;\nborder-radius: 0.5rem;\npadding-top: 1.1111111em;\npadding-right: 1.3333333em;\npadding-bottom: 1.1111111em;\npadding-left: 1.3333333em;"),
970    (r#" :where(ol):not(:where([class~="not-prose"] *))"#, "margin-top: 1.2em;\nmargin-bottom: 1.2em;\npadding-left: 1.6em;"),
971    (r#" :where(ul):not(:where([class~="not-prose"] *))"#, "margin-top: 1.2em;\nmargin-bottom: 1.2em;\npadding-left: 1.6em;"),
972    (r#" :where(li):not(:where([class~="not-prose"] *))"#, "margin-top: 0.6em;\nmargin-bottom: 0.6em;"),
973    (r#" :where(ol > li):not(:where([class~="not-prose"] *))"#, "padding-left: 0.4em;"),
974    (r#" :where(ul > li):not(:where([class~="not-prose"] *))"#, "padding-left: 0.4em;"),
975    (r#" :where(.prose > ul > li p):not(:where([class~="not-prose"] *))"#, "margin-top: 0.8em;\nmargin-bottom: 0.8em;"),
976    (r#" :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *))"#, "margin-top: 1.2em;"),
977    (r#" :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *))"#, "margin-bottom: 1.2em;"),
978    (r#" :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *))"#, "margin-top: 1.2em;"),
979    (r#" :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *))"#, "margin-bottom: 1.2em;"),
980    (r#" :where(ul ul, ul ol, ol ul, ol ol):not(:where([class~="not-prose"] *))"#, "margin-top: 0.8em;\nmargin-bottom: 0.8em;"),
981    (r#" :where(hr):not(:where([class~="not-prose"] *))"#, "margin-top: 2.8em;\nmargin-bottom: 2.8em;"),
982    (r#" :where(hr + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
983    (r#" :where(h2 + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
984    (r#" :where(h3 + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
985    (r#" :where(h4 + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
986    (r#" :where(table):not(:where([class~="not-prose"] *))"#, "font-size: 0.9em;\nline-height: 1.5555556;"),
987    (r#" :where(thead th):not(:where([class~="not-prose"] *))"#, "padding-right: 0.6666667em;\npadding-bottom: 0.8888889em;\npadding-left: 0.6666667em;"),
988    (r#" :where(thead th:first-child):not(:where([class~="not-prose"] *))"#, "padding-left: 0;"),
989    (r#" :where(thead th:last-child):not(:where([class~="not-prose"] *))"#, "padding-right: 0;"),
990    (r#" :where(tbody td, tfoot td):not(:where([class~="not-prose"] *))"#, "padding-top: 0.8888889em;\npadding-right: 0.6666667em;\npadding-bottom: 0.8888889em;\npadding-left: 0.6666667em;"),
991    (r#" :where(tbody td:first-child, tfoot td:first-child):not(:where([class~="not-prose"] *))"#, "padding-left: 0;"),
992    (r#" :where(tbody td:last-child, tfoot td:last-child):not(:where([class~="not-prose"] *))"#, "padding-right: 0;"),
993    (r#" :where(:not(kbd) > kbd):not(:where([class~="not-prose"] *))"#, "background-color: var(--en-prose-kbd-bg);\ncolor: var(--en-prose-kbd-text);\npadding: 0.4em 0.5em;\nborder-radius: 0.4em;"),
994    (r#" :where(.prose > :first-child):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
995    (r#" :where(.prose > :last-child):not(:where([class~="not-prose"] *))"#, "margin-bottom: 0;"),
996];
997
998const PROSE_2XL_CSS: &[(&str, &str)] = &[
999    (r#""#, "font-size: 1.5rem;\nline-height: 1.6666667;"),
1000    (r#" :where(p):not(:where([class~="not-prose"] *))"#, "margin-top: 1.3333333em;\nmargin-bottom: 1.3333333em;"),
1001    (r#" :where([class~="lead"]):not(:where([class~="not-prose"] *))"#, "font-size: 1.25em;\nline-height: 1.4666667;\nmargin-top: 1.0666667em;\nmargin-bottom: 1.0666667em;"),
1002    (r#" :where(blockquote):not(:where([class~="not-prose"] *))"#, "margin-top: 1.7777778em;\nmargin-bottom: 1.7777778em;\npadding-left: 1.1111111em;"),
1003    (r#" :where(h1):not(:where([class~="not-prose"] *))"#, "font-size: 2.6666667em;\nmargin-top: 0;\nmargin-bottom: 0.875em;\nline-height: 1;"),
1004    (r#" :where(h2):not(:where([class~="not-prose"] *))"#, "font-size: 2em;\nmargin-top: 1.5em;\nmargin-bottom: 0.8333333em;\nline-height: 1.0833333;"),
1005    (r#" :where(h3):not(:where([class~="not-prose"] *))"#, "font-size: 1.5em;\nmargin-top: 1.5555556em;\nmargin-bottom: 0.6666667em;\nline-height: 1.2222222;"),
1006    (r#" :where(h4):not(:where([class~="not-prose"] *))"#, "margin-top: 1.6666667em;\nmargin-bottom: 0.6666667em;\nline-height: 1.5;"),
1007    (r#" :where(img):not(:where([class~="not-prose"] *))"#, "margin-top: 2em;\nmargin-bottom: 2em;"),
1008    (r#" :where(video):not(:where([class~="not-prose"] *))"#, "margin-top: 2em;\nmargin-bottom: 2em;"),
1009    (r#" :where(figure):not(:where([class~="not-prose"] *))"#, "margin-top: 2em;\nmargin-bottom: 2em;"),
1010    (r#" :where(figure > *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;\nmargin-bottom: 0;"),
1011    (r#" :where(figcaption):not(:where([class~="not-prose"] *))"#, "font-size: 0.8333333em;\nline-height: 1.6;\nmargin-top: 1em;"),
1012    (r#" :where(code):not(:where([class~="not-prose"] *))"#, "font-size: 0.8333333em;"),
1013    (r#" :where(h2 code):not(:where([class~="not-prose"] *))"#, "font-size: 0.875em;"),
1014    (r#" :where(h3 code):not(:where([class~="not-prose"] *))"#, "font-size: 0.8888889em;"),
1015    (r#" :where(pre):not(:where([class~="not-prose"] *))"#, "font-size: 0.8333333em;\nline-height: 1.8;\nmargin-top: 2em;\nmargin-bottom: 2em;\nborder-radius: 0.5rem;\npadding-top: 1.2em;\npadding-right: 1.6em;\npadding-bottom: 1.2em;\npadding-left: 1.6em;"),
1016    (r#" :where(ol):not(:where([class~="not-prose"] *))"#, "margin-top: 1.3333333em;\nmargin-bottom: 1.3333333em;\npadding-left: 1.5833333em;"),
1017    (r#" :where(ul):not(:where([class~="not-prose"] *))"#, "margin-top: 1.3333333em;\nmargin-bottom: 1.3333333em;\npadding-left: 1.5833333em;"),
1018    (r#" :where(li):not(:where([class~="not-prose"] *))"#, "margin-top: 0.5em;\nmargin-bottom: 0.5em;"),
1019    (r#" :where(ol > li):not(:where([class~="not-prose"] *))"#, "padding-left: 0.4166667em;"),
1020    (r#" :where(ul > li):not(:where([class~="not-prose"] *))"#, "padding-left: 0.4166667em;"),
1021    (r#" :where(.prose > ul > li p):not(:where([class~="not-prose"] *))"#, "margin-top: 0.8333333em;\nmargin-bottom: 0.8333333em;"),
1022    (r#" :where(.prose > ul > li > *:first-child):not(:where([class~="not-prose"] *))"#, "margin-top: 1.3333333em;"),
1023    (r#" :where(.prose > ul > li > *:last-child):not(:where([class~="not-prose"] *))"#, "margin-bottom: 1.3333333em;"),
1024    (r#" :where(.prose > ol > li > *:first-child):not(:where([class~="not-prose"] *))"#, "margin-top: 1.3333333em;"),
1025    (r#" :where(.prose > ol > li > *:last-child):not(:where([class~="not-prose"] *))"#, "margin-bottom: 1.3333333em;"),
1026    (r#" :where(ul ul, ul ol, ol ul, ol ol):not(:where([class~="not-prose"] *))"#, "margin-top: 0.6666667em;\nmargin-bottom: 0.6666667em;"),
1027    (r#" :where(hr):not(:where([class~="not-prose"] *))"#, "margin-top: 3em;\nmargin-bottom: 3em;"),
1028    (r#" :where(hr + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
1029    (r#" :where(h2 + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
1030    (r#" :where(h3 + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
1031    (r#" :where(h4 + *):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
1032    (r#" :where(table):not(:where([class~="not-prose"] *))"#, "font-size: 0.8333333em;\nline-height: 1.4;"),
1033    (r#" :where(thead th):not(:where([class~="not-prose"] *))"#, "padding-right: 0.6em;\npadding-bottom: 0.8em;\npadding-left: 0.6em;"),
1034    (r#" :where(thead th:first-child):not(:where([class~="not-prose"] *))"#, "padding-left: 0;"),
1035    (r#" :where(thead th:last-child):not(:where([class~="not-prose"] *))"#, "padding-right: 0;"),
1036    (r#" :where(tbody td, tfoot td):not(:where([class~="not-prose"] *))"#, "padding-top: 0.8em;\npadding-right: 0.6em;\npadding-bottom: 0.8em;\npadding-left: 0.6em;"),
1037    (r#" :where(tbody td:first-child, tfoot td:first-child):not(:where([class~="not-prose"] *))"#, "padding-left: 0;"),
1038    (r#" :where(tbody td:last-child, tfoot td:last-child):not(:where([class~="not-prose"] *))"#, "padding-right: 0;"),
1039    (r#" :where(:not(kbd) > kbd):not(:where([class~="not-prose"] *))"#, "background-color: var(--en-prose-kbd-bg);\ncolor: var(--en-prose-kbd-text);\npadding: 0.4em 0.5em;\nborder-radius: 0.4em;"),
1040    (r#" :where(.prose > :first-child):not(:where([class~="not-prose"] *))"#, "margin-top: 0;"),
1041    (r#" :where(.prose > :last-child):not(:where([class~="not-prose"] *))"#, "margin-bottom: 0;"),
1042];
1043
1044const PROSE_INVERT_CSS: &str = "--en-prose-body: var(--en-prose-invert-body);
1045--en-prose-headings: var(--en-prose-invert-headings);
1046--en-prose-lead: var(--en-prose-invert-lead);
1047--en-prose-links: var(--en-prose-invert-links);
1048--en-prose-bold: var(--en-prose-invert-bold);
1049--en-prose-counters: var(--en-prose-invert-counters);
1050--en-prose-bullets: var(--en-prose-invert-bullets);
1051--en-prose-hr: var(--en-prose-invert-hr);
1052--en-prose-quotes: var(--en-prose-invert-quotes);
1053--en-prose-quote-borders: var(--en-prose-invert-quote-borders);
1054--en-prose-captions: var(--en-prose-invert-captions);
1055--en-prose-code: var(--en-prose-invert-code);
1056--en-prose-pre-code: var(--en-prose-invert-pre-code);
1057--en-prose-pre-bg: var(--en-prose-invert-pre-bg);
1058--en-prose-th-borders: var(--en-prose-invert-th-borders);
1059--en-prose-td-borders: var(--en-prose-invert-td-borders);
1060--en-prose-kbd-text: var(--en-prose-invert-kbd-text);
1061--en-prose-kbd-bg: var(--en-prose-invert-kbd-bg);";
1062
1063#[derive(Debug)]
1064pub struct Prose;
1065
1066impl Plugin for Prose {
1067    fn can_handle(&self, context: ContextCanHandle) -> bool {
1068        matches!(context.modifier, Modifier::Builtin { value, .. } if [
1069                "", "sm", "base", "lg", "xl", "2xl", "gray", "slate", "zinc", "neutral", "stone",
1070                "invert",
1071            ]
1072            .contains(value))
1073    }
1074
1075    fn needs_wrapping(&self) -> bool {
1076        false
1077    }
1078
1079    fn handle(&self, context: &mut ContextHandle) {
1080        match context.modifier {
1081            Modifier::Builtin { value, .. } => match *value {
1082                "" => {
1083                    generate_at_rules(context, |context| {
1084                        context.buffer.lines(PROSE_DEFAULT_CSS.lines());
1085                    });
1086                }
1087                "sm" => {
1088                    generate_at_rules(context, |context| {
1089                        PROSE_SM_CSS.iter().for_each(|rule| {
1090                            generate_class(
1091                                context,
1092                                |context| context.buffer.lines(rule.1.lines()),
1093                                rule.0,
1094                            )
1095                        })
1096                    });
1097                }
1098                "base" => {
1099                    generate_at_rules(context, |context| {
1100                        PROSE_BASE_CSS.iter().for_each(|rule| {
1101                            generate_class(
1102                                context,
1103                                |context| context.buffer.lines(rule.1.lines()),
1104                                rule.0,
1105                            )
1106                        })
1107                    });
1108                }
1109                "lg" => {
1110                    generate_at_rules(context, |context| {
1111                        PROSE_LG_CSS.iter().for_each(|rule| {
1112                            generate_class(
1113                                context,
1114                                |context| context.buffer.lines(rule.1.lines()),
1115                                rule.0,
1116                            )
1117                        })
1118                    });
1119                }
1120                "xl" => {
1121                    generate_at_rules(context, |context| {
1122                        PROSE_XL_CSS.iter().for_each(|rule| {
1123                            generate_class(
1124                                context,
1125                                |context| context.buffer.lines(rule.1.lines()),
1126                                rule.0,
1127                            )
1128                        })
1129                    });
1130                }
1131                "2xl" => {
1132                    generate_at_rules(context, |context| {
1133                        PROSE_2XL_CSS.iter().for_each(|rule| {
1134                            generate_class(
1135                                context,
1136                                |context| context.buffer.lines(rule.1.lines()),
1137                                rule.0,
1138                            )
1139                        })
1140                    });
1141                }
1142                "gray" => {
1143                    generate_wrapper(context, |context| {
1144                        context.buffer.lines(PROSE_GRAY_CSS.lines());
1145                    });
1146                }
1147                "slate" => {
1148                    generate_wrapper(context, |context| {
1149                        context.buffer.lines(PROSE_SLATE_CSS.lines());
1150                    });
1151                }
1152                "zinc" => {
1153                    generate_wrapper(context, |context| {
1154                        context.buffer.lines(PROSE_ZINC_CSS.lines());
1155                    });
1156                }
1157                "neutral" => {
1158                    generate_wrapper(context, |context| {
1159                        context.buffer.lines(PROSE_NEUTRAL_CSS.lines());
1160                    });
1161                }
1162                "stone" => {
1163                    generate_wrapper(context, |context| {
1164                        context.buffer.lines(PROSE_STONE_CSS.lines());
1165                    });
1166                }
1167                "invert" => {
1168                    generate_wrapper(context, |context| {
1169                        context.buffer.lines(PROSE_INVERT_CSS.lines());
1170                    });
1171                }
1172                _ => unreachable!(),
1173            },
1174            Modifier::Arbitrary { .. } => unreachable!(),
1175        }
1176    }
1177}
1178
1179pub fn register(config: &mut Config) {
1180    for (name, selector) in [
1181        ("headings", Some(":where(h1, h2, h3, h4, h5, h6, th)")),
1182        ("h1", None),
1183        ("h2", None),
1184        ("h3", None),
1185        ("h4", None),
1186        ("h5", None),
1187        ("h6", None),
1188        ("p", None),
1189        ("a", None),
1190        ("blockquote", None),
1191        ("figure", None),
1192        ("figcaption", None),
1193        ("strong", None),
1194        ("em", None),
1195        ("code", None),
1196        ("pre", None),
1197        ("ol", None),
1198        ("ul", None),
1199        ("li", None),
1200        ("table", None),
1201        ("thead", None),
1202        ("tr", None),
1203        ("th", None),
1204        ("td", None),
1205        ("kbd", None),
1206        ("img", None),
1207        ("video", None),
1208        ("hr", None),
1209        ("lead", Some(r#"[class~="lead"]"#)),
1210    ] {
1211        config.register_variant(
1212            format!("prose-{name}"),
1213            Variant::new(
1214                config.last_variant_order(),
1215                format!(
1216                    r#"& :is({}:not(:where([class~="not-prose"] *)))"#,
1217                    if let Some(selector) = selector {
1218                        Cow::from(selector)
1219                    } else {
1220                        Cow::from(format!(":where({name})"))
1221                    }
1222                ),
1223            ),
1224        );
1225    }
1226
1227    config.register_plugin("prose", &Prose);
1228}
1229
1230#[cfg(test)]
1231mod tests {
1232    use encre_css::Config;
1233
1234    use std::fs;
1235
1236    #[test]
1237    fn tailwind_lorem_ipsum() {
1238        let content = fs::read_to_string("tests/fixtures/tailwind-lorem-ipsum.html").unwrap();
1239        let expected = fs::read_to_string("tests/fixtures/tailwind-lorem-ipsum.css").unwrap();
1240
1241        let mut config = Config::default();
1242        super::register(&mut config);
1243
1244        let generated = encre_css::generate([content.as_str()], &config);
1245        assert_eq!(generated, expected.trim_end());
1246    }
1247}