Skip to content

feat: implement color themes#35

Merged
Shunseii merged 1 commit intomainfrom
feat/color-themes
Dec 30, 2025
Merged

feat: implement color themes#35
Shunseii merged 1 commit intomainfrom
feat/color-themes

Conversation

@Shunseii
Copy link
Copy Markdown
Owner

@Shunseii Shunseii commented Dec 30, 2025

Summary by CodeRabbit

  • New Features

    • Added color theme selection with Nord and Tokyo Night plus a dedicated Color Theme menu in Settings; theme persists and initializes on load.
  • Improvements

    • Updated color palettes and theme styles; refined UI styling across navigation, headers, flashcards, and other components for visual consistency.
    • Minor text color and interactive tweaks for better contrast.
  • Documentation

    • Added "Adding Color Themes" guide and updated example environment variables.

✏️ Tip: You can customize this high-level summary in your review settings.

@Shunseii Shunseii self-assigned this Dec 30, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 30, 2025

📝 Walkthrough

Walkthrough

Adds a persistent color-theme system (enum, atom, DOM sync, selector), new theme CSS files and tokens, updates module path aliases to @bahar/design-system, multiple styling adjustments across components, and i18n entries plus README guidance for adding color themes.

Changes

Cohort / File(s) Summary
Color theme core
apps/web/src/atoms/theme.ts, apps/web/src/components/ThemeMenu.tsx, apps/web/index.html, apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
New ColorTheme enum, colorThemeAtom (storage + DOM sync), updateColorThemeInDOM(), getAllColorThemes(), new ColorThemeMenu component, index.html initializes stored theme, Settings now renders ColorThemeMenu.
Design-system CSS & imports
packages/design-system/themes.css, packages/design-system/colors.css, packages/design-system/globals.css
Added themes.css with nord/tokyo-night (light/dark) CSS variables; adjusted dark token values in colors.css; imported themes.css from globals.css.
Module alias / tsconfig updates
apps/marketing/components.json, apps/marketing/tsconfig.json, apps/web/components.json, apps/web/tsconfig.json, packages/web-ui/components.json, packages/web-ui/tsconfig.json
Redirected lib/utils aliases to @bahar/design-system; added @bahar/design-system/* path mappings; added ui alias in packages/web-ui/components.json.
Component styling updates
apps/web/src/components/DesktopNavigation.tsx, apps/web/src/components/MobileHeader.tsx, apps/web/src/components/OTPForm.tsx, apps/web/src/components/LanguageMenu.tsx, apps/web/src/components/search/InfiniteScroll.tsx, apps/web/src/components/features/flashcards/.../*, apps/web/src/routes/_authorized-layout/.../*.tsx, apps/web/src/routes/_unauthorized-layout/login/route.lazy.tsx
Wide set of presentational Tailwind/class changes: swap gradients to linear variants, adjust bg/border tokens (e.g., bg-background, bg-sidebar, border-sidebar-border), small typographic color tweaks, and shadow/hover adjustments. No behavioral logic changes.
Flashcards refinements (types & styling)
apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx, .../GradeFeedback.tsx, .../FlashcardDrawer.tsx, .../TagBadgesList.tsx
Renamed internal type GradeOptionConfigGradeOptionsConfig, added optional textStyles, updated label typing, and multiple styling tweaks (borders, gradients, hover behavior).
Documentation & localization
apps/web/README.md, packages/i18n/locales/ar.po, packages/i18n/locales/en.po, packages/i18n/locales/{ar,en}.ts
Added "Adding Color Themes" guide and README environment var examples; added/transformed i18n entries for theme labels (Default, Nord, Tokyo Night) and adjusted translation anchors.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI as ColorThemeMenu
    participant Atom as colorThemeAtom
    participant DOM as DocumentElement
    participant Storage as localStorage

    rect rgb(220,235,255)
    Note over Storage,DOM: Page load initialization
    Storage->>Atom: read "color-theme"
    Atom->>DOM: updateColorThemeInDOM(theme)
    DOM->>DOM: set/remove data-theme attribute
    end

    rect rgb(255,240,220)
    Note over User,Atom: User selects theme
    User->>UI: select option
    UI->>Atom: set new value
    Atom->>DOM: updateColorThemeInDOM(theme)
    Atom->>Storage: persist "color-theme"
    Storage-->>Atom: stored
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 Hop, a palette in my paw,

Nord and Tokyo-night I saw,
Stored safe in little keys,
Styles dancing with the breeze,
Hooray—design blooms, hip-hop hooray!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: implement color themes' accurately describes the main objective of the pull request, which is to add support for multiple color themes (Nord, Tokyo Night, and Default) across the application.
✨ Finishing touches
  • 📝 Generate docstrings

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 and usage tips.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Dec 30, 2025

Deploying bahar with  Cloudflare Pages  Cloudflare Pages

Latest commit: 985dff3
Status: ✅  Deploy successful!
Preview URL: https://f9ae3d2d.bahar-5xu.pages.dev
Branch Preview URL: https://feat-color-themes.bahar-5xu.pages.dev

View logs

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/web/index.html (1)

34-37: Pre-theme initialization prevents FOUC effectively.

The color theme initialization before React loads is a good approach to prevent flash of unstyled content. The explicit exclusion of "default" is sensible since it represents the base styling.

Optionally, consider validating the theme value against allowed themes to prevent setting invalid data-theme attributes:

🔎 Optional: Add theme validation
  const colorTheme = localStorage.getItem("color-theme");
- if (colorTheme && colorTheme !== "default") {
+ const validThemes = ["nord", "tokyo-night"];
+ if (colorTheme && colorTheme !== "default" && validThemes.includes(colorTheme)) {
    document.documentElement.setAttribute("data-theme", colorTheme);
  }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b602f0a and bf54053.

📒 Files selected for processing (31)
  • apps/marketing/components.json
  • apps/marketing/tsconfig.json
  • apps/web/README.md
  • apps/web/components.json
  • apps/web/index.html
  • apps/web/src/atoms/theme.ts
  • apps/web/src/components/DesktopNavigation.tsx
  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/components/OTPForm.tsx
  • apps/web/src/components/ThemeMenu.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeFeedback.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/TagBadgesList.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/route.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/route.tsx
  • apps/web/src/routes/_unauthorized-layout/login/route.lazy.tsx
  • apps/web/tsconfig.json
  • packages/design-system/colors.css
  • packages/design-system/globals.css
  • packages/design-system/themes.css
  • packages/i18n/locales/ar.po
  • packages/i18n/locales/ar.ts
  • packages/i18n/locales/en.po
  • packages/i18n/locales/en.ts
  • packages/web-ui/components.json
  • packages/web-ui/tsconfig.json
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript with strict typing across entire codebase
Do not use any type unless absolutely necessary
Error handling with try/catch blocks and structured error types
Use Drizzle ORM for database operations
Use DisplayError class for user-friendly error messages and Result<T, E> type for explicit error handling (Rust-like pattern)

Files:

  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/DesktopNavigation.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/route.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/components/OTPForm.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeFeedback.tsx
  • apps/web/src/routes/_unauthorized-layout/login/route.lazy.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/components/ThemeMenu.tsx
  • apps/web/src/atoms/theme.ts
  • packages/i18n/locales/ar.ts
  • apps/web/src/routes/_authorized-layout/_search-layout/route.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/TagBadgesList.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
  • packages/i18n/locales/en.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Write self-documenting code and avoid overuse of comments
Component naming: PascalCase for components, camelCase for functions/variables

Files:

  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/DesktopNavigation.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/route.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/components/OTPForm.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeFeedback.tsx
  • apps/web/src/routes/_unauthorized-layout/login/route.lazy.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/components/ThemeMenu.tsx
  • apps/web/src/atoms/theme.ts
  • packages/i18n/locales/ar.ts
  • apps/web/src/routes/_authorized-layout/_search-layout/route.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/TagBadgesList.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
  • packages/i18n/locales/en.ts
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{tsx,jsx}: React components use functional style with hooks
Prefer using jotai atoms over React Context
State management: use Tanstack Query for async state and Jotai for atomic state
Use Tanstack Query for server state management

Files:

  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/DesktopNavigation.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/route.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/components/OTPForm.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeFeedback.tsx
  • apps/web/src/routes/_unauthorized-layout/login/route.lazy.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/components/ThemeMenu.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/route.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/TagBadgesList.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
apps/web/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Web app uses Shadcn/UI components and Tailwind CSS v4 for styling, use the cn() utility function for combining and conditionally applying Tailwind classes

Files:

  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/DesktopNavigation.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/route.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/components/OTPForm.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeFeedback.tsx
  • apps/web/src/routes/_unauthorized-layout/login/route.lazy.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/components/ThemeMenu.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/route.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/TagBadgesList.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
apps/web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/web/**/*.{ts,tsx}: Web app uses Tanstack Router for client-side routing
Orama is used for client-side WASM search engine with multi-language support (Arabic + English), indexed from local database on app initialization

Files:

  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/DesktopNavigation.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/route.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/components/OTPForm.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeFeedback.tsx
  • apps/web/src/routes/_unauthorized-layout/login/route.lazy.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/components/ThemeMenu.tsx
  • apps/web/src/atoms/theme.ts
  • apps/web/src/routes/_authorized-layout/_search-layout/route.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/TagBadgesList.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
apps/{web,mobile}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Lingui (v5) for internationalization in both web and mobile applications

Files:

  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/DesktopNavigation.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/route.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/components/OTPForm.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeFeedback.tsx
  • apps/web/src/routes/_unauthorized-layout/login/route.lazy.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/components/ThemeMenu.tsx
  • apps/web/src/atoms/theme.ts
  • apps/web/src/routes/_authorized-layout/_search-layout/route.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/TagBadgesList.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
🧠 Learnings (8)
📚 Learning: 2025-12-28T19:33:44.247Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T19:33:44.247Z
Learning: Applies to apps/web/**/*.{tsx,jsx} : Web app uses Shadcn/UI components and Tailwind CSS v4 for styling, use the `cn()` utility function for combining and conditionally applying Tailwind classes

Applied to files:

  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/DesktopNavigation.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/route.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/routes/_unauthorized-layout/login/route.lazy.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • packages/design-system/globals.css
  • apps/web/README.md
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
📚 Learning: 2025-12-28T19:33:44.247Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T19:33:44.247Z
Learning: Applies to apps/{web,mobile}/**/*.{ts,tsx} : Use Lingui (v5) for internationalization in both web and mobile applications

Applied to files:

  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/tsconfig.json
  • packages/i18n/locales/ar.ts
  • packages/i18n/locales/en.po
📚 Learning: 2025-12-28T19:33:44.247Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T19:33:44.247Z
Learning: Applies to apps/mobile/**/*.{ts,tsx} : Mobile app uses UniWind (Tailwind for React Native) with Tailwind CSS v4

Applied to files:

  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/DesktopNavigation.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/route.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/components/MobileHeader.tsx
  • apps/web/tsconfig.json
  • apps/web/src/components/OTPForm.tsx
  • apps/web/src/routes/_unauthorized-layout/login/route.lazy.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • packages/design-system/globals.css
  • apps/marketing/tsconfig.json
📚 Learning: 2025-12-28T19:33:44.247Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T19:33:44.247Z
Learning: Applies to apps/web/**/*.{ts,tsx} : Web app uses Tanstack Router for client-side routing

Applied to files:

  • apps/web/src/routes/_authorized-layout/_app-layout/route.tsx
  • apps/web/tsconfig.json
📚 Learning: 2025-12-28T19:33:44.247Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T19:33:44.247Z
Learning: Applies to apps/mobile/**/*.{ts,tsx} : Mobile app uses Expo with file-based routing (Expo Router)

Applied to files:

  • apps/web/src/routes/_authorized-layout/_app-layout/route.tsx
  • apps/web/src/components/MobileHeader.tsx
  • apps/web/tsconfig.json
📚 Learning: 2025-11-27T06:02:25.941Z
Learnt from: Shunseii
Repo: Shunseii/bahar PR: 24
File: apps/web/src/components/features/decks/DeckDialogContent.tsx:195-201
Timestamp: 2025-11-27T06:02:25.941Z
Learning: In apps/web/src/components/features/decks/DeckDialogContent.tsx, the backend API calls (trpc.decks.create and trpc.decks.update) are temporary and planned to be removed after migration is complete.

Applied to files:

  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
📚 Learning: 2025-12-28T19:33:44.247Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T19:33:44.247Z
Learning: Applies to **/*.{tsx,jsx} : Prefer using jotai atoms over React Context

Applied to files:

  • apps/web/src/components/ThemeMenu.tsx
📚 Learning: 2025-12-28T19:33:44.247Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T19:33:44.247Z
Learning: Applies to **/*.{tsx,jsx} : React components use functional style with hooks

Applied to files:

  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
🧬 Code graph analysis (5)
apps/web/src/components/LanguageMenu.tsx (1)
packages/web-ui/src/components/select.tsx (1)
  • SelectTrigger (155-155)
apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx (1)
apps/web/src/components/ThemeMenu.tsx (1)
  • ColorThemeMenu (98-129)
packages/i18n/locales/ar.ts (1)
packages/i18n/locales/en.ts (1)
  • messages (1-1)
apps/web/src/components/features/flashcards/FlashcardDrawer/TagBadgesList.tsx (1)
packages/web-ui/src/components/badge.tsx (1)
  • Badge (35-35)
packages/i18n/locales/en.ts (1)
packages/i18n/locales/ar.ts (1)
  • messages (1-1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Workers Builds: bahar-marketing
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (37)
apps/web/src/routes/_authorized-layout/_app-layout/route.tsx (1)

16-16: LGTM! Semantic color token improves theming support.

The change from bg-muted/40 to bg-background correctly uses a semantic color token that will automatically adapt to different color themes. This aligns with the new theming system introduced in this PR.

apps/web/src/components/OTPForm.tsx (2)

60-60: LGTM! Theme-aware caret color.

Replacing bg-white with bg-foreground makes the caret color adapt to the active theme, ensuring proper visibility across different color schemes.


133-133: LGTM! Consolidated theme-aware text color.

The change to text-foreground simplifies the color class by removing the dark mode variant and using a semantic token that automatically adapts to all themes.

apps/web/src/routes/_authorized-layout/_search-layout/route.tsx (1)

19-19: LGTM! Consistent theming approach.

This change mirrors the identical update in _app-layout/route.tsx, ensuring consistent use of semantic color tokens across layout components.

packages/i18n/locales/ar.ts (1)

1-1: LGTM! Formatting normalization.

No functional changes observed. The compiled message catalog includes the necessary translations for the theme system as referenced in the PR summary.

apps/web/src/components/features/flashcards/FlashcardDrawer/GradeFeedback.tsx (1)

29-29: Verify the opacity increase for "Again" feedback.

The change from bg-muted/20 to bg-muted increases the background opacity from 20% to 100%, making the "Again" feedback significantly more prominent. Please verify this is intentional and that the visual feedback remains balanced compared to other rating options (Hard, Good, Easy).

apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx (1)

59-59: Verify border appearance with new theme system.

Removing border-0 means the Card component will now render with its default border. Please verify that this border displays correctly across all color themes (Default, Nord, Tokyo Night) and maintains the desired visual hierarchy.

packages/i18n/locales/en.ts (1)

1-1: LGTM! Formatting normalization.

No functional changes observed. The compiled message catalog structure remains intact.

apps/web/src/components/search/InfiniteScroll.tsx (2)

411-411: LGTM! Consistent gradient token usage.

The accent line gradient change aligns with the other gradient updates in this component, using the new theme-aware gradient utilities.


342-349: No action needed. The gradient utilities (bg-linear-to-br, bg-linear-to-b) are built-in Tailwind CSS v4 utilities (renamed in v4 from the older bg-gradient-to-* syntax) and are fully supported by the installed version (4.1.7). They do not require custom design system configuration and will render correctly across all themes with the existing semantic color tokens.

Likely an incorrect or invalid review comment.

packages/i18n/locales/en.po (1)

514-516: LGTM! Theme translations added correctly.

All three color theme labels ("Default", "Nord", "Tokyo Night") have been added to the English locale with appropriate source references to the ThemeMenu component.

Also applies to: 1145-1147, 1701-1703

packages/design-system/themes.css (1)

1-163: LGTM! Comprehensive theme system with excellent color consistency.

The theme definitions are well-structured with:

  • Complete variable sets across all four theme variants (Nord light/dark, Tokyo Night light/dark)
  • Valid Oklch color values throughout
  • Consistent naming conventions
  • Clear separation of standard and extra colors

The use of Oklch color space is a modern choice that provides perceptually uniform colors and better color manipulation capabilities.

packages/design-system/globals.css (1)

3-3: LGTM! Import order is correct.

The themes.css import is correctly placed after colors.css and before the plugin directive, ensuring base colors are defined before theme-specific overrides.

apps/web/src/components/features/flashcards/FlashcardDrawer/TagBadgesList.tsx (1)

46-46: LGTM! Simplified badge styling improves consistency.

Removing the opacity and hover transitions from non-interactive tag badges is the correct approach. The badges are purely presentational elements without click handlers, so the simplified styling with border-border aligns better with their function and the design system standardization.

packages/i18n/locales/ar.po (1)

514-516: LGTM! Arabic translations are appropriate.

The translations for theme names are well-chosen:

  • "Default" → "افتراضي" (translated)
  • "Nord" → "نورد" (transliterated, appropriate for proper name)
  • "Tokyo Night" → "ليلة طوكيو" (translated literally)

Also applies to: 1145-1147, 1701-1703

packages/design-system/colors.css (1)

49-51: LGTM! Dark mode contrast improvements.

The adjustments to card and popover colors in dark mode are beneficial:

  • Lightness increased from 14% to 18% (better visibility)
  • Chroma slightly reduced from 0.03 to 0.025 (less eye strain)

These changes improve readability and reduce visual fatigue in dark mode while maintaining the overall color scheme.

apps/web/src/components/LanguageMenu.tsx (1)

37-37: LGTM! Migrating to design system color tokens.

Removing the hardcoded dark:text-slate-50 class allows the SelectTrigger to properly inherit text colors from the active theme. This change aligns with the design system standardization effort and ensures better theme integration.

apps/web/src/routes/_unauthorized-layout/login/route.lazy.tsx (1)

88-92: LGTM! Proper use of design system color tokens.

The migration from hardcoded Tailwind colors to semantic design system tokens is the correct approach:

  • text-foreground for the primary heading (h1)
  • text-muted-foreground for descriptive text (paragraph)

This ensures the login page respects the selected color theme and maintains consistent typography colors across the application.

packages/web-ui/tsconfig.json (1)

9-10: LGTM! Path alias correctly configured.

The new @bahar/design-system/* alias is properly set up to enable imports from the centralized design-system package. The relative path is correct and aligns with the monorepo structure.

apps/web/tsconfig.json (1)

10-11: LGTM! Path alias correctly configured.

The @bahar/design-system/* alias is properly configured with the correct relative path from the web app to the design-system package.

apps/marketing/tsconfig.json (1)

9-10: LGTM! Consistent with monorepo-wide refactor.

The path alias is correctly configured and consistent with the pattern established in other apps.

apps/web/README.md (1)

80-122: Excellent documentation for the new theming system!

The step-by-step guide is comprehensive and includes all necessary changes across CSS, TypeScript, and i18n. The code examples are clear and follow project conventions. This will be very helpful for future theme additions.

apps/web/src/components/DesktopNavigation.tsx (1)

27-27: LGTM! Styling updated for new theme system.

The transition from gradient/backdrop-blur to semantic color tokens (border-sidebar-border, bg-sidebar) aligns with the new design-system theming. The directional border classes are correctly maintained.

apps/web/src/components/MobileHeader.tsx (2)

65-65: LGTM! Sheet styling updated for theme consistency.

The DraggableSheetContent now uses the semantic border and background tokens from the design-system, consistent with the theming updates across other navigation components.


103-103: LGTM! Header styling aligned with design-system tokens.

The MobileHeader styling update mirrors the changes in DesktopNavigation, using consistent semantic color tokens for borders and backgrounds.

apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx (1)

33-33: LGTM!

The ColorThemeMenu is correctly imported and integrated within the Appearance settings section, following the existing pattern established by ThemeMenu. The placement in the UI flow is logical.

Also applies to: 206-210

apps/marketing/components.json (1)

16-17: LGTM!

The alias updates correctly redirect lib and utils to the @bahar/design-system package, aligning with the broader consolidation of design-system utilities across the monorepo.

apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx (2)

398-398: LGTM!

The styling updates correctly use Tailwind CSS v4 gradient syntax (bg-linear-to-br instead of bg-gradient-to-*). The enhanced border opacity and shadow improve visual definition of the flashcard content area.


410-410: LGTM!

Consistent use of Tailwind CSS v4 gradient syntax for the dividers.

Also applies to: 427-427

apps/web/src/components/ThemeMenu.tsx (3)

11-20: LGTM!

The imports are well-organized, bringing in the necessary Palette icon and color theme-related exports from the theme atom.


84-96: LGTM!

ColorThemeLabel follows the established pattern from ThemeLabel, providing consistent i18n-ready labels via <Trans> for each color theme option.


98-129: LGTM!

ColorThemeMenu is well-implemented, following the same pattern as ThemeMenu. It correctly uses jotai's useAtom hook with colorThemeAtom for state management, adhering to the coding guidelines preference for jotai atoms over React Context.

apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx (2)

11-17: LGTM!

The type definition improvements are clean. Using React.ReactNode explicitly and adding the optional textStyles field provides flexibility for per-grade text styling customization.


86-93: LGTM!

The styling updates improve visual feedback with hover:text-foreground and hover:shadow-lg. Including textStyles in the cn() call allows per-grade text customization while safely handling undefined values.

apps/web/src/atoms/theme.ts (2)

45-59: LGTM!

The ColorTheme enum and supporting functions are well-designed:

  • Enum values use kebab-case which aligns with CSS data-attribute conventions
  • updateColorThemeInDOM correctly removes the attribute for DEFAULT, allowing CSS to fall back to base theme variables

61-80: LGTM!

The colorThemeAtom implementation correctly follows the established pattern from themeAtom. The null-coalescing in getItem (line 67) provides safer handling when localStorage returns null, which is a nice improvement over the themeAtom pattern.

packages/web-ui/components.json (1)

15-18: LGTM!

The alias updates consolidate the design-system references across the monorepo. The explicit ui alias pointing to @bahar/web-ui/components improves clarity for shadcn CLI operations.

Comment thread apps/web/components.json Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
apps/web/components.json (1)

16-17: Follow up on design-system package exports.

The alias changes from @/lib and @bahar/web-ui/lib/utils to @bahar/design-system are consistent with the theming refactor. However, a previous review comment flagged that the design-system package.json lacks proper export definitions for these paths.

As noted in the previous review, please verify that packages/design-system/package.json includes the necessary exports:

"exports": {
  ".": "./src/index.ts",
  "./utils": "./src/utils.ts",
  "./globals.css": "./globals.css",
  "./colors.css": "./colors.css",
  "./themes.css": "./themes.css"
}

Run the following script to verify the exports configuration:

#!/bin/bash
# Check if design-system package.json has proper exports
if [ -f "packages/design-system/package.json" ]; then
  echo "=== Checking package.json exports ==="
  cat packages/design-system/package.json | jq '.exports'
  
  echo -e "\n=== Checking if referenced files exist ==="
  [ -f "packages/design-system/src/index.ts" ] && echo "✓ src/index.ts exists" || echo "✗ src/index.ts missing"
  [ -f "packages/design-system/src/utils.ts" ] && echo "✓ src/utils.ts exists" || echo "✗ src/utils.ts missing"
  [ -f "packages/design-system/globals.css" ] && echo "✓ globals.css exists" || echo "✗ globals.css missing"
  [ -f "packages/design-system/themes.css" ] && echo "✓ themes.css exists" || echo "✗ themes.css missing"
fi
🧹 Nitpick comments (1)
apps/web/src/components/ThemeMenu.tsx (1)

98-129: Consider differentiating color theme icons.

The implementation is solid and follows the ThemeMenu pattern well. However, unlike ThemeMenu which uses distinct icons for each theme (Moon, Sun, Monitor), ColorThemeMenu uses the same Palette icon for all themes.

Optional enhancement: Add distinct icons per theme

You could enhance visual distinction by using different icons for each color theme, similar to how ThemeMenu differentiates its options. For example:

+const ColorThemeIcon: FC<{ theme: ColorTheme }> = ({ theme }) => {
+  switch (theme) {
+    case ColorTheme.NORD:
+      return <Snowflake size={16} />;
+    case ColorTheme.TOKYO_NIGHT:
+      return <Moon size={16} />;
+    case ColorTheme.DEFAULT:
+    default:
+      return <Palette size={16} />;
+  }
+};

 export const ColorThemeMenu = () => {
   // ...
   return (
     <Select /* ... */>
       {/* ... */}
       <SelectContent>
         <SelectGroup>
           {getAllColorThemes().map((theme) => (
             <SelectItem className="cursor-pointer" key={theme} value={theme}>
               <div className="flex flex-row items-center gap-x-2">
-                <Palette size={16} />
+                <ColorThemeIcon theme={theme} />
                 <ColorThemeLabel theme={theme} />
               </div>
             </SelectItem>
           ))}
         </SelectGroup>
       </SelectContent>
     </Select>
   );
 };

Note: You would need to import additional icons like Snowflake from lucide-react.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between bf54053 and 985dff3.

📒 Files selected for processing (31)
  • apps/marketing/components.json
  • apps/marketing/tsconfig.json
  • apps/web/README.md
  • apps/web/components.json
  • apps/web/index.html
  • apps/web/src/atoms/theme.ts
  • apps/web/src/components/DesktopNavigation.tsx
  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/components/OTPForm.tsx
  • apps/web/src/components/ThemeMenu.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeFeedback.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/TagBadgesList.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/route.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/route.tsx
  • apps/web/src/routes/_unauthorized-layout/login/route.lazy.tsx
  • apps/web/tsconfig.json
  • packages/design-system/colors.css
  • packages/design-system/globals.css
  • packages/design-system/themes.css
  • packages/i18n/locales/ar.po
  • packages/i18n/locales/ar.ts
  • packages/i18n/locales/en.po
  • packages/i18n/locales/en.ts
  • packages/web-ui/components.json
  • packages/web-ui/tsconfig.json
✅ Files skipped from review due to trivial changes (2)
  • apps/web/src/routes/_authorized-layout/_search-layout/route.tsx
  • packages/i18n/locales/en.ts
🚧 Files skipped from review as they are similar to previous changes (16)
  • apps/web/tsconfig.json
  • packages/design-system/colors.css
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeOption.tsx
  • packages/web-ui/tsconfig.json
  • apps/marketing/components.json
  • packages/design-system/themes.css
  • apps/web/src/components/DesktopNavigation.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/GradeFeedback.tsx
  • apps/web/src/components/features/flashcards/FlashcardDrawer/TagBadgesList.tsx
  • apps/web/src/routes/_unauthorized-layout/login/route.lazy.tsx
  • packages/i18n/locales/ar.ts
  • apps/web/src/atoms/theme.ts
  • apps/web/src/components/features/flashcards/FlashcardDrawer/FlashcardDrawer.tsx
  • apps/marketing/tsconfig.json
  • apps/web/index.html
  • apps/web/src/routes/_authorized-layout/_app-layout/route.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript with strict typing across entire codebase
Do not use any type unless absolutely necessary
Error handling with try/catch blocks and structured error types
Use Drizzle ORM for database operations
Use DisplayError class for user-friendly error messages and Result<T, E> type for explicit error handling (Rust-like pattern)

Files:

  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/ThemeMenu.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/components/OTPForm.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Write self-documenting code and avoid overuse of comments
Component naming: PascalCase for components, camelCase for functions/variables

Files:

  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/ThemeMenu.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/components/OTPForm.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{tsx,jsx}: React components use functional style with hooks
Prefer using jotai atoms over React Context
State management: use Tanstack Query for async state and Jotai for atomic state
Use Tanstack Query for server state management

Files:

  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/ThemeMenu.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/components/OTPForm.tsx
apps/web/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Web app uses Shadcn/UI components and Tailwind CSS v4 for styling, use the cn() utility function for combining and conditionally applying Tailwind classes

Files:

  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/ThemeMenu.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/components/OTPForm.tsx
apps/web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/web/**/*.{ts,tsx}: Web app uses Tanstack Router for client-side routing
Orama is used for client-side WASM search engine with multi-language support (Arabic + English), indexed from local database on app initialization

Files:

  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/ThemeMenu.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/components/OTPForm.tsx
apps/{web,mobile}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Lingui (v5) for internationalization in both web and mobile applications

Files:

  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/components/LanguageMenu.tsx
  • apps/web/src/components/ThemeMenu.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx
  • apps/web/src/components/OTPForm.tsx
🧠 Learnings (6)
📚 Learning: 2025-12-28T19:33:44.247Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T19:33:44.247Z
Learning: Applies to apps/mobile/**/*.{ts,tsx} : Mobile app uses UniWind (Tailwind for React Native) with Tailwind CSS v4

Applied to files:

  • apps/web/src/components/MobileHeader.tsx
  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/components/LanguageMenu.tsx
  • packages/design-system/globals.css
  • apps/web/src/components/OTPForm.tsx
📚 Learning: 2025-12-28T19:33:44.247Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T19:33:44.247Z
Learning: Applies to apps/mobile/**/*.{ts,tsx} : Mobile app uses Expo with file-based routing (Expo Router)

Applied to files:

  • apps/web/src/components/MobileHeader.tsx
📚 Learning: 2025-12-28T19:33:44.247Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T19:33:44.247Z
Learning: Applies to apps/web/**/*.{tsx,jsx} : Web app uses Shadcn/UI components and Tailwind CSS v4 for styling, use the `cn()` utility function for combining and conditionally applying Tailwind classes

Applied to files:

  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/components/LanguageMenu.tsx
  • packages/design-system/globals.css
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
  • apps/web/README.md
📚 Learning: 2025-11-27T06:02:25.941Z
Learnt from: Shunseii
Repo: Shunseii/bahar PR: 24
File: apps/web/src/components/features/decks/DeckDialogContent.tsx:195-201
Timestamp: 2025-11-27T06:02:25.941Z
Learning: In apps/web/src/components/features/decks/DeckDialogContent.tsx, the backend API calls (trpc.decks.create and trpc.decks.update) are temporary and planned to be removed after migration is complete.

Applied to files:

  • apps/web/src/components/search/InfiniteScroll.tsx
  • apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx
📚 Learning: 2025-12-28T19:33:44.247Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T19:33:44.247Z
Learning: Applies to apps/{web,mobile}/**/*.{ts,tsx} : Use Lingui (v5) for internationalization in both web and mobile applications

Applied to files:

  • apps/web/src/components/LanguageMenu.tsx
  • packages/i18n/locales/en.po
📚 Learning: 2025-12-28T19:33:44.247Z
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T19:33:44.247Z
Learning: Applies to **/*.{tsx,jsx} : Prefer using jotai atoms over React Context

Applied to files:

  • apps/web/src/components/ThemeMenu.tsx
🧬 Code graph analysis (4)
apps/web/src/components/LanguageMenu.tsx (1)
packages/web-ui/src/components/select.tsx (1)
  • SelectTrigger (155-155)
apps/web/src/components/ThemeMenu.tsx (3)
packages/web-ui/src/components/select.tsx (6)
  • SelectTrigger (155-155)
  • Select (152-152)
  • SelectValue (154-154)
  • SelectContent (156-156)
  • SelectGroup (153-153)
  • SelectItem (158-158)
apps/web/src/atoms/theme.ts (2)
  • colorThemeAtom (61-80)
  • getAllColorThemes (51-51)
apps/web/src/hooks/useDir.ts (1)
  • useDir (4-10)
apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx (1)
packages/web-ui/src/components/card.tsx (1)
  • Card (79-79)
apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx (1)
apps/web/src/components/ThemeMenu.tsx (1)
  • ColorThemeMenu (98-129)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (17)
apps/web/src/components/MobileHeader.tsx (1)

65-65: LGTM! Theme token updates are consistent.

The changes correctly update the styling to use sidebar-specific design tokens (border-sidebar-border and bg-sidebar) instead of generic tokens. This ensures visual consistency between the mobile header and drawer navigation, aligning with the PR's color theme implementation.

Also applies to: 103-103

apps/web/src/components/OTPForm.tsx (2)

57-63: LGTM! Caret color now uses semantic token.

The change from bg-white to bg-foreground aligns the caret color with the new theming system, making it adaptable across different color themes.


132-135: LGTM! Text color now uses semantic token.

Removing dark:text-slate-50 and relying on text-foreground ensures the heading text adapts automatically to the selected color theme without explicit dark mode overrides.

packages/design-system/globals.css (1)

1-4: LGTM! Theme import added in correct order.

The themes.css import is placed after colors.css, allowing theme-specific color tokens to properly extend or override base color definitions.

apps/web/src/components/LanguageMenu.tsx (1)

30-39: LGTM! Consistent theming approach.

Removing dark:text-slate-50 from the SelectTrigger aligns with the broader theming refactor, allowing the component to inherit theme-appropriate colors automatically.

packages/i18n/locales/en.po (1)

194-196: LGTM! Translation entries for new theme features.

The added translation keys for color themes ("Nord", "Default", "Tokyo Night") and flashcard grading options ("Again", "Easy", "Good", "Hard") properly support the new theming and flashcard features. Line reference updates reflect source file reorganization.

Also applies to: 514-516, 615-617, 868-870, 881-883, 1145-1147, 1701-1703

apps/web/src/routes/_authorized-layout/_search-layout/index.lazy.tsx (1)

59-59: Verify intentional border styling change.

The border-0 class was removed from the Card component, which means it will now display with the default border. This could be an intentional design change to align with the new theming system, but please confirm this visual change is desired.

If intentional, this change aligns with design system standardization and allows theme-defined borders to be visible.

apps/web/src/routes/_authorized-layout/_app-layout/settings/route.lazy.tsx (2)

33-33: LGTM! ColorThemeMenu import added cleanly.

The import addition is clean and follows the existing pattern for importing UI components from the ThemeMenu module.


206-210: LGTM! ColorThemeMenu integrated appropriately.

The ColorThemeMenu component is rendered in the logical location within the Appearance section, placed between ThemeMenu (light/dark mode) and LanguageMenu, providing a good user experience flow.

apps/web/README.md (1)

80-123: Excellent documentation for the color theme system!

The "Adding Color Themes" section provides clear, step-by-step guidance with code examples that align with the actual implementation. This will be valuable for future contributors and maintainers.

apps/web/src/components/ThemeMenu.tsx (3)

11-20: LGTM!

The new imports for Palette icon and color theme utilities are properly added and follow the existing import patterns.


63-63: Verify the removal of dark mode text color class.

The dark:text-slate-50 class was removed from the SelectTrigger. This affects the existing ThemeMenu component's appearance in dark mode. Please confirm this styling change is intentional and doesn't negatively impact visibility or contrast.


84-96: LGTM!

The ColorThemeLabel component follows the same pattern as ThemeLabel and properly handles all ColorTheme enum values with internationalization.

packages/web-ui/components.json (1)

14-18: Verify duplicate alias configuration.

The "ui" alias (line 15) and "components" alias (line 14) both point to "@bahar/web-ui/components". This duplication might be intentional for migration purposes, but could also lead to inconsistent usage across the codebase.

The consolidation of "lib" and "utils" to "@bahar/design-system" aligns well with the PR objectives.

If the duplicate aliases are temporary for migration, consider documenting this or adding a comment explaining the strategy.

packages/i18n/locales/ar.po (1)

514-516: LGTM!

The Arabic translations for the new color theme options are accurate and appropriate:

  • "Default" → "افتراضي" (correct)
  • "Nord" → "نورد" (appropriate transliteration for proper noun)
  • "Tokyo Night" → "ليلة طوكيو" (correct translation)

The anchor references correctly point to the new ColorThemeLabel component in ThemeMenu.tsx.

Also applies to: 1145-1147, 1701-1703

apps/web/src/components/search/InfiniteScroll.tsx (2)

411-411: Covered by previous comment.

This line uses the same bg-linear-to-b utility that should be verified in the previous comment.


342-344: Replace bg-linear-to-* with standard Tailwind gradient utilities bg-gradient-to-*.

The classes bg-linear-to-br, bg-linear-to-b, and bg-linear-to-r are not defined in your Tailwind configuration or design-system package and are not standard Tailwind v4 utilities. The codebase already uses the correct syntax bg-gradient-to-{direction} elsewhere. Update these to match the standard:

  • bg-linear-to-brbg-gradient-to-br
  • bg-linear-to-bbg-gradient-to-b
  • bg-linear-to-rbg-gradient-to-r

This applies to lines 342–344, 347–348, and similar usage elsewhere in the component.

⛔ Skipped due to learnings
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T19:33:44.247Z
Learning: Applies to apps/web/**/*.{tsx,jsx} : Web app uses Shadcn/UI components and Tailwind CSS v4 for styling, use the `cn()` utility function for combining and conditionally applying Tailwind classes
Learnt from: CR
Repo: Shunseii/bahar PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T19:33:44.247Z
Learning: Applies to apps/mobile/**/*.{ts,tsx} : Mobile app uses UniWind (Tailwind for React Native) with Tailwind CSS v4

@Shunseii Shunseii merged commit 959ca3c into main Dec 30, 2025
2 checks passed
@Shunseii Shunseii deleted the feat/color-themes branch December 30, 2025 18:08
@coderabbitai coderabbitai Bot mentioned this pull request Apr 2, 2026
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