├── .gitignore ├── LICENSE ├── README.md ├── img ├── antique-preview.gif ├── antique.png ├── classical-humanist-preview.gif ├── classical-humanist.png ├── didone-preview.gif ├── didone.png ├── geometric-humanist-preview.gif ├── geometric-humanist.png ├── handwritten-preview.gif ├── handwritten.png ├── humanist-preview.gif ├── humanist.png ├── industrial-preview.gif ├── industrial.png ├── logo-mfs.svg ├── monospace-code-preview.gif ├── monospace-code.png ├── monospace-slab-serif-preview.gif ├── monospace-slab-serif.png ├── neo-grotesque-preview.gif ├── neo-grotesque.png ├── old-style-preview.gif ├── old-style.png ├── rounded-sans-preview.gif ├── rounded-sans.png ├── slab-serif-preview.gif ├── slab-serif.png ├── system-ui-preview.gif ├── system-ui.png ├── transitional-preview.gif └── transitional.png └── site ├── README.md ├── package-lock.json ├── package.json └── src ├── _scripts.js ├── _styles.css ├── favicon.png ├── img ├── og-modernfontstacks.png └── white-rabbit.png ├── index.html └── robots.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .nova 3 | site/dist 4 | site/node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Modern Font Stacks 4 | 5 |

6 | 7 |

Modern Font Stacks

8 |

System font stack CSS organized by typeface classification for every modern OS

9 | 10 |

The fastest fonts available. No downloading, no layout shifts, no flashes — just instant renders.

11 | 12 |
13 |
14 |

15 | System UI  ·  16 | Transitional  ·  17 | Old Style  ·  18 | Humanist  ·  19 | Geometric Humanist 20 |

21 |

22 | Classical Humanist  ·  23 | Neo-Grotesque  ·  24 | Monospace Slab Serif  ·  25 | Monospace Code 26 |

27 |

28 | Industrial  ·  29 | Rounded Sans  ·  30 | Slab Serif  ·  31 | Antique  ·  32 | Didone  ·  33 | Handwritten 34 |

35 |
36 |

37 |
38 | Additional Features   /   39 | Operating System Support   /   40 | Plugins and Extensions 41 |

42 |
43 | 44 | ## System UI 45 | 46 | System UI fonts are those native to the operating system interface. They are highly legible and easy to read at small sizes, contains many font weights, and is ideal for UI elements. 47 | 48 | #### CSS Font Stack 49 | ```css 50 | font-family: system-ui, sans-serif; 51 | ``` 52 | 53 | System UI Font Stack 54 | 55 |    💻 **[View in Your Browser](https://modernfontstacks.com/?stack=system-ui) ([Article View](https://modernfontstacks.com/?stack=system-ui#article-view) / [Characters](https://modernfontstacks.com/?stack=system-ui#characters))** 56 | 57 |
58 | 🎥 Preview Rendering Across Operating Systems 59 | System UI Font Rendering 60 |
61 | 62 |
63 | ✅ Font Weights & Notes 64 | 65 |
66 | 67 | | Font Weights | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 68 | |:----------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 69 | | San Francisco | ● | ● | ● | ● | ● | ● | ● | ● | ● | 70 | | Segoe UI | ● | ● | ● | ● | ● | ● | ● | ● | ● | 71 | | Roboto | ● | ● | ● | ● | ● | ● | ● | ● | ● | 72 | | Ubuntu | ● | | ● | ● | ● | | ● | | | 73 | | Cantarell | ● | | ● | ● | | | ● | ● | | 74 | | Noto Sans | ● | ● | ● | ● | ● | ● | ● | ● | ● | 75 | 76 | #### Notes 77 | - System UI is less of a font stack and more of a CSS value, `system-ui`, representing the default user interface font. It is [widely supported](https://caniuse.com/font-family-system-ui) on all modern operating systems. 78 | - The fonts shown are the default fonts for UI in each modern OS. 79 | 80 |
81 | 82 |

Back to Top ↑

83 | 84 | 85 | ## Transitional 86 | 87 | Transitional typefaces are a mix between Old Style and Modern typefaces that was developed during The Enlightenment. One of the most famous examples of a Transitional typeface is Times New Roman, which was developed for the Times of London newspaper. 88 | 89 | #### CSS Font Stack 90 | ```css 91 | font-family: Charter, 'Bitstream Charter', 'Sitka Text', Cambria, serif; 92 | ``` 93 | 94 | Transitional Font Stack 95 | 96 |    💻 **[View in Your Browser](https://modernfontstacks.com/?stack=transitional) ([Article View](https://modernfontstacks.com/?stack=transitional#article-view) / [Characters](https://modernfontstacks.com/?stack=transitional#characters))** 97 | 98 |
99 | 🎥 Preview Rendering Across Operating Systems 100 | Transitional Font Rendering 101 |
102 | 103 |
104 | ✅ Font Weights & Notes 105 | 106 |
107 | 108 | | Font Weights | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 109 | |:----------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 110 | | Charter | | | | ● | | | ● | | ● | 111 | | Bitstream Charter | | | | ● | | | ● | | | 112 | | Sitka Text | | | | ● | | | ● | | | 113 | | Cambria | | | | ● | | | ● | | | 114 | | Noto Serif¹ | | | | ● | | | ● | | | 115 | 116 | 117 | #### Notes 118 | - [Charter](https://practicaltypography.com/charter.html) is a fantastic and timeless typeface designed by Matthew Carter in 1987 for low-resolution 300dpi fax machines and laser printers. It has a large x-height helping with readability, and holds up beautifully on today's screens. 119 | - Charter for macOS has an [odd wide non-breaking space](https://github.com/system-fonts/modern-font-stacks/issues/12#issuecomment-1716229190) (` `). This bug has been reported to Apple. 120 | - [Sitka](https://learn.microsoft.com/en-us/typography/font-list/sitka) is another beautiful typeface designed by Matthew Carter that slightly resembles Charter. Sitka was designed in collaboration [Microsoft's Advanced Reading Technologies](https://www.microsoft.com/en-us/research/uploads/prod/2021/06/Larson-Carter-2015-Sitka.pdf) to optimize readability. 121 | - Android uses Noto Serif as its default `serif` font, so no need to specify in the stack. 122 | 123 |
124 | 125 |

Back to Top ↑

126 | 127 | 128 | ## Old Style 129 | 130 | Old Style typefaces are characterized by diagonal stress, low contrast between thick and thin strokes, and rounded serifs, and were developed in the Renaissance period. One of the most famous examples of an Old Style typeface is Garamond. 131 | 132 | #### CSS Font Stack 133 | ```css 134 | font-family: 'Iowan Old Style', 'Palatino Linotype', 'URW Palladio L', P052, serif; 135 | ``` 136 | 137 | Old Style Font Stack 138 | 139 |    💻 **[View in Your Browser](https://modernfontstacks.com/?stack=old-style) ([Article View](https://modernfontstacks.com/?stack=old-style#article-view) / [Characters](https://modernfontstacks.com/?stack=old-style#characters))** 140 | 141 |
142 | 🎥 Preview Rendering Across Operating Systems 143 | Old Style Font Rendering 144 |
145 | 146 |
147 | ✅ Font Weights & Notes 148 | 149 |
150 | 151 | | Font Weights | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 152 | |:----------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 153 | | Iowan Old Style | | | | ● | | | ● | | ● | 154 | | Palatino Linotype | | | | ● | | | ● | | | 155 | | URW Palladio L | | | | ● | | | ● | | | 156 | | P052 | | | | ● | | | ● | | | 157 | | Noto Serif¹ | | | | ● | | | ● | | | 158 | 159 | 160 | #### Notes 161 | - Android uses Noto Serif as its default `serif` font, so no need to specify in the stack. 162 | 163 |
164 | 165 |

Back to Top ↑

166 | 167 | 168 | ## Humanist 169 | 170 | Humanist typefaces are characterized by their organic, calligraphic forms and low contrast between thick and thin strokes. These typefaces are inspired by the handwriting of the Renaissance period and are often considered to be more legible and easier to read than other sans-serif typefaces. 171 | 172 | #### CSS Font Stack 173 | ```css 174 | font-family: Seravek, 'Gill Sans Nova', Ubuntu, Calibri, 'DejaVu Sans', source-sans-pro, sans-serif; 175 | ``` 176 | 177 | Humanist Font Stack 178 | 179 |    💻 **[View in Your Browser](https://modernfontstacks.com/?stack=humanist) ([Article View](https://modernfontstacks.com/?stack=humanist#article-view) / [Characters](https://modernfontstacks.com/?stack=humanist#characters))** 180 | 181 |
182 | 🎥 Preview Rendering Across Operating Systems 183 | Humanist Font Rendering 184 |
185 | 186 |
187 | ✅ Font Weights & Notes 188 | 189 |
190 | 191 | | Font Weights | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 192 | |:----------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 193 | | Seravek | | ● | ● | ● | ● | | ● | | | 194 | | Gill Sans Nova | | | ● | ● | | | ● | ● | | 195 | | Ubuntu | ● | | ● | ● | ● | | ● | | | 196 | | Calibri | | | ● | ● | | | ● | | | 197 | | DejaVu Sans | ● | | | ● | | | ● | | | 198 | | Source Sans Pro | | | | ● | | ● | ● | | | 199 | 200 | #### Notes 201 | - [Gill Sans Nova](https://apps.microsoft.com/store/detail/gill-sans-nova/9PK93BG0Z1JJ) is available as a supplemental downloadable font. 202 | - Source Sans Pro uses name [source-sans-pro](https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/fonts.xml#263) under Android, so this font only targets Android devices. 203 | 204 |
205 | 206 |

Back to Top ↑

207 | 208 | 209 | ## Geometric Humanist 210 | 211 | Geometric Humanist typefaces are characterized by their clean, geometric forms and uniform stroke widths. These typefaces are often considered to be modern and sleek in appearance, and are often used for headlines and other display purposes. Futura is a famous example of this classification. 212 | 213 | #### CSS Font Stack 214 | ```css 215 | font-family: Avenir, Montserrat, Corbel, 'URW Gothic', source-sans-pro, sans-serif; 216 | ``` 217 | 218 | Geometric Humanist Font Stack 219 | 220 |    💻 **[View in Your Browser](https://modernfontstacks.com/?stack=geometric-humanist) ([Article View](https://modernfontstacks.com/?stack=geometric-humanist#article-view) / [Characters](https://modernfontstacks.com/?stack=geometric-humanist#characters))** 221 | 222 | 223 |
224 | 🎥 Preview Rendering Across Operating Systems 225 | Geometric Humanist Font Rendering 226 |
227 | 228 |
229 | ✅ Font Weights & Notes 230 | 231 |
232 | 233 | | Font Weights | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 234 | |:----------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 235 | | Avenir | | | ● | ● | ● | | | ● | ● | 236 | | Montserrat | ● | ● | ● | ● | ● | ● | ● | ● | ● | 237 | | Corbel | | | ● | ● | | | ● | | | 238 | | URW Gothic | | | ● | | | ● | | | | 239 | | Source Sans Pro | | | | ● | | ● | ● | | | 240 | 241 | #### Notes 242 | - Avenir was chosen over Avenir Next for macOS because the weight 300 is much more legible on the web over the 200 weight that Avenir Next has. If you're looking for an ultra-light or ultra-black, feel free to swap Avenir for Avenir Next. 243 | - Source Sans Pro uses name [source-sans-pro](https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/fonts.xml#263) under Android, so this font only targets Android devices. 244 | 245 |
246 | 247 |

Back to Top ↑

248 | 249 | 250 | ## Classical Humanist 251 | 252 | Classical Humanist typefaces are characterized by how the strokes subtly widen as they reach the stroke terminals without ending in a serif. These typefaces are inspired by classical Roman capitals and the stone-carving on Renaissance-period tombstones. 253 | 254 | #### CSS Font Stack 255 | ```css 256 | font-family: Optima, Candara, 'Noto Sans', source-sans-pro, sans-serif; 257 | ``` 258 | 259 | Classical Humanist Font Stack 260 | 261 | 262 |    💻 **[View in Your Browser](https://modernfontstacks.com/?stack=classical-humanist) ([Article View](https://modernfontstacks.com/?stack=classical-humanist#article-view) / [Characters](https://modernfontstacks.com/?stack=classical-humanist#characters))** 263 | 264 |
265 | 🎥 Preview Rendering Across Operating Systems 266 | Classical Humanist Font Rendering 267 |
268 | 269 |
270 | ✅ Font Weights & Notes 271 | 272 |
273 | 274 | | Font Weights | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 275 | |:----------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 276 | | Optima | | | | ● | | | ● | | ● | 277 | | Candara | | | ● | ● | | | ● | | | 278 | | Noto Sans | ● | ● | ● | ● | ● | ● | ● | ● | ● | 279 | | Source Sans Pro | | | | ● | | ● | ● | | | 280 | 281 | #### Notes 282 | - Source Sans Pro uses name [source-sans-pro](https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/fonts.xml#263) under Android, so this font only targets Android devices. 283 | 284 |
285 | 286 |

Back to Top ↑

287 | 288 | 289 | ## Neo-Grotesque 290 | 291 | Neo-Grotesque typefaces are a style of sans-serif that was developed in the late 19th and early 20th centuries and is characterized by its clean, geometric forms and uniform stroke widths. One of the most famous examples of a Neo-Grotesque typeface is Helvetica. 292 | 293 | #### CSS Font Stack 294 | ```css 295 | font-family: Inter, Roboto, 'Helvetica Neue', 'Arial Nova', 'Nimbus Sans', Arial, sans-serif; 296 | ``` 297 | 298 | Neo-Grotesque Font Stack 299 | 300 |    💻 **[View in Your Browser](https://modernfontstacks.com/?stack=neo-grotesque) ([Article View](https://modernfontstacks.com/?stack=neo-grotesque#article-view) / [Characters](https://modernfontstacks.com/?stack=neo-grotesque#characters))** 301 | 302 |
303 | 🎥 Preview Rendering Across Operating Systems 304 | Neo-Grotesque Font Rendering 305 |
306 | 307 |
308 | ✅ Font Weights & Notes 309 | 310 |
311 | 312 | | Font Weights | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 313 | |:----------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 314 | | Inter | ● | ● | ● | ● | ● | ● | ● | ● | ● | 315 | | Roboto | ● | ● | ● | ● | ● | ● | ● | ● | ● | 316 | | Helvetica Neue | ● | ● | ● | ● | ● | ● | ● | | | 317 | | Arial Nova | | | ● | ● | | | ● | | | 318 | | Nimbus Sans | | | | ● | | ● | ● | | | 319 | | Arial | | | | ● | | ● | ● | | | 320 | 321 | #### Notes 322 | - [Arial Nova](https://apps.microsoft.com/store/detail/arial-nova/9NS5CT1MZ7M8) is available as a supplemental downloadable font. 323 | - Roboto is used for Linux (MX Linux, ElementaryOS, etc) and manual installs. It will not render Roboto on Android, but [Android's generic sans-serif](https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/fonts.xml#26) will. 324 | 325 | 326 |
327 | 328 |

Back to Top ↑

329 | 330 | 331 | ## Monospace Slab Serif 332 | 333 | Monospace Slab Serif typefaces are characterized by their fixed-width letters, which have the same width regardless of their shape, and its simple, geometric forms. Used to emulate typewriter output for reports, tabular work and technical documentation. 334 | 335 | #### CSS Font Stack 336 | ```css 337 | font-family: 'Nimbus Mono PS', 'Courier New', monospace; 338 | ``` 339 | 340 | Monospace Slab Serif Font Stack 341 | 342 |    💻 **[View in Your Browser](https://modernfontstacks.com/?stack=monospace-slab-serif) ([Article View](https://modernfontstacks.com/?stack=monospace-slab-serif#article-view) / [Characters](https://modernfontstacks.com/?stack=monospace-slab-serif#characters))** 343 | 344 |
345 | 🎥 Preview Rendering Across Operating Systems 346 | Monospace Slab Serif Font Rendering 347 |
348 | 349 |
350 | ✅ Font Weights & Notes 351 | 352 |
353 | 354 | | Font Weights | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 355 | |:----------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 356 | | Nimbus Mono PS | | | | ● | | | ● | | | 357 | | Courier New | | | | ● | | | ● | | | 358 | | Cutive Mono | | | | ● | | | | | | 359 | 360 | #### Notes 361 | - Nimbus Mono PS is specified first because many Linux distros create name alias for Courier New and not always represent a slab serif 362 | - Cutive Mono doesn't need to be represented in the stack as Android creates a name alias for Courier New. 363 | - Cutive Mono unfortunately only has one weight 364 | 365 | 366 |
367 | 368 |

Back to Top ↑

369 | 370 | 371 | ## Monospace Code 372 | 373 | Monospace Code typefaces are specifically designed for use in programming and other technical applications. These typefaces are characterized by their monospaced design, which means that all letters and characters have the same width, and their clear, legible forms. 374 | 375 | 376 | #### CSS Font Stack 377 | ```css 378 | font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace; 379 | ``` 380 | 381 | Monospace Code Font Stack 382 | 383 |    💻 **[View in Your Browser](https://modernfontstacks.com/?stack=monospace-code) ([Article View](https://modernfontstacks.com/?stack=monospace-code#article-view) / [Characters](https://modernfontstacks.com/?stack=monospace-code#characters))** 384 | 385 |
386 | 🎥 Preview Rendering Across Operating Systems 387 | Monospace Code Font Rendering 388 |
389 | 390 |
391 | ✅ Font Weights & Notes 392 | 393 |
394 | 395 | | Font Weights | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 396 | |:----------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 397 | | SF Mono | | | ● | ● | ● | ● | ● | ● | | 398 | | Cascadia Code | ● | ● | ● | ● | | ● | ● | | | 399 | | Source Code Pro | | ● | ● | ● | ● | ● | ● | ● | | 400 | | Menlo | | | | ● | | | ● | | | 401 | | Consolas | | | | ● | | | ● | | | 402 | | DejaVu Sans Mono | | | | ● | | | ● | | | 403 | | Droid Sans Mono | | | | ● | | | | | | 404 | 405 | #### Notes 406 | - SF Mono is [only available](https://caniuse.com/extended-system-fonts) via `ui-monospace` on macOS 10.15+ and iOS 13.3+ while using Safari 407 | - Droid Sans Mono for Android does not need to be specified in the stack as `monospace` is a name alias for it 408 | 409 |
410 | 411 |

Back to Top ↑

412 | 413 | 414 | ## Industrial 415 | 416 | Industrial typefaces originated in the late 19th century and was heavily influenced by the advancements in technology and industry during that time. Industrial typefaces are characterized by their bold, sans-serif letterforms, simple and straightforward appearance, and the use of straight lines and geometric shapes. 417 | 418 | 419 | #### CSS Font Stack 420 | ```css 421 | font-family: Bahnschrift, 'DIN Alternate', 'Franklin Gothic Medium', 'Nimbus Sans Narrow', sans-serif-condensed, sans-serif; 422 | ``` 423 | 424 | Industrial Font Stack 425 | 426 |    💻 **[View in Your Browser](https://modernfontstacks.com/?stack=industrial) ([Article View](https://modernfontstacks.com/?stack=industrial#article-view) / [Characters](https://modernfontstacks.com/?stack=industrial#characters))** 427 | 428 |
429 | 🎥 Preview Rendering Across Operating Systems 430 | Industrial Font Rendering 431 |
432 | 433 |
434 | ✅ Font Weights & Notes 435 | 436 |
437 | 438 | | Font Weights | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 439 | |:------------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 440 | | Bahnschrift | ● | ● | ● | ● | ● | ● | ● | ● | ● | 441 | | DIN Alternate | | | | | | | ● | | | 442 | | Franklin Gothic Medium | | | | | ● | | | | | 443 | | Nimbus Sans Narrow | | | | ● | | | ● | | | 444 | | Roboto Condensed | ● | ● | ● | ● | ● | ● | ● | ● | ● | 445 | 446 | #### Notes 447 | - Since this stack is limited on weights across operating systems, it's best to use as a Medium/Bold display font 448 | - Bahnschrift is one of the first [variable font](https://learn.microsoft.com/en-us/typography/font-list/bahnschrift) added to Windows. 449 | - Roboto Condensed uses name [sans-serif-condensed](https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/fonts.xml#126) under Android, so this font only targets Android devices. 450 | 451 |
452 | 453 |

Back to Top ↑

454 | 455 | 456 | ## Rounded Sans 457 | 458 | Rounded typefaces are characterized by the rounded curved letterforms and give a softer, friendlier appearance. The rounded edges give the typeface a more organic and playful feel, making it suitable for use in informal or child-friendly designs. The rounded sans-serif style has been popular since the 1950s, and it continues to be widely used in advertising, branding, and other forms of graphic design. 459 | 460 | 461 | #### CSS Font Stack 462 | ```css 463 | font-family: ui-rounded, 'Hiragino Maru Gothic ProN', Quicksand, Comfortaa, Manjari, 'Arial Rounded MT', 'Arial Rounded MT Bold', Calibri, source-sans-pro, sans-serif; 464 | ``` 465 | 466 | Rounded Sans Font Stack 467 | 468 |    💻 **[View in Your Browser](https://modernfontstacks.com/?stack=rounded-sans) ([Article View](https://modernfontstacks.com/?stack=rounded-sans#article-view) / [Characters](https://modernfontstacks.com/?stack=rounded-sans#characters))** 469 | 470 |
471 | 🎥 Preview Rendering Across Operating Systems 472 | Rounded Sans Font Rendering 473 |
474 | 475 |
476 | ✅ Font Weights & Notes 477 | 478 |
479 | 480 | | Font Weights | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 481 | |:------------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 482 | | SF Pro Rounded | ● | ● | ● | ● | ● | ● | ● | ● | ● | 483 | | Hiragino Maru Gothic | | | | ● | | | | | | 484 | | Quicksand | | | ● | ● | | | ● | | | 485 | | Comfortaa | | | ● | ● | | | ● | | | 486 | | Manjari | ● | | | ● | | | ● | | | 487 | | Arial Rounded MT | | | | | | | ● | | | 488 | | Arial Rounded MT Bold | | | | | | | ● | | | 489 | | Calibri | | | ● | ● | | | ● | | | 490 | | Source Sans Pro | | | | ● | | ● | ● | | | 491 | 492 | #### Notes 493 | - SF Pro Rounded is [only available](https://caniuse.com/extended-system-fonts) via `ui-rounded` on macOS 10.15+ and iOS 13.3+ while using Safari 494 | - Hiragino Maru Gothic is technically a Japanese typeface but has support for all the latin characters. The Mac font does not include a bold so a faux bold will be displayed on screen. 495 | - Arial Rounded MT is needed for Windows, while Arial Rounded MT Bold is needed for iOS, Mac, and older Windows installs 496 | - Source Sans Pro uses name [source-sans-pro](https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/fonts.xml#263) under Android, so this font only targets Android devices. It's not a rounded typeface, but it's better than Roboto here. 497 | 498 | 499 |
500 | 501 |

Back to Top ↑

502 | 503 | 504 | ## Slab Serif 505 | 506 | Slab Serif typefaces are characterized by the presence of thick, block-like serifs on the ends of each letterform. These serifs are usually unbracketed, meaning they do not have any curved or tapered transitions to the main stroke of the letter. 507 | 508 | 509 | #### CSS Font Stack 510 | ```css 511 | font-family: Rockwell, 'Rockwell Nova', 'Roboto Slab', 'DejaVu Serif', 'Sitka Small', serif; 512 | ``` 513 | 514 | Slab Serif Font Stack 515 | 516 |    💻 **[View in Your Browser](https://modernfontstacks.com/?stack=slab-serif) ([Article View](https://modernfontstacks.com/?stack=slab-serif#article-view) / [Characters](https://modernfontstacks.com/?stack=slab-serif#characters))** 517 | 518 |
519 | 🎥 Preview Rendering Across Operating Systems 520 | Slab Serif Font Rendering 521 |
522 | 523 |
524 | ✅ Font Weights & Notes 525 | 526 |
527 | 528 | | Font Weights | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 529 | |:------------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 530 | | Rockwell | | | | ● | | | ● | | | 531 | | Rockwell Nova | | | ● | ● | | | ● | ● | | 532 | | Roboto Slab | ● | | ● | ● | | | ● | | | 533 | | DejaVu Serif | | | | ● | | | ● | | | 534 | | Sitka Small | | | | ● | | | ● | | | 535 | | Noto Serif | | | | ● | | | ● | | | 536 | 537 | 538 | #### Notes 539 | - [Rockwell](https://learn.microsoft.com/en-us/typography/font-list/rockwell) is included with Windows Office 540 | - [Rockwell Nova](https://apps.microsoft.com/store/detail/arial-nova/9NS5CT1MZ7M8) is available as a supplemental downloadable font. 541 | - Android uses Noto Serif as its default `serif` font, so no need to specify in the stack. 542 | 543 |
544 | 545 |

Back to Top ↑

546 | 547 | 548 | ## Antique 549 | 550 | Antique typefaces, also known as Egyptians, are a subset of serif typefaces that were popular in the 19th century. They are characterized by their block-like serifs and thick uniform stroke weight. 551 | 552 | #### CSS Font Stack 553 | ```css 554 | font-family: Superclarendon, 'Bookman Old Style', 'URW Bookman', 'URW Bookman L', 'Georgia Pro', Georgia, serif; 555 | ``` 556 | 557 | Antique Font Stack 558 | 559 |    💻 **[View in Your Browser](https://modernfontstacks.com/?stack=antique) ([Article View](https://modernfontstacks.com/?stack=antique#article-view) / [Characters](https://modernfontstacks.com/?stack=antique#characters))** 560 | 561 |
562 | 🎥 Preview Rendering Across Operating Systems 563 | Antique Font Rendering 564 |
565 | 566 |
567 | ✅ Font Weights & Notes 568 | 569 |
570 | 571 | | Font Weights | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 572 | |:------------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 573 | | Superclarendon | | | ● | ● | | | ● | | ● | 574 | | Bookman Old Style | | | | ● | | | ● | | | 575 | | URW Bookman | | | ● | | | ● | | | | 576 | | Georgia Pro | | | ● | ● | | ● | ● | | ● | 577 | | Georgia | | | | ● | | | ● | | | 578 | | Noto Serif¹ | | | | ● | | | ● | | | 579 | 580 | 581 | #### Notes 582 | - [Georgia Pro](https://apps.microsoft.com/store/detail/georgia-pro/9N9DZG1XT2MB) is available as a supplemental downloadable font. 583 | - Android uses Noto Serif as alias for `Georgia`, so no need to specify in the stack. 584 | 585 |
586 | 587 |

Back to Top ↑

588 | 589 | 590 | ## Didone 591 | 592 | Didone typefaces, also known as Modern typefaces, are characterized by the high contrast between thick and thin strokes, vertical stress, and hairline serifs with no bracketing. The Didone style emerged in the late 18th century and gained popularity during the 19th century. 593 | 594 | 595 | #### CSS Font Stack 596 | ```css 597 | font-family: Didot, 'Bodoni MT', 'Noto Serif Display', 'URW Palladio L', P052, Sylfaen, serif; 598 | ``` 599 | 600 | Didone Font Stack 601 | 602 |    💻 **[View in Your Browser](https://modernfontstacks.com/?stack=didone) ([Article View](https://modernfontstacks.com/?stack=didone#article-view) / [Characters](https://modernfontstacks.com/?stack=didone#characters))** 603 | 604 |
605 | 🎥 Preview Rendering Across Operating Systems 606 | Didone Font Rendering 607 |
608 | 609 |
610 | ✅ Font Weights & Notes 611 | 612 |
613 | 614 | | Font Weights | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 615 | |:------------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 616 | | Didot | | | | ● | | | ● | | | 617 | | Bodoni MT | | | | ● | | | ● | | ● | 618 | | Noto Serif Display | ● | ● | ● | ● | ● | ● | ● | ● | ● | 619 | | URW Palladio L | | | | ● | | | ● | | | 620 | | P052 | | | | ● | | | ● | | | 621 | | Sylfaen | | | | ● | | | | | | 622 | | Noto Serif¹ | | | | ● | | | ● | | | 623 | 624 | 625 | #### Notes 626 | - Android uses Noto Serif as its default `serif` font, so no need to specify in the stack. 627 | - Sylfaen does not include a bold so a faux bold will be displayed on screen. 628 | 629 |
630 | 631 |

Back to Top ↑

632 | 633 | 634 | ## Handwritten 635 | 636 | Handwritten typefaces are designed to mimic the look and feel of handwriting. Despite the vast array of handwriting styles, this font stack tend to adopt a more informal and everyday style of handwriting. 637 | 638 | #### CSS Font Stack 639 | ```css 640 | font-family: 'Segoe Print', 'Bradley Hand', Chilanka, TSCu_Comic, casual, cursive; 641 | ``` 642 | 643 | Handwritten Font Stack 644 | 645 |    💻 **[View in Your Browser](https://modernfontstacks.com/?stack=handwritten) ([Article View](https://modernfontstacks.com/?stack=handwritten#article-view) / [Characters](https://modernfontstacks.com/?stack=handwritten#characters))** 646 | 647 |
648 | 🎥 Preview Rendering Across Operating Systems 649 | Handwritten Font Rendering 650 |
651 | 652 |
653 | ✅ Font Weights & Notes 654 | 655 |
656 | 657 | | Font Weights | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 658 | |:------------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| 659 | | Segoe Print | | | | ● | | | ● | | | 660 | | Bradley Hand | | | | | | | ● | | | 661 | | Chilanka | | | | ● | | | | | | 662 | | TSCu_Comic | | | | ● | | | | | | 663 | | Coming Soon | | | | ● | | | | | | 664 | 665 | 666 | #### Notes 667 | - Coming Soon uses name [casual](https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/fonts.xml#249) under Android, so this font only targets Android devices. 668 | 669 |
670 | 671 |

Back to Top ↑

672 | 673 | 674 | ## Additional Features 675 | 676 | #### Emoji Support 677 | 678 | Looking to add native emojis to your page? Append these fonts at the end of your font stack: 679 | 680 | ```css 681 | 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji' 682 | ``` 683 | 684 | #### Anti-Aliasing 685 | 686 | Render your text with anti-aliasing by using these CSS properties: 687 | 688 | ```css 689 | html { 690 | -webkit-font-smoothing: antialiased; 691 | -moz-osx-font-smoothing: grayscale; 692 | } 693 | ``` 694 | 695 |
696 | 697 | ## Operating System Support 698 | - [Windows 7 or newer](https://learn.microsoft.com/en-us/typography/fonts/windows_7_font_list) 699 | - [Android 10 or newer](https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/fonts.xml) (Very limited with 8 fonts) 700 | - [iOS 9.3 or newer](https://developer.apple.com/fonts/system-fonts/) 701 | - [macOS 10.9 (Mavericks) or newer](https://support.apple.com/en-us/HT201375) 702 | - [Linux](https://docs.google.com/spreadsheets/d/1kbxC3UyGTzpA9aOEJD-GYH0uHTops5VSEb8jKKD9Wwc/edit?usp=sharing) (Sampled 12 popular distros) 703 | 704 |

Back to Top ↑

705 | 706 | 707 | ## Plugins and Extensions 708 | - [Modern Font Stacks for Tailwind CSS](https://github.com/BorisAnthony/mfs-tailwind) by [BorisAnthony](https://github.com/BorisAnthony) 709 | - [Modern Font Stacks for WordPress](https://github.com/LittleBigThing/Modern-Font-Stacks-for-WP) by [LittleBigThing](https://github.com/LittleBigThing) 710 | - Modern Font Stacks are supported natively by [Webstudio](http://github.com/webstudio-is/webstudio/) 711 | 712 |

Back to Top ↑

713 | -------------------------------------------------------------------------------- /img/antique-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/antique-preview.gif -------------------------------------------------------------------------------- /img/antique.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/antique.png -------------------------------------------------------------------------------- /img/classical-humanist-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/classical-humanist-preview.gif -------------------------------------------------------------------------------- /img/classical-humanist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/classical-humanist.png -------------------------------------------------------------------------------- /img/didone-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/didone-preview.gif -------------------------------------------------------------------------------- /img/didone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/didone.png -------------------------------------------------------------------------------- /img/geometric-humanist-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/geometric-humanist-preview.gif -------------------------------------------------------------------------------- /img/geometric-humanist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/geometric-humanist.png -------------------------------------------------------------------------------- /img/handwritten-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/handwritten-preview.gif -------------------------------------------------------------------------------- /img/handwritten.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/handwritten.png -------------------------------------------------------------------------------- /img/humanist-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/humanist-preview.gif -------------------------------------------------------------------------------- /img/humanist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/humanist.png -------------------------------------------------------------------------------- /img/industrial-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/industrial-preview.gif -------------------------------------------------------------------------------- /img/industrial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/industrial.png -------------------------------------------------------------------------------- /img/logo-mfs.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /img/monospace-code-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/monospace-code-preview.gif -------------------------------------------------------------------------------- /img/monospace-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/monospace-code.png -------------------------------------------------------------------------------- /img/monospace-slab-serif-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/monospace-slab-serif-preview.gif -------------------------------------------------------------------------------- /img/monospace-slab-serif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/monospace-slab-serif.png -------------------------------------------------------------------------------- /img/neo-grotesque-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/neo-grotesque-preview.gif -------------------------------------------------------------------------------- /img/neo-grotesque.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/neo-grotesque.png -------------------------------------------------------------------------------- /img/old-style-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/old-style-preview.gif -------------------------------------------------------------------------------- /img/old-style.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/old-style.png -------------------------------------------------------------------------------- /img/rounded-sans-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/rounded-sans-preview.gif -------------------------------------------------------------------------------- /img/rounded-sans.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/rounded-sans.png -------------------------------------------------------------------------------- /img/slab-serif-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/slab-serif-preview.gif -------------------------------------------------------------------------------- /img/slab-serif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/slab-serif.png -------------------------------------------------------------------------------- /img/system-ui-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/system-ui-preview.gif -------------------------------------------------------------------------------- /img/system-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/system-ui.png -------------------------------------------------------------------------------- /img/transitional-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/transitional-preview.gif -------------------------------------------------------------------------------- /img/transitional.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/img/transitional.png -------------------------------------------------------------------------------- /site/README.md: -------------------------------------------------------------------------------- 1 | # Modern Font Stacks Website 2 | 3 | A simple site showcasing all the different font stacks 4 | 5 | #### NPM Packages Used 6 | - [HTML Includes](https://github.com/entozoon/html-includes) - HTML compilation with partial includes and minification 7 | - [Servor](https://github.com/lukejacksonn/servor) - A dependency-free dev server for modern web application development 8 | 9 | 10 | ## NPM Scripts 11 | 12 | #### Install 13 | ``` 14 | npm install 15 | ``` 16 | 17 | #### Develop / Serve / Watch 18 | ``` 19 | npm run serve 20 | ``` 21 | Open your page on [localhost:8080](http://localhost:8080/). 22 | 23 | 24 | #### Build / Deploy 25 | ``` 26 | npm run build 27 | ``` 28 | 29 | 30 | ## Notes 31 | - `dist` is destroyed and recreated from `src` on each build/serve 32 | - Image and binary files will only be copied from `src` to `dist` on each build/serve (no Watch support) 33 | - Files in `src` starting with an `_` underscore) will not be copied to `dist` 34 | -------------------------------------------------------------------------------- /site/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "modern-font-stacks-site", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "modern-font-stacks-site", 9 | "version": "1.0.0", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "html-includes": "^5.0.0", 13 | "servor": "^4.0.2" 14 | } 15 | }, 16 | "node_modules/array-back": { 17 | "version": "3.1.0", 18 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", 19 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", 20 | "dev": true, 21 | "engines": { 22 | "node": ">=6" 23 | } 24 | }, 25 | "node_modules/ast-types": { 26 | "version": "0.9.6", 27 | "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", 28 | "integrity": "sha512-qEdtR2UH78yyHX/AUNfXmJTlM48XoFZKBdwi1nzkI1mJL21cmbu0cvjxjpkXJ5NENMq42H+hNs8VLJcqXLerBQ==", 29 | "dev": true, 30 | "engines": { 31 | "node": ">= 0.8" 32 | } 33 | }, 34 | "node_modules/balanced-match": { 35 | "version": "1.0.2", 36 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 37 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 38 | "dev": true 39 | }, 40 | "node_modules/big.js": { 41 | "version": "5.2.2", 42 | "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", 43 | "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", 44 | "dev": true, 45 | "engines": { 46 | "node": "*" 47 | } 48 | }, 49 | "node_modules/brace-expansion": { 50 | "version": "1.1.11", 51 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 52 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 53 | "dev": true, 54 | "dependencies": { 55 | "balanced-match": "^1.0.0", 56 | "concat-map": "0.0.1" 57 | } 58 | }, 59 | "node_modules/camel-case": { 60 | "version": "3.0.0", 61 | "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", 62 | "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", 63 | "dev": true, 64 | "dependencies": { 65 | "no-case": "^2.2.0", 66 | "upper-case": "^1.1.1" 67 | } 68 | }, 69 | "node_modules/clean-css": { 70 | "version": "4.2.4", 71 | "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", 72 | "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", 73 | "dev": true, 74 | "dependencies": { 75 | "source-map": "~0.6.0" 76 | }, 77 | "engines": { 78 | "node": ">= 4.0" 79 | } 80 | }, 81 | "node_modules/command-line-args": { 82 | "version": "5.2.1", 83 | "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", 84 | "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", 85 | "dev": true, 86 | "dependencies": { 87 | "array-back": "^3.1.0", 88 | "find-replace": "^3.0.0", 89 | "lodash.camelcase": "^4.3.0", 90 | "typical": "^4.0.0" 91 | }, 92 | "engines": { 93 | "node": ">=4.0.0" 94 | } 95 | }, 96 | "node_modules/commander": { 97 | "version": "2.20.3", 98 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 99 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 100 | "dev": true 101 | }, 102 | "node_modules/concat-map": { 103 | "version": "0.0.1", 104 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 105 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 106 | "dev": true 107 | }, 108 | "node_modules/emojis-list": { 109 | "version": "3.0.0", 110 | "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", 111 | "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", 112 | "dev": true, 113 | "engines": { 114 | "node": ">= 4" 115 | } 116 | }, 117 | "node_modules/es6-templates": { 118 | "version": "0.2.3", 119 | "resolved": "https://registry.npmjs.org/es6-templates/-/es6-templates-0.2.3.tgz", 120 | "integrity": "sha512-sziUVwcvQ+lOsrTyUY0Q11ilAPj+dy7AQ1E1MgSaHTaaAFTffaa08QSlGNU61iyVaroyb6nYdBV6oD7nzn6i8w==", 121 | "dev": true, 122 | "dependencies": { 123 | "recast": "~0.11.12", 124 | "through": "~2.3.6" 125 | } 126 | }, 127 | "node_modules/esprima": { 128 | "version": "3.1.3", 129 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", 130 | "integrity": "sha512-AWwVMNxwhN8+NIPQzAQZCm7RkLC4RbM3B1OobMuyp3i+w73X57KCKaVIxaRZb+DYCojq7rspo+fmuQfAboyhFg==", 131 | "dev": true, 132 | "bin": { 133 | "esparse": "bin/esparse.js", 134 | "esvalidate": "bin/esvalidate.js" 135 | }, 136 | "engines": { 137 | "node": ">=4" 138 | } 139 | }, 140 | "node_modules/fastparse": { 141 | "version": "1.1.2", 142 | "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", 143 | "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", 144 | "dev": true 145 | }, 146 | "node_modules/find-replace": { 147 | "version": "3.0.0", 148 | "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", 149 | "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", 150 | "dev": true, 151 | "dependencies": { 152 | "array-back": "^3.0.1" 153 | }, 154 | "engines": { 155 | "node": ">=4.0.0" 156 | } 157 | }, 158 | "node_modules/fs-extra": { 159 | "version": "7.0.1", 160 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", 161 | "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", 162 | "dev": true, 163 | "dependencies": { 164 | "graceful-fs": "^4.1.2", 165 | "jsonfile": "^4.0.0", 166 | "universalify": "^0.1.0" 167 | }, 168 | "engines": { 169 | "node": ">=6 <7 || >=8" 170 | } 171 | }, 172 | "node_modules/fs.realpath": { 173 | "version": "1.0.0", 174 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 175 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 176 | "dev": true 177 | }, 178 | "node_modules/function-bind": { 179 | "version": "1.1.1", 180 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 181 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 182 | "dev": true 183 | }, 184 | "node_modules/glob": { 185 | "version": "7.2.3", 186 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 187 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 188 | "dev": true, 189 | "dependencies": { 190 | "fs.realpath": "^1.0.0", 191 | "inflight": "^1.0.4", 192 | "inherits": "2", 193 | "minimatch": "^3.1.1", 194 | "once": "^1.3.0", 195 | "path-is-absolute": "^1.0.0" 196 | }, 197 | "engines": { 198 | "node": "*" 199 | }, 200 | "funding": { 201 | "url": "https://github.com/sponsors/isaacs" 202 | } 203 | }, 204 | "node_modules/graceful-fs": { 205 | "version": "4.2.10", 206 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", 207 | "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", 208 | "dev": true 209 | }, 210 | "node_modules/has": { 211 | "version": "1.0.3", 212 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 213 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 214 | "dev": true, 215 | "dependencies": { 216 | "function-bind": "^1.1.1" 217 | }, 218 | "engines": { 219 | "node": ">= 0.4.0" 220 | } 221 | }, 222 | "node_modules/he": { 223 | "version": "1.2.0", 224 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 225 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 226 | "dev": true, 227 | "bin": { 228 | "he": "bin/he" 229 | } 230 | }, 231 | "node_modules/html-includes": { 232 | "version": "5.0.0", 233 | "resolved": "https://registry.npmjs.org/html-includes/-/html-includes-5.0.0.tgz", 234 | "integrity": "sha512-grGDUxJqLk5Lp50R2uWNk6oyKx6Je0V0INRZAuQurp9ZkhpYLDexGPNl4txuszFEbBckmZSG0+zETyApOZc0xg==", 235 | "dev": true, 236 | "dependencies": { 237 | "command-line-args": "^5.1.1", 238 | "fs-extra": "^7.0.0", 239 | "glob": "^7.1.2", 240 | "html-loader": "^0.5.5", 241 | "html-minifier": "^4.0.0", 242 | "loader-utils": "^1.1.0", 243 | "node-watch": "^0.6.2", 244 | "shelljs": "^0.8.3" 245 | }, 246 | "bin": { 247 | "html-includes": "bin/run.js" 248 | } 249 | }, 250 | "node_modules/html-loader": { 251 | "version": "0.5.5", 252 | "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-0.5.5.tgz", 253 | "integrity": "sha512-7hIW7YinOYUpo//kSYcPB6dCKoceKLmOwjEMmhIobHuWGDVl0Nwe4l68mdG/Ru0wcUxQjVMEoZpkalZ/SE7zog==", 254 | "dev": true, 255 | "dependencies": { 256 | "es6-templates": "^0.2.3", 257 | "fastparse": "^1.1.1", 258 | "html-minifier": "^3.5.8", 259 | "loader-utils": "^1.1.0", 260 | "object-assign": "^4.1.1" 261 | } 262 | }, 263 | "node_modules/html-loader/node_modules/commander": { 264 | "version": "2.17.1", 265 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", 266 | "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", 267 | "dev": true 268 | }, 269 | "node_modules/html-loader/node_modules/html-minifier": { 270 | "version": "3.5.21", 271 | "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", 272 | "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", 273 | "dev": true, 274 | "dependencies": { 275 | "camel-case": "3.0.x", 276 | "clean-css": "4.2.x", 277 | "commander": "2.17.x", 278 | "he": "1.2.x", 279 | "param-case": "2.1.x", 280 | "relateurl": "0.2.x", 281 | "uglify-js": "3.4.x" 282 | }, 283 | "bin": { 284 | "html-minifier": "cli.js" 285 | }, 286 | "engines": { 287 | "node": ">=4" 288 | } 289 | }, 290 | "node_modules/html-loader/node_modules/uglify-js": { 291 | "version": "3.4.10", 292 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", 293 | "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", 294 | "dev": true, 295 | "dependencies": { 296 | "commander": "~2.19.0", 297 | "source-map": "~0.6.1" 298 | }, 299 | "bin": { 300 | "uglifyjs": "bin/uglifyjs" 301 | }, 302 | "engines": { 303 | "node": ">=0.8.0" 304 | } 305 | }, 306 | "node_modules/html-loader/node_modules/uglify-js/node_modules/commander": { 307 | "version": "2.19.0", 308 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", 309 | "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", 310 | "dev": true 311 | }, 312 | "node_modules/html-minifier": { 313 | "version": "4.0.0", 314 | "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", 315 | "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", 316 | "dev": true, 317 | "dependencies": { 318 | "camel-case": "^3.0.0", 319 | "clean-css": "^4.2.1", 320 | "commander": "^2.19.0", 321 | "he": "^1.2.0", 322 | "param-case": "^2.1.1", 323 | "relateurl": "^0.2.7", 324 | "uglify-js": "^3.5.1" 325 | }, 326 | "bin": { 327 | "html-minifier": "cli.js" 328 | }, 329 | "engines": { 330 | "node": ">=6" 331 | } 332 | }, 333 | "node_modules/inflight": { 334 | "version": "1.0.6", 335 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 336 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 337 | "dev": true, 338 | "dependencies": { 339 | "once": "^1.3.0", 340 | "wrappy": "1" 341 | } 342 | }, 343 | "node_modules/inherits": { 344 | "version": "2.0.4", 345 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 346 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 347 | "dev": true 348 | }, 349 | "node_modules/interpret": { 350 | "version": "1.4.0", 351 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", 352 | "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", 353 | "dev": true, 354 | "engines": { 355 | "node": ">= 0.10" 356 | } 357 | }, 358 | "node_modules/is-core-module": { 359 | "version": "2.11.0", 360 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", 361 | "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", 362 | "dev": true, 363 | "dependencies": { 364 | "has": "^1.0.3" 365 | }, 366 | "funding": { 367 | "url": "https://github.com/sponsors/ljharb" 368 | } 369 | }, 370 | "node_modules/json5": { 371 | "version": "1.0.2", 372 | "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", 373 | "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", 374 | "dev": true, 375 | "dependencies": { 376 | "minimist": "^1.2.0" 377 | }, 378 | "bin": { 379 | "json5": "lib/cli.js" 380 | } 381 | }, 382 | "node_modules/jsonfile": { 383 | "version": "4.0.0", 384 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 385 | "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", 386 | "dev": true, 387 | "optionalDependencies": { 388 | "graceful-fs": "^4.1.6" 389 | } 390 | }, 391 | "node_modules/loader-utils": { 392 | "version": "1.4.2", 393 | "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", 394 | "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", 395 | "dev": true, 396 | "dependencies": { 397 | "big.js": "^5.2.2", 398 | "emojis-list": "^3.0.0", 399 | "json5": "^1.0.1" 400 | }, 401 | "engines": { 402 | "node": ">=4.0.0" 403 | } 404 | }, 405 | "node_modules/lodash.camelcase": { 406 | "version": "4.3.0", 407 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", 408 | "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", 409 | "dev": true 410 | }, 411 | "node_modules/lower-case": { 412 | "version": "1.1.4", 413 | "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", 414 | "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", 415 | "dev": true 416 | }, 417 | "node_modules/minimatch": { 418 | "version": "3.1.2", 419 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 420 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 421 | "dev": true, 422 | "dependencies": { 423 | "brace-expansion": "^1.1.7" 424 | }, 425 | "engines": { 426 | "node": "*" 427 | } 428 | }, 429 | "node_modules/minimist": { 430 | "version": "1.2.7", 431 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", 432 | "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", 433 | "dev": true, 434 | "funding": { 435 | "url": "https://github.com/sponsors/ljharb" 436 | } 437 | }, 438 | "node_modules/no-case": { 439 | "version": "2.3.2", 440 | "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", 441 | "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", 442 | "dev": true, 443 | "dependencies": { 444 | "lower-case": "^1.1.1" 445 | } 446 | }, 447 | "node_modules/node-watch": { 448 | "version": "0.6.4", 449 | "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.6.4.tgz", 450 | "integrity": "sha512-cI6CHzivIFESe8djiK3Wh90CtWQBxLwMem8x8S+2GSvCvFgoMuOKVlfJtQ/2v3Afg3wOnHl/+tXotEs8z5vOrg==", 451 | "dev": true, 452 | "engines": { 453 | "node": ">=6" 454 | } 455 | }, 456 | "node_modules/object-assign": { 457 | "version": "4.1.1", 458 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 459 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 460 | "dev": true, 461 | "engines": { 462 | "node": ">=0.10.0" 463 | } 464 | }, 465 | "node_modules/once": { 466 | "version": "1.4.0", 467 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 468 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 469 | "dev": true, 470 | "dependencies": { 471 | "wrappy": "1" 472 | } 473 | }, 474 | "node_modules/param-case": { 475 | "version": "2.1.1", 476 | "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", 477 | "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", 478 | "dev": true, 479 | "dependencies": { 480 | "no-case": "^2.2.0" 481 | } 482 | }, 483 | "node_modules/path-is-absolute": { 484 | "version": "1.0.1", 485 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 486 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 487 | "dev": true, 488 | "engines": { 489 | "node": ">=0.10.0" 490 | } 491 | }, 492 | "node_modules/path-parse": { 493 | "version": "1.0.7", 494 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 495 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 496 | "dev": true 497 | }, 498 | "node_modules/private": { 499 | "version": "0.1.8", 500 | "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", 501 | "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", 502 | "dev": true, 503 | "engines": { 504 | "node": ">= 0.6" 505 | } 506 | }, 507 | "node_modules/recast": { 508 | "version": "0.11.23", 509 | "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", 510 | "integrity": "sha512-+nixG+3NugceyR8O1bLU45qs84JgI3+8EauyRZafLgC9XbdAOIVgwV1Pe2da0YzGo62KzWoZwUpVEQf6qNAXWA==", 511 | "dev": true, 512 | "dependencies": { 513 | "ast-types": "0.9.6", 514 | "esprima": "~3.1.0", 515 | "private": "~0.1.5", 516 | "source-map": "~0.5.0" 517 | }, 518 | "engines": { 519 | "node": ">= 0.8" 520 | } 521 | }, 522 | "node_modules/recast/node_modules/source-map": { 523 | "version": "0.5.7", 524 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 525 | "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", 526 | "dev": true, 527 | "engines": { 528 | "node": ">=0.10.0" 529 | } 530 | }, 531 | "node_modules/rechoir": { 532 | "version": "0.6.2", 533 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", 534 | "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", 535 | "dev": true, 536 | "dependencies": { 537 | "resolve": "^1.1.6" 538 | }, 539 | "engines": { 540 | "node": ">= 0.10" 541 | } 542 | }, 543 | "node_modules/relateurl": { 544 | "version": "0.2.7", 545 | "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", 546 | "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", 547 | "dev": true, 548 | "engines": { 549 | "node": ">= 0.10" 550 | } 551 | }, 552 | "node_modules/resolve": { 553 | "version": "1.22.1", 554 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", 555 | "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", 556 | "dev": true, 557 | "dependencies": { 558 | "is-core-module": "^2.9.0", 559 | "path-parse": "^1.0.7", 560 | "supports-preserve-symlinks-flag": "^1.0.0" 561 | }, 562 | "bin": { 563 | "resolve": "bin/resolve" 564 | }, 565 | "funding": { 566 | "url": "https://github.com/sponsors/ljharb" 567 | } 568 | }, 569 | "node_modules/servor": { 570 | "version": "4.0.2", 571 | "resolved": "https://registry.npmjs.org/servor/-/servor-4.0.2.tgz", 572 | "integrity": "sha512-MlmQ5Ntv4jDYUN060x/KEmN7emvIqKMZ9OkM+nY8Bf2+KkyLmGsTqWLyAN2cZr5oESAcH00UanUyyrlS1LRjFw==", 573 | "dev": true, 574 | "bin": { 575 | "servor": "cli.js" 576 | } 577 | }, 578 | "node_modules/shelljs": { 579 | "version": "0.8.5", 580 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", 581 | "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", 582 | "dev": true, 583 | "dependencies": { 584 | "glob": "^7.0.0", 585 | "interpret": "^1.0.0", 586 | "rechoir": "^0.6.2" 587 | }, 588 | "bin": { 589 | "shjs": "bin/shjs" 590 | }, 591 | "engines": { 592 | "node": ">=4" 593 | } 594 | }, 595 | "node_modules/source-map": { 596 | "version": "0.6.1", 597 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 598 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 599 | "dev": true, 600 | "engines": { 601 | "node": ">=0.10.0" 602 | } 603 | }, 604 | "node_modules/supports-preserve-symlinks-flag": { 605 | "version": "1.0.0", 606 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 607 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 608 | "dev": true, 609 | "engines": { 610 | "node": ">= 0.4" 611 | }, 612 | "funding": { 613 | "url": "https://github.com/sponsors/ljharb" 614 | } 615 | }, 616 | "node_modules/through": { 617 | "version": "2.3.8", 618 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 619 | "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", 620 | "dev": true 621 | }, 622 | "node_modules/typical": { 623 | "version": "4.0.0", 624 | "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", 625 | "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", 626 | "dev": true, 627 | "engines": { 628 | "node": ">=8" 629 | } 630 | }, 631 | "node_modules/uglify-js": { 632 | "version": "3.17.4", 633 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", 634 | "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", 635 | "dev": true, 636 | "bin": { 637 | "uglifyjs": "bin/uglifyjs" 638 | }, 639 | "engines": { 640 | "node": ">=0.8.0" 641 | } 642 | }, 643 | "node_modules/universalify": { 644 | "version": "0.1.2", 645 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 646 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", 647 | "dev": true, 648 | "engines": { 649 | "node": ">= 4.0.0" 650 | } 651 | }, 652 | "node_modules/upper-case": { 653 | "version": "1.1.3", 654 | "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", 655 | "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", 656 | "dev": true 657 | }, 658 | "node_modules/wrappy": { 659 | "version": "1.0.2", 660 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 661 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 662 | "dev": true 663 | } 664 | }, 665 | "dependencies": { 666 | "array-back": { 667 | "version": "3.1.0", 668 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", 669 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", 670 | "dev": true 671 | }, 672 | "ast-types": { 673 | "version": "0.9.6", 674 | "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", 675 | "integrity": "sha512-qEdtR2UH78yyHX/AUNfXmJTlM48XoFZKBdwi1nzkI1mJL21cmbu0cvjxjpkXJ5NENMq42H+hNs8VLJcqXLerBQ==", 676 | "dev": true 677 | }, 678 | "balanced-match": { 679 | "version": "1.0.2", 680 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 681 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 682 | "dev": true 683 | }, 684 | "big.js": { 685 | "version": "5.2.2", 686 | "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", 687 | "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", 688 | "dev": true 689 | }, 690 | "brace-expansion": { 691 | "version": "1.1.11", 692 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 693 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 694 | "dev": true, 695 | "requires": { 696 | "balanced-match": "^1.0.0", 697 | "concat-map": "0.0.1" 698 | } 699 | }, 700 | "camel-case": { 701 | "version": "3.0.0", 702 | "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", 703 | "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", 704 | "dev": true, 705 | "requires": { 706 | "no-case": "^2.2.0", 707 | "upper-case": "^1.1.1" 708 | } 709 | }, 710 | "clean-css": { 711 | "version": "4.2.4", 712 | "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", 713 | "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", 714 | "dev": true, 715 | "requires": { 716 | "source-map": "~0.6.0" 717 | } 718 | }, 719 | "command-line-args": { 720 | "version": "5.2.1", 721 | "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", 722 | "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", 723 | "dev": true, 724 | "requires": { 725 | "array-back": "^3.1.0", 726 | "find-replace": "^3.0.0", 727 | "lodash.camelcase": "^4.3.0", 728 | "typical": "^4.0.0" 729 | } 730 | }, 731 | "commander": { 732 | "version": "2.20.3", 733 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 734 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 735 | "dev": true 736 | }, 737 | "concat-map": { 738 | "version": "0.0.1", 739 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 740 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 741 | "dev": true 742 | }, 743 | "emojis-list": { 744 | "version": "3.0.0", 745 | "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", 746 | "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", 747 | "dev": true 748 | }, 749 | "es6-templates": { 750 | "version": "0.2.3", 751 | "resolved": "https://registry.npmjs.org/es6-templates/-/es6-templates-0.2.3.tgz", 752 | "integrity": "sha512-sziUVwcvQ+lOsrTyUY0Q11ilAPj+dy7AQ1E1MgSaHTaaAFTffaa08QSlGNU61iyVaroyb6nYdBV6oD7nzn6i8w==", 753 | "dev": true, 754 | "requires": { 755 | "recast": "~0.11.12", 756 | "through": "~2.3.6" 757 | } 758 | }, 759 | "esprima": { 760 | "version": "3.1.3", 761 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", 762 | "integrity": "sha512-AWwVMNxwhN8+NIPQzAQZCm7RkLC4RbM3B1OobMuyp3i+w73X57KCKaVIxaRZb+DYCojq7rspo+fmuQfAboyhFg==", 763 | "dev": true 764 | }, 765 | "fastparse": { 766 | "version": "1.1.2", 767 | "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", 768 | "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", 769 | "dev": true 770 | }, 771 | "find-replace": { 772 | "version": "3.0.0", 773 | "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", 774 | "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", 775 | "dev": true, 776 | "requires": { 777 | "array-back": "^3.0.1" 778 | } 779 | }, 780 | "fs-extra": { 781 | "version": "7.0.1", 782 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", 783 | "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", 784 | "dev": true, 785 | "requires": { 786 | "graceful-fs": "^4.1.2", 787 | "jsonfile": "^4.0.0", 788 | "universalify": "^0.1.0" 789 | } 790 | }, 791 | "fs.realpath": { 792 | "version": "1.0.0", 793 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 794 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 795 | "dev": true 796 | }, 797 | "function-bind": { 798 | "version": "1.1.1", 799 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 800 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 801 | "dev": true 802 | }, 803 | "glob": { 804 | "version": "7.2.3", 805 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 806 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 807 | "dev": true, 808 | "requires": { 809 | "fs.realpath": "^1.0.0", 810 | "inflight": "^1.0.4", 811 | "inherits": "2", 812 | "minimatch": "^3.1.1", 813 | "once": "^1.3.0", 814 | "path-is-absolute": "^1.0.0" 815 | } 816 | }, 817 | "graceful-fs": { 818 | "version": "4.2.10", 819 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", 820 | "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", 821 | "dev": true 822 | }, 823 | "has": { 824 | "version": "1.0.3", 825 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 826 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 827 | "dev": true, 828 | "requires": { 829 | "function-bind": "^1.1.1" 830 | } 831 | }, 832 | "he": { 833 | "version": "1.2.0", 834 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 835 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 836 | "dev": true 837 | }, 838 | "html-includes": { 839 | "version": "5.0.0", 840 | "resolved": "https://registry.npmjs.org/html-includes/-/html-includes-5.0.0.tgz", 841 | "integrity": "sha512-grGDUxJqLk5Lp50R2uWNk6oyKx6Je0V0INRZAuQurp9ZkhpYLDexGPNl4txuszFEbBckmZSG0+zETyApOZc0xg==", 842 | "dev": true, 843 | "requires": { 844 | "command-line-args": "^5.1.1", 845 | "fs-extra": "^7.0.0", 846 | "glob": "^7.1.2", 847 | "html-loader": "^0.5.5", 848 | "html-minifier": "^4.0.0", 849 | "loader-utils": "^1.4.2", 850 | "node-watch": "^0.6.2", 851 | "shelljs": "^0.8.3" 852 | } 853 | }, 854 | "html-loader": { 855 | "version": "0.5.5", 856 | "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-0.5.5.tgz", 857 | "integrity": "sha512-7hIW7YinOYUpo//kSYcPB6dCKoceKLmOwjEMmhIobHuWGDVl0Nwe4l68mdG/Ru0wcUxQjVMEoZpkalZ/SE7zog==", 858 | "dev": true, 859 | "requires": { 860 | "es6-templates": "^0.2.3", 861 | "fastparse": "^1.1.1", 862 | "html-minifier": "^3.5.8", 863 | "loader-utils": "^1.4.2", 864 | "object-assign": "^4.1.1" 865 | }, 866 | "dependencies": { 867 | "commander": { 868 | "version": "2.17.1", 869 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", 870 | "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", 871 | "dev": true 872 | }, 873 | "html-minifier": { 874 | "version": "3.5.21", 875 | "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", 876 | "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", 877 | "dev": true, 878 | "requires": { 879 | "camel-case": "3.0.x", 880 | "clean-css": "4.2.x", 881 | "commander": "2.17.x", 882 | "he": "1.2.x", 883 | "param-case": "2.1.x", 884 | "relateurl": "0.2.x", 885 | "uglify-js": "3.4.x" 886 | } 887 | }, 888 | "uglify-js": { 889 | "version": "3.4.10", 890 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", 891 | "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", 892 | "dev": true, 893 | "requires": { 894 | "commander": "~2.19.0", 895 | "source-map": "~0.6.1" 896 | }, 897 | "dependencies": { 898 | "commander": { 899 | "version": "2.19.0", 900 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", 901 | "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", 902 | "dev": true 903 | } 904 | } 905 | } 906 | } 907 | }, 908 | "html-minifier": { 909 | "version": "4.0.0", 910 | "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", 911 | "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", 912 | "dev": true, 913 | "requires": { 914 | "camel-case": "^3.0.0", 915 | "clean-css": "^4.2.1", 916 | "commander": "^2.19.0", 917 | "he": "^1.2.0", 918 | "param-case": "^2.1.1", 919 | "relateurl": "^0.2.7", 920 | "uglify-js": "^3.5.1" 921 | } 922 | }, 923 | "inflight": { 924 | "version": "1.0.6", 925 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 926 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 927 | "dev": true, 928 | "requires": { 929 | "once": "^1.3.0", 930 | "wrappy": "1" 931 | } 932 | }, 933 | "inherits": { 934 | "version": "2.0.4", 935 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 936 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 937 | "dev": true 938 | }, 939 | "interpret": { 940 | "version": "1.4.0", 941 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", 942 | "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", 943 | "dev": true 944 | }, 945 | "is-core-module": { 946 | "version": "2.11.0", 947 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", 948 | "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", 949 | "dev": true, 950 | "requires": { 951 | "has": "^1.0.3" 952 | } 953 | }, 954 | "json5": { 955 | "version": "1.0.2", 956 | "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", 957 | "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", 958 | "dev": true, 959 | "requires": { 960 | "minimist": "^1.2.0" 961 | } 962 | }, 963 | "jsonfile": { 964 | "version": "4.0.0", 965 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 966 | "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", 967 | "dev": true, 968 | "requires": { 969 | "graceful-fs": "^4.1.6" 970 | } 971 | }, 972 | "loader-utils": { 973 | "version": "1.4.2", 974 | "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", 975 | "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", 976 | "dev": true, 977 | "requires": { 978 | "big.js": "^5.2.2", 979 | "emojis-list": "^3.0.0", 980 | "json5": "^1.0.1" 981 | } 982 | }, 983 | "lodash.camelcase": { 984 | "version": "4.3.0", 985 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", 986 | "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", 987 | "dev": true 988 | }, 989 | "lower-case": { 990 | "version": "1.1.4", 991 | "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", 992 | "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", 993 | "dev": true 994 | }, 995 | "minimatch": { 996 | "version": "3.1.2", 997 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 998 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 999 | "dev": true, 1000 | "requires": { 1001 | "brace-expansion": "^1.1.7" 1002 | } 1003 | }, 1004 | "minimist": { 1005 | "version": "1.2.7", 1006 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", 1007 | "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", 1008 | "dev": true 1009 | }, 1010 | "no-case": { 1011 | "version": "2.3.2", 1012 | "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", 1013 | "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", 1014 | "dev": true, 1015 | "requires": { 1016 | "lower-case": "^1.1.1" 1017 | } 1018 | }, 1019 | "node-watch": { 1020 | "version": "0.6.4", 1021 | "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.6.4.tgz", 1022 | "integrity": "sha512-cI6CHzivIFESe8djiK3Wh90CtWQBxLwMem8x8S+2GSvCvFgoMuOKVlfJtQ/2v3Afg3wOnHl/+tXotEs8z5vOrg==", 1023 | "dev": true 1024 | }, 1025 | "object-assign": { 1026 | "version": "4.1.1", 1027 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1028 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 1029 | "dev": true 1030 | }, 1031 | "once": { 1032 | "version": "1.4.0", 1033 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1034 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1035 | "dev": true, 1036 | "requires": { 1037 | "wrappy": "1" 1038 | } 1039 | }, 1040 | "param-case": { 1041 | "version": "2.1.1", 1042 | "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", 1043 | "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", 1044 | "dev": true, 1045 | "requires": { 1046 | "no-case": "^2.2.0" 1047 | } 1048 | }, 1049 | "path-is-absolute": { 1050 | "version": "1.0.1", 1051 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1052 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1053 | "dev": true 1054 | }, 1055 | "path-parse": { 1056 | "version": "1.0.7", 1057 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1058 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1059 | "dev": true 1060 | }, 1061 | "private": { 1062 | "version": "0.1.8", 1063 | "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", 1064 | "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", 1065 | "dev": true 1066 | }, 1067 | "recast": { 1068 | "version": "0.11.23", 1069 | "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", 1070 | "integrity": "sha512-+nixG+3NugceyR8O1bLU45qs84JgI3+8EauyRZafLgC9XbdAOIVgwV1Pe2da0YzGo62KzWoZwUpVEQf6qNAXWA==", 1071 | "dev": true, 1072 | "requires": { 1073 | "ast-types": "0.9.6", 1074 | "esprima": "~3.1.0", 1075 | "private": "~0.1.5", 1076 | "source-map": "~0.5.0" 1077 | }, 1078 | "dependencies": { 1079 | "source-map": { 1080 | "version": "0.5.7", 1081 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 1082 | "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", 1083 | "dev": true 1084 | } 1085 | } 1086 | }, 1087 | "rechoir": { 1088 | "version": "0.6.2", 1089 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", 1090 | "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", 1091 | "dev": true, 1092 | "requires": { 1093 | "resolve": "^1.1.6" 1094 | } 1095 | }, 1096 | "relateurl": { 1097 | "version": "0.2.7", 1098 | "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", 1099 | "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", 1100 | "dev": true 1101 | }, 1102 | "resolve": { 1103 | "version": "1.22.1", 1104 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", 1105 | "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", 1106 | "dev": true, 1107 | "requires": { 1108 | "is-core-module": "^2.9.0", 1109 | "path-parse": "^1.0.7", 1110 | "supports-preserve-symlinks-flag": "^1.0.0" 1111 | } 1112 | }, 1113 | "servor": { 1114 | "version": "4.0.2", 1115 | "resolved": "https://registry.npmjs.org/servor/-/servor-4.0.2.tgz", 1116 | "integrity": "sha512-MlmQ5Ntv4jDYUN060x/KEmN7emvIqKMZ9OkM+nY8Bf2+KkyLmGsTqWLyAN2cZr5oESAcH00UanUyyrlS1LRjFw==", 1117 | "dev": true 1118 | }, 1119 | "shelljs": { 1120 | "version": "0.8.5", 1121 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", 1122 | "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", 1123 | "dev": true, 1124 | "requires": { 1125 | "glob": "^7.0.0", 1126 | "interpret": "^1.0.0", 1127 | "rechoir": "^0.6.2" 1128 | } 1129 | }, 1130 | "source-map": { 1131 | "version": "0.6.1", 1132 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1133 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1134 | "dev": true 1135 | }, 1136 | "supports-preserve-symlinks-flag": { 1137 | "version": "1.0.0", 1138 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 1139 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 1140 | "dev": true 1141 | }, 1142 | "through": { 1143 | "version": "2.3.8", 1144 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 1145 | "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", 1146 | "dev": true 1147 | }, 1148 | "typical": { 1149 | "version": "4.0.0", 1150 | "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", 1151 | "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", 1152 | "dev": true 1153 | }, 1154 | "uglify-js": { 1155 | "version": "3.17.4", 1156 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", 1157 | "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", 1158 | "dev": true 1159 | }, 1160 | "universalify": { 1161 | "version": "0.1.2", 1162 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 1163 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", 1164 | "dev": true 1165 | }, 1166 | "upper-case": { 1167 | "version": "1.1.3", 1168 | "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", 1169 | "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", 1170 | "dev": true 1171 | }, 1172 | "wrappy": { 1173 | "version": "1.0.2", 1174 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1175 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 1176 | "dev": true 1177 | } 1178 | } 1179 | } 1180 | -------------------------------------------------------------------------------- /site/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "modern-font-stacks-site", 3 | "version": "1.0.0", 4 | "description": "Modern Font Stacks Website", 5 | "author": "Dan Klammer", 6 | "license": "MIT", 7 | "scripts": { 8 | "setup": "rm -rf /dist/ ; cp -r ./src/. ./dist ; rm ./dist/_*.*", 9 | "build": "npm run setup && html-includes --src src --dest dist --minify minifyJS=true", 10 | "serve": "npm run setup && servor dist --reload --browse & html-includes --src src --dest dist --watch" 11 | }, 12 | "devDependencies": { 13 | "html-includes": "^5.0.0", 14 | "servor": "^4.0.2" 15 | }, 16 | "overrides": { 17 | "html-includes": { 18 | "loader-utils": "^1.4.2" 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /site/src/_scripts.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Checks if a font is available to be used on a web page. 3 | * 4 | * @param {String} fontName The name of the font to check 5 | * @param {Function} callback A function to handle the boolean result of the font availability check 6 | * @license MIT 7 | * @copyright Sam Clarke 2013 8 | * @author Sam Clarke 9 | * @url https://www.samclarke.com/javascript-is-font-available/ 10 | * 11 | * Modified on 02/2023 to execute the font availability check asynchronously 12 | * using requestIdleCallback, and to invoke the callback function with the boolean result of the check. 13 | */ 14 | 15 | ((document) => { 16 | let width; 17 | const body = document.body; 18 | 19 | const container = document.createElement('span'); 20 | container.innerHTML = 'wi'.repeat(100); 21 | container.style.cssText = ` 22 | position:absolute; 23 | width:auto; 24 | font-size:128px; 25 | left:-99999px; 26 | `; 27 | 28 | const getWidth = (fontFamily) => { 29 | container.style.fontFamily = fontFamily; 30 | 31 | body.appendChild(container); 32 | width = container.clientWidth; 33 | body.removeChild(container); 34 | 35 | return width; 36 | }; 37 | 38 | // Pre compute the widths of monospace, serif & sans-serif 39 | // to improve performance. 40 | const monoWidth = getWidth('monospace'); 41 | const serifWidth = getWidth('serif'); 42 | const sansWidth = getWidth('sans-serif'); 43 | 44 | window.isFontAvailable = (font, callback) => { 45 | if ('requestIdleCallback' in window) { 46 | requestIdleCallback(() => { 47 | const available = 48 | monoWidth !== getWidth(`${font},monospace`) || 49 | sansWidth !== getWidth(`${font},sans-serif`) || 50 | serifWidth !== getWidth(`${font},serif`); 51 | callback(available); 52 | }); 53 | } else { 54 | // Fallback to setTimeout for Safari 55 | setTimeout(() => { 56 | const available = 57 | monoWidth !== getWidth(`${font},monospace`) || 58 | sansWidth !== getWidth(`${font},sans-serif`) || 59 | serifWidth !== getWidth(`${font},serif`); 60 | callback(available); 61 | }, 0); 62 | } 63 | }; 64 | })(document); 65 | 66 | 67 | // ----- FONT STACKS ----- // 68 | const fonts = document.querySelector('#fonts'); 69 | const previewText = document.querySelector('#preview-text'); 70 | const fontWeightRange = document.querySelector('#fontweight'); 71 | const fontWeightOutput = document.querySelector('#weightoutput'); 72 | const fontWeights = document.querySelectorAll('.font-weights span'); 73 | const systemFont = document.querySelectorAll('.font-stack span'); 74 | const systemFontWeight = document.querySelectorAll('.font-stack var'); 75 | const fontCard = document.querySelectorAll('.font-card'); 76 | 77 | const changeSize = (newVal) => { 78 | fonts.style.fontSize = `${newVal}em`; 79 | }; 80 | 81 | const changeWeight = (newVal) => { 82 | fonts.style.fontWeight = newVal; 83 | fonts.setAttribute('data-weight', newVal); 84 | systemFontWeight.forEach(element => { 85 | if (newVal === '400'){ 86 | element.innerText = 'normal'; 87 | } else if (newVal === '700') { 88 | element.innerText = 'bold'; 89 | } else { 90 | element.innerText = newVal; 91 | } 92 | }); 93 | }; 94 | 95 | Array.from(fontWeights).forEach(e => { 96 | e.addEventListener('click', () => { 97 | const fontWeightValue = e.innerText; 98 | fonts.style.fontWeight = fontWeightValue; 99 | fonts.setAttribute('data-weight', fontWeightValue); 100 | fontWeightRange.value = fontWeightValue; 101 | systemFontWeight.forEach(element => { 102 | if (fontWeightValue === '400'){ 103 | element.innerText = 'normal'; 104 | } else if (fontWeightValue === '700') { 105 | element.innerText = 'bold'; 106 | } else { 107 | element.innerText = fontWeightValue; 108 | } 109 | }); 110 | }); 111 | }); 112 | 113 | const updateText = (newVal) => { 114 | const elements = document.querySelectorAll('.font-preview'); 115 | Array.from(elements).forEach((el) => { 116 | el.innerText = newVal; 117 | }); 118 | }; 119 | 120 | const enterToBlur = (el) => { 121 | if (event.key === 'Enter'){ 122 | el.blur(); 123 | } 124 | }; 125 | 126 | // add event listeners 127 | const fontSizeInput = document.getElementById('fontsize'); 128 | fontSizeInput.addEventListener('input', (event) => { 129 | const newVal = event.target.value; 130 | document.querySelector('#sizeoutput').innerText = newVal; 131 | changeSize(newVal); 132 | }); 133 | fontSizeInput.addEventListener('change', (event) => { 134 | const newVal = event.target.value; 135 | changeSize(newVal); 136 | }); 137 | 138 | const fontWeightInput = document.getElementById('fontweight'); 139 | fontWeightInput.addEventListener('input', (event) => { 140 | const newVal = event.target.value; 141 | document.querySelector('#weightoutput').innerText = newVal; 142 | changeWeight(newVal); 143 | }); 144 | fontWeightInput.addEventListener('change', (event) => { 145 | const newVal = event.target.value; 146 | changeWeight(newVal); 147 | }); 148 | 149 | const previewTextInput = document.getElementById('preview-text'); 150 | previewTextInput.addEventListener('input', (event) => { 151 | const newVal = event.target.value; 152 | updateText(newVal); 153 | }); 154 | previewTextInput.addEventListener('change', (event) => { 155 | const newVal = event.target.value; 156 | updateText(newVal); 157 | }); 158 | previewTextInput.addEventListener('keyup', (event) => { 159 | if (event.key === 'Enter') { 160 | event.target.blur(); 161 | } 162 | }); 163 | 164 | Array.from(systemFont).forEach((el) => { 165 | const font = el.innerText; 166 | isFontAvailable(font, (available) => { 167 | if (available) { 168 | el.classList.add('yep'); 169 | } else { 170 | el.classList.add('nope'); 171 | } 172 | }); 173 | }); 174 | 175 | 176 | // ----- PREVIEW ----- // 177 | const preview = document.querySelector('#preview'); 178 | const previewMenu = document.querySelector('#preview details'); 179 | const previewButtons = document.querySelectorAll('#preview button'); 180 | const urlParams = new URLSearchParams(window.location.search); 181 | const stackParam = urlParams.get('stack'); 182 | 183 | const stacksAvail = Array.from(previewButtons, el => el.className); 184 | 185 | // If has proper URL param 186 | if (stacksAvail.includes(stackParam)) { 187 | preview.className = ''; 188 | preview.classList.add(stackParam); 189 | previewButtons.forEach(el => { 190 | el.dataset.on = false; 191 | }); 192 | document.querySelector(`#preview .${CSS.escape(stackParam)}`).dataset.on = true; 193 | document.querySelector(`#${CSS.escape(stackParam)}`).scrollIntoView(); 194 | document.querySelector(`#${CSS.escape(stackParam)}`).classList.add('highlight'); 195 | 196 | document.addEventListener('click', e => { 197 | fontCard.forEach(el => { 198 | el.classList.remove('highlight'); 199 | }); 200 | }, { once: true }); 201 | } 202 | 203 | // Font stack buttons 204 | previewButtons.forEach(e => { 205 | e.addEventListener('click', function(){ 206 | preview.className = ''; 207 | preview.classList.add(this.className); 208 | previewMenu.removeAttribute("open"); 209 | previewButtons.forEach(el => { 210 | el.dataset.on = false; 211 | }); 212 | this.dataset.on = true; 213 | // urlParams.set('stack', this.className); 214 | // window.history.replaceState(null, null, '?' + urlParams + '#preview'); 215 | // window.history.replaceState({}, document.title, location.protocol + '//' + location.host + location.pathname); 216 | }); 217 | }); 218 | 219 | 220 | // ----- MENU ACTIONS ----- // 221 | const menu = document.querySelector('#menu details'); 222 | const menuLinks = document.querySelectorAll('#menu nav a'); 223 | 224 | menuLinks.forEach(e => { 225 | e.addEventListener('click', () => { 226 | menu.removeAttribute("open"); 227 | }); 228 | }); 229 | 230 | document.addEventListener('click', event => { 231 | const isClickInside = menu.contains(event.target); 232 | if (!isClickInside) { 233 | menu.removeAttribute("open"); 234 | } 235 | }); 236 | 237 | document.querySelectorAll('.smooth-scroll').forEach(anchor => { 238 | anchor.addEventListener('click', e => { 239 | e.preventDefault(); 240 | document.querySelector(anchor.getAttribute('href')).scrollIntoView({ 241 | behavior: 'smooth' 242 | }); 243 | window.history.replaceState(null, null, anchor.getAttribute('href')); 244 | }); 245 | }); -------------------------------------------------------------------------------- /site/src/_styles.css: -------------------------------------------------------------------------------- 1 | /*! modern-normalize v1.1.0 | MIT License | https://github.com/sindresorhus/modern-normalize */*,::after,::before{box-sizing:border-box}html{-moz-tab-size:4;tab-size:4}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}body{font-family:system-ui,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji'}hr{height:0;color:inherit}abbr[title]{text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Consolas,'Liberation Mono',Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}::-moz-focus-inner{border-style:none;padding:0}:-moz-focusring{outline:1px dotted ButtonText}:-moz-ui-invalid{box-shadow:none}legend{padding:0}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item} 2 | 3 | 4 | /* === BASE === */ 5 | 6 | html { 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | body { 12 | margin: 0; 13 | background: #fff; 14 | font-family: system-ui, sans-serif; 15 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3E%3Cpath fill='%23666' opacity='0.4' d='M1 3h1v1H1V3zm2-2h1v1H3V1z'%3E%3C/path%3E%3C/svg%3E"); 16 | } 17 | 18 | a { 19 | color: #000; 20 | text-decoration-color: #ccc; 21 | text-decoration-thickness: 2px; 22 | text-underline-offset: 4px; 23 | } 24 | 25 | @media (hover: hover) { 26 | a:hover { 27 | text-decoration-color: #000; 28 | } 29 | } 30 | 31 | 32 | /* === MENU NAVIGATION === */ 33 | 34 | #menu details { 35 | position: absolute; 36 | z-index: 3; 37 | top: 0.5rem; 38 | right: 0.5rem; 39 | padding: 0.5rem; 40 | border: 2px solid transparent; 41 | } 42 | 43 | #menu details[open] { 44 | background: rgba(255,255,255,0.98); 45 | border: 2px solid #000; 46 | box-shadow: 3px 3px 0 0 rgba(180,180,180,0.30); 47 | } 48 | 49 | #menu summary { 50 | display: block; 51 | position: relative; 52 | z-index: 1; 53 | list-style: none; 54 | cursor: pointer; 55 | text-align: right; 56 | padding: 0.5rem; 57 | margin-top: -0.5rem; 58 | margin-right: -0.5rem; 59 | margin-left: auto; 60 | width: 3rem; 61 | height: 3rem; 62 | } 63 | 64 | #menu summary::-webkit-details-marker { 65 | display: none; 66 | } 67 | 68 | #menu #i-close, 69 | #menu details[open] #i-menu { display: none; } 70 | #menu details[open] #i-close { display: block; } 71 | 72 | #menu nav { 73 | display: flex; 74 | flex-direction: column; 75 | padding-bottom: 0.25rem; 76 | min-width: 7rem; 77 | margin-top: -2.5rem; 78 | } 79 | 80 | #menu nav a { 81 | color: #000; 82 | font-size: 1.125rem; 83 | padding: 0.5rem 1rem; 84 | margin: 0 -0.75rem; 85 | font-weight: 400; 86 | text-decoration: none; 87 | } 88 | 89 | @media (hover: hover) { 90 | #menu nav a:hover { 91 | color: #202020; 92 | text-decoration: underline; 93 | } 94 | } 95 | 96 | 97 | /* === ABOUT HEADER === */ 98 | 99 | header { 100 | width: 100%; 101 | margin: 0; 102 | padding: 2.5rem 0.75rem; 103 | background: #fff; 104 | border-bottom: 1px solid #ddd; 105 | } 106 | 107 | header > div { 108 | width: 100%; 109 | max-width: 64rem; 110 | margin: 0 auto; 111 | text-align: center; 112 | } 113 | 114 | header .logo-link { 115 | display: inline-block; 116 | text-decoration: underline; 117 | text-decoration-color: transparent; 118 | text-decoration-thickness: 2px; 119 | text-underline-offset: 0.4rem; 120 | transition: all 0.3s ease; 121 | } 122 | 123 | @media (hover: hover) { 124 | header .logo-link:hover { 125 | text-decoration-color: #ddd; 126 | } 127 | } 128 | 129 | header svg { 130 | display: block; 131 | margin: 0 auto; 132 | overflow: visible; 133 | } 134 | 135 | .logo-front-layer, 136 | .logo-middle-layer, 137 | .logo-back-layer { 138 | transition: transform 0.3s ease; 139 | } 140 | 141 | @media (hover: hover) { 142 | header .logo-link:hover .logo-front-layer { transform: translate(-2px, -1px); } 143 | header .logo-link:hover .logo-middle-layer { transform: translate(2px, 1px); } 144 | header .logo-link:hover .logo-back-layer { transform: translate(6px, 3px); } 145 | } 146 | 147 | header h1 { 148 | font-family: Charter, 'Bitstream Charter', 'Sitka Text', Cambria, serif; 149 | font-size: 2.25rem; 150 | line-height: 1.1; 151 | text-align: center; 152 | margin: 0.5rem 1rem 0.5rem; 153 | font-weight: 400; 154 | } 155 | 156 | header h2 { 157 | font-size: 1rem; 158 | line-height: 1.4; 159 | text-align: center; 160 | margin: 0.75rem 0; 161 | font-weight: 600; 162 | } 163 | 164 | header p { 165 | line-height: 1.4; 166 | margin-top: 0; 167 | } 168 | 169 | #about-buttons { 170 | display: flex; 171 | justify-content: center; 172 | padding: 0.75rem 1rem 1rem; 173 | gap: 0.75rem; 174 | } 175 | 176 | .btn { 177 | display: inline-flex; 178 | gap: 0.5rem; 179 | justify-content: center; 180 | position: relative; 181 | font-size: 1rem; 182 | line-height: 1; 183 | font-weight: 600; 184 | align-items: center; 185 | text-decoration: none; 186 | padding: 0.5rem 1.25rem; 187 | border: 2px solid #ddd; 188 | border-radius: 4px; 189 | background: #fdfdfd; 190 | } 191 | 192 | @media (hover: hover) { 193 | .btn:hover { 194 | border: 2px solid #aaa; 195 | } 196 | } 197 | 198 | .btn:active { 199 | top: 1px; 200 | } 201 | 202 | 203 | /* === UI ELEMENTS === */ 204 | 205 | section > h2 { 206 | font-family: system-ui, sans-serif; 207 | font-size: 1rem; 208 | text-align: center; 209 | text-transform: uppercase; 210 | letter-spacing: 2px; 211 | font-weight: 400; 212 | background: #252525; 213 | color: #fff; 214 | margin: 0; 215 | padding: 1rem; 216 | border-top: 1px solid #353535; 217 | border-bottom: 1px solid #353535; 218 | } 219 | 220 | .ui-bg { 221 | position: sticky; 222 | top: 0; 223 | z-index: 2; 224 | display: flex; 225 | flex-direction: row; 226 | justify-content: space-between; 227 | width: 100%; 228 | background: #000; 229 | color: #fff; 230 | } 231 | 232 | .ui { 233 | display: flex; 234 | flex-wrap: wrap; 235 | justify-content: space-between; 236 | align-items: start; 237 | width: 100%; 238 | max-width: 72rem; 239 | margin: 0 auto; 240 | padding: 0 1rem; 241 | gap: 0 1rem; 242 | } 243 | 244 | .ui > div { 245 | flex: 1 auto; 246 | max-width: calc(50% - 0.5rem); 247 | padding: 0.75rem 0; 248 | } 249 | 250 | .ui div label { 251 | display: block; 252 | font-size: 0.75rem; 253 | text-align: left; 254 | text-transform: uppercase; 255 | letter-spacing: 1px; 256 | padding-bottom: 0.5rem; 257 | color: #808080; 258 | font-weight: 600; 259 | white-space: nowrap; 260 | } 261 | 262 | .ui div input { 263 | width: 100%; 264 | appearance: none; 265 | background: #404040; 266 | height: 3px; 267 | border-radius: 2px; 268 | cursor: grab; 269 | } 270 | 271 | .ui div input:active { 272 | cursor: grabbing; 273 | } 274 | 275 | .ui div input::-webkit-slider-thumb { 276 | appearance: none; 277 | width: .25rem; 278 | height: 1.25rem; 279 | background: #fff; 280 | border-radius: 1rem; 281 | border: none; 282 | } 283 | 284 | .ui div input::-moz-range-thumb { 285 | width: .25rem; 286 | height: 1.25rem; 287 | background: #fff; 288 | border-radius: 1rem; 289 | border: none; 290 | } 291 | 292 | .ui div output { 293 | color: #fff; 294 | display: inline-block; 295 | min-width: 3.5rem; 296 | } 297 | 298 | #sizeoutput:after { 299 | content: "em"; 300 | text-transform: lowercase; 301 | } 302 | 303 | #preview-text { 304 | width: 100%; 305 | flex: 1 auto; 306 | appearance: none; 307 | border-radius: 3px; 308 | border: none; 309 | background: transparent; 310 | color: #fff; 311 | padding: 0.5rem 0 1rem; 312 | outline: none; 313 | } 314 | 315 | #preview-text::-webkit-search-cancel-button { 316 | appearance: none; 317 | display: inline-block; 318 | width: 12px; 319 | height: 12px; 320 | margin-left: 10px; 321 | background: 322 | linear-gradient(45deg, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 43%,#ccc 45%,#ccc 55%,rgba(0,0,0,0) 57%,rgba(0,0,0,0) 100%), 323 | linear-gradient(135deg, transparent 0%,transparent 43%,#ccc 45%,#ccc 55%,transparent 57%,transparent 100%); 324 | cursor: pointer: 325 | } 326 | 327 | 328 | /* === SECTION: FONT STACKS === */ 329 | 330 | #font-stacks { 331 | text-align: center; 332 | } 333 | 334 | #fonts { 335 | max-width: 84rem; 336 | margin: 0 auto; 337 | padding: 2rem 1rem; 338 | font-size: 2rem; 339 | } 340 | 341 | .font-card { 342 | display: flex; 343 | flex-direction: column; 344 | justify-content: space-between; 345 | margin-bottom: 1.5rem; 346 | background: #fff; 347 | border: 1px solid #e5e7eb; 348 | border-bottom-width: 2px; 349 | border: 1px solid #888; 350 | box-shadow: 4px 4px 0 0 rgba(0,0,0,0.15); 351 | scroll-margin-top: 6rem; 352 | } 353 | 354 | .font-link { 355 | padding: 0 4px 0; 356 | color: #707070; 357 | position: relative; 358 | top: 4px; 359 | left: 2px; 360 | float: right; 361 | } 362 | 363 | @media (hover: hover) { 364 | .font-link:hover { 365 | color: #000; 366 | } 367 | 368 | .font-title:hover .font-link { 369 | display: inline-flex; 370 | } 371 | } 372 | 373 | @media (hover: none) { 374 | .font-title .font-link { 375 | display: inline-flex; 376 | } 377 | } 378 | 379 | .font-card.highlight { 380 | outline: 2px solid #000; 381 | } 382 | 383 | .font-title { 384 | display: flex; 385 | justify-content: space-between; 386 | align-items: center; 387 | padding: 1.25rem .75rem; 388 | border-bottom: 1px solid #e5e7eb; 389 | } 390 | 391 | .font-title h3 { 392 | font-size: 1.5rem; 393 | margin: 0; 394 | font-weight: 400; 395 | text-align: left; 396 | } 397 | 398 | .font-callout { 399 | font-family: system-ui, sans-serif; 400 | -webkit-font-smoothing: antialiased; 401 | -moz-osx-font-smoothing: grayscale; 402 | white-space: nowrap; 403 | background: #eee; 404 | color: #505050; 405 | padding: 6px 10px; 406 | font-size: 13px; 407 | font-weight: 600; 408 | line-height: 1; 409 | border-radius: 20px; 410 | } 411 | 412 | .font-preview { 413 | display: block; 414 | flex: 1 auto; 415 | margin: 0; 416 | padding: 1.5rem .75rem; 417 | line-height: 1.2; 418 | overflow: hidden; 419 | } 420 | 421 | .font-preview:empty:after { 422 | content: "ABCDEFGHIJKLM\a NOPQRSTUVWXYZ\a abcdefghijklm\a nopqrstuvwxyz\a 1234567890"; 423 | white-space: pre; 424 | } 425 | 426 | .font-weights { 427 | display: flex; 428 | justify-content: space-between; 429 | font-size: .9375rem; 430 | padding: 1rem .75rem; 431 | border-top: 1px solid #e5e7eb; 432 | } 433 | 434 | .font-weights span { 435 | text-decoration: none; 436 | text-underline-offset: 3px; 437 | cursor: pointer; 438 | } 439 | 440 | .weight-100 { font-weight: 100; } 441 | .weight-200 { font-weight: 200; } 442 | .weight-300 { font-weight: 300; } 443 | .weight-400 { font-weight: 400; } 444 | .weight-500 { font-weight: 500; } 445 | .weight-600 { font-weight: 600; } 446 | .weight-700 { font-weight: 700; } 447 | .weight-800 { font-weight: 800; } 448 | .weight-900 { font-weight: 900; } 449 | 450 | [data-weight="100"] .weight-100, 451 | [data-weight="200"] .weight-200, 452 | [data-weight="300"] .weight-300, 453 | [data-weight="400"] .weight-400, 454 | [data-weight="500"] .weight-500, 455 | [data-weight="600"] .weight-600, 456 | [data-weight="700"] .weight-700, 457 | [data-weight="800"] .weight-800, 458 | [data-weight="900"] .weight-900 { 459 | text-decoration: underline; 460 | } 461 | 462 | .font-stack { 463 | display: flex; 464 | justify-content: start; 465 | align-items: center; 466 | min-height: 5rem; 467 | text-align: left; 468 | padding: .5rem .75rem .75rem; 469 | border-top: 1px solid #e5e7eb; 470 | } 471 | 472 | .font-stack code { 473 | font-family: 'Cascadia Code', Menlo, Consolas, 'DejaVu Sans Mono', monospace; 474 | -webkit-font-smoothing: antialiased; 475 | -moz-osx-font-smoothing: grayscale; 476 | font-size: 13px; 477 | line-height: 1.66; 478 | font-weight: normal; 479 | color: #1e293b; 480 | } 481 | 482 | .font-stack code strong { 483 | font-weight: 400; 484 | display: block; 485 | } 486 | 487 | .font-stack code var { 488 | font-style: normal; 489 | } 490 | 491 | #font-stacks-key { 492 | display: flex; 493 | flex-direction: row; 494 | gap: 1rem; 495 | justify-content: space-between; 496 | padding: 1rem; 497 | font-size: 13px; 498 | font-weight: 500; 499 | grid-column: 1 / -1; 500 | } 501 | 502 | #font-stacks-key > div { 503 | display: flex; 504 | flex: 1 auto; 505 | flex-direction: row; 506 | gap: 1rem; 507 | justify-content: center; 508 | } 509 | 510 | #font-stacks-key .how-to-use { 511 | display: none; 512 | gap: 0.5rem; 513 | } 514 | 515 | #font-stacks-key .how-to-use span { 516 | font-weight: normal; 517 | } 518 | 519 | #font-stacks-key .how-to-use code { 520 | font-family: 'Cascadia Code', Menlo, Consolas, 'DejaVu Sans Mono', monospace; 521 | background: #f4f6f6; 522 | padding: 4px; 523 | border-radius: 3px; 524 | font-size: 12px; 525 | color: #1e293b; 526 | } 527 | 528 | .nope { 529 | color: #DC2626; 530 | } 531 | 532 | .yep { 533 | text-decoration: underline; 534 | text-underline-offset: 3px; 535 | color: #265997; 536 | } 537 | 538 | .yep ~ .yep { 539 | text-decoration-style: dotted; 540 | text-decoration-color: #26599799; 541 | } 542 | 543 | 544 | /* === SECTION : PREVIEW : ARTICLE VIEW === */ 545 | 546 | #article-viewport { 547 | background: #fff; 548 | padding-bottom: 3rem; 549 | } 550 | 551 | #preview .ui { 552 | list-style: none; 553 | padding: 0; 554 | } 555 | 556 | #preview .ui summary::-webkit-details-marker { 557 | display: none; 558 | } 559 | 560 | #preview .ui summary { 561 | display: flex; 562 | flex-wrap: wrap; 563 | justify-content: center; 564 | width: 100%; 565 | padding: 1rem; 566 | gap: 0.75rem; 567 | } 568 | 569 | #preview .ui button { 570 | appearance: none; 571 | flex: 1 auto; 572 | background: transparent; 573 | color: #ccc; 574 | font-size: 1.125rem; 575 | line-height: 1.1; 576 | min-height: 1.5rem; 577 | border: 2px solid rgba(255,255,255, 0.2); 578 | border-radius: 4px; 579 | padding: 0.5rem; 580 | margin: 0; 581 | vertical-align: top; 582 | cursor: pointer; 583 | position: relative; 584 | } 585 | 586 | #preview button:active { 587 | top: 1px; 588 | } 589 | 590 | #preview button[data-on="true"] { 591 | border: 2px solid rgba(255,255,255, 1); 592 | color: #fff; 593 | } 594 | 595 | #preview article { 596 | font-size: 1.125rem; 597 | line-height: 1.7777778; 598 | max-width: 47rem; 599 | margin: 0 auto; 600 | padding: 3rem 1rem 2rem; 601 | } 602 | 603 | #preview article .title { 604 | display: block; 605 | font-size: 2.5rem; 606 | margin: 4rem auto 6rem; 607 | max-width: 32rem; 608 | line-height: 1.1; 609 | text-align: center; 610 | font-weight: 200; 611 | } 612 | 613 | #preview article .author { 614 | display: block; 615 | font-size: 1.25rem; 616 | margin: 1rem auto; 617 | max-width: 32rem; 618 | line-height: 1.1; 619 | text-align: center; 620 | font-weight: 400; 621 | font-style: italic; 622 | } 623 | 624 | #preview article img { 625 | display: block; 626 | margin: 0 auto; 627 | } 628 | 629 | #preview article .chapter { 630 | display: block; 631 | font-size: 1rem; 632 | line-height: 1; 633 | text-align: center; 634 | text-transform: uppercase; 635 | letter-spacing: 1px; 636 | font-weight: 500; 637 | } 638 | 639 | #preview article .chapter-name { 640 | display: block; 641 | margin: 0.75rem 0 1rem; 642 | font-size: 1.75rem; 643 | line-height: 1.1; 644 | text-align: center; 645 | font-weight: 600; 646 | } 647 | 648 | #preview article p:first-of-type::first-letter { 649 | font-size: 225%; 650 | line-height: 1; 651 | margin-right: 0.1rem; 652 | } 653 | 654 | 655 | /* === SECTION : PREVIEW : ARTICLE VIEW === */ 656 | 657 | h2#characters { 658 | scroll-margin-top: 7.45rem; 659 | } 660 | 661 | #font-characters { 662 | max-width: 84rem; 663 | margin: 0 auto; 664 | padding: 3rem 1rem; 665 | content-visibility: auto; 666 | min-height: 150vh; 667 | } 668 | 669 | .character-set { 670 | box-shadow: 4px 4px 0 0 rgba(0,0,0,0.15); 671 | } 672 | 673 | .character-set h3 { 674 | font-family: system-ui, sans-serif; 675 | font-weight: 500; 676 | padding: 1rem; 677 | background: #eee; 678 | margin: 3rem 0 0; 679 | border: 1px solid #888; 680 | width: calc(100% + 1px); 681 | margin-left: -1px; 682 | } 683 | 684 | .character-set:first-child h3 { 685 | margin-top: 0; 686 | } 687 | 688 | .character-set div { 689 | display: grid; 690 | grid-template-columns: repeat(auto-fill, minmax(4rem, 1fr)); 691 | text-align: center; 692 | font-size: 1.75rem; 693 | line-height: 1; 694 | background: #f5f5f5; 695 | } 696 | 697 | .character-set i { 698 | height: 4rem; 699 | display: flex; 700 | justify-content: center; 701 | align-items: center; 702 | font-style: normal; 703 | background: #fff; 704 | border: 1px solid #888; 705 | margin: -1px 0 0 -1px; 706 | } 707 | 708 | 709 | /* === FONT STACKS === */ 710 | 711 | .system-ui { 712 | font-family: system-ui, sans-serif; 713 | } 714 | 715 | .transitional { 716 | font-family: Charter, 'Bitstream Charter', 'Sitka Text', Cambria, serif; 717 | } 718 | 719 | .old-style { 720 | font-family: 'Iowan Old Style', 'Palatino Linotype', 'URW Palladio L', P052, serif; 721 | } 722 | 723 | .humanist { 724 | font-family: Seravek, 'Gill Sans Nova', Ubuntu, Calibri, 'DejaVu Sans', source-sans-pro, sans-serif; 725 | } 726 | 727 | .geometric-humanist { 728 | font-family: Avenir, Montserrat, Corbel, 'URW Gothic', source-sans-pro, sans-serif; 729 | } 730 | 731 | .classical-humanist { 732 | font-family: Optima, Candara, 'Noto Sans', sans-serif; 733 | } 734 | 735 | .neo-grotesque { 736 | font-family: Inter, Roboto, 'Helvetica Neue', 'Arial Nova', 'Nimbus Sans', Arial, sans-serif; 737 | } 738 | 739 | .monospace-slab-serif { 740 | font-family: 'Nimbus Mono PS', 'Courier New', monospace; 741 | -webkit-font-smoothing: auto; 742 | -moz-osx-font-smoothing: auto; 743 | } 744 | 745 | .monospace-code { 746 | font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace; 747 | } 748 | 749 | .industrial { 750 | font-family: Bahnschrift, 'DIN Alternate', 'Franklin Gothic Medium', 'Nimbus Sans Narrow', sans-serif-condensed, sans-serif; 751 | } 752 | 753 | .rounded-sans { 754 | font-family: ui-rounded, 'Hiragino Maru Gothic ProN', Quicksand, Comfortaa, Manjari, 'Arial Rounded MT', 'Arial Rounded MT Bold', Calibri, source-sans-pro, sans-serif; 755 | } 756 | 757 | @font-face { 758 | font-family: 'Rockwell'; 759 | src: local('Rockwell'); 760 | ascent-override: 100%; 761 | } 762 | 763 | .slab-serif { 764 | font-family: Rockwell, 'Rockwell Nova', 'Roboto Slab', 'DejaVu Serif', 'Sitka Small', serif; 765 | } 766 | 767 | .antique { 768 | font-family: Superclarendon, 'Bookman Old Style', 'URW Bookman', 'URW Bookman L', 'Georgia Pro', Georgia, serif; 769 | } 770 | 771 | .didone { 772 | font-family: Didot, 'Bodoni MT', 'Noto Serif Display', 'URW Palladio L', P052, Sylfaen, serif; 773 | -webkit-font-smoothing: auto; 774 | -moz-osx-font-smoothing: auto; 775 | } 776 | 777 | .handwritten { 778 | font-family: 'Segoe Print', 'Bradley Hand', Chilanka, TSCu_Comic, casual, cursive; 779 | } 780 | 781 | /* === Footer === */ 782 | 783 | footer { 784 | padding: 2rem 1rem 2.25rem; 785 | background: #252525; 786 | color: #ccc; 787 | font-size: 0.875rem; 788 | line-height: 1.5; 789 | text-align: center; 790 | } 791 | 792 | footer a { 793 | color: inherit; 794 | text-decoration-color: #aaa; 795 | text-decoration-thickness: 1px; 796 | } 797 | 798 | @media (hover: hover) { 799 | footer a:hover { 800 | color: inherit; 801 | text-decoration-color: #fff; 802 | } 803 | } 804 | 805 | footer span { 806 | padding: 0 0.5rem; 807 | opacity: 0.5 808 | } 809 | 810 | 811 | /* === SM DESKTOP STYLES === */ 812 | @media (min-width: 42rem) { 813 | 814 | header h2 { 815 | font-size: 1.25rem; 816 | font-weight: 500; 817 | } 818 | 819 | header p { 820 | font-size: 1.125rem; 821 | } 822 | 823 | #menu details { 824 | position: fixed; 825 | } 826 | 827 | section > h2 { 828 | padding: 1.5rem 1rem; 829 | } 830 | 831 | .ui { 832 | min-height: 4.5rem; 833 | padding: 0 4rem; 834 | } 835 | 836 | #preview-text { 837 | width: auto; 838 | padding: 0.75rem; 839 | margin-left: 1rem; 840 | align-self: center; 841 | border: 2px solid #404040; 842 | } 843 | 844 | #fonts { 845 | display: grid; 846 | grid-template-columns: repeat(auto-fill, minmax(22rem, 1fr)); 847 | gap: 0 1.5rem; 848 | padding: 3rem 1.5rem 4rem; 849 | } 850 | 851 | .font-title { 852 | padding: 1.25rem 1rem; 853 | } 854 | 855 | .font-preview { 856 | padding: 1.5rem 1rem; 857 | } 858 | 859 | .font-weights { 860 | font-size: 1rem; 861 | padding: 1rem; 862 | } 863 | 864 | .font-stack { 865 | padding: 0.5rem 1rem 0.75rem; 866 | } 867 | 868 | #preview .ui { 869 | max-width: 84rem; 870 | min-height: 7.5rem; 871 | } 872 | 873 | #preview .ui summary { 874 | padding: 1rem 4rem; 875 | gap: 0.5rem 876 | } 877 | 878 | #preview article { 879 | font-size: 1.25rem; 880 | } 881 | 882 | #preview article .title { 883 | font-size: 3rem; 884 | } 885 | 886 | #preview article .chapter-name { 887 | font-size: 2rem; 888 | } 889 | 890 | #preview article img { 891 | margin: 0 -3rem 0 1.5rem; 892 | float: right; 893 | } 894 | 895 | .character-set div { 896 | grid-template-columns: repeat(auto-fill, minmax(3.75rem, 1fr)); 897 | font-size: 1.5rem; 898 | } 899 | 900 | .character-set span { 901 | height: 3.75rem; 902 | } 903 | 904 | } 905 | 906 | /* === MD DESKTOP STYLES === */ 907 | @media (min-width: 54rem) { 908 | 909 | #font-stacks-key .how-to-use { 910 | display: flex; 911 | } 912 | 913 | #font-stacks-key > div { 914 | flex: 0 auto; 915 | } 916 | 917 | } 918 | 919 | /* === LG DESKTOP STYLES === */ 920 | @media (min-width: 80rem) { 921 | 922 | #font-characters { 923 | padding: 3rem 1.5rem 6rem; 924 | column-count: 2; 925 | column-gap: 3rem; 926 | } 927 | 928 | .character-set { 929 | break-inside: avoid; 930 | } 931 | 932 | } 933 | 934 | 935 | /* === MOBILE STYLES === */ 936 | 937 | @media (max-width: 42rem) { 938 | 939 | #preview .ui button { 940 | display: none; 941 | } 942 | 943 | #preview button[data-on="true"] { 944 | display: block !important; 945 | pointer-events: none; 946 | } 947 | 948 | #preview button[data-on="true"]:after { 949 | content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='1.5' stroke='%23fff' width='24' height='24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M8.25 15L12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9' /%3E%3C/svg%3E%0A"); 950 | position: absolute; 951 | right: 6px; 952 | top: 6px; 953 | } 954 | 955 | #preview .ui[open] button { 956 | display: block; 957 | } 958 | 959 | #preview .ui[open] button[data-on="true"]:after { 960 | content: none; 961 | } 962 | } 963 | 964 | /* === TOUCH ONLY STYLES === */ 965 | 966 | @media (pointer: coarse) { 967 | 968 | .ui div input::-webkit-slider-thumb { 969 | width: 0.25rem; 970 | height: 2.75rem; 971 | background: linear-gradient(90deg, #fff0 0%, #fff0 47%, #fff 47%, #fff 53%, #fff0 53%, #fff0 100%); 972 | transform: scaleX(12); 973 | box-shadow: none; 974 | border-top: 0.75rem solid #000; 975 | border-bottom: 0.75rem solid #000; 976 | } 977 | 978 | .ui div input::-moz-range-thumb { 979 | width: 0.25rem; 980 | height: 2.75rem; 981 | background: linear-gradient(90deg, #fff0 0%, #fff0 47%, #fff 47%, #fff 53%, #fff0 53%, #fff0 100%); 982 | transform: scaleX(12); 983 | box-shadow: none; 984 | border-top: 0.75rem solid #000; 985 | border-bottom: 0.75rem solid #000; 986 | } 987 | 988 | } 989 | -------------------------------------------------------------------------------- /site/src/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/site/src/favicon.png -------------------------------------------------------------------------------- /site/src/img/og-modernfontstacks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/site/src/img/og-modernfontstacks.png -------------------------------------------------------------------------------- /site/src/img/white-rabbit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/system-fonts/modern-font-stacks/ba9ebcfcea446f47352aacb69ceca22b2e9d682c/site/src/img/white-rabbit.png -------------------------------------------------------------------------------- /site/src/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: --------------------------------------------------------------------------------