Color the read-time chip and measure only visible text - #23
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The bar's read time becomes a filled chip whose weight escalates with the estimate — kernel-green under 5 minutes, beige-muted to 15, charcoal past that. The Kernel palette has no red or amber and gold is never a background, so the escalation is contrast weight rather than hue; the tooltip carries the same meaning in words. The overlay also re-measures the text that is actually visible once the doc has settled (hidden tab panels, closed <details>, unopened dialogs) and posts jh:readtime. The SSR full-text estimate still paints first, so a doc whose overlay never runs is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
sjmiller609
force-pushed
the
hypeship/viewer-read-time
branch
from
July 31, 2026 15:41
b5e5311 to
d46dc4a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #21 (now in
main): the read time in the viewer bar becomes a colored chip, and the number counts only the text a reader can actually see on first load.1. The chip
Read time is now text in a filled box whose weight escalates with the estimate:
< 5 min#81b300#2122255–15 min#e1dccf> 15 min#212225#f2f0e7On brand compliance: the Kernel palette has no status colors — no red, no amber — and gold is explicitly never a background, so a literal ok/warn/error traffic light can't be built from approved tokens. Every value above is from the palette, and the escalation is carried by contrast weight instead of hue. Geometry mirrors the website's
Tag(4px radius, hairline border, 4/8px padding). Contrast: beige-muted+charcoal and charcoal+beige are AAA; kernel-green+charcoal is AA, which the brand guide allows for short dense glyphs like this one.On a dark bar the two darker borders switch to a light tone (
paletteVars) — otherwise the grey hairline disappears and the charcoal chip merges into the bar. Fills are literals rather than derived from the sampled doc palette, so the chip holds its contrast whatever colors the doc uses.Color isn't the only signal: the tooltip spells out the estimate, and past 15 minutes it says why the chip is heavy.
Thresholds live next to the rate constants in
lib/docs/reading-time.ts. Exactly 15 minutes iswarn; only 16+ isover.2. Visible-text measurement
The server estimate counts every word in the stored HTML — it can't see that three of four tab panels are hidden by a class defined in a
<style>block. The overlay can, so it walks the laid-out DOM, prunes hidden subtrees (display:none,visibility,opacity:0,hidden,aria-hidden, closed<details>beyond its summary,<dialog>withoutopen) plus our own injected chips, counts what survives with the same wpm/CJK rules, and postsjh:readtime.The shell seeds
readMinutesfrom the SSR value and swaps in the overlay's — so the chip paints immediately and a doc whose overlay never runs keeps the full-text number. Measurement runs on load, at 400ms with the theme sample, and once more at 1500ms; each report supersedes the last, which is what catches a tab UI that only hides its panels after script runs.The rate constants are duplicated in the overlay (stringified browser JS, can't import server code) and marked as needing to stay in sync — same split as the reaction signature.
Assumption worth confirming: the chip's color follows the number shown, i.e. the visible-text estimate. So a 40-minute doc with most content behind tabs shows a green
4 min read. The alternative is coloring by total text while displaying visible-only.Testing
npm test— 171 passing, including threshold boundaries at 4/5/15/16 and the tooltip copy.npm run buildandtsc --noEmitclean./d/[slug]first-load JS unchanged at 165 kB.4 mingreen,9 minbeige,21 mincharcoal; a CSS-tabbed doc23 → 4; a script-tabbed doc that hides panels 1s after load23 → 4; a doc with 4000 words in a closed<details>22 → 3. Chips checked on light and dark docs.Note
Low Risk
UI-only viewer chrome and overlay messaging; main maintenance risk is keeping duplicated read-rate constants in overlay.ts aligned with reading-time.ts.
Overview
Read time now starts from the SSR estimate but the doc iframe overlay re-counts only visible prose (hidden panels, closed
<details>, zero-opacity nodes, injected chips/anchors excluded) and sendsjh:readtimeto replace the bar value once layout settles (load, 400ms, 1500ms).The chrome read-time chip is restyled with Kernel palette buckets via
readTimeLevel/readTimeTitle(ok<5 min,warn5–15,over>15), including dark-bar border CSS vars and hiding the chip on mobile (<=768px).lib/docs/reading-time.tsdocuments the SSR vs overlay split and exports the level/title helpers; WPM/CJK rates are duplicated in the stringified overlay script with an explicit sync comment.Reviewed by Cursor Bugbot for commit d46dc4a. Bugbot is set up for automated code reviews on this repo. Configure here.