Skip to content

feat(frontend): marketing site, theme, wordmark, and UI polish#465

Open
skylerwww wants to merge 1 commit intoOpenSecretCloud:masterfrom
skylerwww:feature/frontend-ui-marketing-updates
Open

feat(frontend): marketing site, theme, wordmark, and UI polish#465
skylerwww wants to merge 1 commit intoOpenSecretCloud:masterfrom
skylerwww:feature/frontend-ui-marketing-updates

Conversation

@skylerwww
Copy link
Copy Markdown

@skylerwww skylerwww commented Apr 7, 2026

Summary

  • Maple wordmark component and brand assets; sidebar and chat chrome tweaks
  • Theme context, marketing home and solutions routes, agent/research pages
  • Shadcn/ui and dialog styling updates across account, billing, and team flows
  • Research empty state: Manrope heading, smaller size, descender-safe gradient text
  • Remove unused Bitcount font from index.html

Notes

Pushed from fork skylerwww/Maple — please review and merge when ready.

Made with Cursor


Open with Devin

- Add Maple wordmark component and brand assets; sidebar and chat chrome tweaks
- Theme context, marketing home and solutions routes, agent/research pages
- Shadcn/ui and dialog styling updates across account, billing, and team flows
- Research hero: Manrope, smaller heading, descender-safe gradient text
- Trim unused Bitcount font from index.html

Made-with: Cursor
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 2 potential issues.

View 5 additional findings in Devin Review.

Open in Devin Review

Comment thread frontend/index.html
@@ -1,5 +1,5 @@
<!doctype html>
<html lang="en" style="color-scheme: light dark">
<html lang="en">
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.

🔴 Dark mode flash-of-wrong-theme (FOUC) for users with dark OS preference

The PR removes the CSS @media (prefers-color-scheme: dark) rule from frontend/src/index.css (old lines 92-155) and the style="color-scheme: light dark" attribute from frontend/index.html:2, replacing them with a class-based .dark selector that depends on ThemeContext adding a .dark class via useEffect. Since useEffect runs only after React mounts, there is a window between initial page paint and React hydration where dark-mode users will see the light theme flash. The old media-query approach applied dark styles instantly without any JavaScript. Tailwind's darkMode: "class" (frontend/tailwind.config.js:9) also means all dark: utility variants now require the .dark class to be present, compounding the issue. The standard fix is an inline <script> in <head> that reads localStorage and applies the .dark class synchronously before any content paints.

Prompt for agents
The PR replaced CSS media-query-based dark mode with a class-based approach (ThemeContext adds .dark class via useEffect after React mount). This creates a flash-of-wrong-theme for dark mode users because the .dark class isn't applied until JavaScript executes.

To fix this, add a small inline script in the <head> of frontend/index.html (before any stylesheets or the main bundle) that synchronously reads the theme preference from localStorage (key: maple-theme) and applies the .dark class and color-scheme style to the <html> element. Something like:

<script>
  (function() {
    var stored = localStorage.getItem('maple-theme');
    var isDark = stored === 'dark' || (stored !== 'light' && window.matchMedia('(prefers-color-scheme: dark)').matches);
    if (isDark) {
      document.documentElement.classList.add('dark');
      document.documentElement.style.colorScheme = 'dark';
    } else {
      document.documentElement.style.colorScheme = 'light';
    }
  })();
</script>

This must run before any CSS is evaluated to prevent the flash. The ThemeContext (frontend/src/contexts/ThemeContext.tsx) already uses the same localStorage key (maple-theme) and the same logic, so this inline script just front-runs it.

The relevant files are:
- frontend/index.html (add the inline script in <head>)
- frontend/src/contexts/ThemeContext.tsx (ensure STORAGE_KEY matches)
- frontend/src/index.css (the .dark block at line 161 needs the class applied early)
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

return "system";
});

const resolvedTheme = theme === "system" ? getSystemTheme() : theme;
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.

🟡 ThemeContext resolvedTheme becomes stale when OS theme changes in "system" mode

resolvedTheme at frontend/src/contexts/ThemeContext.tsx:28 is a derived value computed during render, not React state. When theme === "system" and the OS preference changes, the media query handler (lines 51-59) correctly updates the DOM (adds/removes .dark class), but never calls setState, so resolvedTheme in the context remains stale until something else triggers a re-render. Any current or future consumer reading resolvedTheme from useTheme() will get an incorrect value after an OS theme switch. The fix is to store the resolved theme in state and update it from the media query handler.

Prompt for agents
In frontend/src/contexts/ThemeContext.tsx, the resolvedTheme on line 28 is computed as a plain derived value during render:

  const resolvedTheme = theme === 'system' ? getSystemTheme() : theme;

This doesn't update when the OS theme changes because the media query handler (lines 51-59) manipulates the DOM directly without triggering a React state update.

Fix: make resolvedTheme a state variable. For example:

  const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>(() =>
    theme === 'system' ? getSystemTheme() : theme
  );

Then in the media query change handler, call setResolvedTheme(mediaQuery.matches ? 'dark' : 'light'). Also update resolvedTheme when theme changes (e.g. in a useEffect dependent on theme).

This ensures that any component consuming resolvedTheme from the context gets an up-to-date value after an OS theme switch.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

AnthonyRonning added a commit that referenced this pull request Apr 14, 2026
Detailed spec derived from designer PR #465, scoped to the
authenticated product UI only. Covers design system tokens,
theme architecture, component-by-component visual changes,
and engineering standards for reimplementation.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
AnthonyRonning added a commit that referenced this pull request Apr 14, 2026
Detailed spec derived from designer PR #465, scoped to the
authenticated product UI only. Covers design system tokens,
theme architecture, component-by-component visual changes,
and engineering standards for reimplementation.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.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.

1 participant