Skip to content

Design v2#889

Merged
dennyabrain merged 15 commits intotattle-made:mainfrom
strangerobot:design-v2
Apr 13, 2026
Merged

Design v2#889
dennyabrain merged 15 commits intotattle-made:mainfrom
strangerobot:design-v2

Conversation

@strangerobot
Copy link
Copy Markdown
Contributor

@strangerobot strangerobot commented Apr 7, 2026


name: UI changes for the homepage


Describe the PR
Made changes to the homepage, added animations, and added new icons.

Summary by CodeRabbit

  • New Features

    • New site shell, navbar with scroll/parallax effects, announcements, projects, recent blogs, support, resources, footer, email subscription, dashed-style button and updated nav link.
  • UI/Style Updates

    • Global reveal/stagger animations, new keyframes, Labrada font, decorative section borders and updated button/link styling.
  • Bug Fixes / Cleanup

    • Removed legacy announcement banner; page wrappers updated to forward layout props; added .DS_Store ignore.
  • Chores

    • Added a new runtime dependency.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 7, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a1a4cae7-4bfe-4dc6-b9c6-210dae0705a6

📥 Commits

Reviewing files that changed from the base of the PR and between 6b6bacc and 29027b5.

📒 Files selected for processing (2)
  • uli-website/src/components/molecules/SupportUs.jsx
  • uli-website/src/pages/blog/index.jsx
✅ Files skipped from review due to trivial changes (1)
  • uli-website/src/pages/blog/index.jsx

📝 Walkthrough

Walkthrough

Adds a new AppShell, navbar, footer scaffold, announcement and content sections, scroll-reveal hooks and CSS animations, several new atom/molecule components, updates many MDX pages to forward props into ContentPageShell, and small build/config edits (.gitignore, package.json, tailwind).

Changes

Cohort / File(s) Summary
Build & config
/.gitignore, uli-website/package.json, uli-website/tailwind.config.js
Add .DS_Store ignore, add @chenglou/pretext dependency, and register labrada font family in Tailwind.
Atoms
uli-website/src/components/atoms/DashedButton.jsx, uli-website/src/components/atoms/NavLinkNew.jsx
Add DashedButton component and styled NavLinkNew (presentation + hover styles).
Core shell & layout
uli-website/src/components/molecules/AppShellNew.jsx, uli-website/src/components/molecules/NavBarNew.jsx, uli-website/src/components/molecules/FooterNew.jsx
Introduce AppShellNew (i18n, Helmet, layout), NavBarNew (mobile menu, scroll parallax) and scaffolded FooterNew.
Announcements
uli-website/src/components/molecules/Announcements.jsx, uli-website/src/components/molecules/AnnouncementBanner.jsx
Add new Announcements component and remove previous AnnouncementBanner file (banner UI relocated/rewritten).
Content sections
uli-website/src/components/molecules/Projects.jsx, uli-website/src/components/molecules/RecentBlogs.jsx, uli-website/src/components/molecules/Resources.jsx, uli-website/src/components/molecules/SupportUs.jsx, uli-website/src/components/molecules/EmailSubscription_Archive.jsx
Add Projects, RecentBlogs (GraphQL + formatting), Resources, SupportUs (accordion), and EmailSubscription UI components.
Section borders & page shell
uli-website/src/components/molecules/SectionBorders.jsx, uli-website/src/components/molecules/ContentPageShell.jsx
Add section border components and refactor ContentPageShell with styled MDX component map, conditional headers, font loading, and adjusted padding.
Hooks & styles
uli-website/src/hooks/useScrollReveal.js, uli-website/src/styles/global.css
Add useScrollReveal/useStaggerReveal hooks (IntersectionObserver), global CSS animations, reveal utilities, and Google Fonts import.
Pages & composition
uli-website/src/pages/new-home.js, uli-website/src/pages/process.mdx, uli-website/src/pages/**/*.mdx (30+ files), uli-website/src/pages/blog/index.jsx
Switch homepage to AppShellNew and Announcements, add process page, update 30+ MDX pages to accept props and spread into ContentPageShell, and tweak blog list styling.
Misc / Removed
uli-website/src/components/molecules/AnnouncementBanner.jsx (removed)
Remove old AnnouncementBanner implementation (replaced by Announcements).

Sequence Diagram(s)

sequenceDiagram
  participant User as User
  participant Browser as Browser
  participant App as AppShellNew
  participant Nav as NavBarNew
  participant Hook as useScrollReveal
  participant Router as Gatsby/Router

  User->>Browser: navigate / load page
  Browser->>App: mount AppShellNew (renders Helmet, NavBarNew, children)
  App->>Nav: render NavBarNew (attach scroll listener)
  Browser->>Hook: observe sections (Announcements, Projects, RecentBlogs)
  Note over Hook,Browser: IntersectionObserver adds "visible" class when in view
  User->>Browser: scroll
  Browser->>Nav: scroll event → NavBarNew updates backgroundPositionX (parallax)
  User->>App: click DashedButton
  App->>Router: navigate(to internal or external URL)
  Router-->>Browser: route change / external navigation
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • maanasb01

Poem

🐇 I hopped through code with stitched delight,
New shells and banners in the night.
Dashed buttons drum and navbars sway,
Animations glow as pages play.
Props pass through — the site takes flight!

🚥 Pre-merge checks | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is incomplete; it lacks required sections like testing steps, expected behavior, and screenshots, and provides only high-level summary statements without specific implementation details. Complete the description by adding: (1) Detailed list of specific changes (new components, modified files, etc.), (2) Steps to test the changes, (3) Expected behavior, (4) Screenshots if applicable, and (5) Any other relevant context.
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% 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 'Design v2' is vague and generic, referring to a design iteration without clearly describing the specific changes made in this PR. Use a more descriptive title that captures the main change, such as 'Redesign homepage with new animations and component updates' or 'Update homepage UI with AppShellNew and section components'.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 14

Note

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

🟡 Minor comments (9)
uli-website/src/components/atoms/DashedButton.jsx-5-8 (1)

5-8: ⚠️ Potential issue | 🟡 Minor

Set an explicit button type to avoid accidental form submission.

Without type="button", this defaults to submit inside forms and can trigger unintended submits.

Suggested fix
     <button
+      type="button"
       className={`font-labrada bg-transparent cursor-pointer border-[0.5px] border-solid [border-image-source:url('/dashed-btn-bg.png')] [border-image-slice:0%_fill] [border-image-repeat:round] hover:bg-[`#FFC8A6`] active:bg-[`#F28948`] ${className}`}
       onClick={onClick}
     >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/atoms/DashedButton.jsx` around lines 5 - 8, In the
DashedButton.jsx component the rendered <button> currently has no explicit type,
which causes it to act as a submit inside forms; update the button element in
the DashedButton component to include an explicit type (e.g., type="button") or
accept a type prop with a default of "button" so callers can override it; ensure
you update the JSX where className and onClick are used and preserve existing
props and behavior.
uli-website/src/pages/new-home.js-40-40 (1)

40-40: ⚠️ Potential issue | 🟡 Minor

Placeholder link to="#" for "Our Process".

The "Our Process" link navigates to #, which doesn't lead anywhere meaningful. Consider either linking to the actual destination, or adding a TODO comment if the page isn't ready yet to track this for follow-up.

Would you like me to open an issue to track adding the actual "Our Process" page link?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/pages/new-home.js` at line 40, The NavLinkNew instance for
"Our Process" uses a placeholder prop to="#" which doesn't navigate to a real
route; update the NavLinkNew element's to prop to the correct route (e.g.,
"/our-process" or the actual destination used elsewhere) or, if the page isn't
ready yet, replace the placeholder with a clear TODO comment and/or link to a
pending issue ID to track it (reference the NavLinkNew component and its to
prop).
uli-website/src/components/molecules/FooterNew.jsx-16-20 (1)

16-20: ⚠️ Potential issue | 🟡 Minor

Footer links are placeholders with no functionality.

"Link 1", "Link 2", "Link 3" have cursor-pointer styling suggesting interactivity, but no onClick handlers or navigation. Either wire up actual navigation or add a TODO comment to track this incomplete work.

-        <Text className="text-[13px] font-medium cursor-pointer">Link 1</Text>
-        <Text className="text-[13px] font-medium cursor-pointer">Link 2</Text>
-        <Text className="text-[13px] font-medium cursor-pointer">Link 3</Text>
+        {/* TODO: Replace with actual footer navigation links */}
+        <Text className="text-[13px] font-medium cursor-pointer">Link 1</Text>
+        <Text className="text-[13px] font-medium cursor-pointer">Link 2</Text>
+        <Text className="text-[13px] font-medium cursor-pointer">Link 3</Text>

Would you like me to open an issue to track completing the footer navigation links?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/FooterNew.jsx` around lines 16 - 20, The
three placeholder Text nodes in FooterNew.jsx ("Link 1", "Link 2", "Link 3") are
styled as interactive but have no navigation; update each Text (or replace with
your app's Link component) to either add proper navigation handlers (e.g.,
onClick that calls navigate/useRouter.push or href attributes) pointing to their
intended routes, or if routes aren't ready add a clear TODO comment and remove
the misleading cursor-pointer style; locate the elements inside the Box in the
FooterNew component and apply the chosen fix consistently for all three link
items.
uli-website/src/styles/global.css-1-1 (1)

1-1: ⚠️ Potential issue | 🟡 Minor

Match the repository's configured @import notation.

Stylelint is already flagging Line 1 because this repo expects @import '…'; rather than @import url('…');, so lint will stay red until the import syntax is normalized.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/styles/global.css` at line 1, Change the CSS `@import` to use
the repository's expected notation (replace the url(...) form with the plain
string form) so the import in global.css matches the lint rule; update the
existing `@import` declaration at the top of global.css to use `@import`
'<font-URL-or-string>'; ensuring the same font URL string is preserved but
without the url(...) wrapper so Stylelint no longer flags the rule.
uli-website/src/styles/global.css-24-124 (1)

24-124: ⚠️ Potential issue | 🟡 Minor

Rename the new keyframes to kebab-case or lint will keep failing.

Stylelint flags each new keyframe name here (fadeUp, fadeIn, fadeRight, scaleIn, borderSlideX, borderSlideY) against the configured keyframes-name-pattern. Please rename them and update the matching animation references.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/styles/global.css` around lines 24 - 124, The keyframe names
(fadeUp, fadeIn, fadeRight, scaleIn, borderSlideX, borderSlideY) violate the
project's keyframes-name-pattern; rename each to kebab-case (e.g., fade-up,
fade-in, fade-right, scale-in, border-slide-x, border-slide-y) and update every
CSS animation/animation-name reference that uses those identifiers (notably the
`@keyframes` declarations and the .border-animate-x, .border-animate-y,
.border-animate-x-delay classes and any other places using
fadeUp/fadeIn/fadeRight/scaleIn) so the names match exactly.
uli-website/src/components/molecules/Projects.jsx-119-120 (1)

119-120: ⚠️ Potential issue | 🟡 Minor

Fix the interpolated class typo in the content column.

Line 120 uses $${...}, so the conditional class becomes $lg:pl-8 instead of lg:pl-8 and the extra desktop padding never applies.

Suggested fix
-        className={`flex flex-col w-full md:w-[60%] lg:w-[65%] gap-8 $${order % 2 != 0 ? "lg:pl-8" : ""}`}
+        className={`flex flex-col w-full md:w-[60%] lg:w-[65%] gap-8 ${order % 2 !== 0 ? "lg:pl-8" : ""}`}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/Projects.jsx` around lines 119 - 120,
The className template in Projects.jsx currently uses "$${...}" causing the
literal "$lg:pl-8" to be emitted; update the interpolation in the Box
component's className (the template that builds the content column) to use a
single "${...}" so the conditional resolves to "lg:pl-8" when order % 2 != 0
instead of "$lg:pl-8".
uli-website/src/components/molecules/Announcements.jsx-18-21 (1)

18-21: ⚠️ Potential issue | 🟡 Minor

Remove the stray > from the border-image utility.

Line 20 turns [border-image-repeat:round] into a different class token, so that style never gets generated/applied.

Suggested fix
-    [border-image-repeat:round]>
+    [border-image-repeat:round]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/Announcements.jsx` around lines 18 - 21,
The class string in Announcements.jsx contains a stray ">" after the custom
Tailwind utility token `[border-image-repeat:round]` which breaks that token (so
the border-image-repeat style is never generated); edit the JSX className where
the tokens `[border-image-source:...]`, `[border-image-slice:...]`,
`[border-image-repeat:round]`, and `animate-[fadeUp_1.2s_ease-out_forwards]` are
declared and remove the trailing ">" so `[border-image-repeat:round]` becomes a
single valid class token.
uli-website/src/components/molecules/ContentPageShell.jsx-320-322 (1)

320-322: ⚠️ Potential issue | 🟡 Minor

Only open external MDX links in a new tab.

This override applies _blank to internal and hash links too, so in-page anchors and same-site links lose their normal navigation behavior. Limit the extra attributes to external URLs only.

Suggested change
   a: (props) => (
-    <StyledLink target="_blank" rel="noopener noreferrer" {...props} />
+    <StyledLink
+      {...props}
+      target={/^https?:\/\//.test(props.href || "") ? "_blank" : undefined}
+      rel={/^https?:\/\//.test(props.href || "") ? "noopener noreferrer" : undefined}
+    />
   ),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/ContentPageShell.jsx` around lines 320 -
322, The custom MDX link renderer currently forces target="_blank" and rel on
every anchor; change the a: renderer (the inline function that returns
<StyledLink ... />) to only add target="_blank" and rel="noopener noreferrer"
when the link is external (e.g., href exists and starts with "http", "//", or
"mailto:") and avoid setting those attributes for hash links (href starting with
"#") or internal/site-relative links (href starting with "/" or same-origin).
Update the renderer to read props.href, branch on those conditions, and pass
target/rel only for external cases while preserving original props for internal
and anchor links.
uli-website/src/components/molecules/RecentBlogs.jsx-30-48 (1)

30-48: ⚠️ Potential issue | 🟡 Minor

Pick the first author separator, not the last one.

The current loop keeps the largest separator index via Math.max, so "Alice & Bob, Carol" becomes "Alice & Bob et al." instead of "Alice et al.". It also risks matching and inside a single name. Use the earliest non-negative separator index.

Suggested change
 function formatAuthor(author) {
   if (typeof author !== "string") return "";
-  let firstDividerIndex = -1;
-  let dividers = ["&", "and", "And", ","];
-  for (let d of dividers) {
-    let i = author.indexOf(d);
-
-    if (firstDividerIndex === -1) {
-      firstDividerIndex = Math.max(firstDividerIndex, i);
-    } else {
-      firstDividerIndex = Math.max(firstDividerIndex, i);
-    }
-  }
+  const dividerIndexes = [" & ", " and ", " And ", ","]
+    .map((divider) => author.indexOf(divider))
+    .filter((index) => index >= 0);
+  const firstDividerIndex = dividerIndexes.length
+    ? Math.min(...dividerIndexes)
+    : -1;
   if (firstDividerIndex === -1) return author;
-
-  author = author.substring(0, firstDividerIndex).trim().concat(" et al.");
-
-  return author;
+  return author.substring(0, firstDividerIndex).trim().concat(" et al.");
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/RecentBlogs.jsx` around lines 30 - 48,
The formatAuthor function currently picks the largest separator index (Math.max)
and can match substrings like "and" inside names; change it to find the earliest
non-negative separator index instead of the last one and ensure "and"/"And" are
matched as whole words (use a regex word-boundary search) so inputs like "Alice
& Bob, Carol" return "Alice et al." and not "Alice & Bob et al."; update the
loop in formatAuthor to compute the minimum positive index (ignore -1) or use
regex to locate the first separator and then substring up to that position.
🧹 Nitpick comments (8)
uli-website/src/components/molecules/SectionBorders.jsx (1)

7-45: Make decorative border layers non-interactive.

These are purely visual overlays; add pointerEvents: "none" so they never block clicks/taps on nearby section content.

Proposed patch
 style={{
   position: "absolute",
+  pointerEvents: "none",
   top: 0,
   left: 0,
   right: 0,
   height: 16,
 }}

Apply the same pointerEvents: "none" to the left/right/bottom decorative border Box styles as well.

Also applies to: 53-93, 102-129

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/SectionBorders.jsx` around lines 7 - 45,
The decorative border Box elements (the ones with className
"border-animate-x-delay" in SectionBorders.jsx that use backgroundImage
'/section-border.svg') are currently interactive and can block clicks; update
the style objects for those decorative Boxes (left, right, and any bottom border
Boxes around the title) to include pointerEvents: "none" so they never capture
pointer events and do not block nearby content interactions.
uli-website/src/components/atoms/NavLinkNew.jsx (1)

6-13: Remove stale commented-out NavLink code.

This block is dead and adds noise now that NavLinkNew is the active implementation.

Proposed patch
-// // Navlink component for the new design
-// export default function NavLink({children, className=""}) {
-//   return (
-//     <Text className={`cursor-pointer hover:text-[`#F28948`] hover:underline #{className}`}>{children}</Text>
-    
-//   )
-// }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/atoms/NavLinkNew.jsx` around lines 6 - 13, Remove
the stale commented-out NavLink block in NavLinkNew.jsx: delete the old
commented export default function NavLink({children, className=""}) { ... } so
the file only contains the active NavLinkNew implementation; ensure no other
dead commented NavLink code remains and run a quick lint/format to keep the file
clean.
uli-website/src/components/atoms/DashedButton.jsx (1)

6-6: Consider adding a visible keyboard focus style.

Hover/active states are defined, but an explicit focus-visible style would improve keyboard accessibility consistency.

Suggested refactor
-      className={`font-labrada bg-transparent cursor-pointer border-[0.5px] border-solid [border-image-source:url('/dashed-btn-bg.png')] [border-image-slice:0%_fill] [border-image-repeat:round] hover:bg-[`#FFC8A6`] active:bg-[`#F28948`] ${className}`}
+      className={`font-labrada bg-transparent cursor-pointer border-[0.5px] border-solid [border-image-source:url('/dashed-btn-bg.png')] [border-image-slice:0%_fill] [border-image-repeat:round] hover:bg-[`#FFC8A6`] active:bg-[`#F28948`] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[`#F28948`] ${className}`}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/atoms/DashedButton.jsx` at line 6, The button's
className in DashedButton.jsx lacks a keyboard focus-visible style; update the
className template used in the DashedButton component to include an explicit
focus-visible utility (e.g., focus-visible:outline or focus-visible:ring with
color/offset) so keyboard users see a clear visible focus state alongside the
existing hover/active styles.
uli-website/src/components/molecules/FooterNew.jsx (2)

1-4: Remove unused imports.

Several imports are unused: useState, useEffect, useContext, Nav, ResponsiveContext, NavLink, and navigate. Clean these up to reduce bundle size and improve clarity.

-import React, { useState, useEffect, useContext } from "react";
-import { Box, Nav, Text, ResponsiveContext } from "grommet";
-import { NavLink } from "../atoms/UliCore";
-import { navigate } from "gatsby";
+import React from "react";
+import { Box, Text } from "grommet";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/FooterNew.jsx` around lines 1 - 4, The
import list contains unused symbols—remove useState, useEffect, useContext, Nav,
ResponsiveContext, NavLink, and navigate from the top imports in FooterNew.jsx;
keep only the actual used exports (e.g., React plus Box and Text from "grommet")
so the component (FooterNew) imports only what it uses and reduces bundle size
and dead code.

6-7: Remove dead code.

The commented-out size variable (line 7) should be removed if it's not needed.

 export default function FooterNew() {
-  // const size = useContext(ResponsiveContext);
-
   return (
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/FooterNew.jsx` around lines 6 - 7,
Remove the dead commented code referencing the unused size variable in the
FooterNew component: delete the commented line "// const size =
useContext(ResponsiveContext);" inside the FooterNew function and, if present,
also remove any now-unused imports like ResponsiveContext or useContext to keep
the file clean; ensure FooterNew still compiles and runs after removing the dead
code.
uli-website/src/pages/new-home.js (1)

7-9: Remove unused import.

Resources is imported on line 7 but never used (the JSX usage on line 47 is commented out). Line 9 is also a duplicate commented import. Remove the unused import to keep the code clean.

 import RecentBlogs from "../components/molecules/RecentBlogs";
-import Resources from "../components/molecules/Resources";
 import SupportUs from "../components/molecules/SupportUs";
-// import Resources from "../components/molecules/Resources";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/pages/new-home.js` around lines 7 - 9, Remove the unused
Resources import and the duplicate commented import: delete the import statement
"import Resources from ../components/molecules/Resources" (the one that is
unused because the <Resources /> JSX on line ~47 is commented out) and also
remove the commented duplicate import line; keep only the needed imports such as
SupportUs and ensure there are no remaining references to the Resources symbol
in new-home.js.
uli-website/src/styles/global.css (1)

86-93: Drop the first duplicate stagger-visible rule.

Lines 86-89 keep staggered children hidden, but Lines 90-93 immediately override the exact same selector with the visible state. The first block is dead/confusing.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/styles/global.css` around lines 86 - 93, Remove the duplicate
rule that uses the selector ".reveal-stagger.visible > *" which sets opacity: 0
and transform: translateY(16px); and either place the initial hidden state on
the non-.visible selector (e.g., ".reveal-stagger > *") or delete the first
block so only the visible-state rule remains; update the CSS so the initial
hidden state and the visible-state rule are not defined on the identical
selector ".reveal-stagger.visible > *" to avoid the dead/overridden declaration.
uli-website/src/components/molecules/RecentBlogs.jsx (1)

78-78: Remove the leftover query logging before merge.

This will log on every homepage render in production and adds noise to the browser console.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/RecentBlogs.jsx` at line 78, Remove the
leftover console.log(data) in the RecentBlogs component so it doesn't log on
every homepage render in production; locate the console.log call in
RecentBlogs.jsx (inside the RecentBlogs component where data is handled) and
delete it (or replace it with a development-only logger guard if you need
runtime debugging), ensuring no stray console logging remains before merging.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@uli-website/src/components/molecules/Announcements.jsx`:
- Around line 35-43: The component currently contains Figma implementation notes
inside the Text node and a DashedButton that navigates to "/" which is a no-op
on the homepage; update the placeholder announcement copy in Announcements.jsx
by replacing the Text content with the real announcement message, change the
DashedButton content label from "learn more" to the intended CTA text, and
update its onClick (or replace navigate("/")) to the correct target route or
external URL; alternatively, refactor Announcements.jsx to accept props (message
and ctaHref/ctaOnClick) and wire the button to use those props so the live site
won’t ship the placeholder copy or a dead link.

In `@uli-website/src/components/molecules/AppShellNew.jsx`:
- Around line 19-29: The homepage OG title is empty because location.pathname
"/" gets normalized to an empty string and then passed to formatTitle; update
the logic around fullPath/title so that after trimming the trailing "/" and
deriving title (variables fullPath and title) you check if title is falsy (empty
string) or matches the locale list and set title = "Uli" before calling
formatTitle; ensure the same change covers the branch that currently checks
["hi","en","ta","ma"] and that the final title used for the og:title (where
formatTitle is applied) will never be empty.

In `@uli-website/src/components/molecules/ContentPageShell.jsx`:
- Around line 341-349: In formatDate, detect date-only frontmatter (e.g. strings
matching /^\d{4}-\d{2}-\d{2}$/) and treat them as calendar dates in UTC to avoid
local timezone shifts: parse the year/month/day parts and construct the Date via
Date.UTC(year, month-1, day) (or new Date(Date.UTC(...))), then call
toLocaleDateString with a fixed timeZone ('UTC') and the existing day/month/year
options; for non-date-only inputs keep the current parsing but format them with
the same fixed timeZone or leave as-is per project preference so viewers west of
UTC do not see the previous-day result.

In `@uli-website/src/components/molecules/EmailSubscription_Archive.jsx`:
- Around line 20-40: The form currently uses action="#" so submitted emails are
discarded; update the EmailSubscription_Archive component to manage the email
input with React state (e.g., useState for an email value), add an onSubmit
handler on the <form> (replace action="#" with onSubmit), call
event.preventDefault(), validate the email, then perform the submit action
(either call a provided prop like onSubscribe(email) or send a network request
via fetch/axios) and handle success/error UI; ensure the <input> has a name/id
and value/onChange tied to state and the <button> remains type="submit" (and
remove the nonstandard <Text> wrapper) so keyboard/ARIA behavior stays correct.
- Around line 35-40: The email input in the EmailSubscription_Archive component
is using type="text" with no accessible name; change the input to type="email",
add a name attribute and a unique id, and provide an associated visible <label
for="..."> or at minimum an aria-label (e.g., aria-label="Email address") so
screen readers and browser autofill/validation work; update the input referenced
in the component (the input element next to the mail logo and the subscribe
button) and keep existing classes/markup intact.

In `@uli-website/src/components/molecules/NavBarNew.jsx`:
- Line 59: The mobile menu toggle button in NavBarNew.jsx (the button that calls
setOpen and reads open) lacks an accessible name and aria-expanded, so update
that button to provide an accessible label and state: set a dynamic aria-label
(e.g., aria-label={open ? "Close menu" : "Open menu"}), add aria-expanded={open}
and optionally aria-controls pointing to the mobile menu container id (e.g.,
"mobile-menu") so assistive tech knows what it controls; keep the img decorative
(alt="") or remove alt if you rely on the button label.
- Around line 61-70: The NavBarNew component currently uses placeholder anchors
for menu items — replace the NavLinkNew instances for the "Contact" and "Data Y"
items (desktop and mobile variants rendered by NavLinkNew) so they point to real
routes or route constants instead of "#" (update the NavLinkNew with proper
to="/contact" and to="/data-y" or your app's matching route names/route
constants), ensuring both the desktop block around the Box and the mobile menu
blocks use the same real route values.

In `@uli-website/src/components/molecules/Projects.jsx`:
- Around line 18-27: The buttons array in Projects.jsx contains external URLs
but the component's button click handler currently routes all clicks through
Gatsby's navigate(), which only supports internal routes; update the click
handling logic in the Projects component (the handler that calls navigate()) to
detect external URLs (e.g., strings starting with "http://" or "https://") and
use standard navigation (render an anchor <a href="..."> for links or call
window.location.assign(url) for programmatic navigation) for those, while
retaining Gatsby's navigate() for internal routes; also replace the "/#"
placeholder entries in the buttons array with real internal paths or ensure they
are treated as internal routes rather than external.

In `@uli-website/src/components/molecules/RecentBlogs.jsx`:
- Around line 94-108: The row uses a clickable Box with onClick and an inner
Text that also calls navigate(blog.fields.slug), which breaks
keyboard/accessibility and link behaviors; replace the clickable Box with a
semantic anchor/link element (or your routing Link) for the whole row and set
its href to blog.fields.slug, remove the onClick handlers from Box and inner
Text (so only the anchor performs navigation), preserve displayed values from
formatDate(blog.frontmatter.date), blog.frontmatter.name, and
formatAuthor(blog.frontmatter.author), and ensure the anchor supports target/rel
if needed for open-in-new-tab behavior.
- Around line 7-20: The formatDate function currently coerces the input with
Number(input) which turns ISO date strings into NaN and causes "Invalid date"
for every post; change formatDate to parse the ISO string directly (e.g., pass
input into new Date(input) or use Date.parse(input) before new Date) and keep
the existing validation (isNaN(date.getTime())) to handle bad input; also remove
the stray debug console.log(data) in RecentBlogs.jsx so no debug output is left
in production.

In `@uli-website/src/components/molecules/Resources.jsx`:
- Around line 113-122: The resource row uses a clickable Box with onClick and a
nested Text that also has onClick, and the Box isn't keyboard-accessible; update
the interaction to be keyboard-friendly and avoid duplicate navigation: make the
outer Box a semantic interactive element (e.g., render as a <button> or add
role="button" and tabIndex={0}), implement an onKeyDown handler on the Box that
triggers navigate(r.url) for Enter/Space, and remove the nested Text's onClick
(or stop propagation) so only the row-level navigate(r.url) is invoked; keep the
navigate call centralized in the Box's onClick/onKeyDown handlers (referencing
Box, Text, navigate, and r.url).

In `@uli-website/src/components/molecules/SupportUs.jsx`:
- Around line 25-49: The CTA items array currently lacks explicit action
targets, causing the click handler (the onClick for the CTA button that checks
for "email" in the label) to only handle mailto actions and leave "Uli
Community" and "Uli Github" inert; add a clear action field to each object in
items (e.g., url or href with either a full URL or a mailto: link) and then
update the CTA button's click handler (the component's onClick function) to use
that field (open external links with window.open or navigate, and use mailto:
links when the href starts with mailto:) instead of branching on buttonText;
reference the items array and the CTA button onClick handler when making
changes.
- Around line 107-145: Replace the clickable header div with a semantic <button
type="button"> (preserve className, inline styles, onClick={onToggle},
onMouseEnter/onMouseLeave handlers and child components MaskIcon, item.title,
PixelatedArrow) so it becomes keyboard-focusable; add aria-expanded={isOpen} and
aria-controls pointing to the expandable panel id (e.g.
aria-controls={`support-panel-${item.id}`}), give the expandable content
container a matching id and role="region" and optional aria-labelledby
referencing the button id, and ensure you do not remove the browser focus
outline (avoid forcing outline:none) so keyboard users can see focus.

In `@uli-website/src/hooks/useScrollReveal.js`:
- Around line 15-31: The IntersectionObserver block in useScrollReveal's
useEffect can leave elements hidden when the API is unavailable or blocked;
update the effect in useScrollReveal (the useEffect that references ref and
creates a new IntersectionObserver) to detect lack of support and immediately
add the "visible" class (i.e., if typeof IntersectionObserver === "undefined" or
window.IntersectionObserver is falsy) and return early; also add the same
fallback to the second identical useEffect (the other block that observes ref
and toggles "visible") so elements don't remain hidden in browsers/environments
without IntersectionObserver support.

---

Minor comments:
In `@uli-website/src/components/atoms/DashedButton.jsx`:
- Around line 5-8: In the DashedButton.jsx component the rendered <button>
currently has no explicit type, which causes it to act as a submit inside forms;
update the button element in the DashedButton component to include an explicit
type (e.g., type="button") or accept a type prop with a default of "button" so
callers can override it; ensure you update the JSX where className and onClick
are used and preserve existing props and behavior.

In `@uli-website/src/components/molecules/Announcements.jsx`:
- Around line 18-21: The class string in Announcements.jsx contains a stray ">"
after the custom Tailwind utility token `[border-image-repeat:round]` which
breaks that token (so the border-image-repeat style is never generated); edit
the JSX className where the tokens `[border-image-source:...]`,
`[border-image-slice:...]`, `[border-image-repeat:round]`, and
`animate-[fadeUp_1.2s_ease-out_forwards]` are declared and remove the trailing
">" so `[border-image-repeat:round]` becomes a single valid class token.

In `@uli-website/src/components/molecules/ContentPageShell.jsx`:
- Around line 320-322: The custom MDX link renderer currently forces
target="_blank" and rel on every anchor; change the a: renderer (the inline
function that returns <StyledLink ... />) to only add target="_blank" and
rel="noopener noreferrer" when the link is external (e.g., href exists and
starts with "http", "//", or "mailto:") and avoid setting those attributes for
hash links (href starting with "#") or internal/site-relative links (href
starting with "/" or same-origin). Update the renderer to read props.href,
branch on those conditions, and pass target/rel only for external cases while
preserving original props for internal and anchor links.

In `@uli-website/src/components/molecules/FooterNew.jsx`:
- Around line 16-20: The three placeholder Text nodes in FooterNew.jsx ("Link
1", "Link 2", "Link 3") are styled as interactive but have no navigation; update
each Text (or replace with your app's Link component) to either add proper
navigation handlers (e.g., onClick that calls navigate/useRouter.push or href
attributes) pointing to their intended routes, or if routes aren't ready add a
clear TODO comment and remove the misleading cursor-pointer style; locate the
elements inside the Box in the FooterNew component and apply the chosen fix
consistently for all three link items.

In `@uli-website/src/components/molecules/Projects.jsx`:
- Around line 119-120: The className template in Projects.jsx currently uses
"$${...}" causing the literal "$lg:pl-8" to be emitted; update the interpolation
in the Box component's className (the template that builds the content column)
to use a single "${...}" so the conditional resolves to "lg:pl-8" when order % 2
!= 0 instead of "$lg:pl-8".

In `@uli-website/src/components/molecules/RecentBlogs.jsx`:
- Around line 30-48: The formatAuthor function currently picks the largest
separator index (Math.max) and can match substrings like "and" inside names;
change it to find the earliest non-negative separator index instead of the last
one and ensure "and"/"And" are matched as whole words (use a regex word-boundary
search) so inputs like "Alice & Bob, Carol" return "Alice et al." and not "Alice
& Bob et al."; update the loop in formatAuthor to compute the minimum positive
index (ignore -1) or use regex to locate the first separator and then substring
up to that position.

In `@uli-website/src/pages/new-home.js`:
- Line 40: The NavLinkNew instance for "Our Process" uses a placeholder prop
to="#" which doesn't navigate to a real route; update the NavLinkNew element's
to prop to the correct route (e.g., "/our-process" or the actual destination
used elsewhere) or, if the page isn't ready yet, replace the placeholder with a
clear TODO comment and/or link to a pending issue ID to track it (reference the
NavLinkNew component and its to prop).

In `@uli-website/src/styles/global.css`:
- Line 1: Change the CSS `@import` to use the repository's expected notation
(replace the url(...) form with the plain string form) so the import in
global.css matches the lint rule; update the existing `@import` declaration at the
top of global.css to use `@import` '<font-URL-or-string>'; ensuring the same font
URL string is preserved but without the url(...) wrapper so Stylelint no longer
flags the rule.
- Around line 24-124: The keyframe names (fadeUp, fadeIn, fadeRight, scaleIn,
borderSlideX, borderSlideY) violate the project's keyframes-name-pattern; rename
each to kebab-case (e.g., fade-up, fade-in, fade-right, scale-in,
border-slide-x, border-slide-y) and update every CSS animation/animation-name
reference that uses those identifiers (notably the `@keyframes` declarations and
the .border-animate-x, .border-animate-y, .border-animate-x-delay classes and
any other places using fadeUp/fadeIn/fadeRight/scaleIn) so the names match
exactly.

---

Nitpick comments:
In `@uli-website/src/components/atoms/DashedButton.jsx`:
- Line 6: The button's className in DashedButton.jsx lacks a keyboard
focus-visible style; update the className template used in the DashedButton
component to include an explicit focus-visible utility (e.g.,
focus-visible:outline or focus-visible:ring with color/offset) so keyboard users
see a clear visible focus state alongside the existing hover/active styles.

In `@uli-website/src/components/atoms/NavLinkNew.jsx`:
- Around line 6-13: Remove the stale commented-out NavLink block in
NavLinkNew.jsx: delete the old commented export default function
NavLink({children, className=""}) { ... } so the file only contains the active
NavLinkNew implementation; ensure no other dead commented NavLink code remains
and run a quick lint/format to keep the file clean.

In `@uli-website/src/components/molecules/FooterNew.jsx`:
- Around line 1-4: The import list contains unused symbols—remove useState,
useEffect, useContext, Nav, ResponsiveContext, NavLink, and navigate from the
top imports in FooterNew.jsx; keep only the actual used exports (e.g., React
plus Box and Text from "grommet") so the component (FooterNew) imports only what
it uses and reduces bundle size and dead code.
- Around line 6-7: Remove the dead commented code referencing the unused size
variable in the FooterNew component: delete the commented line "// const size =
useContext(ResponsiveContext);" inside the FooterNew function and, if present,
also remove any now-unused imports like ResponsiveContext or useContext to keep
the file clean; ensure FooterNew still compiles and runs after removing the dead
code.

In `@uli-website/src/components/molecules/RecentBlogs.jsx`:
- Line 78: Remove the leftover console.log(data) in the RecentBlogs component so
it doesn't log on every homepage render in production; locate the console.log
call in RecentBlogs.jsx (inside the RecentBlogs component where data is handled)
and delete it (or replace it with a development-only logger guard if you need
runtime debugging), ensuring no stray console logging remains before merging.

In `@uli-website/src/components/molecules/SectionBorders.jsx`:
- Around line 7-45: The decorative border Box elements (the ones with className
"border-animate-x-delay" in SectionBorders.jsx that use backgroundImage
'/section-border.svg') are currently interactive and can block clicks; update
the style objects for those decorative Boxes (left, right, and any bottom border
Boxes around the title) to include pointerEvents: "none" so they never capture
pointer events and do not block nearby content interactions.

In `@uli-website/src/pages/new-home.js`:
- Around line 7-9: Remove the unused Resources import and the duplicate
commented import: delete the import statement "import Resources from
../components/molecules/Resources" (the one that is unused because the
<Resources /> JSX on line ~47 is commented out) and also remove the commented
duplicate import line; keep only the needed imports such as SupportUs and ensure
there are no remaining references to the Resources symbol in new-home.js.

In `@uli-website/src/styles/global.css`:
- Around line 86-93: Remove the duplicate rule that uses the selector
".reveal-stagger.visible > *" which sets opacity: 0 and transform:
translateY(16px); and either place the initial hidden state on the non-.visible
selector (e.g., ".reveal-stagger > *") or delete the first block so only the
visible-state rule remains; update the CSS so the initial hidden state and the
visible-state rule are not defined on the identical selector
".reveal-stagger.visible > *" to avoid the dead/overridden declaration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 158fe569-5f70-4c45-8aeb-cc02cdb8ec16

📥 Commits

Reviewing files that changed from the base of the PR and between 5a35861 and c46a378.

⛔ Files ignored due to path filters (19)
  • .DS_Store is excluded by !**/.DS_Store
  • uli-website/.DS_Store is excluded by !**/.DS_Store
  • uli-website/package-lock.json is excluded by !**/package-lock.json
  • uli-website/static/Track_Icons/Database.png is excluded by !**/*.png
  • uli-website/static/Track_Icons/Slur Editor.png is excluded by !**/*.png
  • uli-website/static/Track_Icons/Tools.png is excluded by !**/*.png
  • uli-website/static/Track_Icons/Workshops.png is excluded by !**/*.png
  • uli-website/static/cross-icon.svg is excluded by !**/*.svg
  • uli-website/static/dashed-btn-bg.png is excluded by !**/*.png
  • uli-website/static/hamburger-icon.svg is excluded by !**/*.svg
  • uli-website/static/heading.svg is excluded by !**/*.svg
  • uli-website/static/mail-logo.svg is excluded by !**/*.svg
  • uli-website/static/project-card-bg.svg is excluded by !**/*.svg
  • uli-website/static/project-card-logo.svg is excluded by !**/*.svg
  • uli-website/static/section-border-vertical.svg is excluded by !**/*.svg
  • uli-website/static/section-border.svg is excluded by !**/*.svg
  • uli-website/static/subscribe-bar-bg.svg is excluded by !**/*.svg
  • uli-website/static/subscribe-btn-bg.png is excluded by !**/*.png
  • uli-website/static/top-border.svg is excluded by !**/*.svg
📒 Files selected for processing (53)
  • .gitignore
  • uli-website/package.json
  • uli-website/src/components/atoms/DashedButton.jsx
  • uli-website/src/components/atoms/NavLinkNew.jsx
  • uli-website/src/components/molecules/AnnouncementBanner.jsx
  • uli-website/src/components/molecules/Announcements.jsx
  • uli-website/src/components/molecules/AppShellNew.jsx
  • uli-website/src/components/molecules/ContentPageShell.jsx
  • uli-website/src/components/molecules/EmailSubscription_Archive.jsx
  • uli-website/src/components/molecules/FooterNew.jsx
  • uli-website/src/components/molecules/NavBarNew.jsx
  • uli-website/src/components/molecules/Projects.jsx
  • uli-website/src/components/molecules/RecentBlogs.jsx
  • uli-website/src/components/molecules/Resources.jsx
  • uli-website/src/components/molecules/SectionBorders.jsx
  • uli-website/src/components/molecules/SupportUs.jsx
  • uli-website/src/hooks/useScrollReveal.js
  • uli-website/src/pages/about.mdx
  • uli-website/src/pages/blog/Uli-workshop.mdx
  • uli-website/src/pages/blog/approach-data-annotation.mdx
  • uli-website/src/pages/blog/approach.mdx
  • uli-website/src/pages/blog/chisel-online-abuse.mdx
  • uli-website/src/pages/blog/collective-journey.mdx
  • uli-website/src/pages/blog/context-matters.mdx
  • uli-website/src/pages/blog/cross-platform-pt1.mdx
  • uli-website/src/pages/blog/cross-platform_pt_2.mdx
  • uli-website/src/pages/blog/getting-started-with-aws-copilot.mdx
  • uli-website/src/pages/blog/hover-feature-making.mdx
  • uli-website/src/pages/blog/making-of-August-2023.mdx
  • uli-website/src/pages/blog/making-of-dec-2021.mdx
  • uli-website/src/pages/blog/making-of-dec-2023.mdx
  • uli-website/src/pages/blog/making-of-feb-2022.mdx
  • uli-website/src/pages/blog/making-of-jan-2022.mdx
  • uli-website/src/pages/blog/making-of-mar-2022.mdx
  • uli-website/src/pages/blog/responsible-display.mdx
  • uli-website/src/pages/blog/silencing-impact-OGBV.mdx
  • uli-website/src/pages/blog/slurs-occur-every-language.mdx
  • uli-website/src/pages/blog/tech4dev-user-research-lessons.mdx
  • uli-website/src/pages/blog/uli-privacy.mdx
  • uli-website/src/pages/blog/workshop-tech-dev.mdx
  • uli-website/src/pages/faq.mdx
  • uli-website/src/pages/hi/about.mdx
  • uli-website/src/pages/hi/faq.mdx
  • uli-website/src/pages/new-home.js
  • uli-website/src/pages/privacy-policy.mdx
  • uli-website/src/pages/research.mdx
  • uli-website/src/pages/resources.mdx
  • uli-website/src/pages/ta/about.mdx
  • uli-website/src/pages/ta/faq.mdx
  • uli-website/src/pages/team-2021.mdx
  • uli-website/src/pages/uli-for-ts.mdx
  • uli-website/src/styles/global.css
  • uli-website/tailwind.config.js
💤 Files with no reviewable changes (1)
  • uli-website/src/components/molecules/AnnouncementBanner.jsx

Comment on lines +19 to +29
let fullPath = location.pathname;
if (fullPath.slice(-1) === "/") {
fullPath = fullPath.slice(0, -1);
}
let title = fullPath.split("/").at(-1);

if (["hi", "en", "ta", "ma"].includes(title)) {
title = "Uli";
}

title = formatTitle(title);
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 | 🟠 Major

The homepage og:title resolves to an empty string.

For /, Lines 19-23 normalize the path to "", so title stays empty and Line 51 emits a blank Open Graph title on the homepage. Please default the root/empty case to "Uli" before formatting.

Also applies to: 51-51

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/AppShellNew.jsx` around lines 19 - 29,
The homepage OG title is empty because location.pathname "/" gets normalized to
an empty string and then passed to formatTitle; update the logic around
fullPath/title so that after trimming the trailing "/" and deriving title
(variables fullPath and title) you check if title is falsy (empty string) or
matches the locale list and set title = "Uli" before calling formatTitle; ensure
the same change covers the branch that currently checks ["hi","en","ta","ma"]
and that the final title used for the og:title (where formatTitle is applied)
will never be empty.

Comment on lines +341 to +349
function formatDate(input) {
if (!input) return "";
const d = new Date(input);
if (isNaN(d.getTime())) return String(input);
return d.toLocaleDateString("en-GB", {
day: "numeric",
month: "long",
year: "numeric",
});
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 | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
node - <<'NODE'
const input = "2021-08-01";
for (const tz of ["UTC", "America/Los_Angeles", "Asia/Kolkata"]) {
  console.log(
    tz,
    new Date(input).toLocaleDateString("en-GB", {
      day: "numeric",
      month: "long",
      year: "numeric",
      timeZone: tz,
    })
  );
}
NODE

Repository: tattle-made/Uli

Length of output: 136


🏁 Script executed:

#!/bin/bash
node - <<'NODE'
// Test the suggested fix with various inputs
const inputs = [
  "2021-08-01",           // date-only
  "2021-08-01T12:00:00Z", // datetime with Z
  "2021-08-01T12:00:00",  // datetime without timezone
  1627804800000,          // timestamp (2021-08-01 00:00:00 UTC)
  "invalid-date",         // invalid input
  "",                      // empty string
  null,                    // null
  "08/01/2021"            // different format
];

function formatDateOriginal(input) {
  if (!input) return "";
  const d = new Date(input);
  if (isNaN(d.getTime())) return String(input);
  return d.toLocaleDateString("en-GB", {
    day: "numeric",
    month: "long",
    year: "numeric",
  });
}

function formatDateFixed(input) {
  if (!input) return "";
  const normalized =
    /^\d{4}-\d{2}-\d{2}$/.test(String(input))
      ? `${input}T00:00:00Z`
      : input;
  const d = new Date(normalized);
  if (isNaN(d.getTime())) return String(input);
  return d.toLocaleDateString("en-GB", {
    day: "numeric",
    month: "long",
    year: "numeric",
    timeZone: "UTC",
  });
}

console.log("Testing Original vs Fixed in America/Los_Angeles:");
inputs.forEach(input => {
  const orig = formatDateOriginal(input);
  const fixed = formatDateFixed(input);
  console.log(`Input: ${JSON.stringify(input)}`);
  console.log(`  Original (LA): ${orig}`);
  console.log(`  Fixed (UTC):   ${fixed}`);
  console.log();
});
NODE

Repository: tattle-made/Uli

Length of output: 722


🏁 Script executed:

cd uli-website && grep -r "formatDate" --include="*.jsx" --include="*.js" --include="*.ts" --include="*.tsx" | head -20

Repository: tattle-made/Uli

Length of output: 568


🏁 Script executed:

cat -n uli-website/src/components/molecules/RecentBlogs.jsx | grep -A 8 "function formatDate"

Repository: tattle-made/Uli

Length of output: 345


🏁 Script executed:

cat -n uli-website/src/pages/blog/index.jsx | grep -B 2 -A 8 "const formatDate"

Repository: tattle-made/Uli

Length of output: 506


Preserve the calendar day for date-only frontmatter.

new Date("2021-08-01") is parsed at midnight UTC, then formatted in the viewer's local timezone. For users west of UTC, this renders as 31 July 2021, so post metadata becomes off by one day. Normalize date-only inputs and format them in a fixed timezone.

Suggested change
 function formatDate(input) {
   if (!input) return "";
-  const d = new Date(input);
+  const normalized =
+    /^\d{4}-\d{2}-\d{2}$/.test(String(input))
+      ? `${input}T00:00:00Z`
+      : input;
+  const d = new Date(normalized);
   if (isNaN(d.getTime())) return String(input);
   return d.toLocaleDateString("en-GB", {
     day: "numeric",
     month: "long",
     year: "numeric",
+    timeZone: "UTC",
   });
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/ContentPageShell.jsx` around lines 341 -
349, In formatDate, detect date-only frontmatter (e.g. strings matching
/^\d{4}-\d{2}-\d{2}$/) and treat them as calendar dates in UTC to avoid local
timezone shifts: parse the year/month/day parts and construct the Date via
Date.UTC(year, month-1, day) (or new Date(Date.UTC(...))), then call
toLocaleDateString with a fixed timeZone ('UTC') and the existing day/month/year
options; for non-date-only inputs keep the current parsing but format them with
the same fixed timeZone or leave as-is per project preference so viewers west of
UTC do not see the previous-day result.

Comment on lines +20 to +40
<form action="#" className="w-full flex justify-center">
<div
className="w-full lg:w-[50%] 2xl:w-[30%]
border-1
border-solid
[border-image-source:url('/subscribe-bar-bg.svg')]
[border-image-slice:0%_fill]
[border-image-repeat:round]
relative
flex
flex-row
px-3
items-center
"
>
<img src="/mail-logo.svg" alt="" />
<input
type="text"
className="w-full h-10 px-3 outline-none border-none bg-transparent"
/>
<button className="border-0 px-5 h-7 text-white bg-[url(/subscribe-btn-bg.png)] cursor-pointer font-labrada"><Text className="text-[13px]">subscribe</Text></button>
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 | 🟠 Major

The subscribe form currently discards the email address.

With action="#" and a default submit button, clicking “subscribe” or pressing Enter just submits back to the same page fragment. There is no submit handler or network action here, so the flow cannot work.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/EmailSubscription_Archive.jsx` around
lines 20 - 40, The form currently uses action="#" so submitted emails are
discarded; update the EmailSubscription_Archive component to manage the email
input with React state (e.g., useState for an email value), add an onSubmit
handler on the <form> (replace action="#" with onSubmit), call
event.preventDefault(), validate the email, then perform the submit action
(either call a provided prop like onSubscribe(email) or send a network request
via fetch/axios) and handle success/error UI; ensure the <input> has a name/id
and value/onChange tied to state and the <button> remains type="submit" (and
remove the nonstandard <Text> wrapper) so keyboard/ARIA behavior stays correct.

Comment on lines +35 to +40
<img src="/mail-logo.svg" alt="" />
<input
type="text"
className="w-full h-10 px-3 outline-none border-none bg-transparent"
/>
<button className="border-0 px-5 h-7 text-white bg-[url(/subscribe-btn-bg.png)] cursor-pointer font-labrada"><Text className="text-[13px]">subscribe</Text></button>
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 | 🟠 Major

Use a real email field with an accessible label.

The input on Lines 36-39 has no associated label/name and uses type="text", so screen readers get no field name and browsers cannot provide email validation/autofill. This should be type="email" plus a visible label or aria-label.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/EmailSubscription_Archive.jsx` around
lines 35 - 40, The email input in the EmailSubscription_Archive component is
using type="text" with no accessible name; change the input to type="email", add
a name attribute and a unique id, and provide an associated visible <label
for="..."> or at minimum an aria-label (e.g., aria-label="Email address") so
screen readers and browser autofill/validation work; update the input referenced
in the component (the input element next to the mail logo and the subscribe
button) and keep existing classes/markup intact.

Comment on lines +94 to +108
<Box
key={idx}
className=" mx-auto border-t-0 border-r-0 border-l-0 border-b-2 border-dashed border-black/30 flex flex-col lg:flex-row gap-1 lg:gap-6 w-full lg:w-[70%] 2xl:w-[50%] pb-2 hover:bg-[#FFE7D9] active:bg-[#FFC8A6] focus:outline-none focus:ring-0 hover:scale-103 transition-transform duration-300 ease-in-out"
onClick={() => navigate(blog.fields.slug)}
>
<Text className="min-w-[7em] text-xs lg:text-[14px]">
{formatDate(blog.frontmatter.date)}
</Text>
<Box className="cursor-pointer" style={{ textAlign: "start" }}>
<Text onClick={() => navigate(blog.fields.slug)} className="font-semibold lg:font-semibold text-[14px] lg:text-[16px]">
{blog.frontmatter.name}
</Text>
</Box>
<Box className="lg:text-end" style={{ minWidth: "7em", flexGrow: 1 }}>
<Text className="text-[13px] lg:text-[14px]">{formatAuthor(blog.frontmatter.author)}</Text>
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 | 🟠 Major

Use a semantic link for each blog row.

The row is clickable only through onClick on a Box, so it is not keyboard reachable and loses normal link behavior like open-in-new-tab/copy-link. The nested title click handler also double-dispatches navigation on title clicks. Render a single anchor/link for the row instead.

Suggested change
-              <Box
-                key={idx}
-                className=" mx-auto border-t-0 border-r-0 border-l-0 border-b-2 border-dashed border-black/30 flex flex-col lg:flex-row gap-1 lg:gap-6 w-full lg:w-[70%] 2xl:w-[50%] pb-2 hover:bg-[`#FFE7D9`] active:bg-[`#FFC8A6`] focus:outline-none focus:ring-0 hover:scale-103 transition-transform duration-300 ease-in-out"
-                onClick={() => navigate(blog.fields.slug)}
-              >
+              <a
+                key={idx}
+                href={blog.fields.slug}
+                className="mx-auto border-t-0 border-r-0 border-l-0 border-b-2 border-dashed border-black/30 flex flex-col lg:flex-row gap-1 lg:gap-6 w-full lg:w-[70%] 2xl:w-[50%] pb-2 hover:bg-[`#FFE7D9`] active:bg-[`#FFC8A6`] focus:outline-none focus:ring-0 hover:scale-103 transition-transform duration-300 ease-in-out"
+              >
                 <Text className="min-w-[7em] text-xs lg:text-[14px]">
                   {formatDate(blog.frontmatter.date)}
                 </Text>
                 <Box className="cursor-pointer" style={{ textAlign: "start" }}>
-                  <Text onClick={() => navigate(blog.fields.slug)} className="font-semibold lg:font-semibold text-[14px] lg:text-[16px]">
+                  <Text className="font-semibold lg:font-semibold text-[14px] lg:text-[16px]">
                     {blog.frontmatter.name}
                   </Text>
                 </Box>
                 <Box className="lg:text-end" style={{ minWidth: "7em", flexGrow: 1 }}>
                   <Text className="text-[13px] lg:text-[14px]">{formatAuthor(blog.frontmatter.author)}</Text>
                 </Box>
-              </Box>
+              </a>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/RecentBlogs.jsx` around lines 94 - 108,
The row uses a clickable Box with onClick and an inner Text that also calls
navigate(blog.fields.slug), which breaks keyboard/accessibility and link
behaviors; replace the clickable Box with a semantic anchor/link element (or
your routing Link) for the whole row and set its href to blog.fields.slug,
remove the onClick handlers from Box and inner Text (so only the anchor performs
navigation), preserve displayed values from formatDate(blog.frontmatter.date),
blog.frontmatter.name, and formatAuthor(blog.frontmatter.author), and ensure the
anchor supports target/rel if needed for open-in-new-tab behavior.

Comment on lines +113 to +122
<Box
key={id}
className=" cursor-pointer flex flex-row lg:justify-between pb-[5px] pr-2 grow border-t-0 border-r-0 border-l-0 border-b-2 border-dashed border-black/30 hover:bg-[#FFE7D9] active:bg-[#FFC8A6] focus:outline-none focus:ring-0 hover:scale-100 transition-transform duration-100 ease-in-out"
onClick={() => navigate(r.url)}
>
<Text className="w-[30%] md:w-[15%] lg:w-auto text-[14px] lg:text-[16px]">{r.type}</Text>
<Text
className="cursor-pointer text-[14px] lg:text-[16px]"
onClick={() => navigate(r.url)}
>
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 | 🟠 Major

Use keyboard-accessible interaction for resource rows and avoid double navigation handlers.

The row is a clickable div-like element (Box) without keyboard activation, and the nested Text has another onClick, which can trigger redundant navigation via bubbling.

Proposed patch
 <Box
   key={id}
   className=" cursor-pointer flex flex-row lg:justify-between pb-[5px] pr-2 grow  border-t-0 border-r-0 border-l-0 border-b-2 border-dashed border-black/30 hover:bg-[`#FFE7D9`] active:bg-[`#FFC8A6`] focus:outline-none focus:ring-0 hover:scale-100 transition-transform duration-100 ease-in-out"
   onClick={() => navigate(r.url)}
+  role="link"
+  tabIndex={0}
+  onKeyDown={(e) => {
+    if (e.key === "Enter" || e.key === " ") {
+      e.preventDefault();
+      navigate(r.url);
+    }
+  }}
 >
   <Text className="w-[30%] md:w-[15%] lg:w-auto text-[14px] lg:text-[16px]">{r.type}</Text>
-  <Text
-    className="cursor-pointer text-[14px] lg:text-[16px]"
-    onClick={() => navigate(r.url)}
-  >
+  <Text className="text-[14px] lg:text-[16px]">
     {r.name}
   </Text>
 </Box>
📝 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
<Box
key={id}
className=" cursor-pointer flex flex-row lg:justify-between pb-[5px] pr-2 grow border-t-0 border-r-0 border-l-0 border-b-2 border-dashed border-black/30 hover:bg-[#FFE7D9] active:bg-[#FFC8A6] focus:outline-none focus:ring-0 hover:scale-100 transition-transform duration-100 ease-in-out"
onClick={() => navigate(r.url)}
>
<Text className="w-[30%] md:w-[15%] lg:w-auto text-[14px] lg:text-[16px]">{r.type}</Text>
<Text
className="cursor-pointer text-[14px] lg:text-[16px]"
onClick={() => navigate(r.url)}
>
<Box
key={id}
className=" cursor-pointer flex flex-row lg:justify-between pb-[5px] pr-2 grow border-t-0 border-r-0 border-l-0 border-b-2 border-dashed border-black/30 hover:bg-[`#FFE7D9`] active:bg-[`#FFC8A6`] focus:outline-none focus:ring-0 hover:scale-100 transition-transform duration-100 ease-in-out"
onClick={() => navigate(r.url)}
role="link"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
navigate(r.url);
}
}}
>
<Text className="w-[30%] md:w-[15%] lg:w-auto text-[14px] lg:text-[16px]">{r.type}</Text>
<Text className="text-[14px] lg:text-[16px]">
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/Resources.jsx` around lines 113 - 122,
The resource row uses a clickable Box with onClick and a nested Text that also
has onClick, and the Box isn't keyboard-accessible; update the interaction to be
keyboard-friendly and avoid duplicate navigation: make the outer Box a semantic
interactive element (e.g., render as a <button> or add role="button" and
tabIndex={0}), implement an onKeyDown handler on the Box that triggers
navigate(r.url) for Enter/Space, and remove the nested Text's onClick (or stop
propagation) so only the row-level navigate(r.url) is invoked; keep the navigate
call centralized in the Box's onClick/onKeyDown handlers (referencing Box, Text,
navigate, and r.url).

Comment on lines +107 to +145
return (
<div
onMouseEnter={() => setIsHover(true)}
onMouseLeave={() => setIsHover(false)}
onClick={onToggle}
className="w-full flex flex-col cursor-pointer transition-all duration-300 overflow-hidden"
style={{
backgroundColor: bg,
...dashedBorderStyle,
minHeight: '82px'
}}
>
<div
className="grid grid-cols-[44px_1fr_32px] md:grid-cols-[44px_1fr_40px] items-center w-full p-[22px] gap-4 md:gap-6"
style={{ boxSizing: 'border-box' }}
>
<div className="flex justify-center flex-shrink-0">
<MaskIcon url={item.iconUrl} color={textColor} size={34} />
</div>
<div className="flex-1 min-w-0">
<span
className="text-[19px] md:text-[34px] leading-[1.1em] break-words block w-full"
style={{ color: textColor, fontFamily: "'XStitch', sans-serif" }}
>
{item.title}
</span>
</div>
<div className="flex justify-end flex-shrink-0">
<PixelatedArrow color={textColor} isOpen={isOpen} />
</div>
</div>

<div
style={{
maxHeight: isOpen ? '450px' : '0px',
opacity: isOpen ? 1 : 0,
transition: 'max-height 0.4s ease-in-out, opacity 0.3s ease-in-out',
padding: isOpen ? '0 22px 30px 22px' : '0 22px'
}}
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 | 🟠 Major

Use a real button for the accordion trigger.

The expandable header is a clickable div, so it is not keyboard-focusable and exposes no expanded/collapsed state. That makes the section unreliable for keyboard and screen-reader users.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/SupportUs.jsx` around lines 107 - 145,
Replace the clickable header div with a semantic <button type="button">
(preserve className, inline styles, onClick={onToggle},
onMouseEnter/onMouseLeave handlers and child components MaskIcon, item.title,
PixelatedArrow) so it becomes keyboard-focusable; add aria-expanded={isOpen} and
aria-controls pointing to the expandable panel id (e.g.
aria-controls={`support-panel-${item.id}`}), give the expandable content
container a matching id and role="region" and optional aria-labelledby
referencing the button id, and ensure you do not remove the browser focus
outline (avoid forcing outline:none) so keyboard users can see focus.

Comment on lines +15 to +31
useEffect(() => {
const el = ref.current;
if (!el) return;

const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
el.classList.add("visible");
observer.unobserve(el); // animate only once
}
},
{ threshold, rootMargin }
);

observer.observe(el);
return () => observer.disconnect();
}, [threshold, rootMargin]);
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 | 🟠 Major

Add a fallback for browsers/environments where the observer never runs.

uli-website/src/styles/global.css:63-72 hides .reveal content by default, so if IntersectionObserver is unavailable or blocked, every section using these hooks stays invisible forever. Please add a capability fallback that applies visible immediately.

Also applies to: 43-59

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/hooks/useScrollReveal.js` around lines 15 - 31, The
IntersectionObserver block in useScrollReveal's useEffect can leave elements
hidden when the API is unavailable or blocked; update the effect in
useScrollReveal (the useEffect that references ref and creates a new
IntersectionObserver) to detect lack of support and immediately add the
"visible" class (i.e., if typeof IntersectionObserver === "undefined" or
window.IntersectionObserver is falsy) and return early; also add the same
fallback to the second identical useEffect (the other block that observes ref
and toggles "visible") so elements don't remain hidden in browsers/environments
without IntersectionObserver support.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
uli-website/src/components/molecules/NavBarNew.jsx (1)

59-59: ⚠️ Potential issue | 🟠 Major

Add accessible name and expanded state to the mobile menu toggle.

Line 59 still lacks an accessible label and expanded/collapse state metadata, so screen-reader users can’t identify control purpose/state.

🛠️ Proposed fix
-<Box flex direction="row" gap="medium" justify="end" align="end" className="lg:hidden" ><button className="bg-inherit m-0 p-0 border-none transition-transform duration-300" onClick={()=>{setOpen(prev => !prev)}}><img src={open ? "/cross-icon.svg" :"/hamburger-icon.svg"} alt="" className={`transition-transform duration-300 ${open ? "rotate-90" : "rotate-0"}`} /></button></Box>
+<Box flex direction="row" gap="medium" justify="end" align="end" className="lg:hidden">
+  <button
+    type="button"
+    className="bg-inherit m-0 p-0 border-none transition-transform duration-300"
+    aria-label={open ? "Close menu" : "Open menu"}
+    aria-expanded={open}
+    aria-controls="mobile-menu"
+    onClick={() => setOpen(prev => !prev)}
+  >
+    <img
+      src={open ? "/cross-icon.svg" : "/hamburger-icon.svg"}
+      alt=""
+      className={`transition-transform duration-300 ${open ? "rotate-90" : "rotate-0"}`}
+    />
+  </button>
+</Box>
-<Box className={`bg-[`#FFE7D9`] w-full text-center overflow-hidden transition-all duration-300 ease-in-out ${open ? "max-h-96 opacity-100 mt-9 mb-4" : "max-h-0 opacity-0"} lg:hidden`}>
+<Box id="mobile-menu" className={`bg-[`#FFE7D9`] w-full text-center overflow-hidden transition-all duration-300 ease-in-out ${open ? "max-h-96 opacity-100 mt-9 mb-4" : "max-h-0 opacity-0"} lg:hidden`}>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/NavBarNew.jsx` at line 59, The mobile
menu toggle button in NavBarNew.jsx lacks accessible name and expanded state;
update the button (the element that calls setOpen and uses open) to include an
accessible label (aria-label or visually-hidden text) that describes its purpose
(e.g., "Toggle navigation menu") and add aria-expanded={open} so assistive tech
knows its state; also ensure the collapsible menu element has a matching id and
add aria-controls on the button pointing to that id so screen readers can
associate the control with the menu.
🧹 Nitpick comments (4)
uli-website/src/components/molecules/NavBarNew.jsx (2)

62-64: Remove commented-out navigation code before merge.

Keeping old commented blocks in the component adds noise and makes future diffs harder to read.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/NavBarNew.jsx` around lines 62 - 64,
Remove the leftover commented navigation block in NavBarNew.jsx (the commented
NavLinkNew and Text lines) to clean up the component; locate the commented lines
around the NavBarNew render/return and delete the entire commented-out
NavLinkNew/ Text fragment so the file contains only active JSX.

15-23: Prevent redundant animation frame scheduling on scroll.

Line 16 currently schedules a new requestAnimationFrame for each scroll event. Coalescing to one in-flight frame avoids unnecessary work during rapid scroll bursts.

♻️ Proposed refactor
 useEffect(() => {
-  let rafId;
+  let rafId = null;
+  let ticking = false;
   const handleScroll = () => {
-    rafId = requestAnimationFrame(() => {
+    if (ticking) return;
+    ticking = true;
+    rafId = requestAnimationFrame(() => {
       if (borderRef.current) {
         const scrollY = window.scrollY || window.pageYOffset;
         // Slow drift: 0.3x scroll speed
         borderRef.current.style.backgroundPositionX = `${scrollY * 0.3}px`;
       }
+      ticking = false;
     });
   };
   window.addEventListener("scroll", handleScroll, { passive: true });
   return () => {
     window.removeEventListener("scroll", handleScroll);
-    cancelAnimationFrame(rafId);
+    if (rafId !== null) cancelAnimationFrame(rafId);
   };
 }, []);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/NavBarNew.jsx` around lines 15 - 23,
handleScroll currently calls requestAnimationFrame on every scroll event causing
redundant frames; modify handleScroll to check a shared rafId (already declared)
and only call requestAnimationFrame when rafId is null/undefined, store the
returned id in rafId, and inside the RAF callback clear rafId (set to null)
after updating borderRef.current.style.backgroundPositionX so further scrolls
can schedule a new frame; alternatively, call cancelAnimationFrame(rafId) before
scheduling and reassign rafId—use the rafId and borderRef symbols to locate and
update the logic.
uli-website/src/components/molecules/SupportUs.jsx (2)

139-145: Consider a more robust expand/collapse technique.

The maxHeight: 450px is a magic number that could clip content if descriptions grow longer. For static content this works, but a CSS grid-based approach (grid-template-rows: 0fr/1fr) provides smoother animations without height assumptions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/SupportUs.jsx` around lines 139 - 145,
The inline expand/collapse currently hardcodes maxHeight ('450px') in the
SupportUs.jsx div which can clip longer content; replace the size-dependent
animation with a grid-based technique: change the container's style logic (the
div using isOpen) to use CSS grid row sizing (e.g., toggle between
'gridTemplateRows: "0fr"' and 'gridTemplateRows: "1fr"') and opacity, move
transition rules to CSS or a className for smoother animation, and remove the
magic maxHeight/padding dependence so the content height grows naturally without
clipping.

61-81: Global regex with test() in a loop is fragile; pattern is also duplicated.

The g flag causes the regex to maintain lastIndex state between test() calls, which can lead to unexpected behavior. Additionally, this same regex pattern is duplicated at line 154.

Consider extracting to a module-level constant and using a non-global version for testing:

♻️ Proposed refactor
+// Module-level constant (after imports)
+const EMAIL_PATTERN = /[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+/;
+const EMAIL_PATTERN_GLOBAL = new RegExp(EMAIL_PATTERN.source, 'gi');
+
 const HighlightedDescription = ({ text }) => {
-  const emailRegex = /([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/gi;
-  const parts = text.split(emailRegex);
+  const parts = text.split(new RegExp(`(${EMAIL_PATTERN.source})`, 'gi'));
   
   return (
     <div className="text-[15px] md:text-[18px] leading-[1.2em] w-full mt-2" style={{ color: "#000000", fontFamily: "'Labrada', serif" }}>
       {parts.map((part, i) => 
-        emailRegex.test(part) ? (
+        EMAIL_PATTERN.test(part) ? (
           <a 

Then at line 154, reuse the constant:

-              window.location.href = `mailto:${item.description.match(/([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/gi)?.[0] || '[email protected]'}`;
+              window.location.href = `mailto:${item.description.match(EMAIL_PATTERN_GLOBAL)?.[0] || '[email protected]'}`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/SupportUs.jsx` around lines 61 - 81, The
code uses a global regex with test() inside HighlightedDescription which is
brittle and the same pattern is duplicated elsewhere; extract the email pattern
to a module-level constant and create two RegExp instances from it: one
non-global regex (e.g., EMAIL_TEST_REGEX without the 'g' flag) to use with
test() in the parts.map, and another (e.g., EMAIL_SPLIT_REGEX with 'gi') for
splitting if needed; replace the inline /.../gi in HighlightedDescription and
the duplicated pattern at the other usage (the duplicate around line 154) to use
these shared constants so test() does not rely on lastIndex and the pattern is
not duplicated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@uli-website/src/components/molecules/NavBarNew.jsx`:
- Around line 50-56: The logo image in NavBarNew.jsx is clickable via an onClick
on the <img>, which is not keyboard-accessible; replace the bare <img> with a
semantic, focusable control (e.g., a <button type="button"> or a react-router
<Link>) that wraps the image so keyboard users can activate it. Update the
element that currently contains the onClick (the img inside Box) to a button
with the same onClick handler (navigate("/")), add an accessible label
(aria-label="Home" or similar), and preserve visual styles by resetting button
default styles (no border/background, padding 0, cursor pointer) so the
appearance stays the same while gaining keyboard/focus support.

---

Duplicate comments:
In `@uli-website/src/components/molecules/NavBarNew.jsx`:
- Line 59: The mobile menu toggle button in NavBarNew.jsx lacks accessible name
and expanded state; update the button (the element that calls setOpen and uses
open) to include an accessible label (aria-label or visually-hidden text) that
describes its purpose (e.g., "Toggle navigation menu") and add
aria-expanded={open} so assistive tech knows its state; also ensure the
collapsible menu element has a matching id and add aria-controls on the button
pointing to that id so screen readers can associate the control with the menu.

---

Nitpick comments:
In `@uli-website/src/components/molecules/NavBarNew.jsx`:
- Around line 62-64: Remove the leftover commented navigation block in
NavBarNew.jsx (the commented NavLinkNew and Text lines) to clean up the
component; locate the commented lines around the NavBarNew render/return and
delete the entire commented-out NavLinkNew/ Text fragment so the file contains
only active JSX.
- Around line 15-23: handleScroll currently calls requestAnimationFrame on every
scroll event causing redundant frames; modify handleScroll to check a shared
rafId (already declared) and only call requestAnimationFrame when rafId is
null/undefined, store the returned id in rafId, and inside the RAF callback
clear rafId (set to null) after updating
borderRef.current.style.backgroundPositionX so further scrolls can schedule a
new frame; alternatively, call cancelAnimationFrame(rafId) before scheduling and
reassign rafId—use the rafId and borderRef symbols to locate and update the
logic.

In `@uli-website/src/components/molecules/SupportUs.jsx`:
- Around line 139-145: The inline expand/collapse currently hardcodes maxHeight
('450px') in the SupportUs.jsx div which can clip longer content; replace the
size-dependent animation with a grid-based technique: change the container's
style logic (the div using isOpen) to use CSS grid row sizing (e.g., toggle
between 'gridTemplateRows: "0fr"' and 'gridTemplateRows: "1fr"') and opacity,
move transition rules to CSS or a className for smoother animation, and remove
the magic maxHeight/padding dependence so the content height grows naturally
without clipping.
- Around line 61-81: The code uses a global regex with test() inside
HighlightedDescription which is brittle and the same pattern is duplicated
elsewhere; extract the email pattern to a module-level constant and create two
RegExp instances from it: one non-global regex (e.g., EMAIL_TEST_REGEX without
the 'g' flag) to use with test() in the parts.map, and another (e.g.,
EMAIL_SPLIT_REGEX with 'gi') for splitting if needed; replace the inline /.../gi
in HighlightedDescription and the duplicated pattern at the other usage (the
duplicate around line 154) to use these shared constants so test() does not rely
on lastIndex and the pattern is not duplicated.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4bcb99da-1aca-4117-88f6-1cd5c4795ca5

📥 Commits

Reviewing files that changed from the base of the PR and between c46a378 and 122db9f.

⛔ Files ignored due to path filters (4)
  • uli-website/static/track_icons/Database.png is excluded by !**/*.png
  • uli-website/static/track_icons/Slur Editor.png is excluded by !**/*.png
  • uli-website/static/track_icons/Tools.png is excluded by !**/*.png
  • uli-website/static/track_icons/Workshops.png is excluded by !**/*.png
📒 Files selected for processing (6)
  • uli-website/src/components/molecules/Announcements.jsx
  • uli-website/src/components/molecules/FooterNew.jsx
  • uli-website/src/components/molecules/NavBarNew.jsx
  • uli-website/src/components/molecules/Projects.jsx
  • uli-website/src/components/molecules/SupportUs.jsx
  • uli-website/src/pages/new-home.js
✅ Files skipped from review due to trivial changes (2)
  • uli-website/src/components/molecules/FooterNew.jsx
  • uli-website/src/components/molecules/Announcements.jsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • uli-website/src/components/molecules/Projects.jsx
  • uli-website/src/pages/new-home.js

Comment on lines +50 to +56
<Box align="center">
<img
src="/Uli_Logo.png"
alt="Uli Logo"
style={{ height: "32px", cursor: "pointer" }}
onClick={() => navigate("/")}
/>
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 | 🟠 Major

Use a semantic link/button for the clickable logo.

Line 55 attaches navigation to an <img>, which is not keyboard-accessible by default. This is an accessibility blocker for keyboard and assistive-tech users.

🛠️ Proposed fix
-        <Box align="center">
-          <img
-            src="/Uli_Logo.png"
-            alt="Uli Logo"
-            style={{ height: "32px", cursor: "pointer" }}
-            onClick={() => navigate("/")}
-          />
-        </Box>
+        <Box align="center">
+          <NavLink to="/" aria-label="Go to homepage">
+            <img
+              src="/Uli_Logo.png"
+              alt="Uli Logo"
+              style={{ height: "32px" }}
+            />
+          </NavLink>
+        </Box>
📝 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
<Box align="center">
<img
src="/Uli_Logo.png"
alt="Uli Logo"
style={{ height: "32px", cursor: "pointer" }}
onClick={() => navigate("/")}
/>
<Box align="center">
<NavLink to="/" aria-label="Go to homepage">
<img
src="/Uli_Logo.png"
alt="Uli Logo"
style={{ height: "32px" }}
/>
</NavLink>
</Box>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/NavBarNew.jsx` around lines 50 - 56, The
logo image in NavBarNew.jsx is clickable via an onClick on the <img>, which is
not keyboard-accessible; replace the bare <img> with a semantic, focusable
control (e.g., a <button type="button"> or a react-router <Link>) that wraps the
image so keyboard users can activate it. Update the element that currently
contains the onClick (the img inside Box) to a button with the same onClick
handler (navigate("/")), add an accessible label (aria-label="Home" or similar),
and preserve visual styles by resetting button default styles (no
border/background, padding 0, cursor pointer) so the appearance stays the same
while gaining keyboard/focus support.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@uli-website/src/components/molecules/SupportUs.jsx`:
- Around line 141-166: The collapsed panel currently only toggles
maxHeight/opacity (controlled by isOpen) leaving interactive elements like the
button and email link in the tab order and removing focus cues via outline-none;
update the component so when isOpen is false the panel and its children
(HighlightedDescription, the CTA button that checks item.buttonText and mailto
logic, and any link navigation using navigate(item.url)) are truly hidden —
either unmount the panel via conditional rendering (render nothing when isOpen
is false) or add aria-hidden="true" plus visibility: hidden and pointer-events:
none and tabindex="-1" on those interactive elements so they are removed from
keyboard focus; also remove outline-none and replace it with a visible focus
style (e.g., use :focus-visible class) on the CTA button to preserve keyboard
focus indication.
- Around line 153-160: The onClick handler currently uses Gatsby's
navigate(item.url) for all item.url values, which breaks absolute external URLs
(e.g., https://github.com/sponsors/tattle-made); change the logic in the onClick
handler for the SupportUs component so that when item.url is an absolute
external URL you set window.location.href = item.url instead of calling navigate
— keep the existing mailto handling (item.buttonText/email regex) and only
replace navigate(item.url) with a conditional that detects external URLs (or
checks for http/https prefix) and uses window.location.href for externals and
navigate for internal paths.

In `@uli-website/src/pages/blog/index.jsx`:
- Line 21: The Box component in the blog page uses the JSX prop "class" which
prevents Tailwind/Grommet styles from applying; update the Box element in
index.jsx to use "className" instead of "class" (locate the Box with the value
"bg-red-200 p-2 mb-80") so the styling props are recognized by React JSX.

In `@uli-website/src/pages/process.mdx`:
- Around line 18-22: The page copy contains an editorial placeholder "(insert
video currently in research section)" and a truncated sentence starting "While
we keep the values of care and radical inclusion as our north star, we recognize
that in hitting"—replace the placeholder with the intended embedded video or a
stable link and a short caption, and complete the truncated sentence to convey
the full idea (e.g., describe the tradeoffs/challenges faced when
operationalizing those values). Update the "The Uli project..." paragraph to
flow smoothly and ensure the methodology paragraph mentions the award and
related papers clearly; remove any leftover editorial markers before merging.
- Line 20: The phrase "India languages" in the sentence describing the flagship
dataset is a grammatical error; update that phrase to "Indian languages" (or
"languages in India") in the paragraph mentioning the dataset on misogyny to
correct the wording and improve clarity—locate the sentence containing "the
flagship dataset on misogyny in India languages with experts with lived
experience of abuse" and replace "India languages" accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aa4e158a-884b-4926-a0e3-94a9884fe0cf

📥 Commits

Reviewing files that changed from the base of the PR and between 122db9f and bd56f8a.

📒 Files selected for processing (4)
  • uli-website/src/components/molecules/SupportUs.jsx
  • uli-website/src/pages/blog/index.jsx
  • uli-website/src/pages/new-home.js
  • uli-website/src/pages/process.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
  • uli-website/src/pages/new-home.js

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (2)
uli-website/src/pages/process.mdx (2)

43-43: ⚠️ Potential issue | 🟡 Minor

Fix wording: “India languages” → “Indian languages”.

Line 43 still has the same grammar issue previously flagged; please update this phrase for readability.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/pages/process.mdx` at line 43, Replace the incorrect phrase
"India languages" with "Indian languages" in the sentence starting "The
methodology of building the flagship dataset on misogyny in India languages..."
in process.mdx so the sentence reads "...dataset on misogyny in Indian
languages..."; ensure the change updates only that phrase for readability and
grammatical correctness.

45-45: ⚠️ Potential issue | 🟠 Major

Complete the truncated closing sentence before merge.

Line 45 is still an unfinished sentence fragment, which leaves the section broken for readers.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/pages/process.mdx` at line 45, The sentence fragment "While
we keep the values of care and radical inclusion as our north star, we recognize
that in hitting" in the process.mdx content is incomplete; complete the closing
sentence so the paragraph reads as a full thought (for example finish with an
explicit consequence or action like "we may need to make difficult trade-offs
and prioritize in the short term to ensure long-term sustainability," or another
agreed-upon conclusion). Locate the fragment in src/pages/process.mdx and
replace the truncated line with the completed sentence that matches the document
tone and intent.
🧹 Nitpick comments (1)
uli-website/src/components/molecules/SupportUs.jsx (1)

151-152: Minor: spacing around operator and focus indicator removed.

Line 151 uses !=0 without spaces. Line 152 has outline-none which removes the default focus indicator, harming keyboard navigation.

✨ Suggested improvements
-          {item.buttonText.length!=0 && <button 
-            className="bg-black py-[12px] px-[24px] w-max mt-4 border-none outline-none cursor-pointer hover:bg-[`#333333`] transition-colors active:scale-95 transform"
+          {item.buttonText.length !== 0 && <button 
+            className="bg-black py-[12px] px-[24px] w-max mt-4 border-none cursor-pointer hover:bg-[`#333333`] transition-colors active:scale-95 transform focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/SupportUs.jsx` around lines 151 - 152,
In SupportUs.jsx, fix the conditional render by spacing and using strict
comparison for item.buttonText (e.g., item.buttonText !== 0 or better check
length with item.buttonText.length !== 0 or item.buttonText.length > 0) and
restore accessible focus styling by removing the "outline-none" utility on the
button and replacing it with an accessible focus style (e.g., a visible focus
ring class) so keyboard users retain a visible focus indicator.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@uli-website/src/components/molecules/SupportUs.jsx`:
- Around line 63-83: In HighlightedDescription, the emailRegex is declared with
the global flag which makes repeated emailRegex.test(part) calls unreliable
because lastIndex is mutated; change the regex to a non-global pattern (remove
the 'g' flag) or use a fresh RegExp instance for each test, and update the
parts.map logic to call test() against the non-global regex (or use
part.match(emailRegex) without the global flag) so email strings are
consistently detected and rendered as mailto links.

In `@uli-website/src/pages/process.mdx`:
- Around line 33-36: The iframe uses lowercase/deprecated HTML attributes;
update the JSX to use React DOM prop names and non-deprecated usage: replace
frameborder with frameBorder (or remove it and use CSS styling on the iframe
element), change referrerpolicy to referrerPolicy, and replace allowfullscreen
with either the React prop allowFullScreen or ensure fullscreen is enabled via
the allow attribute (e.g., include "fullscreen" in allow). Locate the iframe
element in the file and apply these camelCase updates and/or remove deprecated
attributes in favor of CSS/allow="fullscreen".

---

Duplicate comments:
In `@uli-website/src/pages/process.mdx`:
- Line 43: Replace the incorrect phrase "India languages" with "Indian
languages" in the sentence starting "The methodology of building the flagship
dataset on misogyny in India languages..." in process.mdx so the sentence reads
"...dataset on misogyny in Indian languages..."; ensure the change updates only
that phrase for readability and grammatical correctness.
- Line 45: The sentence fragment "While we keep the values of care and radical
inclusion as our north star, we recognize that in hitting" in the process.mdx
content is incomplete; complete the closing sentence so the paragraph reads as a
full thought (for example finish with an explicit consequence or action like "we
may need to make difficult trade-offs and prioritize in the short term to ensure
long-term sustainability," or another agreed-upon conclusion). Locate the
fragment in src/pages/process.mdx and replace the truncated line with the
completed sentence that matches the document tone and intent.

---

Nitpick comments:
In `@uli-website/src/components/molecules/SupportUs.jsx`:
- Around line 151-152: In SupportUs.jsx, fix the conditional render by spacing
and using strict comparison for item.buttonText (e.g., item.buttonText !== 0 or
better check length with item.buttonText.length !== 0 or item.buttonText.length
> 0) and restore accessible focus styling by removing the "outline-none" utility
on the button and replacing it with an accessible focus style (e.g., a visible
focus ring class) so keyboard users retain a visible focus indicator.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b2cd2731-c6b3-42f3-b049-f78ce376e2a0

📥 Commits

Reviewing files that changed from the base of the PR and between bd56f8a and 6b6bacc.

⛔ Files ignored due to path filters (3)
  • uli-website/static/support_icons/database.svg is excluded by !**/*.svg
  • uli-website/static/support_icons/support.svg is excluded by !**/*.svg
  • uli-website/static/support_icons/workshop.svg is excluded by !**/*.svg
📒 Files selected for processing (3)
  • uli-website/src/components/molecules/Projects.jsx
  • uli-website/src/components/molecules/SupportUs.jsx
  • uli-website/src/pages/process.mdx
✅ Files skipped from review due to trivial changes (1)
  • uli-website/src/components/molecules/Projects.jsx

Comment on lines +63 to +83
const HighlightedDescription = ({ text }) => {
const emailRegex = /([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/gi;
const parts = text.split(emailRegex);

return (
<div className="text-[15px] md:text-[18px] leading-[1.2em] w-full mt-2" style={{ color: "#000000", fontFamily: "'Labrada', serif" }}>
{parts.map((part, i) =>
emailRegex.test(part) ? (
<a
key={i}
href={`mailto:${part}`}
className="underline font-bold hover:opacity-60 transition-opacity"
onClick={(e) => e.stopPropagation()}
>
{part}
</a>
) : part
)}
</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.

⚠️ Potential issue | 🟡 Minor

Global regex with test() in a loop causes intermittent matching failures.

The emailRegex is declared with the global flag (g), which maintains lastIndex state across test() calls. When iterating over parts in map(), successful matches advance lastIndex, potentially causing subsequent calls to fail on different strings. This can result in emails not being detected as links.

🐛 Proposed fix: use a non-global regex for testing
 const HighlightedDescription = ({ text }) => {
   const emailRegex = /([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/gi;
+  const emailTestRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$/i;
   const parts = text.split(emailRegex);
   
   return (
     <div className="text-[15px] md:text-[18px] leading-[1.2em] w-full mt-2" style={{ color: "#000000", fontFamily: "'Labrada', serif" }}>
       {parts.map((part, i) => 
-        emailRegex.test(part) ? (
+        emailTestRegex.test(part) ? (
           <a 
             key={i} 
             href={`mailto:${part}`} 
             className="underline font-bold hover:opacity-60 transition-opacity"
             onClick={(e) => e.stopPropagation()}
           >
             {part}
           </a>
         ) : part
       )}
     </div>
   );
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/components/molecules/SupportUs.jsx` around lines 63 - 83, In
HighlightedDescription, the emailRegex is declared with the global flag which
makes repeated emailRegex.test(part) calls unreliable because lastIndex is
mutated; change the regex to a non-global pattern (remove the 'g' flag) or use a
fresh RegExp instance for each test, and update the parts.map logic to call
test() against the non-global regex (or use part.match(emailRegex) without the
global flag) so email strings are consistently detected and rendered as mailto
links.

Comment on lines +33 to +36
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen
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 | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

In React JSX, what are the correct <iframe> prop names for frameborder, referrerpolicy, and allowfullscreen?

💡 Result:

In React JSX, the correct prop names for the <iframe> attributes are: - frameborder: frameBorder (deprecated; use CSS border instead) - referrerpolicy: referrerPolicy - allowfullscreen: allowFullScreen (boolean; deprecated in favor of allow="fullscreen") Example: <iframe src="..." frameBorder={0} referrerPolicy="no-referrer" allowFullScreen /> Note: frameborder and allowfullscreen are deprecated HTML attributes. Prefer modern alternatives like CSS for borders and allow="fullscreen" for fullscreen support.

Citations:


Use React-correct iframe prop names.

Lines 33–36 use lowercase HTML attribute names in JSX. Switch to React DOM prop casing (camelCase).

Additionally, frameborder and allowfullscreen are deprecated HTML attributes. Consider using CSS for borders and allow="fullscreen" for fullscreen support instead.

Proposed fix
-        frameborder="0"
+        frameBorder="0"
         allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
-        referrerpolicy="strict-origin-when-cross-origin"
-        allowfullscreen
+        referrerPolicy="strict-origin-when-cross-origin"
+        allowFullScreen
📝 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
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerPolicy="strict-origin-when-cross-origin"
allowFullScreen
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uli-website/src/pages/process.mdx` around lines 33 - 36, The iframe uses
lowercase/deprecated HTML attributes; update the JSX to use React DOM prop names
and non-deprecated usage: replace frameborder with frameBorder (or remove it and
use CSS styling on the iframe element), change referrerpolicy to referrerPolicy,
and replace allowfullscreen with either the React prop allowFullScreen or ensure
fullscreen is enabled via the allow attribute (e.g., include "fullscreen" in
allow). Locate the iframe element in the file and apply these camelCase updates
and/or remove deprecated attributes in favor of CSS/allow="fullscreen".

@dennyabrain dennyabrain merged commit 401554a into tattle-made:main Apr 13, 2026
3 checks passed
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.

4 participants