Migrate to the Twilight design system#48
Conversation
Replaces the template's MonaSans/Atkinson + Lora type and ad-hoc black/white-alpha colors with the Twilight system: semantic CSS-variable tokens (src/styles/tokens.css) wired to Tailwind utilities, Source Serif 4 prose on Inter UI, and regenerated brand assets (favicon.svg, og-image*.png, touch/chrome icons). Swaps hardcoded color classes for the auto-flipping semantic tokens (bg-bg, text-fg, text-muted, etc.) across components and pages, and drops the now-unused legacy fonts/images. Adds the design-system source of truth under docs/ (DESIGN_SYSTEM.md + docs/design-system/) and the dispatches-design skill, both referenced from CLAUDE.md. New helpers: ExcerptEntry component, rehype-sidenotes, and contentCard helpers. Note: the migrated header frost (src/styles/global.css) diverges from the documented reference and is addressed in follow-up work. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The header read saturated content scrolling behind it through an almost- transparent 4% tint and a 2x `filter: saturate()`, so a list title flipping to plum mid-hover smeared into a bright plum-pink flash — jarring against the deliberately low-saturation palette. Replace the 4% `--bg-elevated` tint with a dedicated opaque-ish veil token `--bg-frost` (paper @ 75% light / night @ 68% dark), exposed as the `bg-frost` utility, and drop the saturate boost entirely. The veil hides the one saturated color in the system (plum) while costing nothing on the near-neutral indigo/paper, so the flash is gone without touching the hover transition. Verified in light and dark via forced-plum-under-header screenshots and a production build. Reconcile the design-system source of truth to match: token tables in DESIGN_SYSTEM.md, the header recipe in design-system/README.md, the colors_and_type.css mirror, and the header/radii preview cards. (The generated _ds_manifest.json is left as-is; it carries no recipe prose.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The theme preference is stored in localStorage and applied via a `dark` class on <html>. But ClientRouter (View Transitions) rebuilds <html>'s attributes from the incoming server-rendered page on every swap, which drops the class. The astro:after-swap handler (init) re-synced the toggle button states but never re-applied the theme class, so the selection visually reset to light on each in-site navigation even though the stored preference and button highlight stayed correct. Re-apply the resolved theme in init() via preloadTheme(). init() already runs on astro:after-swap, which fires before paint, so the class is restored without a flash. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PR Validation ✅All checks passed! Ready for review. Checks Performed:✓ Linting This is a complete dry-run of the deployment process, ensuring your changes will deploy successfully when merged. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b03e35c88e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| <width>1200</width> | ||
| <height>630</height> |
There was a problem hiding this comment.
Keep the RSS image within spec
When feed clients validate or render rss.xml, these dimensions make the RSS <image> invalid: RSS 2.0 caps the image width at 144px and height at 400px, but this now advertises the 1200×630 OG art. Use a smaller feed logo/image here (or restore an appropriately sized RSS icon) so validators and readers do not reject or ignore the feed image.
Useful? React with 👍 / 👎.
Review: Migrate to the Twilight design systemThis is a large but well-scoped design-system migration: semantic CSS-variable tokens wired to Tailwind utilities, Source Serif 4 replacing Lora, regenerated brand assets, and a theme-persistence fix for View Transitions. The token architecture is clean — auto-flipping dark-mode semantics mean the Bug — sidenote node sharing for repeated footnote citations
Fix: clone the content array before spreading. // Line 121 — replace:
const content = notes.get(targetId) || [];
// with:
const content = structuredClone(notes.get(targetId) || []);Cleanup — dead
|
The RSS <image> advertised the 1200x630 OG art, exceeding the RSS 2.0 caps (144w x 400h), so validators/readers could reject or ignore it. Point it at a new public/rss-image.png — the brand favicon glyph rasterized from the design-system SVG to 144x144 (the spec ceiling), which is the right shape/semantics for a feed logo. Also drop <itunes:image>: this is a blog feed with no podcast plans, and the itunes: prefix was never declared by @astrojs/rss, making it an undeclared-namespace XML well-formedness error that strict validators would reject the whole feed over. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…upe helpers - rehype-sidenotes: structuredClone note content so a footnote cited more than once doesn't share hast nodes across sidenotes (one-parent invariant) - Head.astro + global.css: remove the dead animate() driver and the .animate tombstone — no element uses the class and the entrance animation is gone, so the no-op JS was a footgun if the CSS were ever un-commented - BackToPrev/BackToTop/ContentCard: drop redundant border-border; the bare `border` utility already resolves to var(--border) via borderColor.DEFAULT - contentCardHelpers: extract resolveBriefTitlePrefix shared by both brief mappers; getBriefCardProps now delegates base props to getStandardCardProps - global.css: document why dark:prose-invert is a sanctioned dark: exception Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PR Validation ✅All checks passed! Ready for review. Checks Performed:✓ Linting This is a complete dry-run of the deployment process, ensuring your changes will deploy successfully when merged. |
Code ReviewThis is a large, cohesive design-system migration: semantic CSS tokens wired to Tailwind utilities, Source Serif 4 replacing Lora, a new editorial-feed component ( Bugs
{data.imageDark && <meta property="og:image:dark" content={data.imageDark} />}
const plainTitle = title.replace(/<[^>]*>/g, "");
import { stripMarkdown } from "@lib/markdown";
// …
const plainTitle = stripMarkdown(title);
Minor / cleanupUnused parameters retained via void itemCount;
void pageType;The comment says they're "retained for potential future per-list cards." If that's the intent, a Source Serif 4 italic not preloaded ( The regular font file is preloaded but the italic file is not: <link rel="preload" href="/fonts/source-serif-4-latin.woff2" .../>
<!-- italic missing -->The previous setup preloaded two Lora weights; now only one of two Source Serif 4 files is hinted. Since <link rel="preload" href="/fonts/source-serif-4-latin-italic.woff2" as="font" type="font/woff2" crossorigin/>Everything else looks solid — the token architecture is clean, the Tufte sidenote plugin handles cloning and edge cases correctly, the dark-mode token flipping via 🤖 Generated with Claude Code |
…l markdown, prune unused params, preload serif italic - og:image:dark is not part of the Open Graph protocol and no platform honors it, so the dark social card never shipped. Remove the meta tag and all imageDark plumbing (OpenGraphData field, OG_IMAGE_DARK, resolveEntryImage return, Head.astro default). Keep og-image-dark.png as a brand asset and correct the design doc that claimed it was served. - ExcerptEntry aria-label now uses stripMarkdown(title) so inline code / emphasis isn't announced as literal backticks/asterisks. - Drop the unused pageType/itemCount params from getListOGData (dynamic OG cards are ruled out by the design system) and update the 4 callers. - Preload source-serif-4-latin-italic.woff2 to avoid a flash of fallback italic in prose body text. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks for the review — all four points addressed in 7dceff4. Bugs
Minor / cleanup
Verified: |
PR Validation ✅All checks passed! Ready for review. Checks Performed:✓ Linting This is a complete dry-run of the deployment process, ensuring your changes will deploy successfully when merged. |
Code Review — PR #48: Migrate to the Twilight design systemThis PR migrates the site from ad-hoc hardcoded color values (stone/black/white) to a coherent semantic-token design system ( Findings1.
|
…olor to JS theme - rehype-sidenotes: warn via file.message() when a footnote's non-paragraph blocks (lists, code, blockquotes) can't render in an inline sidenote, instead of dropping them silently - Head: replace the two prefers-color-scheme theme-color metas with a single <meta id="theme-color"> synced by applyThemeColor() inside toggleTheme(), so mobile browser chrome tracks the JS-toggled theme (load, toggle, OS change, View Transition swap) rather than the OS preference - ExcerptEntry: strip markdown from titlePrefix in the aria-label so screen readers don't announce literal markdown syntax - global.css: flag the unused .marginalia block as a reserved hook documented in DESIGN_SYSTEM.md §8 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PR Validation ✅All checks passed! Ready for review. Checks Performed:✓ Linting This is a complete dry-run of the deployment process, ensuring your changes will deploy successfully when merged. |
Code ReviewThis PR migrates the site from the template's ad-hoc color/font palette to a coherent Twilight design system: semantic CSS tokens in Four items worth a look: 1.
|
PR Validation ✅All checks passed! Ready for review. Checks Performed:✓ Linting This is a complete dry-run of the deployment process, ensuring your changes will deploy successfully when merged. |
Review of PR #48 (Twilight design-system migration)This is a large, well-organized migration (fonts, semantic color tokens, theme toggle, brand assets, sidenotes). Overall the token/Tailwind wiring is clean and the theme-toggle accessibility work (proper Correctness
Accessibility
Test coverage
Minor / non-blocking
Verified clean
Nice migration overall — items 1-4 are the ones I'd want resolved before shipping broadly (2 and 4 are user-facing regressions in specific conditions; 1 is a latent bug that'll surface as soon as a post uses a named footnote label). 🤖 Generated with Claude Code |
# Conflicts: # vitest.config.ts
PR Validation ✅All checks passed! Ready for review. Checks Performed:✓ Linting This is a complete dry-run of the deployment process, ensuring your changes will deploy successfully when merged. |
PR Validation ✅All checks passed! Ready for review. Checks Performed:✓ Linting This is a complete dry-run of the deployment process, ensuring your changes will deploy successfully when merged. |
Review of PR #48 (Twilight design-system migration)Reviewed the current head (
I also spot-checked the pieces most likely to have regressed from these fixes — Nothing new jumped out as a blocker. Two very minor, non-blocking observations, neither a regression from this PR:
No security concerns (OG image URLs are zod 🤖 Generated with Claude Code |
Migrates the site from the template's MonaSans/Atkinson/Lora type and ad-hoc black/white-alpha colors to the Twilight design system: semantic CSS-variable tokens (
src/styles/tokens.css) wired to Tailwind utilities, Source Serif 4 prose on Inter UI, and regenerated brand assets (favicon, OG images, touch/chrome icons), with hardcoded color classes swapped for auto-flipping tokens across every component and page and the legacy fonts/images dropped. Adds the design-system source of truth underdocs/plus thedispatches-designskill (both referenced fromCLAUDE.md) and new helpers (ExcerptEntry,rehype-sidenotes, contentCard helpers). Also fixes a plum flash in the frosted header by replacing the 4% tint +saturate()boost with a dedicated opaque-ishbg-frostveil token, and persists the selected theme across View Transition navigations by re-applying the resolved theme class in theastro:after-swaphandler.🤖 Generated with Claude Code