Milestone v1 (v2.0.0): Mokosh — Session Capture #1
134
scripts/subset-fonts.sh
Executable file
134
scripts/subset-fonts.sh
Executable file
@@ -0,0 +1,134 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# scripts/subset-fonts.sh — Plan 01-12 Wave 1 Task 1.
|
||||||
|
#
|
||||||
|
# One-off subsetting recipe for the Mokosh design-integration font bundle:
|
||||||
|
#
|
||||||
|
# Lora variable (normal + italic, axis wght 400-700) — display family per
|
||||||
|
# R2 designer reply 2026-05-19 (substitutes Newsreader for Cyrillic
|
||||||
|
# coverage; Cyreal foundry, OFL-1.1)
|
||||||
|
# IBM Plex Sans (Regular, Medium, SemiBold, Bold) — UI body family
|
||||||
|
# IBM Plex Mono (Regular, Medium) — diagnostic / timer family
|
||||||
|
#
|
||||||
|
# All faces are subsetted to Latin (U+0020-007E + U+00A0-00FF) + Cyrillic
|
||||||
|
# basic (U+0400-045F + supplemental code points) per RESEARCH §1 + §6.
|
||||||
|
# Total bundled artifact target: ~250-300 KB per R2 substitution adjustment.
|
||||||
|
#
|
||||||
|
# Upstream sources:
|
||||||
|
# Lora-Cyrillic: https://github.com/cyrealtype/Lora-Cyrillic (main branch)
|
||||||
|
# IBM Plex: https://github.com/IBM/plex (master branch)
|
||||||
|
#
|
||||||
|
# Output: src/shared/fonts/*.woff2 (7 or 8 files depending on Lora italic
|
||||||
|
# upstream layout — A5 in RESEARCH Assumptions Log).
|
||||||
|
#
|
||||||
|
# Re-run trigger: when the upstream Lora-Cyrillic or IBM/plex releases
|
||||||
|
# bump a major version with bug fixes; or when the UNICODES range needs
|
||||||
|
# expansion (Cyrillic supplement, extra punctuation). The committed
|
||||||
|
# WOFF2 files are the source of truth — running this script overwrites
|
||||||
|
# them only on intentional regeneration.
|
||||||
|
#
|
||||||
|
# References:
|
||||||
|
# - fontTools pyftsubset:
|
||||||
|
# https://fonttools.readthedocs.io/en/latest/subset/index.html
|
||||||
|
# - WOFF2 (RFC 8081): https://www.rfc-editor.org/rfc/rfc8081
|
||||||
|
# - OFL-1.1 best practices: https://scripts.sil.org/OFL_web
|
||||||
|
#
|
||||||
|
# Google bash style applies; see https://google.github.io/styleguide/shellguide.html
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
readonly REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||||
|
readonly FONTS_OUT_DIR="${REPO_ROOT}/src/shared/fonts"
|
||||||
|
|
||||||
|
# Subset coverage per RESEARCH §1 + §6:
|
||||||
|
# Latin core U+0020-007E
|
||||||
|
# Latin supplement U+00A0-00FF (covers Cyrillic context: nbsp, ©, ®, ™ etc.)
|
||||||
|
# Latin extended bits U+0131 (dotless i), U+0152-0153 (Œœ), U+0301 (combining acute)
|
||||||
|
# Cyrillic basic U+0400-045F (full RU + UA basic alphabet)
|
||||||
|
# Cyrillic supplement U+0490-0491 (Ґґ), U+04B0-04B1 (Ұұ — Kazakh)
|
||||||
|
# Numero sign U+2116 (№ — common Russian punctuation)
|
||||||
|
readonly UNICODES='U+0020-007E,U+00A0-00FF,U+0131,U+0152-0153,U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116'
|
||||||
|
|
||||||
|
# Common pyftsubset flags shared across faces.
|
||||||
|
readonly -a PYFTSUBSET_FLAGS=(
|
||||||
|
"--unicodes=${UNICODES}"
|
||||||
|
'--flavor=woff2'
|
||||||
|
"--layout-features=*"
|
||||||
|
'--no-hinting'
|
||||||
|
'--desubroutinize'
|
||||||
|
'--name-IDs=*'
|
||||||
|
'--name-legacy'
|
||||||
|
'--name-languages=*'
|
||||||
|
)
|
||||||
|
|
||||||
|
# subset_face <input-ttf> <output-woff2>
|
||||||
|
subset_face() {
|
||||||
|
local -r input_ttf="$1"
|
||||||
|
local -r output_woff2="$2"
|
||||||
|
if [[ ! -f "${input_ttf}" ]]; then
|
||||||
|
echo "ERROR: input TTF not found: ${input_ttf}" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
pyftsubset "${input_ttf}" \
|
||||||
|
"${PYFTSUBSET_FLAGS[@]}" \
|
||||||
|
"--output-file=${output_woff2}"
|
||||||
|
local -r bytes="$(stat -c%s "${output_woff2}")"
|
||||||
|
echo " subsetted: ${output_woff2} (${bytes} bytes)"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local -r scratch="${1:-}"
|
||||||
|
if [[ -z "${scratch}" || ! -d "${scratch}" ]]; then
|
||||||
|
cat >&2 <<EOF
|
||||||
|
Usage: $(basename "$0") <scratch-dir>
|
||||||
|
|
||||||
|
<scratch-dir> must contain the upstream TTFs:
|
||||||
|
Lora-VariableFont_wght.ttf
|
||||||
|
Lora-Italic-VariableFont_wght.ttf
|
||||||
|
IBMPlexSans-Regular.ttf, -Medium.ttf, -SemiBold.ttf, -Bold.ttf
|
||||||
|
IBMPlexMono-Regular.ttf, -Medium.ttf
|
||||||
|
|
||||||
|
Fetch recipe:
|
||||||
|
SCRATCH=\$(mktemp -d)
|
||||||
|
curl -L -o "\${SCRATCH}/Lora-VariableFont_wght.ttf" \\
|
||||||
|
"https://raw.githubusercontent.com/cyrealtype/Lora-Cyrillic/main/fonts/variable/Lora%5Bwght%5D.ttf"
|
||||||
|
curl -L -o "\${SCRATCH}/Lora-Italic-VariableFont_wght.ttf" \\
|
||||||
|
"https://raw.githubusercontent.com/cyrealtype/Lora-Cyrillic/main/fonts/variable/Lora-Italic%5Bwght%5D.ttf"
|
||||||
|
for v in Regular Medium SemiBold Bold; do
|
||||||
|
curl -L -o "\${SCRATCH}/IBMPlexSans-\${v}.ttf" \\
|
||||||
|
"https://raw.githubusercontent.com/IBM/plex/master/packages/plex-sans/fonts/complete/ttf/IBMPlexSans-\${v}.ttf"
|
||||||
|
done
|
||||||
|
for v in Regular Medium; do
|
||||||
|
curl -L -o "\${SCRATCH}/IBMPlexMono-\${v}.ttf" \\
|
||||||
|
"https://raw.githubusercontent.com/IBM/plex/master/packages/plex-mono/fonts/complete/ttf/IBMPlexMono-\${v}.ttf"
|
||||||
|
done
|
||||||
|
EOF
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "${FONTS_OUT_DIR}"
|
||||||
|
|
||||||
|
echo "==> Subsetting Lora (variable, Cyreal foundry; R2 substitute for Newsreader)"
|
||||||
|
subset_face "${scratch}/Lora-VariableFont_wght.ttf" "${FONTS_OUT_DIR}/Lora-VariableFont.woff2"
|
||||||
|
subset_face "${scratch}/Lora-Italic-VariableFont_wght.ttf" "${FONTS_OUT_DIR}/Lora-Italic-VariableFont.woff2"
|
||||||
|
|
||||||
|
echo "==> Subsetting IBM Plex Sans (4 weights)"
|
||||||
|
local variant
|
||||||
|
for variant in Regular Medium SemiBold Bold; do
|
||||||
|
subset_face "${scratch}/IBMPlexSans-${variant}.ttf" "${FONTS_OUT_DIR}/IBMPlexSans-${variant}.woff2"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "==> Subsetting IBM Plex Mono (2 weights)"
|
||||||
|
for variant in Regular Medium; do
|
||||||
|
subset_face "${scratch}/IBMPlexMono-${variant}.ttf" "${FONTS_OUT_DIR}/IBMPlexMono-${variant}.woff2"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "==> Bundle summary:"
|
||||||
|
du -ch "${FONTS_OUT_DIR}"/*.woff2 | tail -1
|
||||||
|
echo
|
||||||
|
echo "==> Done. Files emitted under ${FONTS_OUT_DIR}."
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
BIN
src/shared/fonts/IBMPlexMono-Medium.woff2
Normal file
BIN
src/shared/fonts/IBMPlexMono-Medium.woff2
Normal file
Binary file not shown.
BIN
src/shared/fonts/IBMPlexMono-Regular.woff2
Normal file
BIN
src/shared/fonts/IBMPlexMono-Regular.woff2
Normal file
Binary file not shown.
BIN
src/shared/fonts/IBMPlexSans-Bold.woff2
Normal file
BIN
src/shared/fonts/IBMPlexSans-Bold.woff2
Normal file
Binary file not shown.
BIN
src/shared/fonts/IBMPlexSans-Medium.woff2
Normal file
BIN
src/shared/fonts/IBMPlexSans-Medium.woff2
Normal file
Binary file not shown.
BIN
src/shared/fonts/IBMPlexSans-Regular.woff2
Normal file
BIN
src/shared/fonts/IBMPlexSans-Regular.woff2
Normal file
Binary file not shown.
BIN
src/shared/fonts/IBMPlexSans-SemiBold.woff2
Normal file
BIN
src/shared/fonts/IBMPlexSans-SemiBold.woff2
Normal file
Binary file not shown.
93
src/shared/fonts/LICENSE-IBM-Plex.txt
Normal file
93
src/shared/fonts/LICENSE-IBM-Plex.txt
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
Copyright © 2017 IBM Corp. with Reserved Font Name "Plex"
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
|
||||||
|
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
93
src/shared/fonts/LICENSE-Lora.txt
Normal file
93
src/shared/fonts/LICENSE-Lora.txt
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
Copyright 2011 The Lora Project Authors (https://github.com/cyrealtype/Lora-Cyrillic), with Reserved Font Name "Lora".
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
https://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
BIN
src/shared/fonts/Lora-Italic-VariableFont.woff2
Normal file
BIN
src/shared/fonts/Lora-Italic-VariableFont.woff2
Normal file
Binary file not shown.
BIN
src/shared/fonts/Lora-VariableFont.woff2
Normal file
BIN
src/shared/fonts/Lora-VariableFont.woff2
Normal file
Binary file not shown.
137
src/shared/fonts/README.md
Normal file
137
src/shared/fonts/README.md
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
# Self-hosted fonts — Mokosh design integration
|
||||||
|
|
||||||
|
These WOFF2 files are bundled with the extension and loaded at runtime
|
||||||
|
via the `@font-face` rules in `../tokens.css`. MV3 CSP (`style-src 'self'`
|
||||||
|
+ `font-src 'self'`) forbids remote `@import` URLs at runtime; the
|
||||||
|
production `tokens.css` therefore references local `./fonts/*.woff2`
|
||||||
|
paths exclusively.
|
||||||
|
|
||||||
|
## What's bundled
|
||||||
|
|
||||||
|
| File | Family | Weight axis | Style | Size | Source |
|
||||||
|
|-----------------------------------|------------------|-------------|--------|-------|------------------------------------------|
|
||||||
|
| `Lora-VariableFont.woff2` | Lora | 400-700 | normal | ~49KB | cyrealtype/Lora-Cyrillic (Cyreal, OFL) |
|
||||||
|
| `Lora-Italic-VariableFont.woff2` | Lora | 400-700 | italic | ~53KB | cyrealtype/Lora-Cyrillic (Cyreal, OFL) |
|
||||||
|
| `IBMPlexSans-Regular.woff2` | IBM Plex Sans | 400 fixed | normal | ~24KB | IBM/plex (master, OFL) |
|
||||||
|
| `IBMPlexSans-Medium.woff2` | IBM Plex Sans | 500 fixed | normal | ~25KB | IBM/plex |
|
||||||
|
| `IBMPlexSans-SemiBold.woff2` | IBM Plex Sans | 600 fixed | normal | ~25KB | IBM/plex |
|
||||||
|
| `IBMPlexSans-Bold.woff2` | IBM Plex Sans | 700 fixed | normal | ~23KB | IBM/plex |
|
||||||
|
| `IBMPlexMono-Regular.woff2` | IBM Plex Mono | 400 fixed | normal | ~15KB | IBM/plex |
|
||||||
|
| `IBMPlexMono-Medium.woff2` | IBM Plex Mono | 500 fixed | normal | ~15KB | IBM/plex |
|
||||||
|
|
||||||
|
Total bundle: ~236 KB after subsetting.
|
||||||
|
|
||||||
|
## R2 designer substitution (2026-05-19)
|
||||||
|
|
||||||
|
The original D-05 design pairing called for **Newsreader** as the display
|
||||||
|
serif. Per designer reply 2026-05-19 (followed up at
|
||||||
|
`.planning/intel/brand-decisions-v1-followup-display-font.md`),
|
||||||
|
**Lora** replaces Newsreader because:
|
||||||
|
|
||||||
|
1. Lora ships with full **Cyrillic basic** coverage via the Cyreal
|
||||||
|
foundry release (designed by Olga Karpushina). Newsreader's Cyrillic
|
||||||
|
was partial / inconsistent across weights.
|
||||||
|
2. Lora is a single **variable font** (axis `wght` 400-700) — one face
|
||||||
|
covers the entire range rather than four separate static weights.
|
||||||
|
3. License is the same SIL OFL-1.1 + free for commercial use.
|
||||||
|
|
||||||
|
Both normal and italic upstream files are bundled separately because
|
||||||
|
Lora-Cyrillic releases italic as its own variable file (axis `wght`,
|
||||||
|
same range). Verified via the upstream GitHub contents API at execute
|
||||||
|
time per RESEARCH §A5.
|
||||||
|
|
||||||
|
## Subset coverage
|
||||||
|
|
||||||
|
All faces are subsetted via `pyftsubset` to:
|
||||||
|
|
||||||
|
```
|
||||||
|
U+0020-007E (Latin core: ASCII printable)
|
||||||
|
U+00A0-00FF (Latin-1 supplement: nbsp, ©, ®, ™, etc.)
|
||||||
|
U+0131 (dotless i)
|
||||||
|
U+0152-0153 (Œœ)
|
||||||
|
U+0301 (combining acute accent)
|
||||||
|
U+0400-045F (Cyrillic basic: full Russian + Ukrainian alphabet)
|
||||||
|
U+0490-0491 (Ґґ — Ukrainian)
|
||||||
|
U+04B0-04B1 (Ұұ — Kazakh)
|
||||||
|
U+2116 (№ — common Russian punctuation)
|
||||||
|
```
|
||||||
|
|
||||||
|
This is sufficient for the operator-facing copy specified in
|
||||||
|
`_locales/{en,ru}/messages.json` and the welcome page hero (per
|
||||||
|
brand-decisions-v1.md D-08 tagline).
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
All faces ship under SIL OFL-1.1:
|
||||||
|
|
||||||
|
- `LICENSE-Lora.txt` — verbatim copy of the Lora-Cyrillic OFL.txt header
|
||||||
|
+ Lora Project Authors copyright.
|
||||||
|
- `LICENSE-IBM-Plex.txt` — verbatim copy of IBM/plex LICENSE.txt + IBM
|
||||||
|
Corp. copyright.
|
||||||
|
|
||||||
|
Per OFL-1.1 §4 (Reserved Font Name): keep the original family names
|
||||||
|
(`Lora`, `IBM Plex Sans`, `IBM Plex Mono`) when distributing the
|
||||||
|
subsetted derivatives, since neither family name is being modified.
|
||||||
|
|
||||||
|
## Regeneration recipe
|
||||||
|
|
||||||
|
Network access required (upstream is GitHub).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
SCRATCH=$(mktemp -d)
|
||||||
|
|
||||||
|
# Lora variable + italic (Cyreal foundry)
|
||||||
|
curl -L -o "${SCRATCH}/Lora-VariableFont_wght.ttf" \
|
||||||
|
'https://raw.githubusercontent.com/cyrealtype/Lora-Cyrillic/main/fonts/variable/Lora%5Bwght%5D.ttf'
|
||||||
|
curl -L -o "${SCRATCH}/Lora-Italic-VariableFont_wght.ttf" \
|
||||||
|
'https://raw.githubusercontent.com/cyrealtype/Lora-Cyrillic/main/fonts/variable/Lora-Italic%5Bwght%5D.ttf'
|
||||||
|
|
||||||
|
# IBM Plex Sans (4 weights)
|
||||||
|
for v in Regular Medium SemiBold Bold; do
|
||||||
|
curl -L -o "${SCRATCH}/IBMPlexSans-${v}.ttf" \
|
||||||
|
"https://raw.githubusercontent.com/IBM/plex/master/packages/plex-sans/fonts/complete/ttf/IBMPlexSans-${v}.ttf"
|
||||||
|
done
|
||||||
|
|
||||||
|
# IBM Plex Mono (2 weights)
|
||||||
|
for v in Regular Medium; do
|
||||||
|
curl -L -o "${SCRATCH}/IBMPlexMono-${v}.ttf" \
|
||||||
|
"https://raw.githubusercontent.com/IBM/plex/master/packages/plex-mono/fonts/complete/ttf/IBMPlexMono-${v}.ttf"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Run the subsetter
|
||||||
|
scripts/subset-fonts.sh "${SCRATCH}"
|
||||||
|
|
||||||
|
# Verify outputs
|
||||||
|
ls -la src/shared/fonts/*.woff2
|
||||||
|
du -ch src/shared/fonts/*.woff2 | tail -1
|
||||||
|
```
|
||||||
|
|
||||||
|
After regeneration, run the test gate:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
SKIP_BUILD=1 npx vitest run tests/build/fonts-present.test.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
## Why not Google Fonts CDN at runtime
|
||||||
|
|
||||||
|
MV3 manifest CSP enforces `style-src 'self'` and `font-src 'self'`. A
|
||||||
|
`@import url(https://fonts.googleapis.com/...)` line in `tokens.css`
|
||||||
|
would fail at runtime with a `Content Security Policy: The page's
|
||||||
|
settings blocked the loading of a resource...` error.
|
||||||
|
|
||||||
|
The handoff `tokens.css` in `.planning/intel/design-incoming/` carries a
|
||||||
|
preview-only Google Fonts `@import` (line 12) marked as "loaded from
|
||||||
|
Google Fonts in PREVIEW HTML only" — `src/shared/tokens.css` replaces
|
||||||
|
that line with the seven local `@font-face` rules pointing at this
|
||||||
|
directory.
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- `.planning/phases/01-stabilize-video-pipeline/01-12-PLAN.md` —
|
||||||
|
authoritative plan for this design integration
|
||||||
|
- `.planning/phases/01-stabilize-video-pipeline/01-12-RESEARCH.md` —
|
||||||
|
research basis (typography pairing, R2 substitution rationale,
|
||||||
|
subsetting recipe)
|
||||||
|
- `.planning/intel/brand-decisions-v1.md` D-05 — typography pairing
|
||||||
|
- `.planning/intel/brand-decisions-v1-followup-display-font.md` — R2
|
||||||
|
Lora substitution context (designer reply 2026-05-19)
|
||||||
Reference in New Issue
Block a user