Skip to content

[feat] Add a light theme to the marketing site with a system-aware switcher - #6124

Merged
mmabrouk merged 4 commits into
mainfrom
feat/website-light-mode
Sep 4, 2026
Merged

[feat] Add a light theme to the marketing site with a system-aware switcher#6124
mmabrouk merged 4 commits into
mainfrom
feat/website-light-mode

Conversation

@mmabrouk

Copy link
Copy Markdown
Member

Context

The marketing site only had a dark theme. Every component hard-coded its dark colors in inline styles, so there was no seam to render it any other way. Design handed over light versions of the landing, pricing, blog, and blog post pages, and we want the site to follow the visitor's system preference.

Changes

Colors now resolve through semantic --th-* tokens defined in the new src/styles/theme.css. The :root block holds the light values taken from the design mockups. The [data-theme="dark"] block holds the exact literals that were in the components before, so dark mode renders the same as it does today.

Before, in Hero.astro:

style="background:var(--ag-d-bg-1);border:1px solid rgba(255,255,255,0.07);"

After:

style="background:var(--th-bg-1);border:1px solid var(--th-section-border);"

Where no token fits because the two themes need unrelated values, the component defines its own pair instead:

.ag-hiw-card { --c-bg: #ffffff; }
[data-theme="dark"] .ag-hiw-card { --c-bg: rgba(255,255,255,0.02); }

An inline script in Base.astro runs before the stylesheets and sets data-theme on <html>. It reads localStorage("ag-theme"), which holds system, light, or dark and defaults to system. In system mode it follows prefers-color-scheme and updates live when the OS theme changes. Because it runs before first paint, there is no flash of the wrong theme. It also keeps the theme-color meta tag in sync.

SiteNav gains a switcher next to the CTAs. It cycles system, light, and dark, and shows a monitor, sun, or moon icon for the current preference. It appears in the mobile menu too.

Layout, spacing, typography, and copy are untouched. The mockups moved some elements around (for example the highlighted word in the hero headline); those differences were deliberately not carried over, since this PR only changes the theme.

Sections that the light design keeps dark stay dark: Reliability, Open source with its terminal, and the Enterprise plan card. Only their surface color is tuned per theme, using the warmer carbons the light design calls for. Blog and author pages use white chrome in light, matching the mockups.

Tests / notes

  • Checked the landing, pricing, blog index, a blog post, authors, contact, imprint, and 404 pages in both themes at 1440px, plus the landing at 390px with the mobile menu open.
  • Verified the scrolled nav pill, the prose styles in a real post, and that dark mode still matches the current site on every page.
  • pnpm build succeeds (48 pages). Deployed to the preview worker and confirmed the switcher works there: https://agenta-website-preview.mahmoud-637.workers.dev/
  • One deliberate dark-mode change: the outline button on the 404 page previously rendered its light styling even in dark. It now renders the dark ghost style like every other outline button.
  • Values I had to invent, because the mockups do not cover them, are worth a designer's eye: the contact, imprint, authors, and 404 pages, the nav dropdown panels, and the prose code blocks, tables, and blockquotes.

What to QA

  • Load the site with your OS set to light. It renders light. Switch your OS to dark with the switcher on system. The page follows without a reload.
  • Click the switcher through system, light, and dark. The icon changes each time and the choice survives a reload.
  • Set light, then hard reload. There is no dark flash before the page paints.
  • Open the landing in light and scroll past the hero. The nav collapses into the floating pill with a white halo, and the wordmark clips to the leaf.
  • Open a blog post in light. Headings, links, inline code, and lists are all readable, and the nav and footer are white rather than grey.
  • Check the pricing page in light. Plan cards are white, the Enterprise card stays dark, and the comparison table has alternating row stripes.
  • Regression: switch to dark and walk the same pages. They should look exactly like production does today.
  • Regression: at 390px wide, open the hamburger menu in both themes. The panel, the buttons, and the switcher are all legible.

…itcher

The site was dark-only. Every component hard-coded its dark colors inline,
so there was no way to render it light.

Colors now resolve through semantic --th-* tokens in src/styles/theme.css.
The :root values are light (ported from the light-mode design mockups); the
[data-theme="dark"] values reproduce the previous literals exactly, so dark
mode is unchanged.

An inline script in Base.astro sets data-theme on <html> before first paint
from localStorage("ag-theme"), defaulting to the OS preference and tracking
it live. SiteNav gains a switcher that cycles system, light, and dark.

Layout, spacing, type, and content are untouched. Sections the design keeps
dark in light mode (Reliability, Open source, the Enterprise plan card, the
terminal) stay dark, with only their surface tuned per theme.
@vercel

vercel Bot commented Aug 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
agenta-documentation Ready Ready Preview Sep 4, 2026 9:00am UTC

Request Review

@coderabbitai

coderabbitai Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Team

Run ID: efa5564b-c438-49e6-8fbc-1f90bfe92830

📥 Commits

Reviewing files that changed from the base of the PR and between 2353655 and a9c717a.

📒 Files selected for processing (5)
  • website/scripts/check-ui-primitives.mjs
  • website/src/components/Button.astro
  • website/src/components/SectionTitle.astro
  • website/src/layouts/Base.astro
  • website/src/styles/global.css

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.


📝 Summary

Summary by CodeRabbit

  • New Features

    • Added light, dark, and system theme options with automatic preference detection.
    • Added reusable full-width sections, linked badges, and theme-aware navigation controls.
    • Expanded light-mode styling across video placeholders, pricing, blog, author, contact, API, and interactive panels.
    • Improved responsive layouts and accessible theme switching across desktop and mobile.
  • Changes

    • Standardized navigation, logos, buttons, badges, cards, section borders, spacing, and visual tokens.
    • Inline article CTA cards are no longer displayed.

Walkthrough

The website adds light and dark theme support, shared Section, Badge, and Button primitives, centralized theme tokens, navigation theme controls, page migrations, and a build-time checker for duplicated UI recipes.

Changes

Website UI theming and primitives

Layer / File(s) Summary
Theme foundation and enforcement
website/src/styles/theme.css, website/src/styles/tokens.css, website/src/styles/global.css, website/scripts/check-ui-primitives.mjs, website/package.json, website/AGENTS.md
Adds semantic theme tokens, global themed styles, shared button and badge classes, UI primitive guidance, and a lint check that runs before builds.
Shared layout primitives
website/src/components/Section.astro, website/src/components/Badge.astro, website/src/components/Button.astro, website/src/components/SectionTitle.astro
Adds the shared section wrapper and converts badges and buttons to reusable class-based components. Section titles use theme variables and updated spacing.
Site shell and theme controls
website/src/layouts/Base.astro, website/src/layouts/Site.astro, website/src/components/SiteNav.astro, website/src/components/SiteFooter.astro, website/src/pages/index.astro
Adds theme preference resolution, theme controls, theme-specific logos, sticky navigation wiring, and the simplified landing-page shell.
Page and band migration
website/src/pages/*.astro, website/src/components/CtaBand.astro, website/src/components/Hero.astro, website/src/components/OpenSource.astro, website/src/components/OpenStandards.astro, website/src/components/Reliability.astro
Replaces raw section wrappers, inline badges, and inline buttons with shared primitives and theme variables across site pages and content bands.
Interactive component theming
website/src/components/HowItWorks.*, website/src/components/Template*.{astro,tsx}, website/src/components/PostCard.astro, website/src/components/PlanCard.astro, website/src/components/HostingToggle.tsx, website/src/components/CategoryFilter.tsx, website/src/components/InlineCta.astro, website/src/components/HeroVideo.astro
Moves component colors and surfaces to light/dark theme variables while preserving component behavior and interaction logic.

Estimated code review effort: 4 (Complex) | ~60 minutes

Merge Risk: 🟡 Moderate · up to 23536

Light-mode users can see dark browser chrome, and Windows contributors can be blocked from building the website. These issues should be fixed before merge.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.43% which is insufficient. The required threshold is 60.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 14 functions across 5 files. (34 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely describes the main change: adding a light theme with a system-aware theme switcher to the marketing site.
Description check ✅ Passed The description is directly related to the changeset and explains the theme tokens, pre-paint initialization, switcher behavior, affected pages, dark-mode preservation, and validation performed.
Full details: Docstring Coverage

Explanation

Docstring coverage is 21.43% which is insufficient. The required threshold is 60.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 14 functions across 5 files. (34 skipped: 34 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/website-light-mode

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.

…hip and button through one component

Framer measurements drove every value here. The rest-state nav bar is the
first band of the page grid: 1px left, right and bottom border in the grid
colour, going transparent once the bar becomes the pill. The blog, author and
pricing bodies are flat white bands with no side lines, while the nav, the CTA
band and the footer keep the grid, exactly as Framer draws them. The dark pill
gets the same four-layer border as the light one so the side rules meet a
visible edge.

Every full-width band now renders through components/Section.astro, which owns
the grid border and the -1px overlap (tone: grid, dark, flat). Every eyebrow
chip renders through components/Badge.astro or its .ag-badge class (24px,
uppercase, 12px/400, 1px outline, transparent inside, ink-600). The last
hand-drawn buttons on the contact page and in the blog inline CTA use the shared
.ag-btn. The landing page renders through the shared Site layout like every
other page, so the 1440 column is defined once.

scripts/check-ui-primitives.mjs runs before every build and fails when a page
draws the frame, the grid, a chip or a button by hand. The rules are documented
in website/AGENTS.md.

Claude-Session: https://claude.ai/code/session_01Q2VVWyYPi7hVthnGiqGPXU
@mmabrouk
mmabrouk marked this pull request as ready for review September 3, 2026 19:02
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Website preview

Preview URL: https://pr-6124-agenta-website-preview.mahmoud-637.workers.dev

Built from a9c717a92cadfe5fa0d718467219c65ee488a229. This comment updates in place on every push.

@mmabrouk
mmabrouk changed the base branch from release/v0.112.3 to main September 3, 2026 19:03
@mmabrouk
mmabrouk enabled auto-merge September 3, 2026 19:05
Resolves three conflicts: the build scripts in package.json (main's OpenAPI
copy and build verification join the UI-primitive guard), and the Open source
and Open standards headers (main's real <h2> headings keep the shared Badge
eyebrow and the theme colours). Main's new /api page gets the shared Badge and
Section like every other page; the guard caught its hand-drawn chip.

Claude-Session: https://claude.ai/code/session_01Q2VVWyYPi7hVthnGiqGPXU

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Team

Run ID: 589119e5-6bfe-43e3-b203-19b86174d355

📥 Commits

Reviewing files that changed from the base of the PR and between 3f15771 and 7732534.

📒 Files selected for processing (38)
  • website/AGENTS.md
  • website/package.json
  • website/scripts/check-ui-primitives.mjs
  • website/src/components/Badge.astro
  • website/src/components/Button.astro
  • website/src/components/CategoryFilter.tsx
  • website/src/components/CtaBand.astro
  • website/src/components/Hero.astro
  • website/src/components/HeroVideo.astro
  • website/src/components/HostingToggle.tsx
  • website/src/components/HowItWorks.astro
  • website/src/components/HowItWorks.tsx
  • website/src/components/InlineCta.astro
  • website/src/components/OpenSource.astro
  • website/src/components/OpenStandards.astro
  • website/src/components/PlanCard.astro
  • website/src/components/PostCard.astro
  • website/src/components/Reliability.astro
  • website/src/components/Section.astro
  • website/src/components/SectionTitle.astro
  • website/src/components/SiteFooter.astro
  • website/src/components/SiteNav.astro
  • website/src/components/TemplateExplorer.tsx
  • website/src/components/TemplateSection.astro
  • website/src/layouts/Base.astro
  • website/src/layouts/Site.astro
  • website/src/pages/404.astro
  • website/src/pages/authors/[slug].astro
  • website/src/pages/authors/index.astro
  • website/src/pages/blog/[slug].astro
  • website/src/pages/blog/index.astro
  • website/src/pages/contact.astro
  • website/src/pages/imprint.astro
  • website/src/pages/index.astro
  • website/src/pages/pricing.astro
  • website/src/styles/global.css
  • website/src/styles/theme.css
  • website/src/styles/tokens.css

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Comment thread website/scripts/check-ui-primitives.mjs Outdated
Comment thread website/src/components/Button.astro
Comment thread website/src/components/SectionTitle.astro
Comment thread website/src/layouts/Base.astro
@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
website/src/layouts/Base.astro (1)

74-75: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Move the theme-color meta element before the initializer or update it after insertion. With the default system preference resolving to light, the initializer runs before the meta element exists, so the later dark value remains. Supported browsers can use that value for dark browser chrome while the page is light.

website/scripts/check-ui-primitives.mjs (1)

18-18: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Convert the file URL with fileURLToPath before scanning src. On Windows, URL.pathname produces /C:/..., which is not the Windows filesystem path expected by readdirSync. The guard can therefore fail before astro build, because website/package.json runs it first.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Team

Run ID: 90e1bd5f-a58e-4655-aa49-c0dc332eca6e

📥 Commits

Reviewing files that changed from the base of the PR and between ded2cc3 and 2353655.

📒 Files selected for processing (39)
  • website/AGENTS.md
  • website/package.json
  • website/scripts/check-ui-primitives.mjs
  • website/src/components/Badge.astro
  • website/src/components/Button.astro
  • website/src/components/CategoryFilter.tsx
  • website/src/components/CtaBand.astro
  • website/src/components/Hero.astro
  • website/src/components/HeroVideo.astro
  • website/src/components/HostingToggle.tsx
  • website/src/components/HowItWorks.astro
  • website/src/components/HowItWorks.tsx
  • website/src/components/InlineCta.astro
  • website/src/components/OpenSource.astro
  • website/src/components/OpenStandards.astro
  • website/src/components/PlanCard.astro
  • website/src/components/PostCard.astro
  • website/src/components/Reliability.astro
  • website/src/components/Section.astro
  • website/src/components/SectionTitle.astro
  • website/src/components/SiteFooter.astro
  • website/src/components/SiteNav.astro
  • website/src/components/TemplateExplorer.tsx
  • website/src/components/TemplateSection.astro
  • website/src/layouts/Base.astro
  • website/src/layouts/Site.astro
  • website/src/pages/404.astro
  • website/src/pages/api.astro
  • website/src/pages/authors/[slug].astro
  • website/src/pages/authors/index.astro
  • website/src/pages/blog/[slug].astro
  • website/src/pages/blog/index.astro
  • website/src/pages/contact.astro
  • website/src/pages/imprint.astro
  • website/src/pages/index.astro
  • website/src/pages/pricing.astro
  • website/src/styles/global.css
  • website/src/styles/theme.css
  • website/src/styles/tokens.css
🚧 Files skipped from review as they are similar to previous changes (36)
  • website/src/components/PlanCard.astro
  • website/scripts/check-ui-primitives.mjs
  • website/package.json
  • website/src/pages/index.astro
  • website/src/components/SectionTitle.astro
  • website/src/layouts/Site.astro
  • website/src/components/CtaBand.astro
  • website/src/components/HostingToggle.tsx
  • website/src/styles/theme.css
  • website/src/components/TemplateSection.astro
  • website/src/components/Hero.astro
  • website/src/components/SiteNav.astro
  • website/src/pages/authors/index.astro
  • website/src/components/HeroVideo.astro
  • website/src/components/Section.astro
  • website/src/pages/imprint.astro
  • website/src/layouts/Base.astro
  • website/src/pages/authors/[slug].astro
  • website/src/components/OpenSource.astro
  • website/src/components/Button.astro
  • website/src/pages/contact.astro
  • website/src/components/HowItWorks.astro
  • website/src/pages/404.astro
  • website/src/components/InlineCta.astro
  • website/AGENTS.md
  • website/src/components/Badge.astro
  • website/src/components/HowItWorks.tsx
  • website/src/components/TemplateExplorer.tsx
  • website/src/pages/pricing.astro
  • website/src/styles/tokens.css
  • website/src/pages/blog/index.astro
  • website/src/components/CategoryFilter.tsx
  • website/src/pages/blog/[slug].astro
  • website/src/components/OpenStandards.astro
  • website/src/components/SiteFooter.astro
  • website/src/components/Reliability.astro

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.

Four fixes from the CodeRabbit pass, all confirmed against the code:

- check-ui-primitives.mjs resolved its source root through URL.pathname, which
  returns "/C:/..." on Windows and would fail every fs call before astro build
  starts. It uses fileURLToPath now.
- Button dropped every attribute outside its own prop list, so callers could
  not set id, type, disabled, aria-*, data-* or download. It extends the Astro
  HTML attributes and spreads the rest onto the rendered element.
- SectionTitle wrote #FFFFFF twice and .ag-btn--dark wrote #ffffff, against the
  rule that a component never carries a hex. All three use --text-on-dark.
- The theme-color meta element sat after the pre-paint theme resolver, so
  querySelector found nothing on the first run and a light first paint kept the
  dark colour until the next theme change. The meta element now precedes the
  resolver. Verified: a light first paint reports #F6F5F3.

Claude-Session: https://claude.ai/code/session_01Q2VVWyYPi7hVthnGiqGPXU
@mmabrouk
mmabrouk merged commit ffee618 into main Sep 4, 2026
11 of 13 checks passed
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