Skip to content

Hotfix#262

Open
deeg454 wants to merge 83 commits into
devfrom
hotfix
Open

Hotfix#262
deeg454 wants to merge 83 commits into
devfrom
hotfix

Conversation

@deeg454

@deeg454 deeg454 commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

What

  • removal of register link and added volunteer link in the home page

Summary by CodeRabbit

  • New Features
    • Added/expanded the event website experience with new landing sections (map, FAQ, sponsors, team, footer) and ticket/QR-based dashboard views.
    • Introduced a dedicated FAQ page with animated FAQ content.
    • Added Cloudflare/OpenNext workflow support for preview/deploy/upload.
  • UI & Branding
    • Refreshed typography, colors, imagery, focus states, and multiple page layouts (including mobile navigation).
  • Bug Fixes / Behavior
    • Registration and RSVP availability now follow the live event configuration more consistently.
  • Admin / Toggles
    • Removed several admin toggle management pages and related controls.

MKorolyova and others added 30 commits March 21, 2026 18:39
partner section, partners must be updated later
…in component, implement useFindPosition hook to calculate overlay positions
implement  map section with dynamic pin positioning, create reusable …
@deeg454 deeg454 requested a review from MKorolyova July 15, 2026 01:00
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4f1c4bb8-3b47-4025-8fbd-cd3cfaba7f91

📥 Commits

Reviewing files that changed from the base of the PR and between 4a8abb9 and efd557c.

📒 Files selected for processing (1)
  • apps/web/src/components/landing/Hero.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/src/components/landing/Hero.tsx

📝 Walkthrough

Walkthrough

The PR redesigns the landing page, dashboard, event pass, FAQ, navigation, and registration experiences. It adds OpenNext Cloudflare deployment support, replaces Redis-backed public settings with static configuration, updates database clients and theme tokens, and introduces new visual assets.

Changes

Platform redesign and runtime migration

Layer / File(s) Summary
Runtime and deployment configuration
.env.example, apps/web/open-next.config.ts, apps/web/package.json, apps/web/wrangler.toml, packages/db/*, packages/config/hackkit.config.ts
Adds OpenNext/Cloudflare scripts and configuration, updates environment handling, separates edge and Node database clients, and changes hackathon metadata and availability settings.
Landing experience
apps/web/src/app/page.tsx, apps/web/src/components/landing/*, apps/web/public/img/assets/*
Rebuilds landing sections with animated hero, about, map, partners, team carousel, FAQ preview, footer, pins, thread overlays, and new image assets.
FAQ page
apps/web/src/app/faq/*
Adds a dedicated responsive FAQ route with structured content, animated items, decorative backgrounds, and shared navigation/footer.
Dashboard and event pass
apps/web/src/app/dash/*, apps/web/src/components/dash/*
Replaces bubble-based dashboard content with ticket and QR layouts, redesigned countdown visuals, custom navigation, and a simplified event pass.
Registration and navigation flow
apps/web/src/app/register/page.tsx, apps/web/src/app/rsvp/page.tsx, apps/web/src/app/sign-up/*, apps/web/src/components/shared/*, apps/web/src/components/registration/*
Uses static configuration for registration and RSVP availability, adds a reusable closed-registration view, converts navigation to static links, and updates registration styling.
Shared theme and controls
apps/web/src/app/globals.css, apps/web/tailwind.config.js, apps/web/src/components/shadcn/ui/*
Replaces theme tokens with direct CSS-variable values, adds background and pin styling, and reduces focus-ring thickness and offset across shared controls.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Visitor
  participant LandingPage
  participant LandingThread
  participant ThreadUtility
  participant BrowserDOM

  Visitor->>LandingPage: Open landing page
  LandingPage->>LandingThread: Render thread mount component
  LandingThread->>ThreadUtility: Mount observers and redraw handler
  ThreadUtility->>BrowserDOM: Measure pins and render SVG thread overlay
  BrowserDOM-->>Visitor: Display connected landing sections
Loading

Possibly related PRs

  • acmutsa/HackKit#222: Changes Redis environment key-prefix handling that is superseded here by removing the Redis utility.
  • acmutsa/HackKit#241: Updates admin navigation and layout areas also changed in this PR.

Suggested reviewers: mkorolyova

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.13% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is too generic and doesn’t describe the main change, which is a landing-page link update via config. Use a specific title like 'Remove home registration link and add volunteer link'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

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

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

Caution

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

⚠️ Outside diff range comments (2)
apps/web/src/app/layout.tsx (1)

11-15: 🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win

Remove the unused theme variable and cookies() call that forces unnecessary dynamic rendering.

The theme variable is computed but never applied anywhere in the layout. While theme switching itself is still active (managed client-side by ThemeSwitcher.tsx), the server-side cookies() call in the root layout serves no purpose and opts the entire route (and all descendant pages) out of static rendering. The theme styling is handled client-side via the .dark CSS class toggle, so the server-side cookie read can be safely removed.

🧹 Proposed fix
-	const theme = cookies().get("hk_theme")?.value || defaultTheme;
 	return (
 		<ClerkProvider>
 			<html lang="en">
 				<body>{children}</body>
🤖 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 `@apps/web/src/app/layout.tsx` around lines 11 - 15, Remove the unused theme
assignment and its cookies() call from the root layout, including any now-unused
imports such as defaultTheme. Leave client-side theme handling through
ThemeSwitcher.tsx unchanged so the layout no longer forces dynamic rendering.
apps/web/src/components/registration/RegisterForm.tsx (1)

1653-1657: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix the missing space in the Tailwind class string.

When uploadedFile is false, this template string evaluates to border-2cursor-pointer. This invalid class name prevents Tailwind from applying both the border-2 border width and the cursor-pointer hover state.

🐛 Proposed fix
-													className={`border-2${
+													className={`border-2 ${
🤖 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 `@apps/web/src/components/registration/RegisterForm.tsx` around lines 1653 -
1657, Update the className template in the registration form so the conditional
cursor-pointer class is separated from the existing border-2 class with
whitespace when uploadedFile is false. Preserve the empty suffix when
uploadedFile is true and keep the remaining layout classes unchanged.
🟡 Minor comments (15)
apps/web/src/components/dash/overview/ServerBubbles.tsx-108-111 (1)

108-111: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make Pass No. data-driven or rename it. RH-10-2026 is hardcoded in apps/web/src/components/dash/overview/ServerBubbles.tsx, so every ticket shows the same value; if it’s meant to be a shared event/edition label, rename the field to avoid implying a unique pass number.

🤖 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 `@apps/web/src/components/dash/overview/ServerBubbles.tsx` around lines 108 -
111, Update the pass-number display in the ServerBubbles component to use the
ticket’s actual pass-number data instead of the hardcoded “RH-10-2026” value. If
the value is intentionally shared across all tickets, rename the “Pass No.”
label to accurately describe the shared event or edition identifier.
apps/web/src/components/landing/FooterLinks.tsx-18-25 (1)

18-25: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Footer Register link should use /register/auth is the wrong destination for this CTA; the app’s registration route is /register.

🤖 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 `@apps/web/src/components/landing/FooterLinks.tsx` around lines 18 - 25, Update
the Register entry in the resources array to use the /register route instead of
/auth, while leaving all other footer links unchanged.
apps/web/src/components/landing/About.tsx-32-32 (1)

32-32: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Replace duration-400 with a real Tailwind duration. apps/web/tailwind.config.js doesn’t extend transitionDuration, so this class won’t generate CSS; use duration-[400ms] or add theme.extend.transitionDuration.400. Also applies to lines 66 and 118.

🤖 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 `@apps/web/src/components/landing/About.tsx` at line 32, Update the landing
page container class in About.tsx, including the matching instances near lines
66 and 118, replacing the unsupported duration-400 utility with the arbitrary
Tailwind value duration-[400ms].
apps/web/src/components/landing/Hero.tsx-134-147 (1)

134-147: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove the leftover Register CTA

  • The tape sticker still renders on the landing page and points to /, so the label no longer matches the action.
  • #AC1903 on the two wrapper divs is a bare class token and has no effect; remove it or replace it with a real Tailwind utility.
🤖 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 `@apps/web/src/components/landing/Hero.tsx` around lines 134 - 147, Remove the
leftover Register CTA block from the landing page, including its tape-sticker
image, Link, and “Register” heading. Also remove the unused `#AC1903` class token
from both wrapper divs or replace it with a valid Tailwind utility.
apps/web/src/components/landing/Map.tsx-141-141 (1)

141-141: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Prettier formatting failure.

CI reports a Prettier formatting mismatch for this file; Line 141's indentation (spaces instead of tabs) is a visible instance. Run prettier --write to resolve.

🤖 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 `@apps/web/src/components/landing/Map.tsx` at line 141, Run Prettier with write
mode on the Map component file to normalize formatting, including the
indentation around the closing div and any other mismatches reported by CI.

Source: Pipeline failures

apps/web/src/components/landing/Map.tsx-164-198 (1)

164-198: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Duplicate React keys within the same parent.

line3_1/line3_2/line3_3 (and separately line2_1/line2_2) each run their own .map((char, i) => ... key={l1-${i}}), but their outputs are rendered as siblings inside the same <p>. This produces duplicate keys (l1-0, l1-1, …) across the combined children array, which React will warn about and can cause incorrect reconciliation.

🔧 Proposed fix — make keys unique per line
 						{line3_1.split("").map((char, i) => (
 							<motion.span
-								key={`l1-${i}`}
+								key={`sp1-line1-${i}`}
...
 						{line3_2.split("").map((char, i) => (
 							<motion.span
-								key={`l1-${i}`}
+								key={`sp1-line2-${i}`}
...
 						{line3_3.split("").map((char, i) => (
 							<motion.span
-								key={`l1-${i}`}
+								key={`sp1-line3-${i}`}

Apply the same pattern to line2_1/line2_2.

Also applies to: 230-252

🤖 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 `@apps/web/src/components/landing/Map.tsx` around lines 164 - 198, Update the
character keys in the line3_1, line3_2, and line3_3 maps within Map so each line
uses a distinct key prefix, and apply the same per-line uniqueness to the
line2_1 and line2_2 maps. Preserve the existing animation behavior while
ensuring all sibling keys are unique.
apps/web/src/app/sign-up/[[...sign-up]]/page.tsx-3-3 (1)

3-3: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Stray double semicolon.

🔧 Fix
-import RegisterClosed from "`@/components/registration/RegistretionClosed`";;
+import RegisterClosed from "`@/components/registration/RegistretionClosed`";
🤖 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 `@apps/web/src/app/sign-up/`[[...sign-up]]/page.tsx at line 3, Remove the stray
duplicate semicolon from the RegisterClosed import statement at the module top
level, leaving the import path and symbol unchanged.
apps/web/src/components/landing/PartnerCard.tsx-40-42 (1)

40-42: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fallback href causes an unintended same-page jump instead of disabling the card.

When partner.url is empty, the card still links to #Sponsors, which is this very section — clicking it just jumps in place rather than behaving as a non-interactive card (the cursor-default styling suggests that was the intent).

🔧 Suggested fix
-		<Link
-			href={partner.url || "`#Sponsors`"}
-			target={partner.url ? "_blank" : undefined}
-			className={`duration-350 group h-fit ${padding[index] ?? padding[padding.length - 1]} font-semibold opacity-100  ${partner.url ? "" : "cursor-default"}`}
-		>
+		<Wrapper
+			{...(partner.url
+				? { href: partner.url, target: "_blank", rel: "noopener noreferrer" }
+				: {})}
+			className={`duration-350 group h-fit ${padding[index] ?? padding[padding.length - 1]} font-semibold opacity-100  ${partner.url ? "" : "pointer-events-none cursor-default"}`}
+		>

where Wrapper renders <Link> when partner.url exists and a plain <div> otherwise.

🤖 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 `@apps/web/src/components/landing/PartnerCard.tsx` around lines 40 - 42, Update
the wrapper rendering in PartnerCard so cards with a partner.url use the
existing link behavior, while cards without a URL render as a non-interactive
div instead of using the "`#Sponsors`" fallback href. Preserve the current styling
and cursor-default behavior for cards without URLs.
apps/web/src/components/landing/Map.tsx-158-162 (1)

158-162: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Add rel="noopener noreferrer" to every _blank link here.

  • apps/web/src/components/landing/Map.tsx#L158-L162
  • apps/web/src/components/landing/Map.tsx#L224-L228
  • apps/web/src/components/landing/PartnerCard.tsx#L40-L41
  • apps/web/src/components/landing/MLHBadge.tsx#L11-L16
🤖 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 `@apps/web/src/components/landing/Map.tsx` around lines 158 - 162, Add
rel="noopener noreferrer" to every target="_blank" link in Map.tsx, including
both Map link sites, PartnerCard.tsx, and MLHBadge.tsx; update the affected
anchor elements without changing their existing destinations or behavior.
apps/web/src/components/shared/NavBarLinksGrouper.tsx-3-10 (1)

3-10: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Registration CTA is still present
apps/web/src/components/shared/Navbar.tsx still shows a /register button for signed-out users, and apps/web/src/components/shared/NavBarLinksGrouper.tsx has no Volunteer link. If this PR is meant to remove the home-page registration link, that change still needs to land here.

🤖 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 `@apps/web/src/components/shared/NavBarLinksGrouper.tsx` around lines 3 - 10,
Remove the signed-out `/register` CTA from the `Navbar` component and add a
Volunteer entry to the `navBarLinks` array in `NavBarLinksGrouper`, using the
intended volunteer destination and preserving the existing navigation links.
apps/web/src/components/landing/Partners.tsx-4-16 (1)

4-16: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Apply the font-shadows variable or use shadowsIntoLight.className on the text
Partners.tsx defines --font-shadows, but only shadowsIntoLight.className is applied here, and apps/web/src/app/layout.tsx never attaches shadowsIntoLight.variable. The font-shadows text at lines 52 and 65 will fall back to the default font unless that variable is added on an ancestor.

🤖 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 `@apps/web/src/components/landing/Partners.tsx` around lines 4 - 16, Update
Partners.tsx so the text using the font-shadows styling receives the configured
Shadows_Into_Light font: either apply shadowsIntoLight.className directly to
those text elements or attach shadowsIntoLight.variable to an ancestor and
preserve the corresponding font-family usage. Ensure both font-shadows text
instances render with the intended font.
apps/web/src/components/landing/faq.json-8-10 (1)

8-10: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Unresolved <Date> placeholder will render literally to users.

Both apps/web/src/components/landing/faq.json and apps/web/src/app/faq/faq.json contain this placeholder at line 9. Both faq.tsx and faq-client.tsx render item.answer verbatim with no string interpolation, so users will see "The deadline for registration is , at 23:59." on the live page.

No registration deadline is defined in the config; you'll need to either add it to hackkit.config.ts and interpolate it into the answer string, or replace the placeholder with the actual date directly in both JSON files.

🤖 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 `@apps/web/src/components/landing/faq.json` around lines 8 - 10, Replace the
unresolved <Date> placeholder with the actual registration deadline in both FAQ
JSON files, preserving the existing answer wording and ensuring both FAQ
renderers display the concrete date without interpolation.
apps/web/src/components/landing/partners.json-4-26 (1)

4-26: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Partner data contains missing logo assets and inconsistent capitalization—blocking if/when the commented render is uncommented.

Three of four referenced logo files don't exist in apps/web/public/img/partner-logos/: only HEB.svg is present; dell.svg, apple.svg, and google.svg are missing. Additionally, the brand name "google" should be "Google" for display consistency, and HEB.svg uses uppercase while the other three entries (in the JSON) reference lowercase filenames. Since the Partners component rendering is currently commented out (lines 70–105 in Partners.tsx), these issues do not cause a live error, but they must be resolved before the component is activated.

🤖 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 `@apps/web/src/components/landing/partners.json` around lines 4 - 26, Update
the partner entries in the partners data to reference only existing logo assets
in the partner-logos directory, preserving the valid HEB.svg reference and
replacing or adding the missing Dell, Apple, and Google assets as needed.
Normalize the Google display name to “Google” and ensure each logo filename
matches the asset’s exact capitalization so the Partners component can render
without broken images.
apps/web/src/app/register/page.tsx-52-52 (1)

52-52: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the typographical errors in the user-facing text.

"a issue" should be "an issue", and "Psttt" is typically spelled "Psst".

📝 Proposed fix
-							Psttt... Running into a issue? Please let us know on{" "}
+							Psst... Running into an issue? Please let us know on{" "}
🤖 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 `@apps/web/src/app/register/page.tsx` at line 52, Update the user-facing text
near the registration page to replace “Psttt” with “Psst” and “a issue” with “an
issue,” leaving the surrounding message unchanged.
apps/web/src/components/registration/RegistretionClosed.tsx-30-31 (1)

30-31: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Escape the single quote to prevent React linting errors.

The unescaped single quote in you've can trigger a react/no-unescaped-entities warning or error. Consider using &apos; or wrapping the word in a JS expression to ensure safe parsing.

📝 Proposed fix
-					This operation is currently closed to new team members. If you believe
-					this was an error, or you've got intel for us —
+					This operation is currently closed to new team members. If you believe
+					this was an error, or you&apos;ve got intel for us —
🤖 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 `@apps/web/src/components/registration/RegistretionClosed.tsx` around lines 30
- 31, Update the text rendered by the registration-closed component to escape
the apostrophe in “you've” using an entity or JSX expression, while preserving
the displayed message.
🧹 Nitpick comments (15)
apps/web/src/app/faq/page.tsx (1)

6-16: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the unnecessary React Fragment.

The outer fragment (<> ... </>) is unneeded because the component only returns a single root <div> element.

♻️ Proposed refactor
 export default function FAQPage() {
   return (
-    <>
-   
     <div className="w-full overflow-x-hidden">
       <LandingThread />
       <Navbar />
       <FAQClient />
       <Footer/>
     </div>
-    </>
   );
 }
🤖 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 `@apps/web/src/app/faq/page.tsx` around lines 6 - 16, Remove the unnecessary
outer React Fragment from the component’s return block so it returns the
existing root div directly. Preserve the LandingThread, Navbar, FAQClient, and
Footer elements and their order unchanged.
apps/web/src/app/faq/faq-client.tsx (2)

3-15: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Remove the unused Oswald font.

The Oswald font is imported and instantiated but never applied anywhere in the component. Removing it avoids an unnecessary network request, which improves page load performance.

♻️ Proposed refactor
-import { Oswald } from "next/font/google";
 import { Manuale } from "next/font/google";
 import faqs from "./faq.json";
 import { motion } from "motion/react";
 import Pin from "`@/components/landing/Pin`";
 const manuale = Manuale({
     subsets: ["latin"],
     display: "swap",
 });
-const oswald = Oswald({
-    variable: "--font-oswald",
-    subsets: ["latin"],
-});
🤖 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 `@apps/web/src/app/faq/faq-client.tsx` around lines 3 - 15, Remove the unused
Oswald import and its oswald font configuration from faq-client.tsx, while
leaving the Manuale configuration and other imports unchanged.

27-30: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Dynamically compute the split index for FAQ columns.

Hardcoding LEFT_COUNT = 5 splits the columns evenly for the current list of 10 items. However, if items are added or removed in the future, the layout could become unbalanced. Consider computing the midpoint dynamically.

♻️ Proposed refactor
-const LEFT_COUNT = 5;
 const allFaqs = faqs.faq as Faq[];
+const LEFT_COUNT = Math.ceil(allFaqs.length / 2);
 const leftFaqs = allFaqs.slice(0, LEFT_COUNT);
 const rightFaqs = allFaqs.slice(LEFT_COUNT);
🤖 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 `@apps/web/src/app/faq/faq-client.tsx` around lines 27 - 30, Update the FAQ
split logic around allFaqs, leftFaqs, and rightFaqs to compute the split index
dynamically from allFaqs.length, using a midpoint that keeps the two columns
balanced as items are added or removed. Replace the fixed LEFT_COUNT value and
preserve the existing slice-based column assignment.
apps/web/public/img/assets/about/about.webp (1)

284-284: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Consider stripping EXIF/XMP metadata from public image assets.

These WebP images contain embedded EXIF/XMP authoring metadata (e.g., Adobe Photoshop Web tracking info). Stripping metadata from production assets is generally recommended to optimize image sizes and remove unnecessary authoring footprints.

  • apps/web/public/img/assets/about/about.webp#L284-L284: strip the embedded <x:xmpmeta> block before deploying.
  • apps/web/public/img/assets/about/about2.webp#L432-L432: strip the embedded <x:xmpmeta> block before deploying.
  • apps/web/public/img/assets/dash/lable-vertical.webp#L162-L236: strip the embedded EXIF and <x:xmpmeta> block before deploying.
🤖 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 `@apps/web/public/img/assets/about/about.webp` at line 284, Strip embedded
authoring metadata from all affected production assets:
apps/web/public/img/assets/about/about.webp (lines 284-284),
apps/web/public/img/assets/about/about2.webp (lines 432-432), and
apps/web/public/img/assets/dash/lable-vertical.webp (lines 162-236). Remove the
XMP metadata block from the first two assets, and remove both EXIF and XMP
metadata from the dash asset, while preserving the image content and format.
apps/web/next.config.mjs (1)

24-28: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Hardcoded pnpm module path is brittle to dependency updates.

Hardcoding the exact pnpm versioned path (@libsql+isomorphic-ws@0.1.5) will break output tracing silently if the library is updated in the future.

Consider resolving the path dynamically if possible, or leave a comment warning future maintainers that this path must be updated alongside any version bumps to @libsql/isomorphic-ws.

🤖 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 `@apps/web/next.config.mjs` around lines 24 - 28, Update the
outputFileTracingIncludes configuration to avoid silently becoming stale when
`@libsql/isomorphic-ws` changes versions: resolve the package path dynamically if
supported by the Next.js configuration, otherwise add a clear maintenance
comment adjacent to the hardcoded path requiring updates alongside dependency
version bumps.
apps/web/src/app/dash/pass/page.tsx (1)

15-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Font loader duplicated across files.

Manuale({...}) here duplicates the identical call in ClientBubbles.tsx/ServerBubbles.tsx; Shadows_Into_Light is also imported but never used in this file. See the consolidated comment for the shared-fonts-file recommendation.

🤖 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 `@apps/web/src/app/dash/pass/page.tsx` around lines 15 - 21, Remove the unused
Shadows_Into_Light import and stop creating the duplicate Manuale loader in this
page. Reuse the shared font definitions from the consolidated shared-fonts file,
including the existing manuale symbol, so page rendering preserves the current
font configuration.
apps/web/src/app/dash/layout.tsx (2)

50-54: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Decorative pin images missing aria-hidden/empty alt.

Both pin images use alt={"Pin"} with no aria-hidden, unlike the shared Pin component's convention (alt="" + aria-hidden="true") used elsewhere for the same decorative graphic. Screen readers will announce "Pin" twice on this header for no informational value.

♿ Proposed fix
 <img
     src={"/img/assets/menu/pin1.webp"}
-    alt={"Pin"}
+    alt=""
+    aria-hidden
     className="pointer-events-none h-12 w-auto sm:h-14 md:h-20 lg:h-24 xl:h-28"
 />

Also applies to: 83-87

🤖 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 `@apps/web/src/app/dash/layout.tsx` around lines 50 - 54, Update both
decorative pin image elements in the dash layout, including the instances near
the visible image and the additionally referenced occurrence, to use an empty
alt value and aria-hidden="true". Preserve their existing sources, classes, and
layout behavior while matching the shared Pin component’s accessibility
convention.

9-15: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Font loader duplicated across files.

Shadows_Into_Light({...}) is redefined here identically to ClientBubbles.tsx and ServerBubbles.tsx. Per Next.js docs, calling a Google font function multiple times hosts multiple instances; the recommended pattern is a shared font-definitions file. See consolidated comment below for all affected sites.

🤖 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 `@apps/web/src/app/dash/layout.tsx` around lines 9 - 15, Consolidate the
duplicated Shadows_Into_Light definition used by the layout and the
ClientBubbles and ServerBubbles components into one shared font-definitions
module. Export and reuse the shared font instance in each consumer, including
the current shadow reference, while preserving the existing subset and weight
configuration.
apps/web/src/components/dash/overview/ServerBubbles.tsx (1)

6-18: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Font loaders duplicated across files.

Duplicates identical Manuale/Shadows_Into_Light definitions in ClientBubbles.tsx, dash/layout.tsx, and dash/pass/page.tsx. See consolidated comment.

🤖 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 `@apps/web/src/components/dash/overview/ServerBubbles.tsx` around lines 6 - 18,
Consolidate the duplicated Manuale and Shadows_Into_Light font loaders used by
ServerBubbles.tsx, ClientBubbles.tsx, dash/layout.tsx, and dash/pass/page.tsx
into the existing shared font definition. Remove the local Manuale and
Shadows_Into_Light declarations and update consumers to import and reuse the
shared symbols.
apps/web/src/components/dash/overview/ClientBubbles.tsx (1)

3-14: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Font loaders duplicated across files.

Both Manuale and Shadows_Into_Light are re-invoked here identically to ServerBubbles.tsx, dash/layout.tsx, and dash/pass/page.tsx. See consolidated comment for all sites and the recommended fix.

🤖 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 `@apps/web/src/components/dash/overview/ClientBubbles.tsx` around lines 3 - 14,
Remove the duplicated Manuale and Shadows_Into_Light loader initialization from
ClientBubbles.tsx and reuse the shared font-loader definitions established for
these components. Update references to preserve the existing font styling while
ensuring each loader is invoked only once across the relevant dashboard files.
apps/web/src/components/shared/Navbar.tsx (1)

60-65: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Empty home link left as a TODO.

<Link href={"/"}> currently wraps only a {/* TODO: add rh logo */} comment, so it renders an invisible clickable region with no visible content or accessible name. Want me to draft a placeholder (e.g. the RowdyHacks wordmark/logo) to fill this in, or open a tracking issue?

🤖 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 `@apps/web/src/components/shared/Navbar.tsx` around lines 60 - 65, Update the
home Link in the Navbar component to include a visible RowdyHacks logo or
wordmark and an accessible name, replacing the TODO-only content. Preserve the
existing home destination and styling while ensuring the link is not empty or
invisible.
apps/web/src/components/shared/MobileNavBarLinks.tsx (1)

7-23: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Unnecessary async after removing the Redis fetch.

The function no longer awaits anything now that navLinks is sourced synchronously from the static navBarLinks import; the async keyword is vestigial.

♻️ Proposed cleanup
-export default async function MobileNavBarLinks() {
+export default function MobileNavBarLinks() {
🤖 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 `@apps/web/src/components/shared/MobileNavBarLinks.tsx` around lines 7 - 23,
Remove the unnecessary async keyword from the MobileNavBarLinks function, since
it synchronously reads the imported navBarLinks data and performs no awaited
operations. Preserve the existing rendered navigation structure and behavior.
apps/web/src/components/landing/Hero.tsx (1)

47-47: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Invalid class token #AC1903 has no effect.

className="#AC1903 absolute ..." includes #AC1903 as a bare class name (lines 47 and 67), which Tailwind/CSS will simply ignore. If a color was intended here, use an arbitrary-value utility (e.g. text-[#AC1903] or bg-[#AC1903]) instead of a stray hex literal.

Also applies to: 67-67

🤖 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 `@apps/web/src/components/landing/Hero.tsx` at line 47, Remove the invalid bare
`#AC1903` token from the className values at both hero decoration elements, or
replace it with the appropriate Tailwind arbitrary-value color utility if the
color is intended to style them. Preserve the remaining positioning and
transform classes.
apps/web/src/components/landing/Partners.tsx (1)

25-35: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Shared DossierPins overlay pattern duplicated across landing sections. Each file defines its own local DossierPins component with hardcoded <Pin> positions instead of a shared, parameterized component.

  • apps/web/src/components/landing/Partners.tsx#L25-L35: extract this 4-pin layout into a shared component (e.g. exported from Pin.tsx) that accepts a list of position classes.
  • apps/web/src/components/landing/faq.tsx#L127-L135: replace this local 3-pin variant with the same shared component, passing its distinct position set as a prop.
🤖 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 `@apps/web/src/components/landing/Partners.tsx` around lines 25 - 35, The local
DossierPins components duplicate a shared overlay pattern; extract a reusable,
exported parameterized component from Pin.tsx that accepts position-class data
and preserves each pin’s no_thread setting. In
apps/web/src/components/landing/Partners.tsx lines 25-35, replace the four
hardcoded pins with the shared component and its four-position configuration; in
apps/web/src/components/landing/faq.tsx lines 127-135, replace the local
three-pin variant with the same component and pass its distinct positions.
apps/web/src/components/registration/RegistretionClosed.tsx (1)

15-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Fix the typo in the component's filename.

The file name contains a typo ("Registretion" instead of "Registration"). Consider renaming the file and updating its references to maintain a consistent codebase.

  • apps/web/src/components/registration/RegistretionClosed.tsx#L15-L16: Rename this file to RegistrationClosed.tsx.
  • apps/web/src/app/register/page.tsx#L3-L3: Update the import path to match the corrected filename.
🤖 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 `@apps/web/src/components/registration/RegistretionClosed.tsx` around lines 15
- 16, Rename the component file from RegistretionClosed.tsx to
RegistrationClosed.tsx, and update the import in
apps/web/src/app/register/page.tsx at line 3 to reference the corrected
filename.
🤖 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 `@apps/web/package.json`:
- Around line 11-12: Update the deploy and upload scripts in package.json to
pass the --keep-vars option to their respective opennextjs-cloudflare deploy and
upload commands, preserving dashboard-managed Cloudflare variables not declared
in wrangler.toml. Keep the existing build command and flags unchanged.

In `@apps/web/src/app/faq/faq-client.tsx`:
- Around line 17-23: Update the img source in PaperBg to use the root-relative
FAQ background path with a leading slash, ensuring it resolves to
/img/assets/faq/FAQ.svg from the nested /faq route.

In `@apps/web/src/app/faq/faq.json`:
- Around line 7-10: Replace the unresolved <Date> placeholder in the FAQ answer
for “When is the deadline to apply?” with the actual registration deadline date,
preserving the existing 23:59 time wording.

In `@apps/web/src/components/dash/shared/DashNavItem.tsx`:
- Around line 16-21: Update the className construction in DashNavItem so the
active-path condition applies an actual active CSS class instead of
interpolating its boolean result. Preserve the existing exclusions for “/admin”
and “/dash”, and retain the current base typography classes.

In `@apps/web/src/components/landing/About.tsx`:
- Around line 15-24: Extract the duplicated DossierPins component into a shared
landing/DossierPins.tsx module, preserving its existing Pin elements and
positioning classes. Remove the local DossierPins definitions from About.tsx,
Partners.tsx, WorkWithUs.tsx, and faq.tsx, and import the shared component in
each consumer.

In `@apps/web/src/components/landing/Partners.tsx`:
- Around line 66-105: Restore the PartnerCard grid in the Partners component by
removing the “Currently under investigation” placeholder and re-enabling the
rendering of partnerData.partners, including the existing placeholder cards. In
apps/web/src/components/landing/Partners.tsx lines 66-105, update the disabled
JSX; apps/web/src/components/landing/partners.json lines 4-26 requires no direct
change because its entries should be consumed by the restored grid.

In `@apps/web/src/env.ts`:
- Line 23: Update the env validation configuration in the env schema to stop
using NODE_ENV as the skip condition. Gate skipValidation behind an explicit
build-only environment flag, ensuring production runtime deployments still
validate required Clerk, Turso, R2, BOT_API_URL, and INTERNAL_AUTH_KEY values.

In `@apps/web/tailwind.config.js`:
- Around line 26-70: Update the theme color values in the Tailwind color
configuration, including primary, secondary, background, hackathon, and related
variables, to use an alpha-aware <alpha-value> form or color-mix() rather than
plain var(--x) values. Preserve the existing color-token mappings and ensure
opacity utilities such as bg-secondary/80, bg-background/80, and
from-hackathon/80 are generated correctly.

In `@packages/config/hackkit.config.ts`:
- Around line 139-140: Update the startDate initialization to construct the
timestamp with Date.UTC, preserving October 3, 2026 at 14:00 UTC so it is
deterministic across environments and matches the documented 9:00 AM CDT time.

---

Outside diff comments:
In `@apps/web/src/app/layout.tsx`:
- Around line 11-15: Remove the unused theme assignment and its cookies() call
from the root layout, including any now-unused imports such as defaultTheme.
Leave client-side theme handling through ThemeSwitcher.tsx unchanged so the
layout no longer forces dynamic rendering.

In `@apps/web/src/components/registration/RegisterForm.tsx`:
- Around line 1653-1657: Update the className template in the registration form
so the conditional cursor-pointer class is separated from the existing border-2
class with whitespace when uploadedFile is false. Preserve the empty suffix when
uploadedFile is true and keep the remaining layout classes unchanged.

---

Minor comments:
In `@apps/web/src/app/register/page.tsx`:
- Line 52: Update the user-facing text near the registration page to replace
“Psttt” with “Psst” and “a issue” with “an issue,” leaving the surrounding
message unchanged.

In `@apps/web/src/app/sign-up/`[[...sign-up]]/page.tsx:
- Line 3: Remove the stray duplicate semicolon from the RegisterClosed import
statement at the module top level, leaving the import path and symbol unchanged.

In `@apps/web/src/components/dash/overview/ServerBubbles.tsx`:
- Around line 108-111: Update the pass-number display in the ServerBubbles
component to use the ticket’s actual pass-number data instead of the hardcoded
“RH-10-2026” value. If the value is intentionally shared across all tickets,
rename the “Pass No.” label to accurately describe the shared event or edition
identifier.

In `@apps/web/src/components/landing/About.tsx`:
- Line 32: Update the landing page container class in About.tsx, including the
matching instances near lines 66 and 118, replacing the unsupported duration-400
utility with the arbitrary Tailwind value duration-[400ms].

In `@apps/web/src/components/landing/faq.json`:
- Around line 8-10: Replace the unresolved <Date> placeholder with the actual
registration deadline in both FAQ JSON files, preserving the existing answer
wording and ensuring both FAQ renderers display the concrete date without
interpolation.

In `@apps/web/src/components/landing/FooterLinks.tsx`:
- Around line 18-25: Update the Register entry in the resources array to use the
/register route instead of /auth, while leaving all other footer links
unchanged.

In `@apps/web/src/components/landing/Hero.tsx`:
- Around line 134-147: Remove the leftover Register CTA block from the landing
page, including its tape-sticker image, Link, and “Register” heading. Also
remove the unused `#AC1903` class token from both wrapper divs or replace it with
a valid Tailwind utility.

In `@apps/web/src/components/landing/Map.tsx`:
- Line 141: Run Prettier with write mode on the Map component file to normalize
formatting, including the indentation around the closing div and any other
mismatches reported by CI.
- Around line 164-198: Update the character keys in the line3_1, line3_2, and
line3_3 maps within Map so each line uses a distinct key prefix, and apply the
same per-line uniqueness to the line2_1 and line2_2 maps. Preserve the existing
animation behavior while ensuring all sibling keys are unique.
- Around line 158-162: Add rel="noopener noreferrer" to every target="_blank"
link in Map.tsx, including both Map link sites, PartnerCard.tsx, and
MLHBadge.tsx; update the affected anchor elements without changing their
existing destinations or behavior.

In `@apps/web/src/components/landing/PartnerCard.tsx`:
- Around line 40-42: Update the wrapper rendering in PartnerCard so cards with a
partner.url use the existing link behavior, while cards without a URL render as
a non-interactive div instead of using the "`#Sponsors`" fallback href. Preserve
the current styling and cursor-default behavior for cards without URLs.

In `@apps/web/src/components/landing/partners.json`:
- Around line 4-26: Update the partner entries in the partners data to reference
only existing logo assets in the partner-logos directory, preserving the valid
HEB.svg reference and replacing or adding the missing Dell, Apple, and Google
assets as needed. Normalize the Google display name to “Google” and ensure each
logo filename matches the asset’s exact capitalization so the Partners component
can render without broken images.

In `@apps/web/src/components/landing/Partners.tsx`:
- Around line 4-16: Update Partners.tsx so the text using the font-shadows
styling receives the configured Shadows_Into_Light font: either apply
shadowsIntoLight.className directly to those text elements or attach
shadowsIntoLight.variable to an ancestor and preserve the corresponding
font-family usage. Ensure both font-shadows text instances render with the
intended font.

In `@apps/web/src/components/registration/RegistretionClosed.tsx`:
- Around line 30-31: Update the text rendered by the registration-closed
component to escape the apostrophe in “you've” using an entity or JSX
expression, while preserving the displayed message.

In `@apps/web/src/components/shared/NavBarLinksGrouper.tsx`:
- Around line 3-10: Remove the signed-out `/register` CTA from the `Navbar`
component and add a Volunteer entry to the `navBarLinks` array in
`NavBarLinksGrouper`, using the intended volunteer destination and preserving
the existing navigation links.

---

Nitpick comments:
In `@apps/web/next.config.mjs`:
- Around line 24-28: Update the outputFileTracingIncludes configuration to avoid
silently becoming stale when `@libsql/isomorphic-ws` changes versions: resolve the
package path dynamically if supported by the Next.js configuration, otherwise
add a clear maintenance comment adjacent to the hardcoded path requiring updates
alongside dependency version bumps.

In `@apps/web/public/img/assets/about/about.webp`:
- Line 284: Strip embedded authoring metadata from all affected production
assets: apps/web/public/img/assets/about/about.webp (lines 284-284),
apps/web/public/img/assets/about/about2.webp (lines 432-432), and
apps/web/public/img/assets/dash/lable-vertical.webp (lines 162-236). Remove the
XMP metadata block from the first two assets, and remove both EXIF and XMP
metadata from the dash asset, while preserving the image content and format.

In `@apps/web/src/app/dash/layout.tsx`:
- Around line 50-54: Update both decorative pin image elements in the dash
layout, including the instances near the visible image and the additionally
referenced occurrence, to use an empty alt value and aria-hidden="true".
Preserve their existing sources, classes, and layout behavior while matching the
shared Pin component’s accessibility convention.
- Around line 9-15: Consolidate the duplicated Shadows_Into_Light definition
used by the layout and the ClientBubbles and ServerBubbles components into one
shared font-definitions module. Export and reuse the shared font instance in
each consumer, including the current shadow reference, while preserving the
existing subset and weight configuration.

In `@apps/web/src/app/dash/pass/page.tsx`:
- Around line 15-21: Remove the unused Shadows_Into_Light import and stop
creating the duplicate Manuale loader in this page. Reuse the shared font
definitions from the consolidated shared-fonts file, including the existing
manuale symbol, so page rendering preserves the current font configuration.

In `@apps/web/src/app/faq/faq-client.tsx`:
- Around line 3-15: Remove the unused Oswald import and its oswald font
configuration from faq-client.tsx, while leaving the Manuale configuration and
other imports unchanged.
- Around line 27-30: Update the FAQ split logic around allFaqs, leftFaqs, and
rightFaqs to compute the split index dynamically from allFaqs.length, using a
midpoint that keeps the two columns balanced as items are added or removed.
Replace the fixed LEFT_COUNT value and preserve the existing slice-based column
assignment.

In `@apps/web/src/app/faq/page.tsx`:
- Around line 6-16: Remove the unnecessary outer React Fragment from the
component’s return block so it returns the existing root div directly. Preserve
the LandingThread, Navbar, FAQClient, and Footer elements and their order
unchanged.

In `@apps/web/src/components/dash/overview/ClientBubbles.tsx`:
- Around line 3-14: Remove the duplicated Manuale and Shadows_Into_Light loader
initialization from ClientBubbles.tsx and reuse the shared font-loader
definitions established for these components. Update references to preserve the
existing font styling while ensuring each loader is invoked only once across the
relevant dashboard files.

In `@apps/web/src/components/dash/overview/ServerBubbles.tsx`:
- Around line 6-18: Consolidate the duplicated Manuale and Shadows_Into_Light
font loaders used by ServerBubbles.tsx, ClientBubbles.tsx, dash/layout.tsx, and
dash/pass/page.tsx into the existing shared font definition. Remove the local
Manuale and Shadows_Into_Light declarations and update consumers to import and
reuse the shared symbols.

In `@apps/web/src/components/landing/Hero.tsx`:
- Line 47: Remove the invalid bare `#AC1903` token from the className values at
both hero decoration elements, or replace it with the appropriate Tailwind
arbitrary-value color utility if the color is intended to style them. Preserve
the remaining positioning and transform classes.

In `@apps/web/src/components/landing/Partners.tsx`:
- Around line 25-35: The local DossierPins components duplicate a shared overlay
pattern; extract a reusable, exported parameterized component from Pin.tsx that
accepts position-class data and preserves each pin’s no_thread setting. In
apps/web/src/components/landing/Partners.tsx lines 25-35, replace the four
hardcoded pins with the shared component and its four-position configuration; in
apps/web/src/components/landing/faq.tsx lines 127-135, replace the local
three-pin variant with the same component and pass its distinct positions.

In `@apps/web/src/components/registration/RegistretionClosed.tsx`:
- Around line 15-16: Rename the component file from RegistretionClosed.tsx to
RegistrationClosed.tsx, and update the import in
apps/web/src/app/register/page.tsx at line 3 to reference the corrected
filename.

In `@apps/web/src/components/shared/MobileNavBarLinks.tsx`:
- Around line 7-23: Remove the unnecessary async keyword from the
MobileNavBarLinks function, since it synchronously reads the imported
navBarLinks data and performs no awaited operations. Preserve the existing
rendered navigation structure and behavior.

In `@apps/web/src/components/shared/Navbar.tsx`:
- Around line 60-65: Update the home Link in the Navbar component to include a
visible RowdyHacks logo or wordmark and an accessible name, replacing the
TODO-only content. Preserve the existing home destination and styling while
ensuring the link is not empty or invisible.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

Comment thread apps/web/package.json
Comment on lines +11 to +12
"deploy": "opennextjs-cloudflare build --dangerouslyUseUnsupportedNextVersion && opennextjs-cloudflare deploy",
"upload": "opennextjs-cloudflare build --dangerouslyUseUnsupportedNextVersion && opennextjs-cloudflare upload",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the relevant package scripts and Cloudflare config.
git ls-files apps/web/package.json apps/web/wrangler.toml
printf '\n--- package.json (lines around scripts) ---\n'
cat -n apps/web/package.json | sed -n '1,120p'
printf '\n--- wrangler.toml ---\n'
cat -n apps/web/wrangler.toml | sed -n '1,220p'

Repository: acmutsa/HackKit

Length of output: 4536


🏁 Script executed:

#!/bin/bash
set -euo pipefail

git ls-files apps/web/package.json apps/web/wrangler.toml
printf '\n--- package.json (lines around scripts) ---\n'
cat -n apps/web/package.json | sed -n '1,120p'
printf '\n--- wrangler.toml ---\n'
cat -n apps/web/wrangler.toml | sed -n '1,220p'

Repository: acmutsa/HackKit

Length of output: 4536


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- package.json scripts ---\n'
cat -n apps/web/package.json | sed -n '1,120p'

printf '\n--- wrangler.toml ---\n'
cat -n apps/web/wrangler.toml | sed -n '1,220p'

Repository: acmutsa/HackKit

Length of output: 244


🌐 Web query:

OpenNext Cloudflare keep-vars deploy upload wrangler dashboard secrets documentation

💡 Result:

To manage secrets and environment variables when deploying OpenNext applications to Cloudflare, follow these recommended practices: Runtime Environment Variables and Secrets For production, you should set environment variables and secrets directly in the Cloudflare dashboard or via Wrangler [1][2]. Secrets are encrypted and cannot be read back after creation [1]. If you are using Workers Builds (CI/CD), ensure you set these in the "Build variables and secrets" section of your project settings in the Cloudflare dashboard, as these are required for the Next.js build process to function correctly [1]. Using --keep-vars When deploying via the OpenNext CLI, you can use the --keep-vars option to prevent existing environment variables on your Cloudflare Worker from being deleted during a deployment. This is typically invoked as follows [1]: opennextjs-cloudflare deploy -- --keep-vars Managing Secrets during Deployment You should avoid hardcoding secrets in your configuration files (e.g., wrangler.toml) [2]. During local development, you can use a.dev.vars file (which should be excluded from version control) [1][3]. For production deployments, Cloudflare Wrangler supports uploading secrets alongside your code. You can use the --secrets-file flag with wrangler deploy or wrangler versions upload to pass secrets securely [4][5]. Best Practices for Development - Local Development: Use.dev.vars or.env files to manage variables locally [1][3][2]. - Accessing Variables: Within your application code, access variables and secrets via the env parameter provided in the getCloudflareContext function or directly from the request context in API routes [3][2]. - Avoid Baking Secrets: Do not include secrets in your source code or configuration files [2]. Always rely on Cloudflare's secure secret storage [1][4]. For consistent and reproducible deployments, it is recommended to use Cloudflare’s Workers Builds system, which integrates directly with your repository, rather than manual command-line uploads [6][7].

Citations:


🌐 Web query:

OpenNext Cloudflare upload keep-vars wrangler versions upload

💡 Result:

When using the OpenNext Cloudflare adapter, you can use the --keep-vars flag to prevent your existing environment variables (set in the Cloudflare Dashboard) from being overwritten during deployment [1][2]. If you are using the opennextjs-cloudflare CLI to upload your application, you can pass this flag to the underlying wrangler command by separating it from the CLI arguments with a double dash (--). For example: npx opennextjs-cloudflare upload -- --keep-vars The upload command itself is designed to create a new version of your application on Cloudflare without immediately serving it, which supports gradual deployment workflows [3][4][5]. Internally, this command executes wrangler versions upload [3]. While the CLI handles the complex transformation of your Next.js build for the Workers environment, you can use this --keep-vars option to maintain your dashboard-configured environment variables across updates [1][2]. Note that you should use the opennextjs-cloudflare CLI commands (such as build, deploy, or upload) rather than calling wrangler directly for deployment tasks, as these CLI commands handle necessary processes like R2 cache population and environment configuration automatically [3][4][6].

Citations:


Preserve dashboard vars on deploy and upload.

deploy and upload should pass --keep-vars; otherwise Wrangler can delete Cloudflare dashboard-managed variables that aren't declared in apps/web/wrangler.toml.

Proposed fix
-    "deploy": "opennextjs-cloudflare build --dangerouslyUseUnsupportedNextVersion && opennextjs-cloudflare deploy",
-    "upload": "opennextjs-cloudflare build --dangerouslyUseUnsupportedNextVersion && opennextjs-cloudflare upload",
+    "deploy": "opennextjs-cloudflare build --dangerouslyUseUnsupportedNextVersion && opennextjs-cloudflare deploy -- --keep-vars",
+    "upload": "opennextjs-cloudflare build --dangerouslyUseUnsupportedNextVersion && opennextjs-cloudflare upload -- --keep-vars",
📝 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
"deploy": "opennextjs-cloudflare build --dangerouslyUseUnsupportedNextVersion && opennextjs-cloudflare deploy",
"upload": "opennextjs-cloudflare build --dangerouslyUseUnsupportedNextVersion && opennextjs-cloudflare upload",
"deploy": "opennextjs-cloudflare build --dangerouslyUseUnsupportedNextVersion && opennextjs-cloudflare deploy -- --keep-vars",
"upload": "opennextjs-cloudflare build --dangerouslyUseUnsupportedNextVersion && opennextjs-cloudflare upload -- --keep-vars",
🤖 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 `@apps/web/package.json` around lines 11 - 12, Update the deploy and upload
scripts in package.json to pass the --keep-vars option to their respective
opennextjs-cloudflare deploy and upload commands, preserving dashboard-managed
Cloudflare variables not declared in wrangler.toml. Keep the existing build
command and flags unchanged.

Source: MCP tools

Comment on lines +17 to +23
function PaperBg() {
return (
<img src="img/assets/faq/FAQ.svg" alt=""
className="absolute w-full h-full inset-0 drop-shadow-[6px_8px_3px_rgba(0,0,0,0.45)]" />
);

}

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 | 🔴 Critical | ⚡ Quick win

Fix the broken image path for the FAQ background.

The image source img/assets/faq/FAQ.svg is missing a leading slash. Because this component is rendered on a nested route (/faq), the browser will resolve this path relative to the current URL (resulting in /faq/img/assets/faq/FAQ.svg), which causes a 404 error and breaks the background.

🐛 Proposed fix
 function PaperBg() {
     return (
-        <img src="img/assets/faq/FAQ.svg" alt=""
+        <img src="/img/assets/faq/FAQ.svg" alt=""
             className="absolute w-full h-full inset-0 drop-shadow-[6px_8px_3px_rgba(0,0,0,0.45)]" />
     );
📝 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
function PaperBg() {
return (
<img src="img/assets/faq/FAQ.svg" alt=""
className="absolute w-full h-full inset-0 drop-shadow-[6px_8px_3px_rgba(0,0,0,0.45)]" />
);
}
function PaperBg() {
return (
<img src="/img/assets/faq/FAQ.svg" alt=""
className="absolute w-full h-full inset-0 drop-shadow-[6px_8px_3px_rgba(0,0,0,0.45)]" />
);
}
🤖 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 `@apps/web/src/app/faq/faq-client.tsx` around lines 17 - 23, Update the img
source in PaperBg to use the root-relative FAQ background path with a leading
slash, ensuring it resolves to /img/assets/faq/FAQ.svg from the nested /faq
route.

Comment on lines +7 to +10
{
"question": "When is the deadline to apply?",
"answer": "The deadline for registration is <Date>, at 23:59."
},

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

Resolve the placeholder date.

The answer contains an unresolved <Date> placeholder for the registration deadline. Leaving this unresolved will hide important information from attendees.

🤖 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 `@apps/web/src/app/faq/faq.json` around lines 7 - 10, Replace the unresolved
<Date> placeholder in the FAQ answer for “When is the deadline to apply?” with
the actual registration deadline date, preserving the existing 23:59 time
wording.

Comment on lines +16 to 21

className={`text-sm hover:underline sm:text-sm md:text-lg lg:text-2xl xl:text-3xl 2xl:text-3xl ${
(currPath.startsWith(path) &&
path !== "/admin" &&
path !== "/dash") ||
currPath === path
? "border-b-muted text-primary dark:border-b-primary"
: "border-b-transparent text-muted-foreground hover:border-b-muted"
path !== "/dash")
}`}

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

Active-link styling is a no-op: boolean is stringified into className instead of driving a class.

${(currPath.startsWith(path) && path !== "/admin" && path !== "/dash")} interpolates as the literal text "true"/"false" in the class list — not a valid CSS class — so the active nav item never gets distinct styling. This regresses the active-state indicator that the previous implementation had.

🐛 Proposed fix
 			<button
-
-				className={`text-sm hover:underline sm:text-sm md:text-lg lg:text-2xl xl:text-3xl 2xl:text-3xl  ${
-					(currPath.startsWith(path) &&
-						path !== "/admin" &&
-						path !== "/dash") 
-				}`}
+				className={`text-sm hover:underline sm:text-sm md:text-lg lg:text-2xl xl:text-3xl 2xl:text-3xl ${
+					currPath.startsWith(path) &&
+					path !== "/admin" &&
+					path !== "/dash"
+						? "underline font-bold"
+						: ""
+				}`}
			>
📝 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
className={`text-sm hover:underline sm:text-sm md:text-lg lg:text-2xl xl:text-3xl 2xl:text-3xl ${
(currPath.startsWith(path) &&
path !== "/admin" &&
path !== "/dash") ||
currPath === path
? "border-b-muted text-primary dark:border-b-primary"
: "border-b-transparent text-muted-foreground hover:border-b-muted"
path !== "/dash")
}`}
className={`text-sm hover:underline sm:text-sm md:text-lg lg:text-2xl xl:text-3xl 2xl:text-3xl ${
currPath.startsWith(path) &&
path !== "/admin" &&
path !== "/dash"
? "underline font-bold"
: ""
}`}
🤖 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 `@apps/web/src/components/dash/shared/DashNavItem.tsx` around lines 16 - 21,
Update the className construction in DashNavItem so the active-path condition
applies an actual active CSS class instead of interpolating its boolean result.
Preserve the existing exclusions for “/admin” and “/dash”, and retain the
current base typography classes.

Comment on lines +15 to +24
function DossierPins() {
return (
<>
<Pin className="absolute right-[70%] top-[0%] z-40 sm:right-[18%] sm:top-[9%] md:right-[18%] md:top-[9%]" />
<Pin className="absolute right-[40%] top-[-2%] z-40 sm:right-[7%] sm:top-[49%] md:right-[7%] md:top-[49%]" />
<Pin className="absolute right-[5%] top-[6%] z-40 sm:right-[14%] sm:top-[85%] md:right-[19%] md:top-[90%] lg:right-[10%] lg:top-[91%]" />
<Pin className="absolute right-[11%] top-[90%] z-40 sm:right-[45%] sm:top-[95%] lg:right-[36%] lg:top-[95%]" />
</>
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Extract duplicated DossierPins() into a shared component.

This exact function is copy-pasted identically into Partners.tsx, WorkWithUs.tsx, and faq.tsx. Any future pin repositioning requires editing four files in lockstep.

♻️ Suggested extraction
-function DossierPins() {
-	return (
-		<>	
-			<Pin className="absolute right-[70%] top-[0%] z-40 sm:right-[18%] sm:top-[9%]  md:right-[18%] md:top-[9%]" />
-			<Pin className="absolute right-[40%] top-[-2%] z-40 sm:right-[7%]  sm:top-[49%] md:right-[7%]  md:top-[49%]" />
-			<Pin className="absolute right-[5%] top-[6%] z-40 sm:right-[14%] sm:top-[85%] md:right-[19%] md:top-[90%] lg:right-[10%] lg:top-[91%]" />
-			<Pin className="absolute right-[11%] top-[90%] z-40 sm:right-[45%] sm:top-[95%] lg:right-[36%] lg:top-[95%]" />
-		</>
-	);
-}
+import DossierPins from "./DossierPins";

Move the body into a new apps/web/src/components/landing/DossierPins.tsx and import it in all four consuming files.

🤖 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 `@apps/web/src/components/landing/About.tsx` around lines 15 - 24, Extract the
duplicated DossierPins component into a shared landing/DossierPins.tsx module,
preserving its existing Pin elements and positioning classes. Remove the local
DossierPins definitions from About.tsx, Partners.tsx, WorkWithUs.tsx, and
faq.tsx, and import the shared component in each consumer.

Comment on lines +66 to +105
Currently under investigation
</p>
</div>

{/* <div className="relative h-fit w-full">
<div className="absolute inset-0 flex h-[100vh] w-full items-center justify-end pt-[5vh] sm:h-[50vh] md:h-[100vh] lg:h-[80vh] xl:h-[90vh] 2xl:h-[100vh]">
<Image
src="/img/sponsors/sponsors-background.svg"
alt="sponsors-background"
fill
className="object-contain object-right px-[5vw] rotate-[10deg] drop-shadow-[6px_8px_3px_rgba(0,0,0,0.45)]"
/>
</div>

<div className="no-scrollbar relative mx-auto flex h-fit w-[90%] flex-wrap items-center justify-start gap-5 overflow-y-hidden overflow-x-visible pb-2 pt-8 sm:w-[90%] sm:pb-8 sm:pt-10 md:pt-[3.5rem] lg:gap-12 lg:pb-12 lg:pt-[4rem]">
{partnerData.partners.map(
(partner: Partner, index: number) => (
<PartnerCard
key={partner.name}
partner={partner}
is_title={false}
index={index}
/>
),
)}
{Array.from({ length: 6 }, (_, index) => (
<PartnerCard
key={`sponsor-placeholder-${index}`}
partner={{
name: "Logo",
logo: "",
url: "",
tier: "",
}}
is_title={false}
index={partnerData.partners.length + index}
/>
))}
</div>
</div> */}

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
set -euo pipefail

printf 'Files:\n'
git ls-files apps/web/src/components/landing/Partners.tsx apps/web/src/components/landing/partners.json

printf '\nOutline Partners.tsx:\n'
ast-grep outline apps/web/src/components/landing/Partners.tsx --view expanded || true

printf '\nSearch for partners.json usage:\n'
rg -n "partners\.json|partnerData|PartnerCard|Currently under investigation" apps/web/src/components/landing apps/web/src -g '!**/node_modules/**' || true

printf '\nShow relevant section of Partners.tsx:\n'
sed -n '1,220p' apps/web/src/components/landing/Partners.tsx

printf '\nShow partners.json:\n'
sed -n '1,220p' apps/web/src/components/landing/partners.json

Repository: acmutsa/HackKit

Length of output: 6047


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find other render paths or imports of the landing partners component.
rg -n "from ['\"].*Partners['\"]|<Partners\b|partners\.json|partnerData" apps/web -g '!**/node_modules/**' || true

Repository: acmutsa/HackKit

Length of output: 553


Sponsor list is still disabled. Partners.tsx renders the “Currently under investigation” placeholder instead of partnerData.partners, so the entries in partners.json never appear on the page.
apps/web/src/components/landing/Partners.tsx — restore the PartnerCard grid when the sponsors section is ready.

📍 Affects 2 files
  • apps/web/src/components/landing/Partners.tsx#L66-L105 (this comment)
  • apps/web/src/components/landing/partners.json#L4-L26
🤖 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 `@apps/web/src/components/landing/Partners.tsx` around lines 66 - 105, Restore
the PartnerCard grid in the Partners component by removing the “Currently under
investigation” placeholder and re-enabling the rendering of
partnerData.partners, including the existing placeholder cards. In
apps/web/src/components/landing/Partners.tsx lines 66-105, update the disabled
JSX; apps/web/src/components/landing/partners.json lines 4-26 requires no direct
change because its entries should be consumed by the restored grid.

Comment thread apps/web/src/env.ts
client: {
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string(),
},
skipValidation: process.env.NODE_ENV === "production",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== apps/web/src/env.ts ==\n'
cat -n apps/web/src/env.ts

printf '\n== usages of INTERNAL_AUTH_KEY / BOT_API_URL / Clerk / Turso / R2 in apps/web ==\n'
rg -n --hidden --glob 'apps/web/**' 'INTERNAL_AUTH_KEY|BOT_API_URL|CLERK|TURSO|R2|confirmVerifyDiscord|skipValidation' .

printf '\n== any explicit build-only validation opt-out variables ==\n'
rg -n --hidden --glob 'apps/web/**' 'skipValidation|NODE_ENV === "production"|BUILD_ONLY|BUILD_ONLY|VALIDATION|ENV_VALIDATION' apps/web

Repository: acmutsa/HackKit

Length of output: 50374


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== env.ts consumers in apps/web/src ==\n'
rg -n --glob 'apps/web/src/**' 'confirmVerifyDiscord|env\.BOT_API_URL|env\.INTERNAL_AUTH_KEY|createEnv|skipValidation' apps/web/src

printf '\n== confirmVerifyDiscord definition and nearby lines ==\n'
file=$(rg -l --glob 'apps/web/src/**' 'confirmVerifyDiscord' apps/web/src | head -n 1)
if [ -n "${file:-}" ]; then
  echo "FILE: $file"
  sed -n '1,220p' "$file" | cat -n
fi

printf '\n== package version for `@t3-oss/env-nextjs` ==\n'
rg -n --glob 'package.json' '"`@t3-oss/env-nextjs`"|`@t3-oss/env-nextjs`' .

Repository: acmutsa/HackKit

Length of output: 2690


Do not bypass env validation in production apps/web/src/env.ts:23

skipValidation: process.env.NODE_ENV === "production" lets misconfigured production deploys start with missing Clerk/Turso/R2/BOT_API_URL/INTERNAL_AUTH_KEY values, and apps/web/src/actions/discord-verify.ts reads those at runtime. Gate this behind an explicit build-only flag instead of NODE_ENV.

🤖 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 `@apps/web/src/env.ts` at line 23, Update the env validation configuration in
the env schema to stop using NODE_ENV as the skip condition. Gate skipValidation
behind an explicit build-only environment flag, ensuring production runtime
deployments still validate required Clerk, Turso, R2, BOT_API_URL, and
INTERNAL_AUTH_KEY values.

Comment on lines +26 to 70
border: "var(--border)",
input: "var(--input)",
ring: "var(--ring)",
background: "var(--background)",
foreground: "var(--foreground)",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
DEFAULT: "var(--primary)",
foreground: "var(--primary-foreground)",
},
nav: "hsl(var(--nav))",
hackathon: "hsl(var(--hackathon-primary))",
nav: "var(--nav)",
hackathon: "var(--hackathon-primary)",
secondary: {
DEFAULT: "hsl(var(--secondary))",
foreground: "hsl(var(--secondary-foreground))",
DEFAULT: "var(--secondary)",
foreground: "var(--secondary-foreground)",
},
destructive: {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
DEFAULT: "var(--destructive)",
foreground: "var(--destructive-foreground)",
},
muted: {
DEFAULT: "hsl(var(--muted))",
foreground: "hsl(var(--muted-foreground))",
DEFAULT: "var(--muted)",
foreground: "var(--muted-foreground)",
},
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
DEFAULT: "var(--accent)",
foreground: "var(--accent-foreground)",
},
popover: {
DEFAULT: "hsl(var(--popover))",
foreground: "hsl(var(--popover-foreground))",
DEFAULT: "var(--popover)",
foreground: "var(--popover-foreground)",
},
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
DEFAULT: "var(--card)",
foreground: "var(--card-foreground)",
},
sidebar: {
DEFAULT: "hsl(var(--sidebar-background))",
foreground: "hsl(var(--sidebar-foreground))",
primary: "hsl(var(--sidebar-primary))",
"primary-foreground":
"hsl(var(--sidebar-primary-foreground))",
accent: "hsl(var(--sidebar-accent))",
"accent-foreground":
"hsl(var(--sidebar-accent-foreground))",
border: "hsl(var(--sidebar-border))",
ring: "hsl(var(--sidebar-ring))",
DEFAULT: "var(--sidebar)",
foreground: "var(--sidebar-foreground)",
primary: "var(--sidebar-primary)",
"primary-foreground": "var(--sidebar-primary-foreground)",
accent: "var(--sidebar-accent)",
"accent-foreground": "var(--sidebar-accent-foreground)",
border: "var(--sidebar-border)",
ring: "var(--sidebar-ring)",
},

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 | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for opacity-modifier usage on the affected color tokens
rg -nP '\b(bg|text|border|ring|from|to|via|divide|outline|decoration|placeholder|fill|stroke|ring-offset)-(primary|secondary|accent|muted|destructive|card|popover|sidebar|border|input|ring|background|foreground|nav|hackathon)(-[a-z]+)?/\d' apps/web/src

Repository: acmutsa/HackKit

Length of output: 2579


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== tailwind config ==\n'
cat -n apps/web/tailwind.config.js | sed -n '1,140p'

printf '\n== color variable definitions ==\n'
rg -n --no-heading --context 2 --fixed-strings '--primary:' apps/web/src apps/web | sed -n '1,200p'
rg -n --no-heading --context 2 --fixed-strings '--background:' apps/web/src apps/web | sed -n '1,200p'
rg -n --no-heading --context 2 --fixed-strings '--sidebar-ring:' apps/web/src apps/web | sed -n '1,200p'

Repository: acmutsa/HackKit

Length of output: 4425


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== tailwind config excerpt ==\n'
sed -n '1,160p' apps/web/tailwind.config.js | nl -ba

printf '\n== variable declarations in global styles ==\n'
rg -n --no-heading --context 3 -- '--(primary|secondary|destructive|muted|accent|popover|card|border|input|ring|background|foreground|sidebar|sidebar-primary|sidebar-accent|sidebar-border|sidebar-ring):' apps/web/src apps/web

Repository: acmutsa/HackKit

Length of output: 224


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== Tailwind package version ==\n'
rg -n --no-heading '"tailwindcss"|tailwindcss' package.json apps/web/package.json pnpm-lock.yaml package-lock.json yarn.lock 2>/dev/null | sed -n '1,120p'

printf '\n== color variable declarations ==\n'
rg -n --no-heading -e '--(primary|secondary|destructive|muted|accent|popover|card|border|input|ring|background|foreground|nav|hackathon|sidebar|sidebar-primary|sidebar-foreground|sidebar-primary-foreground|sidebar-accent|sidebar-accent-foreground|sidebar-border|sidebar-ring)\s*:' apps/web/src apps/web | sed -n '1,240p'

printf '\n== opacity-modifier usages ==\n'
rg -n --no-heading -e '\b(bg|text|border|ring|from|to|via|divide|outline|decoration|placeholder|fill|stroke|ring-offset)-(primary|secondary|accent|muted|destructive|card|popover|sidebar|border|input|ring|background|foreground|nav|hackathon)(-[a-z]+)?/\d+' apps/web/src | sed -n '1,240p'

Repository: acmutsa/HackKit

Length of output: 1135


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== Tailwind package version ==\n'
rg -n --no-heading -e '"tailwindcss"|tailwindcss' package.json apps/web/package.json pnpm-lock.yaml package-lock.json yarn.lock 2>/dev/null | sed -n '1,120p'

printf '\n== color variable declarations ==\n'
rg -n --no-heading -e '--(primary|secondary|destructive|muted|accent|popover|card|border|input|ring|background|foreground|nav|hackathon|sidebar|sidebar-primary|sidebar-foreground|sidebar-primary-foreground|sidebar-accent|sidebar-accent-foreground|sidebar-border|sidebar-ring)\s*:' apps/web/src apps/web | sed -n '1,240p'

printf '\n== opacity-modifier usages ==\n'
rg -n --no-heading -e '\b(bg|text|border|ring|from|to|via|divide|outline|decoration|placeholder|fill|stroke|ring-offset)-(primary|secondary|accent|muted|destructive|card|popover|sidebar|border|input|ring|background|foreground|nav|hackathon)(-[a-z]+)?/\d+' apps/web/src | sed -n '1,240p'

Repository: acmutsa/HackKit

Length of output: 1135


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== color variable declarations in CSS/SCSS ==\n'
rg -n --no-heading -e '--(primary|secondary|destructive|muted|accent|popover|card|border|input|ring|background|foreground|nav|hackathon|sidebar|sidebar-primary|sidebar-foreground|sidebar-primary-foreground|sidebar-accent|sidebar-accent-foreground|sidebar-border|sidebar-ring)\s*:' \
  apps/web -g '*.css' -g '*.scss' -g '*.pcss' | sed -n '1,240p'

printf '\n== package manifest tailwind refs ==\n'
rg -n --no-heading -e '"tailwindcss"|tailwindcss-animate' apps/web/package.json package.json pnpm-lock.yaml package-lock.json yarn.lock | sed -n '1,200p'

Repository: acmutsa/HackKit

Length of output: 2013


🌐 Web query:

Tailwind CSS opacity modifiers custom color value var(--x) <alpha-value> color-mix documentation

💡 Result:

Tailwind CSS handles opacity modifiers for custom colors differently depending on the version and your implementation method. In Tailwind CSS v4, the framework natively utilizes the CSS color-mix function [1]. When you use a slash-based opacity modifier (e.g., bg-primary/50), Tailwind generates CSS that applies transparency by mixing your color variable with transparent [2][1]: background-color: color-mix(in srgb, var(--color-primary) 50%, transparent); For older versions (v3) or when defining custom colors in your tailwind.config.js that need to support opacity modifiers, the standard approach is to use the placeholder [1][3]. This placeholder acts as a hook that Tailwind replaces with the alpha channel value provided by the utility (e.g., the 50 in bg-primary/50) [1][3]. To make a custom color support this, you must define it in your configuration using a format that allows for an alpha channel, such as [1][4]: // tailwind.config.js module.exports = { theme: { extend: { colors: { primary: 'rgb(var(--color-primary-rgb) / )', }, }, }, } If you are using a raw CSS variable that cannot be easily converted to an RGB/HSL channel format, you can use the color-mix pattern directly in your configuration to enable compatibility with Tailwind's opacity modifiers [5][4]: // tailwind.config.js module.exports = { theme: { extend: { colors: { custom: 'color-mix(in srgb, var(--my-custom-var), transparent calc(100% * (1 - )))', }, }, }, } Note that is a specific keyword recognized by Tailwind's compiler during the utility generation process [3]. When used inside the config, it ensures that your custom color responds to standard Tailwind opacity syntax [1][3]. If you are attempting to use the theme function within your CSS, you can also pass an opacity directly using the slash syntax, such as theme('colors.primary / 50%') [6].

Citations:


Keep these theme colors alpha-aware bg-secondary/80, bg-background/80, from-hackathon/80, and similar utilities already depend on /NN opacity support, but Tailwind 3.4.6 won’t apply that to plain var(--x) color values. Use an <alpha-value>-compatible form or color-mix() so these classes keep working.

🤖 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 `@apps/web/tailwind.config.js` around lines 26 - 70, Update the theme color
values in the Tailwind color configuration, including primary, secondary,
background, hackathon, and related variables, to use an alpha-aware
<alpha-value> form or color-mix() rather than plain var(--x) values. Preserve
the existing color-token mappings and ensure opacity utilities such as
bg-secondary/80, bg-background/80, and from-hackathon/80 are generated
correctly.

Comment on lines 139 to +140
// Come in and change this date to whenever the hackathon starts
startDate: new Date(new Date(2024, 1, 24).setHours(9)),
startDate: new Date(new Date(2026, 9, 3).setHours(14, 0, 0, 0)), // October 3, 2026 at 9:00 AM CDT

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

Use Date.UTC to avoid timezone inconsistencies.

Using new Date(...) and .setHours(...) relies on the system's local timezone. In a local development environment (e.g., US Central Time), this evaluates to 2:00 PM CDT, but in a serverless environment like Cloudflare (which defaults to UTC), it evaluates to 14:00 UTC (9:00 AM CDT).

To ensure the date is deterministic across all environments and matches your comment (9:00 AM CDT = 14:00 UTC), use Date.UTC.

🐛 Proposed fix
-	// Come in and change this date to whenever the hackathon starts
-	startDate: new Date(new Date(2026, 9, 3).setHours(14, 0, 0, 0)), // October 3, 2026 at 9:00 AM CDT
+	// Come in and change this date to whenever the hackathon starts
+	startDate: new Date(Date.UTC(2026, 9, 3, 14, 0, 0)), // October 3, 2026 at 9:00 AM CDT
📝 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
// Come in and change this date to whenever the hackathon starts
startDate: new Date(new Date(2024, 1, 24).setHours(9)),
startDate: new Date(new Date(2026, 9, 3).setHours(14, 0, 0, 0)), // October 3, 2026 at 9:00 AM CDT
// Come in and change this date to whenever the hackathon starts
startDate: new Date(Date.UTC(2026, 9, 3, 14, 0, 0)), // October 3, 2026 at 9:00 AM CDT
🤖 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 `@packages/config/hackkit.config.ts` around lines 139 - 140, Update the
startDate initialization to construct the timestamp with Date.UTC, preserving
October 3, 2026 at 14:00 UTC so it is deterministic across environments and
matches the documented 9:00 AM CDT time.

this must be changet throught hackkit.config since it is not only one button
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.

5 participants