The operator reads the site at 110% browser zoom; make that the default
scale. Tailwind v4 utilities are rem-based, so `html { font-size:110% }`
scales type, spacing, columns and controls together the way zoom does,
while media queries keep firing at the same viewport widths.
Things that did not scale with the root size and had to move:
- the `lg` reader grid is now 15rem + gap-x-8 (was 16rem + gap-x-10) so
the TOC sidebar and the 68ch article still fit at 1024-1100px;
- the TOC reveal margin in app.js is 1.5rem of the computed root size
instead of a fixed 24px, and the run funnel SVG height is `h-3`;
- long unbreakable tokens on the phone-width dashboard (settings group
ids and headings, config warnings, run warnings) now wrap with
`overflow-wrap:anywhere`, and the feed candidates table sits in the
same `.scroll-x` wrapper as the other dashboard tables. Overview and
feeds already overflowed a 390px viewport before this change; settings
started to. All three fit now.
Verified with before/after screenshots of 27 pages at 390-1440px on the
seeded dev database: no page body scrolls horizontally, the reader
layout, TOC sidebar and dashboard match the old 110%-zoom rendering.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VXYGBPoHZSDSfE5WcJ9bvj
Finishes the Codex partial (0cdc302) after seeing it rendered.
Rating widget
- Inactive segments go text-ink-2 (ink on hover) so the group recedes
beside serif body copy; the per-verdict tint stays the only colour.
- Hit area: the ::after overlay is positioned against the padding box,
so -inset-y-1/-1.5 only gave 37/41 px. Now -inset-y-1.5/-2 -> 41 px
desktop, 45 px phone.
- focus-visible hugs the segment (z-20, ring-offset-0); the inherited
ring-offset-2 painted a detached box over the neighbouring buttons.
- The note field is a quiet bottom-hairline input everywhere (rule at
rest, ink on focus) instead of a box on reader pages and an invisible
border in tables.
Issue section headers
- The Brief, every section name and Colophon now use one serif
uppercase, letter-spaced mark on a double rule. A sentence-case
text-2xl header was screenshotted first and rejected: it reads as
another headline, which is the problem being fixed.
Ratings table verdict column
- New .rating-cell block: a one-column 15rem grid, segmented group with
clear/cleared flush right, note field beneath on the same width, group
top-aligned with the article title. 13rem cannot hold the labels plus
the wider "cleared" state, so rows wrapped and overlapped the Article
column.
- Drop the dead CurrentRow::verdict field left over from removing the
badge (clippy -D warnings).
Also: reader-page on world/behind so the text-wrap: balance polish item
covers those chapters.
Verified on the dev server at 127.0.0.1:3602 in light and dark, desktop
and 390 px: rating clicks toggle .active/aria-pressed with no navigation
and no console output; note text round-trips; cargo fmt, clippy
--all-targets -D warnings, cargo test (445 lib + integration) and
npm run css:check are clean. See docs/plans/briefs/ui-pass/handoff-rating.md.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MD4VWGq6mGcd8Bg67qyx9k
Signed-in issue pages (issue, article, world, behind) get a chapter list
that marks where the reader is. One `issue_toc` helper builds it for all
four handlers: the picks in issue order numbered across sections, then
World Briefing, Behind the paper and a colophon anchor, with
position/total over the navigable chapters.
At `lg` and up it is a sticky left column with its own sticky header
(issue number, "Chapter N of M", a 2px progress bar); below `lg` the same
`<nav>` collapses behind a sticky hamburger bar and drops down as a
panel that closes on link tap, Escape and outside tap. Without JS the
panel is simply visible; `theme.js` marks the document scripted before
paint so it never flashes open. Article pages advance the progress bar
with scroll position through `requestAnimationFrame`, and the bar is a
`<progress>` element because a percentage width would need an inline
style the CSP forbids.
Also fixes the phone "ears" row from the step 2 review: the row no
longer wraps at 390px, the dateline has a short form below `sm:`, and
the toggle and account link stay on one line.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NHyYupFdBiR4VfoUM7NjSM
Replaces the hand-written stylesheet with a Tailwind CSS v4 source
(src/web/tailwind.css) whose minified build is committed as
src/web/static/app.css and still embedded with include_str!, so the binary
and the test suite never need Node. package.json pins tailwindcss and
@tailwindcss/cli to 4.3.3 and adds css, css:watch and css:check.
Colours are semantic CSS variables swapped per theme and exposed to Tailwind
through @theme inline, so templates write bg-paper/text-ink/border-rule once
and both themes work. theme.js runs synchronously in <head> to set
data-theme before paint; app.js cycles the toggle system -> light -> dark and
persists the choice. Newsreader is self-hosted and served from
web::static_asset with the same ETag/304 logic as the other assets.
Every reader template is restyled: ears row, centred masthead with its rules,
tracked section labels, the drop cap on The Brief, "Why it's here" with its
accent bar, the segmented rating control, prev/next cards, and the colophon
as a two-column definition grid. Dashboard templates are untouched (step 3).
Also fixes a .block collision with Tailwind's display utility, the SVG
`hidden` property that never toggled the theme icon, and points the dev
seed's profile_path at ./dev so previewing cannot rewrite data/profile.md.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NHyYupFdBiR4VfoUM7NjSM
Signed-in issue page with the Brief, downloads, index and colophon; article,
World Briefing and Behind the paper pages under the login guard; the rating
widget with its fetch enhancement; the admin-only POST /rate writing
dashboard-attributed rating events; the HMAC confirmation page links to the
site.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NHyYupFdBiR4VfoUM7NjSM