mirror of
https://github.com/PR0M3TH3AN/VoxVera.git
synced 2026-10-27 09:40:40 +00:00
Locale-aware defaults: browser language list + US Letter/A4 paper size
Language inference: - Walk navigator.languages (the full ordered preference list), not just navigator.language, and pick the first base language we support. A user who prefers e.g. Dutch then German now gets German instead of the English fallback. De-duplicates the default-language resolution into setDefaultText. Paper size (US Letter + A4): - Add A4 (210x297mm) alongside US Letter (8.5x11in). Sheet dimensions move to CSS custom properties (--sheet-w/--sheet-h) toggled by a paper-letter/paper-a4 class on <html>; the tear-off column and QR codes stay fixed physical sizes and the content column flexes. - @page size is injected by JS (id voxvera-page-size) since @page cannot read CSS variables across engines; the print block keeps margin:0 and a Letter default for the pre-JS state. - Default paper is chosen from the browser locale's region subtag (en-US -> Letter, en-GB/de-DE -> A4) — "by location" without geolocation, falling back to Letter when no region is present. A manual override selector (topbar + viewer controls) persists in localStorage and wins over the default. - Paper size is a local print/view preference and is never written into the Nostr event, so a flyer reprints on either size unchanged. - Add paper_size/paper_letter/paper_a4 labels for all 14 languages. Docs + tests: - Spec gains a "Print paper size" section; AGENTS.md records the not-in-payload invariant; README adds a feature bullet; the field-limits cheat sheet gains Letter/A4 columns (re-measured per paper size). - Playwright: add tests for navigator.languages inference, region-based paper default (A4 and Letter), and override persistence. 54 tests pass across Chromium, Firefox, WebKit, and Android/iOS mobile emulations. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
c5b2c20fc9
commit
127f9c3134
8 files changed
+310
-32
No files matched your search
+18
-14
@@ -9,7 +9,8 @@ So the real limit is enforced for you as you type — the numbers below are
|
||||
practical guidance for drafting copy, sizing translations, or prompting an LLM
|
||||
to write flyer text that will fit on the first try.
|
||||
|
||||
Capacity varies by **script**, not by individual language, for three reasons:
|
||||
Capacity varies by **script** (not by individual language) and by **paper
|
||||
size**, for these reasons:
|
||||
|
||||
1. The flyer body font is monospace (`Courier New`), so within a script every
|
||||
character takes the same width regardless of upper/lowercase.
|
||||
@@ -17,19 +18,22 @@ Capacity varies by **script**, not by individual language, for three reasons:
|
||||
[`nostr-static-client-spec.md`](nostr-static-client-spec.md#letter-spacing-by-script)).
|
||||
3. Glyph width differs by script — CJK glyphs are full-width (≈2× a Latin
|
||||
character), Devanagari fallback glyphs are narrower, etc.
|
||||
4. **Paper size.** A4 (210×297mm) is slightly narrower and taller than US
|
||||
Letter (8.5×11in), so single-line fields hold ~2 fewer characters on A4
|
||||
while the body holds a little more. Both sizes are shown below.
|
||||
|
||||
## Single-line fields (hard caps)
|
||||
|
||||
**Title**, **Subtitle**, and **Headline** are single-line: they never wrap, so
|
||||
these are the limits people actually run into. Counts are characters
|
||||
(codepoints).
|
||||
(codepoints), shown as **Letter / A4**.
|
||||
|
||||
| Languages | Title | Headline | Subtitle |
|
||||
|---|---|---|---|
|
||||
| Latin & Cyrillic & Hebrew — en, es, de, fr, pt, sw, tr, ru, he | ~28 | ~28 | ~32 |
|
||||
| Arabic & Persian — ar, fa | ~28 | ~28 | ~38 |
|
||||
| Devanagari — hi | ~36 | ~36 | ~51 |
|
||||
| CJK — ja, zh | ~17 | ~17 | ~23 |
|
||||
| Languages | Title & Headline | Subtitle |
|
||||
|---|---|---|
|
||||
| Latin & Cyrillic & Hebrew — en, es, de, fr, pt, sw, tr, ru, he | ~28 / ~26 | ~32 / ~30 |
|
||||
| Arabic & Persian — ar, fa | ~28 / ~27 | ~38 / ~36 |
|
||||
| Devanagari — hi | ~36 / ~35 | ~51 / ~48 |
|
||||
| CJK — ja, zh | ~17 / ~16 | ~23 / ~21 |
|
||||
|
||||
## Multi-line fields (generous)
|
||||
|
||||
@@ -37,12 +41,12 @@ these are the limits people actually run into. Counts are characters
|
||||
(`footer_message`) wrap across multiple lines, so they hold far more and are
|
||||
bounded only by the remaining height of the sheet.
|
||||
|
||||
| Languages | Body (content) |
|
||||
| Languages | Body (content) — Letter / A4 |
|
||||
|---|---|
|
||||
| Latin & Cyrillic & Hebrew | ~1,900 (a few hundred words) |
|
||||
| Arabic & Persian | ~1,850 |
|
||||
| Devanagari — hi | ~2,450 |
|
||||
| CJK — ja, zh | ~1,170 |
|
||||
| Latin & Cyrillic & Hebrew | ~1,900 / ~2,000 (a few hundred words) |
|
||||
| Arabic & Persian | ~1,850 / ~1,930 |
|
||||
| Devanagari — hi | ~2,450 / ~2,545 |
|
||||
| CJK — ja, zh | ~1,170 / ~1,220 |
|
||||
|
||||
`url_message` and `footer_message` share the lower portion of the sheet and can
|
||||
hold roughly 1,200–4,800 characters depending on script, but for a readable
|
||||
@@ -55,7 +59,7 @@ URLs scan more reliably).
|
||||
## Notes and caveats
|
||||
|
||||
- **Approximate.** These come from rendering each script in a headless browser
|
||||
at true print size (8.5in × 11in, content column 4.75in). The
|
||||
at true print size for both Letter (8.5×11in) and A4 (210×297mm). The
|
||||
Latin/Cyrillic numbers (`Courier New`) are the most reliable; numbers for
|
||||
Hebrew, Arabic, Persian, Devanagari, and CJK depend on the system fallback
|
||||
font, which can differ slightly between devices and from print output.
|
||||
|
||||
@@ -122,6 +122,36 @@ The client and schema helper must:
|
||||
- keep attachments unsupported in V1
|
||||
- avoid remote frontend dependencies
|
||||
|
||||
## Print paper size
|
||||
|
||||
The flyer supports two print sizes: **US Letter** (8.5×11in) and **A4**
|
||||
(210×297mm), covering every country whose language the client supports (Letter
|
||||
in North America and a few Latin American countries; A4 everywhere else,
|
||||
including the EU, Russia, China, Japan, and the Middle East).
|
||||
|
||||
- Dimensions live in CSS custom properties `--sheet-w` / `--sheet-h`, switched
|
||||
by a `paper-letter` / `paper-a4` class on `<html>` (`applyPaperSize` in
|
||||
`nostr-client.js`). The tear-off column (`3.75in`) and QR codes (`1.25in`)
|
||||
stay fixed physical sizes; the content column flexes to the sheet width.
|
||||
- The print `@page { size: … }` is injected by JS (an element with id
|
||||
`voxvera-page-size`), because `@page size` cannot read CSS custom properties
|
||||
across engines. The static `@media print` block keeps `margin: 0` and a
|
||||
Letter default for the pre-JS state.
|
||||
- The default is chosen from the **region subtag** of the browser locale
|
||||
(`preferredPaperSize` — e.g. `en-GB` → A4, `en-US` → Letter). This is "by
|
||||
location" without geolocation, using the same signal as language. When no
|
||||
locale carries a region, it falls back to Letter.
|
||||
- A user override (the paper-size selector) is stored in `localStorage`
|
||||
(`voxvera_paper`) and wins over the region default.
|
||||
- **Paper size is a local print/view preference and is never written into the
|
||||
Nostr event.** A flyer authored on Letter reprints on A4 for a European
|
||||
viewer without changing the source event. The live fit-check protects
|
||||
authoring on whichever size is active; switching to a narrower size after
|
||||
authoring can ellipsis-truncate a maxed-out single-line field.
|
||||
|
||||
Field capacity therefore varies by paper size; see
|
||||
[`flyer-field-limits.md`](flyer-field-limits.md).
|
||||
|
||||
## Localization
|
||||
|
||||
Flyer defaults come from `site/locales.js`.
|
||||
|
||||
Reference in new issue
Block a user