···88## [Unreleased]
991010### Added
1111+- Mobile/touch viability (v0.61.0, #688) — three CSS refinements that unblock phone use of every editor. (1) `.toolbar.gdocs-toolbar` now wraps at base instead of forcing `flex-wrap: nowrap` + overflow, so narrow desktop windows (~800px) no longer cut off trailing buttons; height became `min-height: 40px` so a wrapped row can grow vertically. (2) The `@media (max-width: 768px)` block now enlarges every `.btn-icon` (topbar outline/comments/history/share/AI-chat/shortcuts buttons across all editors) to `min-width: 44px; min-height: 44px` with `0.5rem` padding — meeting Apple HIG & WCAG 2.5.5 touch-target guidance. Previously only `.tb-btn` got this treatment, leaving topbar icon buttons at the desktop 28px. (3) The same block adds `flex-wrap: wrap` + `row-gap: var(--space-xs)` to `.app-topbar` so overflowing buttons drop to a second row instead of pushing the title or action group off-screen. Also removed a stray `.toolbar { flex-wrap: nowrap }` rule inside the legacy `@media (max-width: 640px)` block that contradicted the newer 768px wrap rule. 7 new regression tests (`tests/mobile-viability.test.ts`) pin the CSS invariants so future refactors can't silently reintroduce nowrap or shrink touch targets. No JS/HTML changes — all 6 editors already had the topbar buttons and the sidebars already overlay at <=768px / go full-width at <=480px. (#688)
1112- AI chat now identifies the signed-in user in every editor's system prompt (v0.60.0, #678). A shared `fetchUserIdentity()` helper (`src/lib/user-identity.ts`) resolves the current user by first probing `/api/me` (Tailscale identity injected by the serve layer) and falling back to the `tools-username` key in localStorage for anonymous/local access. A process-wide cache (`src/lib/user-identity-cache.ts`) memoizes the promise so all 6 chat panels (docs, sheets, slides, diagrams, forms, calendar) share a single network call. `buildSystemMessage` gained a `userIdentity` option that injects a single sentence (`The signed-in user is "Name" (login). Address them by first name when appropriate.`); when name equals login, the parenthetical is dropped; when identity is `null`/missing, the line is omitted entirely. 16 new tests cover fetch fallback chain, memoization, empty-name guards, and identity-line presence across editor types. (#678)
1213- AI chat endpoint URL validation (v0.59.0, #675) — the AI chat settings panel now validates the Endpoint field before persisting. Invalid inputs (empty strings, `ftp://…`, `javascript:`, `file://`, bare hostnames without a protocol, protocol-relative `//…`, malformed URLs) no longer overwrite a working endpoint in localStorage: the previous value is retained. Invalid inputs also set `aria-invalid="true"` on the input and surface an inline error message (`role="alert"`) explaining the accepted formats (`/api/ai` same-origin path or an absolute https URL). A permanent helper hint sits below the input so users understand the format up-front; both elements are linked via `aria-describedby`. Built on the existing `validateEndpoint()` helper, which was previously only consulted to toggle the onboarding banner. 17 new tests (7 unit tests for `validateEndpoint`, 10 jsdom tests for the persist flow + a11y attributes).
1314- Sheets fit-and-finish (v0.58.0) — four Excel/Sheets-parity wins for daily spreadsheet work: