Offer the three proposed font groups in Themes
The theme menu now carries a fourth choice beside light/dark and the accent: the font pairing. All three pairings are free for commercial use (SIL OFL), have a Vietnamese subset, and are self-hosted — the landing still makes no CDN request. - styles/fonts.css: 22 @font-face blocks for Plus Jakarta Sans, Inter, JetBrains Mono, Fraunces, Be Vietnam Pro, Courier Prime and Space Mono, vietnamese/latin-ext/latin subsets only, under public/assets/fonts. - styles/tokens.css: [data-fonts="studio|editorial|native"] sets --font, --font-heading and --mono. Studio (Plus Jakarta Sans + Inter + JetBrains Mono) is the default. - theme/: FontSetId + FONT_SETS, persisted as rc.fonts, applied as <html data-fonts> next to data-theme and data-accent. - TopBar and the landing nav both get the picker; on the landing the theme tool now opens a small popover (light/dark + font group) instead of toggling on click. - landing.css: --lp-display/--lp-mono now resolve to the chosen group, so the picker retypes the whole page. Syne.woff2 goes with its @font-face.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useI18n, LANGS } from '../i18n/I18nProvider';
|
||||
import { ACCENTS, useTheme } from '../theme/ThemeProvider';
|
||||
import { ACCENTS, FONT_SETS, useTheme } from '../theme/ThemeProvider';
|
||||
import type { User } from '../api';
|
||||
|
||||
// Header: the app's TopBar minus everything camera-only, plus the two controls
|
||||
@@ -29,7 +29,7 @@ export function TopBar({
|
||||
onLogout: () => void;
|
||||
}) {
|
||||
const { t, lang, setLang } = useI18n();
|
||||
const { mode, accent, setMode, setAccent } = useTheme();
|
||||
const { mode, accent, fonts, setMode, setAccent, setFonts } = useTheme();
|
||||
const [menu, setMenu] = useState<'theme' | 'lang' | 'account' | null>(null);
|
||||
const wrap = useRef<HTMLDivElement>(null);
|
||||
|
||||
@@ -79,6 +79,20 @@ export function TopBar({
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<div className="chip-row" style={{ marginTop: 8 }}>
|
||||
{FONT_SETS.map((entry) => (
|
||||
<button
|
||||
key={entry.id}
|
||||
type="button"
|
||||
data-key={`fonts-${entry.id}`}
|
||||
title={entry.note}
|
||||
className={`chip${fonts === entry.id ? ' on' : ''}`}
|
||||
onClick={() => setFonts(entry.id)}
|
||||
>
|
||||
{entry.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user