Commit Graph
7 Commits
Author SHA1 Message Date
thallada da24e7c7c5 Merge branch 'ui-shell': nav state, ears, feeds table, font flash, faster navigation
# Conflicts:
#	src/web/static/app.css
2026-09-04 17:08:10 +00:00
thalladaandClaude Fable 5.1 5cc4ac4bd3 UI pass: nav state, ears, feeds table, font flash, faster navigation
- Issue pages highlight Archive instead of Latest unless the issue is the
  newest one (IssueView::is_latest), with a router test.
- The ears row is empty by default and says "Dashboard" on dashboard pages;
  "Morning edition" only survives on the empty-state hero.
- Run page: the Feeds card table is fixed-layout and truncates long feed
  names with the full title on hover instead of pushing the entries column
  out of the card.
- Static assets are content-hashed, so serve them immutable for a year;
  preload both Newsreader faces and use font-display: block so a cache
  revalidation never paints the fallback serif first. Persisted details
  state is restored pre-paint from theme.js.
- Cross-document view transitions (140 ms fade, masthead held still) and
  Speculation Rules (prerender reader pages, prefetch dashboard pages on
  hover) served from /static/speculation.json via the Speculation-Rules
  header, which the CSP would otherwise block inline. No client router.
- Dashboard nav gets the same accent underline as the site nav; 40 px
  targets for the theme toggle, account link and dashboard nav.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MD4VWGq6mGcd8Bg67qyx9k
2026-09-04 17:06:48 +00:00
thalladaandClaude Fable 5.1 ad2e99eeb9 UI pass: table-of-contents sidebar fixes and scroll sync
- The open hamburger panel now fills the viewport below the sticky bar
  (100dvh, measured bar offset) and locks the page behind it. Locking only
  the root element: locking body too made it its own scroll container and
  un-stuck the bar.
- Front-page scroll-spy: the current chapter marker, mobile label/counter,
  desktop "Chapter N of M" line and both progress bars follow the reader
  through "In This Issue"; passed chapters read in ink. The sidebar
  auto-scrolls to keep the current chapter in view.
- The sidebar scrollbar sits in a reserved gutter instead of over the text.
- Hamburger cross-fades to a close icon; 44px tap targets on phones.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MD4VWGq6mGcd8Bg67qyx9k
2026-09-04 17:05:39 +00:00
thalladaandClaude Fable 5.1 e719e031cf Merge branch 'v2-toc': table-of-contents sidebar
Keeps both the dashboard and sidebar component blocks in tailwind.css and
rebuilds the compiled app.css.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NHyYupFdBiR4VfoUM7NjSM
2026-09-03 21:53:06 +00:00
thalladaandClaude Fable 5.1 ca910d99e5 Web dashboard v2 step 4: table-of-contents sidebar
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
2026-09-03 21:50:05 +00:00
thalladaandClaude Fable 5.1 a4c338a9f9 Web dashboard v2 step 3: dashboard restyle
Restyle every template under src/web/templates/dashboard/ plus the shared
partials _candidate_row.html, _signals_table.html and _pagination.html with
Tailwind utilities and the design system step 2 built, so the dashboard reads
as the sans-serif instrument-panel half of the same publication as the reader
pages: a page header on every page, stat tiles, compact tables with sticky
heads inside .scroll-x, tinted badges, one inline filter form per page,
settings groups with a sticky save bar, job cards, a scrolling journal block
and a rating widget that fits inside a table cell.

tailwind.css gains the dashboard vocabulary (.page-head/.page-desc/
.page-actions, .tiles/.tile*, .cell-wrap, .scroll-x.tall, .filters,
.pager/.tabs, .setting*/.save-bar, .disclosure, .sparklines/.spark-figure,
td .rating overrides, tr.superseded) plus a styled <meter> and a disabled
control state. Renames class="inline" to form-inline: Tailwind emits an
.inline display utility that was beating form.inline's layout.

Three small backend changes: job cards show the status and time of their last
run (attach_last_runs, no extra query, unit-tested); the Stats page passes
"stats" as its nav key so the admin nav no longer highlights Overview; and the
settings load-error banner drops its "! " prefix, with its assertion updated.

cargo test: 477 passed. npm run css:check clean.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NHyYupFdBiR4VfoUM7NjSM
2026-09-03 21:30:09 +00:00
thalladaandClaude Fable 5.1 12134f3596 Web dashboard v2 step 2: Tailwind design system, theme toggle, reader pages
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
2026-09-03 20:51:08 +00:00