Skip to content

feat(display): default HTML pages to fit-width, top-aligned - #4

Merged
kelchm merged 2 commits into
mainfrom
feat/fit-width
Jul 16, 2026
Merged

feat(display): default HTML pages to fit-width, top-aligned#4
kelchm merged 2 commits into
mainfrom
feat/fit-width

Conversation

@kelchm

@kelchm kelchm commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Problem

The HTML display pages served to clients like Visionect (/rotation, and the zero-config root /) size the image with object-fit: contain — it fits both axes, so a newspaper whose aspect ratio differs from the panel shrinks into a letterboxed thumbnail with tiny, unreadable text.

Change

Default both HTML pages to fitting the viewport width, keeping the aspect ratio, pinning the top of the page to the top of the viewport, and clipping whatever runs past the bottom.

Why width-fit is the right default: it's a genuinely distinct scale rule (scale-to-width, neither contain's min nor cover's max). On a portrait panel it's equivalent to contain; on a wider panel it fills the glass and keeps the masthead/lead legible. In the one geometry where it would clip content, contain's non-cropped alternative was already an unreadable thumbnail — so width-fit dominates where they differ, and a front page front-loads its value at the top anyway.

fit= surface (HTML pages)

value scale anchor crops for
default (width) width top bottom reading — masthead-first
?fit=contain fit inside center never whole page as an artifact
?fit=cover fill center both fill the glass

Pair with ?margin=0 to pin flush to the top-left corner.

  • fit=width is client-side CSS only/rotation.png and /api/display still frame with contain/cover server-side (unchanged), so the shared vocabulary stays consistent.
  • The URL builder's Fit control offers all three for the Visionect target (defaulting to width) and contain/cover for the image/TRMNL targets, omitting fit from the URL when it matches the target default.

Behavior change

Existing HTML displays render fit-to-width on upgrade. Add ?fit=contain to the page URL to restore the previous letterboxed layout. Documented in CHANGELOG.

Verification

go build ./cmd/..., gofmt, and go test ./cmd/... all clean; no stale fit=width/body.width references. Visual behavior confirmed against a harness mirroring the final template CSS (a self-contained comparison of the three modes in a landscape panel).

🤖 Generated with Claude Code

https://claude.ai/code/session_01E2DKHiUNkAc1jo6gb4Ghi2

The HTML display pages (/rotation for Visionect and the zero-config root /)
fit the image to both viewport axes with object-fit: contain, so a paper
whose aspect ratio differs from the panel shrinks to a letterboxed thumbnail
with tiny, unreadable text.

Default them instead to fitting the viewport width, keeping the aspect ratio,
pinning the top of the page to the top of the viewport, and clipping whatever
runs past the bottom. This keeps the masthead and lead story large and legible
on any panel wider than the paper; where it would clip content, contain's
alternative was already an unreadable thumbnail, so width-fit dominates in the
one case they differ.

- New ?fit= values on the HTML pages: default (width, top), ?fit=contain
  (previous letterboxed behavior), ?fit=cover (fill, center-crop). fit=width is
  client-side CSS only; /rotation.png and /api/display still frame with
  contain/cover server-side.
- URL builder's Fit control offers all three for the Visionect target
  (defaulting to width) and contain/cover for the image/TRMNL targets, omitting
  fit from the URL when it matches the target default.

Behavior change: existing HTML displays render fit-to-width on upgrade; add
?fit=contain to restore the letterboxed layout.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2DKHiUNkAc1jo6gb4Ghi2
Copilot AI review requested due to automatic review settings July 16, 2026 02:41
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@kelchm, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 23 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 92b1a8c8-3380-4fdb-8663-edb875ce8dc6

📥 Commits

Reviewing files that changed from the base of the PR and between 7772646 and e3821f6.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • cmd/broadsheet-server/main.go
  • cmd/broadsheet-server/rotation.go
  • cmd/broadsheet-server/web/templates/builder.html

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR changes the default framing behavior of the HTML-based display pages so rendered newspaper pages fit the viewport width, remain top-aligned, and clip overflow at the bottom, improving legibility on panels whose aspect ratio would otherwise cause object-fit: contain letterboxing.

Changes:

  • Updates /rotation (Visionect/HTML) and the zero-config root HTML page to default to width-fit + top alignment, with ?fit=contain and ?fit=cover as explicit opt-in modes.
  • Updates the URL builder to expose the appropriate Fit choices per target and to omit fit from generated URLs when it matches the target default.
  • Documents the behavior change and the new fit semantics in CHANGELOG.md.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
cmd/broadsheet-server/web/templates/builder.html Updates Fit UI + URL emission rules so Visionect defaults to width-fit while other targets keep contain/cover defaults.
cmd/broadsheet-server/rotation.go Changes /rotation page CSS/JS to default to width-fit/top alignment, with `fit=contain
cmd/broadsheet-server/main.go Changes the zero-config HTML display page to the same default width-fit/top alignment behavior with `fit=contain
CHANGELOG.md Documents the HTML display behavior change and the fit= options.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@kelchm
kelchm merged commit ebbd27e into main Jul 16, 2026
5 checks passed
@kelchm
kelchm deleted the feat/fit-width branch July 16, 2026 03:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants