Skip to content

chore: theme token cleanup + chrome-active helper#137

Open
yigitdot wants to merge 6 commits into
mainfrom
chore/theme-chrome-followups
Open

chore: theme token cleanup + chrome-active helper#137
yigitdot wants to merge 6 commits into
mainfrom
chore/theme-chrome-followups

Conversation

@yigitdot
Copy link
Copy Markdown
Collaborator

@yigitdot yigitdot commented May 25, 2026

Summary

#115 was reviewed in parallel and intentionally deferred (audit comment posted on the issue); the helper extracted here is where its routing-aware fix will live.

Test plan

  • pnpm lint — clean
  • pnpm exec tsc --noEmit — clean
  • pnpm test — 101 pass, including the 6 resolveActiveSection cases
  • pnpm build — static export clean; built CSS contains .px-frame-gutter / .py-frame-pad-y / .max-w-frame / .min-h-frame-min-h and zero var(--frame-*) refs
  • pnpm dev smoke: gutter / max-width rail / section min-height visually unchanged on /, /blog/, and a post
  • Nav tone: scroll past intro on /text-paper; back-nav /blog// paints text-ink until first scroll; /blog/foo/ stays text-ink regardless of scroll
  • Mobile drawer (<768px): close × sits at the same gutter offset

🤖 Generated with Claude Code

yigitdot and others added 3 commits May 25, 2026 17:07
The `--font-sans` entry in `@theme inline` was never read: `html, body`
applies `font-family: var(--font-geist-sans), …` directly, and no
component uses the `font-sans` utility class (verified by grep across
`.ts(x)` / `.mdx`). Removing it loses no behavior — the `font-sans`
utility falls back to Tailwind's default sans stack — and shrinks the
theme surface.

Closes #105

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Finishes the migration left at the end of #78 / #101: the typography
half landed under the `--text-*` namespace (Approach A); the layout
half stayed as raw vars consumed via `px-[var(--frame-gutter)]` /
`max-w-[var(--frame-max)]` arbitrary-value classes (Approach B).

Renames so layout tokens auto-generate utilities:
- `--frame-gutter`    → `--spacing-frame-gutter` ⇒ `px-frame-gutter`
- `--frame-pad-y`     → `--spacing-frame-pad-y`  ⇒ `py-frame-pad-y`
- `--frame-max`       → `--container-frame`      ⇒ `max-w-frame`
- `--frame-min-h-cap` → `--spacing-frame-min-h: min(100svh, 54rem)`
  ⇒ `min-h-frame-min-h` (the `min()` was already at the lone call
  site; folding it into the token removes the last arbitrary value)

Frame.tsx, Footer.tsx, and Chrome.tsx's <nav> switch to the generated
utilities. The mobile-menu close button's raw CSS ref becomes
`right: var(--spacing-frame-gutter)`. The `--nav-h` comment block is
updated to match.

Closes #102

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The home-route-gated nav-tone ternary in `Chrome.tsx` (the #112 fix
plus the back-nav flash guard) was load-bearing but uncovered. Pulling
it into a pure helper lets it be unit-tested without dragging in
jsdom / RTL / IntersectionObserver mocks — the function takes
`(pathname, scrolled, observed, fallback)` and is independent of any
runtime.

Adds five cases from the issue, including the two regressions the
original fix exists to prevent: off-home stale `active` (the #112 bug)
and back-nav pre-scroll flash. `vitest.config.ts`'s existing
`**/*.test.ts` include glob picks the new file up unchanged.

Closes #117

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 25, 2026 14:10
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 25, 2026

Deploying website with  Cloudflare Pages  Cloudflare Pages

Latest commit: 86293ff
Status: ✅  Deploy successful!
Preview URL: https://376b8da6.website-70y.pages.dev
Branch Preview URL: https://chore-theme-chrome-followups.website-70y.pages.dev

View logs

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors CSS variable naming to align with Tailwind CSS v4 conventions and extracts the active section resolution logic into a dedicated utility function with accompanying tests. Key changes include renaming frame-related spacing and sizing variables and updating the Chrome, Footer, and Frame components to use these new utility classes. A critical issue was identified regarding the use of the --container-* namespace in app/globals.css, which does not automatically generate the max-w-frame utility; it is recommended to use the --width- namespace instead to ensure the styles are correctly applied.

Comment thread app/globals.css
--frame-gutter: clamp(1.5rem, 4vw, 4rem);
--frame-pad-y: clamp(
/* Shared content rail: every Frame centers within --container-frame. */
--container-frame: 1280px;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

In Tailwind CSS v4, the --container-* namespace is specifically reserved for configuring the container utility (e.g., centering, padding, or breakpoint-specific max-widths). It does not automatically generate a max-w-* utility for the given name. To enable the max-w-frame utility used in Chrome.tsx, Footer.tsx, and Frame.tsx, you should use the --width-* namespace (or --spacing-* if you want it available for padding/margin as well).

  --width-frame: 1280px;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Verified — --container-* does generate max-w-* in Tailwind v4. After pnpm build on this branch (39ac7c8), the static export contains .max-w-frame{max-width:1280px} — exactly the utility Chrome.tsx / Footer.tsx / Frame.tsx rely on. Tailwind v4's own defaults follow the same pattern: node_modules/tailwindcss/theme.css defines --container-3xs--container-7xl, which back the framework's max-w-3xsmax-w-7xl utilities, and the official v4 docs implement every max-w-* as max-width: var(--container-<name>) (e.g. max-w-2xs is max-width: var(--container-2xs)).

The @frame: container-query variant the comment alludes to is an additional output of --container-*, not a substitute — both happen. --width-* isn't a max-width-generating namespace in v4, so renaming to --width-frame would actually break max-w-frame. No change needed.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Chore PR that cleans up theme tokens and adds a small testable helper. Removes an unreferenced --font-sans token, promotes --frame-* layout vars to Tailwind v4 namespaces (--spacing-frame-* / --container-frame) so plain utilities like px-frame-gutter / max-w-frame replace arbitrary-value classes, and extracts the home-route nav-tone ternary in Chrome.tsx into a pure resolveActiveSection helper with 5 unit tests.

Changes:

  • Drop unreferenced --font-sans and rename --frame-* tokens to Tailwind v4 namespaces; update all consumers and the lone CSS ref.
  • Replace [var(--frame-*)] arbitrary-value classes in Frame, Footer, and Chrome with generated utilities.
  • Extract resolveActiveSection helper from Chrome.tsx and add table-driven Vitest cases.

Reviewed changes

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

Show a summary per file
File Description
app/globals.css Removes --font-sans; renames --frame-*--spacing-frame-* / --container-frame; folds min() into --spacing-frame-min-h; updates comments and .mm-toggle right.
components/ui/Frame.tsx Switches to px-frame-gutter py-frame-pad-y, min-h-frame-min-h, and max-w-frame utilities.
components/site/Footer.tsx Switches to px-frame-gutter / max-w-frame utilities.
components/site/Chrome.tsx Switches nav classes to new utilities; replaces inline ternary with resolveActiveSection(...).
components/site/chrome-active.ts New pure helper returning observed when on / and scrolled, else fallback.
components/site/chrome-active.test.ts Adds 5 Vitest cases covering the #112 bug, back-nav flash guard, passthrough, and off-home dominance.

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

yigitdot and others added 3 commits May 25, 2026 19:48
The "(the #112 bug)" parenthetical belongs in PR / commit history,
not in a long-lived test name where it rots once the issue is
forgotten. The behavior the test guards (off-home + scrolled →
fall back) is already self-describing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…h test

Addresses review feedback on the helper introduced in 39ac7c8:

- Constrain `<T extends string>` so unrelated types can't unify
  silently (`resolveActiveSection(p, s, 42, "intro")` stops
  compiling). Preserves the literal-union inference at the call site.
- Move the multi-line guard rationale from above the call site in
  Chrome.tsx to above the function in chrome-active.ts, where the
  `pathname === "/" && scrolled` logic actually lives. The original
  framing leaked Chrome.tsx-specific vocabulary (`DARK_SECTIONS`,
  `text-paper`); tightened to describe the helper's own contract.
- Add a 6th vitest case asserting the helper is exact-match
  (`/?utm=x` falls back), defending against a future caller that
  swaps usePathname() for something query-/hash-including.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Walks back two refinements from 0730f82:

- The constraint blocked no real misuse — the sole call site already
  infers T to a literal-string union from the caller's typing.
- The rehomed comment said the off-home observer "holds stale values"
  but the observer is never built off-home (Chrome.tsx's IO useEffect
  early-returns when no section nodes exist). It also kept the inherited
  "past the intro hero" framing for `scrolled`, which is misleading —
  scrolled flips at scrollY > 8, well inside intro. Rewritten as the
  "new observer has had a moment to fire" heuristic it actually is,
  with the back-nav restored-scroll caveat noted.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants