Skip to content

Added Dynamic Themes depending on collision status and time.#130

Merged
krishkhinchi merged 3 commits into
7-Blocks:mainfrom
TheLinuxGuy-ssh:main
Jul 22, 2026
Merged

Added Dynamic Themes depending on collision status and time.#130
krishkhinchi merged 3 commits into
7-Blocks:mainfrom
TheLinuxGuy-ssh:main

Conversation

@TheLinuxGuy-ssh

@TheLinuxGuy-ssh TheLinuxGuy-ssh commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Description

Added a dynamic background system for the dashboard that switches between space-themed animations based on live conditions like space weather, collision risk, and time of day. There's also a manual override dropdown in the top bar.

Related Issue

Fixes #94

Checklist

  • I have read the contributing guidelines
  • My code follows the project guidelines
  • I have completed testing of my changes
  • Documentation has been updated (if applicable)

Screenshots / Screen Recordings

image image

More themes, as specified in the issue to create. Just check them out.

Breaking Changes

No breaking changes. The background sits behind all existing UI and doesn't affect any current functionality.


ECSoC26 Submission

ECSoC26 contributors only — select your difficulty level by checking exactly one box below.
Leaving all boxes unchecked, or checking more than one, will cause the automation to fail.

  • ECSoC26-L1 – Beginner
  • ECSoC26-L2 – Intermediate
  • ECSoC26-L3 – Advanced

Summary by CodeRabbit

  • New Features

    • Added dynamic backgrounds that adapt to daytime, nighttime, weather conditions, and collision alerts.
    • Introduced animated themes including auroras, solar storms, meteors, and starry skies.
    • Backgrounds now transition smoothly when conditions change.
    • Added automatic support for reduced-motion preferences and pausing animations when the tab is hidden.
  • Style

    • Updated layouts, panels, drawers, and terminals with translucent surfaces and backdrop blur for improved visual integration.

Greptile Summary

This PR adds condition-driven animated backgrounds to the dashboard. The main changes are:

  • Six lazy-loaded space background themes.
  • Automatic selection from collision, weather, and time data.
  • Reduced-motion and tab-visibility animation controls.
  • Translucent layout and page surfaces that reveal the background.

Confidence Score: 4/5

Time-based selection, collision coverage, and per-element animation transforms can produce incorrect backgrounds and need fixes before merging.

  • Day and night can remain stale and use the wrong timezone.
  • High-risk collisions outside the first result page are ignored.
  • The promised manual selection has no state path.
  • Shared keyframes erase distinct meteor and orbit transforms.

frontend/src/hooks/useBackgroundTheme.ts, frontend/src/utils/backgroundEngine.ts, and frontend/src/styles/index.css

Important Files Changed

Filename Overview
frontend/src/hooks/useBackgroundTheme.ts Adds automatic theme selection and animation gating, but lacks a time trigger and manual override state and only checks one collision page.
frontend/src/utils/backgroundEngine.ts Adds theme priorities and condition evaluation, with day and night based on UTC rather than local time.
frontend/src/components/DynamicBackground/DynamicBackground.tsx Adds lazy theme loading and transitions, with a fallback frame possible between uncached themes.
frontend/src/styles/index.css Adds background animations and reduced-motion rules, but two keyframes overwrite component-specific transforms.
frontend/src/components/layouts/MainLayout.tsx Mounts the background behind the application and makes the main layout surfaces translucent.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  W[Weather query] --> H[useBackgroundTheme]
  C[Collision query] --> H
  T[Current time] --> H
  H --> E[evaluateTheme]
  E --> D[DynamicBackground]
  D --> L[Lazy theme component]
  L --> A[CSS animation layer]
  D --> M[MainLayout background]
Loading
Prompt To Fix All With AI
Fix the following 8 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 8
frontend/src/hooks/useBackgroundTheme.ts:29-32
**Day/Night Theme Stays Stale**

`isDaytime()` is read inside this memo, but time is not a dependency. If API responses remain structurally unchanged when the app crosses 06:00 or 18:00, the memo keeps the previous theme until some query data actually changes.

### Issue 2 of 8
frontend/src/utils/backgroundEngine.ts:85-88
**UTC Drives Local Daylight Theme**

The fixed UTC window makes day and night incorrect for users outside UTC. For example, a user in Tokyo receives the day theme from 15:00 until 03:00 local time instead of during local daylight hours.

```suggestion
export function isDaytime(): boolean {
  const hour = new Date().getHours();
  return hour >= 6 && hour < 18;
}
```

### Issue 3 of 8
frontend/src/hooks/useBackgroundTheme.ts:29-32
**Manual Override Cannot Be Applied**

`currentTheme` is always derived from live conditions, and this hook exposes no override value or setter. As a result, the manual theme selection described for the top bar cannot take precedence over automatic selection or persist across renders.

### Issue 4 of 8
frontend/src/hooks/useBackgroundTheme.ts:27
**Collision Alert Uses One Page**

This fetch examines only the first 50 unfiltered collisions, while the server orders them by numeric risk score and the theme checks categorical risk and status. If a `CRITICAL` or pending `HIGH` collision falls outside that page, the dashboard shows a non-alert theme even though a qualifying conjunction exists.

### Issue 5 of 8
frontend/src/styles/index.css:337-343
**Meteor Angles Are Overwritten**

The keyframes replace each meteor's complete inline transform with `rotate(-25deg)`. Meteors configured at -15°, -35°, and -20° therefore snap to -25° during animation and lose their distinct trajectories.

### Issue 6 of 8
frontend/src/styles/index.css:350-353
**Orbit Tilts Are Overwritten**

These keyframes replace the complete transforms supplied by the collision component. The rings configured at 65° and 75°, with different starting Z rotations, both animate at 70° and lose the intended layered orbit geometry.

### Issue 7 of 8
frontend/src/hooks/useBackgroundTheme.ts:34-35
**Hidden Mount Starts Animations**

`isTabActive` starts as `true` without checking `document.hidden`. When the layout first mounts in an already-hidden tab, every enabled background animation starts until a later visibility event updates this state, defeating the resource-saving gate.

### Issue 8 of 8
frontend/src/components/DynamicBackground/DynamicBackground.tsx:58-69
**Theme Switch Shows Loading Frame**

With `mode="wait"`, the next lazy theme is not mounted until the old theme finishes its 1.2-second exit. If its chunk is not cached, the dark fallback then replaces the background while loading, producing a visible blank step between themes on slower connections.

Reviews (1): Last reviewed commit: "More Theme Ambience Fixes" | Re-trigger Greptile

Greptile also left 8 inline comments on this PR.

Copilot AI review requested due to automatic review settings July 22, 2026 19:16
@codeant-ai

codeant-ai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Skipping CodeAnt AI review — this PR is a back-merge between long-lived branches (mainmain). The diff here has already been reviewed when the underlying commits landed on the source branch, so re-running analysis would produce duplicate findings on already-reviewed code.

If you want to analyze this anyway (e.g. you resolved conflicts with new logic), comment @codeant-ai : review and CodeAnt will start a review.

@github-actions github-actions Bot added ECSoC26 Official label for ECSoC26 event contributions. ECSoC26-L2 Level 2 contribution for the ECSoC26 event. bug Something isn't working documentation Improvements or additions to documentation frontend Frontend development size/XL Very large or complex contribution. type:bug Fixes an existing bug or unexpected behavior. type:documentation Improves project documentation. type:frontend Changes frontend or client-side code. labels Jul 22, 2026
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds an automatic, condition-driven dynamic background system with six animated themes, lazy loading, reduced-motion and tab-visibility handling, layout integration, and translucent UI surfaces.

Changes

Dynamic background system

Layer / File(s) Summary
Theme selection and animation state
frontend/src/utils/backgroundEngine.ts, frontend/src/hooks/useBackgroundTheme.ts
Defines theme priorities and daylight detection, resolves themes from weather and collision data, and controls animation using tab visibility and reduced-motion preferences.
Theme visual components and animations
frontend/src/components/DynamicBackground/*, frontend/src/styles/index.css
Adds day, night, solar storm, aurora, meteor, and collision-alert backgrounds with conditional gradient effects and shared animation keyframes.
Lazy theme orchestration
frontend/src/components/DynamicBackground/DynamicBackground.tsx
Lazy-loads theme components, renders a gradient fallback, passes animation state, and fades between selected themes.
Layout and translucent surface integration
frontend/src/components/layouts/MainLayout.tsx, frontend/src/pages/AIAgents.tsx, frontend/src/pages/CollisionCenter.tsx, frontend/src/pages/Dashboard.tsx, frontend/src/pages/NotFound.tsx, frontend/src/pages/Satellites.tsx
Places the dynamic background in the main layout and updates page containers with translucent backgrounds, borders, and blur effects.

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

Sequence Diagram(s)

sequenceDiagram
  participant MainLayout
  participant DynamicBackground
  participant useBackgroundTheme
  participant backgroundEngine
  participant ThemeComponent
  MainLayout->>DynamicBackground: render background layer
  DynamicBackground->>useBackgroundTheme: read theme and animation state
  useBackgroundTheme->>backgroundEngine: evaluate weather, collision, and daylight conditions
  backgroundEngine-->>useBackgroundTheme: return prioritized theme
  DynamicBackground->>ThemeComponent: lazy-load selected component
  ThemeComponent-->>MainLayout: render animated background
Loading

Possibly related PRs

  • 7-Blocks/Kepler#52: Shares the global [aria-hidden="true"] animation behavior in frontend/src/styles/index.css.

Suggested labels: enhancement, type:feature

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The dynamic backgrounds and automatic theme engine are implemented, but the linked issue's manual selector and local storage preference are not evidenced in the changes. Add the manual theme selector with Auto/individual/Default options and persist the user's choice in local storage.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed The remaining layout and style updates appear to support the new dynamic background and readability requirements.
Title check ✅ Passed The title clearly summarizes the main change: dynamic themes based on collision status and time.
Description check ✅ Passed The description matches the template and includes all required sections, a related issue, checklist, screenshots, breaking changes, and one ECSoC26 selection.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added AI Artificial Intelligence and Machine Learning enhancement New feature or request type:feature Introduces a new feature or enhancement. labels Jul 22, 2026
Comment on lines +29 to +32
const currentTheme = useMemo(
() => resolveAutoTheme(weatherQuery.data, collisionsQuery.data),
[weatherQuery.data, collisionsQuery.data]
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Day/Night Theme Stays Stale

isDaytime() is read inside this memo, but time is not a dependency. If API responses remain structurally unchanged when the app crosses 06:00 or 18:00, the memo keeps the previous theme until some query data actually changes.

Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/hooks/useBackgroundTheme.ts
Line: 29-32

Comment:
**Day/Night Theme Stays Stale**

`isDaytime()` is read inside this memo, but time is not a dependency. If API responses remain structurally unchanged when the app crosses 06:00 or 18:00, the memo keeps the previous theme until some query data actually changes.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +85 to +88
export function isDaytime(): boolean {
const hour = new Date().getUTCHours();
return hour >= 6 && hour < 18;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 UTC Drives Local Daylight Theme

The fixed UTC window makes day and night incorrect for users outside UTC. For example, a user in Tokyo receives the day theme from 15:00 until 03:00 local time instead of during local daylight hours.

Suggested change
export function isDaytime(): boolean {
const hour = new Date().getUTCHours();
return hour >= 6 && hour < 18;
}
export function isDaytime(): boolean {
const hour = new Date().getHours();
return hour >= 6 && hour < 18;
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/utils/backgroundEngine.ts
Line: 85-88

Comment:
**UTC Drives Local Daylight Theme**

The fixed UTC window makes day and night incorrect for users outside UTC. For example, a user in Tokyo receives the day theme from 15:00 until 03:00 local time instead of during local daylight hours.

```suggestion
export function isDaytime(): boolean {
  const hour = new Date().getHours();
  return hour >= 6 && hour < 18;
}
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +29 to +32
const currentTheme = useMemo(
() => resolveAutoTheme(weatherQuery.data, collisionsQuery.data),
[weatherQuery.data, collisionsQuery.data]
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Manual Override Cannot Be Applied

currentTheme is always derived from live conditions, and this hook exposes no override value or setter. As a result, the manual theme selection described for the top bar cannot take precedence over automatic selection or persist across renders.

Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/hooks/useBackgroundTheme.ts
Line: 29-32

Comment:
**Manual Override Cannot Be Applied**

`currentTheme` is always derived from live conditions, and this hook exposes no override value or setter. As a result, the manual theme selection described for the top bar cannot take precedence over automatic selection or persist across renders.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

export function useBackgroundTheme() {
const prefersReducedMotion = useReducedMotion();
const weatherQuery = useWeatherStatus();
const collisionsQuery = useCollisions({ size: 50 });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Collision Alert Uses One Page

This fetch examines only the first 50 unfiltered collisions, while the server orders them by numeric risk score and the theme checks categorical risk and status. If a CRITICAL or pending HIGH collision falls outside that page, the dashboard shows a non-alert theme even though a qualifying conjunction exists.

Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/hooks/useBackgroundTheme.ts
Line: 27

Comment:
**Collision Alert Uses One Page**

This fetch examines only the first 50 unfiltered collisions, while the server orders them by numeric risk score and the theme checks categorical risk and status. If a `CRITICAL` or pending `HIGH` collision falls outside that page, the dashboard shows a non-alert theme even though a qualifying conjunction exists.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +337 to +343
@keyframes meteor-streak {
0% { opacity: 0; transform: rotate(-25deg) translateX(0); }
5% { opacity: 1; }
15% { opacity: 0.8; }
25% { opacity: 0; transform: rotate(-25deg) translateX(100%); }
100% { opacity: 0; transform: rotate(-25deg) translateX(100%); }
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Meteor Angles Are Overwritten

The keyframes replace each meteor's complete inline transform with rotate(-25deg). Meteors configured at -15°, -35°, and -20° therefore snap to -25° during animation and lose their distinct trajectories.

Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/styles/index.css
Line: 337-343

Comment:
**Meteor Angles Are Overwritten**

The keyframes replace each meteor's complete inline transform with `rotate(-25deg)`. Meteors configured at -15°, -35°, and -20° therefore snap to -25° during animation and lose their distinct trajectories.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +350 to +353
@keyframes orbit-rotate {
0% { transform: rotateX(70deg) rotateZ(0deg); }
100% { transform: rotateX(70deg) rotateZ(360deg); }
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Orbit Tilts Are Overwritten

These keyframes replace the complete transforms supplied by the collision component. The rings configured at 65° and 75°, with different starting Z rotations, both animate at 70° and lose the intended layered orbit geometry.

Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/styles/index.css
Line: 350-353

Comment:
**Orbit Tilts Are Overwritten**

These keyframes replace the complete transforms supplied by the collision component. The rings configured at 65° and 75°, with different starting Z rotations, both animate at 70° and lose the intended layered orbit geometry.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +34 to +35
const [isTabActive, setIsTabActive] = useState(true);
const animating = !prefersReducedMotion && isTabActive;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Hidden Mount Starts Animations

isTabActive starts as true without checking document.hidden. When the layout first mounts in an already-hidden tab, every enabled background animation starts until a later visibility event updates this state, defeating the resource-saving gate.

Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/hooks/useBackgroundTheme.ts
Line: 34-35

Comment:
**Hidden Mount Starts Animations**

`isTabActive` starts as `true` without checking `document.hidden`. When the layout first mounts in an already-hidden tab, every enabled background animation starts until a later visibility event updates this state, defeating the resource-saving gate.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +58 to +69
<AnimatePresence mode="wait">
<motion.div
key={currentTheme}
className="absolute inset-0"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 1.2, ease: 'easeInOut' }}
>
<Suspense fallback={<FallbackLoader />}>
{ThemeComponent && <ThemeComponent animating={animating} />}
</Suspense>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Theme Switch Shows Loading Frame

With mode="wait", the next lazy theme is not mounted until the old theme finishes its 1.2-second exit. If its chunk is not cached, the dark fallback then replaces the background while loading, producing a visible blank step between themes on slower connections.

Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/components/DynamicBackground/DynamicBackground.tsx
Line: 58-69

Comment:
**Theme Switch Shows Loading Frame**

With `mode="wait"`, the next lazy theme is not mounted until the old theme finishes its 1.2-second exit. If its chunk is not cached, the dark fallback then replaces the background while loading, producing a visible blank step between themes on slower connections.

How can I resolve this? If you propose a fix, please make it concise.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds a dynamic animated dashboard background system that selects a space-themed theme based on live conditions (space weather + collision risk) and time-of-day, and integrates it behind the main app layout.

Changes:

  • Introduces a theme evaluation engine (evaluateTheme) plus a React hook to compute the active background theme.
  • Adds a lazily loaded DynamicBackground component and multiple theme-specific background renderers (Day/Night/Aurora/Solar Storm/Meteor/Collision Alert).
  • Updates several UI surfaces to be more translucent / blurred so the background can show through.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
frontend/src/utils/backgroundEngine.ts Adds theme definitions, priority model, and theme evaluation logic.
frontend/src/hooks/useBackgroundTheme.ts Adds hook that queries weather/collisions and computes the current theme + animation gating.
frontend/src/components/DynamicBackground/DynamicBackground.tsx Adds background host with lazy-loaded theme components and crossfade transitions.
frontend/src/components/DynamicBackground/DayBackground.tsx Implements day-mode background visuals.
frontend/src/components/DynamicBackground/NightBackground.tsx Implements night-mode background visuals.
frontend/src/components/DynamicBackground/AuroraBackground.tsx Implements aurora-mode background visuals.
frontend/src/components/DynamicBackground/SolarStormBackground.tsx Implements solar-storm-mode background visuals.
frontend/src/components/DynamicBackground/MeteorBackground.tsx Implements meteor-shower-mode background visuals.
frontend/src/components/DynamicBackground/CollisionAlertBackground.tsx Implements collision-alert-mode background visuals.
frontend/src/styles/index.css Adds new keyframes and reduced-motion handling for background animations.
frontend/src/components/layouts/MainLayout.tsx Mounts the dynamic background behind the app shell and adjusts shell translucency.
frontend/src/pages/Dashboard.tsx Adjusts hero section styling to allow background to show through.
frontend/src/pages/CollisionCenter.tsx Adjusts panel opacity/blur for background visibility.
frontend/src/pages/Satellites.tsx Adjusts drawer border/background opacity for background visibility.
frontend/src/pages/AIAgents.tsx Adjusts execution log panel translucency to match new background layering.
frontend/src/pages/NotFound.tsx Removes fixed background class to allow background/layering to show.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +178 to 180
<header className="h-12 backdrop-blur-xl bg-bg-deep-space/70 border-b border-border-panel/60 flex justify-between items-center px-4 md:px-6 w-full sticky top-0 z-30">
{/* Command Search & Mobile Toggle */}
<div className="flex items-center gap-2 sm:gap-4 flex-1">
Comment on lines +24 to +44
export function useBackgroundTheme() {
const prefersReducedMotion = useReducedMotion();
const weatherQuery = useWeatherStatus();
const collisionsQuery = useCollisions({ size: 50 });

const currentTheme = useMemo(
() => resolveAutoTheme(weatherQuery.data, collisionsQuery.data),
[weatherQuery.data, collisionsQuery.data]
);

const [isTabActive, setIsTabActive] = useState(true);
const animating = !prefersReducedMotion && isTabActive;

useEffect(() => {
const handleVisibility = () => {
setIsTabActive(!document.hidden);
};
document.addEventListener('visibilitychange', handleVisibility);
return () =>
document.removeEventListener('visibilitychange', handleVisibility);
}, []);
Comment on lines +52 to +66
export const DynamicBackground: React.FC = () => {
const { currentTheme, animating } = useBackgroundTheme();
const ThemeComponent = themeComponents[currentTheme];

return (
<div className="fixed inset-0 z-0 pointer-events-none" aria-hidden="true">
<AnimatePresence mode="wait">
<motion.div
key={currentTheme}
className="absolute inset-0"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 1.2, ease: 'easeInOut' }}
>
Comment on lines +44 to +48
// Check weather status for solar storm / aurora / meteor
if (conditions.weatherStatus) {
const ws = conditions.weatherStatus;

// Solar storm: elevated active storm or flare count
Comment on lines +337 to +343
@keyframes meteor-streak {
0% { opacity: 0; transform: rotate(-25deg) translateX(0); }
5% { opacity: 1; }
15% { opacity: 0.8; }
25% { opacity: 0; transform: rotate(-25deg) translateX(100%); }
100% { opacity: 0; transform: rotate(-25deg) translateX(100%); }
}
Comment on lines +350 to +353
@keyframes orbit-rotate {
0% { transform: rotateX(70deg) rotateZ(0deg); }
100% { transform: rotateX(70deg) rotateZ(360deg); }
}

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
frontend/src/styles/index.css (1)

355-361: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reduced-motion override selector is app-wide, not scoped to the dynamic background.

[aria-hidden="true"] * matches descendants of any aria-hidden="true" element anywhere in the app, not just the background layers. This could unintentionally zero out transitions/animations on unrelated decorative aria-hidden elements elsewhere in the codebase.

Suggested scoping
 `@media` (prefers-reduced-motion: reduce) {
-  [aria-hidden="true"] * {
+  .dynamic-bg * {
     animation-duration: 0.01ms !important;
     animation-iteration-count: 1 !important;
     transition-duration: 0.01ms !important;
   }
 }

Add the dynamic-bg class to the root wrapper in DynamicBackground.tsx.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/styles/index.css` around lines 355 - 361, Scope the
reduced-motion selector to the dynamic background by adding the dynamic-bg class
to the root wrapper in DynamicBackground.tsx, then update the media-query
selector in the stylesheet to target only descendants of that class with
aria-hidden="true".
frontend/src/components/DynamicBackground/DynamicBackground.tsx (1)

40-50: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Tighten themeComponents key type to BackgroundTheme for compile-time coverage.

Typed as Record<string, ...>, so adding a new value to BackgroundThemes without a matching entry here fails silently at runtime (ThemeComponent becomes undefined) rather than at compile time. THEME_PRIORITY in backgroundEngine.ts already uses the stricter Record<BackgroundTheme, number> pattern — mirror it here.

Suggested fix
+import { BackgroundThemes, type BackgroundTheme } from '`@/utils/backgroundEngine`';
-import { BackgroundThemes } from '`@/utils/backgroundEngine`';

 const themeComponents: Record<
-  string,
+  BackgroundTheme,
   React.LazyExoticComponent<React.FC<{ animating: boolean }>>
 > = {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/components/DynamicBackground/DynamicBackground.tsx` around lines
40 - 50, Update the themeComponents declaration to use BackgroundTheme as its
Record key type, matching the stricter THEME_PRIORITY typing pattern in
backgroundEngine.ts. Keep the existing lazy component value type and all theme
mappings unchanged so missing BackgroundThemes are reported at compile time.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/hooks/useBackgroundTheme.ts`:
- Around line 24-51: Update useBackgroundTheme to accept the persisted theme
preference and apply it when resolving currentTheme, allowing
Auto/Default/manual selections to override the weather and collision-derived
theme. Preserve the existing animation and visibility behavior, and thread the
preference through the existing theme resolution or override mechanism rather
than ignoring it.

In `@frontend/src/utils/backgroundEngine.ts`:
- Around line 3-10: Update evaluateTheme to add a METEOR_SHOWER candidate using
the available meteor-shower activity field on weatherStatus, following the
existing solar-storm and aurora condition patterns. Place this condition before
the COLLISION_ALERT check and preserve the defined theme priority so automatic
evaluation can return BackgroundThemes.METEOR_SHOWER.
- Around line 85-88: Update isDaytime() to use the user's local hour via
getHours() instead of UTC hours, while preserving the existing 6-inclusive
through 18-exclusive daytime window.

---

Nitpick comments:
In `@frontend/src/components/DynamicBackground/DynamicBackground.tsx`:
- Around line 40-50: Update the themeComponents declaration to use
BackgroundTheme as its Record key type, matching the stricter THEME_PRIORITY
typing pattern in backgroundEngine.ts. Keep the existing lazy component value
type and all theme mappings unchanged so missing BackgroundThemes are reported
at compile time.

In `@frontend/src/styles/index.css`:
- Around line 355-361: Scope the reduced-motion selector to the dynamic
background by adding the dynamic-bg class to the root wrapper in
DynamicBackground.tsx, then update the media-query selector in the stylesheet to
target only descendants of that class with aria-hidden="true".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4a909153-5edc-4019-97ff-43d79097c70e

📥 Commits

Reviewing files that changed from the base of the PR and between 22a6054 and 1bfab96.

📒 Files selected for processing (16)
  • frontend/src/components/DynamicBackground/AuroraBackground.tsx
  • frontend/src/components/DynamicBackground/CollisionAlertBackground.tsx
  • frontend/src/components/DynamicBackground/DayBackground.tsx
  • frontend/src/components/DynamicBackground/DynamicBackground.tsx
  • frontend/src/components/DynamicBackground/MeteorBackground.tsx
  • frontend/src/components/DynamicBackground/NightBackground.tsx
  • frontend/src/components/DynamicBackground/SolarStormBackground.tsx
  • frontend/src/components/layouts/MainLayout.tsx
  • frontend/src/hooks/useBackgroundTheme.ts
  • frontend/src/pages/AIAgents.tsx
  • frontend/src/pages/CollisionCenter.tsx
  • frontend/src/pages/Dashboard.tsx
  • frontend/src/pages/NotFound.tsx
  • frontend/src/pages/Satellites.tsx
  • frontend/src/styles/index.css
  • frontend/src/utils/backgroundEngine.ts

Comment on lines +24 to +51
export function useBackgroundTheme() {
const prefersReducedMotion = useReducedMotion();
const weatherQuery = useWeatherStatus();
const collisionsQuery = useCollisions({ size: 50 });

const currentTheme = useMemo(
() => resolveAutoTheme(weatherQuery.data, collisionsQuery.data),
[weatherQuery.data, collisionsQuery.data]
);

const [isTabActive, setIsTabActive] = useState(true);
const animating = !prefersReducedMotion && isTabActive;

useEffect(() => {
const handleVisibility = () => {
setIsTabActive(!document.hidden);
};
document.addEventListener('visibilitychange', handleVisibility);
return () =>
document.removeEventListener('visibilitychange', handleVisibility);
}, []);

return {
currentTheme,
animating,
prefersReducedMotion: !!prefersReducedMotion,
};
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n "localStorage" frontend/src -g '*.ts' -g '*.tsx'
rg -n "BackgroundThemes\.|useBackgroundTheme" frontend/src/components -g '*.tsx' -A3 -B3

Repository: 7-Blocks/Kepler

Length of output: 2456


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== useBackgroundTheme =="
sed -n '1,220p' frontend/src/hooks/useBackgroundTheme.ts

echo
echo "== background-related components/hooks =="
rg -n "BackgroundThemes|useBackgroundTheme|theme|localStorage|auto" frontend/src/components frontend/src/hooks frontend/src/utils -g '*.ts' -g '*.tsx' -g '*.js' -g '*.jsx' -A4 -B4

echo
echo "== potential theme selector files =="
fd -i "theme" frontend/src
fd -i "background" frontend/src

Repository: 7-Blocks/Kepler

Length of output: 42599


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== all theme-related symbols =="
rg -n "useBackgroundTheme|resolveAutoTheme|BackgroundThemes|set.*Theme|theme.*set|localStorage|Auto" frontend/src -g '*.ts' -g '*.tsx' -A3 -B3

echo
echo "== inspect background engine and hook =="
sed -n '1,220p' frontend/src/utils/backgroundEngine.ts
sed -n '1,220p' frontend/src/hooks/useBackgroundTheme.ts

echo
echo "== inspect dynamic background component =="
sed -n '1,220p' frontend/src/components/DynamicBackground/DynamicBackground.tsx

Repository: 7-Blocks/Kepler

Length of output: 26854


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== repo-wide localStorage usage =="
rg -n "localStorage" . -g '*.ts' -g '*.tsx' -g '*.js' -g '*.jsx' -g '*.md' -A2 -B2

echo
echo "== repo-wide theme selector terms =="
rg -n "Auto|Default|manual.*theme|theme.*selector|selector.*theme|background theme" frontend . -g '*.ts' -g '*.tsx' -g '*.js' -g '*.jsx' -g '*.md' -A3 -B3

Repository: 7-Blocks/Kepler

Length of output: 188


Pass the saved theme preference into useBackgroundTheme. currentTheme is always recomputed from weather/collision data, so a user-selected Auto/Default/manual preference can’t override the background here. Thread the persisted choice into this hook (or an override layer) so the selector can take effect.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/hooks/useBackgroundTheme.ts` around lines 24 - 51, Update
useBackgroundTheme to accept the persisted theme preference and apply it when
resolving currentTheme, allowing Auto/Default/manual selections to override the
weather and collision-derived theme. Preserve the existing animation and
visibility behavior, and thread the preference through the existing theme
resolution or override mechanism rather than ignoring it.

Comment on lines +3 to +10
export const BackgroundThemes = {
DAY: 'day',
NIGHT: 'night',
SOLAR_STORM: 'solar-storm',
AURORA: 'aurora',
METEOR_SHOWER: 'meteor-shower',
COLLISION_ALERT: 'collision-alert',
} as const;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Meteor Shower theme is unreachable — evaluateTheme never produces it.

METEOR_SHOWER is defined and prioritized, and DynamicBackground.tsx maps it to a component, but no branch in evaluateTheme ever pushes a METEOR_SHOWER candidate. Per issue #94, Meteor Shower is one of the six required automatic themes, so this acceptance criterion is currently unmet — the theme is dead code that can only ever be reached via a (not-shown) manual override.

Suggested fix direction
   // Check collisions for high-risk conjunctions
   if (conditions.collisions && conditions.collisions.length > 0) {

Add a meteor-shower condition (e.g. based on a meteor_shower_active/similar field on weatherStatus, if the API exposes one) before the collision check, mirroring the solar-storm/aurora pattern.

Also applies to: 22-29, 31-83

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/utils/backgroundEngine.ts` around lines 3 - 10, Update
evaluateTheme to add a METEOR_SHOWER candidate using the available meteor-shower
activity field on weatherStatus, following the existing solar-storm and aurora
condition patterns. Place this condition before the COLLISION_ALERT check and
preserve the defined theme priority so automatic evaluation can return
BackgroundThemes.METEOR_SHOWER.

Comment on lines +85 to +88
export function isDaytime(): boolean {
const hour = new Date().getUTCHours();
return hour >= 6 && hour < 18;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

isDaytime() uses UTC hours, breaking day/night theming for non-UTC users.

getUTCHours() with a fixed 6–18 window means the Day/Night theme boundary is only correct for users in UTC+0. For most timezones the app will show "Day" background during local night and vice versa, defeating the "time of day" requirement from issue #94.

Suggested fix
 export function isDaytime(): boolean {
-  const hour = new Date().getUTCHours();
+  const hour = new Date().getHours();
   return hour >= 6 && hour < 18;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function isDaytime(): boolean {
const hour = new Date().getUTCHours();
return hour >= 6 && hour < 18;
}
export function isDaytime(): boolean {
const hour = new Date().getHours();
return hour >= 6 && hour < 18;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/utils/backgroundEngine.ts` around lines 85 - 88, Update
isDaytime() to use the user's local hour via getHours() instead of UTC hours,
while preserving the existing 6-inclusive through 18-exclusive daytime window.

@krishkhinchi krishkhinchi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!!

@krishkhinchi
krishkhinchi merged commit 7a7b936 into 7-Blocks:main Jul 22, 2026
12 checks passed
@ecsoc-sentinel ecsoc-sentinel Bot added ECSoC26-L2 Level 2 contribution for the ECSoC26 event. and removed ECSoC26-L2 Level 2 contribution for the ECSoC26 event. labels Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI Artificial Intelligence and Machine Learning bug Something isn't working documentation Improvements or additions to documentation ECSoC26-L2 Level 2 contribution for the ECSoC26 event. ECSoC26 Official label for ECSoC26 event contributions. enhancement New feature or request frontend Frontend development size/XL Very large or complex contribution. type:bug Fixes an existing bug or unexpected behavior. type:documentation Improves project documentation. type:feature Introduces a new feature or enhancement. type:frontend Changes frontend or client-side code.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🌙 Dynamic Background Based on Space Weather and Orbital Conditions

3 participants