- commit
- 7814de5675c77b0724b49c0462437bb5fe09c0f8
- parent
- 405cc8922e99bb7b3d7cd79223e4b5820c965d5a
- author
- cat <admin@dev.site>
- ci
- ✓ passed in 76s, signed by cat
- kind
- feat risk score 1.8 of 3, Jev's estimate
- review
- #13 A design system: tokens, three fonts, no caps, real controls
ci attestation
forge-attestation 1 type ci commit 7814de5675c77b0724b49c0462437bb5fe09c0f8 tree bd4929ff077a19088725e323c9011e6ac1557b4c script .forge/ci 38df37c0d5a6382f60569079a0dd821094e37e4a result pass exit 0 started 2026-10-19T02:56:38Z duration 76s runner (not shown here; refs/notes/ci has it) system Darwin 25.5.0 arm64 env host log sha256:3a5f868f6485e32e2b906f468fbdda5527d89e5fee7c311fbaf31764a6787a18 253 lines |remote: review #4: /dami/greet/reviews/4/ |pushed wip/i18n |2e92bfd running .forge/ci: greet.sh: say what it is | | sh: /bin/sh | | ok greet |2e92bfd pass in 0s, signed |pushed main |remote: review #4: /dami/greet/reviews/4/ |pushed wip/i18n |8aa5f00 running .forge/ci: wave at the world | | sh: /bin/sh | | FAIL greet : got 'hello, world o/', want 'hello, world' |8aa5f00 fail in 0s, signed |forge: 1 commit(s) did not pass |remote: review #6: /dami/greet/reviews/6/ |pushed ana/wave |d2e2a0d running .forge/ci: update the test for the wave | | sh: /bin/sh | | ok greet |d2e2a0d pass in 0s, signed |remote: review #6: /dami/greet/reviews/6/ |pushed ana/wave |warning: You appear to have cloned an empty repository. |site home: deployed 9c8ab23 -> /sites/ana/dotfiles/home/ |created ana/notes |remote: review #1: /ana/notes/reviews/1/ |pushed ana/todo |landing #1 A todo list: ana/todo -> main |95ec728 running .forge/ci: web, server and Python versions of greet | | sh: /bin/sh | | ok greet |95ec728 pass in 0s, signed |pushed main |e07c2e1 running .forge/ci: messages: notes for the later regions | | sh: /bin/sh | | ok greet |e07c2e1 pass in 0s, signed |remote: review #7: /dami/greet/reviews/7/ |pushed dami/regions |created dami/forge |warning: You appear to have cloned an empty repository. |site guide: deployed 470f3bd -> /sites/dami/forge/guide/ |(node:50379) ExperimentalWarning: stripTypeScriptTypes is an experimental feature and might change at any time |(Use `node --trace-warnings ...` to show where the warning was created) |built ana/dotfiles in 1s -> /var/folders/b4/mv8w4c8j0zj0_mldppxdbdw00000gn/T/forge-ci.g2ioDS/wt/demo/root/.forge/www |(node:50503) ExperimentalWarning: stripTypeScriptTypes is an experimental feature and might change at any time |(Use `node --trace-warnings ...` to show where the warning was created) |built ana/notes in 0s -> /var/folders/b4/mv8w4c8j0zj0_mldppxdbdw00000gn/T/forge-ci.g2ioDS/wt/demo/root/.forge/www |(node:50641) ExperimentalWarning: stripTypeScriptTypes is an experimental feature and might change at any time |(Use `node --trace-warnings ...` to show where the warning was created) |built dami/forge in 1s -> /var/folders/b4/mv8w4c8j0zj0_mldppxdbdw00000gn/T/forge-ci.g2ioDS/wt/demo/root/.forge/www |(node:50772) ExperimentalWarning: stripTypeScriptTypes is an experimental feature and might change at any time |(Use `node --trace-warnings ...` to show where the warning was created) |built dami/greet in 1s -> /var/folders/b4/mv8w4c8j0zj0_mldppxdbdw00000gn/T/forge-ci.g2ioDS/wt/demo/root/.forge/www |(node:51447) ExperimentalWarning: stripTypeScriptTypes is an experimental feature and might change at any time |(Use `node --trace-warnings ...` to show where the warning was created) |built - in 1s -> /var/folders/b4/mv8w4c8j0zj0_mldppxdbdw00000gn/T/forge-ci.g2ioDS/wt/demo/root/.forge/www |226 of 226 pages render the same without 11ty |guide: 4 files, links ok |ok
Signature: good, cat
| M | lib/ | 18 | ++++-- |
| M | lib/ | 2 | +- |
| M | lib/ | 1 | + |
| M | site/ | 1 | + |
| A | site/ | 93 | ++++++++++++++++++++++++++++++ |
| A | site/ | 93 | ++++++++++++++++++++++++++++++ |
| A | site/ | 92 | ++++++++++++++++++++++++++++++ |
| A | site/ | 34 | +++++++++++ |
| A | site/ | bin | |
| A | site/ | bin | |
| A | site/ | bin | |
| A | site/ | bin | |
| M | site/ | 11 | +++- |
@@ -1,6 +1,7 @@
11 // Assets under content-hashed names, /assets/style.<hash>.css, so browsers2-// can cache them forever: the stylesheet, the logo, the vendored scripts,3-// our TypeScript with its types stripped, mermaid, sqlite-wasm (its script and2+// can cache them forever: the stylesheet, the logo, the fonts (in fonts/,3+// shipped next to the rest), the vendored scripts, our TypeScript with its4+// types stripped, mermaid, sqlite-wasm (its script and45 // its .wasm, for code search), and @simplewebauthn/browser (passkeys, on56 // the sign-in page). 11ty's bundle plugin67 // writes the templates' own CSS next to them, also named by a hash.@@ -17,6 +18,7 @@ import { fileURLToPath } from 'node:url';
1718 1819 const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');1920 const src = path.join(root, 'site', 'assets');21+const fonts = path.join(src, 'fonts');2022 const MERMAID = path.join(root, 'node_modules', 'mermaid', 'dist', 'mermaid.min.js');2123 const SQLITE = path.join(root, 'node_modules', '@sqlite.org', 'sqlite-wasm', 'dist');2224 const WEBAUTHN = path.join(root, 'node_modules', '@simplewebauthn', 'browser', 'dist', 'bundle', 'index.umd.min.js');@@ -42,7 +44,8 @@ export interface Asset {
4244 data: Buffer;4345 }4446 45-// By short name: style, logo, fixi, ssexi, diffs, keys, live,47+// By short name: style, logo, open-sans, noto-sans-mono, noto-serif,48+// noto-serif-italic, fixi, ssexi, diffs, keys, live,4649 // search, query, codesearch, login, ui, mermaid, sqlite3, sqlite3wasm, webauthn.4750 export type Assets = Record<string, Asset>;4851 @@ -51,6 +54,7 @@ let memo: { key: string; assets: Assets } | null = null;
5154 export function assets(): Assets {5255 const files: [string, string, string][] = [5356 ...fs.readdirSync(src).filter((f) => /\.(css|svg|webp|js|ts)$/.test(f)).sort().map((f): [string, string, string] => [f.split('.')[0], f, path.join(src, f)]),57+ ...fs.readdirSync(fonts).filter((f) => f.endsWith('.woff2')).sort().map((f): [string, string, string] => [f.split('.')[0], f, path.join(fonts, f)]),5458 ...VENDOR,5559 ];5660 // Rebuilt only when a source changes (the dev server rebuilds in one process).@@ -58,10 +62,10 @@ export function assets(): Assets {
5862 if (memo?.key === key) return memo.assets;5963 // Our scripts import each other as './query.ts', which Node and tsc read6064 // as it is; shipped, that is the other file's hashed name, so a script's61- // name changes with what it imports. A url(./x.webp) in the stylesheet62- // becomes that file's hashed name the same way.65+ // name changes with what it imports. A url(./fonts/x.woff2) in the66+ // stylesheet becomes that file's hashed name the same way, beside it.6367 const local = (base: string, dep: string): Asset => {64- const d = files.find(([, b, p]) => b === dep && path.dirname(p) === src);68+ const d = files.find(([, , p]) => path.relative(src, p) === dep);6569 if (!d) throw new Error(`${base} links ./${dep}, which is not in site/assets`);6670 return make(d);6771 };@@ -77,7 +81,7 @@ export function assets(): Assets {
7781 data = Buffer.from(js);7882 ext = '.js';7983 } else if (ext === '.css') {80- data = Buffer.from(data.toString('utf8').replace(/\burl\(\.\/([\w-]+\.\w+)\)/g, (_, dep: string) => `url(./${local(base, dep).file})`));84+ data = Buffer.from(data.toString('utf8').replace(/\burl\(\.\/((?:fonts\/)?[\w-]+\.\w+)\)/g, (_, dep: string) => `url(./${local(base, dep).file})`));8185 }8286 const a = { file: `${name}.${hash(data)}${ext}`, data };8387 made.set(short, a);@@ -257,7 +257,7 @@ export function privateHandler(cfg: PrivateConfig): http.RequestListener {
257257 const css = renderer?.bundles.get(url.pathname);258258 const data = a?.data ?? (css != null ? Buffer.from(css) : null);259259 if (!data) return notFound(res, req.method === 'HEAD');260- const type = /\.css$/.test(name) ? 'text/css; charset=utf-8' : /\.js$/.test(name) ? 'text/javascript; charset=utf-8' : /\.wasm$/.test(name) ? 'application/wasm' : /\.svg$/.test(name) ? 'image/svg+xml' : /\.webp$/.test(name) ? 'image/webp' : 'application/octet-stream';260+ const type = /\.css$/.test(name) ? 'text/css; charset=utf-8' : /\.js$/.test(name) ? 'text/javascript; charset=utf-8' : /\.wasm$/.test(name) ? 'application/wasm' : /\.svg$/.test(name) ? 'image/svg+xml' : /\.webp$/.test(name) ? 'image/webp' : /\.woff2$/.test(name) ? 'font/woff2' : 'application/octet-stream';261261 res.writeHead(200, { 'Content-Type': type, 'Cache-Control': 'public, max-age=31536000, immutable', 'Content-Length': data.length });262262 res.end(req.method === 'HEAD' ? undefined : data);263263 }@@ -10,6 +10,7 @@ import type http from 'node:http';
1010 export const TYPES: Record<string, string> = {1111 '.html': 'text/html; charset=utf-8', '.css': 'text/css; charset=utf-8', '.js': 'text/javascript; charset=utf-8', '.svg': 'image/svg+xml',1212 '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.gif': 'image/gif', '.webp': 'image/webp', '.avif': 'image/avif', '.ico': 'image/x-icon',13+ '.woff2': 'font/woff2',1314 '.txt': 'text/plain; charset=utf-8', '.xml': 'application/xml', '.json': 'application/json', '.wasm': 'application/wasm', '.db': 'application/vnd.sqlite3', '.parquet': 'application/vnd.apache.parquet',1415 };1516 @@ -11,6 +11,7 @@
1111 <meta name="viewport" content="width=device-width, initial-scale=1">1212 <title>{% block title %}{{ p.title if p and p.title else forge.config.name }}{% endblock %}</title>1313 <link rel="icon" href="{{ assets.logo }}" type="image/svg+xml">14+<link rel="preload" href="{{ assets['open-sans'] }}" as="font" type="font/woff2" crossorigin>1415 <link rel="stylesheet" href="{{ assets.style }}">1516 {# The CSS that this page's templates and includes carry ({% css %}). -#}1617 <link rel="stylesheet" href="{% getBundleFileUrl "css" %}">@@ -0,0 +1,93 @@
1+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/latin-greek-cyrillic)2+3+This Font Software is licensed under the SIL Open Font License, Version 1.1.4+This license is copied below, and is also available with a FAQ at:5+https://scripts.sil.org/OFL6+7+8+-----------------------------------------------------------9+SIL OPEN FONT LICENSE Version 1.1 - 26 February 200710+-----------------------------------------------------------11+12+PREAMBLE13+The goals of the Open Font License (OFL) are to stimulate worldwide14+development of collaborative font projects, to support the font creation15+efforts of academic and linguistic communities, and to provide a free and16+open framework in which fonts may be shared and improved in partnership17+with others.18+19+The OFL allows the licensed fonts to be used, studied, modified and20+redistributed freely as long as they are not sold by themselves. The21+fonts, including any derivative works, can be bundled, embedded, 22+redistributed and/or sold with any software provided that any reserved23+names are not used by derivative works. The fonts and derivatives,24+however, cannot be released under any other type of license. The25+requirement for fonts to remain under this license does not apply26+to any document created using the fonts or their derivatives.27+28+DEFINITIONS29+"Font Software" refers to the set of files released by the Copyright30+Holder(s) under this license and clearly marked as such. This may31+include source files, build scripts and documentation.32+33+"Reserved Font Name" refers to any names specified as such after the34+copyright statement(s).35+36+"Original Version" refers to the collection of Font Software components as37+distributed by the Copyright Holder(s).38+39+"Modified Version" refers to any derivative made by adding to, deleting,40+or substituting -- in part or in whole -- any of the components of the41+Original Version, by changing formats or by porting the Font Software to a42+new environment.43+44+"Author" refers to any designer, engineer, programmer, technical45+writer or other person who contributed to the Font Software.46+47+PERMISSION & CONDITIONS48+Permission is hereby granted, free of charge, to any person obtaining49+a copy of the Font Software, to use, study, copy, merge, embed, modify,50+redistribute, and sell modified and unmodified copies of the Font51+Software, subject to the following conditions:52+53+1) Neither the Font Software nor any of its individual components,54+in Original or Modified Versions, may be sold by itself.55+56+2) Original or Modified Versions of the Font Software may be bundled,57+redistributed and/or sold with any software, provided that each copy58+contains the above copyright notice and this license. These can be59+included either as stand-alone text files, human-readable headers or60+in the appropriate machine-readable metadata fields within text or61+binary files as long as those fields can be easily viewed by the user.62+63+3) No Modified Version of the Font Software may use the Reserved Font64+Name(s) unless explicit written permission is granted by the corresponding65+Copyright Holder. This restriction only applies to the primary font name as66+presented to the users.67+68+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font69+Software shall not be used to promote, endorse or advertise any70+Modified Version, except to acknowledge the contribution(s) of the71+Copyright Holder(s) and the Author(s) or with their explicit written72+permission.73+74+5) The Font Software, modified or unmodified, in part or in whole,75+must be distributed entirely under this license, and must not be76+distributed under any other license. The requirement for fonts to77+remain under this license does not apply to any document created78+using the Font Software.79+80+TERMINATION81+This license becomes null and void if any of the above conditions are82+not met.83+84+DISCLAIMER85+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,86+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF87+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT88+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE89+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,90+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL91+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING92+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM93+OTHER DEALINGS IN THE FONT SOFTWARE.@@ -0,0 +1,93 @@
1+Copyright 2022 The Noto Project Authors (https://github.com/notofonts/latin-greek-cyrillic)2+3+This Font Software is licensed under the SIL Open Font License, Version 1.1.4+This license is copied below, and is also available with a FAQ at:5+https://scripts.sil.org/OFL6+7+8+-----------------------------------------------------------9+SIL OPEN FONT LICENSE Version 1.1 - 26 February 200710+-----------------------------------------------------------11+12+PREAMBLE13+The goals of the Open Font License (OFL) are to stimulate worldwide14+development of collaborative font projects, to support the font creation15+efforts of academic and linguistic communities, and to provide a free and16+open framework in which fonts may be shared and improved in partnership17+with others.18+19+The OFL allows the licensed fonts to be used, studied, modified and20+redistributed freely as long as they are not sold by themselves. The21+fonts, including any derivative works, can be bundled, embedded, 22+redistributed and/or sold with any software provided that any reserved23+names are not used by derivative works. The fonts and derivatives,24+however, cannot be released under any other type of license. The25+requirement for fonts to remain under this license does not apply26+to any document created using the fonts or their derivatives.27+28+DEFINITIONS29+"Font Software" refers to the set of files released by the Copyright30+Holder(s) under this license and clearly marked as such. This may31+include source files, build scripts and documentation.32+33+"Reserved Font Name" refers to any names specified as such after the34+copyright statement(s).35+36+"Original Version" refers to the collection of Font Software components as37+distributed by the Copyright Holder(s).38+39+"Modified Version" refers to any derivative made by adding to, deleting,40+or substituting -- in part or in whole -- any of the components of the41+Original Version, by changing formats or by porting the Font Software to a42+new environment.43+44+"Author" refers to any designer, engineer, programmer, technical45+writer or other person who contributed to the Font Software.46+47+PERMISSION & CONDITIONS48+Permission is hereby granted, free of charge, to any person obtaining49+a copy of the Font Software, to use, study, copy, merge, embed, modify,50+redistribute, and sell modified and unmodified copies of the Font51+Software, subject to the following conditions:52+53+1) Neither the Font Software nor any of its individual components,54+in Original or Modified Versions, may be sold by itself.55+56+2) Original or Modified Versions of the Font Software may be bundled,57+redistributed and/or sold with any software, provided that each copy58+contains the above copyright notice and this license. These can be59+included either as stand-alone text files, human-readable headers or60+in the appropriate machine-readable metadata fields within text or61+binary files as long as those fields can be easily viewed by the user.62+63+3) No Modified Version of the Font Software may use the Reserved Font64+Name(s) unless explicit written permission is granted by the corresponding65+Copyright Holder. This restriction only applies to the primary font name as66+presented to the users.67+68+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font69+Software shall not be used to promote, endorse or advertise any70+Modified Version, except to acknowledge the contribution(s) of the71+Copyright Holder(s) and the Author(s) or with their explicit written72+permission.73+74+5) The Font Software, modified or unmodified, in part or in whole,75+must be distributed entirely under this license, and must not be76+distributed under any other license. The requirement for fonts to77+remain under this license does not apply to any document created78+using the Font Software.79+80+TERMINATION81+This license becomes null and void if any of the above conditions are82+not met.83+84+DISCLAIMER85+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,86+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF87+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT88+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE89+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,90+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL91+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING92+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM93+OTHER DEALINGS IN THE FONT SOFTWARE.@@ -0,0 +1,92 @@
1+Copyright 2020 The Open Sans Project Authors (https://github.com/googlefonts/opensans)2+3+This Font Software is licensed under the SIL Open Font License, Version 1.1.4+This license is copied below, and is also available with a FAQ at:5+https://scripts.sil.org/OFL6+7+-----------------------------------------------------------8+SIL OPEN FONT LICENSE Version 1.1 - 26 February 20079+-----------------------------------------------------------10+11+PREAMBLE12+The goals of the Open Font License (OFL) are to stimulate worldwide13+development of collaborative font projects, to support the font14+creation efforts of academic and linguistic communities, and to15+provide a free and open framework in which fonts may be shared and16+improved in partnership with others.17+18+The OFL allows the licensed fonts to be used, studied, modified and19+redistributed freely as long as they are not sold by themselves. The20+fonts, including any derivative works, can be bundled, embedded,21+redistributed and/or sold with any software provided that any reserved22+names are not used by derivative works. The fonts and derivatives,23+however, cannot be released under any other type of license. The24+requirement for fonts to remain under this license does not apply to25+any document created using the fonts or their derivatives.26+27+DEFINITIONS28+"Font Software" refers to the set of files released by the Copyright29+Holder(s) under this license and clearly marked as such. This may30+include source files, build scripts and documentation.31+32+"Reserved Font Name" refers to any names specified as such after the33+copyright statement(s).34+35+"Original Version" refers to the collection of Font Software36+components as distributed by the Copyright Holder(s).37+38+"Modified Version" refers to any derivative made by adding to,39+deleting, or substituting -- in part or in whole -- any of the40+components of the Original Version, by changing formats or by porting41+the Font Software to a new environment.42+43+"Author" refers to any designer, engineer, programmer, technical44+writer or other person who contributed to the Font Software.45+46+PERMISSION & CONDITIONS47+Permission is hereby granted, free of charge, to any person obtaining48+a copy of the Font Software, to use, study, copy, merge, embed,49+modify, redistribute, and sell modified and unmodified copies of the50+Font Software, subject to the following conditions:51+52+1) Neither the Font Software nor any of its individual components, in53+Original or Modified Versions, may be sold by itself.54+55+2) Original or Modified Versions of the Font Software may be bundled,56+redistributed and/or sold with any software, provided that each copy57+contains the above copyright notice and this license. These can be58+included either as stand-alone text files, human-readable headers or59+in the appropriate machine-readable metadata fields within text or60+binary files as long as those fields can be easily viewed by the user.61+62+3) No Modified Version of the Font Software may use the Reserved Font63+Name(s) unless explicit written permission is granted by the64+corresponding Copyright Holder. This restriction only applies to the65+primary font name as presented to the users.66+67+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font68+Software shall not be used to promote, endorse or advertise any69+Modified Version, except to acknowledge the contribution(s) of the70+Copyright Holder(s) and the Author(s) or with their explicit written71+permission.72+73+5) The Font Software, modified or unmodified, in part or in whole,74+must be distributed entirely under this license, and must not be75+distributed under any other license. The requirement for fonts to76+remain under this license does not apply to any document created using77+the Font Software.78+79+TERMINATION80+This license becomes null and void if any of the above conditions are81+not met.82+83+DISCLAIMER84+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,85+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF86+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT87+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE88+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,89+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL90+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING91+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM92+OTHER DEALINGS IN THE FONT SOFTWARE.@@ -0,0 +1,34 @@
1+2+# How the fonts here were made; the forge never runs this, it serves the3+# outputs. Sources: the variable fonts in google/fonts (ofl/), under the SIL4+# Open Font License (each family's OFL-*.txt is next to its fonts).5+#6+# python3 -m venv /tmp/fonts-venv && /tmp/fonts-venv/bin/pip install fonttools brotli7+# PATH=/tmp/fonts-venv/bin:$PATH sh site/assets/fonts/make-fonts.sh <dir of sources>8+#9+# <dir> holds OpenSans[wdth,wght].ttf, NotoSansMono[wdth,wght].ttf,10+# NotoSerif[wdth,wght].ttf and NotoSerif-Italic[wdth,wght].ttf. Each is11+# pinned to its normal width (the pages never change it) and keeps a weight12+# range, then is cut down to Latin, the punctuation, and the arrows, ticks,13+# triangles and box drawing the templates print; a glyph a font lacks14+# comes from the system's fonts.15+set -eu16+src=${1:?usage: make-fonts.sh <dir of source .ttf files>}17+here=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)18+tmp=$(mktemp -d)19+trap 'rm -rf "$tmp"' EXIT20+# Basic Latin, Latin-1, the Latin Extended-A letters of European languages,21+# general punctuation, the euro and trade marks, arrows, minus and the22+# comparison signs, the branch sign, box drawing (stack indents), small23+# triangles (folds) and ticks and crosses (CI).24+uni='U+0020-007E,U+00A0-00FF,U+0100-017F,U+0192,U+02C6,U+02DA,U+02DC,U+2000-206F,U+20AC,U+2122,U+2190-21FF,U+2212,U+2260,U+2264-2265,U+2387,U+2500-257F,U+25B4-25BF,U+2713-2717'25+make() { # make <source> <out> <weights>26+ fonttools varLib.instancer -q -o "$tmp/$2.ttf" "$src/$1" wdth=100 "wght=$3"27+ pyftsubset "$tmp/$2.ttf" --unicodes="$uni" --layout-features+=tnum,zero,case --flavor=woff2 \28+ --no-hinting --desubroutinize --output-file="$here/$2.woff2"29+}30+make 'OpenSans[wdth,wght].ttf' open-sans 300:80031+make 'NotoSansMono[wdth,wght].ttf' noto-sans-mono 400:70032+make 'NotoSerif[wdth,wght].ttf' noto-serif 400:70033+make 'NotoSerif-Italic[wdth,wght].ttf' noto-serif-italic 400:70034+ls -l "$here"/*.woff2Binary file.
Binary file.
Binary file.
Binary file.
@@ -4,6 +4,12 @@
44 /* The look: square corners, content on the page between 1px rules, labels55 in small uppercase monospace, one accent (#3148F6) for links, the current66 tab's bar, focus and primary actions, on a plain page. */7+/* The fonts, self-hosted, variable in weight, cut to Latin and the symbols8+ the pages print (fonts/make-fonts.sh). The sans is preloaded (base.njk). */9+@font-face { font-family: "Open Sans"; src: url(./fonts/open-sans.woff2) format("woff2"); font-weight: 300 800; font-style: normal; font-display: swap; }10+@font-face { font-family: "Noto Sans Mono"; src: url(./fonts/noto-sans-mono.woff2) format("woff2"); font-weight: 400 700; font-style: normal; font-display: swap; }11+@font-face { font-family: "Noto Serif"; src: url(./fonts/noto-serif.woff2) format("woff2"); font-weight: 400 700; font-style: normal; font-display: swap; }12+@font-face { font-family: "Noto Serif"; src: url(./fonts/noto-serif-italic.woff2) format("woff2"); font-weight: 400 700; font-style: italic; font-display: swap; }713 :root {814 --bg: #e9e9e9;915 --fg: #1c2127;@@ -30,8 +36,9 @@
3036 --fail: #c7162b;3137 --warn: #b46a00;3238 --merged: #3148f6;33- --sans: "Ubuntu", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;34- --mono: ui-monospace, SFMono-Regular, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;39+ --sans: "Open Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;40+ --mono: "Noto Sans Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;41+ --serif: "Noto Serif", Georgia, Cambria, "Times New Roman", serif;3542 color-scheme: light dark;3643 }3744 @media (prefers-color-scheme: dark) {