Skip to content

Commit fb3b306

Browse files
authored
Merge pull request #16 from dreamrec/claude/v2.0-pr27-chat-font-toggle
add: chat font-size toggle (small/large) with retro glyph control
2 parents 2039d0a + 286e368 commit fb3b306

2 files changed

Lines changed: 369 additions & 0 deletions

File tree

td_component/tdpilot_api_chat.html

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@
9898
display: inline-flex;
9999
align-items: center;
100100
gap: 6px;
101+
/* PR-27: keeps .rhs (and the font toggle that follows it as a
102+
sibling) clustered at the right edge in the 3-child status bar.
103+
No-op for the pre-PR-27 2-child layout. */
104+
margin-left: auto;
101105
}
102106
#status-bar .rhs::before {
103107
content: "[";
@@ -145,6 +149,42 @@
145149
visibility: hidden;
146150
}
147151
#status-bar.working .cursor { visibility: visible; }
152+
/* PR-27 (v2.0) — chat font-size toggle. Two-state glyph control
153+
(`a` / `A`) at the far right of the status bar; the active size
154+
lights up in --accent, the inactive in --muted. Click swaps the
155+
size class on <html>; the body has no other knowledge of the
156+
toggle, so the rest of the chat keeps its existing scale.
157+
Defaults to small (today's behavior) so existing users see no
158+
change unless they opt in. */
159+
#font-toggle {
160+
background: transparent;
161+
border: 1px solid var(--rule);
162+
color: var(--muted);
163+
font-family: inherit;
164+
padding: 1px 7px 2px;
165+
margin-left: 10px;
166+
cursor: pointer;
167+
display: inline-flex;
168+
align-items: baseline;
169+
gap: 3px;
170+
letter-spacing: 0; /* override status-bar uppercase tracking */
171+
text-transform: none; /* lowercase 'a' must stay lowercase */
172+
line-height: 1;
173+
}
174+
#font-toggle:hover {
175+
border-color: var(--accent);
176+
background: var(--bg-3);
177+
}
178+
#font-toggle .fs-a { font-size: 9px; color: var(--muted); }
179+
#font-toggle .fs-A { font-size: 13px; color: var(--muted); }
180+
:root.fs-small #font-toggle .fs-a { color: var(--accent); }
181+
:root.fs-large #font-toggle .fs-A { color: var(--accent); }
182+
/* Scales chat content + input only — chrome (status bar, buttons,
183+
modal headers, badges) stays fixed at its designed scale so the
184+
layout doesn't reflow awkwardly. Tool-call summaries inherit
185+
from #history so they scale automatically. */
186+
:root.fs-large #history { font-size: 17px; }
187+
:root.fs-large #input { font-size: 17px; }
148188
@keyframes blink {
149189
0%, 49% { opacity: 1; }
150190
50%, 100% { opacity: 0; }
@@ -670,6 +710,11 @@
670710
<span class="rhs">
671711
<span id="status-text">idle</span><span id="model-badge"></span><span id="token-meter"></span><span class="cursor"></span>
672712
</span>
713+
<button id="font-toggle" type="button"
714+
title="Toggle chat font size (small / large)"
715+
aria-label="Toggle chat font size">
716+
<span class="fs-a">a</span><span class="fs-A">A</span>
717+
</button>
673718
</div>
674719
<!--
675720
History is intentionally empty on initial DOM. The IIFE injects the
@@ -758,6 +803,27 @@ <h4>quickstart</h4>
758803
const $modelBadge = document.getElementById('model-badge');
759804
const $tokenMeter = document.getElementById('token-meter');
760805
const $scrollJump = document.getElementById('scroll-jump');
806+
const $fontToggle = document.getElementById('font-toggle');
807+
808+
// PR-27 (v2.0) — chat font-size toggle. Two states; the active one
809+
// is reflected as a class on <html>. Persisted per-browser via
810+
// localStorage so the choice survives reloads. Restored before any
811+
// history rendering happens so users with a saved 'large' setting
812+
// never see a small-text flash on page load.
813+
const FONT_KEY = 'tdpilot.fontMode';
814+
function applyFontMode(mode) {
815+
if (mode !== 'small' && mode !== 'large') mode = 'small';
816+
document.documentElement.classList.remove('fs-small', 'fs-large');
817+
document.documentElement.classList.add('fs-' + mode);
818+
try { localStorage.setItem(FONT_KEY, mode); } catch (_) { /* private mode */ }
819+
}
820+
let _savedFontMode = 'small';
821+
try { _savedFontMode = localStorage.getItem(FONT_KEY) || 'small'; } catch (_) { /* private mode */ }
822+
applyFontMode(_savedFontMode);
823+
$fontToggle.addEventListener('click', () => {
824+
const cur = document.documentElement.classList.contains('fs-large') ? 'large' : 'small';
825+
applyFontMode(cur === 'large' ? 'small' : 'large');
826+
});
761827

762828
// Render the initial welcome from the same template fullSync uses, so
763829
// the wizard DOM is guaranteed present.
@@ -1822,6 +1888,19 @@ <h4>quickstart</h4>
18221888
$input.focus();
18231889
return;
18241890
}
1891+
// PR-27 (v2.0) — Cmd/Ctrl + `+` / `-` toggles chat font size
1892+
// independently of the browser-native zoom (which still works).
1893+
// `=` matches `+` for the unshifted keycap on US/EU layouts.
1894+
if (cmd && (e.key === '+' || e.key === '=')) {
1895+
e.preventDefault();
1896+
applyFontMode('large');
1897+
return;
1898+
}
1899+
if (cmd && e.key === '-') {
1900+
e.preventDefault();
1901+
applyFontMode('small');
1902+
return;
1903+
}
18251904
// End — jump to bottom of history. Useful after scrolling up to
18261905
// read older content.
18271906
if (e.key === 'End' && !inInput) {

0 commit comments

Comments
 (0)