feat(settings): menu and body-text font size, and a bolder menu by default
The sidebar read as muted 13px; the menu items now use their own size at medium weight so they carry at a glance (Todoist-ish). Both sizes are choices under Settings → Appearance: - Menu font size drives a dedicated --menu-size the sidebar uses. - Body text size re-scales the shared type tokens (the list and the notes), the same mechanism a look uses. The two are independent on purpose — one is a glance down a list of names, the other a paragraph you read. Kept in localStorage like theme and look, and applied in app.html before first paint so a chosen size does not flash in and resize. Four steps each (Small/Default/Large/Largest); Default carries no attribute so the base tokens stand. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
c0c1281415
commit
8dfab618f7
@@ -1441,7 +1441,10 @@
|
||||
border-radius: var(--radius);
|
||||
color: var(--ink-muted);
|
||||
text-decoration: none;
|
||||
font-size: var(--text-sm);
|
||||
/* Its own size (Settings → Appearance) and medium weight, so the menu items
|
||||
carry more than the muted small text they used to and read at a glance. */
|
||||
font-size: var(--menu-size);
|
||||
font-weight: 500;
|
||||
transition:
|
||||
background var(--fast) var(--ease),
|
||||
color var(--fast) var(--ease);
|
||||
@@ -1455,7 +1458,7 @@
|
||||
a.active {
|
||||
background: var(--surface-raised);
|
||||
color: var(--ink);
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Only your own projects reorder. A shared one sits where its owner put it —
|
||||
|
||||
@@ -230,6 +230,14 @@ export const da = {
|
||||
'Gemmes i denne browser. Det er en egenskab ved den skærm, du sidder ved — en bærbar i solen og en skærm i et mørkt rum vil have hvert sit svar.',
|
||||
'account.look': 'Udseende',
|
||||
'account.lookHint': 'Temaet siger hvor lyst. Det her siger hvordan det læses — skrift, luft og hjørner. De to kan kombineres frit.',
|
||||
'account.sizes': 'Skriftstørrelse',
|
||||
'account.sizesHint': 'Menuen og brødteksten kan sættes hver for sig — den ene er et blik ned over en liste, den anden en tekst, man læser.',
|
||||
'account.menuSize': 'Menu',
|
||||
'account.textSize': 'Brødtekst',
|
||||
'size.small': 'Lille',
|
||||
'size.default': 'Standard',
|
||||
'size.large': 'Stor',
|
||||
'size.xl': 'Størst',
|
||||
'look.verdande': 'Verdande',
|
||||
'look.verdandeNote': 'Som du kender den.',
|
||||
'look.rolig': 'Rolig',
|
||||
|
||||
@@ -226,6 +226,14 @@ export const en = {
|
||||
'Kept in this browser. It is a property of the screen you are sitting at — a laptop in the sun and a monitor in a dark room want different answers.',
|
||||
'account.look': 'Appearance',
|
||||
'account.lookHint': 'The theme says how bright. This says how it reads — typeface, air and corners. The two combine freely.',
|
||||
'account.sizes': 'Text size',
|
||||
'account.sizesHint': 'The menu and the body text set separately — one is a glance down a list, the other a paragraph you read.',
|
||||
'account.menuSize': 'Menu',
|
||||
'account.textSize': 'Body text',
|
||||
'size.small': 'Small',
|
||||
'size.default': 'Default',
|
||||
'size.large': 'Large',
|
||||
'size.xl': 'Largest',
|
||||
'look.verdande': 'Verdande',
|
||||
'look.verdandeNote': 'As you know it.',
|
||||
'look.rolig': 'Calm',
|
||||
|
||||
@@ -1051,6 +1051,52 @@ class Look {
|
||||
|
||||
export const look = new Look();
|
||||
|
||||
/**
|
||||
* The font-size steps, shared by the menu and the body-text controls. `default`
|
||||
* carries no attribute, so the base tokens in app.css stand unchanged.
|
||||
*/
|
||||
export const SIZES = [
|
||||
{ id: 'small', name: 'size.small' },
|
||||
{ id: 'default', name: 'size.default' },
|
||||
{ id: 'large', name: 'size.large' },
|
||||
{ id: 'xl', name: 'size.xl' }
|
||||
];
|
||||
|
||||
/**
|
||||
* A font-size preference — the same shape as Look: kept in localStorage and
|
||||
* mirrored onto <html>, where app.html sets it before first paint so a chosen size
|
||||
* does not flash in at the default and resize. Two instances below, because the
|
||||
* menu and the body text are separate questions.
|
||||
*/
|
||||
class Sizing {
|
||||
current = $state('default');
|
||||
#key;
|
||||
#attr;
|
||||
|
||||
constructor(key, attr) {
|
||||
this.#key = key;
|
||||
this.#attr = attr;
|
||||
if (typeof document !== 'undefined') {
|
||||
this.current = document.documentElement.dataset[attr] ?? 'default';
|
||||
}
|
||||
}
|
||||
|
||||
set(id) {
|
||||
if (!SIZES.some((s) => s.id === id)) return;
|
||||
this.current = id;
|
||||
if (id === 'default') delete document.documentElement.dataset[this.#attr];
|
||||
else document.documentElement.dataset[this.#attr] = id;
|
||||
try {
|
||||
localStorage.setItem(this.#key, id);
|
||||
} catch {
|
||||
// Private browsing; the choice simply will not persist.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const menuSize = new Sizing('verdande:menu-size', 'menuSize');
|
||||
export const textSize = new Sizing('verdande:text-size', 'textSize');
|
||||
|
||||
/** Theme, kept in localStorage and applied to the document element. */
|
||||
class Theme {
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user