← typeset typeset.css Download

typeset.css

The CSS implementation. Everything is scoped to .typeset, so it cannot leak into surrounding markup. Drop it in and add the class.

Fonts are not included. The page must load EB Garamond, Source Sans 3 and IBM Plex Mono itself. For a document you send, self-host and embed them rather than fetching from a CDN at print time — and note that Google's build of EB Garamond has no real small caps, so the browser synthesises them. Download this stylesheet with the three families and their licences →

1303 lines · 43.2 KB

1/* ==========================================================================
2 typeset.css — a print stylesheet for essays, letters, and reports.
3 Units are in points. Everything is scoped to `.typeset`.
4 ========================================================================== */
5
6/*! @s tokens :: Tokens */
7.typeset {
8 /* Families */
9 --ts-serif: "EB Garamond", "Iowan Old Style", Palatino, Georgia, serif;
10 --ts-sans: "Source Sans 3", "Helvetica Neue", Helvetica, Arial, sans-serif;
11 --ts-mono: "IBM Plex Mono", "SF Mono", Menlo, Consolas, monospace;
12
13 /* Scale — 11pt base, ~1.2 ratio */
14 --ts-xs: 8pt;
15 --ts-sm: 9.5pt;
16 --ts-base: 11pt;
17 --ts-h4: 12pt;
18 --ts-h3: 14pt;
19 --ts-h2: 18pt;
20 --ts-h1: 24pt;
21
22 /* Rhythm */
23 --ts-leading: 1.45;
24 --ts-leading-tight: 1.2;
25 --ts-space: 11pt; /* one line of base leading, near enough */
26 --ts-measure: 33em; /* ~66 characters at 11pt serif */
27
28 /* Ink — never pure black: it blooms on laser and glares in a PDF */
29 --ts-ink: #1a1a1a;
30 --ts-ink-muted: #5a5a5a;
31 --ts-ink-faint: #8a8a8a;
32 --ts-rule: #c9c4bd;
33 --ts-rule-strong: #6f6a64;
34 --ts-wash: #f4f1ec;
35 --ts-accent: #7a1f1f; /* oxblood: reads as dark grey in greyscale */
36}
37/*! @e */
38
39/*! @s foundation :: Foundation */
40.typeset {
41 font-family: var(--ts-serif);
42 font-size: var(--ts-base);
43 font-variant-numeric: oldstyle-nums proportional-nums;
44 line-height: var(--ts-leading);
45 color: var(--ts-ink);
46 text-rendering: optimizeLegibility;
47 font-kerning: normal;
48 font-feature-settings: "liga" 1, "kern" 1;
49}
50
51/* Measure is a property of the text column, not the page. Centred, not flush
52 to one edge: foundation.rhythm.measure_position — where the measure is
53 narrower than the page's own text width, the surplus splits evenly on
54 both sides. `margin-inline: auto` is inert wherever there is no surplus
55 (measure: none in two columns, or any block already at 100%), so it needs
56 no opt-out for those; `.typeset--sidenotes` is the one case that DOES
57 carry a surplus and still wants it flush, and it resets this back below. */
58/* Every block rule below sets its vertical margins alone (margin-block), so
59 this rule owns the horizontal ones and the measure stays centred. The two
60 blocks whose browser default carries a side margin when nested — blockquote
61 and figure — zero it in their own rules and are re-centred as direct
62 children further down.
63
64 The measure is counted in the body's ems, as Typst counts it. An em in
65 --ts-measure would otherwise resolve against each block's own size — 33em of
66 an 18pt heading is wider than the page — so it is computed once, on
67 .typeset, into a registered length that every child inherits as is. */
68@property --ts-measure-computed {
69 syntax: "<length-percentage> | none";
70 inherits: true;
71 initial-value: none;
72}
73.typeset { --ts-measure-computed: var(--ts-measure); }
74.typeset > * {
75 box-sizing: border-box; /* a block's own padding sits inside the measure, as Typst's inset does */
76 max-width: var(--ts-measure-computed);
77 margin-inline: auto;
78}
79
80.typeset--measure-wide { --ts-measure: 40em; }
81.typeset--measure-narrow { --ts-measure: 27em; }
82/*! @e */
83
84/*! @s page :: Page setup */
85/* Symmetric is what a document gets unless it asks for binding: the named
86 size applies to all four sides. `standard` is the default size, set here on
87 the unqualified page — every named page below is a page-name override of
88 just its margins, and everything else on this rule (size, running head,
89 folio, first-page suppression) still cascades onto it. */
90@page {
91 size: A4; /* or: Letter */
92 margin: 20mm; /* foundation.page.margins.symmetric_mm.standard */
93
94 /* Margin boxes need a paged-media engine: Paged.js, WeasyPrint, Prince.
95 Chrome's own print dialog ignores them. */
96 @top-center {
97 content: string(ts-running-head);
98 font: 8pt/1 "Source Sans 3", sans-serif;
99 letter-spacing: 0.08em;
100 text-transform: uppercase;
101 color: #8a8a8a;
102 }
103 @bottom-center {
104 content: counter(page);
105 font: 9pt/1 "EB Garamond", serif;
106 font-variant-numeric: oldstyle-nums;
107 color: #5a5a5a;
108 }
109}
110
111/* No running head or folio on the opening page. */
112@page :first {
113 @top-center { content: none; }
114 @bottom-center { content: none; }
115}
116
117/* The running head follows the current section. */
118.typeset h2 { string-set: ts-running-head content(text); }
119
120/* The three symmetric sizes, the same value on every side. `standard` names
121 the default set above; the class exists so a document can ask for it back
122 explicitly, the same as narrow and wide. */
123.typeset--margin-narrow { page: ts-margin-narrow; }
124.typeset--margin-standard { page: ts-margin-standard; }
125.typeset--margin-wide { page: ts-margin-wide; }
126
127@page ts-margin-narrow { margin: 10mm; }
128@page ts-margin-standard { margin: 20mm; }
129@page ts-margin-wide { margin: 30mm; }
130
131/* Duplex: the explicit opt-in for a sheet that will be bound. Top and bottom
132 stay at the symmetric value; left and right split into an inner (binding)
133 edge and an outer edge, mirrored by page side so the gutter stays on the
134 spine rather than swapping sides every other sheet. */
135.typeset--margin-duplex-narrow { page: ts-margin-duplex-narrow; }
136.typeset--margin-duplex-standard { page: ts-margin-duplex-standard; }
137.typeset--margin-duplex-wide { page: ts-margin-duplex-wide; }
138
139@page ts-margin-duplex-narrow { margin-top: 10mm; margin-bottom: 10mm; }
140@page ts-margin-duplex-narrow:right { margin-left: 13mm; margin-right: 7mm; }
141@page ts-margin-duplex-narrow:left { margin-left: 7mm; margin-right: 13mm; }
142
143@page ts-margin-duplex-standard { margin-top: 20mm; margin-bottom: 20mm; }
144@page ts-margin-duplex-standard:right { margin-left: 23mm; margin-right: 17mm; }
145@page ts-margin-duplex-standard:left { margin-left: 17mm; margin-right: 23mm; }
146
147@page ts-margin-duplex-wide { margin-top: 30mm; margin-bottom: 30mm; }
148@page ts-margin-duplex-wide:right { margin-left: 33mm; margin-right: 27mm; }
149@page ts-margin-duplex-wide:left { margin-left: 27mm; margin-right: 33mm; }
150/*! @e */
151
152/*! @s heading :: Headings */
153/* The shared base every heading level builds on: line-height, color, margin rhythm and break behaviour. Not a style in its own right — each level below overrides family, weight and size to become itself. */
154.typeset h1,
155.typeset h2,
156.typeset h3,
157.typeset h4,
158.typeset h5,
159.typeset h6 {
160 font-family: var(--ts-sans);
161 font-weight: 600;
162 line-height: var(--ts-leading-tight);
163 color: var(--ts-ink);
164
165 /* A heading belongs to what follows it, not to what precedes it. */
166 margin-block: calc(var(--ts-space) * 2) calc(var(--ts-space) * 0.5);
167
168 /* Never strand a heading at the foot of a page. */
169 break-after: avoid;
170 break-inside: avoid;
171 text-wrap: balance;
172}
173
174/* @style heading-h1 */
175.typeset h1 {
176 font-size: var(--ts-h1);
177 font-weight: 300;
178 letter-spacing: -0.015em;
179 margin-top: 0;
180}
181
182/* @style heading-h2 */
183.typeset h2 {
184 font-size: var(--ts-h2);
185 letter-spacing: -0.01em;
186}
187
188/* @style heading-h3 */
189.typeset h3 { font-size: var(--ts-h3); }
190
191/* @style heading-h4 */
192.typeset h4 { font-size: var(--ts-h4); }
193
194/* Below h4, drop the size change and shift register instead. */
195/* @style heading-h5 */
196.typeset h5 {
197 font-size: var(--ts-base);
198 font-family: var(--ts-serif);
199 font-weight: 600;
200 font-variant-caps: all-small-caps;
201 letter-spacing: 0.06em;
202}
203
204/* @style heading-h6 */
205.typeset h6 {
206 font-size: var(--ts-base);
207 font-family: var(--ts-serif);
208 font-weight: 400;
209 font-style: italic;
210}
211
212/* A run-in heading: the h6 sits on the first line of its paragraph. */
213.typeset .ts-heading-run-in {
214 display: inline;
215 margin: 0;
216}
217.typeset .ts-heading-run-in + p { display: inline; }
218.typeset .ts-heading-run-in::after { content: " · "; color: var(--ts-ink-faint); }
219/*! @e */
220
221/*! @s numbering :: Section numbering */
222.typeset--numbered { counter-reset: ts-heading-h2; }
223
224/* @style numbering-h2 */
225.typeset--numbered h2 {
226 counter-increment: ts-heading-h2;
227 counter-reset: ts-heading-h3;
228}
229.typeset--numbered h2::before {
230 content: counter(ts-heading-h2) " ";
231 color: var(--ts-ink-faint);
232 font-variant-numeric: lining-nums tabular-nums;
233}
234
235/* @style numbering-h3 */
236.typeset--numbered h3 { counter-increment: ts-heading-h3; }
237.typeset--numbered h3::before {
238 content: counter(ts-heading-h2) "." counter(ts-heading-h3) " ";
239 color: var(--ts-ink-faint);
240 font-variant-numeric: lining-nums tabular-nums;
241}
242/*! @e */
243
244/*! @s paragraph :: Paragraphs */
245/* @style paragraph-spaced */
246.typeset {
247 /* Paragraph separation is one decision expressed as two values: a gap, or an
248 indent, never both. A template sets these; nothing else needs to know. */
249 --ts-para-gap: var(--ts-space);
250 --ts-para-indent: 0;
251}
252
253/* @style paragraph-indented */
254.typeset--indented {
255 --ts-para-gap: 0;
256 --ts-para-indent: 1.5em;
257}
258
259.typeset p {
260 margin-block: 0 var(--ts-para-gap);
261 text-indent: var(--ts-para-indent);
262 orphans: 2; /* no single line left at the foot of a page */
263 widows: 2; /* no single line carried to the head of the next */
264}
265
266/* The first paragraph after a heading, block or break is flush: the thing above
267 it has already marked the start.
268
269 Enumerated rather than written as `:is(...)`. Paged.js rewrites every
270 stylesheet through its own CSS parser, which does not understand `:is()`: it
271 splits the selector on the commas INSIDE the argument list and emits
272 fragments like ` .ts-callout)+p`, which throw on querySelectorAll
273 and abort pagination entirely — a blank document, not a degraded one. Keep
274 this list flat. */
275.typeset h1 + p,
276.typeset h2 + p,
277.typeset h3 + p,
278.typeset h4 + p,
279.typeset h5 + p,
280.typeset h6 + p,
281.typeset blockquote + p,
282.typeset figure + p,
283.typeset pre + p,
284.typeset table + p,
285.typeset hr + p,
286.typeset .ts-break + p,
287.typeset .ts-callout + p,
288.typeset > p:first-child {
289 text-indent: 0;
290}
291/*! @e */
292
293/*! @s justification :: Justification & hyphenation */
294/* Justification without hyphenation opens rivers of white space.
295 Both, or neither. And `lang` must be set — hyphenation is per-language. */
296/* @style justification-justified */
297.typeset--justified {
298 text-align: justify;
299 text-align-last: left; /* the last line is never stretched */
300 text-justify: inter-word;
301 hyphens: auto;
302 hyphenate-limit-chars: 6 3 3; /* min word, before break, after break */
303 -webkit-hyphenate-limit-before: 3;
304 -webkit-hyphenate-limit-after: 3;
305 hyphenate-limit-lines: 2; /* never stack 3 hyphens in a row */
306}
307
308/* Ragged right. This is the default — the point of naming it is so a document
309 can state the choice rather than express it as the absence of a class, and so
310 the two options read as siblings in the source.
311
312 `text-wrap: pretty` asks the engine to spend more effort on the rag: it
313 avoids a very short last line and evens out the right edge, which is the one
314 thing a ragged setting can get wrong. Hyphenation stays off — a hyphen exists
315 to help justification, and without justification it only breaks a word for
316 no gain. */
317/* @style justification-ragged */
318.typeset--ragged {
319 text-align: left;
320 text-align-last: left;
321 hyphens: manual;
322 text-wrap: pretty;
323}
324
325/* `text-align-last` inherits as well, so a block that centres itself must
326 restore it — otherwise its last line, which for a one-line block is its only
327 line, is flushed left. See .ts-quote-pullquote and .ts-break.
328
329 Never justify a heading, a cell, or a listing. Every other block that must
330 stay flush left — subtitle, byline, caption, address, notes — declares
331 `text-align: left` in its own rule, because a direct match always beats an
332 inherited value and its descendants then inherit `left` in turn. Relying on
333 an exception list here instead means every new block silently opts in. */
334/* @style justification-exclusions — headings h1-h4, body cells and listings are pulled back to flush under .typeset--justified; every other never-justified block declares text-align: left in its own rule, per the note above. */
335.typeset--justified h1,
336.typeset--justified h2,
337.typeset--justified h3,
338.typeset--justified h4,
339.typeset--justified td,
340.typeset--justified pre { text-align: left; hyphens: manual; }
341/*! @e */
342
343/*! @s dropcap :: Drop cap */
344.typeset .ts-dropcap::first-letter {
345 float: left;
346 font-family: var(--ts-serif);
347 font-size: 3.05em; /* tuned to cover exactly three lines */
348 line-height: 0.86;
349 font-weight: 400;
350 color: var(--ts-accent);
351 padding: 0.02em 0.06em 0 0;
352}
353.typeset .ts-dropcap { text-indent: 0; }
354
355/* A drop cap wants the opening words in small caps to bridge the size jump. */
356.typeset .ts-dropcap-lede { font-variant-caps: all-small-caps; letter-spacing: 0.04em; }
357/*! @e */
358
359/*! @s inline :: Inline emphasis */
360/* @style inline-strong */
361.typeset strong, .typeset b { font-weight: 600; }
362/* @style inline-emphasis */
363.typeset em, .typeset i { font-style: italic; }
364/* @style inline-emphasis-nested */
365.typeset em em, .typeset em i { font-style: normal; } /* nested emphasis flips */
366.typeset strong em, .typeset em strong { font-weight: 600; font-style: italic; }
367
368/* Small caps for named entities, acronyms, and stage directions. */
369.typeset .ts-inline-small-caps {
370 font-variant-caps: all-small-caps;
371 letter-spacing: 0.05em;
372 font-variant-numeric: oldstyle-nums;
373}
374
375/* @style inline-abbr */
376.typeset abbr[title] {
377 font-variant-caps: all-small-caps;
378 letter-spacing: 0.05em;
379 text-decoration: none;
380 border-bottom: 0.5pt dotted var(--ts-ink-faint);
381}
382
383/* @style inline-deleted */
384.typeset s, .typeset del { text-decoration: line-through; color: var(--ts-ink-muted); }
385/* @style inline-inserted */
386.typeset ins { text-decoration: underline; text-underline-offset: 0.15em; }
387/* @style inline-highlight */
388.typeset mark { background: var(--ts-wash); box-shadow: 0 0 0 2pt var(--ts-wash); }
389
390/* Real super/subscripts, not shifted full-size digits. */
391/* @style inline-superscript */
392/* @style inline-subscript */
393.typeset sup, .typeset sub {
394 font-size: 0.72em;
395 line-height: 0;
396 position: relative;
397 vertical-align: baseline;
398}
399.typeset sup { top: -0.45em; }
400.typeset sub { bottom: -0.22em; }
401
402/* @style inline-kbd */
403.typeset kbd {
404 font: 0.85em/1 var(--ts-sans);
405 padding: 0.15em 0.35em;
406 border: 0.5pt solid var(--ts-rule);
407 border-bottom-width: 1.5pt;
408 border-radius: 2pt;
409}
410/*! @e */
411
412/*! @s code-inline :: Inline code */
413/* @style code-inline */
414.typeset code {
415 font-family: var(--ts-mono);
416 font-size: 0.86em; /* mono runs large; pull it back optically */
417 font-variant-ligatures: none;
418 background: var(--ts-wash);
419 padding: 0.1em 0.28em;
420 border-radius: 2pt;
421 overflow-wrap: break-word;
422}
423/*! @e */
424
425/*! @s link :: Links in print */
426/* @style link */
427.typeset a {
428 color: inherit;
429 text-decoration: underline;
430 text-decoration-thickness: 0.5pt;
431 text-underline-offset: 0.14em;
432 text-decoration-skip-ink: auto;
433}
434
435/* Paper has no hover. Spell out external URLs where they carry information. */
436@media print {
437 /* @style link-print-url */
438 .typeset a[href^="http"]::after {
439 content: " (" attr(href) ")";
440 font: 0.82em var(--ts-mono);
441 color: var(--ts-ink-muted);
442 word-break: break-all;
443 }
444 /* Internal and mailto links read fine as-is. */
445 .typeset a[href^="#"]::after,
446 .typeset a[href^="mailto"]::after,
447 .typeset a.ts-link-bare::after { content: none; }
448}
449/*! @e */
450
451/*! @s numeral :: Numerals */
452/* Old-style figures sit in the x-height and belong in running prose.
453 Lining figures are uniform-height and belong in headings and tables.
454 Tabular figures share one advance width so columns align. */
455.typeset .ts-numeral-prose { font-variant-numeric: oldstyle-nums proportional-nums; }
456.typeset .ts-numeral-display { font-variant-numeric: lining-nums proportional-nums; }
457.typeset .ts-numeral-tabular { font-variant-numeric: lining-nums tabular-nums; }
458.typeset .ts-numeral-fraction { font-variant-numeric: diagonal-fractions; }
459/*! @e */
460
461/*! @s quote :: Block quotations */
462/* @style quote-blockquote */
463.typeset blockquote {
464 margin-block: calc(var(--ts-space) * 1.25);
465 margin-inline: 0;
466 padding-left: calc(var(--ts-space) * 1.5);
467 border-left: 1pt solid var(--ts-rule);
468 color: var(--ts-ink);
469 font-size: 10.5pt;
470 break-inside: avoid;
471}
472.typeset blockquote > :last-child { margin-bottom: 0; }
473.typeset > blockquote { margin-inline: auto; }
474
475/* Attribution: an em dash, and never inside the quote. */
476.typeset blockquote cite,
477.typeset .ts-quote-attribution {
478 display: block;
479 text-align: left;
480 margin-top: calc(var(--ts-space) * 0.5);
481 font-size: var(--ts-sm);
482 font-style: normal;
483 color: var(--ts-ink-muted);
484}
485.typeset blockquote cite::before,
486.typeset .ts-quote-attribution::before { content: "— "; }
487
488/* An epigraph opens a chapter: no rule, indented from the right, italic. */
489.typeset .ts-quote-epigraph {
490 border: 0;
491 text-align: left;
492 margin: 0 0 calc(var(--ts-space) * 2) auto;
493 padding: 0;
494 max-width: 24em;
495 font-style: italic;
496 font-size: 10pt;
497 color: var(--ts-ink-muted);
498}
499.typeset .ts-quote-epigraph cite { font-style: normal; }
500
501/* A pull quote is display type lifted from the body. It repeats — so it must
502 never be the only place a claim appears. */
503.typeset .ts-quote-pullquote {
504 border: 0;
505 text-align: center;
506 text-align-last: center;
507 border-top: 1.5pt solid var(--ts-rule-strong);
508 border-bottom: 0.5pt solid var(--ts-rule);
509 padding: var(--ts-space) 0;
510 margin-block: calc(var(--ts-space) * 1.5);
511 font-family: var(--ts-sans);
512 font-size: 15pt;
513 font-weight: 300;
514 line-height: 1.3;
515 text-wrap: balance;
516}
517
518/* Verse: preserve the poet's line breaks, indent the runovers. */
519.typeset .ts-quote-verse {
520 border: 0;
521 text-align: left;
522 padding-left: calc(var(--ts-space) * 2);
523 white-space: pre-line;
524 font-size: var(--ts-base);
525 text-indent: -1.5em;
526 padding-inline-start: calc(var(--ts-space) * 2 + 1.5em);
527}
528/*! @e */
529
530/*! @s list :: Lists */
531.typeset ul,
532.typeset ol {
533 margin-block: 0 var(--ts-space);
534 padding-left: 1.4em;
535}
536.typeset li { margin-bottom: calc(var(--ts-space) * 0.25); }
537.typeset li > ul,
538.typeset li > ol { margin-block: calc(var(--ts-space) * 0.25) 0; }
539.typeset li:last-child { margin-bottom: 0; }
540
541/* @style list-unordered */
542.typeset ul { list-style: none; }
543.typeset ul > li::before {
544 content: "·";
545 float: left;
546 width: 1.4em;
547 margin-left: -1.4em;
548 text-align: left;
549 color: var(--ts-ink-muted);
550 font-weight: 700;
551}
552/* @style list-unordered-nested */
553.typeset ul ul > li::before { content: "–"; font-weight: 400; }
554
555/* The marker is drawn here rather than by the browser, so the colour, weight
556 and column are under control. One consequence is worth knowing before it
557 surprises anyone: `start` and `value` set the browser's own `list-item`
558 counter, which nothing below reads, so a list that must begin at eight
559 resets this counter instead — `<ol style="counter-reset: ts-ol 7">`. */
560/* @style list-ordered */
561.typeset ol {
562 list-style: none;
563 counter-reset: ts-ol;
564}
565.typeset ol > li { counter-increment: ts-ol; }
566.typeset ol > li::before {
567 content: counter(ts-ol) ".";
568 float: left;
569 width: 1.4em;
570 margin-left: -1.4em;
571 color: var(--ts-ink-muted);
572 font-variant-numeric: lining-nums tabular-nums;
573}
574/* @style list-ordered-nested */
575.typeset ol ol > li::before { content: counter(ts-ol, lower-alpha) "."; }
576
577/* A tight list for enumerations that are not prose. */
578.typeset .ts-list-tight li { margin-bottom: 0; }
579
580/* Definition lists: the right shape for terms, glossaries, and letter fields. */
581.typeset dl { margin-block: 0 var(--ts-space); }
582/* @style list-definition-term */
583.typeset dt {
584 text-align: left;
585 font-weight: 600;
586 font-family: var(--ts-sans);
587 font-size: var(--ts-sm);
588 margin-top: calc(var(--ts-space) * 0.6);
589 break-after: avoid;
590}
591.typeset dt:first-child { margin-top: 0; }
592/* @style list-definition-description */
593.typeset dd { margin: 0 0 0 calc(var(--ts-space) * 1.5); }
594/*! @e */
595
596/*! @s table :: Tables */
597/* @style table */
598.typeset table {
599 width: 100%;
600 border-collapse: collapse;
601 margin-block: calc(var(--ts-space) * 1.25);
602 font-family: var(--ts-sans);
603 font-size: var(--ts-sm);
604 font-variant-numeric: lining-nums tabular-nums;
605 line-height: 1.35;
606}
607
608/* Rules, not grids. Vertical rules are almost never needed — the columns
609 already read as columns. */
610/* @style table-cell */
611.typeset th,
612.typeset td {
613 padding: 0.45em 0.7em 0.45em 0;
614 text-align: left;
615 vertical-align: baseline;
616 border-bottom: 0.5pt solid var(--ts-rule);
617}
618.typeset th:last-child,
619.typeset td:last-child { padding-right: 0; }
620
621/* @style table-header-cell */
622/* The header row carries two of the three rules the section's principle asks
623 for: the one above it, which opens the table, and the one below it, which
624 separates the labels from the data. The third closes the body, below. */
625.typeset thead th {
626 font-weight: 600;
627 font-size: var(--ts-xs);
628 letter-spacing: 0.07em;
629 text-transform: uppercase;
630 color: var(--ts-ink-muted);
631 border-top: 1pt solid var(--ts-rule-strong);
632 border-bottom: 1pt solid var(--ts-rule-strong);
633}
634.typeset tbody tr:last-child td { border-bottom: 1pt solid var(--ts-rule-strong); }
635/* @style table-footer-cell */
636.typeset tfoot td { font-weight: 600; border-bottom: 0; }
637
638/* Numbers align on their right edge. Units go in the header, not every cell. */
639.typeset .ts-table-cell-numeric { text-align: right; font-variant-numeric: lining-nums tabular-nums; }
640.typeset th.ts-table-cell-numeric { text-align: right; }
641
642/* Repeat the header on every page a long table spans. */
643.typeset thead { display: table-header-group; }
644.typeset tfoot { display: table-footer-group; }
645/* @style table-row */
646.typeset tr { break-inside: avoid; }
647
648/* @style table-caption */
649.typeset caption {
650 caption-side: top;
651 text-align: left;
652 font-family: var(--ts-sans);
653 font-size: var(--ts-sm);
654 color: var(--ts-ink);
655 padding-bottom: 0.5em;
656 max-width: none;
657}
658/* The shared base under every caption/label variant: small-caps, weight and
659 tracking common to a table caption's label, a figure caption's label, the
660 abstract's label and a letter address block's label. Not a style in its
661 own right — always written alongside one of the four named classes below,
662 which each carry what makes their label different from the others. */
663.typeset .ts-label {
664 font-weight: 600;
665 font-variant-caps: all-small-caps;
666 letter-spacing: 0.06em;
667}
668/* Empty on purpose: the base above already carries everything a table
669 caption's label needs. The class exists so the style has a name. */
670.typeset .ts-table-caption-label { }
671
672/* Optional zebra for wide, dense tables only. */
673.typeset .ts-table-zebra tbody tr:nth-child(even) { background: var(--ts-wash); }
674/*! @e */
675
676/*! @s codeblock :: Code blocks */
677/* @style codeblock */
678.typeset pre {
679 font-family: var(--ts-mono);
680 font-size: 8.5pt;
681 line-height: 1.45;
682 background: var(--ts-wash);
683 border-left: 2pt solid var(--ts-rule-strong);
684 padding: 0.8em 1em;
685 margin-block: calc(var(--ts-space) * 1.25);
686 overflow-x: auto;
687
688 /* Paper cannot scroll. Wrap, and mark the wrap. */
689 white-space: pre-wrap;
690 overflow-wrap: break-word;
691 tab-size: 2;
692 break-inside: avoid;
693}
694.typeset pre code {
695 background: none;
696 padding: 0;
697 font-size: inherit;
698}
699
700@media print {
701 .typeset pre { break-inside: auto; } /* long listings must be allowed to split */
702}
703/*! @e */
704
705/*! @s figure :: Figures & captions */
706/* @style figure */
707.typeset figure {
708 margin-block: calc(var(--ts-space) * 1.5);
709 margin-inline: 0;
710 break-inside: avoid;
711}
712.typeset > figure { margin-inline: auto; }
713.typeset figure img,
714.typeset figure svg {
715 display: block;
716 max-width: 100%;
717 height: auto;
718}
719/* @style figure-caption */
720.typeset figcaption {
721 text-align: left;
722 font-family: var(--ts-sans);
723 font-size: var(--ts-sm);
724 line-height: 1.4;
725 color: var(--ts-ink-muted);
726 margin-top: 0.5em;
727 padding-top: 0.4em;
728 border-top: 0.5pt solid var(--ts-rule);
729}
730.typeset .ts-figure-caption-label { color: var(--ts-ink); }
731/*! @e */
732
733/*! @s note :: Footnotes & endnotes */
734/* The reference mark. Superscript, no brackets, and it must not disturb
735 the line's leading. */
736.typeset .ts-note-marker {
737 font-size: 0.7em;
738 line-height: 0;
739 position: relative;
740 top: -0.45em;
741 font-variant-numeric: lining-nums;
742 text-decoration: none;
743 color: var(--ts-accent);
744}
745.typeset .ts-note-marker::before { content: counter(ts-note-footnote); }
746.typeset { counter-reset: ts-note-footnote; }
747.typeset .ts-note-marker { counter-increment: ts-note-footnote; }
748
749/* True bottom-of-page footnotes need an engine that implements the CSS
750 footnote spec — WeasyPrint 53+ and Prince do; browsers do not. Where they
751 are unavailable this degrades to an endnotes block, which is why the notes
752 live in the document rather than in a generated-content property. */
753@supports (float: footnote) {
754 /* @style letter-footnote — a letter's footnote is the document footnote mechanism: the marker above and the endnotes block below. */
755 .typeset .ts-note-footnote {
756 float: footnote;
757 footnote-display: block;
758 font-size: var(--ts-sm);
759 line-height: 1.35;
760 }
761 .typeset .ts-note-endnotes { display: none; }
762}
763
764.typeset .ts-note-endnotes {
765 text-align: left;
766 margin-top: calc(var(--ts-space) * 2);
767 padding-top: var(--ts-space);
768 border-top: 0.5pt solid var(--ts-rule);
769 font-size: var(--ts-sm);
770 line-height: 1.4;
771 counter-reset: ts-endnote;
772}
773.typeset .ts-note-endnotes ol { padding-left: 1.8em; }
774.typeset .ts-note-endnotes li { margin-bottom: 0.4em; }
775
776/* Sidenotes: no page-break arithmetic, and the reader never loses their
777 place. They cost you a wide right margin. */
778/* The reserved margin must be wide enough for the gap plus the note: 2em + 11em
779 here, with an em to spare. */
780.typeset--sidenotes { --ts-measure: 27em; padding-right: 14em; }
781/* Exempt from foundation.rhythm.measure_position: the narrowed measure here
782 is not a column asking to sit in the middle of the page, it is the price
783 of the reserved margin above, and that margin has to stay wholly on the
784 right, where .ts-note-sidenote's own offset (below) expects to find it. */
785.typeset--sidenotes > * { margin-inline: 0; }
786.typeset--sidenotes p { position: relative; }
787.typeset .ts-note-sidenote {
788 position: absolute;
789
790 /* Anchored to the paragraph's own right edge, NOT to `calc(measure + 2em)`.
791 The measure is a max-width, so the paragraph is whichever is narrower —
792 the measure, or what the container's padding leaves it. Offsetting from the
793 measure therefore puts the note in the wrong place whenever the padding is
794 the binding constraint, and it lands on top of the text. */
795 left: 100%;
796 margin-left: 2em;
797 width: 11em;
798 margin-top: -0.3em;
799 font-family: var(--ts-sans);
800 font-size: var(--ts-xs);
801 line-height: 1.4;
802 color: var(--ts-ink-muted);
803 text-align: left;
804 text-indent: 0;
805}
806.typeset .ts-note-sidenote::before {
807 content: counter(ts-note-footnote) " ";
808 color: var(--ts-accent);
809 font-weight: 600;
810}
811/*! @e */
812
813/*! @s callout :: Callouts */
814.typeset .ts-callout {
815 margin-block: calc(var(--ts-space) * 1.25);
816 padding: 0.75em 1em;
817 border: 0.5pt solid var(--ts-rule);
818 border-left: 2.5pt solid var(--ts-rule-strong);
819 background: var(--ts-wash);
820 font-size: 10pt;
821 break-inside: avoid;
822}
823.typeset .ts-callout > :last-child { margin-bottom: 0; }
824.typeset .ts-callout-title {
825 font-family: var(--ts-sans);
826 font-size: var(--ts-xs);
827 font-weight: 700;
828 letter-spacing: 0.09em;
829 text-transform: uppercase;
830 color: var(--ts-ink-muted);
831 margin-bottom: 0.35em;
832}
833.typeset .ts-callout-warning { border-left-color: var(--ts-accent); }
834.typeset .ts-callout-warning .ts-callout-title { color: var(--ts-accent); }
835/*! @e */
836
837/*! @s break :: Section breaks */
838/* A blank line cannot survive a page break — if the break falls on the gap,
839 the reader never sees it. Use a visible mark: one of the four variants
840 below, each supplying its own ::before content.
841
842 This rule is the block geometry a bare <hr> and .ts-break both need —
843 internal, and it renders no mark of its own. The mark comes from the
844 ::before of a specific variant (or, for <hr>, the rule right below). */
845.typeset hr,
846.typeset .ts-break {
847 border: 0;
848 height: auto;
849 margin-block: calc(var(--ts-space) * 1.5);
850 text-align: center;
851 text-align-last: center; /* a one-line block IS its own last line */
852 color: var(--ts-ink-faint);
853 break-after: avoid;
854}
855/* A bare <hr> carries no variant class, so its mark is fixed here: three
856 widely spaced asterisks, the same values .ts-break-asterisks::before
857 uses below for a document that spells the choice out explicitly. */
858.typeset hr::before {
859 content: "* * *";
860 letter-spacing: 0.6em;
861 font-size: 10pt;
862}
863
864/* Three widely spaced asterisks, the default treatment. */
865.typeset .ts-break-asterisks::before { content: "* * *"; letter-spacing: 0.6em; font-size: 10pt; }
866/* An asterism, for a heavier division. */
867.typeset .ts-break-asterism::before { content: "⁂"; letter-spacing: 0; font-size: 14pt; }
868/* A fleuron, for a decorative one. */
869.typeset .ts-break-fleuron::before { content: "❦"; letter-spacing: 0; font-size: 12pt; color: var(--ts-accent); }
870/* A plain rule, for a report. */
871.typeset .ts-break-rule::before { content: none; }
872.typeset .ts-break-rule { border-top: 0.5pt solid var(--ts-rule); height: 0; }
873/*! @e */
874
875/*! @s frontmatter :: Front matter */
876.typeset .ts-frontmatter-title-block {
877 margin-bottom: calc(var(--ts-space) * 3);
878 padding-bottom: var(--ts-space);
879 border-bottom: 0.5pt solid var(--ts-rule);
880}
881.typeset .ts-frontmatter-title-block h1 { margin-bottom: 0.25em; }
882.typeset .ts-frontmatter-subtitle {
883 text-align: left;
884 font-family: var(--ts-sans);
885 font-size: var(--ts-h3);
886 font-weight: 300;
887 line-height: 1.25;
888 color: var(--ts-ink-muted);
889 margin-block: 0 var(--ts-space);
890 text-wrap: balance;
891}
892.typeset .ts-frontmatter-byline {
893 text-align: left;
894 font-variant-caps: all-small-caps;
895 letter-spacing: 0.08em;
896 font-size: var(--ts-base);
897 margin-block: 0;
898}
899.typeset .ts-frontmatter-dateline {
900 text-align: left;
901 font-family: var(--ts-sans);
902 font-size: var(--ts-sm);
903 color: var(--ts-ink-muted);
904 margin-block: 0.2em 0;
905}
906
907.typeset .ts-frontmatter-abstract {
908 text-align: left;
909 font-size: 10pt;
910 line-height: 1.45;
911 color: var(--ts-ink-muted);
912 max-width: 30em;
913 margin-bottom: calc(var(--ts-space) * 2);
914}
915.typeset .ts-frontmatter-abstract-label {
916 font-family: var(--ts-sans);
917 font-size: var(--ts-xs);
918 font-weight: 700;
919 font-variant-caps: normal;
920 letter-spacing: 0.1em;
921 text-transform: uppercase;
922 color: var(--ts-ink-faint);
923 display: block;
924 margin-bottom: 0.3em;
925}
926
927/* The colophon closes the document: how it was made, and in what. */
928.typeset .ts-frontmatter-colophon {
929 text-align: left;
930 margin-top: calc(var(--ts-space) * 3);
931 padding-top: var(--ts-space);
932 border-top: 0.5pt solid var(--ts-rule);
933 font-size: var(--ts-sm);
934 font-style: italic;
935 color: var(--ts-ink-muted);
936 max-width: 26em;
937 break-before: avoid;
938}
939/*! @e */
940
941/*! @s toc :: Table of contents */
942/* Dot leaders and real page numbers need `target-counter()` — a paged-media
943 engine only. In a browser the leaders render and the numbers do not. */
944.typeset .ts-toc { text-align: left; font-family: var(--ts-sans); font-size: var(--ts-sm); }
945.typeset .ts-toc ol { padding-left: 0; }
946/* @style toc-entry */
947.typeset .ts-toc li { margin-bottom: 0.35em; }
948.typeset .ts-toc li::before { content: none; }
949.typeset .ts-toc a {
950 display: flex;
951 align-items: baseline;
952 gap: 0.4em;
953 text-decoration: none;
954}
955.typeset .ts-toc a::after {
956 content: target-counter(attr(href url), page);
957 font-variant-numeric: lining-nums tabular-nums;
958 color: var(--ts-ink-muted);
959}
960.typeset .ts-toc .ts-toc-leader {
961 flex: 1;
962 border-bottom: 0.5pt dotted var(--ts-rule);
963 transform: translateY(-0.15em);
964}
965.typeset .ts-toc .ts-toc-entry-2 { padding-left: 1.5em; }
966/*! @e */
967
968/*! @s bibliography :: Bibliography */
969/* Same scale and weight as heading-h2 — a bibliography heading reads as a
970 section heading — but its own element, distinct from heading-h2, which is
971 what lets it span both columns in the two-column template while an
972 ordinary section heading cannot (templates.two-column.spanning). */
973.typeset .ts-bibliography-heading {
974 font-family: var(--ts-sans);
975 font-weight: 600;
976 font-size: var(--ts-h2);
977 line-height: var(--ts-leading-tight);
978 letter-spacing: -0.01em;
979 color: var(--ts-ink);
980 margin-block: calc(var(--ts-space) * 2) calc(var(--ts-space) * 0.5);
981 break-after: avoid;
982 break-inside: avoid;
983 text-wrap: balance;
984}
985/* Hanging indent: the author's surname is the thing being scanned, so it must
986 be the leftmost thing on the entry. */
987.typeset .ts-bibliography-entry {
988 text-align: left;
989 font-size: var(--ts-sm);
990 line-height: 1.4;
991 padding-left: 0;
992 list-style: none;
993}
994.typeset .ts-bibliography-entry li {
995 padding-left: 1.8em;
996 text-indent: -1.8em;
997 margin-bottom: 0.55em;
998 break-inside: avoid;
999}
1000.typeset .ts-bibliography-entry li::before { content: none; }
1001.typeset .ts-bibliography-entry cite { font-style: italic; }
1002/*! @e */
1003
1004/*! @s letter :: Letter */
1005/* @style letter-page — a letter's own page: no running head, no folio, the
1006 standard margin (foundation.page.margins.symmetric_mm.standard, 20mm) plus
1007 letter-page.derivation.letter_inset_mm (15mm) on every edge, and the text
1008 justified at 12pt across the full width that leaves — about 66 characters
1009 on A4. The letterhead reaches back out to the standard margin (below). */
1010.typeset--letter {
1011 page: ts-letter;
1012 --ts-base: 12pt;
1013 --ts-measure: 100%;
1014 text-align: justify;
1015 hyphens: auto;
1016}
1017@page ts-letter {
1018 margin: 35mm 35mm 35mm; /* every edge: 20mm standard + 15mm letter_inset_mm */
1019 @top-center { content: none; }
1020 @bottom-center { content: none; }
1021}
1022
1023/* Sender and address blocks are address data, not a masthead: the name line
1024 in small caps at body size, the lines below it a step smaller, so the eye
1025 finds who before where. Nothing bold, nothing in the sans, nothing larger
1026 than the text. The block is set at the detail size and its first line is
1027 raised back to body size. */
1028.typeset .ts-letter-sender {
1029 text-align: left;
1030 font-size: calc(var(--ts-base) * 0.85);
1031 line-height: 1.35;
1032 color: var(--ts-ink);
1033 margin-block: 0 calc(var(--ts-base) * 2.5);
1034}
1035.typeset .ts-letter-sender p {
1036 margin: 0;
1037 text-indent: 0;
1038}
1039
1040/* Address blocks are not prose: they are line-broken data. */
1041.typeset .ts-letter-address-block {
1042 text-align: left;
1043 font-style: normal;
1044 font-size: calc(var(--ts-base) * 0.85);
1045 line-height: 1.35;
1046 margin-bottom: calc(var(--ts-space) * 1.5);
1047}
1048.typeset .ts-letter-sender::first-line,
1049.typeset .ts-letter-address-block::first-line {
1050 font-size: var(--ts-base);
1051 font-variant-caps: all-small-caps;
1052}
1053/* Floated so it is not the block's first formatted line: the name is, and
1054 ::first-line above reaches the name rather than the label. */
1055.typeset .ts-letter-address-label {
1056 display: block;
1057 float: left;
1058 width: 100%;
1059 font-family: var(--ts-sans);
1060 font-size: var(--ts-xs);
1061 font-weight: 400;
1062 font-variant-caps: normal;
1063 letter-spacing: 0.1em;
1064 text-transform: uppercase;
1065 color: var(--ts-ink-faint);
1066 margin-bottom: 0.25em;
1067}
1068
1069/* The letterhead sits the standard margin (20mm) from the paper's edge, or at
1070 the text's own edge where that is nearer the paper. Each child of .typeset
1071 is held to the measure and centred; the address column and the crest lift
1072 that for themselves and take whichever offset from the page's text box is
1073 smaller: the measure's own centring surplus, or the standard margin less
1074 the page's margin (negative where the margin is wider, so it reaches out). */
1075.typeset { --ts-page-margin: 20mm; }
1076.typeset--margin-narrow { --ts-page-margin: 10mm; }
1077.typeset--margin-wide { --ts-page-margin: 30mm; }
1078.typeset--letter { --ts-page-margin: 35mm; } /* letter-page: 20mm standard + 15mm inset */
1079.typeset {
1080 --ts-letterhead-offset: min(
1081 calc((100% - min(var(--ts-measure-computed), 100%)) / 2),
1082 calc(20mm - var(--ts-page-margin))
1083 );
1084}
1085.typeset > .ts-letter-addresses {
1086 max-width: none;
1087 margin-inline: var(--ts-letterhead-offset) 0;
1088}
1089.typeset > .ts-letter-crest {
1090 float: right;
1091 width: 20mm;
1092 max-width: none;
1093 margin: 0 var(--ts-letterhead-offset) 0 var(--ts-space);
1094}
1095.typeset .ts-letter-crest img,
1096.typeset .ts-letter-crest svg { display: block; width: 100%; height: auto; }
1097
1098.typeset .ts-letter-date {
1099 margin-block: calc(var(--ts-base) * 3) calc(var(--ts-base) * 2);
1100 font-variant-numeric: oldstyle-nums;
1101 text-align: left;
1102}
1103
1104/* A line under the date — a dedication, a feast, a devotion. It is the date's
1105 own next line, so it climbs back over the date's whole gap and carries that
1106 gap itself. Written against the same token as the date's margin so the two
1107 cannot drift apart.
1108
1109 Deliberately not `.ts-letter-date:has(+ .ts-letter-date-note)`: Paged.js's
1110 CSS parser does not understand `:has()` any more than it understands `:is()`,
1111 and a selector it cannot parse aborts pagination outright. */
1112.typeset .ts-letter-date-note {
1113 margin-block: calc(var(--ts-base) * -2) calc(var(--ts-base) * 2);
1114 font-size: calc(var(--ts-base) * 0.9);
1115 font-style: italic;
1116 color: var(--ts-ink-muted);
1117 text-indent: 0;
1118}
1119.typeset .ts-letter-salutation { margin-block: calc(var(--ts-base) * 2); text-align: left; }
1120
1121/* A quotation in a letter is set apart by indent and colour, not by a rule. */
1122.typeset--letter blockquote,
1123.typeset .ts-letter-quote {
1124 margin: calc(var(--ts-base) * 1.5) calc(var(--ts-base) * 2);
1125 padding: 0;
1126 border: 0;
1127 font-size: calc(var(--ts-base) * 1.05);
1128 font-style: italic;
1129 font-weight: 400;
1130 color: var(--ts-ink-muted);
1131}
1132
1133.typeset .ts-letter-closing { margin-block: calc(var(--ts-base) * 3) calc(var(--ts-base) * 2); text-align: left; }
1134
1135/* The typed name, with room above it to sign. No rule: a ruled line is a form
1136 to be filled in, and this is a letter. */
1137.typeset .ts-letter-signature {
1138 text-align: left;
1139 margin-top: calc(var(--ts-base) * 3);
1140 text-indent: 0;
1141 break-inside: avoid;
1142}
1143.typeset .ts-letter-signature img { display: block; max-height: 16mm; margin-bottom: 0.2em; }
1144
1145/* Same reasoning as the postscript: "Enc." introduces a sentence, it does not
1146 head a section. Left as the only small-caps label in a letter it was the one
1147 thing on the page shouting. */
1148.typeset .ts-letter-enclosures {
1149 text-align: left;
1150 margin-top: calc(var(--ts-base) * 2);
1151 font-size: var(--ts-base);
1152 text-indent: 0;
1153}
1154/* A postscript is a sentence that happens to begin with "P.S." — the label is
1155 not a heading, so it matches the text it introduces exactly. It stands off
1156 the signature by the signature's own distance from the closing. */
1157.typeset .ts-letter-postscript {
1158 text-align: left;
1159 margin-top: calc(var(--ts-base) * 3);
1160 font-size: var(--ts-base);
1161 text-indent: 0;
1162}
1163/*! @e */
1164
1165/*! @s two-column :: Two column, equal */
1166/* Papers, journal articles, newsletters, technical notes — documents scanned
1167 and referenced as much as read.
1168
1169 The base size drops to 9.5pt here, and that is arithmetic rather than taste:
1170 an 82mm column carries 42 characters at 11pt, below the 45-character floor
1171 this stylesheet sets for a line of prose. 9.5pt restores 49. An
1172 implementation that keeps 11pt in two columns breaks the measure rule, which
1173 is the rule everything else is downstream of. */
1174.typeset--two-column {
1175 /* Every step comes down. A 24pt heading in an 82mm column spends three lines
1176 saying two words. */
1177 --ts-xs: 7pt;
1178 --ts-sm: 8.5pt;
1179 --ts-base: 9.5pt;
1180 --ts-h4: 9.5pt;
1181 --ts-h3: 11pt;
1182 --ts-h2: 13pt;
1183 --ts-h1: 20pt;
1184
1185 /* Leading tightens with the measure: a shorter line needs less separation to
1186 keep the return sweep unambiguous. */
1187 --ts-leading: 1.4;
1188 --ts-space: 9.5pt;
1189
1190 /* The column IS the measure, so the character cap comes off. */
1191 --ts-measure: none;
1192 --ts-column-gap: 6mm;
1193
1194 /* A blank line costs 3% of a column, so paragraphs indent here by default —
1195 not as an option. */
1196 --ts-para-gap: 0;
1197 --ts-para-indent: 1.25em;
1198
1199 font-size: var(--ts-base);
1200 columns: 2;
1201 column-gap: var(--ts-column-gap);
1202 column-fill: balance; /* the final page balances its columns */
1203
1204 /* Justification with hyphenation is MANDATORY at this measure, not optional:
1205 at 49 characters a ragged edge serrates the column and the word gaps read
1206 as rivers. This is the one place the stylesheet removes a choice. */
1207 text-align: justify;
1208 text-align-last: left;
1209 hyphens: auto;
1210 hyphenate-limit-chars: 6 3 3;
1211 hyphenate-limit-lines: 2;
1212}
1213
1214/* Spans both columns, always — templates.two-column.spanning.always in
1215 spec.json, unmarked. Each is a direct child of the multicol container,
1216 which is what column-span requires. */
1217.typeset--two-column > .ts-frontmatter-title-block,
1218.typeset--two-column > .ts-frontmatter-subtitle,
1219.typeset--two-column > .ts-frontmatter-byline,
1220.typeset--two-column > .ts-frontmatter-dateline,
1221.typeset--two-column > .ts-frontmatter-abstract,
1222.typeset--two-column > h1,
1223.typeset--two-column > .ts-bibliography-heading,
1224.typeset--two-column > .ts-frontmatter-colophon,
1225.typeset--two-column > .ts-span {
1226 column-span: all;
1227}
1228
1229/* Spanning is opt-in per instance for figures and tables: it costs a break in
1230 both columns, so the default stays column-width. A spanning element must sit
1231 at the top or the bottom of the page, never mid-column. */
1232.typeset--two-column > .ts-span {
1233 break-before: avoid-column;
1234 margin-bottom: calc(var(--ts-space) * 1.5);
1235}
1236
1237/* An optional hairline where the columns need separating. Most journals omit
1238 it — the gutter is already doing the work. */
1239.typeset--two-column.typeset--column-rule {
1240 column-rule: 0.5pt solid var(--ts-rule);
1241}
1242
1243/* A sidenote has no margin to live in here. Rather than let it be positioned
1244 off the page and silently lost, it degrades to an inline aside. */
1245.typeset--two-column .ts-note-sidenote {
1246 position: static;
1247 display: block;
1248 width: auto;
1249 margin: 0.4em 0;
1250 padding-left: 0.6em;
1251 border-left: 0.5pt solid var(--ts-rule);
1252 text-indent: 0;
1253}
1254
1255/* A three-line cap at 3.05em is 29pt — 10mm of the column given to one
1256 letter. The opening small caps carry the signal instead. */
1257.typeset--two-column .ts-dropcap::first-letter {
1258 float: none;
1259 font-size: inherit;
1260 line-height: inherit;
1261 color: inherit;
1262 padding: 0;
1263}
1264
1265/* Denser matter for a narrower column. */
1266.typeset--two-column blockquote { font-size: 9pt; padding-left: var(--ts-space); }
1267.typeset--two-column table { font-size: 8pt; line-height: 1.3; }
1268.typeset--two-column pre { font-size: 7.5pt; }
1269.typeset--two-column figcaption { font-size: 8pt; }
1270.typeset--two-column .ts-note-endnotes { font-size: 8.5pt; }
1271.typeset--two-column .ts-quote-pullquote { font-size: 12pt; }
1272.typeset--two-column .ts-frontmatter-abstract { font-size: 9pt; max-width: none; }
1273.typeset--two-column .ts-quote-epigraph { max-width: none; }
1274/*! @e */
1275
1276/*! @s utility :: Pagination utilities */
1277.ts-utility-break-before { break-before: page; }
1278.ts-utility-break-after { break-after: page; }
1279.ts-utility-keep-together { break-inside: avoid; page-break-inside: avoid; }
1280.ts-utility-no-hyphens { hyphens: manual; }
1281
1282/* Non-breaking spaces belong in the markup, but these catch the common cases:
1283 a figure and its unit, an initial and a surname. */
1284.ts-utility-tie { white-space: nowrap; }
1285
1286/* @style utility-print-only — names the pair: this block and the .ts-print-only block right below it. */
1287@media print {
1288 .ts-screen-only { display: none !important; }
1289}
1290@media screen {
1291 .ts-print-only { display: none !important; }
1292}
1293
1294/* Force backgrounds and rules to survive the print dialog's ink-saving. */
1295/* @style utility-color-adjust */
1296@media print {
1297 .typeset,
1298 .typeset * {
1299 -webkit-print-color-adjust: exact;
1300 print-color-adjust: exact;
1301 }
1302}
1303/*! @e */