Skip to content

Conversation

@wraith4081
Copy link
Contributor

Description:

migrate tailwindcss v3 to v4

Please complete the following:

  • I have added screenshots for all UI updates
  • I process any text displayed to the user through translateText() and I've added it to the en.json file
  • I have added relevant tests to the test directory
  • I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced

Please put your Discord username so you can be contacted if a bug or regression is found:

wraith4081

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 29, 2025

Walkthrough

Widespread presentational refactor: Tailwind/Tailwind plugin and build config changes, removal of prior PostCSS/Tailwind config, TypeScript moduleResolution update, global styles replaced with a themed stylesheet, and many component-level class/token updates; index.html adds persisted dark-mode preload handling.

Changes

Cohort / File(s) Summary
Build & Config
package.json, postcss.config.js, tailwind.config.js, vite.config.ts, tsconfig.json
Add @tailwindcss/vite plugin and enable it in Vite; upgrade Tailwind dependency; remove PostCSS/Tailwind config exports; set TS moduleResolution"bundler".
HTML Init
index.html
Add IIFE to read persisted settings.darkMode from localStorage (try/catch), apply preload class on load, and remove it after load.
Global Styles
src/client/styles.css
Replace Tailwind directives with @import "tailwindcss" integration, add @theme CSS variables, base layer, scrollbar and UI primitives, and many new global utility classes.
Modal & Inputs
src/client/AccountModal.ts, src/client/FlagInputModal.ts, src/client/StatsModal.ts, src/client/TerritoryPatternsModal.ts, src/client/UsernameInput.ts
Systematic class updates: space-x-*gap-*, shadow-smshadow-xs, focus:outline-nonefocus:outline-hidden, roundedrounded-sm, spacing token replacements (e.g., p-[1rem]p-4).
Core UI / Buttons
src/client/Matchmaking.ts, src/client/PublicLobby.ts, src/client/components/ui/ActionButton.ts
Focus, shadow and minor spacing/radius token adjustments; no logic changes.
Graphics Layers
src/client/graphics/layers/* (e.g., ChatDisplay.ts, ControlPanel.ts, EventsDisplay.ts, PlayerPanel.ts, UnitDisplay.ts, WinModal.ts, SettingsModal.ts, ReplayPanel.ts, SpawnTimer.ts, PlayerInfoOverlay.ts, EmojiTable.ts)
Large presentational refactor: normalize z-index/spacing tokens (z-[9999]z-9999, right-[10px]right-2.5), blur and radius adjustments (backdrop-blur-smbackdrop-blur-xs, roundedrounded-sm/rounded-xs), flex-shrink-0shrink-0, bg opacity token updates (bg-opacity-*bg-.../*), and CSS-variable-driven widths/positions.
Component Library
src/client/components/* (e.g., LobbyTeamView.ts, PatternButton.ts, baseComponents/*, baseComponents/ranking/PlayerRow.ts)
Tailwind token normalization, sizing token changes, color/border moved to CSS variables for some headers, and minor grid/layout syntax tweaks.
Modals / Misc UI
src/client/GameInfoModal.ts, src/client/HelpModal.ts, src/client/LanguageModal.ts, src/client/NewsModal.ts, src/client/DarkModeButton.ts, src/client/SendResourceModal.ts
Width/spacing token updates, z-index numeric tokens, padding/size token changes, shadow and radius refinements; some inline styles replaced by class-based CSS variable usage.
Minor Imports & Selectors
src/client/components/ModalOverlay.ts, src/client/FlagInput.ts, src/client/GoogleAdElement.ts
Import path tweak (lit/decoratorslit/decorators.js), changed DOM id/attributes in FlagInput.ts (may break existing selector #flag-preview), and minor class-based display change in GoogleAdElement.
Utilities & Renderers
src/client/utilities/RenderUnitTypeOptions.ts, src/client/graphics/.../MultiTabModal.ts, PerformanceOverlay.ts, TeamStats.ts, SpawnTimer.ts
Move inline widths/positions to CSS variables and class-based w-(--width)/left-(--left); replace several inline styles with utility classes and CSS variables for dynamic sizing.

Sequence Diagram(s)

(omitted — changes are primarily presentational and build/config updates, not new multi-component control flow)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

UI/UX, DevOps - CICD

Suggested reviewers

  • evanpelle
  • scottanderson
  • VariableVince

Poem

✨ Classes shift and pixels breathe anew,
Dark mode kept safe in storage too,
Corners slimmed and shadows toned,
Build tools joined to set the zone,
A quieter UI wakes in view.

Pre-merge checks

❌ 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
Title check ✅ Passed The title clearly and concisely summarizes the main change: migrating Tailwind CSS from v3 to v4. It is specific, descriptive, and matches the changeset scope.
Description check ✅ Passed The description is directly related to the changeset, specifying the purpose of migrating Tailwind CSS v3 to v4 and confirming completion of all required checks.

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.

Copy link
Contributor

@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 (3)
src/client/components/baseComponents/ranking/PlayerRow.ts (1)

30-32: Tailwind v4 opacity syntax looks correct.

The slash notation (border-yellow-50/0) matches Tailwind v4 requirements. The border logic is working as intended: winners get bold yellow borders, current players get faint borders, others get transparent borders.

Minor note: border-yellow-50 is very light and might be barely visible for the current player. Consider using a darker shade like border-yellow-200 or border-yellow-300 if you want the current player border to be more noticeable.

Optional: Make current player border more visible
          ${player.winner
          ? "border-yellow-500"
-          : visibleBorder
-            ? "border-yellow-50"
-            : "border-yellow-50/0"}
+          : visibleBorder
+            ? "border-yellow-300"
+            : "border-yellow-50/0"}
src/client/graphics/layers/EmojiTable.ts (1)

83-83: Use shadow-xs for consistency with other components.

The close button uses shadow-sm, but other components in this PR (ActionButton.ts, FlagInputModal.ts, GameRightSidebar.ts) use shadow-xs for similar shadow styling. For visual consistency across the UI, consider using shadow-xs here.

🔎 Proposed fix
-                   bg-zinc-700 hover:bg-red-500 text-white rounded-full shadow-sm transition-colors z-[10004]"
+                   bg-zinc-700 hover:bg-red-500 text-white rounded-full shadow-xs transition-colors z-[10004]"
src/client/styles.css (1)

34-38: Remove outdated vendor prefixes.

The -webkit-box-sizing and -moz-box-sizing prefixes are no longer needed. All modern browsers (and Tailwind v4's browser target: Chrome 111+, Safari 16.4+, Firefox 128+) support unprefixed box-sizing.

Suggested fix
 * {
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
   box-sizing: border-box;
 }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b569e68 and bad82fc.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (33)
  • index.html
  • package.json
  • postcss.config.js
  • src/client/AccountModal.ts
  • src/client/FlagInputModal.ts
  • src/client/Matchmaking.ts
  • src/client/PublicLobby.ts
  • src/client/StatsModal.ts
  • src/client/TerritoryPatternsModal.ts
  • src/client/UsernameInput.ts
  • src/client/components/LobbyTeamView.ts
  • src/client/components/PatternButton.ts
  • src/client/components/baseComponents/ranking/PlayerRow.ts
  • src/client/components/baseComponents/setting/SettingKeybind.ts
  • src/client/components/baseComponents/stats/PlayerStatsTree.ts
  • src/client/components/ui/ActionButton.ts
  • src/client/graphics/layers/ChatDisplay.ts
  • src/client/graphics/layers/ControlPanel.ts
  • src/client/graphics/layers/EmojiTable.ts
  • src/client/graphics/layers/EventsDisplay.ts
  • src/client/graphics/layers/GameLeftSidebar.ts
  • src/client/graphics/layers/GameRightSidebar.ts
  • src/client/graphics/layers/HeadsUpMessage.ts
  • src/client/graphics/layers/PlayerInfoOverlay.ts
  • src/client/graphics/layers/PlayerPanel.ts
  • src/client/graphics/layers/ReplayPanel.ts
  • src/client/graphics/layers/SendResourceModal.ts
  • src/client/graphics/layers/SettingsModal.ts
  • src/client/graphics/layers/UnitDisplay.ts
  • src/client/graphics/layers/WinModal.ts
  • src/client/styles.css
  • tailwind.config.js
  • vite.config.ts
💤 Files with no reviewable changes (2)
  • postcss.config.js
  • tailwind.config.js
🧰 Additional context used
🧠 Learnings (9)
📚 Learning: 2025-06-09T02:20:43.637Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 1110
File: src/client/Main.ts:293-295
Timestamp: 2025-06-09T02:20:43.637Z
Learning: In src/client/Main.ts, during game start in the handleJoinLobby callback, UI elements are hidden using direct DOM manipulation with classList.add("hidden") for consistency. This includes modals, buttons, and error divs. The codebase follows this pattern rather than using component APIs for hiding elements during game transitions.

Applied to files:

  • src/client/components/LobbyTeamView.ts
  • src/client/graphics/layers/ReplayPanel.ts
  • src/client/AccountModal.ts
  • src/client/Matchmaking.ts
  • src/client/graphics/layers/ChatDisplay.ts
  • src/client/TerritoryPatternsModal.ts
  • src/client/graphics/layers/WinModal.ts
  • src/client/styles.css
  • src/client/graphics/layers/GameLeftSidebar.ts
  • src/client/graphics/layers/PlayerInfoOverlay.ts
  • src/client/PublicLobby.ts
  • src/client/graphics/layers/GameRightSidebar.ts
  • src/client/components/baseComponents/ranking/PlayerRow.ts
  • src/client/graphics/layers/EventsDisplay.ts
  • src/client/graphics/layers/PlayerPanel.ts
  • index.html
📚 Learning: 2025-10-26T15:37:07.732Z
Learnt from: GlacialDrift
Repo: openfrontio/OpenFrontIO PR: 2298
File: src/client/graphics/layers/TerritoryLayer.ts:200-210
Timestamp: 2025-10-26T15:37:07.732Z
Learning: In GameImpl.ts lines 124-139, team assignment logic varies by number of teams: when numPlayerTeams < 8, teams are assigned ColoredTeams values (Red, Blue, Yellow, Green, Purple, Orange, Teal); when numPlayerTeams >= 8, teams are assigned generic string identifiers like "Team 1", "Team 2", etc., which are not members of ColoredTeams.

Applied to files:

  • src/client/components/LobbyTeamView.ts
📚 Learning: 2025-06-10T09:56:44.473Z
Learnt from: Ble4Ch
Repo: openfrontio/OpenFrontIO PR: 1063
File: src/core/configuration/PastelThemeDark.ts:53-53
Timestamp: 2025-06-10T09:56:44.473Z
Learning: In ColorAllocator class in src/core/configuration/Colors.ts, the correct method names are assignColor(id: string): Colord for general color assignment and assignTeamColor(team: Team): Colord for team-specific colors. There are no assignPlayerColor() or assignBotColor() methods.

Applied to files:

  • src/client/components/LobbyTeamView.ts
  • src/client/components/baseComponents/ranking/PlayerRow.ts
📚 Learning: 2025-06-22T05:48:19.241Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 786
File: src/client/TerritoryPatternsModal.ts:337-338
Timestamp: 2025-06-22T05:48:19.241Z
Learning: In src/client/TerritoryPatternsModal.ts, the bit shifting operators (<<) used in coordinate calculations with decoder.getScale() are intentional and should not be changed to multiplication. The user scottanderson confirmed this is functioning as intended.

Applied to files:

  • src/client/TerritoryPatternsModal.ts
📚 Learning: 2025-05-19T06:00:38.007Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 784
File: src/core/game/StatsImpl.ts:125-134
Timestamp: 2025-05-19T06:00:38.007Z
Learning: In StatsImpl.ts, unused parameters in boat/stats-related methods are intentionally kept for future use and shouldn't be removed.

Applied to files:

  • src/client/components/baseComponents/stats/PlayerStatsTree.ts
📚 Learning: 2025-06-07T19:47:34.514Z
Learnt from: its-sii
Repo: openfrontio/OpenFrontIO PR: 1089
File: src/client/styles/components/setting.css:9-22
Timestamp: 2025-06-07T19:47:34.514Z
Learning: In src/client/styles/components/setting.css, the padding difference between .setting-item and .setting-item-group is intentional - .setting-item-group doesn't need padding for the specific grouped setting styling being implemented.

Applied to files:

  • src/client/components/baseComponents/setting/SettingKeybind.ts
📚 Learning: 2025-06-07T19:47:34.514Z
Learnt from: its-sii
Repo: openfrontio/OpenFrontIO PR: 1089
File: src/client/styles/components/setting.css:9-22
Timestamp: 2025-06-07T19:47:34.514Z
Learning: This project uses plain CSS, not Sass/SCSS, so CSS features like extend are not available.

Applied to files:

  • src/client/styles.css
📚 Learning: 2025-12-13T14:58:29.645Z
Learnt from: scamiv
Repo: openfrontio/OpenFrontIO PR: 2607
File: src/core/execution/PlayerExecution.ts:271-295
Timestamp: 2025-12-13T14:58:29.645Z
Learning: In src/core/execution/PlayerExecution.ts surroundedBySamePlayer(), the `as Player` cast on `mg.playerBySmallID(scan.enemyId)` is intentional. Since scan.enemyId comes from ownerID() on an owned tile and playerBySmallID() only returns Player or undefined, the cast expresses a known invariant. The maintainers prefer loud failures (runtime errors) over silent masking (early returns with guards) for corrupted game state scenarios at trusted call sites.

Applied to files:

  • src/client/components/baseComponents/ranking/PlayerRow.ts
📚 Learning: 2025-08-12T00:31:50.144Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 1752
File: src/core/game/Game.ts:750-752
Timestamp: 2025-08-12T00:31:50.144Z
Learning: In the OpenFrontIO codebase, changes to the PlayerInteraction interface (like adding canDonateGold and canDonateTroops flags) do not require corresponding updates to src/core/Schemas.ts or server serialization code.

Applied to files:

  • src/client/components/baseComponents/ranking/PlayerRow.ts
  • src/client/graphics/layers/PlayerPanel.ts
🧬 Code graph analysis (2)
src/client/graphics/layers/ReplayPanel.ts (1)
src/core/configuration/PastelTheme.ts (1)
  • backgroundColor (188-190)
src/client/graphics/layers/WinModal.ts (2)
src/client/LangSelector.ts (1)
  • translateText (258-278)
src/client/Utils.ts (1)
  • translateText (92-147)
🔇 Additional comments (43)
src/client/components/PatternButton.ts (2)

101-101: Tailwind v4 migration looks good here.

The border radius update from rounded to rounded-sm is correct for the v4 migration. The pattern preview container now uses a smaller border radius, which is a sensible visual adjustment for this use case. All other Tailwind classes in the file already use v4 syntax correctly (slash opacity syntax, no deprecated utilities).


68-132: Well-structured component logic with proper v4 class usage.

The render method is clean and maintainable. Type safety with the satisfies operator, proper event handlers, and good separation of concerns with the helper functions keep this readable. No changes needed here—the migration preserved the code quality.

src/client/graphics/layers/HeadsUpMessage.ts (1)

63-63: Correct Tailwind v4 migration—opacity syntax updated.

The change from bg-opacity-60 bg-gray-900 to bg-gray-900/60 correctly follows Tailwind v4's breaking change where opacity utilities were removed in favor of the slash syntax. The visual result should be identical.

Please verify the heads-up message banner displays correctly with the semi-transparent background in both light and dark modes.

Based on library documentation: Tailwind v4 removed bg-opacity-* utilities; slash syntax is now required.

src/client/graphics/layers/PlayerPanel.ts (3)

488-488: Tailwind v4 migration applied correctly.

The flex-shrink-0shrink-0 rename follows Tailwind v4's streamlined utility naming.

Also applies to: 501-501


518-518: Critical fix: Grid syntax corrected.

The comma→underscore change fixes invalid CSS. In Tailwind arbitrary values, underscores represent spaces in the generated CSS:

  • Old: grid-cols-[auto,1fr]grid-template-columns: auto, 1fr ❌ (invalid CSS)
  • New: grid-cols-[auto_1fr]grid-template-columns: auto 1fr ✓ (valid CSS)

This is a correctness improvement beyond the v4 migration.

Also applies to: 531-531, 615-615


851-851: Subtle shadow refinement.

The shadowshadow-sm change creates a lighter, more refined appearance for the close button.

src/client/components/baseComponents/ranking/PlayerRow.ts (4)

89-89: LGTM! Correct Tailwind v4 border migration.

The explicit border border-gray-200 is necessary because Tailwind v4 changed the default border color from gray to currentColor. This preserves the intended gray border styling.


193-193: LGTM! Explicit border for v4 compatibility.

Adding border border-gray-200 maintains the gray border styling after the Tailwind v4 default border color change.


203-203: LGTM! Responsive border styling is correct.

The sm:border sm:border-gray-200 correctly adds a gray border on small screens and up, matching the responsive design pattern for the killed player icon.


216-216: LGTM! Consistent border styling.

The explicit border border-gray-200 maintains the gray border appearance and ensures consistency across all player icon variants (flag, killed, profile).

src/client/TerritoryPatternsModal.ts (1)

270-270: LGTM!

The border radius update from rounded to rounded-sm correctly follows the Tailwind v4 migration pattern.

src/client/components/ui/ActionButton.ts (1)

28-31: LGTM!

The changes correctly implement Tailwind v4 conventions:

  • shadow-xs replaces the previous shadow utility with the updated scale
  • focus-visible:outline-hidden replaces outline-none per v4 requirements (outline-none now only removes the outline style, while outline-hidden removes it completely)
src/client/PublicLobby.ts (1)

190-190: LGTM!

The border radius update from rounded-sm to rounded-xs correctly follows Tailwind v4's adjusted scale.

src/client/FlagInputModal.ts (1)

26-26: LGTM!

The styling updates correctly apply Tailwind v4 conventions with shadow-xs and focus:outline-hidden.

vite.config.ts (1)

1-1: LGTM!

The Tailwind CSS v4 integration via the Vite plugin is correctly configured. This replaces the PostCSS-based setup from v3 with the more efficient Oxide engine.

Also applies to: 71-71

src/client/graphics/layers/GameRightSidebar.ts (1)

142-142: LGTM!

The backdrop blur update from backdrop-blur-sm to backdrop-blur-xs aligns with Tailwind v4's updated blur scale.

src/client/components/baseComponents/setting/SettingKeybind.ts (1)

47-47: LGTM!

Both buttons correctly update from rounded to rounded-sm following the Tailwind v4 migration pattern.

Also applies to: 53-53

src/client/Matchmaking.ts (1)

176-176: LGTM! Correct Tailwind v4 migration.

The focus:outline-hidden class correctly replaces the v3 focus:outline-none to fully remove the outline in Tailwind v4.

src/client/graphics/layers/ReplayPanel.ts (1)

69-69: LGTM! Consistent visual refinements.

The styling updates (backdrop-blur-xs, shadow-xs, rounded-sm) tighten the visual design consistently with the Tailwind v4 migration across the codebase.

Also applies to: 96-96

src/client/graphics/layers/PlayerInfoOverlay.ts (1)

482-482: LGTM! Visual styling aligned with migration.

The backdrop blur adjustment matches the consistent visual refinements applied throughout the Tailwind v4 migration.

src/client/graphics/layers/ControlPanel.ts (1)

164-164: LGTM! Consistent control panel styling updates.

The panel container, inner blocks, and slider track elements all receive consistent visual refinements (backdrop-blur-sm, rounded-sm) without affecting control behavior.

Also applies to: 169-169, 213-217

src/client/components/baseComponents/stats/PlayerStatsTree.ts (1)

125-128: LGTM! Uniform button styling across selectors.

All three selector button groups (type, mode, difficulty) receive consistent rounded-sm styling, maintaining visual harmony.

Also applies to: 146-149, 165-168

src/client/components/LobbyTeamView.ts (1)

86-86: LGTM! Consistent team view styling.

Both participant list items and team member rows receive uniform rounded-sm styling updates.

Also applies to: 183-183

src/client/StatsModal.ts (1)

94-94: LGTM! Correct Tailwind v4 updates.

The retry button styling (rounded-sm) and focus outline handling (focus:outline-hidden) are correctly updated for Tailwind v4.

Also applies to: 222-222

src/client/graphics/layers/UnitDisplay.ts (1)

135-135: LGTM! Comprehensive unit display styling updates.

All container elements, tooltips, and unit items receive consistent visual refinements (backdrop-blur-xs, rounded-sm) aligned with the Tailwind v4 migration.

Also applies to: 181-181, 245-245, 267-269

src/client/graphics/layers/ChatDisplay.ts (1)

130-130: LGTM! Tailwind v4 migration looks correct.

The opacity syntax updates (bg-black/60, border-gray-200/0) and radius adjustments (rounded-xs) follow the correct Tailwind v4 patterns. These are purely visual changes with no functional impact.

Also applies to: 156-156, 171-171

src/client/UsernameInput.ts (1)

43-43: LGTM! Correct Tailwind v4 syntax.

The updates to shadow-xs, focus:outline-hidden, and rounded-sm are proper v4 migrations. Note that outline-hidden fully removes the outline (Tailwind v4 behavior), whereas the old outline-none only removed the outline style.

Also applies to: 48-48

src/client/graphics/layers/GameLeftSidebar.ts (1)

90-90: LGTM! Proper Tailwind v4 updates.

The backdrop blur intensity reduction (backdrop-blur-xs) and the shift from space-x-2 to gap-2 are correct v4 patterns. Gap-based layouts provide better control and are the preferred approach in Tailwind v4.

Also applies to: 108-108

src/client/graphics/layers/WinModal.ts (1)

59-59: LGTM! Consistent Tailwind v4 styling updates.

The backdrop blur reduction and consistent application of rounded-sm across all modal elements create a cohesive visual update. All changes follow correct v4 syntax patterns.

Also applies to: 73-79, 126-148, 218-243

src/client/graphics/layers/SettingsModal.ts (1)

192-192: LGTM! Comprehensive Tailwind v4 modal update.

The migration to gap-based layouts (flex flex-col gap-3) and consistent rounded-sm application across all interactive elements demonstrates a thorough v4 update. The backdrop blur reduction is also correct.

Also applies to: 221-221, 223-498

package.json (1)

85-85: Verify browser compatibility requirements for Tailwind v4.

Tailwind CSS v4 requires modern browsers (Chrome 111+, Safari 16.4+, Firefox 128+) and uses modern CSS features like @property, cascade layers, color-mix(), and native nesting. Ensure your target audience supports these browsers.

Based on Tailwind v4 documentation, verify that:

  1. Your user analytics confirm browser support aligns with these requirements
  2. The Vite plugin is properly configured in vite.config.ts
  3. PostCSS configuration was intentionally removed (correct for v4)

Also applies to: 106-106

src/client/AccountModal.ts (1)

160-160: LGTM! Consistent Tailwind v4 focus and spacing updates.

The migration from focus:outline-none to focus:outline-hidden, shadow-sm to shadow-xs, and space utilities to gap-based layouts are all correct v4 patterns. The changes are consistent across all interactive elements in the modal.

Also applies to: 175-175, 212-219, 222-228, 236-236, 382-382

src/client/graphics/layers/SendResourceModal.ts (1)

258-258: LGTM! Thorough Tailwind v4 migration.

The modal demonstrates consistent application of v4 patterns: focus:outline-hidden for full outline removal, rounded-sm for tighter radii, and shadow-sm where appropriate. All syntax is correct.

Also applies to: 364-381, 390-400, 454-463, 556-556

src/client/styles.css (2)

1-8: Tailwind v4 setup looks correct.

The @import "tailwindcss"; syntax and @theme block for ring defaults align with v4 conventions. Setting --default-ring-width: 3px restores the v3 default ring behavior.


10-32: Base layer resets are reasonable for v4 migration.

These resets help preserve v3-like defaults for border colors, placeholder colors, button cursors, and dialog centering. Good approach to minimize visual regressions.

src/client/graphics/layers/EventsDisplay.ts (4)

857-864: Class updates align with Tailwind v4.

The change from flex-shrink-0 to shrink-0 is correct. In Tailwind v4, flex-grow-* and flex-shrink-* were renamed to grow-* and shrink-*.


819-821: Button styling updated correctly.

The rounded-sm class is applied consistently across action buttons as part of the UI refresh.


1029-1036: Backdrop blur levels look good.

Using backdrop-blur-sm for the events toggle and main container provides consistent blur across the UI.


1126-1127: Event action buttons styled consistently.

The rounded-sm class matches other button styles in this component.

index.html (4)

125-141: Dark mode persistence prevents flickering.

The IIFE runs before render, reading settings.darkMode from localStorage and applying the dark class early. The try/catch handles storage access errors gracefully. This is a good fix for the dark mode flickering issue.


201-202: Opacity syntax updated correctly.

Using bg-black/0 instead of the old bg-opacity-0 pattern is the correct Tailwind v4 approach.


396-397: Shrink utility updated correctly.

The change from flex-shrink-0 to shrink-0 follows Tailwind v4 naming conventions.


490-499: Language modal updates look correct.

  • bg-black/50 uses correct v4 opacity syntax.
  • flex flex-col gap-2 replaces space-y-2 appropriately.
  • rounded-sm is consistent with button styling elsewhere.

@iiamlewis iiamlewis added the Devops Infrastructure, CI/CD, dependencies, and maintenance. label Dec 29, 2025
@github-project-automation github-project-automation bot moved this from Triage to Development in OpenFront Release Management Dec 29, 2025
@iiamlewis iiamlewis added this to the v29 milestone Dec 29, 2025
Copy link
Contributor

@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: 2

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bad82fc and 9168aca.

📒 Files selected for processing (2)
  • tests/NationNameLength.test.ts
  • tsconfig.json
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-07T13:15:55.439Z
Learnt from: Aotumuri
Repo: openfrontio/OpenFrontIO PR: 786
File: src/core/Util.ts:4-4
Timestamp: 2025-06-07T13:15:55.439Z
Learning: In the OpenFrontIO codebase, JSON files should be imported using standard import syntax without import attributes, as the TypeScript configuration supports resolveJsonModule and the codebase already uses this pattern successfully in files like src/client/Cosmetic.ts.

Applied to files:

  • tests/NationNameLength.test.ts
🪛 GitHub Actions: 🧪 CI
tests/NationNameLength.test.ts

[error] 13-13: TypeError: globSync is not a function

🔇 Additional comments (1)
tsconfig.json (1)

9-9: Good fit for Vite-based builds.

The bundler module resolution strategy aligns well with Vite and modern bundler workflows. This is the recommended approach for projects using build tools like Vite. Existing imports throughout the codebase already follow compatible patterns with proper file extensions.

Copy link
Contributor

@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

Caution

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

⚠️ Outside diff range comments (1)
package.json (1)

60-60: Remove redundant autoprefixer package.

Tailwind CSS v4 includes Lightning CSS, which handles vendor prefixes automatically. The autoprefixer package is no longer needed.

🔎 Proposed fix
-    "autoprefixer": "^10.4.20",

Based on library documentation: Tailwind v4's built-in Lightning CSS handles vendor prefixes without requiring separate PostCSS plugins.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9168aca and b266fb7.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (1)
  • package.json
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: wraith4081
Repo: openfrontio/OpenFrontIO PR: 2735
File: index.html:390-391
Timestamp: 2025-12-29T23:33:17.920Z
Learning: In Tailwind CSS v4, blur utilities were renamed: `backdrop-blur-sm` from v3 is now `backdrop-blur-xs` in v4, and `backdrop-blur` (bare) becomes `backdrop-blur-sm`. Similarly, other blur utilities like `blur-sm` are renamed to `blur-xs`.
🔇 Additional comments (2)
package.json (2)

70-70: glob 13.0.0 is valid.

The version is the latest release on npm and correctly placed in devDependencies for testing utilities.


86-86: Tailwind v4 migration is complete.

The codebase has already been updated correctly for Tailwind v4. All blur utilities use the new syntax (backdrop-blur-xs), opacity utilities use slash notation (bg-gray-800/70), and CSS variables use parentheses syntax. No old v3 patterns remain.

Copy link
Contributor

@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: 3

♻️ Duplicate comments (1)
index.html (1)

390-390: LGTM!

The backdrop-blur-xs is correct for Tailwind v4. Based on learnings, backdrop-blur-sm from v3 was renamed to backdrop-blur-xs in v4.

🧹 Nitpick comments (2)
src/client/NewsModal.ts (1)

162-162: Simplify arbitrary rgba value to use standard color tokens.

The dark:bg-[rgba(55,65,81,0.7)] can be replaced with dark:bg-gray-700/70, which uses Tailwind's standard color palette with opacity notation. This improves consistency and maintainability.

🔎 Proposed refactor
-          class="border p-1 rounded-lg flex cursor-pointer border-black/30 dark:border-gray-300/60 bg-white/70 dark:bg-[rgba(55,65,81,0.7)]"
+          class="border p-1 rounded-lg flex cursor-pointer border-black/30 dark:border-gray-300/60 bg-white/70 dark:bg-gray-700/70"
src/client/graphics/layers/UnitDisplay.ts (1)

267-269: Remove duplicate rounded-sm class.

The rounded-sm utility appears twice on the same element (lines 267 and 269). While browsers ignore duplicate classes, one instance should be removed for cleaner code.

🔎 Suggested cleanup
          class="${this.canBuild(unitType)
            ? ""
-            : "opacity-40"} border border-slate-500 rounded-sm pr-2 pb-1 flex items-center gap-2 cursor-pointer
+            : "opacity-40"} border border-slate-500 pr-2 pb-1 flex items-center gap-2 cursor-pointer
             ${selected ? "hover:bg-gray-400/10" : "hover:bg-gray-800"}
             rounded-sm text-white ${selected ? "bg-slate-400/20" : ""}"
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0f33042 and 154b21c.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (26)
  • index.html
  • package.json
  • src/client/AccountModal.ts
  • src/client/DarkModeButton.ts
  • src/client/FlagInputModal.ts
  • src/client/GameInfoModal.ts
  • src/client/HelpModal.ts
  • src/client/LanguageModal.ts
  • src/client/Matchmaking.ts
  • src/client/NewsModal.ts
  • src/client/StatsModal.ts
  • src/client/components/PatternButton.ts
  • src/client/components/baseComponents/ranking/PlayerRow.ts
  • src/client/components/baseComponents/ranking/RankingHeader.ts
  • src/client/components/baseComponents/setting/SettingKeybind.ts
  • src/client/graphics/layers/ChatDisplay.ts
  • src/client/graphics/layers/EmojiTable.ts
  • src/client/graphics/layers/GameLeftSidebar.ts
  • src/client/graphics/layers/HeadsUpMessage.ts
  • src/client/graphics/layers/PlayerInfoOverlay.ts
  • src/client/graphics/layers/PlayerPanel.ts
  • src/client/graphics/layers/SendResourceModal.ts
  • src/client/graphics/layers/SettingsModal.ts
  • src/client/graphics/layers/SpawnTimer.ts
  • src/client/graphics/layers/UnitDisplay.ts
  • src/client/graphics/layers/WinModal.ts
🚧 Files skipped from review as they are similar to previous changes (9)
  • src/client/Matchmaking.ts
  • src/client/components/PatternButton.ts
  • src/client/graphics/layers/HeadsUpMessage.ts
  • src/client/AccountModal.ts
  • src/client/graphics/layers/GameLeftSidebar.ts
  • src/client/components/baseComponents/setting/SettingKeybind.ts
  • src/client/FlagInputModal.ts
  • src/client/graphics/layers/ChatDisplay.ts
  • package.json
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: wraith4081
Repo: openfrontio/OpenFrontIO PR: 2735
File: index.html:390-391
Timestamp: 2025-12-29T23:33:17.920Z
Learning: In Tailwind CSS v4, blur utilities were renamed: `backdrop-blur-sm` from v3 is now `backdrop-blur-xs` in v4, and `backdrop-blur` (bare) becomes `backdrop-blur-sm`. Similarly, other blur utilities like `blur-sm` are renamed to `blur-xs`.
📚 Learning: 2025-06-09T02:20:43.637Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 1110
File: src/client/Main.ts:293-295
Timestamp: 2025-06-09T02:20:43.637Z
Learning: In src/client/Main.ts, during game start in the handleJoinLobby callback, UI elements are hidden using direct DOM manipulation with classList.add("hidden") for consistency. This includes modals, buttons, and error divs. The codebase follows this pattern rather than using component APIs for hiding elements during game transitions.

Applied to files:

  • src/client/graphics/layers/PlayerInfoOverlay.ts
  • src/client/graphics/layers/WinModal.ts
  • src/client/graphics/layers/UnitDisplay.ts
  • src/client/graphics/layers/PlayerPanel.ts
  • src/client/GameInfoModal.ts
  • src/client/components/baseComponents/ranking/PlayerRow.ts
  • src/client/StatsModal.ts
  • index.html
📚 Learning: 2025-08-12T00:31:50.144Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 1752
File: src/core/game/Game.ts:750-752
Timestamp: 2025-08-12T00:31:50.144Z
Learning: In the OpenFrontIO codebase, changes to the PlayerInteraction interface (like adding canDonateGold and canDonateTroops flags) do not require corresponding updates to src/core/Schemas.ts or server serialization code.

Applied to files:

  • src/client/graphics/layers/PlayerInfoOverlay.ts
  • src/client/graphics/layers/PlayerPanel.ts
  • src/client/components/baseComponents/ranking/PlayerRow.ts
📚 Learning: 2025-06-10T09:56:44.473Z
Learnt from: Ble4Ch
Repo: openfrontio/OpenFrontIO PR: 1063
File: src/core/configuration/PastelThemeDark.ts:53-53
Timestamp: 2025-06-10T09:56:44.473Z
Learning: In ColorAllocator class in src/core/configuration/Colors.ts, the correct method names are assignColor(id: string): Colord for general color assignment and assignTeamColor(team: Team): Colord for team-specific colors. There are no assignPlayerColor() or assignBotColor() methods.

Applied to files:

  • src/client/graphics/layers/PlayerInfoOverlay.ts
📚 Learning: 2025-12-29T23:33:17.920Z
Learnt from: wraith4081
Repo: openfrontio/OpenFrontIO PR: 2735
File: index.html:390-391
Timestamp: 2025-12-29T23:33:17.920Z
Learning: In Tailwind CSS v4, blur utilities were renamed: `backdrop-blur-sm` from v3 is now `backdrop-blur-xs` in v4, and `backdrop-blur` (bare) becomes `backdrop-blur-sm`. Similarly, other blur utilities like `blur-sm` are renamed to `blur-xs`.

Applied to files:

  • src/client/graphics/layers/WinModal.ts
  • src/client/graphics/layers/UnitDisplay.ts
  • src/client/graphics/layers/SettingsModal.ts
📚 Learning: 2025-10-08T17:14:49.369Z
Learnt from: Foorack
Repo: openfrontio/OpenFrontIO PR: 2141
File: src/client/ClientGameRunner.ts:228-234
Timestamp: 2025-10-08T17:14:49.369Z
Learning: For the window close confirmation feature in `ClientGameRunner.ts`, the troop count requirement (>10,000 troops) from issue #2137 was intentionally removed because it was arbitrary and troop count can be reported as low despite having significant land. The confirmation now triggers for any alive player regardless of troop count.

Applied to files:

  • src/client/graphics/layers/PlayerPanel.ts
📚 Learning: 2025-10-20T20:15:28.858Z
Learnt from: sambokai
Repo: openfrontio/OpenFrontIO PR: 2225
File: src/core/execution/FakeHumanExecution.ts:51-51
Timestamp: 2025-10-20T20:15:28.858Z
Learning: In src/core/execution/FakeHumanExecution.ts, game balance constants like MIRV_COOLDOWN_TICKS, MIRV_HESITATION_ODDS, VICTORY_DENIAL_TEAM_THRESHOLD, VICTORY_DENIAL_INDIVIDUAL_THRESHOLD, and STEAMROLL_CITY_GAP_MULTIPLIER are experimental tuning parameters subject to frequent change during balance testing. Do not flag changes to these values as issues or compare them against previous values.

Applied to files:

  • src/client/graphics/layers/PlayerPanel.ts
📚 Learning: 2025-12-13T14:58:29.645Z
Learnt from: scamiv
Repo: openfrontio/OpenFrontIO PR: 2607
File: src/core/execution/PlayerExecution.ts:271-295
Timestamp: 2025-12-13T14:58:29.645Z
Learning: In src/core/execution/PlayerExecution.ts surroundedBySamePlayer(), the `as Player` cast on `mg.playerBySmallID(scan.enemyId)` is intentional. Since scan.enemyId comes from ownerID() on an owned tile and playerBySmallID() only returns Player or undefined, the cast expresses a known invariant. The maintainers prefer loud failures (runtime errors) over silent masking (early returns with guards) for corrupted game state scenarios at trusted call sites.

Applied to files:

  • src/client/components/baseComponents/ranking/PlayerRow.ts
📚 Learning: 2025-12-29T23:33:17.920Z
Learnt from: wraith4081
Repo: openfrontio/OpenFrontIO PR: 2735
File: index.html:390-391
Timestamp: 2025-12-29T23:33:17.920Z
Learning: In Tailwind CSS v4, update blur-related utilities in HTML templates. The mappings are: backdrop-blur-sm (v3) -> backdrop-blur-xs (v4); backdrop-blur (bare) -> backdrop-blur-sm; blur-sm -> blur-xs. Apply these changes to all HTML files (e.g., index.html and other templates) to reflect the v4 naming. Consider updating a project-wide search/replace or using a codemod to ensure consistency across the codebase.

Applied to files:

  • index.html
🧬 Code graph analysis (1)
src/client/graphics/layers/WinModal.ts (2)
src/client/LangSelector.ts (1)
  • translateText (258-278)
src/client/Utils.ts (1)
  • translateText (92-147)
🔇 Additional comments (56)
src/client/graphics/layers/PlayerInfoOverlay.ts (1)

478-478: LGTM: container positioning migrated correctly.

The top-37.5 and max-w-45 tokens are valid Tailwind v4 utilities and correctly replace the previous arbitrary values.

src/client/HelpModal.ts (1)

609-609: LGTM! Clean migration to numeric height tokens.

The conversion from min-h-[3rem] to min-h-12 aligns with Tailwind v4's preference for numeric tokens over arbitrary values. The change is consistent across all icon blocks.

Also applies to: 626-626, 643-643, 662-662, 679-679

src/client/graphics/layers/SpawnTimer.ts (1)

96-96: LGTM! Correct z-index migration for v4.

The change from z-[999] to z-999 follows Tailwind v4's numeric z-index token pattern.

src/client/NewsModal.ts (1)

166-166: LGTM! Clean utility usage.

The size-12 dark:invert utilities are properly formatted for Tailwind v4.

src/client/StatsModal.ts (1)

94-94: LGTM! Correct Tailwind v4 migrations.

All changes align with v4 guidelines:

  • rounded-sm reduces border radius consistently
  • z-[9998]z-9999 uses numeric z-index tokens
  • focus:outline-nonefocus:outline-hidden correctly applies complete outline removal per v4 spec

Also applies to: 219-219, 222-222

src/client/graphics/layers/EmojiTable.ts (1)

76-76: LGTM! Consistent v4 token migrations.

All styling updates are correct:

  • Z-index values migrated to numeric tokens (z-10002, z-10003, z-10004)
  • Width converted from arbitrary sm:w-[400px] to sm:w-100 (both equal 400px)
  • Shadow reduced to shadow-sm for visual consistency

Also applies to: 83-83, 90-91

src/client/LanguageModal.ts (1)

67-67: LGTM! Clean token migrations.

Both changes are correct for Tailwind v4:

  • Z-index migrated to numeric z-9999 token
  • Width utilities converted from arbitrary px values to numeric tokens (min-w-85, max-w-120)

Also applies to: 70-70

src/client/graphics/layers/SettingsModal.ts (2)

192-192: LGTM! Correct blur utility migration for v4.

Both changes are correct:

  • backdrop-blur-smbackdrop-blur-xs follows Tailwind v4's renamed blur utilities
  • z-[2000]z-2000 uses numeric z-index token

Based on learnings, Tailwind v4 renamed blur utilities where the old backdrop-blur-sm is now backdrop-blur-xs.


221-221: LGTM! Layout and radius updates are consistent.

Changes include:

  • space-y-3flex flex-col gap-3 provides equivalent spacing with modern flexbox
  • All roundedrounded-sm changes reduce border radius consistently across the modal

Also applies to: 223-223, 245-245, 272-272, 292-292, 312-312, 337-337, 362-362, 382-382, 407-407, 432-432, 452-452, 472-472, 498-498

src/client/graphics/layers/WinModal.ts (2)

59-59: LGTM! Multiple correct v4 migrations.

All utility updates on this line are correct for Tailwind v4:

  • backdrop-blur-smbackdrop-blur-xs (renamed blur utility)
  • z-[9999]z-9999 (numeric z-index token)
  • w-[350px]w-87.5 and md:w-[700px]md:w-175 (numeric width tokens)

73-73: LGTM! Consistent border radius reduction.

All roundedrounded-sm changes provide a more subtle corner radius, aligning with the visual updates across the entire PR.

Also applies to: 79-79, 126-126, 132-132, 148-148, 218-218, 232-232, 243-243

src/client/graphics/layers/PlayerPanel.ts (9)

380-381: LGTM!

The size-1 utility correctly replaces the previous h-[4px] w-[4px] for the dot indicator. In Tailwind v4, size-1 maps to 4px (0.25rem).


391-391: LGTM!

Using size-4.5 (18px) for the traitor icon and removing explicit height/width attributes is cleaner. The v4 size utility handles both dimensions.


482-483: LGTM!

Replacing w-[140px] min-w-[140px] with w-35 shrink-0 is a good v4 migration. The w-35 equals 140px and shrink-0 prevents flex shrinking.

Also applies to: 495-496


513-513: LGTM!

The grid template syntax update from grid-cols-[auto,1fr] to grid-cols-[auto_1fr] is correct for Tailwind v4. The underscore replaces the comma in arbitrary grid definitions.

Also applies to: 526-526, 610-610


567-568: LGTM!

Using min-w-5 (20px) and px-1.5 follows the v4 spacing scale correctly for the alliance badge.


578-580: LGTM!

The max-h-30 (120px) correctly replaces max-h-[120px] using the v4 extended spacing scale.


821-821: LGTM!

The z-10001 syntax is correct for Tailwind v4 arbitrary z-index values without brackets.


827-828: LGTM!

Replacing min-w-[300px] max-w-[400px] with min-w-75 max-w-100 uses the v4 extended spacing scale (75 * 4 = 300px, 100 * 4 = 400px).


846-846: LGTM!

The shadow-sm change for the close button is appropriate. Note that in Tailwind v4, the shadow scale was adjusted—this is a valid utility.

index.html (12)

125-141: LGTM!

The IIFE pattern to apply persisted dark mode before paint is a solid approach for preventing FOUC. The try-catch block around localStorage access handles browsers with restricted storage (e.g., private browsing).


201-201: LGTM!

Using bg-black/0 instead of the old bg-opacity-* utility is the correct v4 approach. Tailwind v4 removed separate opacity utilities in favor of slash syntax.


272-272: LGTM!

The z-99999 syntax is correct for Tailwind v4 arbitrary z-index values.


286-286: LGTM!

The border-black/30 and dark:border-gray-300/60 opacity modifiers follow v4 conventions.


363-363: LGTM!

Replacing right-[10px] top-[10px] with right-2.5 top-2.5 (10px) uses the v4 spacing scale correctly.


367-367: LGTM!

The bottom-7.5 (30px) correctly replaces bottom-[30px] using the v4 extended spacing scale.


393-393: LGTM!

The max-w-215 (860px) correctly replaces max-w-[860px] using the v4 extended spacing scale.


396-396: LGTM!

Using shrink-0 instead of flex-shrink-0 is the correct v4 syntax. The flex- prefix was removed in v4.

Also applies to: 421-421, 438-438


470-470: LGTM!

The z-1000 syntax is correct for Tailwind v4 z-index values.


488-491: Check the hidden flex class combination.

The hidden class sets display: none, while flex sets display: flex. Having both on the same element means hidden wins initially (as intended for the modal's default state), but the inline onclick only removes hidden. This works, but be aware that the order of these classes could cause confusion.

No action needed—just noting for clarity.


496-496: LGTM!

The gap-2 spacing in the language list flex container is appropriate.


499-499: LGTM!

Using rounded-sm is correct. In Tailwind v4, rounded (the bare utility) maps to a smaller radius, while rounded-sm provides the previous rounded behavior.

src/client/components/baseComponents/ranking/PlayerRow.ts (14)

30-33: LGTM!

Using border-yellow-50/0 for transparent borders is the correct v4 opacity modifier syntax. The conditional logic for visible borders is clean.


36-36: LGTM!

The w-7.5 (30px) for rank width follows the v4 extended spacing scale.


55-55: LGTM!

The crown icon positioning and sizing with size-3.75 (15px) and size-5 (20px) at different breakpoints is appropriate. The negative positioning values like -top-0.75 and -top-1.75 are valid v4 syntax.


89-89: LGTM!

The size-7.5 (30px) for the score badge replaces the previous width/height combo cleanly.


101-104: LGTM!

The pr-2.5 (10px) padding and h-1.75 (7px) height for the score bar use the v4 extended spacing scale correctly.


114-114: LGTM!

Using min-w-7.5 (30px) and sm:min-w-15 (60px) for bomb type columns is appropriate.


157-157: LGTM!

The w-31.25 (125px) and sm:w-62.5 (250px) for the gold score name container follow the v4 extended spacing scale.


163-163: LGTM!

The w-15 h-7.5 (60px × 30px) and sm:w-25 sm:h-7.5 (100px × 30px) for the gold score pill are valid v4 utilities.


167-167: LGTM!

The size-3.5 (14px) and sm:size-5 (20px) for the gold coin icon are clean v4 size utilities.


174-174: LGTM!

Using w-50 (200px) for the name container and w-37.5 (150px) for the name text follows v4 conventions.

Also applies to: 177-177


188-188: LGTM!

The tag badge sizing with h-3.75 (15px) and sm:h-5 (20px) uses the v4 extended spacing scale correctly.


198-198: LGTM!

The skull icon sizing with size-7.5 (30px) and sm:size-10 (40px) is appropriate.


205-205: LGTM!

The flag dimensions with min-w-7.5 h-7.5 (30px) and sm:min-w-10 sm:h-10 (40px) follow v4 conventions.


211-216: LGTM!

The profile icon container and image sizing with size-7.5, size-10, size-5, size-6.25 (25px), and negative margin -mt-1.25 are all valid v4 utilities.

src/client/graphics/layers/UnitDisplay.ts (3)

135-135: Blur utility correctly updated for v4.

The backdrop-blur-smbackdrop-blur-xs change aligns with Tailwind v4's renamed blur scale. The rounded-lg adjustment is a visual refinement.

Based on learnings, this is the correct v4 migration for blur utilities.

Also applies to: 181-181


245-245: Tooltip styling correctly updated.

The blur utility change to backdrop-blur-xs is correct for v4, and the rounded-sm sizing is appropriate for the tooltip element.


133-133: Fix z-index syntax for Tailwind v4.

Line 133: Change z-1100 back to z-[1100]. Tailwind v4 requires square-bracket notation for arbitrary z-index values. Without brackets, the z-index styling will not apply, breaking the element's stacking order.

⛔ Skipped due to learnings
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 786
File: src/client/TerritoryPatternsModal.ts:337-338
Timestamp: 2025-06-22T05:48:19.241Z
Learning: In src/client/TerritoryPatternsModal.ts, the bit shifting operators (<<) used in coordinate calculations with decoder.getScale() are intentional and should not be changed to multiplication. The user scottanderson confirmed this is functioning as intended.
src/client/graphics/layers/SendResourceModal.ts (5)

255-263: LGTM!

The focus:outline-hidden is the correct Tailwind v4 replacement for focus:outline-none when you want to completely remove the outline. The button styling is clean and accessible with proper hover/focus states.


364-385: LGTM!

The slider input correctly uses focus:outline-hidden for v4. The tooltip styling with rounded-sm and shadow-sm is consistent with the v4 migration pattern used across other modals in this PR.


388-404: LGTM!

The cap marker and label styling with shadow-sm and rounded-sm is consistent with the tooltip above and follows the v4 migration pattern.


451-470: LGTM!

Both action buttons correctly use focus:outline-hidden for v4 while keeping focus-visible:ring-2 for keyboard accessibility. Good separation of concerns between hiding outline and showing focus ring.


544-556: Use arbitrary bracket syntax for custom values instead of bare class names.

Tailwind v4 requires custom numeric values to use bracket syntax. Replace z-1100 with z-[1100] and max-w-135 with max-w-[540px]. These utilities are not defined in the theme configuration and the bare class names will not generate CSS. Other components in the codebase correctly use bracket syntax (e.g., max-w-[30vw], z-9999).

The focus:outline-hidden is correct for v4.

Likely an incorrect or invalid review comment.

src/client/GameInfoModal.ts (2)

52-53: Spacing conversions are correct and use standard Tailwind v4 syntax.

The padding and width conversions from arbitrary pixel values to Tailwind v4's numeric spacing scale are accurate:

  • px-25 = 100px (from pl-[100px] pr-[100px])
  • w-75 = 300px (from w-[300px])
  • w-125 = 500px (from sm:w-[500px])
  • h-37.5 = 150px (from h-[150px])

Tailwind v4 generates numeric spacing utilities dynamically and supports any multiple of the base 0.25rem unit out of the box. No custom theme configuration is needed for these values.


110-110: No changes needed — h-37.5 is valid in Tailwind v4.

Tailwind CSS v4 natively supports arbitrary numeric multipliers for spacing utilities without brackets. The h-37.5 class works correctly and computes to 150px (37.5 × 0.25rem = 9.375rem). The conversion is mathematically sound, and the codebase already uses this pattern consistently across multiple files.

Copy link
Contributor

@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

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 154b21c and 2978139.

📒 Files selected for processing (4)
  • package.json
  • src/client/FlagInputModal.ts
  • src/client/NewsModal.ts
  • src/client/graphics/layers/PlayerPanel.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/client/FlagInputModal.ts
  • package.json
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: wraith4081
Repo: openfrontio/OpenFrontIO PR: 2735
File: index.html:390-391
Timestamp: 2025-12-29T23:33:17.920Z
Learning: In Tailwind CSS v4, blur utilities were renamed: `backdrop-blur-sm` from v3 is now `backdrop-blur-xs` in v4, and `backdrop-blur` (bare) becomes `backdrop-blur-sm`. Similarly, other blur utilities like `blur-sm` are renamed to `blur-xs`.
📚 Learning: 2025-08-12T00:31:50.144Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 1752
File: src/core/game/Game.ts:750-752
Timestamp: 2025-08-12T00:31:50.144Z
Learning: In the OpenFrontIO codebase, changes to the PlayerInteraction interface (like adding canDonateGold and canDonateTroops flags) do not require corresponding updates to src/core/Schemas.ts or server serialization code.

Applied to files:

  • src/client/graphics/layers/PlayerPanel.ts
📚 Learning: 2025-06-09T02:20:43.637Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 1110
File: src/client/Main.ts:293-295
Timestamp: 2025-06-09T02:20:43.637Z
Learning: In src/client/Main.ts, during game start in the handleJoinLobby callback, UI elements are hidden using direct DOM manipulation with classList.add("hidden") for consistency. This includes modals, buttons, and error divs. The codebase follows this pattern rather than using component APIs for hiding elements during game transitions.

Applied to files:

  • src/client/graphics/layers/PlayerPanel.ts
📚 Learning: 2025-12-13T14:58:29.645Z
Learnt from: scamiv
Repo: openfrontio/OpenFrontIO PR: 2607
File: src/core/execution/PlayerExecution.ts:271-295
Timestamp: 2025-12-13T14:58:29.645Z
Learning: In src/core/execution/PlayerExecution.ts surroundedBySamePlayer(), the `as Player` cast on `mg.playerBySmallID(scan.enemyId)` is intentional. Since scan.enemyId comes from ownerID() on an owned tile and playerBySmallID() only returns Player or undefined, the cast expresses a known invariant. The maintainers prefer loud failures (runtime errors) over silent masking (early returns with guards) for corrupted game state scenarios at trusted call sites.

Applied to files:

  • src/client/graphics/layers/PlayerPanel.ts
📚 Learning: 2025-10-08T17:14:49.369Z
Learnt from: Foorack
Repo: openfrontio/OpenFrontIO PR: 2141
File: src/client/ClientGameRunner.ts:228-234
Timestamp: 2025-10-08T17:14:49.369Z
Learning: For the window close confirmation feature in `ClientGameRunner.ts`, the troop count requirement (>10,000 troops) from issue #2137 was intentionally removed because it was arbitrary and troop count can be reported as low despite having significant land. The confirmation now triggers for any alive player regardless of troop count.

Applied to files:

  • src/client/graphics/layers/PlayerPanel.ts
📚 Learning: 2025-10-20T20:15:28.858Z
Learnt from: sambokai
Repo: openfrontio/OpenFrontIO PR: 2225
File: src/core/execution/FakeHumanExecution.ts:51-51
Timestamp: 2025-10-20T20:15:28.858Z
Learning: In src/core/execution/FakeHumanExecution.ts, game balance constants like MIRV_COOLDOWN_TICKS, MIRV_HESITATION_ODDS, VICTORY_DENIAL_TEAM_THRESHOLD, VICTORY_DENIAL_INDIVIDUAL_THRESHOLD, and STEAMROLL_CITY_GAP_MULTIPLIER are experimental tuning parameters subject to frequent change during balance testing. Do not flag changes to these values as issues or compare them against previous values.

Applied to files:

  • src/client/graphics/layers/PlayerPanel.ts
🔇 Additional comments (9)
src/client/NewsModal.ts (1)

162-166: LGTM! Clean migration to standard Tailwind utilities.

The changes replace arbitrary values with standard Tailwind utilities (p-[4px]p-1, size-[48px]size-12), which improves maintainability and aligns with Tailwind best practices. The visual output remains identical since p-1 equals 4px and size-12 equals 48px.

src/client/graphics/layers/PlayerPanel.ts (8)

380-380: LGTM! Clean migration to size-* utility.

The change from h-[4px] w-[4px] to size-1 is idiomatic for Tailwind v4 and maintains the same 4px sizing while being more concise.


391-391: LGTM! Good use of Tailwind's fractional spacing.

The size-4.5 utility correctly replaces explicit dimensions with a semantic spacing token.


482-483: LGTM! Consistent spacing token migration.

Both treasury and defense sections correctly migrate from arbitrary w-[140px] min-w-[140px] to semantic w-35 shrink-0, maintaining the same 140px width while using more idiomatic flex utilities.

Also applies to: 495-496


567-567: LGTM! Correct spacing token conversion.

The change from min-w-[20px] to min-w-5 correctly maintains the 20px minimum width using Tailwind's spacing scale.


578-578: LGTM! Correct max-height migration.

The change from max-h-[120px] to max-h-30 correctly maintains the 120px maximum height using a semantic spacing token.


828-828: LGTM! Correct width constraint migration.

The modal container width constraints correctly migrate from min-w-[300px] max-w-[400px] to min-w-75 max-w-100, maintaining the same 300px minimum and 400px maximum widths using semantic spacing tokens.


846-846: LGTM! Subtle shadow refinement.

The change from shadow to shadow-sm provides a more subtle shadow on the close button. This is a valid Tailwind utility and appears to be an intentional design refinement.


513-513: The grid column syntax change from grid-cols-[auto,1fr] to grid-cols-[auto_1fr] is correct for Tailwind CSS v4. In Tailwind arbitrary values, underscores represent spaces, so grid-cols-[auto_1fr] correctly compiles to grid-template-columns: auto 1fr. This syntax is standard in Tailwind v4 and works as intended across all three locations (lines 513, 526, 610).

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 30, 2025
Copy link
Contributor

@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: 18

Caution

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

⚠️ Outside diff range comments (1)
src/client/graphics/layers/WinModal.ts (1)

59-86: Define custom utilities or switch to arbitrary values; fix aspect ratio comment.

The custom utilities w-87.5, md:w-175, and z-9999 are used throughout the codebase (WinModal.ts, LanguageModal.ts, Matchmaking.ts) but not defined in the @theme block. Add these to your Tailwind v4 configuration:

@theme {
  --default-ring-width: 3px;
  --default-ring-color: var(--color-blue-500);
  
  /* Add these custom utilities */
  --width-87.5: 350px;      /* 87.5 * 4px */
  --width-175: 700px;       /* 175 * 4px */
  --z-index-9999: 9999;
}

Alternatively, use arbitrary values: w-[350px], md:w-[700px], z-[9999].

Also on line 130, the comment <!-- 56.25% = 9:16 --> is incorrect. The value 56.25% creates a 16:9 aspect ratio (widescreen video), not 9:16. Correct it to <!-- 56.25% = 16:9 -->.

The backdrop-blur-xs migration is correct for Tailwind v4.

♻️ Duplicate comments (3)
src/client/graphics/layers/PlayerInfoOverlay.ts (1)

482-482: Backdrop blur update looks correct; shadow conflict remains.

The backdrop-blur-xs change aligns with Tailwind v4's blur utility renaming. However, the line still has both shadow-xs and shadow-lg, which are mutually exclusive—only one should be applied.

Based on learnings, backdrop-blur-smbackdrop-blur-xs is the correct migration for Tailwind v4.

src/client/graphics/layers/PlayerPanel.ts (1)

821-821: Restore brackets for z-index arbitrary value.

As previously noted, arbitrary z-index values must use bracket notation in Tailwind CSS v4. Change z-10001 back to z-[10001].

index.html (1)

463-466: Verify custom z-index value is defined in theme.

The class z-1000 is not a standard Tailwind utility. This is the same issue as z-99999 elsewhere—ensure these values are defined in your theme configuration.

The verification script provided earlier will check for both z-99999 and z-1000 definitions.

🧹 Nitpick comments (4)
src/client/TerritoryPatternsModal.ts (1)

260-269: Unused height parameter creates confusion.

The function accepts both width and height parameters, but only width is used to set the --size variable (line 268). The height parameter is completely ignored. This is confusing and inconsistent with the function signature.

🔎 Refactor to remove unused parameter

If square previews are always intended, simplify the signature:

  private renderColorPreview(
    hexCode: string,
-   width: number,
-   height: number,
+   size: number,
  ): TemplateResult {
    return html`
      <div
        class="rounded-sm size-(--size) bg-(--bg)"
-       style="--size: ${width}px; --bg: ${hexCode};"
+       style="--size: ${size}px; --bg: ${hexCode};"
      ></div>
    `;
  }

Then update the caller at line 275:

  const preview = this.selectedColor
-   ? this.renderColorPreview(this.selectedColor, 48, 48)
+   ? this.renderColorPreview(this.selectedColor, 48)
    : renderPatternPreview(this.selectedPattern ?? null, 48, 48);

If non-square previews are needed in the future, use separate CSS variables for width and height with w-(--width) and h-(--height) utilities instead.

src/client/utilities/RenderUnitTypeOptions.ts (1)

31-33: Consider simplifying the class string formatting.

The multi-line class string is functional but could be more readable as a single line or using a helper function for conditional classes.

🔎 Cleaner formatting option
-      <label
-        class="option-card ${disabledUnits.includes(type)
-          ? ""
-          : "selected"} w-35"
-      >
+      <label
+        class="option-card w-35 ${disabledUnits.includes(type) ? "" : "selected"}"
+      >
src/client/HostLobbyModal.ts (1)

521-521: Consider using design tokens for color values.

The arbitrary color values [#444] and [#ccc] work in Tailwind v4 but bypass your design system. For consistency and maintainability, consider defining these as CSS custom properties or theme colors.

Example using CSS custom properties

If you define colors in your Tailwind v4 CSS:

@theme {
  --color-border-subtle: #444;
  --color-text-muted: #ccc;
}

Then use them as:

-class="w-full border-t border-t-[#444] my-4"
+class="w-full border-t border-t-border-subtle my-4"

-class="mt-2 mb-3 font-bold text-[#ccc] text-center"
+class="mt-2 mb-3 font-bold text-text-muted text-center"

Also applies to: 525-525

src/client/SinglePlayerModal.ts (1)

390-391: Consider using theme colors for consistency.

The arbitrary hex values border-t-[#444] and text-[#ccc] work correctly, but using theme colors (like border-gray-700 and text-gray-300) would improve maintainability and ensure consistency with your design system.

🔎 Suggested refactor using theme colors
-            <hr class="w-full border-t border-t-[#444] my-4" />
-            <div class="mt-2 mb-3 font-bold text-[#ccc] text-center">
+            <hr class="w-full border-t border-gray-700 my-4" />
+            <div class="mt-2 mb-3 font-bold text-gray-300 text-center">
              ${translateText("single_modal.enables_title")}
            </div>
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2978139 and 0ed4806.

📒 Files selected for processing (35)
  • index.html
  • src/client/FlagInput.ts
  • src/client/GameInfoModal.ts
  • src/client/GoogleAdElement.ts
  • src/client/HelpModal.ts
  • src/client/HostLobbyModal.ts
  • src/client/NewsModal.ts
  • src/client/PublicLobby.ts
  • src/client/SinglePlayerModal.ts
  • src/client/TerritoryPatternsModal.ts
  • src/client/components/LobbyTeamView.ts
  • src/client/components/PatternButton.ts
  • src/client/components/baseComponents/ranking/PlayerRow.ts
  • src/client/components/baseComponents/ranking/RankingControls.ts
  • src/client/components/baseComponents/ranking/RankingHeader.ts
  • src/client/components/baseComponents/setting/SettingKeybind.ts
  • src/client/components/baseComponents/stats/GameList.ts
  • src/client/components/baseComponents/stats/PlayerStatsTable.ts
  • src/client/graphics/layers/BuildMenu.ts
  • src/client/graphics/layers/ChatDisplay.ts
  • src/client/graphics/layers/ControlPanel.ts
  • src/client/graphics/layers/EventsDisplay.ts
  • src/client/graphics/layers/GameLeftSidebar.ts
  • src/client/graphics/layers/MultiTabModal.ts
  • src/client/graphics/layers/PerformanceOverlay.ts
  • src/client/graphics/layers/PlayerInfoOverlay.ts
  • src/client/graphics/layers/PlayerPanel.ts
  • src/client/graphics/layers/SendResourceModal.ts
  • src/client/graphics/layers/SettingsModal.ts
  • src/client/graphics/layers/SpawnTimer.ts
  • src/client/graphics/layers/TeamStats.ts
  • src/client/graphics/layers/UnitDisplay.ts
  • src/client/graphics/layers/WinModal.ts
  • src/client/utilities/RenderUnitTypeOptions.ts
  • vite.config.ts
🚧 Files skipped from review as they are similar to previous changes (10)
  • src/client/components/baseComponents/setting/SettingKeybind.ts
  • src/client/components/LobbyTeamView.ts
  • src/client/HelpModal.ts
  • src/client/graphics/layers/SendResourceModal.ts
  • src/client/graphics/layers/GameLeftSidebar.ts
  • vite.config.ts
  • src/client/components/baseComponents/ranking/RankingHeader.ts
  • src/client/graphics/layers/ControlPanel.ts
  • src/client/graphics/layers/ChatDisplay.ts
  • src/client/GameInfoModal.ts
🧰 Additional context used
🧠 Learnings (16)
📓 Common learnings
Learnt from: wraith4081
Repo: openfrontio/OpenFrontIO PR: 2735
File: index.html:390-391
Timestamp: 2025-12-29T23:33:25.733Z
Learning: In Tailwind CSS v4, blur utilities were renamed: `backdrop-blur-sm` from v3 is now `backdrop-blur-xs` in v4, and `backdrop-blur` (bare) becomes `backdrop-blur-sm`. Similarly, other blur utilities like `blur-sm` are renamed to `blur-xs`.
📚 Learning: 2025-08-12T00:31:50.144Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 1752
File: src/core/game/Game.ts:750-752
Timestamp: 2025-08-12T00:31:50.144Z
Learning: In the OpenFrontIO codebase, changes to the PlayerInteraction interface (like adding canDonateGold and canDonateTroops flags) do not require corresponding updates to src/core/Schemas.ts or server serialization code.

Applied to files:

  • src/client/graphics/layers/PlayerInfoOverlay.ts
  • src/client/components/baseComponents/ranking/PlayerRow.ts
  • src/client/SinglePlayerModal.ts
  • src/client/graphics/layers/PlayerPanel.ts
📚 Learning: 2025-06-09T02:20:43.637Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 1110
File: src/client/Main.ts:293-295
Timestamp: 2025-06-09T02:20:43.637Z
Learning: In src/client/Main.ts, during game start in the handleJoinLobby callback, UI elements are hidden using direct DOM manipulation with classList.add("hidden") for consistency. This includes modals, buttons, and error divs. The codebase follows this pattern rather than using component APIs for hiding elements during game transitions.

Applied to files:

  • src/client/graphics/layers/PlayerInfoOverlay.ts
  • index.html
  • src/client/graphics/layers/UnitDisplay.ts
  • src/client/HostLobbyModal.ts
  • src/client/graphics/layers/WinModal.ts
  • src/client/components/baseComponents/ranking/PlayerRow.ts
  • src/client/graphics/layers/EventsDisplay.ts
  • src/client/PublicLobby.ts
  • src/client/components/baseComponents/stats/GameList.ts
  • src/client/SinglePlayerModal.ts
  • src/client/graphics/layers/PlayerPanel.ts
📚 Learning: 2025-08-12T19:26:50.542Z
Learnt from: woodydrn
Repo: openfrontio/OpenFrontIO PR: 1687
File: src/client/graphics/layers/NameLayer.ts:0-0
Timestamp: 2025-08-12T19:26:50.542Z
Learning: In the OpenFrontIO project UI, textShadow styling was rejected by the maintainer as not suiting the current UI design, indicating they prefer cleaner text styling without shadows for better consistency.

Applied to files:

  • src/client/graphics/layers/PlayerInfoOverlay.ts
📚 Learning: 2025-12-29T23:33:25.733Z
Learnt from: wraith4081
Repo: openfrontio/OpenFrontIO PR: 2735
File: index.html:390-391
Timestamp: 2025-12-29T23:33:25.733Z
Learning: In Tailwind CSS v4, blur utilities were renamed: `backdrop-blur-sm` from v3 is now `backdrop-blur-xs` in v4, and `backdrop-blur` (bare) becomes `backdrop-blur-sm`. Similarly, other blur utilities like `blur-sm` are renamed to `blur-xs`.

Applied to files:

  • src/client/graphics/layers/PlayerInfoOverlay.ts
  • src/client/graphics/layers/SettingsModal.ts
📚 Learning: 2025-12-29T23:33:17.920Z
Learnt from: wraith4081
Repo: openfrontio/OpenFrontIO PR: 2735
File: index.html:390-391
Timestamp: 2025-12-29T23:33:17.920Z
Learning: In Tailwind CSS v4, update blur-related utilities in HTML templates. The mappings are: backdrop-blur-sm (v3) -> backdrop-blur-xs (v4); backdrop-blur (bare) -> backdrop-blur-sm; blur-sm -> blur-xs. Apply these changes to all HTML files (e.g., index.html and other templates) to reflect the v4 naming. Consider updating a project-wide search/replace or using a codemod to ensure consistency across the codebase.

Applied to files:

  • index.html
📚 Learning: 2025-10-21T20:06:04.823Z
Learnt from: Saphereye
Repo: openfrontio/OpenFrontIO PR: 2233
File: src/client/HostLobbyModal.ts:891-891
Timestamp: 2025-10-21T20:06:04.823Z
Learning: For the HumansVsNations game mode in `src/client/HostLobbyModal.ts` and related files, the implementation strategy is to generate all nations and adjust their strength for balancing, rather than limiting lobby size based on the number of available nations on the map.

Applied to files:

  • src/client/HostLobbyModal.ts
  • src/client/SinglePlayerModal.ts
📚 Learning: 2025-12-26T22:21:21.904Z
Learnt from: FloPinguin
Repo: openfrontio/OpenFrontIO PR: 2689
File: src/client/PublicLobby.ts:245-245
Timestamp: 2025-12-26T22:21:21.904Z
Learning: In public lobbies with HumansVsNations mode in src/client/PublicLobby.ts, maxPlayers represents only human player slots (already halved in DefaultConfig.ts). The nation NPCs are added automatically server-side and don't count toward maxPlayers. Therefore, getTeamSize correctly returns maxPlayers directly for HumansVsNations to display the proper team size (e.g., maxPlayers=5 yields "5 Humans vs 5 Nations").

Applied to files:

  • src/client/HostLobbyModal.ts
📚 Learning: 2025-10-26T15:37:07.732Z
Learnt from: GlacialDrift
Repo: openfrontio/OpenFrontIO PR: 2298
File: src/client/graphics/layers/TerritoryLayer.ts:200-210
Timestamp: 2025-10-26T15:37:07.732Z
Learning: In GameImpl.ts lines 124-139, team assignment logic varies by number of teams: when numPlayerTeams < 8, teams are assigned ColoredTeams values (Red, Blue, Yellow, Green, Purple, Orange, Teal); when numPlayerTeams >= 8, teams are assigned generic string identifiers like "Team 1", "Team 2", etc., which are not members of ColoredTeams.

Applied to files:

  • src/client/graphics/layers/TeamStats.ts
  • src/client/components/baseComponents/ranking/PlayerRow.ts
📚 Learning: 2025-05-19T06:00:38.007Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 784
File: src/core/game/StatsImpl.ts:125-134
Timestamp: 2025-05-19T06:00:38.007Z
Learning: In StatsImpl.ts, unused parameters in boat/stats-related methods are intentionally kept for future use and shouldn't be removed.

Applied to files:

  • src/client/graphics/layers/TeamStats.ts
  • src/client/components/baseComponents/stats/PlayerStatsTable.ts
📚 Learning: 2025-06-10T09:56:44.473Z
Learnt from: Ble4Ch
Repo: openfrontio/OpenFrontIO PR: 1063
File: src/core/configuration/PastelThemeDark.ts:53-53
Timestamp: 2025-06-10T09:56:44.473Z
Learning: In ColorAllocator class in src/core/configuration/Colors.ts, the correct method names are assignColor(id: string): Colord for general color assignment and assignTeamColor(team: Team): Colord for team-specific colors. There are no assignPlayerColor() or assignBotColor() methods.

Applied to files:

  • src/client/graphics/layers/TeamStats.ts
📚 Learning: 2025-12-13T14:58:29.645Z
Learnt from: scamiv
Repo: openfrontio/OpenFrontIO PR: 2607
File: src/core/execution/PlayerExecution.ts:271-295
Timestamp: 2025-12-13T14:58:29.645Z
Learning: In src/core/execution/PlayerExecution.ts surroundedBySamePlayer(), the `as Player` cast on `mg.playerBySmallID(scan.enemyId)` is intentional. Since scan.enemyId comes from ownerID() on an owned tile and playerBySmallID() only returns Player or undefined, the cast expresses a known invariant. The maintainers prefer loud failures (runtime errors) over silent masking (early returns with guards) for corrupted game state scenarios at trusted call sites.

Applied to files:

  • src/client/components/baseComponents/ranking/PlayerRow.ts
  • src/client/graphics/layers/PlayerPanel.ts
📚 Learning: 2025-06-22T05:48:19.241Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 786
File: src/client/TerritoryPatternsModal.ts:337-338
Timestamp: 2025-06-22T05:48:19.241Z
Learning: In src/client/TerritoryPatternsModal.ts, the bit shifting operators (<<) used in coordinate calculations with decoder.getScale() are intentional and should not be changed to multiplication. The user scottanderson confirmed this is functioning as intended.

Applied to files:

  • src/client/TerritoryPatternsModal.ts
📚 Learning: 2025-10-20T20:15:28.858Z
Learnt from: sambokai
Repo: openfrontio/OpenFrontIO PR: 2225
File: src/core/execution/FakeHumanExecution.ts:51-51
Timestamp: 2025-10-20T20:15:28.858Z
Learning: In src/core/execution/FakeHumanExecution.ts, game balance constants like MIRV_COOLDOWN_TICKS, MIRV_HESITATION_ODDS, VICTORY_DENIAL_TEAM_THRESHOLD, VICTORY_DENIAL_INDIVIDUAL_THRESHOLD, and STEAMROLL_CITY_GAP_MULTIPLIER are experimental tuning parameters subject to frequent change during balance testing. Do not flag changes to these values as issues or compare them against previous values.

Applied to files:

  • src/client/components/baseComponents/stats/GameList.ts
📚 Learning: 2025-10-08T17:14:49.369Z
Learnt from: Foorack
Repo: openfrontio/OpenFrontIO PR: 2141
File: src/client/ClientGameRunner.ts:228-234
Timestamp: 2025-10-08T17:14:49.369Z
Learning: For the window close confirmation feature in `ClientGameRunner.ts`, the troop count requirement (>10,000 troops) from issue #2137 was intentionally removed because it was arbitrary and troop count can be reported as low despite having significant land. The confirmation now triggers for any alive player regardless of troop count.

Applied to files:

  • src/client/graphics/layers/PlayerPanel.ts
📚 Learning: 2025-07-31T12:03:08.052Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 1655
File: resources/maps/giantworldmap/manifest.json:165-174
Timestamp: 2025-07-31T12:03:08.052Z
Learning: In OpenFrontIO draft PRs, flag names in map manifest files may be placeholders that will be updated to match the actual SVG flag file names when the assets are received. The final naming depends on the actual flag SVG files provided, not code naming conventions.

Applied to files:

  • src/client/FlagInput.ts
🧬 Code graph analysis (4)
src/client/graphics/layers/WinModal.ts (2)
src/client/Utils.ts (1)
  • translateText (92-147)
src/client/LangSelector.ts (1)
  • translateText (258-278)
src/client/NewsModal.ts (1)
src/client/LangSelector.ts (1)
  • translateText (258-278)
src/client/components/baseComponents/ranking/PlayerRow.ts (1)
src/client/Utils.ts (1)
  • renderNumber (19-43)
src/client/SinglePlayerModal.ts (2)
src/client/Utils.ts (1)
  • translateText (92-147)
src/client/LangSelector.ts (1)
  • translateText (258-278)
🔇 Additional comments (52)
src/client/graphics/layers/BuildMenu.ts (1)

463-463: LGTM! Clean migration to Tailwind utility class.

The inline style has been correctly replaced with the align-middle utility class, maintaining the same vertical alignment behavior for the gold coin icon.

src/client/graphics/layers/EventsDisplay.ts (6)

156-158: LGTM: Filter style logic updated correctly.

The conditional filter style now uses a semicolon-terminated string when the category is active, and an empty string otherwise. This is cleaner and aligns with the v4 migration.


819-819: LGTM: Border radius updated to rounded-sm.

The retaliate button now uses rounded-sm instead of rounded, consistent with the v4 migration pattern observed throughout the PR.


857-857: LGTM: Shorthand utility shrink-0 applied consistently.

All instances of flex-shrink-0 have been correctly replaced with the shorter shrink-0 utility, which is the Tailwind v4 convention. This affects cancel buttons and status spans across multiple render methods.

Also applies to: 860-860, 893-893, 896-896, 929-929, 932-932


1029-1029: LGTM: Backdrop blur utilities updated for v4.

The backdrop-blur utilities have been correctly renamed to backdrop-blur-sm in both the toggle button wrapper and the main events container, matching the Tailwind v4 naming conventions. Based on learnings, this is the correct mapping for v4.

Also applies to: 1036-1036


1086-1086: LGTM: Pointer events moved to class-based approach.

Moving pointer-events-auto from inline styles to a CSS class is better practice and aligns with the component's approach to styling. This improves consistency and maintainability.


1125-1125: LGTM: Event button border radius updated.

The event action buttons now use rounded-sm instead of rounded, maintaining visual consistency with other button updates in this file.

src/client/graphics/layers/TeamStats.ts (1)

132-133: Clean refactor to CSS-variable-driven grid layout.

The switch from inline grid-template-columns to a CSS variable (--cols) with Tailwind's arbitrary value syntax is clean and maintainable. The column count logic (5 for units view, 4 for control view) correctly matches the conditional rendering below.

src/client/components/baseComponents/stats/PlayerStatsTable.ts (2)

120-129: LGTM! Width utilities applied correctly.

The width distribution (40% for weapon names, 20% each for numeric columns) makes sense and the fractions add up to 100%. Clean conversion from inline styles to Tailwind utilities.


173-173: LGTM! Margin conversion is accurate.

The mt-3 utility correctly replaces the inline margin-top: 0.75rem; style. Clean migration to Tailwind utilities.

src/client/GoogleAdElement.ts (1)

58-58: LGTM! Clean migration to utility class.

Replacing inline style="display:block" with the Tailwind block utility class is cleaner and aligns with the Tailwind v4 migration objective. Since Shadow DOM is disabled (line 27-29), global Tailwind styles apply correctly to this element.

src/client/NewsModal.ts (2)

162-162: LGTM! Clean migration to standard utilities.

The changes from arbitrary values (p-[4px], size-[48px]) to standard Tailwind utilities (p-1, size-12) improve maintainability while preserving the same visual output.

Also applies to: 166-166


171-172: LGTM! Aligns with project-wide CSS variable pattern.

The background-image refactor uses Tailwind's arbitrary value syntax with CSS variables, matching the pattern applied across other components in this migration (TerritoryPatternsModal, SpawnTimer, MultiTabModal).

src/client/PublicLobby.ts (2)

129-129: Good refactor to Tailwind utility.

Converting the inline mask-image style to a Tailwind arbitrary value utility improves maintainability. The syntax looks correct for v4.

Please verify that the fade effect on the map image renders identically to the previous inline style implementation.

Based on learnings, Tailwind v4 introduced finer-grained sizing tokens (like xs), so this utility pattern aligns with v4's approach.


149-149: Correct v4 radius token.

The change from rounded-sm to rounded-xs is consistent with Tailwind v4's finer-grained sizing system. This aligns with the broader pattern of radius refinements across components.

Based on learnings, v4 introduced xs sizing for more precise control (e.g., blur-sm became blur-xs).

src/client/TerritoryPatternsModal.ts (2)

143-143: LGTM! Clean migration to utility classes.

The removal of inline styles and adoption of justify-center items-start utilities aligns well with the Tailwind v4 migration goals.


193-194: The bg-(--bg) syntax is correct for Tailwind v4.

This parentheses syntax with CSS custom properties is the standard approach in Tailwind v4 for dynamic values. It works correctly with the style="--bg: ${hexCode};" declaration and is used consistently throughout your codebase (size-(--size), w-(--width), text-(--color)). No changes needed.

src/client/utilities/RenderUnitTypeOptions.ts (1)

44-44: LGTM!

The migration from inline text-align: center to the text-center utility class is correct.

src/client/HostLobbyModal.ts (1)

98-551: Clean migration from inline styles to Tailwind utilities.

The systematic replacement of inline styles with Tailwind utility classes follows a consistent pattern and maintains the existing visual behavior. The changes are presentational only and don't affect component logic.

src/client/graphics/layers/WinModal.ts (1)

126-126: Consistent border radius updates.

Clean and systematic application of rounded-sm across all inner content sections—YouTube tutorial, pattern buttons, Steam wishlist, and Discord blocks. This maintains visual consistency throughout the modal.

Also applies to: 133-133, 149-149, 219-219, 233-233, 244-244

src/client/graphics/layers/UnitDisplay.ts (3)

135-135: Blur utility updates look correct.

The backdrop blur changes from backdrop-blur-sm to backdrop-blur-xs align with Tailwind v4's renamed blur utilities. Based on learnings, this is the correct migration path.

Also applies to: 181-181, 245-245


245-245: Rounding adjustments look appropriate.

The updates from rounded to rounded-sm provide consistent, slightly tighter border radii across the unit display UI elements.

Also applies to: 267-269


305-305: Good refactor to use Tailwind utilities.

Moving from inline styles to class-based utilities (align-middle size-6) is cleaner and more maintainable.

src/client/graphics/layers/PlayerInfoOverlay.ts (1)

206-206: Clean migration to Tailwind utilities.

Replacing inline vertical-align styles with the align-middle class is consistent with the Tailwind v4 migration and improves maintainability.

Also applies to: 287-287, 391-391

src/client/graphics/layers/SettingsModal.ts (2)

221-221: Layout approach changed from margin-based to gap-based spacing.

The container switched from space-y-3 (margin-based) to flex flex-col gap-3 (flexbox gap-based). Both achieve vertical spacing, but the spacing mechanism differs. The gap approach is more modern and explicit. Verify that this doesn't cause any layout issues, especially with nested elements or edge cases.


223-223: Visual refinement: border radius reduced across all interactive elements.

All option rows and the exit button changed from rounded (4px) to rounded-sm (2px) for a subtler, more refined appearance. This consistent visual change aligns well with the v4 migration aesthetic.

Also applies to: 245-245, 272-272, 292-292, 312-312, 337-337, 362-362, 382-382, 407-407, 432-432, 452-452, 472-472, 498-498

src/client/graphics/layers/PlayerPanel.ts (5)

380-380: LGTM: Size utility consolidation.

The change from h-[4px] w-[4px] to size-1 correctly consolidates the sizing into Tailwind v4's size utility (0.25rem = 4px).


513-513: LGTM: Grid template syntax updated for v4.

Correctly changed grid column templates from comma-separated grid-cols-[auto,1fr] to underscore-separated grid-cols-[auto_1fr], which is the required syntax for arbitrary grid values in Tailwind CSS v4.

Also applies to: 526-526, 610-610


567-567: LGTM: Width and height utilities correctly migrated.

All size conversions are accurate:

  • min-w-5 = 20px
  • max-h-30 = 120px
  • min-w-75 = 300px, max-w-100 = 400px

Also applies to: 578-578, 828-828


839-841: LGTM: Structural styling migrated to utility classes.

Correctly replaced inline styles with Tailwind classes:

  • overflow-visible class replaces inline style
  • Overflow, webkit scrolling, and resize properties now use class syntax
  • Shadow adjustment from shadow to shadow-sm appears intentional

Also applies to: 846-846


391-391: Use arbitrary value syntax for size-4.5.

Tailwind v4's default spacing scale does not include size-4.5; it goes directly from size-4 (16px) to size-5 (20px). Use size-[1.125rem] or size-[18px] instead.

src/client/SinglePlayerModal.ts (2)

127-127: LGTM! Clean migration to utility classes.

The image styling correctly uses Tailwind utilities for the random map card. The custom aspect ratio aspect-2/1 is valid syntax.


394-394: LGTM! Well-structured flex layout.

The flex utilities properly center and wrap the unit type options with appropriate spacing. Clean migration from inline styles.

src/client/components/PatternButton.ts (4)

73-73: LGTM! Correct spacing conversion.

The conversion from max-w-[200px] to max-w-50 is accurate (50 × 0.25rem = 12.5rem = 200px).


100-102: LGTM! Correct sizing utility and overflow handling.

The conversion from w-[120px] h-[120px] to size-30 is accurate, and adding overflow-hidden properly constrains the content.


142-147: LGTM! Proper use of arbitrary property syntax.

The [image-rendering:pixelated] class correctly uses Tailwind's arbitrary property syntax to move styling from inline to utility classes.


159-167: LGTM! Clean grid implementation.

The grid layout and cell styling use standard Tailwind utilities correctly.

index.html (7)

125-141: LGTM! Good FOUC prevention pattern.

The IIFE correctly applies persisted dark mode before page render, and the try-catch handles storage access errors gracefully.


200-202: LGTM! Correct v4 opacity syntax.

The conversion from bg-opacity-0 to bg-black/0 follows Tailwind v4's new color/opacity format.


358-360: LGTM! Correct positioning conversion.

The conversion from right-[10px] top-[10px] to right-2.5 top-2.5 is accurate (2.5 × 0.25rem = 0.625rem = 10px).


361-365: LGTM! Correct spacing conversion.

The conversion from bottom-[30px] to bottom-7.5 is accurate (7.5 × 0.25rem = 1.875rem = 30px).


385-387: LGTM! Correct max-width conversion.

The conversion from max-w-[860px] to max-w-215 is accurate (215 × 0.25rem = 53.75rem = 860px).


388-393: LGTM! Appropriate flex shrink prevention.

Adding shrink-0 to footer sections prevents unwanted flex shrinking and maintains layout integrity.


482-500: LGTM! Clean modal styling updates.

The changes use correct Tailwind v4 syntax:

  • bg-black/50 correctly uses the color/opacity format
  • flex flex-col gap-2 properly replaces space-y-* utilities
  • rounded-sm is a standard border radius utility
src/client/components/baseComponents/ranking/RankingControls.ts (2)

57-59: LGTM! Active state styling is now explicit.

The active state for main buttons now uses explicit utility classes (outline-2 outline-white font-bold) instead of relying on a generic "active" class. This improves clarity and aligns with utility-first styling.


109-111: LGTM! Consistent active state styling.

The sub-button active state styling matches the pattern used for main buttons, ensuring visual consistency across the component.

src/client/graphics/layers/PerformanceOverlay.ts (2)

614-617: Consistent CSS variable pattern for width.

The layer bar width uses the same w-(--width) pattern seen in other components. Ensure this syntax is verified alongside other CSS variable usage in the PR.


554-557: CSS variable positioning syntax is correct in Tailwind v4.

The syntax left-(--left) top-(--top) is valid Tailwind v4 shorthand for CSS custom properties. It automatically expands to left-[var(--left)] and top-[var(--top)], matching the style attributes that set --left and --top. The transform-none class correctly prevents transform conflicts. No changes needed.

src/client/components/baseComponents/ranking/PlayerRow.ts (1)

30-32: LGTM! Improved border visibility logic.

The border logic now uses border-yellow-50/0 (transparent) when neither winner nor current player, which is cleaner than managing separate states. The opacity modifier syntax is correct.

src/client/graphics/layers/MultiTabModal.ts (1)

174-177: CSS variable syntax is correct for Tailwind v4.

The w-(--width) syntax is the correct Tailwind v4 shorthand for CSS custom properties in width utilities. This expands to var(--width) automatically. An alternative valid syntax is w-[var(--width)] if you prefer explicit var() notation, but the current implementation is correct.

src/client/graphics/layers/SpawnTimer.ts (2)

101-103: CSS variable syntax is correct for Tailwind v4.

The shorthand patterns w-(--width) and bg-(--bg) are officially supported in Tailwind v4. This syntax is valid and aligns with Tailwind's documentation for using CSS custom properties in utility classes.


96-96: No review comment was provided. Please include the review comment within <review_comment> tags so I can verify and rewrite it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Devops Infrastructure, CI/CD, dependencies, and maintenance.

Projects

Status: Development

Development

Successfully merging this pull request may close these issues.

2 participants