SEIHouse Sans, version 0.39 (formerly SEIReader) EASIEST APP INSTALL Use the App distribution Actions run's seireader-app-packages download. Extract SEIReader-0.39-web-full.zip into public/seireader/0.39/ and link its sans.css, or install seihouse-seireader-0.39.0.tgz and import @seihouse/seireader/sans.css. Use font-family: "SEIHouse Sans". Legacy asset paths and SEIReader CSS still work. LICENSE permits ecosystem creative use/customization and authorized SEIHouse app/web distribution. Unrelated app embedding and standalone redistribution require permission; see the included full license. The default is ten full WOFF2 fonts (712,464 font bytes), with no build dependencies, OTFs, reference fonts, old versions, Lab pages, or proof images. The browser loads the faces the page uses. Full language/symbol coverage stays together in each face. docs/APP-INSTALL.md has the inspected Development/NovelExpanded host handoff. At the repository root, fonts-full.css is the full delivery; fonts.css is the existing optional subset delivery. Choose one route so the same faces are not registered twice. WHAT YOU HAVE Five weights, each in upright and italic, each as full .woff2 (websites and apps) and .otf (computers). There are also 70 subset WOFF2 files: Latin basic, legacy Latin extended, symbols/icons, latin-ext-2, cyrillic, greek and vietnamese for each style. Light 300, Regular 400, Medium 500, SemiBold 600, Bold 700 Built in: automatic pair spacing, joined fi / fl (apps switch these on by themselves), and screen tuning for crisp small text on Windows and lower-resolution screens. Italic versions: LightItalic, Italic, MediumItalic, SemiBoldItalic, BoldItalic Italic is a real italic: 9-degree slant, rounder handwriting-style letters (a, d, f, h, i, m, n, u), not a tilted copy. WHAT TO TELL YOUR CODING AGENT (copy and paste) For the smaller web delivery, copy fonts.css and the whole fonts/ directory to the site's public root. Import the stylesheet once, before rules that use SEIReader: @import url('/fonts.css'); fonts.css contains all 70 @font-face rules. Latin-ext-2 completes Latin coverage; Cyrillic, Greek and Vietnamese faces follow it. Each includes base Latin letters, combining accents and prose punctuation so complete clusters can shape in one face. Vietnamese is the final preferred face for shared Latin text. Keep the generated order. Its ./fonts/... URLs are relative to fonts.css. Browsers fetch only the subsets needed for each weight, style, and character range. Keep all seven subset files for every style. If you instead want the full .woff2 files, add all ten and register them exactly like this, all under one family name. Do not add, swap, or restyle other fonts for reading text. @font-face { font-family: 'SEIReader'; src: url('/fonts/SEIReader-Light.woff2') format('woff2'); font-weight: 300; font-style: normal; font-display: swap; } @font-face { font-family: 'SEIReader'; src: url('/fonts/SEIReader-LightItalic.woff2') format('woff2'); font-weight: 300; font-style: italic; font-display: swap; } @font-face { font-family: 'SEIReader'; src: url('/fonts/SEIReader-Regular.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; } @font-face { font-family: 'SEIReader'; src: url('/fonts/SEIReader-Italic.woff2') format('woff2'); font-weight: 400; font-style: italic; font-display: swap; } @font-face { font-family: 'SEIReader'; src: url('/fonts/SEIReader-Medium.woff2') format('woff2'); font-weight: 500; font-style: normal; font-display: swap; } @font-face { font-family: 'SEIReader'; src: url('/fonts/SEIReader-MediumItalic.woff2') format('woff2'); font-weight: 500; font-style: italic; font-display: swap; } @font-face { font-family: 'SEIReader'; src: url('/fonts/SEIReader-SemiBold.woff2') format('woff2'); font-weight: 600; font-style: normal; font-display: swap; } @font-face { font-family: 'SEIReader'; src: url('/fonts/SEIReader-SemiBoldItalic.woff2') format('woff2'); font-weight: 600; font-style: italic; font-display: swap; } @font-face { font-family: 'SEIReader'; src: url('/fonts/SEIReader-Bold.woff2') format('woff2'); font-weight: 700; font-style: normal; font-display: swap; } @font-face { font-family: 'SEIReader'; src: url('/fonts/SEIReader-BoldItalic.woff2') format('woff2'); font-weight: 700; font-style: italic; font-display: swap; } .reader-text { font-family: 'SEIReader', system-ui, sans-serif; font-weight: 400; font-synthesis: none; /* never fake bold or italic; the real files cover both */ font-size: 20px; line-height: 1.4; max-width: 60ch; /* about 60 letters per line */ } .comment-text { font-family: 'SEIReader', system-ui, sans-serif; font-weight: 300; /* Light */ font-synthesis: none; } Use or font-style: italic for inner thoughts, book titles, and sound effects, and font-weight: 700 for bold. The browser then picks the real SEIReader file automatically. READING REFINEMENT PREVIEW Open lab/comparison.html to compare 0.39 with the preserved 0.34 baseline, Literata, and Rubik in the same layout. All comparison fonts are embedded for offline use. Choose a language in the new selector. Its encoded (NFC) and decomposed (NFD) rows should match. The main alphabet and real italic are shown beside the original reading and foundation rows. Phase 4 adds Latin Extended-A, Cyrillic, Greek and Vietnamese to those ten Latin inventories; the old baseline/reference rows can use fallback for missing characters. Version 0.35 repairs exported stroke overlaps while preserving widths, nominal settings, weights, kerning and layout tables. Its contour segmentation can differ from 0.34. The earlier dialogue, figure, weight, and word samples remain for comparison. The candidate uses a 0.220 em word space; the preview also offers the original 0.205 from 0.27 and a roomier 0.230 without changing the font files. Compare line-height 1.4 and 1.5, then check 13/15/17px at Regular and Medium. Default chapter line-height stays 1.4. The reference fonts are comparison assets; use SEIReader for the app's reading text. OPTICAL SPACING AND SMALL TEXT Use the font's own pair spacing and real joins in reading text: .reader-text, .comment-text { font-family: "SEIReader", sans-serif; font-synthesis: none; font-kerning: normal; font-variant-ligatures: common-ligatures; letter-spacing: 0; } Version 0.35 carries forward every existing 0.33 default pair value and character advance. New ogonek/punctuation pairs have their own measured room. Hungarian uppercase TY/TTY receive extra clearance only for lang="hu"; other text keeps the established capital spacing. New marks have zero advance and are ignored by pair spacing. Avoid overriding the pair rhythm with extra CSS tracking. Review Light, Regular, and Medium at 13/15/17px in both themes using the comparison page's fixed-size matrix. Check minimum, murmur, river, climate, parallel, and everywhere, upright and italic. Include rival, arrival, vivid, willow, weary, yearly, twilight, and the earlier Lian, Iñés, blade, Entry, Mei's / Mei’s, acquittal, ri/rn/cl/li, office, affinity, flame, and reflection. Inspect “Mei’s,” and “Entry 12?” alongside 1,234.56, 8.50%, and 6089, upright and italic, with proportional and tabular figures. Native Windows proof images are in docs/proofs/0.34/; its family/ images cover all five weights at 20px. Physical browser/device checks remain deferred. fonts.css already uses font-display: swap. Ordinary Latin prose, accented names, and dialogue quotes request Latin extended. System icons, math/music marks, superscripts, and precomposed fractions can request symbols/icons as well. Latin basic remains an optional standalone delivery for deliberately ASCII-only content. Do not preload it expecting fonts.css to select it ahead of Latin extended. Use the full WOFF2 for mixed-script chapters; measure current subset transfer sizes for the app rather than assuming they are smaller. Compare actual transfer sizes for the app. Preload only faces needed for its first view. LATIN FOUNDATION (automatic) Use ordinary Unicode text; ccmp, mark, and mkmk run through the text shaper without opt-in CSS. Keep default shaping enabled. The two forms below must render identically: Cafe\u0301 (e followed by U+0301 acute) Café (precomposed U+00E9) This notation is JavaScript escape syntax. In HTML use Café or actual Unicode. Added combining marks: U+0300/0301/0302/0303/0304/0306/0307/0308/0309/030A/030B/030C, U+0312/031B, U+0323/0326/0327/0328. They attach above, below, or at the side as appropriate; i/j use dotless alternates under above marks. Above and below marks can stack. Use 1.5 line height for passages with frequent tall stacked accents and check line clearance. Font metrics and the app's default 1.4 line height are unchanged. Low/reversed quotes: ‚ „ ‛ ‟. Lexical apostrophes: ʻ (U+02BB), ʼ (U+02BC). French example: « Iñés entre. » (narrow nonbreaking spaces). German example: „Lian sagt: ‚Warte!‘“; Polish dialogue example: „Lian wraca.” Choose quotation conventions using the content's locale; the font does not rewrite text. A dotted circle ◌ makes isolated accents visible in the Lab. U+2009 is a breaking thin space; U+202F is a narrow nonbreaking space, both 0.120 em. Normal spaces stay 0.220 em. The ten new Latin inventories listed below have complete encoded coverage of the pinned CLDR main/auxiliary/index exemplars, both cases, and NFC/NFD forms. Keep actual chapter text; no blanket NFD conversion is needed. Characters outside those inventories can still use fallback. See docs/LANGUAGES-0.34.md and languages.json for the exact audited scope. LOCAL FORMS AND LANGUAGE TAGS Put the language on the actual chapter or passage. Standard locl/ccmp/mark/mkmk features apply automatically; no special CSS switch is needed. Keep them enabled:
İpek · Işık · fikir · fi · fı
Ștefan · țară · ş ţ
TY · TTY · Őrző · tűz
ị́ · ọ̀ · ụ́ · Ị́ · Ọ̀ · Ụ́
çiya · şev · rê
oʻqish · gʻoya
Turkish uses a real dotted i alternate so fi words keep the visible dot; fl still joins. Romanian legacy ŞşŢţ display as ȘșȚț under lang="ro"; use modern comma letters in new content. Kurdish here means Kurmanji in Latin script; Uzbek here means Latin script. Locale-aware case conversion belongs to the app. A font does not correct stored spelling. NUMERIC FEATURES (opt in) Proportional numbers remain the default. The feature settings below work with either the full WOFF2 files or fonts.css subsets: .stat-values { font-variant-numeric: tabular-nums; } /* OpenType tnum */ .super-number { font-feature-settings: 'sups' 1; } /* normal digit input, raised */ .sub-number { font-feature-settings: 'subs' 1; } /* normal digit input, lowered */ .fraction { font-feature-settings: 'frac' 1; } /* e.g. 1/2 or 12/34 */ Use 2 for an exponent, and 1/2 for a fraction. Unicode ⁰¹²³⁴⁵⁶⁷⁸⁹, ₀₁₂₃₄₅₆₇₈₉, ½, ¼, ¾, and the fraction slash ⁄ (U+2044) are directly encoded too. For a precomposed fraction, plain ½/¼/¾ needs no CSS feature. CHARACTERS INCLUDED A-Z, a-z, 0-9 . , : ; … ! ? ' " ‘ ’ “ ” - – — ( ) [ ] { } / \ | _ % + − = < > ≤ ≥ ≠ ≈ & @ # $ * ~ ★ ☆ ✦ • · ◆ ◇ ▲ ▼ ▶ ◀ × ÷ ± ° → ← ↑ ↓ ∞ « » ‹ › ☯ ⚡ ☀ ☾ ☽ ⚔ ♥ ♡ ✓ ✗ © ® ™ ¥ € £ Ⓢ (SEIHouse brand mark) Music: ♩ ♪ ♫ ♬ ♭ ♮ ♯ Player: ⏮ ▶ ⏸ ⏹ ⏺ ⏭ Icons: 🎧 💻 📖 🔖 🔍 🔔 ⚙ ⌂ 🎤 💿 🔊 Accented letters: ÀÁÂÃÄÅ Ç ÈÉÊË ÌÍÎÏ Ñ ÒÓÔÕÖØ ÙÚÛÜ ÝŸ ÆŒ ÐÞ (and lowercase), ß æ œ ð þ ¡ ¿ º ª Numeric additions: ⁰¹²³⁴⁵⁶⁷⁸⁹ ₀₁₂₃₄₅₆₇₈₉ ½ ¼ ¾ ⁄ (U+2044) Latin foundation: the 18 combining marks listed above; ‚ „ ‛ ‟ ʻ ʼ ◌; U+2009/U+202F. Language additions: 94 letters including macron/breve/caron/double-acute/ogonek/comma/dot forms, Łł, İı, ƁƊƘƳ ɓɗƙƴ, and Ịị Ọọ Ụụ Ṅṅ; exact inventory in languages.json. Total: 714 encoded codepoints and 732 glyphs in each full font, including private aliases. Unencoded alternates available through OpenType: zero.tf–nine.tf and zero.numr–nine.numr / zero.dnom–nine.dnom. Use tnum or frac to select these from normal digits. LANGUAGES Covered: English, Spanish, French, Portuguese, German, Italian, Dutch, Catalan, Danish, Norwegian, Swedish, Finnish and Icelandic (everyday text). Additional audited CLDR main/auxiliary/index inventories: Polish, Czech, Hungarian, Romanian, Turkish, Hausa (Latin/Boko), Kurdish (Kurmanji, Latin), Māori, Igbo, Uzbek (Latin), Slovak, Croatian, Slovenian and Vietnamese. Modern Cyrillic: Russian, Ukrainian, Belarusian, Bulgarian, Serbian and Macedonian. Greek is the monotonic repertoire; the historical Bulgarian and polytonic Greek auxiliary letters are excluded explicitly in languages.json. This is alphabet/shaping coverage, not native-reader or physical-device certification. Not yet: the remaining Latin inventories, Kurdish in Arabic, non-Slavic Cyrillic inventories, polytonic Greek and other scripts. Missing characters show in a backup font. ICONS AND PHONES (read this before using symbols in the app) Many symbols also exist as color emoji, and phones (especially iPhone) can swap in the emoji instead of SEIReader's version. Icons like headphones, laptop and book ONLY exist as emoji, so phones will almost always swap those. The reliable way inside your apps is the PRIVATE CODES below. They always show SEIReader's version, because no phone has an emoji for them. (Outside your apps, they show as an empty box, so use them for app interface and system screens, not for text people copy and share.) Code Icon Name HTML JavaScript U+E000 Ⓢ SEIHouse brand  "\uE000" U+E001 🎧 headphones  "\uE001" U+E002 💻 laptop  "\uE002" U+E003 📖 book  "\uE003" U+E004 🔖 bookmark  "\uE004" U+E005 🔍 search  "\uE005" U+E006 🔔 notifications  "\uE006" U+E007 🎤 microphone  "\uE007" U+E008 💿 disc / album  "\uE008" U+E009 🔊 sound  "\uE009" U+E00A ⚙ settings  "\uE00A" U+E00B ⌂ home  "\uE00B" U+E00C ⚡ lightning  "\uE00C" U+E00D ☀ sun  "\uE00D" U+E00E ☯ qi (yin yang)  "\uE00E" U+E00F ♥ heart  "\uE00F" For the other symbols typed normally in text, also add font-variant-emoji: text; to .reader-text and .comment-text so browsers prefer the text version. THE SOURCE ZIP The rules SEIReader is built from, including the emoji demo art. Ask Claude to rebuild from it. PHASE 4 — STEP 1 (0.37) Central European and Turkish alphabets: Polish, Czech, Slovak, Hungarian, Romanian, Croatian, Slovenian, Turkish. All Latin Extended-A codepoints are encoded. Existing settings, weights, letter shapes, metrics and pair spacing remain unchanged. New ACC/MARK recipes use the established light accents. Use actual Unicode and language tags: lang="sk", lang="hr", lang="sl", lang="pl", lang="cs", lang="hu", lang="ro", lang="tr". Keep fonts.css beside fonts/ and retain the generated unicode-range order; latin-ext-2 includes whole Latin words, prose punctuation and combining marks. Existing latin-extended retains its original character inventory. Release identifiers now come from phase4.json; design settings stay untouched. PHASE 4 — STEP 2 (0.38) Added alphabets: Russian (ru), Ukrainian (uk), Belarusian (be), Bulgarian (bg), Serbian Cyrillic (sr), Macedonian (mk), and monotonic Greek (el). Keep language tags on the actual passage, e.g.
or lang="el". New script faces include complete Latin, punctuation and combining marks so mixed names and canonical accent sequences have matching shapes and metrics. The real italic files contain Russian-style cursive forms for б в г д и п т. Coverage is modern/common Slavic and monotonic Greek; polytonic Greek, historical Bulgarian yat/yus and regional stylistic certification are deferred. Existing glyphs, font settings, weights and pair values stay unchanged. PHASE 4 — STEP 3 (0.39) Vietnamese (vi): the full encoded set, including Ơơ Ưư and all stacked tones. Example:
“Nguyễn đọc truyện giữa đêm; những ước mơ vẫn sáng.”
Ordinary Unicode and decomposed input produce identical shapes and positions. For example Ấ and Ấ, Ậ and Ậ, ợ and ợ need no opt-in feature or text conversion. Keep automatic ccmp/mark/mkmk and kerning enabled; real italic styles retain the same light tone marks. Horn pairs have clearance on new glyphs only. fonts.css now has seven subsets per style. Its final vietnamese delivery contains complete Latin text and all accent ingredients, including horns. The full fonts-full.css route is the simplest option for mixed chapters. Existing line metrics and default size/line height remain unchanged. For passages with frequent stacked capitals, inspect 1.5 line height in the reader app; font checks do not certify device comfort.