Skip to content

chore(theme): migrate inline layout/typography CSS-var styles to Tailwind#101

Merged
yigitdot merged 2 commits into
mainfrom
chore/theme-tailwind-vars
May 13, 2026
Merged

chore(theme): migrate inline layout/typography CSS-var styles to Tailwind#101
yigitdot merged 2 commits into
mainfrom
chore/theme-tailwind-vars

Conversation

@yigitdot
Copy link
Copy Markdown
Collaborator

@yigitdot yigitdot commented May 13, 2026

Summary

Follow-up to the color-token migration (#4 / #75 / #76): moves the remaining inline-style CSS-var usages — typography (--fs-*) and layout (--frame-*) — off style={{}}.

  • Typography → Approach A. Renamed the type-scale tokens in @theme inline from --fs-* to Tailwind v4's --text-* namespace, so real font-size utilities auto-generate (text-h1, text-h2, text-h3, text-body, text-lead, text-cta, text-micro, text-method-row, text-price, plus the unused text-display — see chore(theme): drop the unused --text-display token #103) — font-size only (the keys are bare, no --text-*--line-height sibling), identical to the old inline behaviour. Converted ~30 style={{ fontSize: "var(--fs-X)" }} call sites to className="… text-X"; companion declarations in the same object became bracket utilities (lineHeight: "0.9"leading-[0.9], letterSpacing: "-0.01em"tracking-[-0.01em]); --reveal-delay writes preserved. Updated the 4 .prose var(--fs-*) refs + the explanatory comment to --text-*. Also folded the two hard-coded text-[0.6875rem] literals in Pill.tsx / PostRow.tsx (META) into the new text-micro utility — they were the same magnitude as --text-micro.
  • Layout → Approach B. --frame-* token names kept; the inline styles in Frame.tsx, Footer.tsx, Chrome.tsx became arbitrary-value classes (px-[var(--frame-gutter)], py-[var(--frame-pad-y)], max-w-[var(--frame-max)], min-h-[min(100svh,var(--frame-min-h-cap))]); now-empty style props removed. Matches the existing scroll-mt-[var(--nav-h)] precedent; globals.css's right: var(--frame-gutter) unchanged. Promoting --frame-* to a Tailwind namespace (the alternative discussed in chore(theme): migrate inline layout/typography CSS-var styles to Tailwind #78) is tracked separately in chore(theme): promote --frame-* layout tokens to Tailwind namespaces #102.

Out of scope (untouched): scroll-mt-[var(--nav-h)], the --reveal-delay writes.

Net −90 lines across 17 files. prettier-plugin-tailwindcss re-sorted the affected class lists.

Verification

  • pnpm format (clean) · pnpm lint ✅ · pnpm exec tsc --noEmit ✅ · pnpm test ✅ (45/45) · pnpm build ✅ (14/14 static pages)
  • grep var(--fs- in source → none; var(--text-*) in globals.css → the 4 .prose refs only.
  • Built CSS: all referenced text-* utilities emitted (incl. .text-micro{font-size:.6875rem}); --text-body/-lead/-h3 (the .prose-referenced ones) present in :root,:host; --frame-* still emitted (consumed by the bracket utilities + the mobile-menu right:); --nav-h intact.
  • Rendered out/ HTML: zero leftover style="font-size:var(--fs…)" / var(--frame…); text-* and [var(--frame-*)] classes present; style="--reveal-delay:…" still inline.
  • CSS bundle ~44.3 KB → ~44.8 KB (+~570 B; new utility rules vs. inline style attrs dropped from HTML — roughly flat).

Review follow-up

Closes #78

🤖 Generated with Claude Code

…wind

Promote the type-scale tokens in @theme inline from --fs-* to Tailwind
v4's --text-* namespace so font-size utilities (text-h1, text-body, …)
auto-generate, then drop the ~30 inline `style={{ fontSize: var(--fs-X) }}`
sites in favour of those classes (companion lineHeight/letterSpacing →
leading-[…] / tracking-[…]). Layout --frame-* tokens keep their names but
move from inline styles to arbitrary-value classes (px-[var(--frame-gutter)],
max-w-[var(--frame-max)], …), matching the existing scroll-mt-[var(--nav-h)]
precedent. Updates the .prose var(--fs-*) refs to --text-* accordingly.

Closes #78

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 13, 2026 03:39
@cloudflare-workers-and-pages
Copy link
Copy Markdown

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

Deploying website with  Cloudflare Pages  Cloudflare Pages

Latest commit: a09e0e2
Status: ✅  Deploy successful!
Preview URL: https://04031f29.website-70y.pages.dev
Branch Preview URL: https://chore-theme-tailwind-vars.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 migrates font-size and layout styles from inline React style props to Tailwind CSS classes across various components. This change is supported by renaming CSS variables in globals.css to the --text-* namespace, enabling Tailwind v4's automatic utility generation. Feedback suggests that layout-related variables should be promoted to the Tailwind theme (e.g., using the --spacing-* namespace) to avoid the use of arbitrary values in class lists and improve readability.

Comment thread components/ui/Frame.tsx
Comment on lines +23 to +25
className={`relative flex min-h-[min(100svh,var(--frame-min-h-cap))] scroll-mt-[var(--nav-h)] flex-col px-[var(--frame-gutter)] py-[var(--frame-pad-y)] ${TONE_CLASS[tone]} ${className}`}
>
<div
className="@container relative z-10 mx-auto flex w-full flex-1 flex-col"
style={{ maxWidth: "var(--frame-max)" }}
>
<div className="@container relative z-10 mx-auto flex w-full max-w-[var(--frame-max)] flex-1 flex-col">
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Using arbitrary values for theme variables makes the class list harder to read. If the variables in globals.css are promoted to the --spacing-* namespace (as suggested in that file), this can be simplified significantly using standard Tailwind utility classes.

Suggested change
className={`relative flex min-h-[min(100svh,var(--frame-min-h-cap))] scroll-mt-[var(--nav-h)] flex-col px-[var(--frame-gutter)] py-[var(--frame-pad-y)] ${TONE_CLASS[tone]} ${className}`}
>
<div
className="@container relative z-10 mx-auto flex w-full flex-1 flex-col"
style={{ maxWidth: "var(--frame-max)" }}
>
<div className="@container relative z-10 mx-auto flex w-full max-w-[var(--frame-max)] flex-1 flex-col">
className={"relative flex min-h-[min(100svh,var(--spacing-frame-min-h-cap))] scroll-mt-[var(--nav-h)] flex-col px-frame-gutter py-frame-pad-y " + TONE_CLASS[tone] + " " + className}
>
<div className="@container relative z-10 mx-auto flex w-full max-w-frame-max flex-1 flex-col">
References
  1. Avoid migrating inline styles to Tailwind arbitrary values (e.g., px-[var(--variable)]) if the variable is not part of the Tailwind theme configuration. Such migrations should be handled globally by first promoting the variables to the theme to ensure consistency across the codebase.

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.

Deliberate — this is the split called out in #78's "Approach (open question)" section. We took Approach A for the typography tokens (--fs-*--text-*, real text-h1/text-body/… utilities), but Approach B for the layout --frame-* tokens: keep the names, consume them via arbitrary-value classes, matching the existing scroll-mt-[var(--nav-h)] precedent in this same file. Promoting --frame-* to --spacing-*/--container-* renames the public CSS-var API, so it's intentionally kept separate.

Tracked for a possible future pass in #102 — leaving #101 as-is.

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

This PR completes the migration away from inline style={{ ... var(--...) }} usage for typography (--fs-*) and layout (--frame-*) tokens by moving them into Tailwind v4 utilities / arbitrary-value classes, keeping --reveal-delay inline where it’s semantically a variable write for animations.

Changes:

  • Renames the type-scale tokens in app/globals.css from --fs-* to Tailwind v4’s --text-* namespace so text-* font-size utilities are generated, and updates .prose to reference the new tokens.
  • Replaces inline font-size styles across UI/site/blog components with text-h*, text-body, text-lead, etc., plus bracket utilities for leading-* / tracking-* where needed.
  • Replaces inline --frame-* layout styles (gutter/padding/max width/min height) with arbitrary-value Tailwind classes like px-[var(--frame-gutter)], max-w-[var(--frame-max)], etc., and removes now-empty style props.

Reviewed changes

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

Show a summary per file
File Description
components/ui/PostRow.tsx Replaces inline font-size vars with text-h3 / text-body utilities.
components/ui/MethodRow.tsx Migrates method-row and body font sizing to text-method-row / text-body and keeps leading/tracking via utilities.
components/ui/Frame.tsx Converts frame sizing/padding/max-width inline styles to arbitrary-value Tailwind classes.
components/ui/Figure.tsx Converts inline font-size/letter-spacing to text-body and tracking-[...].
components/ui/FaqItem.tsx Replaces inline font sizing with text-lead / text-body while keeping --reveal-delay inline.
components/ui/ComparisonRow.tsx Moves fontSize from inline style to text-body class while preserving reveal delay style var.
components/site/Method.tsx Replaces inline font-size with text-h3.
components/site/Hero.tsx Converts headline/body/CTA font-size inline styles to text-h1 / text-body / text-cta.
components/site/Footer.tsx Migrates frame padding/max-width to bracket utilities and footer micro type to text-micro.
components/site/Faq.tsx Updates FAQ heading sizing to text-h2.
components/site/Comparison.tsx Converts heading/body/price sizing to text-h2 / text-body / text-price, keeping reveal delay inline.
components/site/Close.tsx Moves body/links sizing to text-body / text-lead, preserving reveal delay inline.
components/site/Chrome.tsx Replaces frame gutter/max-width inline styles with bracket utilities.
app/globals.css Renames --fs-*--text-* in @theme inline and updates .prose references/comments accordingly.
app/blog/page.tsx Updates blog index typography from inline styles to text-h2 / text-lead / text-body.
app/blog/[slug]/page.tsx Updates blog post title and prev/next link typography to text-h2 / text-lead.

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

Follow-ups from the #101 review:
- PostRow META + Pill: text-[0.6875rem] -> text-micro (the literal equals
  the --text-micro token now that this PR promoted it; one source of truth).
- globals.css: spell out that the --text-* keys are bare (no
  --text-*--line-height sibling), so the utilities set font-size only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@yigitdot yigitdot merged commit 5e1ec87 into main May 13, 2026
7 checks passed
@yigitdot yigitdot deleted the chore/theme-tailwind-vars branch May 13, 2026 04:12
yigitdot added a commit that referenced this pull request May 13, 2026
`--text-display: clamp(3.5rem, 14vw, 12.5rem)` in the `@theme inline`
block had no call sites — grep across app/, components/, lib/, content/
found only the declaration, and Tailwind v4 never emits a `text-display`
utility because it's never used in a class. Dead since before #101 (was
`--fs-display`; #101 renamed it along with the rest of the scale).

Closes #103

Co-authored-by: Claude Opus 4.7 (1M context) <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

Development

Successfully merging this pull request may close these issues.

chore(theme): migrate inline layout/typography CSS-var styles to Tailwind

2 participants