Added Dino Landing Page with Interactive UI and Responsive Design#180
Added Dino Landing Page with Interactive UI and Responsive Design#180Robot1508 wants to merge 1 commit intodeveloper-diganta:mainfrom
Conversation
📝 WalkthroughWalkthroughA new static HTML page is introduced featuring an interactive landing page with a sticky navbar, hero section, and responsive card grid. The page includes a morphing blob cursor, canvas-based particle animation spelling "DINO", interactive cards with glow effects, and clickable words that trigger animations on the description text. Changes
Sequence DiagramsequenceDiagram
participant User
participant Browser/DOM
participant Canvas
participant Mouse Events
User->>Mouse Events: Move mouse
Mouse Events->>Browser/DOM: Update blob position
Mouse Events->>Canvas: Trigger particle animation
Canvas->>Canvas: Draw animated particles
User->>Mouse Events: Hover over card
Mouse Events->>Browser/DOM: Calculate glow position
Browser/DOM->>Browser/DOM: Update card glow effect
User->>Browser/DOM: Click on word
Browser/DOM->>Browser/DOM: Trigger word animation<br/>(motion + opacity)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Added a responsive and interactive Dino webpage with modern UI, animations, and accessibility-focused design. Please review and suggest any improvements. |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (3)
dino_webpage/dino.html (3)
190-191:--glow-intensityis declared and toggled but never consumed — dead code.The property is set to
0in the base rule and flipped to1on hover (line 219), but it is not referenced in any gradient,opacity,calc(), or other CSS declaration. The actual hover glow is driven by the hardcodedopacity: 0 → 1transition on::after(lines 211, 222) and has no connection to this variable. Either wire it up (e.g., drive the::afteropacity) or remove the dead declarations.♻️ Proposed fix — drive glow opacity from the variable
- --glow-x: 50%; --glow-y: 50%; --glow-intensity: 0; + --glow-x: 50%; --glow-y: 50%; --glow-color: var(--primary);opacity: 0; transition: opacity 0.3s ease;- .magic-bento-card:hover { + .magic-bento-card:hover::after { opacity: 1; } + .magic-bento-card:hover { transform: translateY(-5px); box-shadow: 0 12px 30px rgba(0, 0, 0, 0.08); - --glow-intensity: 1; } - - .magic-bento-card:hover::after { opacity: 1; }Also applies to: 219-219
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@dino_webpage/dino.html` around lines 190 - 191, The CSS custom property --glow-intensity is defined (base rule sets --glow-intensity: 0 and hover flips it to 1) but never used, so either remove it or wire it into the glow rendering; fix by updating the element's ::after rule to drive the glow opacity or other glow parameter from var(--glow-intensity) instead of using a hardcoded opacity transition—locate the selector that defines --glow-intensity and the corresponding ::after pseudo-element (the rules around --glow-x/--glow-y/--glow-color and the ::after opacity transitions) and replace the hardcoded opacity with opacity: var(--glow-intensity) (and ensure transitions include opacity) or remove the unused --glow-intensity declarations if you prefer to keep the existing hardcoded opacity approach.
279-281:.hero-image-sidehas no CSS rule — layout is held together only by the inlinewidth: 300px.There is a CSS rule for
.hero-text-side(line 129) but none for.hero-image-side. Without it, the image container inherits nomax-width, alignment, or responsive constraint, so resizing or adding more content to that side can produce unexpected wrapping/overflow. A paired rule alongside.hero-text-sidewould make this intentional.♻️ Suggested addition to the stylesheet
+ .hero-image-side { + display: flex; + align-items: center; + justify-content: center; + max-width: 320px; + } + + .hero-image-side img { + width: 100%; + height: auto; + }And remove the inline
style="width: 300px;"from the<img>tag.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@dino_webpage/dino.html` around lines 279 - 281, Add a CSS rule for .hero-image-side to pair with the existing .hero-text-side so the image column has explicit sizing/alignment and responsive constraints (e.g., a max-width, flex alignment/justify settings and padding) instead of relying on the inline width; also add responsive image rules for the contained <img> (max-width:100%, height:auto) and remove the inline style="width: 300px;" from the <img> tag so sizing is controlled by the stylesheet.
383-396: CanvasrequestAnimationFrameloop keeps running when the tab is hidden, burning CPU/battery.There is no
document.visibilitychangeguard. Modern browsers throttlerAFin background tabs but do not stop it completely; the canvas still draws. This is particularly wasteful here because the animation is purely decorative.♻️ Proposed fix
+ let rafId = null; + function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); particles.forEach(p => { ctx.fillStyle = `rgba(26, 47, 75, ${p.opacity})`; ctx.font = `bold ${p.size}px system-ui`; ctx.fillText(p.char, p.x, p.y); p.y -= p.v; if (p.y < -30) p.y = canvas.height + 30; }); - requestAnimationFrame(animate); + rafId = requestAnimationFrame(animate); } window.addEventListener('resize', init); - init(); animate(); + init(); animate(); + + document.addEventListener('visibilitychange', () => { + if (document.hidden) { + cancelAnimationFrame(rafId); + } else { + animate(); + } + });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@dino_webpage/dino.html` around lines 383 - 396, The animate loop is never paused when the tab is hidden; add a visibility guard so the rAF loop stops when the document is hidden and resumes when visible. Implement a top-level variable (e.g., animationId) to hold the requestAnimationFrame handle, modify animate to only render when document.visibilityState === 'visible' (or skip drawing and early-return), add a document.addEventListener('visibilitychange', ...) handler that cancels the current frame via cancelAnimationFrame(animationId) when hidden and restarts the loop (e.g., animationId = requestAnimationFrame(animate) or call animate()) when visible, and ensure init does not unconditionally call animate() but uses the visibility-aware start logic; reference functions/idents: animate, init, requestAnimationFrame, cancelAnimationFrame, document.visibilitychange/visibilityState, and animationId.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@dino_webpage/dino.html`:
- Line 269: The image path uses an unencoded filename
"dino_logo-removebg-preview (2).png" which contains spaces and parentheses;
rename the file to a safe name (e.g., "dino_logo.png" or
"dino_logo-removebg-preview-2.png") and update all references in the HTML (the
<img src="images_icons/dino_logo-removebg-preview (2).png" ...> occurrences and
the other reference noted at lines 280-281) to the new filename; alternatively,
if you cannot rename the asset, percent-encode the filename in the src attribute
("%20" for space, "%28" and "%29" for parentheses) so the URL conforms to RFC
3986.
- Line 326: Three <img> tags inside the feature-card blocks (the <div
class="header"> image and its two siblings) lack alt attributes causing WCAG 2.1
SC 1.1.1 violations; add appropriate alt text for each <img> (e.g., concise
descriptive strings that convey the image's purpose like "Rocket icon — fast
setup" or "Analytics icon — insights") or use alt="" for purely decorative
images, ensuring the alt values live on the <img> elements inside the
feature-card/header blocks so screen readers get meaningful text instead of the
CDN URL.
- Line 273: Replace the decorative <div> containing the emoji with an accessible
interactive element: either convert it to a <button> or add role="button",
tabindex="0", and an appropriate aria-label (e.g., aria-label="Profile") and
keyboard event handling to the existing element so it is focusable and announced
by screen readers; update any associated click handlers to also respond to
Enter/Space keypresses on the element (identify the element by its inline styles
or the emoji content to locate it).
- Around line 399-410: The click handler on elements selected by
document.querySelectorAll('.word') lacks a re-entry guard, so multiple rapid
clicks queue overlapping setTimeouts and conflicting transforms; fix by adding
an animation flag (e.g., element.dataset.isAnimating or a class like
'animating') checked at the start of the listener and set to true before
starting the transition, then clear it (set to false/remove class) in the
timeout callback before resetting styles; ensure the guard prevents starting a
new animation while isAnimating is true and that the timeout always clears the
flag even if styles are reset early.
- Around line 316-319: The CTA button markup lacks an action, an explicit type,
and focus/hover feedback: update the <button class="btn-cta"> element to include
type="button" and either attach a click handler (e.g., onclick that opens the
extension page) or replace/wrap it with a semantic link element that navigates
to the extension URL; then extend the .btn-cta CSS to add :hover and
:focus-visible styles (visible outline/box-shadow and a contrast-preserving
background or border change) so both mouse and keyboard users receive clear
feedback while keeping the same visual design.
---
Nitpick comments:
In `@dino_webpage/dino.html`:
- Around line 190-191: The CSS custom property --glow-intensity is defined (base
rule sets --glow-intensity: 0 and hover flips it to 1) but never used, so either
remove it or wire it into the glow rendering; fix by updating the element's
::after rule to drive the glow opacity or other glow parameter from
var(--glow-intensity) instead of using a hardcoded opacity transition—locate the
selector that defines --glow-intensity and the corresponding ::after
pseudo-element (the rules around --glow-x/--glow-y/--glow-color and the ::after
opacity transitions) and replace the hardcoded opacity with opacity:
var(--glow-intensity) (and ensure transitions include opacity) or remove the
unused --glow-intensity declarations if you prefer to keep the existing
hardcoded opacity approach.
- Around line 279-281: Add a CSS rule for .hero-image-side to pair with the
existing .hero-text-side so the image column has explicit sizing/alignment and
responsive constraints (e.g., a max-width, flex alignment/justify settings and
padding) instead of relying on the inline width; also add responsive image rules
for the contained <img> (max-width:100%, height:auto) and remove the inline
style="width: 300px;" from the <img> tag so sizing is controlled by the
stylesheet.
- Around line 383-396: The animate loop is never paused when the tab is hidden;
add a visibility guard so the rAF loop stops when the document is hidden and
resumes when visible. Implement a top-level variable (e.g., animationId) to hold
the requestAnimationFrame handle, modify animate to only render when
document.visibilityState === 'visible' (or skip drawing and early-return), add a
document.addEventListener('visibilitychange', ...) handler that cancels the
current frame via cancelAnimationFrame(animationId) when hidden and restarts the
loop (e.g., animationId = requestAnimationFrame(animate) or call animate()) when
visible, and ensure init does not unconditionally call animate() but uses the
visibility-aware start logic; reference functions/idents: animate, init,
requestAnimationFrame, cancelAnimationFrame,
document.visibilitychange/visibilityState, and animationId.
|
|
||
| <nav class="navbar"> | ||
| <div class="logo-box"> | ||
| <img src="images_icons/dino_logo-removebg-preview (2).png" alt="Dino Logo"> |
There was a problem hiding this comment.
Unencoded space and parentheses in image src paths will break in strict server/proxy configurations.
Both occurrences use dino_logo-removebg-preview (2).png. Spaces and () in a URL must be percent-encoded (%20, %28, %29) per RFC 3986. Most desktop browsers are lenient for local files, but HTTP servers, CDNs, and programmatic URL consumers (e.g., fetch, link prefetch) may reject or mangle the path. The simplest fix is to rename the file.
🐛 Proposed fix
Rename the file to dino_logo.png (or any space/parenthesis-free name) and update both references:
- <img src="images_icons/dino_logo-removebg-preview (2).png" alt="Dino Logo">
+ <img src="images_icons/dino_logo.png" alt="Dino Logo">- <img src="images_icons/dino_logo-removebg-preview (2).png" style="width: 300px;" alt="Dino Mascot">
+ <img src="images_icons/dino_logo.png" style="width: 300px;" alt="Dino Mascot">Also applies to: 280-281
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@dino_webpage/dino.html` at line 269, The image path uses an unencoded
filename "dino_logo-removebg-preview (2).png" which contains spaces and
parentheses; rename the file to a safe name (e.g., "dino_logo.png" or
"dino_logo-removebg-preview-2.png") and update all references in the HTML (the
<img src="images_icons/dino_logo-removebg-preview (2).png" ...> occurrences and
the other reference noted at lines 280-281) to the new filename; alternatively,
if you cannot rename the asset, percent-encode the filename in the src attribute
("%20" for space, "%28" and "%29" for parentheses) so the URL conforms to RFC
3986.
| </div> | ||
| <div class="nav-links"> | ||
| <a href="#">Download</a> | ||
| <div style="color:white; border: 2px solid white; border-radius: 50%; padding: 5px; width: 35px; height: 35px; display: flex; align-items: center; justify-content: center;">👤</div> |
There was a problem hiding this comment.
Profile icon <div> is not keyboard-accessible and is invisible to assistive technology.
The element uses a <div> with an emoji but has no role="button", tabindex="0", or aria-label. Screen readers won't identify it as interactive and keyboard users can't reach it. For an accessibility-extension landing page this is a notable self-contradiction.
♿ Proposed fix
- <div style="color:white; border: 2px solid white; border-radius: 50%; padding: 5px; width: 35px; height: 35px; display: flex; align-items: center; justify-content: center;">👤</div>
+ <button aria-label="User account" style="color:white; border: 2px solid white; border-radius: 50%; padding: 5px; width: 35px; height: 35px; display: flex; align-items: center; justify-content: center; background: transparent; cursor: pointer;">
+ <span aria-hidden="true">👤</span>
+ </button>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@dino_webpage/dino.html` at line 273, Replace the decorative <div> containing
the emoji with an accessible interactive element: either convert it to a
<button> or add role="button", tabindex="0", and an appropriate aria-label
(e.g., aria-label="Profile") and keyboard event handling to the existing element
so it is focusable and announced by screen readers; update any associated click
handlers to also respond to Enter/Space keypresses on the element (identify the
element by its inline styles or the emoji content to locate it).
| <button class="btn-cta"> | ||
| Know more about the Extension | ||
| <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M19 14l-7 7m0 0l-7-7m7 7V3"></path></svg> | ||
| </button> |
There was a problem hiding this comment.
CTA button has no action, no type, and no focus/hover styles.
Three separate gaps:
- No action: Neither an
onclickhandler nor a wrapping<a>is present, so clicking does nothing. The button is purely decorative. - No
type="button": Omittingtypedefaults tosubmitinside any future ancestor form; explicittype="button"is a safe habit. - No focus/hover styles: The
.btn-ctarule has no:hoveror:focus-visibledeclarations, so keyboard and sighted users get no feedback — again ironic for an accessibility page.
🐛 Proposed fix
- <button class="btn-cta">
+ <button class="btn-cta" type="button" onclick="window.location.href='#'">Add to the stylesheet:
+ .btn-cta:hover {
+ filter: brightness(1.1);
+ transform: translateY(-2px);
+ transition: all 0.2s ease;
+ }
+
+ .btn-cta:focus-visible {
+ outline: 3px solid var(--navy);
+ outline-offset: 3px;
+ }📝 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.
| <button class="btn-cta"> | |
| Know more about the Extension | |
| <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M19 14l-7 7m0 0l-7-7m7 7V3"></path></svg> | |
| </button> | |
| <button class="btn-cta" type="button" onclick="window.location.href='#'"> | |
| Know more about the Extension | |
| <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M19 14l-7 7m0 0l-7-7m7 7V3"></path></svg> | |
| </button> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@dino_webpage/dino.html` around lines 316 - 319, The CTA button markup lacks
an action, an explicit type, and focus/hover feedback: update the <button
class="btn-cta"> element to include type="button" and either attach a click
handler (e.g., onclick that opens the extension page) or replace/wrap it with a
semantic link element that navigates to the extension URL; then extend the
.btn-cta CSS to add :hover and :focus-visible styles (visible outline/box-shadow
and a contrast-preserving background or border change) so both mouse and
keyboard users receive clear feedback while keeping the same visual design.
|
|
||
| <section class="card-grid"> | ||
| <div class="magic-bento-card"> | ||
| <div class="header"><img src="https://cdn-icons-png.flaticon.com/512/1160/1160040.png" width="50"></div> |
There was a problem hiding this comment.
All three feature-card <img> elements are missing alt attributes — WCAG 2.1 SC 1.1.1 (Level A) violation.
Without alt, screen readers fall back to reading the full CDN URL aloud, which is meaningless noise. For a product landing page whose entire value proposition is accessibility, this is a critical self-contradiction.
♿ Proposed fix
- <div class="header"><img src="https://cdn-icons-png.flaticon.com/512/1160/1160040.png" width="50"></div>
+ <div class="header"><img src="https://cdn-icons-png.flaticon.com/512/1160/1160040.png" width="50" alt="Color palette icon"></div>- <div class="header"><img src="https://cdn-icons-png.flaticon.com/512/2103/2103633.png" width="50"></div>
+ <div class="header"><img src="https://cdn-icons-png.flaticon.com/512/2103/2103633.png" width="50" alt="Text-to-speech icon"></div>- <div class="header"><img src="https://cdn-icons-png.flaticon.com/512/2092/2092663.png" width="50"></div>
+ <div class="header"><img src="https://cdn-icons-png.flaticon.com/512/2092/2092663.png" width="50" alt="Image removal icon"></div>Also applies to: 334-334, 342-342
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@dino_webpage/dino.html` at line 326, Three <img> tags inside the feature-card
blocks (the <div class="header"> image and its two siblings) lack alt attributes
causing WCAG 2.1 SC 1.1.1 violations; add appropriate alt text for each <img>
(e.g., concise descriptive strings that convey the image's purpose like "Rocket
icon — fast setup" or "Analytics icon — insights") or use alt="" for purely
decorative images, ensuring the alt values live on the <img> elements inside the
feature-card/header blocks so screen readers get meaningful text instead of the
CDN URL.
| document.querySelectorAll('.word').forEach(word => { | ||
| word.addEventListener('click', function() { | ||
| this.style.transition = "transform 1s cubic-bezier(.17,.67,.83,.67), opacity 1s"; | ||
| this.style.transform = `translateY(${window.innerHeight}px) rotate(${Math.random() * 360}deg)`; | ||
| this.style.opacity = "0"; | ||
| setTimeout(() => { | ||
| this.style.transition = "none"; | ||
| this.style.transform = "translateY(0) rotate(0)"; | ||
| this.style.opacity = "1"; | ||
| }, 2000); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Word click animation has no re-entry guard — rapid clicks cause stacked timeouts and visual glitches.
Clicking a word a second time before the 2-second reset fires starts a new transform/opacity animation from the word's current mid-flight (partially invisible, translated) position. The stacked setTimeout callbacks then fight each other: the word can snap, freeze, or become permanently invisible.
🐛 Proposed fix — add an `isAnimating` guard
document.querySelectorAll('.word').forEach(word => {
+ let isAnimating = false;
word.addEventListener('click', function() {
+ if (isAnimating) return;
+ isAnimating = true;
this.style.transition = "transform 1s cubic-bezier(.17,.67,.83,.67), opacity 1s";
this.style.transform = `translateY(${window.innerHeight}px) rotate(${Math.random() * 360}deg)`;
this.style.opacity = "0";
setTimeout(() => {
this.style.transition = "none";
this.style.transform = "translateY(0) rotate(0)";
this.style.opacity = "1";
+ isAnimating = false;
}, 2000);
});
});📝 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.
| document.querySelectorAll('.word').forEach(word => { | |
| word.addEventListener('click', function() { | |
| this.style.transition = "transform 1s cubic-bezier(.17,.67,.83,.67), opacity 1s"; | |
| this.style.transform = `translateY(${window.innerHeight}px) rotate(${Math.random() * 360}deg)`; | |
| this.style.opacity = "0"; | |
| setTimeout(() => { | |
| this.style.transition = "none"; | |
| this.style.transform = "translateY(0) rotate(0)"; | |
| this.style.opacity = "1"; | |
| }, 2000); | |
| }); | |
| }); | |
| document.querySelectorAll('.word').forEach(word => { | |
| let isAnimating = false; | |
| word.addEventListener('click', function() { | |
| if (isAnimating) return; | |
| isAnimating = true; | |
| this.style.transition = "transform 1s cubic-bezier(.17,.67,.83,.67), opacity 1s"; | |
| this.style.transform = `translateY(${window.innerHeight}px) rotate(${Math.random() * 360}deg)`; | |
| this.style.opacity = "0"; | |
| setTimeout(() => { | |
| this.style.transition = "none"; | |
| this.style.transform = "translateY(0) rotate(0)"; | |
| this.style.opacity = "1"; | |
| isAnimating = false; | |
| }, 2000); | |
| }); | |
| }); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@dino_webpage/dino.html` around lines 399 - 410, The click handler on elements
selected by document.querySelectorAll('.word') lacks a re-entry guard, so
multiple rapid clicks queue overlapping setTimeouts and conflicting transforms;
fix by adding an animation flag (e.g., element.dataset.isAnimating or a class
like 'animating') checked at the start of the listener and set to true before
starting the transition, then clear it (set to false/remove class) in the
timeout callback before resetting styles; ensure the guard prevents starting a
new animation while isAnimating is true and that the timeout always clears the
flag even if styles are reset early.
📌 Description
Added a new Dino Interactive Accessibility Webpage.
🚀 Features Added
🛠️ Tech Used
📷 Preview
This page represents the Dino extension and improves user experience with modern UI and interactivity.
✅ Status
Ready for review and merge.
Summary by CodeRabbit