Conversation
Replaces the placeholder home page with a full landing page including: - Hero section with animated webm demo, Space Grotesk headline font, and scroll animations - Student features, instructor, and feature showcase sections - Languages section with SVG logos - Open source / Eclipse Theia section - CTA section - Custom landing navbar, design tokens, and scroll reveal hook - Inline codicon SVGs for all icons (no npm package)
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughRefactors the landing page into modular React components (Hero, Features, Languages, Instructor, Open Source, CTA), adds landing design tokens and Google Fonts, introduces a scroll-reveal hook and LandingNavbar, and adds a Navbar wrapper that switches navbars on home routes. Changes
Sequence Diagram(s)sequenceDiagram
participant Browser
participant Router
participant NavbarWrapper
participant LandingNavbar
participant ThemeNavbar
participant LandingPage
participant IO as IntersectionObserver
Browser->>Router: navigate to URL
Router->>NavbarWrapper: render navbar for current pathname
alt pathname is home ("/" or "/Docs")
NavbarWrapper->>LandingNavbar: render landing navbar
else
NavbarWrapper->>ThemeNavbar: render default theme navbar (forward props)
end
Browser->>LandingPage: render landing components (Hero, Features, ...)
LandingPage->>IO: useScrollReveal attaches observer to sections
IO->>LandingPage: onIntersect -> add `.revealed` (after optional delay)
LandingPage->>Browser: CSS transitions run (reveal animations)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (7)
src/components/landing/Button.module.css (1)
1-43: Add explicit:focus-visiblestyles for keyboard accessibility.Please add a visible focus state for both button variants so keyboard navigation is consistently clear.
Suggested addition
.btnPrimary:hover { background: var(--landing-teal-dark); color: `#fff` !important; } + +.btnPrimary:focus-visible, +.btnSecondary:focus-visible { + outline: 2px solid var(--landing-teal); + outline-offset: 2px; +}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/landing/Button.module.css` around lines 1 - 43, The .btnPrimary and .btnSecondary styles lack an explicit keyboard-visible focus state; add matching :focus-visible rules for both (e.g., .btnPrimary:focus-visible and .btnSecondary:focus-visible) that provide a clear high-contrast outline or box-shadow while preserving border-radius and padding, avoid removing default focus unless replaced, and ensure the focus color/outline contrasts with the background (consistent with hover/active visuals) so keyboard users can clearly see focus.src/theme/Navbar/index.tsx (1)
11-13: Derive home-route detection from configuredbaseUrl(not hard-coded strings).
Line 12will become fragile ifbaseUrlchanges. Compute home matching fromsiteConfig.baseUrlto keep behavior consistent across deployments.Suggested refactor
import React from 'react'; import { useLocation } from '@docusaurus/router'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import NavbarOriginal from '@theme-original/Navbar'; @@ export default function NavbarWrapper(props: Props): React.JSX.Element { const { pathname } = useLocation(); - const isHome = pathname === '/' || pathname === '/Docs/' || pathname === '/Docs'; + const { + siteConfig: { baseUrl }, + } = useDocusaurusContext(); + const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl; + const isHome = pathname === baseUrl || pathname === normalizedBaseUrl;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/theme/Navbar/index.tsx` around lines 11 - 13, Replace the hard-coded home checks with a comparison against the configured baseUrl from Docusaurus: import/use useDocusaurusContext to get siteConfig.baseUrl, normalize it (ensure it has/doesn't have a trailing slash consistently), then compute isHome by comparing pathname to the normalized baseUrl and any expected variant (e.g., `${baseUrl}Docs` and `${baseUrl}Docs/`) instead of '/' and hard-coded '/Docs' strings. Update the code that currently uses useLocation, pathname and isHome so it references siteConfig.baseUrl (via useDocusaurusContext) and performs normalized equality checks.src/components/landing/HeroSection.tsx (1)
33-33: UseuseBaseUrlfor the demo video path.
Line 33hard-codes'/Docs/', which couples the component to one deployment path. Resolve the asset with Docusaurus base-url helpers.Suggested refactor
import Button from './Button'; +import useBaseUrl from '@docusaurus/useBaseUrl'; import styles from './HeroSection.module.css'; @@ export default function HeroSection() { + const demoVideoSrc = useBaseUrl('/videos/artemis-theia-e2e.webm'); return ( @@ - src="/Docs/videos/artemis-theia-e2e.webm" + src={demoVideoSrc}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/landing/HeroSection.tsx` at line 33, The video src is hard-coded to '/Docs/videos/...' in the HeroSection component; import and use Docusaurus' useBaseUrl hook in HeroSection.tsx, call const videoSrc = useBaseUrl('/Docs/videos/artemis-theia-e2e.webm') inside the component (or compute it where props/state live), and replace the src attribute with videoSrc so the asset resolves against the current base URL; ensure you add the import from '@docusaurus/useBaseUrl' and update any JSX referencing the literal path to use the resolved videoSrc.src/components/landing/LanguagesSection.module.css (1)
63-67: Remove redundant mobile media block (no-op duplicate).This repeats the same
grid-template-columns: repeat(2, 1fr)already applied at a wider breakpoint.♻️ Proposed cleanup
`@media` (max-width: 820px) { .inner { grid-template-columns: 1fr; gap: 2.5rem; } .langGrid { grid-template-columns: repeat(2, 1fr); } } - -@media (max-width: 480px) { - .langGrid { - grid-template-columns: repeat(2, 1fr); - } -}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/landing/LanguagesSection.module.css` around lines 63 - 67, The media query that sets .langGrid { grid-template-columns: repeat(2, 1fr); } for (max-width: 480px) is redundant because the same rule is already applied at a wider breakpoint; remove this duplicate media block from LanguagesSection.module.css so .langGrid’s layout is governed by the existing breakpoint only, or if a different mobile layout was intended, change the inner grid-template-columns value rather than duplicating the same rule.src/components/landing/OpenSourceSection.module.css (1)
42-45: Differentiate teal/orange icon variants.
iconColoris passed from TSX, but both classes currently render the same color, so the variant prop has no visual impact.🎨 Example refinement
-.iconTeal, -.iconOrange { - color: var(--landing-text); -} +.iconTeal { + color: var(--landing-teal-dark); + background: var(--landing-teal-light); +} + +.iconOrange { + color: var(--landing-orange-dark); + background: var(--landing-orange-light); +}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/landing/OpenSourceSection.module.css` around lines 42 - 45, The .iconTeal and .iconOrange classes currently both use var(--landing-text) so the iconColor prop has no effect; update the CSS to assign distinct color values (e.g. var(--landing-accent-teal) for .iconTeal and var(--landing-accent-orange) for .iconOrange or explicit hex values) and ensure the TSX uses the iconColor prop to toggle those classes (reference the .iconTeal and .iconOrange class names and the iconColor prop/variant in the component that renders the icon).src/components/landing/StudentFeatures.module.css (1)
19-35: Subpixel border width may render inconsistently.
0.5pxborders can render as 0px or 1px depending on the browser, display density, and zoom level. Consider using1pxfor consistent rendering across devices.Suggested fix
.featureCard { flex: 1; - border: 0.5px solid var(--landing-border); + border: 1px solid var(--landing-border); border-radius: 14px; padding: 1.4rem; background: var(--ifm-background-color); transition: border-color 0.15s; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/landing/StudentFeatures.module.css` around lines 19 - 35, Replace the inconsistent subpixel border on .featureCard by changing the base border from 0.5px to 1px (update the rule that currently reads "border: 0.5px solid ...") and adjust the highlighted state (.featureCard.highlight) to a whole-pixel thicker width (for example change the current border-width 1.5px to 2px) so hover/highlight differences remain visually distinct and render consistently across devices.src/pages/index.module.css (1)
8-13: Same subpixel border consideration applies here.For consistency with the earlier suggestion, consider using
1pxinstead of0.5pxfor the section divider border.Suggested fix
.sectionDivider { border: none; - border-top: 0.5px solid var(--landing-border); + border-top: 1px solid var(--landing-border); max-width: 1100px; margin: 0 auto; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/index.module.css` around lines 8 - 13, Update the .sectionDivider CSS rule to use a 1px border-top instead of 0.5px to avoid subpixel rendering inconsistencies; locate the .sectionDivider selector in src/pages/index.module.css (the rule that currently sets border-top: 0.5px solid var(--landing-border)) and change that value to 1px while keeping the rest of the declaration intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docusaurus.config.ts`:
- Around line 9-11: The stylesheets entry in docusaurus.config.ts currently
loads Google Fonts; remove that external URL and instead add local font files to
your repo and declare them via `@font-face` in your custom CSS (e.g., custom.css),
then reference the local CSS from the config (replace the external URL in the
stylesheets array with the local stylesheet). Ensure the `@font-face` rules point
to the committed font files and that the font-family names match the existing
usage in your site styles.
In `@src/components/landing/HeroSection.module.css`:
- Around line 68-82: The keyframe names use camelCase and violate the Stylelint
keyframes-name-pattern; rename all keyframes to kebab-case (e.g., change
heroFadeUp -> hero-fade-up and heroFadeIn -> hero-fade-in) and update any usages
(animation, animation-name) that reference those names (search for heroFadeUp,
heroFadeIn and the other listed keyframe identifiers at lines ~96, ~114, ~130,
~138-143) so selectors and animation declarations match the new kebab-case
identifiers.
In `@src/components/landing/InstructorSection.tsx`:
- Line 58: The image src in the InstructorSection component is hardcoded to
"/Docs/img/marketing/scorpio.png"; replace this with a baseUrl-aware path by
importing and calling useBaseUrl (as used in LandingNavbar) and passing the
relative path "Docs/img/marketing/scorpio.png" (or "img/marketing/scorpio.png"
depending on your assets dir) through useBaseUrl to generate the src for the
<img> rendered by InstructorSection so the asset resolves correctly when baseUrl
changes.
In `@src/components/landing/LanguagesSection.tsx`:
- Around line 10-16: The languages array in LanguagesSection.tsx currently uses
hardcoded "/Docs/img/marketing/..." paths which break when baseUrl changes;
import useBaseUrl from "@docusaurus/useBaseUrl" in the LanguagesSection
component and call it for each logo path (e.g., replace the static logoSrc
values in the languages const with calls to useBaseUrl('/img/marketing/xxx.svg')
or compute them when the component mounts), ensuring all references to logoSrc
(used when rendering the list) use the resolved URL from useBaseUrl rather than
the "/Docs" prefix.
In `@src/components/landing/OpenSourceSection.tsx`:
- Line 53: In the OpenSourceSection component update the two misspelled
user-facing strings: change "edu ide" to the proper branding "edu IDE" and
correct "Ecplise Source" to "Eclipse Source" (or the project's intended "Open
Source" wording if that was the intent); locate the string literals inside the
OpenSourceSection.tsx component (the displayed copy around the two occurrences)
and replace them with the corrected spellings so the UI shows the proper names.
In `@src/components/landing/SectionHeader.tsx`:
- Around line 4-19: The SectionHeader component lacks a heading id, so
aria-labelledby consumers can't reference its <h2>; update SectionHeaderProps to
include a headingId: string (optional or required per your choice), accept
headingId in the SectionHeader function signature, and add that as the id
attribute on the rendered <h2> (the element rendered by SectionHeader / symbol:
SectionHeader, SectionHeaderProps); then update sections that use
aria-labelledby to pass matching values like "students-heading",
"instructors-heading", "opensource-heading".
In `@src/components/landing/StudentFeatures.module.css`:
- Around line 66-69: The CSS classes .iconTeal and .iconOrange are misleading
because they both set color: var(--landing-text); update
StudentFeatures.module.css so .iconTeal uses var(--landing-teal) and .iconOrange
uses var(--landing-orange) (or consolidate into a single .icon class and update
StudentFeatures.tsx to stop toggling by iconColor) so the styles match the
conditional in StudentFeatures.tsx that applies the classes based on the
iconColor prop.
In `@src/components/landing/StudentFeatures.tsx`:
- Around line 85-90: The useScrollReveal hook schedules setTimeout but doesn't
capture or clear the timer, causing callbacks to run after unmount; update the
hook implementation in src/hooks/useScrollReveal.ts (used by RevealCard and
other components) to store the timer ID (const timeoutId =
window.setTimeout(...)) and call clearTimeout(timeoutId) in the useEffect
cleanup (return () => { clearTimeout(timeoutId); observer.disconnect(); }) so
the reveal callback won't run on detached nodes and resources are cleaned up.
In `@src/hooks/useScrollReveal.ts`:
- Around line 21-23: In useScrollReveal, the setTimeout calls (e.g., the one
that adds 'revealed' to el when delay > 0 and the similar one around lines
33-34) create timers that aren’t cleared; store each timer id (let timer =
setTimeout(...)) and return a cleanup that calls clearTimeout(timer) and also
removes any added classes or observers as appropriate so the timeout cannot run
against a stale DOM element; update both occurrences (the delay > 0 branch and
the other delayed call) to follow this pattern and reference the same cleanup
returned by useEffect.
---
Nitpick comments:
In `@src/components/landing/Button.module.css`:
- Around line 1-43: The .btnPrimary and .btnSecondary styles lack an explicit
keyboard-visible focus state; add matching :focus-visible rules for both (e.g.,
.btnPrimary:focus-visible and .btnSecondary:focus-visible) that provide a clear
high-contrast outline or box-shadow while preserving border-radius and padding,
avoid removing default focus unless replaced, and ensure the focus color/outline
contrasts with the background (consistent with hover/active visuals) so keyboard
users can clearly see focus.
In `@src/components/landing/HeroSection.tsx`:
- Line 33: The video src is hard-coded to '/Docs/videos/...' in the HeroSection
component; import and use Docusaurus' useBaseUrl hook in HeroSection.tsx, call
const videoSrc = useBaseUrl('/Docs/videos/artemis-theia-e2e.webm') inside the
component (or compute it where props/state live), and replace the src attribute
with videoSrc so the asset resolves against the current base URL; ensure you add
the import from '@docusaurus/useBaseUrl' and update any JSX referencing the
literal path to use the resolved videoSrc.
In `@src/components/landing/LanguagesSection.module.css`:
- Around line 63-67: The media query that sets .langGrid {
grid-template-columns: repeat(2, 1fr); } for (max-width: 480px) is redundant
because the same rule is already applied at a wider breakpoint; remove this
duplicate media block from LanguagesSection.module.css so .langGrid’s layout is
governed by the existing breakpoint only, or if a different mobile layout was
intended, change the inner grid-template-columns value rather than duplicating
the same rule.
In `@src/components/landing/OpenSourceSection.module.css`:
- Around line 42-45: The .iconTeal and .iconOrange classes currently both use
var(--landing-text) so the iconColor prop has no effect; update the CSS to
assign distinct color values (e.g. var(--landing-accent-teal) for .iconTeal and
var(--landing-accent-orange) for .iconOrange or explicit hex values) and ensure
the TSX uses the iconColor prop to toggle those classes (reference the .iconTeal
and .iconOrange class names and the iconColor prop/variant in the component that
renders the icon).
In `@src/components/landing/StudentFeatures.module.css`:
- Around line 19-35: Replace the inconsistent subpixel border on .featureCard by
changing the base border from 0.5px to 1px (update the rule that currently reads
"border: 0.5px solid ...") and adjust the highlighted state
(.featureCard.highlight) to a whole-pixel thicker width (for example change the
current border-width 1.5px to 2px) so hover/highlight differences remain
visually distinct and render consistently across devices.
In `@src/pages/index.module.css`:
- Around line 8-13: Update the .sectionDivider CSS rule to use a 1px border-top
instead of 0.5px to avoid subpixel rendering inconsistencies; locate the
.sectionDivider selector in src/pages/index.module.css (the rule that currently
sets border-top: 0.5px solid var(--landing-border)) and change that value to 1px
while keeping the rest of the declaration intact.
In `@src/theme/Navbar/index.tsx`:
- Around line 11-13: Replace the hard-coded home checks with a comparison
against the configured baseUrl from Docusaurus: import/use useDocusaurusContext
to get siteConfig.baseUrl, normalize it (ensure it has/doesn't have a trailing
slash consistently), then compute isHome by comparing pathname to the normalized
baseUrl and any expected variant (e.g., `${baseUrl}Docs` and `${baseUrl}Docs/`)
instead of '/' and hard-coded '/Docs' strings. Update the code that currently
uses useLocation, pathname and isHome so it references siteConfig.baseUrl (via
useDocusaurusContext) and performs normalized equality checks.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ab2bcb43-29a0-4d44-a789-ce6a36cb19b5
⛔ Files ignored due to path filters (9)
static/img/marketing/C_Programming_Language.svgis excluded by!**/*.svgstatic/img/marketing/OCaml_Sticker.svgis excluded by!**/*.svgstatic/img/marketing/java-svgrepo-com.svgis excluded by!**/*.svgstatic/img/marketing/javascript-svgrepo-com.svgis excluded by!**/*.svgstatic/img/marketing/page.pngis excluded by!**/*.pngstatic/img/marketing/python-svgrepo-com.svgis excluded by!**/*.svgstatic/img/marketing/rust-svgrepo-com.svgis excluded by!**/*.svgstatic/img/marketing/scorpio.pngis excluded by!**/*.pngstatic/videos/artemis-theia-e2e.webmis excluded by!**/*.webm
📒 Files selected for processing (26)
docusaurus.config.tssrc/components/landing/Button.module.csssrc/components/landing/Button.tsxsrc/components/landing/CtaSection.module.csssrc/components/landing/CtaSection.tsxsrc/components/landing/FeatureShowcase.module.csssrc/components/landing/FeatureShowcase.tsxsrc/components/landing/HeroSection.module.csssrc/components/landing/HeroSection.tsxsrc/components/landing/InstructorSection.module.csssrc/components/landing/InstructorSection.tsxsrc/components/landing/LandingNavbar.module.csssrc/components/landing/LandingNavbar.tsxsrc/components/landing/LanguagesSection.module.csssrc/components/landing/LanguagesSection.tsxsrc/components/landing/OpenSourceSection.module.csssrc/components/landing/OpenSourceSection.tsxsrc/components/landing/SectionHeader.module.csssrc/components/landing/SectionHeader.tsxsrc/components/landing/StudentFeatures.module.csssrc/components/landing/StudentFeatures.tsxsrc/css/custom.csssrc/hooks/useScrollReveal.tssrc/pages/index.module.csssrc/pages/index.tsxsrc/theme/Navbar/index.tsx
| .iconTeal, | ||
| .iconOrange { | ||
| color: var(--landing-text); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check how these icon classes are used in the StudentFeatures component
rg -n "iconTeal|iconOrange" --type tsx --type tsRepository: EduIDE/Docs
Length of output: 82
🏁 Script executed:
# Search for uses of iconTeal and iconOrange with proper file extensions
rg -n "iconTeal|iconOrange" --type js --type jsx --type ts --type cssRepository: EduIDE/Docs
Length of output: 82
🏁 Script executed:
# Also check the StudentFeatures component directly
find . -name "*StudentFeatures*" -type f | head -20Repository: EduIDE/Docs
Length of output: 151
🏁 Script executed:
# Look at the CSS file to understand the context better
cat -n src/components/landing/StudentFeatures.module.css | head -80Repository: EduIDE/Docs
Length of output: 1982
🏁 Script executed:
# Check for CSS variable definitions in the project
rg "var(--landing-teal|--landing-orange|--landing-text)" --type cssRepository: EduIDE/Docs
Length of output: 37
🏁 Script executed:
# Check the StudentFeatures.tsx component to see how these classes are used
cat -n src/components/landing/StudentFeatures.tsxRepository: EduIDE/Docs
Length of output: 4684
🏁 Script executed:
# Search for CSS variable definitions, checking the entire CSS file
rg "landing-teal|landing-orange|landing-text" --type css -A 1 -B 1Repository: EduIDE/Docs
Length of output: 8958
Icon color classes have misleading names that don't match their styling.
In StudentFeatures.tsx (line 74), the component conditionally applies .iconTeal or .iconOrange based on the iconColor prop, but both classes apply the same color (var(--landing-text)). Their names suggest they should visually differentiate between teal and orange icons. Either apply distinct colors using the available CSS variables (var(--landing-teal) and var(--landing-orange)), or consolidate into a single class if no visual distinction is intended.
Suggested fix if distinct colors are intended
-.iconTeal,
-.iconOrange {
- color: var(--landing-text);
-}
+.iconTeal {
+ color: var(--landing-teal);
+}
+
+.iconOrange {
+ color: var(--landing-orange);
+}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/landing/StudentFeatures.module.css` around lines 66 - 69, The
CSS classes .iconTeal and .iconOrange are misleading because they both set
color: var(--landing-text); update StudentFeatures.module.css so .iconTeal uses
var(--landing-teal) and .iconOrange uses var(--landing-orange) (or consolidate
into a single .icon class and update StudentFeatures.tsx to stop toggling by
iconColor) so the styles match the conditional in StudentFeatures.tsx that
applies the classes based on the iconColor prop.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/components/landing/FeatureShowcase.tsx (1)
36-38: Defer media loading to reduce landing-page payload.Line 36 and Line 38 currently load media eagerly. For multiple showcase blocks, this can inflate initial load cost. Add lazy/media preload hints.
♻️ Suggested diff
- <video src={mediaSrc} autoPlay loop muted playsInline aria-label={mediaAlt} /> + <video + src={mediaSrc} + autoPlay + loop + muted + playsInline + preload="metadata" + aria-label={mediaAlt} + /> ) : ( - <img src={mediaSrc} alt={mediaAlt ?? ''} /> + <img src={mediaSrc} alt={mediaAlt ?? ''} loading="lazy" decoding="async" /> )}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/landing/FeatureShowcase.tsx` around lines 36 - 38, The media elements in FeatureShowcase (the <video> rendered when mediaSrc is a video and the <img> rendered otherwise) are loading eagerly; add lazy-loading hints by adding loading="lazy" and fetchPriority="low" to the <img> (use mediaAlt and mediaSrc as now) and add preload="metadata" and fetchPriority="low" to the <video>; for better deferred autoplay of videos consider wiring an IntersectionObserver in FeatureShowcase to only call play() or render the <video> when it's in viewport (use the existing mediaSrc, mediaAlt and the component render path to locate where to insert these attributes/observer logic).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/components/landing/FeatureShowcase.tsx`:
- Around line 36-38: The media elements in FeatureShowcase (the <video> rendered
when mediaSrc is a video and the <img> rendered otherwise) are loading eagerly;
add lazy-loading hints by adding loading="lazy" and fetchPriority="low" to the
<img> (use mediaAlt and mediaSrc as now) and add preload="metadata" and
fetchPriority="low" to the <video>; for better deferred autoplay of videos
consider wiring an IntersectionObserver in FeatureShowcase to only call play()
or render the <video> when it's in viewport (use the existing mediaSrc, mediaAlt
and the component render path to locate where to insert these
attributes/observer logic).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 8da66353-3db7-4287-aa01-ffbd20b100d0
⛔ Files ignored due to path filters (3)
static/videos/run-button.webmis excluded by!**/*.webmstatic/videos/scorpio.webmis excluded by!**/*.webmstatic/videos/terminal-assistant.webmis excluded by!**/*.webm
📒 Files selected for processing (3)
src/components/landing/FeatureShowcase.module.csssrc/components/landing/FeatureShowcase.tsxsrc/pages/index.tsx
✅ Files skipped from review due to trivial changes (1)
- src/components/landing/FeatureShowcase.module.css
🚧 Files skipped from review as they are similar to previous changes (1)
- src/pages/index.tsx
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/pages/index.tsx (1)
22-51: Consider data-driving theFeatureShowcaseblocks.The three showcase sections are structurally identical; using a small config array +
.map()would reduce repetition and future edit drift.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/index.tsx` around lines 22 - 51, The three repeated FeatureShowcase blocks should be data-driven: create a small array (e.g., featureShowcases) of objects containing the props (label, title, description, mediaSrc, mediaAlt, mediaType, accentColor, reverse) and then render them via featureShowcases.map(...) to return <FeatureShowcase ... /> for each item, inserting the <hr className={styles.sectionDivider} /> between items (or render it conditionally inside the map for all but the last index); update references in this file to use the new array and the FeatureShowcase component name to eliminate duplication.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/pages/index.tsx`:
- Line 21: The decorative <hr> elements in the Home page should be hidden from
assistive tech: update each <hr> in src/pages/index.tsx (inside the Home
component/JSX) to include an accessibility attribute such as aria-hidden="true"
(or role="presentation"/role="none") so screen readers ignore these separators
while preserving visual styling.
---
Nitpick comments:
In `@src/pages/index.tsx`:
- Around line 22-51: The three repeated FeatureShowcase blocks should be
data-driven: create a small array (e.g., featureShowcases) of objects containing
the props (label, title, description, mediaSrc, mediaAlt, mediaType,
accentColor, reverse) and then render them via featureShowcases.map(...) to
return <FeatureShowcase ... /> for each item, inserting the <hr
className={styles.sectionDivider} /> between items (or render it conditionally
inside the map for all but the last index); update references in this file to
use the new array and the FeatureShowcase component name to eliminate
duplication.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 927f6ef0-dfcf-4e6a-ac0c-d3ee15b9f48a
⛔ Files ignored due to path filters (1)
static/img/theia.svgis excluded by!**/*.svg
📒 Files selected for processing (7)
src/components/landing/CtaSection.module.csssrc/components/landing/FeatureShowcase.tsxsrc/components/landing/InstructorSection.tsxsrc/components/landing/LanguagesSection.tsxsrc/components/landing/OpenSourceSection.module.csssrc/components/landing/OpenSourceSection.tsxsrc/pages/index.tsx
✅ Files skipped from review due to trivial changes (5)
- src/components/landing/InstructorSection.tsx
- src/components/landing/LanguagesSection.tsx
- src/components/landing/CtaSection.module.css
- src/components/landing/OpenSourceSection.tsx
- src/components/landing/OpenSourceSection.module.css
🚧 Files skipped from review as they are similar to previous changes (1)
- src/components/landing/FeatureShowcase.tsx
…m roles - Add id prop to SectionHeader and wire it from StudentFeatures, InstructorSection, and OpenSourceSection so aria-labelledby resolves - Wrap decorative ↗ arrow in aria-hidden span in OpenSourceSection - Move role=listitem onto OssCardItem directly, removing the wrapper div
Store the timer handle so it can be cleared in the effect cleanup, preventing a stale callback from firing on a detached element after the component unmounts during the delay window.
…eo poster fallbacks - HeroSection, InstructorSection, and LanguagesSection now route all media paths through useBaseUrl so they work regardless of the site base URL configuration - Add poster attribute to video elements (hero and feature showcases) so an image is displayed while videos load or if they fail - Add mediaPoster prop to FeatureShowcase to thread poster values through - Add symmetric return to useDeferredSrc readyState branch for consistent cleanup behaviour - Wrap decorative → arrow in FeatureShowcase in aria-hidden span - Move role=listitem onto LangItem directly, removing the wrapper div
Summary
Components added
HeroSection— headline, subtext, and CTA buttonsStudentFeatures— key student-facing feature cardsInstructorSection— instructor-focused featuresFeatureShowcase— alternating text/video sections with deferred video loadingLanguagesSection— supported language logosOpenSourceSection— OSS cards + Eclipse Theia prominent block with upstream contributionsCtaSection— bottom call-to-actionLandingNavbar— custom navbar override for the landing pageSectionHeader,Button,useScrollReveal— shared utilitiesSummary by CodeRabbit
New Features
Style