Skip to content

2025 Aurora Website Update#109

Merged
zangjiucheng merged 5 commits into
masterfrom
j7zang/homepage-2026
Sep 8, 2025
Merged

2025 Aurora Website Update#109
zangjiucheng merged 5 commits into
masterfrom
j7zang/homepage-2026

Conversation

@zangjiucheng

@zangjiucheng zangjiucheng commented Aug 25, 2025

Copy link
Copy Markdown
Member

This pull request updates the Home page to highlight Waterloo Rocketry's 2025 Aurora rocket milestone, improves the press release and About Us sections, and enhances the user experience for the gallery and media display. The most significant changes are grouped below.

Content and Press Release Updates:

  • Updated the About Us section to reflect the team's latest achievements, emphasizing the 2025 Aurora rocket launch and its impact on Canadian rocketry.
  • Revised the press release to focus on the Aurora rocket's record-breaking 2025 flight, including new launch details, outcomes, and acknowledgments to sponsors and the university. [1] [2]
  • Updated associated images and dates to match the new 2025 Aurora theme.

Media and Gallery UI Improvements:

  • Enhanced the Photo component in Gallery.jsx to open images in a modal overlay on click or keyboard activation, improving accessibility and user experience.
  • Improved media styling in Home.module.css for images in the media box, adding a hover/focus zoom effect, border radius, and better layout.

This change is Reviewable

Summary by CodeRabbit

  • New Features

    • Added Aurora rocket page with dedicated route and Rockets grid card.
    • Introduced click-to-zoom lightbox for photos.
  • Content

    • Updated Home page press release, imagery, alt text, and media links to reflect Aurora 2025 details and achievements.
  • Style

    • Enhanced media presentation with rounded corners, overflow handling, and subtle hover zoom/shadow effects.
  • Documentation

    • Added guidance on temporary image storage and migration to hosted image links.

@zangjiucheng zangjiucheng marked this pull request as draft August 26, 2025 08:15
@zangjiucheng zangjiucheng marked this pull request as ready for review August 28, 2025 16:55
…and update documentation with 2025 project report links
@zangjiucheng zangjiucheng changed the title Homepage 2025 Aurora Launch 2025 Aurora Website Update Aug 30, 2025

@ChrisYx511 ChrisYx511 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

some points, did not review content, will leave this to Luca

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why don't we just upload these to Flickr instead of temp.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, I asked Alexis before. He mentioned that will be uploaded much later. So instead we will use temp folder for website update in early stage, later after they process all the photos. We can switch to Flicker.

Comment thread src/img/temp/README.md

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

See above for comment for temp folder.

@coderabbitai

coderabbitai Bot commented Sep 6, 2025

Copy link
Copy Markdown

Walkthrough

Adds a lightbox/modal for Photo clicks in Gallery, updates Home content/assets and styles, introduces an Aurora rocket page and route, adds Aurora to the Rockets grid, and includes a README for temporary images. No exported API signature changes except adding the Aurora component.

Changes

Cohort / File(s) Summary of changes
Gallery lightbox interaction
src/components/Gallery/Gallery.jsx
Wraps Photo in a clickable, keyboard-accessible div; adds handleClick to create/remove a full-screen overlay with the image via direct DOM manipulation. No interface changes to exported components.
Routing and new Aurora page
src/index.jsx, src/routes/Rockets.jsx, src/routes/rocketPages/Aurora.jsx
Registers new route rockets/aurora; adds Aurora card to Rockets grid with image metadata; introduces a new static Aurora page component with specs, details, photo/video galleries.
Home content and media updates
src/routes/Home.jsx, src/routes/css/Home.module.css
Updates images, press release date/headline/body, and media links; adds image hover effects and container styling (overflow hidden, border radius) for media boxes.
Documentation
src/img/temp/README.md
Adds notes on temporary image storage and cleanup after Flickr uploads.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant P as Photo (Gallery)
  participant D as Document
  participant O as Overlay <div>
  participant I as <img>

  U->>P: Click or Enter
  P->>D: createElement('div') as overlay
  P->>D: createElement('img') with src/alt
  P->>O: Append I
  P->>D: Append O to body
  Note over O: Full-screen, semi-transparent background<br/>img max 90% viewport
  U->>O: Click overlay
  O->>D: Remove overlay from body
Loading
sequenceDiagram
  autonumber
  participant U as User
  participant R as Router
  participant Pg as Page
  participant A as Aurora

  U->>R: Navigate to /rockets/aurora
  R->>Pg: Render Page(title="Aurora")
  Pg->>A: Render Aurora component
  A-->>U: Static content (specs, details, galleries)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A hop and a click—now photos gleam bright,
Aurora gets routing, a star in the night.
Home’s headline refreshed, CSS with flair,
Rockets all lined, with a new card to share.
In temp we stash pics, till Flickr takes flight—
Ship it, I thump! What a delightful sight. 🐇🚀

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch j7zang/homepage-2026

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.

@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

Caution

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

⚠️ Outside diff range comments (1)
src/routes/Home.jsx (1)

69-72: Broken alt text and ignored style on Photo.

Photo expects altText and doesn’t consume style; current alt is dropped, harming a11y. Wrap to keep rounding and pass altText.

-<Photo link={aboutUsImage1} alt="About Us 1" style={{ borderRadius: '70%' }} />
+<div style={{ borderRadius: '70%', overflow: 'hidden' }}>
+  <Photo link={aboutUsImage1} altText="About Us 1" />
+</div>
♻️ Duplicate comments (1)
src/img/temp/README.md (1)

1-3: Clarify retention policy and guard against accidental commits to temp/

Add an explicit time-bound policy and a pointer to delete-or-block local images on merge. Also add a folder-scoped .gitignore to only allow README.md.

Apply within this file:

 ### Temporary Image Storage

-This folder temporarily stores images that have not yet been uploaded to Flickr. Once the images are uploaded, update the website to use the Flickr links and remove these local files.
+This folder temporarily stores images that have not yet been uploaded to Flickr. Once uploaded to Flickr, update the website to use Flickr links and remove these local files.
+
+Retention: do not keep images here beyond the duration of a PR. On merge to master, there should be no images left in this folder.
+Note: large binaries bloat the repo; prefer Flickr links and remove local copies as soon as possible.

New file suggestion (outside this hunk):

# src/img/temp/.gitignore
# Block everything except the README
*
!.gitignore
!README.md
🧹 Nitpick comments (10)
src/components/Gallery/Gallery.jsx (2)

49-55: Enable Space key activation and prevent page scroll

Support native button keyboard semantics.

-    <div
-      onClick={handleClick}
-      onKeyDown={(e) => e.key === 'Enter' && handleClick()}
+    <div
+      onClick={handleClick}
+      onKeyDown={(e) => {
+        if (e.key === 'Enter' || e.key === ' ') {
+          e.preventDefault();
+          handleClick();
+        }
+      }}
       role="button"
       tabIndex={0}
       style={{ cursor: 'pointer' }}
     >

18-58: Consider using a React Portal/modal instead of manual DOM manipulation

React state + a portal (or react-bootstrap’s Modal) will simplify cleanup, handle focus trapping, aria attributes, and ESC by default.

I can convert Photo to a small Portal-based lightbox or wire up react-bootstrap Modal if you prefer.

src/routes/Rockets.jsx (1)

19-132: Optional: refactor to a data-driven Rockets list

Reduce duplication by mapping an array of rocket metadata to RocketCard entries; easier to insert future rockets in order.

I can provide a quick refactor snippet if helpful.

src/routes/css/Home.module.css (2)

44-46: Nice containment; also round embedded videos.

Add rounding to iframes so video corners match the container.

 .mediaBox {
   ...
   overflow: hidden;
   border-radius: 6px;
 }
+
+.mediaBox iframe {
+  border-radius: 6px;
+}

48-56: Respect reduced motion preferences.

Disable hover zoom for users with prefers-reduced-motion.

 .mediaBox img {
   width: 100%;
   max-width: 400px;
   height: auto;
   display: block;
   margin: 0 auto;
   transition: transform 220ms ease, box-shadow 220ms ease;
   transform-origin: center center;
 }
+
+@media (prefers-reduced-motion: reduce) {
+  .mediaBox img {
+    transition: none;
+  }
+}
src/index.jsx (1)

80-84: Route added correctly; consider cleaning up v6 “exact”.

In React Router v6, exact is a no-op. Consider removing it (here or consistently across the file) in a follow-up.

src/routes/Home.jsx (2)

79-79: Date format consistency.

Consider standardizing dates (e.g., “August 24, 2025” or “2025‑08‑24”) across the site.


118-120: Make iframe title more descriptive.

“Rocket Launch” is generic. Use a descriptive title to improve a11y.

-<Video link="https://www.youtube.com/embed/vRShaLdex7Q?si=k5kqdmuP8fEYu2LC" title="Rocket Launch" />
+<Video link="https://www.youtube.com/embed/vRShaLdex7Q?si=k5kqdmuP8fEYu2LC" title="Aurora — Launch Canada 2025" />
src/routes/rocketPages/Aurora.jsx (2)

43-56: Specs: consider adding metric equivalents.

Adding SI alongside imperial improves clarity for a broader audience.

Example: Diameter: 8" (203 mm); Length: 16 ft (4.88 m); Wet Mass: ~253 lb (~115 kg); Apogee: ~38,000 ft (~11.6 km).


194-205: Photos: good alt texts; consider lazy-loading.

Optional: add loading="lazy" to non-critical images (component-level) to improve performance.

I can update the Gallery Photo component to pass loading="lazy" and keep the modal behavior.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f006f22 and 6091e5b.

⛔ Files ignored due to path filters (1)
  • public/pdfs/2025_project_report.pdf is excluded by !**/*.pdf
📒 Files selected for processing (7)
  • src/components/Gallery/Gallery.jsx (1 hunks)
  • src/img/temp/README.md (1 hunks)
  • src/index.jsx (2 hunks)
  • src/routes/Home.jsx (4 hunks)
  • src/routes/Rockets.jsx (2 hunks)
  • src/routes/css/Home.module.css (1 hunks)
  • src/routes/rocketPages/Aurora.jsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
src/index.jsx (2)
src/components/Page.jsx (1)
  • Page (5-14)
src/routes/rocketPages/Aurora.jsx (1)
  • Aurora (16-226)
src/routes/Rockets.jsx (1)
src/components/RocketCard/RocketCard.jsx (1)
  • RocketCard (13-32)
src/routes/css/Home.module.css (1)
src/components/ImageBox/ImageBox.jsx (1)
  • div (7-15)
src/routes/rocketPages/Aurora.jsx (6)
src/components/RocketPageOutline/RocketPageOutline.jsx (1)
  • RocketPageOutline (8-39)
src/components/Content/Content.jsx (1)
  • Content (6-16)
src/components/SpecsComponent/SpecsComponent.jsx (1)
  • SpecsComponent (49-80)
src/components/DividerLine/DividerLine.jsx (1)
  • DividerLine (6-10)
src/components/TwoColumns/TwoColumns.jsx (1)
  • TwoColumns (6-16)
src/components/Gallery/Gallery.jsx (3)
  • Gallery (71-96)
  • Photo (18-59)
  • Video (61-69)
src/routes/Home.jsx (2)
src/components/Gallery/Gallery.jsx (2)
  • Photo (18-59)
  • Video (61-69)
src/routes/Competition.jsx (1)
  • CoverPhoto (13-55)
🔇 Additional comments (8)
src/routes/Rockets.jsx (2)

6-6: Asset exists and size acceptable
aurora-2025.webp found at src/img/rocket/aurora-2025.webp (85 010 bytes), which is within acceptable limits.


24-32: LGTM: Aurora card wiring verified
Route "rockets/aurora" is registered in src/index.jsx (lines 82–84) and renders <Aurora /> correctly.

src/index.jsx (1)

27-27: Aurora import looks good.

src/routes/Home.jsx (4)

21-21: Asset swap to Aurora image: OK.


23-23: Press image swap: OK.


50-64: Content update reads well; verify factual claims.

Claims like “first-ever liquid engine rocket” (2024) and “more than doubled the Canadian altitude record” (2025) should be confirmed against current records before publishing.


95-97: Double-check event date.

“Thursday, August 21st” aligns with 2025 calendars, but please verify it matches Launch Canada’s official schedule.

src/routes/rocketPages/Aurora.jsx (1)

25-38: Overview copy: fact-check key stats.

Verify height, thrust, apogee, and “doubling last year’s apogee” before publishing.

Comment on lines +19 to +46
const handleClick = () => {
const modal = document.createElement('div');
modal.style.position = 'fixed';
modal.style.top = '0';
modal.style.left = '0';
modal.style.width = '100vw';
modal.style.height = '100vh';
modal.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
modal.style.display = 'flex';
modal.style.justifyContent = 'center';
modal.style.alignItems = 'center';
modal.style.zIndex = '1000';

const img = document.createElement('img');
img.src = link;
img.alt = altText;
img.style.maxWidth = '90%';
img.style.maxHeight = '90%';
img.style.boxShadow = '0 0 10px rgba(255, 255, 255, 0.5)';

modal.appendChild(img);

modal.addEventListener('click', () => {
document.body.removeChild(modal);
});

document.body.appendChild(modal);
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Lightbox a11y: add Escape-to-close, focus return, aria-modal, and body scroll lock

Current modal cannot be closed via keyboard and doesn’t manage focus or background scroll.

Apply:

 const Photo = ({ link, altText }) => {
-  const handleClick = () => {
+  const handleClick = () => {
     const modal = document.createElement('div');
+    const originalOverflow = document.body.style.overflow;
+    const previouslyFocused = document.activeElement;
     modal.style.position = 'fixed';
     modal.style.top = '0';
     modal.style.left = '0';
     modal.style.width = '100vw';
     modal.style.height = '100vh';
     modal.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
     modal.style.display = 'flex';
     modal.style.justifyContent = 'center';
     modal.style.alignItems = 'center';
     modal.style.zIndex = '1000';
+    modal.setAttribute('role', 'dialog');
+    modal.setAttribute('aria-modal', 'true');
+    modal.setAttribute('aria-label', altText);
+    modal.tabIndex = -1;

     const img = document.createElement('img');
     img.src = link;
     img.alt = altText;
     img.style.maxWidth = '90%';
     img.style.maxHeight = '90%';
     img.style.boxShadow = '0 0 10px rgba(255, 255, 255, 0.5)';

-    modal.appendChild(img);
-
-    modal.addEventListener('click', () => {
-      document.body.removeChild(modal);
-    });
-
-    document.body.appendChild(modal);
+    modal.appendChild(img);
+    let onEsc;
+    const close = () => {
+      document.removeEventListener('keydown', onEsc);
+      document.body.style.overflow = originalOverflow;
+      if (document.body.contains(modal)) document.body.removeChild(modal);
+      if (previouslyFocused && previouslyFocused.focus) previouslyFocused.focus();
+    };
+    onEsc = (e) => { if (e.key === 'Escape') close(); };
+    modal.addEventListener('click', close);
+    document.addEventListener('keydown', onEsc);
+    document.body.style.overflow = 'hidden';
+    document.body.appendChild(modal);
+    if (modal.focus) modal.focus();
   };
📝 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
const handleClick = () => {
const modal = document.createElement('div');
modal.style.position = 'fixed';
modal.style.top = '0';
modal.style.left = '0';
modal.style.width = '100vw';
modal.style.height = '100vh';
modal.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
modal.style.display = 'flex';
modal.style.justifyContent = 'center';
modal.style.alignItems = 'center';
modal.style.zIndex = '1000';
const img = document.createElement('img');
img.src = link;
img.alt = altText;
img.style.maxWidth = '90%';
img.style.maxHeight = '90%';
img.style.boxShadow = '0 0 10px rgba(255, 255, 255, 0.5)';
modal.appendChild(img);
modal.addEventListener('click', () => {
document.body.removeChild(modal);
});
document.body.appendChild(modal);
};
const handleClick = () => {
const modal = document.createElement('div');
const originalOverflow = document.body.style.overflow;
const previouslyFocused = document.activeElement;
modal.style.position = 'fixed';
modal.style.top = '0';
modal.style.left = '0';
modal.style.width = '100vw';
modal.style.height = '100vh';
modal.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
modal.style.display = 'flex';
modal.style.justifyContent = 'center';
modal.style.alignItems = 'center';
modal.style.zIndex = '1000';
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', altText);
modal.tabIndex = -1;
const img = document.createElement('img');
img.src = link;
img.alt = altText;
img.style.maxWidth = '90%';
img.style.maxHeight = '90%';
img.style.boxShadow = '0 0 10px rgba(255, 255, 255, 0.5)';
- modal.appendChild(img);
-
- modal.addEventListener('click', () => {
- document.body.removeChild(modal);
- });
-
modal.appendChild(img);
let onEsc;
const close = () => {
document.removeEventListener('keydown', onEsc);
document.body.style.overflow = originalOverflow;
if (document.body.contains(modal)) document.body.removeChild(modal);
if (previouslyFocused && previouslyFocused.focus) previouslyFocused.focus();
};
onEsc = (e) => { if (e.key === 'Escape') close(); };
modal.addEventListener('click', close);
document.addEventListener('keydown', onEsc);
document.body.style.overflow = 'hidden';
document.body.appendChild(modal);
if (modal.focus) modal.focus();
};

Comment on lines +58 to +61
.mediaBox img:hover,
.mediaBox img:focus {
transform: scale(1.03); /* smaller zoom */
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Keyboard focus state won’t fire on the img.

The Photo component makes the wrapper div focusable, not the img. Update selectors so focus styles apply when the wrapper has focus.

-.mediaBox img:hover,
-.mediaBox img:focus {
+.mediaBox div:hover img,
+.mediaBox div:focus img,
+.mediaBox :focus-visible img {
   transform: scale(1.03); /* smaller zoom */
   box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
 }
📝 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
.mediaBox img:hover,
.mediaBox img:focus {
transform: scale(1.03); /* smaller zoom */
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
.mediaBox div:hover img,
.mediaBox div:focus img,
.mediaBox :focus-visible img {
transform: scale(1.03); /* smaller zoom */
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
}
🤖 Prompt for AI Agents
In src/routes/css/Home.module.css around lines 58 to 61, the focus selector
targets the img but the wrapper div is focusable, so the focus styles never
apply; update the selectors so the styles apply when the wrapper has focus
(e.g., change .mediaBox img:focus to .mediaBox:focus img or add .mediaBox:focus,
.mediaBox:focus img) so the transform and box-shadow activate when the wrapper
receives keyboard focus.

Comment on lines +212 to +222
link="https://www.youtube.com/embed/vRShaLdex7Q?si=G7P1eL1YxY9YqCTD"
title="Aurora — Launch Canada 2025"
/>
<Video
link="https://www.youtube.com/embed/65qts5k77M0?si=RCxH2PzIcWDhgeF7"
altText="Eridium - Static Fire #4"
/>
<Video
link="https://www.youtube.com/embed/iuZ5-Du1UfI?si=smPblQNGyaFRywxx"
altText="Playing Music from Portal on a Liquid Rocket Engine"
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Bug: Video uses altText prop; iframe gets no title.

Video expects title, not altText. As-is, the iframe title is undefined, hurting accessibility.

-        <Video
-          link="https://www.youtube.com/embed/65qts5k77M0?si=RCxH2PzIcWDhgeF7"
-          altText="Eridium - Static Fire #4"
-        />
+        <Video
+          link="https://www.youtube.com/embed/65qts5k77M0?si=RCxH2PzIcWDhgeF7"
+          title="Eridium — Static Fire #4"
+        />
-        <Video
-          link="https://www.youtube.com/embed/iuZ5-Du1UfI?si=smPblQNGyaFRywxx"
-          altText="Playing Music from Portal on a Liquid Rocket Engine"
-        />
+        <Video
+          link="https://www.youtube.com/embed/iuZ5-Du1UfI?si=smPblQNGyaFRywxx"
+          title="Playing Music from Portal on a Liquid Rocket Engine"
+        />
📝 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
link="https://www.youtube.com/embed/vRShaLdex7Q?si=G7P1eL1YxY9YqCTD"
title="Aurora — Launch Canada 2025"
/>
<Video
link="https://www.youtube.com/embed/65qts5k77M0?si=RCxH2PzIcWDhgeF7"
altText="Eridium - Static Fire #4"
/>
<Video
link="https://www.youtube.com/embed/iuZ5-Du1UfI?si=smPblQNGyaFRywxx"
altText="Playing Music from Portal on a Liquid Rocket Engine"
/>
<Video
link="https://www.youtube.com/embed/vRShaLdex7Q?si=G7P1eL1YxY9YqCTD"
title="Aurora — Launch Canada 2025"
/>
<Video
link="https://www.youtube.com/embed/65qts5k77M0?si=RCxH2PzIcWDhgeF7"
title="Eridium — Static Fire #4"
/>
<Video
link="https://www.youtube.com/embed/iuZ5-Du1UfI?si=smPblQNGyaFRywxx"
title="Playing Music from Portal on a Liquid Rocket Engine"
/>
🤖 Prompt for AI Agents
In src/routes/rocketPages/Aurora.jsx around lines 212 to 222 the Video
components use the prop altText instead of the expected title prop, which
results in the iframe receiving no title and breaks accessibility; change each
Video instance to pass a title prop (e.g., title="Eridium - Static Fire #4",
title="Playing Music from Portal on a Liquid Rocket Engine") instead of altText
so the iframe gets a proper title, and run a quick test or linter to confirm
prop types and a11y warnings are resolved.

@zangjiucheng zangjiucheng merged commit 1e79aea into master Sep 8, 2025
1 of 2 checks passed
@zangjiucheng zangjiucheng deleted the j7zang/homepage-2026 branch September 8, 2025 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants