Skip to content

Implement blog snippet system and new landing page - #1

Open
Cnnb01 wants to merge 29 commits into
mainfrom
landing_page
Open

Implement blog snippet system and new landing page#1
Cnnb01 wants to merge 29 commits into
mainfrom
landing_page

Conversation

@Cnnb01

@Cnnb01 Cnnb01 commented Jul 28, 2025

Copy link
Copy Markdown

Summary

This PR adds support for rendering blog snippets and full blog content from markdown files using Astro. It includes:

  • BlogCard.tsx: reusable component to render blog snippet previews.
  • BlogSnippets.ts: contains data and its types for previewing blog snippets.
  • Markdown styling improvements for blog content
  • public/styles/mylanding.css for styling all pages.
  • Added images under public/images/ for blog use.
  • Implemented blogLayout.astro to display individual blog pages.
  • Built newLanding page for the new homepage experience.

Summary by CodeRabbit

  • New Features

    • New landing page with dark theme, hero image, overlay title, improved navigation, and a blogs listing; individual blog pages with featured image, author, localized dates, and prev/next links.
    • Newsletter callout and social links.
  • Style

    • New responsive stylesheet and typography for consistent dark-mode presentation.
  • Chores

    • React integration added, dependencies updated, and TypeScript JSX configured; BlogPost type added.
  • Security

    • CSP updated to allow Google Fonts and an external script.

Added:
- Blog images in public/images/
- Global styles in public/styles/mylanding.css
- BlogCard component for displaying blog previews
- blogsnippets.ts with blog metadata
- blogLayout.astro to render individual blog posts
- blogSnippets page to show all previews
- newLnding page for updated landing layout
@coderabbitai

coderabbitai Bot commented Jul 28, 2025

Copy link
Copy Markdown

Walkthrough

Added React integration and TypeScript JSX settings, installed React deps, introduced a dark-themed landing and blog UI, added a BlogPost type, added /newLanding, /blogSnippets, and dynamic /[slug] pages (with getStaticPaths fetching WP posts), and updated CSP to allow Google Fonts and an external script.

Changes

Cohort / File(s) Summary
Astro + TypeScript React setup
landing-panda/astro.config.mjs, landing-panda/tsconfig.json, landing-panda/package.json
Enable @astrojs/react in Astro config; add React deps (react, react-dom, @astrojs/react, @types/react, @types/react-dom); set TypeScript JSX options (jsx: "react-jsx", jsxImportSource: "react").
Landing page & home link
landing-panda/src/pages/newLanding.astro, landing-panda/src/pages/index.astro
Add newLanding.astro (full HTML landing page with two-column hero, metadata, nav, external links); update index.astro to point to /newLanding.
Blog listing and dynamic post pages
landing-panda/src/pages/blogSnippets.astro, landing-panda/src/pages/[slug].astro
Add /blogSnippets page that fetches WP posts and renders excerpts with read-more links; add dynamic /[slug] with getStaticPaths() fetching posts (_embed) and rendering full post content, featured media, author, prev/next links.
Types
landing-panda/src/data/types.ts
Add and export BlogPost TypeScript interface matching WP post shape (id, date, slug, title, content, excerpt, link, author, media URL, optional _embedded).
Styles
landing-panda/src/styles/mylanding.css
Add new dark-themed responsive stylesheet for landing and blog pages (fonts, CSS variables, layout, blog/snippet styles, responsive breakpoints).
Security middleware
server-panda/src/middleware/security.ts
Extend Content Security Policy: allow https://fonts.googleapis.com in style-src and allow https://akongalabs.kit.com/4e5ba9cc5c/index.js in script-src.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant AstroServer as Astro Page
  participant WP as WordPress API

  User->>AstroServer: GET /blogSnippets
  AstroServer->>WP: GET /wp-json/wp/v2/posts
  WP-->>AstroServer: posts[]
  AstroServer-->>User: Rendered blog list (titles, excerpts, read-more links)
Loading
sequenceDiagram
  participant Builder as Astro Build
  participant WP as WordPress API
  participant Page as [slug].astro

  Builder->>WP: GET /wp-json/wp/v2/posts?_embed
  WP-->>Builder: posts[]
  loop for each post
    Builder->>Page: provide post props for /{slug}
    Page-->>Builder: render static HTML (title, content, media, meta)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

In a burrow of CSS I nibble and plot,
I slipped in React carrots, tidy and hot.
Snippets parade and slugs roll by,
Fonts and scripts wave safe in the sky.
Hop, merge, and munch — deploy with a hop! 🥕✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch landing_page

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@Cnnb01
Cnnb01 requested a review from adrianmurage July 28, 2025 05:51

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🧹 Nitpick comments (8)
landing-panda/src/data/blogsnippets.ts (1)

8-33: Consider improving maintainability of blog data structure.

While the current static array works, consider these improvements for better maintainability:

  1. Add metadata like tags, author, or publication status
  2. Consider moving to a more scalable data source (JSON file, CMS, or database)
  3. Add validation for required fields

Here's an enhanced version with additional metadata:

 export type BlogSnippet = {
   date: string;
   title: string;
   snippet: string;
   link: string;
+  author?: string;
+  tags?: string[];
+  published?: boolean;
 };
landing-panda/src/pages/index.astro (1)

17-18: Clean up commented code and consider baseUrl consistency.

Consider removing the commented line rather than leaving it in the codebase. Also, for consistency with other links, you might want to use the same baseUrl pattern:

-        <!-- <p><a href="/landing">Go to Landing Page</a></p> -->
-        <p><a href="/newLanding">Go to Landing Page</a></p>
+        <p><a href={`${baseUrl}/newLanding`}>Go to Landing Page</a></p>
landing-panda/src/pages/blogSnippets.astro (1)

15-19: Consider adding semantic structure.

The navigation links would benefit from being wrapped in a <nav> element for better accessibility and semantic HTML.

Apply this diff to improve semantics:

    <div class="blogs_container">
-        <div class="first_links">
+        <nav class="first_links">
            <a href="/newLanding">Akong'a Labs</a>
            <a href="/blogSnippets">Blogs</a>
-        </div>
+        </nav>
landing-panda/src/components/BlogCard.tsx (1)

12-14: Consider consolidating duplicate links for better UX.

Both the title and "Read more" link point to the same destination, which could be confusing for users and screen readers. Consider making the entire card clickable or removing one of the links.

Option 1 - Make the entire card clickable:

const BlogCard = ({ title, date, snippet, link }: BlogCardProps) => {
  return (
-    <div>
+    <div className="blog-card" onClick={() => window.location.href = link} style={{ cursor: 'pointer' }}>
      <p className="bluecolor" >{date}</p>
-      <h1><a href={link}>{title}</a></h1>
+      <h1>{title}</h1>
      <p className="para_space">{snippet}</p>
-      <a className="bluecolor readmore" href={link}>Read more→</a>
    </div>
  );
};

Option 2 - Keep only the "Read more" link:

      <p className="bluecolor" >{date}</p>
-      <h1><a href={link}>{title}</a></h1>
+      <h1>{title}</h1>
      <p className="para_space">{snippet}</p>
      <a className="bluecolor readmore" href={link}>Read more→</a>
landing-panda/src/pages/newLanding.astro (1)

18-21: Enhance navigation with semantic HTML.

Similar to the blog snippets page, the navigation would benefit from proper semantic structure.

Apply this diff to improve accessibility:

-              <div class="first_links">
+              <nav class="first_links" aria-label="Main navigation">
                  <a href="/newLanding">Akong'a Labs</a>
                  <a href="/blogSnippets">Blogs</a>
-              </div>
+              </nav>
landing-panda/src/pages/blogs/blog1.md (1)

15-15: Missing space after period breaks the sentence

There is no space between “nothing”. and “The”, which renders as a single word in most markdown engines.

-...I **owned nothing**.The outsized returns of my work...
+...I **owned nothing**. The outsized returns of my work...
landing-panda/src/pages/blogs/blog2.md (1)

3-3: Consistent image pathing

Same concern as in blog1.md – prefer the root-based path so directory moves don’t break links.

-cover: ../../../images/blog2.webp
+cover: /images/blog2.webp
landing-panda/src/pages/blogs/blog3.md (1)

3-3: Align cover path with public asset convention

For consistency and to avoid broken URLs on future refactors:

-cover: ../../../images/blog3.webp
+cover: /images/blog3.webp
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1fefb2e and 91300fd.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (14)
  • landing-panda/astro.config.mjs (1 hunks)
  • landing-panda/package.json (1 hunks)
  • landing-panda/public/styles/mylanding.css (1 hunks)
  • landing-panda/src/components/BlogCard.tsx (1 hunks)
  • landing-panda/src/data/blogsnippets.ts (1 hunks)
  • landing-panda/src/pages/blogLayout.astro (1 hunks)
  • landing-panda/src/pages/blogSnippets.astro (1 hunks)
  • landing-panda/src/pages/blogs/blog1.md (1 hunks)
  • landing-panda/src/pages/blogs/blog2.md (1 hunks)
  • landing-panda/src/pages/blogs/blog3.md (1 hunks)
  • landing-panda/src/pages/blogs/blog4.md (1 hunks)
  • landing-panda/src/pages/index.astro (1 hunks)
  • landing-panda/src/pages/newLanding.astro (1 hunks)
  • landing-panda/tsconfig.json (1 hunks)
🧰 Additional context used
🪛 LanguageTool
landing-panda/src/pages/blogs/blog4.md

[uncategorized] ~112-~112: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ... Previous: Solve, Build, Get Paid: Open Source Bounties at Akong’a 🖤 GitHub...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

landing-panda/src/pages/blogs/blog2.md

[uncategorized] ~119-~119: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...](#) Next: Solve, Build, Get Paid: Open Source Bounties at Akong’a

(EN_COMPOUND_ADJECTIVE_INTERNAL)

landing-panda/src/pages/blogs/blog1.md

[style] ~45-~45: ‘by all means’ might be wordy. Consider a shorter alternative.
Context: ...nless you’re in a regulated field. Then by all means, go study, my dear Lawyers and Doctors....

(EN_WORDINESS_PREMIUM_BY_ALL_MEANS)


[style] ~47-~47: ‘in this day and age’ might be wordy. Consider a shorter alternative.
Context: ...us. Learning is very very close to free in this day and age. If you’re reading this, you already pa...

(EN_WORDINESS_PREMIUM_IN_THIS_DAY_AND_AGE)

landing-panda/src/pages/blogs/blog3.md

[uncategorized] ~6-~6: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...og3.webp --- # Solve, Build, Get Paid: Open Source Bounties at Akong’a ![Akonga Banner](/i...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[uncategorized] ~17-~17: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...arn by solving real problems.** How? Open source bounties. To be clear—this isn’t the...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[style] ~73-~73: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...e not for people looking for shortcuts. They’re for: - Developers who want a seriou...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🪛 markdownlint-cli2 (0.17.2)
landing-panda/src/pages/blogs/blog4.md

112-112: No empty links

(MD042, no-empty-links)


114-114: No empty links

(MD042, no-empty-links)

landing-panda/src/pages/blogs/blog3.md

142-142: No empty links

(MD042, no-empty-links)


158-158: No empty links

(MD042, no-empty-links)


168-168: No empty links

(MD042, no-empty-links)


169-169: No empty links

(MD042, no-empty-links)

🔇 Additional comments (15)
landing-panda/src/data/blogsnippets.ts (2)

1-6: LGTM! Clean type definition.

The BlogSnippet type is well-structured with appropriate string properties for blog metadata.


10-13: Verify future dates and incomplete snippet content.

The date "June 28, 2025" appears to be in the future, and the snippet text contains incomplete sentences ("Her interpretation of brutal honesty was focused on the word "brutal". This led to a very very spirited discussion on whether one needs to be brutal to be honest. She questioned whether brutal…").

Please confirm these are intentional for demo purposes.

landing-panda/astro.config.mjs (1)

4-9: LGTM! Proper React integration setup.

The React integration is correctly configured following Astro's standard approach. This enables React components to be used within Astro pages.

landing-panda/tsconfig.json (2)

3-9: LGTM! Improved formatting and structure.

The multiline formatting of include/exclude arrays improves readability and maintainability.


10-13: LGTM! Correct React JSX configuration.

The compiler options are properly configured for React integration using the modern JSX transform. This aligns perfectly with the React integration added to the Astro config.

landing-panda/package.json (2)

11-18: LGTM! Complete React integration dependency setup.

All necessary dependencies for React integration are included with appropriate type definitions. The dependency structure supports the React components and configuration changes made throughout the project.


12-17: React 19.1.0 compatibility with @astrojs/react@4.3.0 confirmed

Verified that @astrojs/react@4.3.0 lists a peer dependency of react: ^19.0.0 (and react-dom: ^19.0.0), so using React 19.1.0 (and its matching type definitions) is fully supported. No further action needed.

landing-panda/src/pages/blogLayout.astro (1)

20-23: LGTM! Navigation structure is well-organized.

The navigation links provide clear pathways between the main site and blog sections, enhancing user experience.

landing-panda/src/pages/blogSnippets.astro (1)

20-29: LGTM! Clean React integration and data mapping.

The mapping over blogPosts and passing props to the BlogCard component is well-structured. The destructuring and prop passing follows React best practices within the Astro context.

landing-panda/src/components/BlogCard.tsx (1)

1-6: LGTM! Well-defined TypeScript interface.

The BlogCardProps type definition is clean and provides clear typing for all required props.

landing-panda/src/pages/blogs/blog4.md (1)

1-4: LGTM! Proper frontmatter configuration.

The layout reference and cover image configuration correctly integrate with the blog system architecture.

landing-panda/src/pages/newLanding.astro (2)

34-34: LGTM! Good image accessibility.

The image includes proper alt text, which is essential for accessibility and SEO.


22-26: LGTM! Clear and engaging content structure.

The company description effectively communicates the mission and values with good use of strikethrough text for emphasis.

landing-panda/src/pages/blogs/blog1.md (1)

3-3: Prefer absolute /images/... path for the cover field

cover is consumed by blogLayout.astro. All other image references in the post use the public-rooted version (/images/blog1.webp). Keeping the same convention prevents accidental 404s if the page is ever moved or the directory depth changes.

-cover: ../../../images/blog1.webp
+cover: /images/blog1.webp
landing-panda/src/pages/blogs/blog2.md (1)

118-119: Placeholder links render as empty anchors

(#) is flagged by markdown-lint (MD042) and will produce dead links in production.
Either point to the real URL or remove the link markup until it exists.

-**Previous:** [Why I’m Starting This Company](#)
-**Next:** [Solve, Build, Get Paid: Open Source Bounties at Akong’a](#)
+<!-- TODO: replace “#” with the actual permalinks once available -->
+**Previous:** Why I’m Starting This Company
+**Next:** Solve, Build, Get Paid: Open Source Bounties at Akong’a

Comment on lines +136 to +139
.blog-post title{
align-content: center;
align-self: center;
}

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

Selector does nothing – title is not a valid HTML element

If you intended to target a .title class inside .blog-post, the selector needs a dot; otherwise the rule is ignored.

-.blog-post title{
+.blog-post .title{
🤖 Prompt for AI Agents
In landing-panda/public/styles/mylanding.css around lines 136 to 139, the
selector ".blog-post title" is invalid because "title" is not an HTML element.
To fix this, change the selector to ".blog-post .title" to target elements with
the class "title" inside elements with the class "blog-post". This will ensure
the CSS rules are applied correctly.

Comment on lines +141 to +144
.blog-post h1, h2, h3 {
margin-top: 1.5rem;
margin-bottom: 0.75rem;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Unintentionally un-scoped h2 & h3 selectors

h2, h3 are no longer under .blog-post, so these rules will apply globally.
Scope each selector explicitly:

-.blog-post h1, h2, h3 {
+.blog-post h1,
+.blog-post h2,
+.blog-post h3 {
📝 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
.blog-post h1, h2, h3 {
margin-top: 1.5rem;
margin-bottom: 0.75rem;
}
.blog-post h1,
.blog-post h2,
.blog-post h3 {
margin-top: 1.5rem;
margin-bottom: 0.75rem;
}
🤖 Prompt for AI Agents
In landing-panda/public/styles/mylanding.css at lines 141 to 144, the selectors
h2 and h3 are not scoped under .blog-post, causing the styles to apply globally.
To fix this, explicitly scope h2 and h3 by prefixing them with .blog-post so the
CSS rules only apply to headings within .blog-post elements.

Comment on lines +3 to +6
import "../../public/images/blog1.webp"
import "../../public/images/blog2.webp"
import "../../public/images/blog3.webp"
import "../../public/images/blog4.webp"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove unnecessary image imports.

The image imports in the frontmatter appear unused in this layout component. These should only be imported where they're actually referenced.

Apply this diff to remove unused imports:

---
import "../../public/styles/mylanding.css"
-import "../../public/images/blog1.webp"
-import "../../public/images/blog2.webp"
-import "../../public/images/blog3.webp"
-import "../../public/images/blog4.webp"
---
📝 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
import "../../public/images/blog1.webp"
import "../../public/images/blog2.webp"
import "../../public/images/blog3.webp"
import "../../public/images/blog4.webp"
import "../../public/styles/mylanding.css"
🤖 Prompt for AI Agents
In landing-panda/src/pages/blogLayout.astro around lines 3 to 6, the image
imports are unused in this layout component. Remove all four import statements
for the blog images to clean up the code and avoid unnecessary imports.

Comment on lines +10 to +16
<head>
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<title>Blog layout</title>
</head>

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

Fix duplicate head tags.

There are nested <head> tags which creates invalid HTML structure that can cause rendering issues and prevent proper meta tag processing.

Apply this diff to fix the structure:

  <head>
-      <head>
-        <meta charset="utf-8" />
-        <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
-        <meta name="viewport" content="width=device-width" />
-        <title>Blog layout</title>
+    <meta charset="utf-8" />
+    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
+    <meta name="viewport" content="width=device-width" />
+    <title>Blog layout</title>
  </head>
📝 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
<head>
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<title>Blog layout</title>
</head>
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<title>Blog layout</title>
</head>
🤖 Prompt for AI Agents
In landing-panda/src/pages/blogLayout.astro around lines 10 to 16, there are
nested <head> tags causing invalid HTML structure. Remove the inner <head> tag
so that only one <head> tag wraps all the meta and link elements, ensuring
proper HTML structure and correct meta tag processing.

Comment thread landing-panda/src/pages/blogs/blog3.md Outdated
Comment on lines +141 to +149
🔗 **Check out the bounties here**:
👉 [Akong’a Labs OSS Bounties GitHub Repo](#)

- Pick a challenge
- Read the instructions
- Follow them to the letter
- Ask questions in public if you’re stuck
- **And most importantly—build something that works.**

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Multiple empty links – fails MD042 and hurts UX

Replace (#) with real URLs or leave plain text until the targets exist.

-🔗 **Check out the bounties here**:
-👉 [Akong’a Labs OSS Bounties GitHub Repo](#)
+🔗 **Check out the bounties here**: 👉 Akong’a Labs OSS Bounties GitHub Repo
...
-Check it out: [Antiwork/bounties](#)
+Check it out: Antiwork/bounties
...
-**Previous:** [Understanding Remote Onboarding: Lessons from Akong'a Labs](#)
-**Next:** [The Power of Honest Communication in Teams](#)
+<!-- TODO: Add real permalinks when available -->
+**Previous:** Understanding Remote Onboarding: Lessons from Akong'a Labs
+**Next:** The Power of Honest Communication in Teams
📝 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
🔗 **Check out the bounties here**:
👉 [Akong’a Labs OSS Bounties GitHub Repo](#)
- Pick a challenge
- Read the instructions
- Follow them to the letter
- Ask questions in public if you’re stuck
- **And most importantly—build something that works.**
🔗 **Check out the bounties here**: 👉 Akong’a Labs OSS Bounties GitHub Repo
- Pick a challenge
- Read the instructions
- Follow them to the letter
- Ask questions in public if you’re stuck
- **And most importantly—build something that works.**
Check it out: Antiwork/bounties
<!-- TODO: Add real permalinks when available -->
**Previous:** Understanding Remote Onboarding: Lessons from Akong'a Labs
**Next:** The Power of Honest Communication in Teams
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

142-142: No empty links

(MD042, no-empty-links)

🤖 Prompt for AI Agents
In landing-panda/src/pages/blogs/blog3.md around lines 141 to 149, the markdown
contains empty links using (#) which triggers MD042 lint errors and degrades
user experience. Replace these placeholder links with actual URLs pointing to
the correct resources. If the URLs are not yet available, remove the link
formatting and leave the text as plain text until valid targets exist.

Comment thread landing-panda/src/pages/blogs/blog4.md Outdated
Comment thread landing-panda/src/pages/blogs/blog4.md Outdated
Comment on lines +112 to +114
**Previous:** [Solve, Build, Get Paid: Open Source Bounties at Akong’a](#)

🖤 [GitHub](#)

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

Fix empty placeholder links.

The markdown contains empty links that will not function properly and create a poor user experience.

Apply this diff to either remove the placeholders or add proper URLs:

-**Previous:** [Solve, Build, Get Paid: Open Source Bounties at Akong'a](#)
+**Previous:** [Solve, Build, Get Paid: Open Source Bounties at Akong'a](/blogs/blog3)

-🖤 [GitHub](#)
+🖤 [GitHub](https://github.com/AkongaLabs)

Or remove the placeholders entirely if the links aren't ready:

-**Previous:** [Solve, Build, Get Paid: Open Source Bounties at Akong'a](#)
-
-🖤 [GitHub](#)
📝 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
**Previous:** [Solve, Build, Get Paid: Open Source Bounties at Akonga](#)
🖤 [GitHub](#)
**Previous:** [Solve, Build, Get Paid: Open Source Bounties at Akong'a](/blogs/blog3)
🖤 [GitHub](https://github.com/AkongaLabs)
🧰 Tools
🪛 LanguageTool

[uncategorized] ~112-~112: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ... Previous: Solve, Build, Get Paid: Open Source Bounties at Akong’a 🖤 GitHub...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

🪛 markdownlint-cli2 (0.17.2)

112-112: No empty links

(MD042, no-empty-links)


114-114: No empty links

(MD042, no-empty-links)

🤖 Prompt for AI Agents
In landing-panda/src/pages/blogs/blog4.md around lines 112 to 114, there are
empty placeholder links that do not function properly. To fix this, either
replace the "#" in the markdown links with the correct URLs or remove the links
entirely if the URLs are not yet available, ensuring no empty or broken links
remain.

Comment on lines +3 to +4
const isDev = import.meta.env.DEV;
const baseUrl = isDev ? "http://localhost:3001" : "";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove unused baseUrl variable.

The baseUrl variable is declared but never used in the component, creating unnecessary code.

Apply this diff to remove the unused variable:

---
import '../../public/styles/mylanding.css'
-const isDev = import.meta.env.DEV;
-const baseUrl = isDev ? "http://localhost:3001" : "";
---
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const isDev = import.meta.env.DEV;
const baseUrl = isDev ? "http://localhost:3001" : "";
---
import '../../public/styles/mylanding.css'
---
🤖 Prompt for AI Agents
In landing-panda/src/pages/newLanding.astro at lines 3 to 4, the variable
baseUrl is declared but never used. Remove the declaration of baseUrl entirely
to clean up the code and avoid unused variables.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (3)
landing-panda/src/pages/blogs/blog3.md (1)

95-96: Empty placeholder links trigger MD042 again

Both “Previous” and “Next” still point to (#) / empty parentheses, re-introducing the lint error already raised in the earlier review. Replace with real permalinks or fall back to plain text until the URLs exist.

-**Previous:** [Understanding Remote Onboarding: Lessons from Akong'a Labs](#)
-**Next:** [The Power of Honest Communication in Teams]()
+<!-- TODO: add real permalinks when available -->
+**Previous:** Understanding Remote Onboarding: Lessons from Akong'a Labs
+**Next:** The Power of Honest Communication in Teams
landing-panda/src/pages/blogs/blog4.md (2)

66-66: Replace placeholder “[EMAIL BOX]” with a real signup form or remove it.


70-70: Update or remove the empty placeholder link (#).

🧹 Nitpick comments (5)
landing-panda/src/pages/blogs/blog3.md (2)

84-86: Extraneous trailing colon after the Antiwork link

The sentence already ends with a colon before the link. The second colon after the closing parenthesis is redundant and will render oddly.

-Check it out over at: [Antiwork/bounties](https://antiwork.com/bounties):
+Check it out over at: [Antiwork/bounties](https://antiwork.com/bounties)

92-94: [EMAIL BOX] is a visible placeholder

Leaving the placeholder in published markdown breaks immersion and looks unfinished. Either embed a real email signup form/component or replace the section with a TODO comment so it is excluded from the rendered HTML.

landing-panda/src/pages/blogs/blog4.md (2)

16-16: Correct typos “wheathe” → “whether” and “concerened” → “concerned”.

-... She questioned wheathe brutal honesty equated to being rude? She was concerened and rightfully so...
+... She questioned whether brutal honesty equated to being rude? She was concerned and rightfully so...

57-57: Refine the wording of the sentence for clarity.

-Good communication breeds by comprehension.
+Good communication is cultivated through comprehension.
landing-panda/src/pages/blogs/blog2.md (1)

24-26: Fix missing initial character in paragraph “First Contact”.

The paragraph currently starts with “fter I got the job…”, dropping the leading “A”.
This typo is visible to end-users and undermines credibility.

-fter I got the job, my manager told me I would be contacted by his assistant, Ivy, through their main communication channel, Telegram.
+After I got the job, my manager told me I would be contacted by his assistant, Ivy, through their main communication channel, Telegram.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 91300fd and d737f6a.

📒 Files selected for processing (6)
  • landing-panda/public/styles/mylanding.css (1 hunks)
  • landing-panda/src/components/BlogCard.tsx (1 hunks)
  • landing-panda/src/pages/blogs/blog1.md (1 hunks)
  • landing-panda/src/pages/blogs/blog2.md (1 hunks)
  • landing-panda/src/pages/blogs/blog3.md (1 hunks)
  • landing-panda/src/pages/blogs/blog4.md (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • landing-panda/public/styles/mylanding.css
🚧 Files skipped from review as they are similar to previous changes (1)
  • landing-panda/src/components/BlogCard.tsx
🧰 Additional context used
🪛 LanguageTool
landing-panda/src/pages/blogs/blog1.md

[style] ~31-~31: ‘by all means’ might be wordy. Consider a shorter alternative.
Context: ...nless you’re in a regulated field. Then by all means go study my dear Lawyers and Doctors. (...

(EN_WORDINESS_PREMIUM_BY_ALL_MEANS)


[style] ~33-~33: ‘in this day and age’ might be wordy. Consider a shorter alternative.
Context: ...us. Learning is very very close to free in this day and age. If you’re reading this, you already pa...

(EN_WORDINESS_PREMIUM_IN_THIS_DAY_AND_AGE)

landing-panda/src/pages/blogs/blog2.md

[grammar] ~24-~24: Ensure spelling is correct
Context: ...ng from day one. --- ## First Contact fter I got the job, my manager told me I wou...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[uncategorized] ~94-~94: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...](#) Next: Solve, Build, Get Paid: Open Source Bounties at Akong’a

(EN_COMPOUND_ADJECTIVE_INTERNAL)

landing-panda/src/pages/blogs/blog3.md

[uncategorized] ~6-~6: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...og3.webp --- # Solve, Build, Get Paid: Open Source Bounties at Akong’a ![Akonga Banner](/i...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[uncategorized] ~13-~13: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ... to earn by solving real problems. How? Open source bounties. To be clear, this isn’t the v...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[style] ~40-~40: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...ssions are of the quality we expect. We are able to look at them knowing they meet our stan...

(BE_ABLE_TO)


[style] ~43-~43: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...e not for people looking for shortcuts. They’re for developers who want a serious ch...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

landing-panda/src/pages/blogs/blog4.md

[grammar] ~16-~16: Ensure spelling is correct
Context: ... be brutal to be honest. She questioned wheathe brutal honesty equated to being rude? S...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~16-~16: Ensure spelling is correct
Context: ... honesty equated to being rude? She was concerened and rightfully so... --- ## The Akong...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~26-~26: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...ng disgruntled. This is something very very important to me and that’s at the core of the Ako...

(EN_WEAK_ADJECTIVE)


[style] ~26-~26: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...DNA. I am human. I am not always right. I will not tolerate a team of “yes” men. ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~26-~26: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... will not tolerate a team of “yes” men. I need to trust that my team will questio...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[uncategorized] ~70-~70: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ... Previous: Solve, Build, Get Paid: Open Source Bounties at Akong’a

(EN_COMPOUND_ADJECTIVE_INTERNAL)

🪛 markdownlint-cli2 (0.17.2)
landing-panda/src/pages/blogs/blog2.md

93-93: No empty links

(MD042, no-empty-links)


94-94: No empty links

(MD042, no-empty-links)

landing-panda/src/pages/blogs/blog3.md

95-95: No empty links

(MD042, no-empty-links)


96-96: No empty links

(MD042, no-empty-links)

landing-panda/src/pages/blogs/blog4.md

70-70: No empty links

(MD042, no-empty-links)

🔇 Additional comments (2)
landing-panda/src/pages/blogs/blog1.md (1)

46-46: Next link is a dead placeholder

href="#" hurts navigation and SEO. Point it to the real next post (e.g. /blogs/blog2) or omit the link until the destination exists.

-**Next:** [Understanding Remote Onboarding: Lessons from Akong'a Labs](#)
+**Next:** [Understanding Remote Onboarding: Lessons from Akong'a Labs](/blogs/blog2)
landing-panda/src/pages/blogs/blog2.md (1)

2-4: Verify “cover” image path – may break at build time.

cover: ../../../images/blog2.webp climbs three directories from src/pages/blogs/ to resolve images/blog2.webp, but the image resides under public/images/.
Astro generally expects either an absolute path (/images/...) or a path under src/assets. Please confirm the asset is picked up correctly; otherwise the cover thumbnail will 404.

Comment thread landing-panda/src/pages/blogs/blog1.md Outdated
Comment on lines +1 to +4
---
layout: ../blogLayout.astro
cover: ../../../images/blog1.webp
---

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

Cover image path likely breaks at runtime

cover: "../../../images/blog1.webp" walks three levels up to project root, but the asset actually lives under public/images/. Astro serves everything inside public from the site-root (/images/...). Use an absolute site path (preferred) or walk into ../public/images.

-cover: ../../../images/blog1.webp
+cover: /images/blog1.webp   # or "../public/images/blog1.webp"
📝 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
---
layout: ../blogLayout.astro
cover: ../../../images/blog1.webp
---
---
layout: ../blogLayout.astro
cover: /images/blog1.webp # or "../public/images/blog1.webp"
---
🤖 Prompt for AI Agents
In landing-panda/src/pages/blogs/blog1.md lines 1 to 4, the cover image path is
incorrect because it uses a relative path that goes three levels up, but the
image is actually in the public/images directory served from the site root. Fix
this by changing the cover path to an absolute site path like
"/images/blog1.webp" instead of "../../../images/blog1.webp".

Comment thread landing-panda/src/pages/blogs/blog1.md Outdated
Comment thread landing-panda/src/pages/blogs/blog2.md Outdated
Cnnb01 added 2 commits July 28, 2025 16:48
- Embedded external form script on blog snippet and individual blog pages
- Implemented responsive design using media queries for different screens sizes
- Adjusted layout and image positioning for better mobile view

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (1)
landing-panda/src/pages/blogs/blog1.md (1)

3-3: Cover image path still incorrect – will 404 at runtime
The image lives under public/images/, which Astro serves from site-root.
Keep the inline image on Line 6, but update the front-matter to the same absolute path to avoid a broken cover URL.

-cover: ../../../images/blog1.webp
+cover: /images/blog1.webp
🧹 Nitpick comments (7)
landing-panda/src/pages/blogs/blog3.md (2)

84-86: Superfluous colon after the Antiwork link

The text already ends with a colon before the link. The extra colon immediately after ) renders as plain text and looks like a typo.

-Check it out over at: [Antiwork/bounties](https://antiwork.com/bounties):
+Check it out over at: [Antiwork/bounties](https://antiwork.com/bounties)

48-52: Minor wording tweak for readability

Missing punctuation after “help you” makes the list of tools read oddly.

-Yup. Use AI tools if they help you Cursor, Zed, ChatGPT, whatever works for you.
+Yup. Use AI tools if they help you—Cursor, Zed, ChatGPT, whatever works for you.
landing-panda/src/pages/blogs/blog4.md (2)

20-30: Style nitpick – repeated intensifiers dilute impact

Sentences such as “very very positive” and “very very important” appear twice in this paragraph. Consider dropping one “very” or using a stronger adjective for tighter prose.


53-54: Grammar tweak for clarity

“Good communication breeds by comprehension.” reads awkwardly.
Suggested: “Good communication is bred by comprehension.” or “Good communication stems from comprehension.”

landing-panda/src/pages/blogs/blog2.md (3)

24-26: Typo: leading “A” dropped

Small but visible copy error.

-fter I got the job, my manager told me …
+After I got the job, my manager told me …

77-77: Extraneous space before comma

Minor punctuation issue—remove the space before the comma to avoid rendering a stray “ , ”.

-article by our founder , it’s the heartbeat behind the company.
+article by our founder, it’s the heartbeat behind the company.

96-97: Use “Open-Source” as a compound adjective

Hyphenating avoids the markdown-lint MD040 complaint and reads better.

-**Next:** [Solve, Build, Get Paid: Open Source Bounties at Akong’a](/blogs/blog3)
+**Next:** [Solve, Build, Get Paid: Open-Source Bounties at Akong’a](/blogs/blog3)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db70c24 and 347fea9.

📒 Files selected for processing (7)
  • landing-panda/public/styles/mylanding.css (1 hunks)
  • landing-panda/src/pages/blogLayout.astro (1 hunks)
  • landing-panda/src/pages/blogSnippets.astro (1 hunks)
  • landing-panda/src/pages/blogs/blog1.md (1 hunks)
  • landing-panda/src/pages/blogs/blog2.md (1 hunks)
  • landing-panda/src/pages/blogs/blog3.md (1 hunks)
  • landing-panda/src/pages/blogs/blog4.md (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • landing-panda/src/pages/blogLayout.astro
  • landing-panda/public/styles/mylanding.css
  • landing-panda/src/pages/blogSnippets.astro
🧰 Additional context used
🪛 LanguageTool
landing-panda/src/pages/blogs/blog1.md

[style] ~31-~31: ‘by all means’ might be wordy. Consider a shorter alternative.
Context: ...nless you’re in a regulated field. Then by all means go study my dear Lawyers and Doctors. (...

(EN_WORDINESS_PREMIUM_BY_ALL_MEANS)


[style] ~33-~33: ‘in this day and age’ might be wordy. Consider a shorter alternative.
Context: ...us. Learning is very very close to free in this day and age. If you’re reading this, you already pa...

(EN_WORDINESS_PREMIUM_IN_THIS_DAY_AND_AGE)

landing-panda/src/pages/blogs/blog2.md

[grammar] ~24-~24: Ensure spelling is correct
Context: ...ng from day one. --- ## First Contact fter I got the job, my manager told me I wou...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[uncategorized] ~97-~97: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...og1) Next: Solve, Build, Get Paid: Open Source Bounties at Akong’a

(EN_COMPOUND_ADJECTIVE_INTERNAL)

landing-panda/src/pages/blogs/blog3.md

[uncategorized] ~6-~6: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...og3.webp --- # Solve, Build, Get Paid: Open Source Bounties at Akong’a ![Akonga Banner](/i...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[style] ~40-~40: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...ssions are of the quality we expect. We are able to look at them knowing they meet our stan...

(BE_ABLE_TO)


[style] ~43-~43: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...e not for people looking for shortcuts. They’re for developers who want a serious ch...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

landing-panda/src/pages/blogs/blog4.md

[style] ~24-~24: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...g disgruntled.* This is something very very important to me and that’s at the core of the Ako...

(EN_WEAK_ADJECTIVE)


[style] ~24-~24: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...DNA. I am human. I am not always right. I will not tolerate a team of “yes” men. ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~24-~24: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... will not tolerate a team of “yes” men. I need to trust that my team will questio...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[uncategorized] ~35-~35: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...Honesty"? We think of our company as a high performance sports team. When we’re on the field we...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[uncategorized] ~67-~67: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ... Previous: Solve, Build, Get Paid: Open Source Bounties at Akong’a

(EN_COMPOUND_ADJECTIVE_INTERNAL)

🪛 markdownlint-cli2 (0.17.2)
landing-panda/src/pages/blogs/blog1.md

12-12: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🔇 Additional comments (4)
landing-panda/src/pages/blogs/blog3.md (2)

98-99: Placeholders successfully removed – nice cleanup

Previous / Next navigation now points to concrete routes instead of empty (#) links. This resolves MD042 lint violations from earlier iterations and improves UX.


93-95: Unvetted third-party script inclusion – validate necessity & CSP

Embedding https://akongalabs.kit.com/4e5ba9cc5c/index.js injects remote JS into every reader’s browser. This:

  1. Adds a network hit that can hurt performance.
  2. Introduces a security/CSP maintenance burden.
  3. Can break static-site guarantees if the script ever goes down.

Verify the script is required (e.g. for forms/analytics) and whitelist the domain in your Astro deployment’s CSP. If it is only used here, consider lazy-loading or replacing with a static embed instead.

landing-panda/src/pages/blogs/blog4.md (1)

60-63: Verify external embed script reliability & privacy

The embedded script at https://akongalabs.kit.com/4e5ba9cc5c/index.js is loaded from a third-party domain. Make sure:

  1. The domain actually hosts the script (avoid runtime 404).
  2. Loading it complies with your privacy / cookie policy.
  3. A <noscript> fallback or graceful degradation path exists.

If unsure, test the script URL in staging before merging.

landing-panda/src/pages/blogs/blog1.md (1)

41-44: Inline <script> embeds third-party code – verify CSP & privacy requirements
Loading external scripts inside Markdown bypasses Astro’s component sandboxing and may clash with a future Content-Security-Policy. Confirm this script is approved, add defer if synchronous execution isn’t required, and document the data it captures.

Comment thread landing-panda/src/pages/blogs/blog1.md Outdated
Comment on lines +11 to +13
> *“You’re going to be somewhere in your career in ten years, why not in your absolute ideal role, doing the kind of work you’d find most rewarding and having the kind of impact that you’re capable of? If you don’t believe that this is possible, you will surely fail. If you do believe it’s possible, look honestly — you might still fail! But you’ll at least see better outcomes by believing consistency will work than by believing it won’t.”*

> **Oz Nova, April 2023**

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

Remove blank line inside blockquote to satisfy MD028 and render correctly
The empty Line 12 terminates the blockquote prematurely; the attribution on Line 13 is rendered outside the quote.

> *“You’re going to be somewhere in your career in ten years, why not in your absolute ideal role, doing the kind of work you’d find most rewarding and having the kind of impact that you’re capable of? If you don’t believe that this is possible, you will surely fail. If you do believe it’s possible, look honestly — you might still fail! But you’ll at least see better outcomes by believing consistency will work than by believing it won’t.”*
-
-> **Oz Nova, April 2023**
+> **Oz Nova, April 2023**

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

12-12: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 Prompt for AI Agents
In landing-panda/src/pages/blogs/blog1.md around lines 11 to 13, remove the
blank line between the quoted text and the attribution inside the blockquote.
This will prevent the blockquote from terminating early and ensure the
attribution is rendered as part of the quote, satisfying MD028.

Comment thread landing-panda/src/pages/blogs/blog2.md Outdated
Comment on lines +2 to +4
layout: ../blogLayout.astro
cover: ../../../images/blog2.webp
---

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Invalid cover path will break image resolution at build-time

cover should point to a URL that the Astro asset pipeline can resolve.
../../../images/blog2.webp walks outside src/ and misses the public/ prefix, so the image will 404 on the generated page.

-cover: ../../../images/blog2.webp
+cover: /images/blog2.webp

Verify that /public/images/blog2.webp exists (it does per this PR) and let Astro serve it from the root.


🏁 Script executed:

#!/bin/bash
# Locate blog2.webp in the repository
echo "Searching for blog2.webp..."
find . -type f -name blog2.webp

# Verify existence of public/images directory
echo "Checking for public/images directory..."
find . -type d -path "./public/images"

Length of output: 267


🏁 Script executed:

#!/bin/bash
# Locate blogLayout.astro in the repository
echo "Searching for blogLayout.astro..."
find . -type f -name "blogLayout.astro"

Length of output: 159


Fix invalid cover path in blog2.md

The frontmatter in landing-panda/src/pages/blogs/blog2.md currently points outside of src/ and misses the public/ prefix, so the image won’t be found at build time.

• File: landing-panda/src/pages/blogs/blog2.md

- cover: ../../../images/blog2.webp
+ cover: /images/blog2.webp

This change lets Astro serve the image from landing-panda/public/images/blog2.webp at /images/blog2.webp.

📝 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
layout: ../blogLayout.astro
cover: ../../../images/blog2.webp
---
layout: ../blogLayout.astro
cover: /images/blog2.webp
---
🤖 Prompt for AI Agents
In landing-panda/src/pages/blogs/blog2.md around lines 2 to 4, the cover image
path in the frontmatter is incorrect because it points outside the src/
directory and lacks the public/ prefix, causing the image not to be found at
build time. Fix this by updating the cover path to start with /images/blog2.webp
so Astro can correctly serve the image from the public/images directory.

Comment thread landing-panda/src/pages/blogs/blog4.md Outdated
@@ -0,0 +1,67 @@
---
layout: ../blogLayout.astro
cover: ../../../images/blog4.webp

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

Fix incorrect cover path – image will not be found at build time

../../../images/blog4.webp points outside Astro’s public/ directory, so the build pipeline won’t copy it and the image will 404 in production.
Replace with an absolute path under public/ (consistent with the in-post image):

-cover: ../../../images/blog4.webp
+cover: /images/blog4.webp
📝 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
cover: ../../../images/blog4.webp
cover: /images/blog4.webp
🤖 Prompt for AI Agents
In landing-panda/src/pages/blogs/blog4.md at line 3, the cover image path is
relative and points outside the public directory, causing a 404 error in
production. Change the cover path to an absolute path starting from the public
directory, matching the format used for in-post images, to ensure the image is
correctly found and included during the build.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (2)
landing-panda/public/styles/mylanding.css (2)

140-143: Selector does nothing – duplicate of prior feedback
title is not an HTML element, so .blog-post title never matches. Use .blog-post .title (note the dot).


145-151: h2 & h3 unintentionally global – duplicate of prior feedback
Only h1 is scoped under .blog-post; h2 and h3 will style every heading on the site. Add the class prefix for each selector.

🧹 Nitpick comments (1)
landing-panda/public/styles/mylanding.css (1)

91-99: Fixed width: 700px limits responsiveness

The hard-coded width defeats the responsive fluid grid on screens narrower than 700 px and wider than your media-query breakpoints. Consider using max-width: 700px with a percentage width or removing the fixed width entirely and relying on padding/margins.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a3a55ed and e5271ed.

📒 Files selected for processing (3)
  • landing-panda/public/styles/mylanding.css (1 hunks)
  • landing-panda/src/components/BlogCard.tsx (1 hunks)
  • landing-panda/src/pages/blogSnippets.astro (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • landing-panda/src/pages/blogSnippets.astro
  • landing-panda/src/components/BlogCard.tsx

Comment on lines +36 to +38
justify-content: center;
padding-left: 60px;
align-content: left;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Invalid value left for align-content – rule is ignored

align-content only accepts values such as flex-start, flex-end, center, space-between, etc. Because left is not valid, the declaration is dropped and the layout may not behave as intended.

-    align-content: left;
+    /* Align items to the start of the cross-axis */
+    align-content: flex-start;
📝 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
justify-content: center;
padding-left: 60px;
align-content: left;
justify-content: center;
padding-left: 60px;
/* Align items to the start of the cross-axis */
align-content: flex-start;
🤖 Prompt for AI Agents
In landing-panda/public/styles/mylanding.css around lines 36 to 38, the CSS
property align-content is set to an invalid value 'left', which is ignored by
browsers. Replace 'left' with a valid value such as 'flex-start' to align
content to the start of the cross axis, ensuring the layout behaves as intended.

Comment on lines +177 to +181
.insider{
font-style: var(--font-family);
font-size: 35px;
}

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

Mis-used CSS property – should be font-family, not font-style

font-style expects keywords like italic, normal, oblique. Passing a font family token makes the declaration invalid and silently ignored.

-.insider{
-    font-style: var(--font-family);
-    font-size: 35px;
-}
+.insider{
+    font-family: var(--font-family);
+    font-size: 35px;
+}

(The same defect appears again at Lines 218-220 – apply the same fix there.)

🤖 Prompt for AI Agents
In landing-panda/public/styles/mylanding.css at lines 177 to 181, the property
`font-style` is incorrectly used with a font family variable; replace
`font-style: var(--font-family);` with `font-family: var(--font-family);` to
correctly apply the font family. Also, apply this same correction to lines 218
to 220 where the same mistake occurs.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
landing-panda/src/pages/blogs/blog4.md (1)

3-3: Fix cover image path to avoid 404 in production.

Use an absolute path under /public like the in-post image.

Apply this diff:

-cover: ../../../images/blog4.webp
+cover: /images/blog4.webp
🧹 Nitpick comments (5)
landing-panda/src/pages/blogs/blog4.md (5)

7-7: Alt text + brand consistency.

Align brand spelling in alt text with body usage.

-![Akonga Banner](/images/blog4.webp)
+![Akong’a banner](/images/blog4.webp)

15-24: Tighten phrasing; remove repeated “very”; improve clarity.

Minor readability/grammar tweaks.

-Her interpretation of brutal honesty was focused on the word “brutal”. This led to a very very spirited discussion on whether one needs to be brutal to be honest. She questioned whether brutal honesty equated to being rude. She was concerned and rightfully so…
+Her interpretation of brutal honesty was focused on the word “brutal.” This led to a very spirited discussion on whether one needs to be brutal to be honest. She questioned whether brutal honesty equated to being rude. She was concerned—and rightfully so…
 
->*Charity chose using questioning to gain clarity as opposed to bowing down to her leader while being disgruntled.*
+>*Charity chose to ask questions to gain clarity rather than defer to her leader while feeling disgruntled.*
 
-This is something very very important to me and that’s at the core of the Akong’a DNA. I am human. I am not always right. I will not tolerate a team of “yes” men. I need to trust that my team will question my questionable moves. That my team will keep me accountable. That my team will have my back.
+This is extremely important to me and is at the core of the Akong’a DNA. I am human. I am not always right. I will not tolerate a team of “yes” men. I need to trust that my team will question my questionable moves, keep me accountable, and have my back.
 
-This to me, was a very teachable moment on the core of our culture here at Akong’a. Charity had done something very very positive by questioning me:
+This, to me, was a very teachable moment on the core of our culture here at Akong’a. Charity had done something very positive by questioning me:

35-41: Compound adjectives and word choices: high‑performance, sugarcoat, teammate; sentence polish.

-We think of our company as a high performance sports team. When we’re on the field we need to make critical decisions in split seconds and be able to trust each other’s judgement.
+We think of our company as a high-performance sports team. When we’re on the field, we need to make critical decisions in split seconds and be able to trust each other’s judgment.
 
-No time to sugar coat.
+No time to sugarcoat.
 
-You say it as it is and your team mate knows the critique is of their work and not of them. Which means that we are all able to pivot quickly and avoid disastrous situations.
+You say it as it is, and your teammate knows the critique is of their work and not of them. That means we can pivot quickly and avoid disastrous situations.
 
-While we are in training, it’s a chill environment where we don’t have to be as “brutal”. We spend most of our time in training mode. But when the situation calls for it, we switch quickly, execute. Then get back to rest state.
+While we are in training, it’s a chill environment where we don’t have to be as “brutal.” We spend most of our time in training mode, but when the situation calls for it, we switch quickly, execute, then return to a resting state.

48-51: Make bullet list grammar consistent (use gerunds).

 - Adjusting expectations
-- Make realistic adjustments
-- Highlight critical issues
-- Upholding working systems
+- Making realistic adjustments
+- Highlighting critical issues
+- Maintaining working systems

53-57: Polish phrasing for clarity.

-Good communication breeds by comprehension.
+Good communication thrives on comprehension.
 
-Comprehension breeds understanding.
+Comprehension breeds understanding.
 
-Understanding opens up space for healthy arguing and dialogue that moves us forward. I believe in curiosity which opens up spaces for dialogues.
+Understanding opens up space for healthy debate and dialogue that moves us forward. I believe in curiosity, which opens up space for dialogue.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e5271ed and 24924f5.

📒 Files selected for processing (3)
  • landing-panda/public/styles/mylanding.css (1 hunks)
  • landing-panda/src/pages/blogLayout.astro (1 hunks)
  • landing-panda/src/pages/blogs/blog4.md (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • landing-panda/public/styles/mylanding.css
  • landing-panda/src/pages/blogLayout.astro
🧰 Additional context used
🪛 LanguageTool
landing-panda/src/pages/blogs/blog4.md

[style] ~24-~24: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...g disgruntled.* This is something very very important to me and that’s at the core of the Ako...

(EN_WEAK_ADJECTIVE)


[style] ~24-~24: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...DNA. I am human. I am not always right. I will not tolerate a team of “yes” men. ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~24-~24: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... will not tolerate a team of “yes” men. I need to trust that my team will questio...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[uncategorized] ~66-~66: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ... Previous: Solve, Build, Get Paid: Open Source Bounties at Akong’a

(EN_COMPOUND_ADJECTIVE_INTERNAL)

🔇 Additional comments (2)
landing-panda/src/pages/blogs/blog4.md (2)

62-63: Verify newsletter embed domain and CSP allowances.

Ensure the script domain is correct and permitted by your Content Security Policy, otherwise the form won’t load in production.

Please verify in a staging build that:

  • The script successfully loads (no 404/CORS errors).
  • If you enforce a CSP, script-src includes the domain in this tag.
  • The embed renders with JS disabled (provide a noscript fallback if needed).

66-66: Prev link fix LGTM.

Placeholder “#” link replaced with a valid route. Thanks.

Comment thread landing-panda/src/pages/blogs/blog4.md Outdated
Comment on lines +1 to +4
---
layout: ../blogLayout.astro
cover: ../../../images/blog4.webp
---

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Add essential frontmatter metadata (title, author, pubDate, description) for layout/SEO.

Many blog layouts and cards consume these. Keeps metadata out of body and improves previews.

Apply this diff:

 ---
 layout: ../blogLayout.astro
+title: The Power of Honest Communication in Teams
+author: adrianmurage
+pubDate: 2025-06-28
+description: "Why direct, respectful feedback accelerates teams and how we practice it at Akong’a."
-cover: ../../../images/blog4.webp
+cover: /images/blog4.webp
 ---

Verify blogLayout.astro uses these keys (or adjust names to match).


🏁 Script executed:

#!/bin/bash
# Locate and inspect the blog layout component to confirm frontmatter keys
files=$(fd blogLayout.astro)
if [ -z "$files" ]; then
  echo "No blogLayout.astro file found"
  exit 1
fi

for f in $files; do
  echo "===== Inspecting $f ====="
  # Print the first 200 lines to see frontmatter destructuring
  sed -n '1,200p' "$f"
done

Length of output: 1488


Ensure frontmatter is consumed by your layout and update metadata

The blog4.md frontmatter should include title, author, pubDate, description, and a normalized cover path—however, blogLayout.astro currently only imports assets and does not reference any frontmatter fields. You’ll need to:

  • In landing-panda/src/pages/blogs/blog4.md, apply the diff below.
  • In landing-panda/src/pages/blogLayout.astro, add frontmatter props (e.g. export interface Props { title: string; author: string; pubDate: string; description: string; cover: string; }) and insert them into your <head> (set <title>, <meta name="description">, etc.) and render cover where appropriate.

Diff for blog4.md:

@@ landing-panda/src/pages/blogs/blog4.md
 ---
 layout: ../blogLayout.astro
+title: The Power of Honest Communication in Teams
+author: adrianmurage
+pubDate: 2025-06-28
+description: "Why direct, respectful feedback accelerates teams and how we practice it at Akong’a."
-cover: ../../../images/blog4.webp
+cover: /images/blog4.webp
 ---

Once you’ve updated the layout to destructure and render these props, the new metadata will populate your page’s <head> and previews as intended.

📝 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
---
layout: ../blogLayout.astro
cover: ../../../images/blog4.webp
---
---
layout: ../blogLayout.astro
title: The Power of Honest Communication in Teams
author: adrianmurage
pubDate: 2025-06-28
description: "Why direct, respectful feedback accelerates teams and how we practice it at Akong’a."
cover: /images/blog4.webp
---
🤖 Prompt for AI Agents
In landing-panda/src/pages/blogs/blog4.md lines 1 to 4, the frontmatter lacks
essential metadata fields like title, author, pubDate, and description, and the
cover path needs normalization. Add these fields to the frontmatter with
appropriate values and ensure the cover path is relative and correct. Then, in
landing-panda/src/pages/blogLayout.astro, define a Props interface including
these fields, destructure them from frontmatter, and use them to set the page's
<title>, <meta name="description">, and render the cover image properly in the
layout.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 11

♻️ Duplicate comments (5)
landing-panda/public/styles/mylanding.css (5)

38-38: Invalid CSS value: align-content: left is ignored

Use a valid value (or use align-items if the intent is to align items on the cross-axis).

-    align-content: left;
+    /* align items to the start of the cross-axis */
+    align-content: flex-start;
+    /* or, if you meant flex items themselves: */
+    /* align-items: flex-start; */

145-148: Selector does nothing – title is not an HTML element

Target the .title class (and center via text-align rather than flex alignment on non-flex parents).

-.blog-post title{
-    align-content: center;
-    align-self: center;
-}
+.blog-post .title{
+    text-align: center;
+}

150-156: Unscoped h2 & h3 – currently apply globally

Scope each heading explicitly to .blog-post.

-.blog-post h1,h2,h3 {
+.blog-post h1,
+.blog-post h2,
+.blog-post h3 {

182-185: Misused property – should be font-family, not font-style

This declaration is ignored by browsers; use font-family.

-.insider{
-    font-style: var(--font-family);
-    font-size: 35px;
-}
+.insider{
+    font-family: var(--font-family);
+    font-size: 35px;
+}

216-222: Repeat of misused property inside media query

Same fix as above: use font-family instead of font-style.

-    .insider{
-        /*border: 1px solid purple;*/
-        font-style: var(--font-family);
-        font-size: 40px;
-        line-height: 1.2;
-        margin: 0;
-        padding: 0;
-    }
+    .insider{
+        /*border: 1px solid purple;*/
+        font-family: var(--font-family);
+        font-size: 40px;
+        line-height: 1.2;
+        margin: 0;
+        padding: 0;
+    }
🧹 Nitpick comments (4)
landing-panda/public/styles/mylanding.css (4)

87-93: Global “all anchors white” may conflict with page theming

You later use .blog-post a { color: inherit; }. Consider scoping the global white rule to a site/container wrapper (e.g., .container a or .blog-body a) to avoid accidental overrides in future pages/components.


16-18: Global overflow-x: hidden can mask layout bugs

This hides horizontal overflow instead of fixing it. With the width fixes proposed, you should be able to remove this.

-body {
-  font-family: var(--font-family);
-  overflow-x: hidden;
-}
+body {
+  font-family: var(--font-family);
+  /* overflow-x: hidden; Avoid masking layout issues */
+}

43-52: Debug borders left in stylesheet

These borders appear to be dev-only. Consider removing or guarding under a debug class.

-    border: 1px solid deeppink;
+    /* border: 1px solid deeppink; */

Also applies to: 189-191, 199-207, 379-384


150-156: Heading hierarchy looks inverted (h2 larger than h1 on small screens)

On small phones, .blog-body h1 is 45px while .blog-body h2 is 65px. Verify intended hierarchy for readability and SEO.

Also applies to: 387-399

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 24924f5 and 065b9f0.

📒 Files selected for processing (2)
  • landing-panda/public/styles/mylanding.css (1 hunks)
  • landing-panda/src/pages/blogSnippets.astro (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • landing-panda/src/pages/blogSnippets.astro
🔇 Additional comments (1)
landing-panda/public/styles/mylanding.css (1)

1-9: Overall theme and structure look solid

Good use of CSS variables, consistent dark theme, and scoped blog styles. Once the issues above are addressed, this sheet will be in good shape for the new landing and blog pages.

Also applies to: 11-18, 20-31, 33-41, 54-63, 64-73, 74-85, 86-94, 95-105, 106-122, 123-138, 157-170, 171-181, 187-224, 225-267, 268-294, 295-322, 323-350, 351-378, 379-385, 386-408, 410-424

Comment on lines +96 to +104
/* Blogs snippets page */
.blogs_container{
/*border: 1px solid red;*/
display: flex;
flex-direction: column;
margin: auto;
width: 700px;
gap: 60px;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fixed width harms responsiveness – prefer fluid width with a max

Use a fluid container with max-width to avoid overflow on small screens.

 .blogs_container{
     /*border: 1px solid red;*/
     display: flex;
     flex-direction: column;
     margin: auto;
-    width: 700px;
+    width: 100%;
+    max-width: 700px;
     gap: 60px;
 }
📝 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
/* Blogs snippets page */
.blogs_container{
/*border: 1px solid red;*/
display: flex;
flex-direction: column;
margin: auto;
width: 700px;
gap: 60px;
}
/* Blogs snippets page */
.blogs_container{
/*border: 1px solid red;*/
display: flex;
flex-direction: column;
margin: auto;
width: 100%;
max-width: 700px;
gap: 60px;
}
🤖 Prompt for AI Agents
In landing-panda/public/styles/mylanding.css around lines 96 to 104, the
.blogs_container uses a fixed width: 700px which breaks responsiveness; change
it to a fluid layout using width: 100% with a max-width: 700px (and keep margin:
auto) so the container scales down on small screens while capping its maximum
width on large screens.

Comment on lines +137 to +138
width: 710px;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Blog body width should be fluid with a max

Prevents clipping and reliance on overflow-x: hidden.

-    width: 710px;
+    width: 100%;
+    max-width: 710px;
📝 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
width: 710px;
}
width: 100%;
max-width: 710px;
}
🤖 Prompt for AI Agents
In landing-panda/public/styles/mylanding.css around lines 137 to 138, the blog
body uses a fixed width (width: 710px) which can cause clipping and relies on
overflow-x: hidden; change this to a fluid layout by replacing the fixed width
with width: 100% and adding max-width: 710px so the content scales on small
viewports while capping at 710px on large screens; ensure any unnecessary
overflow-x: hidden is removed or reevaluated if present.

Comment on lines +139 to +144
.blog-post img {
max-width: 700px; /* or whatever width you prefer */
height: auto;
display: block;
/* margin-top: 1px; */
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Images should scale with container

Use responsive image sizing to avoid overflow.

-.blog-post img {
-  max-width: 700px;  /* or whatever width you prefer */
-  height: auto;
-  display: block;
-  /* margin-top: 1px; */
-}
+.blog-post img {
+  display: block;
+  max-width: 100%;
+  width: 100%;
+  height: auto;
+}
📝 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
.blog-post img {
max-width: 700px; /* or whatever width you prefer */
height: auto;
display: block;
/* margin-top: 1px; */
}
.blog-post img {
display: block;
max-width: 100%;
width: 100%;
height: auto;
}
🤖 Prompt for AI Agents
In landing-panda/public/styles/mylanding.css around lines 139 to 144, the
.blog-post img rule uses a fixed max-width which can still overflow on smaller
containers; change it to be responsive by setting width: 100% and max-width:
700px with height: auto (keep display: block) so images scale down with their
container while capping their maximum size.

Comment on lines +189 to +197
@media (max-width: 479px) {
.blogs_container{
border: 1px solid green;
padding: 2px 30px;
text-align: left;
/*font-size: 120%;*/
width: 430px;
line-height: 1.6;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Overflow risk on small phones (fixed 430px width)

Make it fluid; padding is fine.

-    .blogs_container{
-        border: 1px solid green;
-        padding: 2px 30px;
-        text-align: left;
-        /*font-size: 120%;*/
-        width: 430px;
-        line-height: 1.6;
-    }
+    .blogs_container{
+        /* border: 1px solid green; (debug) */
+        padding: 2px 30px;
+        text-align: left;
+        /* font-size: 120%; */
+        width: 100%;
+        max-width: 700px;
+        line-height: 1.6;
+    }
🤖 Prompt for AI Agents
In landing-panda/public/styles/mylanding.css around lines 189 to 197 the
.blogs_container rule for max-width:479px uses a fixed width: 430px which can
overflow on smaller phones; remove the fixed width and make it fluid by
replacing width: 430px with width: 100% (or max-width: 430px if you want an
upper cap) and add box-sizing: border-box so the existing padding is included in
the element width; keep the padding and text-align as-is.

Comment on lines +212 to +214
a{
text-decoration:none ;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Avoid removing link underlines globally in breakpoints

Removing underlines degrades accessibility and discoverability. If you must, ensure alternative cues (color contrast, focus styles) are present. Safer: keep underlines or scope the change narrowly.

-    a{
-        text-decoration:none ;
-    }
+    /* Consider preserving underlines for accessibility */
+    /* a { text-decoration: underline; } */

Please verify across these breakpoints that links remain clearly identifiable by sight and focus outline.

Also applies to: 247-249, 291-292, 317-319, 345-347, 373-375


To verify that alternative link cues (hover, focus, color) are defined elsewhere and aren’t being globally stripped, let’s search the stylesheet for all link-related rules:


🏁 Script executed:

#!/bin/bash
# List all `a { … }` rules
rg -n "a\s*\{" landing-panda/public/styles

# Find every use of text-decoration
rg -n "text-decoration" landing-panda/public/styles

# Check for focus styles on links
rg -n ":focus" landing-panda/public/styles

# Check for hover styles on links
rg -n ":hover" landing-panda/public/styles

Length of output: 2290


To confirm that your non-underlined links still have sufficient visual cues, let’s inspect the hover and focus rules:


🏁 Script executed:

#!/bin/bash
# Show the `a:hover` rules for context
rg -n -A5 "a:hover" landing-panda/public/styles/mylanding.css

# Show the `a:focus` rules for context
rg -n -A5 "a:focus" landing-panda/public/styles/mylanding.css

Length of output: 263


Ensure link accessibility by scoping or augmenting underline removal

Across multiple breakpoints you’re stripping link underlines (text-decoration: none;) but only changing hover/focus color to white—no additional visual cues are provided. This impairs discoverability and keyboard focus visibility. Either preserve underlines or add compensating styles (e.g. clear focus outlines, border-bottom, or distinct hover backgrounds).

Affected locations in landing-panda/public/styles/mylanding.css:

  • Lines 212–214, 247–249, 290–292, 317–319, 345–347, 373–375

Suggested diff example for each block:

-   a {
-     text-decoration: none;
-   }
+   /* Keep underline or add visual cue for focus/hover */
+   a {
+     /* text-decoration: none; */
+     text-decoration: underline;
+   }
+
+  /* Or, if you must remove underlines: */
+  a:focus {
+    outline: 2px dotted #fff;
+    outline-offset: 2px;
+  }
+  a:hover {
+    background-color: rgba(255,255,255,0.1);
+  }

Please update each breakpoint block accordingly so links remain clearly identifiable by sight and keyboard navigation.

📝 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
a{
text-decoration:none ;
}
/* Keep underline or add visual cue for focus/hover */
a {
/* text-decoration: none; */
text-decoration: underline;
}
/* Or, if you must remove underlines: */
a:focus {
outline: 2px dotted #fff;
outline-offset: 2px;
}
a:hover {
background-color: rgba(255,255,255,0.1);
}

Comment on lines +259 to +265
.insider{
font-style: var(--font-family);
font-size: 35px;
line-height: 1.2;
margin: 0;
padding: 0;
}

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

Third occurrence – font-style still used instead of font-family

This one wasn’t covered by earlier comments; fix it as well.

-    .insider{
-        font-style: var(--font-family);
-        font-size: 35px;
-        line-height: 1.2;
-        margin: 0;
-        padding: 0;
-    }
+    .insider{
+        font-family: var(--font-family);
+        font-size: 35px;
+        line-height: 1.2;
+        margin: 0;
+        padding: 0;
+    }
📝 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
.insider{
font-style: var(--font-family);
font-size: 35px;
line-height: 1.2;
margin: 0;
padding: 0;
}
.insider{
font-family: var(--font-family);
font-size: 35px;
line-height: 1.2;
margin: 0;
padding: 0;
}
🤖 Prompt for AI Agents
In landing-panda/public/styles/mylanding.css around lines 259 to 265, the
.insider rule mistakenly uses the font-style property with var(--font-family);
replace font-style with font-family so the rule reads font-family:
var(--font-family); and remove the incorrect font-style line to ensure the
custom property is applied correctly.

Comment on lines +269 to +277
@media (min-width: 770px) and (max-width: 1024px) {
.blogs_container{
/*border: 1px solid deeppink;*/
padding: 2px 70px;
text-align: left;
font-size: 100%;
width: 750px;
line-height: 1;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fixed 750px width – make fluid

Same rationale as above.

-    .blogs_container{
-        /*border: 1px solid deeppink;*/
-        padding: 2px 70px;
-        text-align: left;
-        font-size: 100%;
-        width: 750px;
-        line-height: 1;
-    }
+    .blogs_container{
+        /*border: 1px solid deeppink;*/
+        padding: 2px 70px;
+        text-align: left;
+        font-size: 100%;
+        width: 100%;
+        max-width: 750px;
+        line-height: 1;
+    }
📝 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
@media (min-width: 770px) and (max-width: 1024px) {
.blogs_container{
/*border: 1px solid deeppink;*/
padding: 2px 70px;
text-align: left;
font-size: 100%;
width: 750px;
line-height: 1;
}
@media (min-width: 770px) and (max-width: 1024px) {
.blogs_container{
/*border: 1px solid deeppink;*/
padding: 2px 70px;
text-align: left;
font-size: 100%;
width: 100%;
max-width: 750px;
line-height: 1;
}
}
🤖 Prompt for AI Agents
In landing-panda/public/styles/mylanding.css around lines 269 to 277, the
.blogs_container rule uses a fixed width: 750px which prevents fluid layouts;
replace the fixed width with a responsive rule such as width: 100% and
max-width: 750px (or remove width and use max-width only), keep the padding and
text alignment, and ensure box-sizing/layout behaves as expected so the
container becomes fluid across viewport sizes within this media query.

Comment on lines +296 to +304
@media (min-width: 1025px) and (max-width: 1439px) {
.blogs_container{
/*border: 1px solid deeppink;*/
padding: 2px 70px;
text-align: left;
font-size: 100%;
width: 750px;
line-height: 1;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fixed 750px width – make fluid

Avoid fixed widths for better responsiveness.

-    .blogs_container{
-        /*border: 1px solid deeppink;*/
-        padding: 2px 70px;
-        text-align: left;
-        font-size: 100%;
-        width: 750px;
-        line-height: 1;
-    }
+    .blogs_container{
+        /*border: 1px solid deeppink;*/
+        padding: 2px 70px;
+        text-align: left;
+        font-size: 100%;
+        width: 100%;
+        max-width: 750px;
+        line-height: 1;
+    }
🤖 Prompt for AI Agents
In landing-panda/public/styles/mylanding.css around lines 296 to 304, the
.blogs_container uses a fixed width: 750px which breaks responsiveness; change
to a fluid layout by replacing width: 750px with width: 100% and max-width:
750px, and ensure box-sizing: border-box so the 2px 70px padding is included in
the container size; this keeps the container fluid on smaller screens while
capping its maximum width on larger viewports.

Comment on lines +324 to +332
@media (min-width: 1440px) and (max-width: 1920px) {
.blogs_container{
/*border: 1px solid deeppink;*/
padding: 2px 70px;
text-align: left;
font-size: 100%;
width: 750px;
line-height: 1;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fixed 750px width – make fluid

Same change for desktop breakpoint.

-    .blogs_container{
-        /*border: 1px solid deeppink;*/
-        padding: 2px 70px;
-        text-align: left;
-        font-size: 100%;
-        width: 750px;
-        line-height: 1;
-    }
+    .blogs_container{
+        /*border: 1px solid deeppink;*/
+        padding: 2px 70px;
+        text-align: left;
+        font-size: 100%;
+        width: 100%;
+        max-width: 750px;
+        line-height: 1;
+    }
📝 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
@media (min-width: 1440px) and (max-width: 1920px) {
.blogs_container{
/*border: 1px solid deeppink;*/
padding: 2px 70px;
text-align: left;
font-size: 100%;
width: 750px;
line-height: 1;
}
@media (min-width: 1440px) and (max-width: 1920px) {
.blogs_container{
/*border: 1px solid deeppink;*/
padding: 2px 70px;
text-align: left;
font-size: 100%;
width: 100%;
max-width: 750px;
line-height: 1;
}
}
🤖 Prompt for AI Agents
In landing-panda/public/styles/mylanding.css around lines 324 to 332, the
.blogs_container uses a fixed width: 750px which prevents fluid resizing on
large desktop screens; change it to be responsive by removing the fixed width
and using a fluid rule such as width: 100% with a max-width (e.g., max-width:
750px) or an appropriate percentage so the container scales with viewport, and
keep padding/text-align/line-height as-is.

Comment on lines +352 to +360
@media (min-width: 1921px) {
.blogs_container{
/*border: 1px solid deeppink;*/
padding: 2px 70px;
text-align: left;
font-size: 100%;
width: 750px;
line-height: 1;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fixed 750px width – make fluid

Same change for very large screens.

-    .blogs_container{
-        /*border: 1px solid deeppink;*/
-        padding: 2px 70px;
-        text-align: left;
-        font-size: 100%;
-        width: 750px;
-        line-height: 1;
-    }
+    .blogs_container{
+        /*border: 1px solid deeppink;*/
+        padding: 2px 70px;
+        text-align: left;
+        font-size: 100%;
+        width: 100%;
+        max-width: 750px;
+        line-height: 1;
+    }
📝 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
@media (min-width: 1921px) {
.blogs_container{
/*border: 1px solid deeppink;*/
padding: 2px 70px;
text-align: left;
font-size: 100%;
width: 750px;
line-height: 1;
}
@media (min-width: 1921px) {
.blogs_container{
/*border: 1px solid deeppink;*/
padding: 2px 70px;
text-align: left;
font-size: 100%;
width: 100%;
max-width: 750px;
line-height: 1;
}
}
🤖 Prompt for AI Agents
In landing-panda/public/styles/mylanding.css around lines 352 to 360, the
.blogs_container rule sets a fixed width: 750px which prevents a fluid layout on
very large screens; replace the fixed width with a fluid pattern such as width:
100% plus max-width: 750px (or remove the fixed width and add a sensible
max-width) so the container scales with viewport while capping its maximum size,
and keep existing padding, text-align and line-height unchanged.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
landing-panda/src/pages/newLanding.astro (1)

3-4: Remove unused baseUrl variable.

The baseUrl variable is declared but never used in the component, creating unnecessary code.

Apply this diff to remove the unused variable:

---
import "../../public/styles/landing_page.css";
-const isDev = import.meta.env.DEV;
-const baseUrl = isDev ? "http://localhost:3001" : "";
---
🧹 Nitpick comments (1)
landing-panda/public/styles/landing_page.css (1)

37-51: Consider simplifying padding declaration.

The container and content classes implement a good flex-based layout structure. However, there's redundant padding specification.

 .container {
   display: flex;
   flex-direction: column;
   height: auto;
-  padding: 0 0px;
+  padding: 0;
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 065b9f0 and f74f774.

📒 Files selected for processing (2)
  • landing-panda/public/styles/landing_page.css (1 hunks)
  • landing-panda/src/pages/newLanding.astro (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
landing-panda/src/pages/**/*.astro

📄 CodeRabbit Inference Engine (.cursorrules)

Create landing pages as Astro files under landing-panda/src/pages/

Files:

  • landing-panda/src/pages/newLanding.astro
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: AkongaLabs/akongalabs-beta#0
File: .cursorrules:0-0
Timestamp: 2025-08-15T14:47:01.737Z
Learning: Applies to landing-panda/src/pages/**/*.astro : Create landing pages as Astro files under landing-panda/src/pages/
📚 Learning: 2025-08-15T14:47:01.737Z
Learnt from: CR
PR: AkongaLabs/akongalabs-beta#0
File: .cursorrules:0-0
Timestamp: 2025-08-15T14:47:01.737Z
Learning: Applies to landing-panda/src/pages/**/*.astro : Create landing pages as Astro files under landing-panda/src/pages/

Applied to files:

  • landing-panda/src/pages/newLanding.astro
🔇 Additional comments (11)
landing-panda/public/styles/landing_page.css (5)

1-9: Well-structured CSS foundation with clear design system.

The font imports, CSS custom properties, and color scheme establish a good foundation for a consistent dark-themed design. The variable naming is descriptive and follows conventions.


11-35: Solid CSS reset and typography foundation.

The box-sizing reset and base styles for html, body, and links are properly implemented. The link color inheritance ensures consistent theming across all states.


53-95: Well-structured navigation and content sections.

The typography hierarchy and spacing for the first_links, title, about, and last_links sections is well thought out. The use of different font families (Bricolage Grotesque for headings, Inter for body text) creates good visual hierarchy.


97-119: Effective hero image implementation with overlay text.

The image container and overlay text positioning create an engaging hero section. The full viewport coverage and object-fit properties ensure proper image display across different screen sizes.


121-224: Comprehensive responsive design with smooth scaling.

The media queries provide excellent responsive behavior across multiple breakpoints (480px, 780px, 1440px, 1920px). The typography scales appropriately, and the layout transition to two-column at 780px is well-implemented. The font sizes and spacing adjustments maintain visual hierarchy at all screen sizes.

landing-panda/src/pages/newLanding.astro (6)

7-17: Well-structured HTML document head.

The meta tags are properly configured for a modern web application, including proper charset, favicon, responsive viewport settings, and Astro generator meta tag.


19-24: Navigation links properly implemented.

The navigation structure uses semantic class names and provides clear paths to the main landing page and blog sections. The links are properly structured for the site's navigation flow.


25-35: Engaging content with good typography hierarchy.

The about section effectively communicates the company's mission with good use of semantic HTML (h2 for title) and visual emphasis through strikethrough and bold text. The messaging clearly differentiates the "stayup" concept from traditional startups.


37-41: External links properly configured.

The social media links use proper external URLs and are well-structured within the navigation footer.


42-50: Hero image implementation with effective branding.

The image container with overlay text creates a strong visual impact. The image path follows proper public asset conventions, and the alt text provides appropriate accessibility support.


1-52: Header image present — file verified

Found: landing-panda/public/images/header-background.webp (WebP, 289,728 bytes ≈ 283 KB). The page landing-panda/src/pages/newLanding.astro (lines 1–52) references /images/header-background.webp.

Optional: consider further compression, responsive srcset, or lazy-loading for better performance.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (5)
landing-panda/src/data/types.ts (2)

4-15: DRY the repeated { rendered: string } shape and clarify intent.

title, guid, content, and excerpt all share the same nested shape. Extracting a named type improves readability and reusability.

Apply this diff within the interface:

-  title: {
-    rendered: string;
-  };
-  guid: {
-    rendered: string;
-  };
-  content: {
-    rendered: string;
-  };
-  excerpt: {
-    rendered: string;
-  };
+  title: RenderedHTML;
+  guid: RenderedHTML;
+  content: RenderedHTML;
+  excerpt: RenderedHTML;

And add this type alias above the interface:

type RenderedHTML = { rendered: string };

10-15: Verify sanitization of content.rendered / excerpt.rendered before rendering (potential XSS)

Quick findings from repo scan:

  • landing-panda/src/data/types.ts — defines content.rendered and excerpt.rendered as strings (likely HTML from a WP-style API).
    content: { rendered: string; };
    excerpt: { rendered: string; };
    
  • I found NO occurrences of common raw-HTML sinks in source files (set:html, dangerouslySetInnerHTML, {@html}, v-html, unsafeHTML, innerHTML).
  • I found NO sanitizer libraries in source files (dompurify, isomorphic-dompurify, sanitize-html, rehype-sanitize). Only references appear in lockfiles.
  • server-panda/src/middleware/security.ts contains a Content Security Policy (useful but not a replacement for sanitizing input).

Recommendation (verify & act):

  • If any component injects content.rendered or excerpt.rendered as HTML, sanitize it first (e.g., DOMPurify or rehype-sanitize) or avoid injecting raw HTML.
  • If you want, I can add a small DOMPurify wrapper for both Astro and React to standardize sanitization.
landing-panda/src/styles/mylanding.css (3)

41-48: Use dynamic viewport units to avoid mobile 100vh issues.

height: 100vh can cause content to be clipped behind mobile browser UI. Prefer 100svh (or dvh) for more predictable behavior on mobile.

Apply this diff:

 .content {
-  height: 100vh;
+  min-height: 100svh;
   display: flex;
   flex-direction: column;
   justify-content: space-between;
   align-items: start;
   padding: 24px 24px 16px 24px;
 }
 
 .image_container {
   position: relative;
   width: 100vw;
-  height: 100vh;
+  min-height: 100svh;
   overflow: hidden;
 }

Also applies to: 94-99


126-136: Remove debug borders and avoid !important.

Borders on production layout (.blogs_container, .blog-title, .asnip, .para_space) and a forced line-height: 1.5 !important look like debugging artifacts and may degrade UX.

Apply this diff:

 .blogs_container{
-    border: 1px solid red;
     display: flex;
     flex-direction: column;
     margin: auto;
-    width: 700px;
+    width: min(700px, 100%);
     gap: 10px;
     /*line-height: 1.5;*/
 }
 
 .blog-title{
-    border: 1px solid yellow;
 
 }
 .asnip{
-    border: 1px solid green;
     display: flex;
     flex-direction: column;
 }
 .para_space{
-    border: 1px solid peru;
-    line-height: 1.5  !important;
+    line-height: 1.5;
 }

And for the small-phone media query:

 @media (max-width: 479px) {
     .blogs_container{
-        border: 1px solid green;
         padding: 2px 30px;
         text-align: left;
         /*font-size: 120%;*/
-        width: 430px;
+        width: 100%;
         line-height: 1.6;
     }

Also applies to: 149-161, 337-345


1-9: “Inter” is used but not imported; unify font usage.

.about references "Inter", sans-serif but only Bricolage Grotesque is imported. Either import Inter or use the same CSS variable for consistency.

Two options:

  • Import Inter:
 @import url('https://fonts.googleapis.com/css2?family=Bricolage+Grotesque&display=swap');
+@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap');
  • Or standardize on var(--font-family) in .about:
 .about {
   flex: 1;
   display: flex;
   line-height: 1.25rem;
   flex-direction: column;
   justify-content: center;
-  font-family: "Inter", sans-serif;
+  font-family: var(--font-family);
 }

Also applies to: 75-76

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f74f774 and 5dd1241.

📒 Files selected for processing (3)
  • landing-panda/src/data/types.ts (1 hunks)
  • landing-panda/src/pages/newLanding.astro (1 hunks)
  • landing-panda/src/styles/mylanding.css (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • landing-panda/src/pages/newLanding.astro
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursorrules)

Use TypeScript across the codebase

Files:

  • landing-panda/src/data/types.ts

Comment thread landing-panda/src/data/types.ts Outdated
Comment thread landing-panda/src/styles/mylanding.css Outdated
Comment on lines +1 to +9
@import url('https://fonts.googleapis.com/css2?family=Bricolage+Grotesque&display=swap');

:root {
--bg-color: #1a1f2e;
--text-color: #e2e8f0;
--font-family:'Bricolage Grotesque', sans-serif;
--blue-color:#7091ff;
--lblue-color:#538cd3;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Avoid duplicating styles between src/styles and public/styles.

The PR adds a parallel stylesheet under public/styles/mylanding.css. Duplication invites drift and maintenance bugs.

Consider centralizing the stylesheet in src/styles and removing the public copy. If both are needed, ensure a single source of truth with a build step copying assets to public.

To locate duplicates and their references:


🏁 Script executed:

#!/bin/bash
fd -a 'mylanding.css' -S
rg -n --fixed-strings 'mylanding.css'

Length of output: 606


Centralize mylanding.css — duplicates found; update imports or remove the public copy

rg shows both copies are referenced, which will cause drift and maintenance bugs.

Files to fix:

  • Imports referencing public/styles/mylanding.css
    • landing-panda/src/components/BlogCard.tsx:1
    • landing-panda/src/pages/blogSnippets.astro:2
    • landing-panda/src/pages/blogLayout.astro:2
  • Imports referencing src/styles/mylanding.css
    • landing-panda/src/pages/newLanding.astro:3 (line 2 contains a commented import for the public copy)

Recommended actions (pick one):

  • Preferred: Use src/styles/mylanding.css as the single source of truth — delete public/styles/mylanding.css and update the three files above to import "../../src/styles/mylanding.css".
  • Or: If you must serve a static file from public, keep only public/styles/mylanding.css and add a build step that copies the canonical src file into public, then make all imports consistently point to public.

Quick verification command:

  • rg -n --hidden --glob '!node_modules' 'mylanding.css'
🤖 Prompt for AI Agents
In landing-panda/src/styles/mylanding.css (lines 1-9): there are duplicate
copies of mylanding.css causing drift; pick a canonical source and make imports
consistent. Preferred: delete public/styles/mylanding.css, update imports in
landing-panda/src/components/BlogCard.tsx,
landing-panda/src/pages/blogSnippets.astro, and
landing-panda/src/pages/blogLayout.astro to point to the src file (e.g. correct
relative path like ../../src/styles/mylanding.css), and remove the commented
public import in landing-panda/src/pages/newLanding.astro; Alternative: if
public must be served, keep only public/styles/mylanding.css, add a build step
to copy src/styles/mylanding.css -> public/styles/mylanding.css, and change all
imports to point to public/styles/mylanding.css so a single file is referenced
by every consumer.

Comment on lines +164 to +178
.blog-body {
/*border: 1px solid pink;*/
display: flex;
flex-direction: column;
margin: 10px auto;
font-size: 120%;
/* align-items: center; */
justify-content: center;
background-color:var(--bg-color);
font-family: var(--font-family);
line-height: 1.6;
padding: 9px;
color:var(--text-color);
width: 710px;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Make blog layout responsive: avoid fixed widths.

Fixed pixel widths will overflow on small screens (e.g., width: 710px and image max-width: 700px). Prefer fluid widths that cap at a max width.

Apply this diff:

 .blog-body {
-    margin: 10px auto;
-    font-size: 120%;
+    margin: 10px auto;
+    font-size: 120%;
     /* align-items: center; */
     justify-content: center;
     background-color:var(--bg-color);
     font-family: var(--font-family);
     line-height: 1.6;
     padding: 9px;
     color:var(--text-color);
-    width: 710px;
+    width: min(710px, 100%);
 }
 .blog-post img {
-  max-width: 700px;  /* or whatever width you prefer */
+  max-width: 100%;
   height: auto;
   display: block;
   /* margin-top: 1px; */
 }

Also applies to: 179-184

🤖 Prompt for AI Agents
In landing-panda/src/styles/mylanding.css around lines 164-178 (also apply same
change to 179-184), the .blog-body uses a fixed width (width: 710px) which
causes overflow on small screens; change this to use a fluid layout by replacing
the fixed width with width: 100% and constrain it using max-width: 710px (keep
margin: 10px auto to center), ensure box-sizing is set so padding is included in
the width, and add responsive image rules (e.g., img inside .blog-body should
have max-width: 100% and height: auto) so images scale on small viewports.

Comment thread landing-panda/src/styles/mylanding.css Outdated
Comment on lines +185 to +188
.blog-post title{
align-content: center;
align-self: center;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Likely typo: .blog-post title should be .blog-post .title.

title is not a valid descendant element you'd expect here (and the HTML <title> tag is not rendered in body). This selector currently does nothing.

Apply this diff:

-.blog-post title{
+.blog-post .title{
📝 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
.blog-post title{
align-content: center;
align-self: center;
}
.blog-post .title{
align-content: center;
align-self: center;
}
🤖 Prompt for AI Agents
In landing-panda/src/styles/mylanding.css around lines 185 to 188 the selector
`.blog-post title` is a typo and matches nothing; change it to the descendant
class selector `.blog-post .title` so the rules apply to elements with class
"title" inside `.blog-post`. Update the selector and keep the existing
properties (or if centering text is intended, consider using `text-align:
center` on `.blog-post .title`) to ensure the styles take effect.

Comment thread landing-panda/src/styles/mylanding.css Outdated
Comment on lines +190 to +196
.blog-post h1,h2,h3 {
margin-top: 1.5rem;
margin-bottom: 0.75rem;
font-size: 40px;
font-weight: 200;
/* margin-left: 3rem; */
}

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

Selector scoping bug: this styles all h2/h3 globally.

.blog-post h1,h2,h3 only scopes h1 to .blog-post; h2 and h3 are global. This will unintentionally restyle headings site-wide.

Apply this diff:

-.blog-post h1,h2,h3 {
+.blog-post h1,
+.blog-post h2,
+.blog-post h3 {
📝 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
.blog-post h1,h2,h3 {
margin-top: 1.5rem;
margin-bottom: 0.75rem;
font-size: 40px;
font-weight: 200;
/* margin-left: 3rem; */
}
.blog-post h1,
.blog-post h2,
.blog-post h3 {
margin-top: 1.5rem;
margin-bottom: 0.75rem;
font-size: 40px;
font-weight: 200;
/* margin-left: 3rem; */
}
🤖 Prompt for AI Agents
In landing-panda/src/styles/mylanding.css around lines 190 to 196, the selector
".blog-post h1,h2,h3" only scopes h1 to .blog-post and leaves h2 and h3 global;
update the selector so each heading is properly scoped (for example replace with
".blog-post h1, .blog-post h2, .blog-post h3") so the styles apply only to
headings inside .blog-post while leaving global h2/h3 untouched.

Comment thread landing-panda/src/styles/mylanding.css Outdated
Comment on lines +223 to +225
font-style: var(--font-family);
font-size: 35px;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Invalid property: font-style used with a font family.

font-style accepts values like normal|italic|oblique. Here you likely intended font-family. The current rule is ignored by the browser, so the intended font isn’t applied.

Apply this diff in all three places:

-.insider{
-    font-style: var(--font-family);
+.insider{
+    font-family: var(--font-family);

Also applies to: 362-369, 406-412

🤖 Prompt for AI Agents
In landing-panda/src/styles/mylanding.css around lines 223-225 (and also at
362-369 and 406-412), the rule mistakenly uses "font-style: var(--font-family);"
which is invalid for font-family values; replace font-style with font-family so
the variable is applied correctly (e.g., change to "font-family:
var(--font-family);") in each of the three locations and ensure no other
font-style values rely on the font-family variable.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (7)
landing-panda/src/pages/[slug].astro (4)

30-31: Add alt text and lazy-loading to the featured image

Improves a11y and performance (CLS/LCP).

-            <img src={post.jetpack_featured_media_url}/>
+            <img
+              src={post.jetpack_featured_media_url}
+              alt={titleText}
+              loading="lazy"
+              decoding="async"
+            />

If available, consider using the embedded media alt text:

// Replace the fallback:
const featuredAlt =
  post._embedded?.["wp:featuredmedia"]?.[0]?.alt_text || titleText;

…and then use alt={featuredAlt}.


17-20: Add lang attribute and use the sanitized title in <title>

Minor SEO/a11y improvement and consistency.

-<html>
+<html lang="en">
   <head>
-    <title>{post.title.rendered}</title>
+    <title>{titleText}</title>
   </head>

24-27: Use semantic

for primary links

Improves accessibility without changing visuals.

-            <div class="first_links_snips">
-                <a href="/newLanding">Akong'a Labs</a>
-                <a href="/blogSnippets">Blogs</a>
-            </div>
+            <nav class="first_links_snips" aria-label="Primary">
+                <a href="/newLanding">Akong'a Labs</a>
+                <a href="/blogSnippets">Blogs</a>
+            </nav>

31-34: Provide a fallback for missing author and format the date safely

The author field might be absent depending on WP configuration.

-              <span class="author">{post._embedded?.author?.[0]?.name}</span>
+              <span class="author">{post._embedded?.author?.[0]?.name ?? "Akong'a Labs"}</span>
landing-panda/src/pages/blogSnippets.astro (3)

5-6: Add failure handling for the posts fetch

Prevents a hard crash at build/runtime on transient API issues; you can also show an empty state when posts.length === 0.

The diff in the previous comment already shows a minimal res.ok guard. Optionally, wrap in try/catch and log a warning:

-const res = await fetch("https://akongalabs.com/wp-json/wp/v2/posts?per_page=10");
-let posts: BlogPost[] = [];
-if (res.ok) {
-  posts = (await res.json()) as BlogPost[];
-} else {
-  console.warn("Failed to fetch posts:", res.status, res.statusText);
-}
+let posts: BlogPost[] = [];
+try {
+  const res = await fetch("https://akongalabs.com/wp-json/wp/v2/posts?per_page=10");
+  if (res.ok) posts = (await res.json()) as BlogPost[];
+  else console.warn("Failed to fetch posts:", res.status, res.statusText);
+} catch (err) {
+  console.warn("Error fetching posts:", err);
+}

Then render an empty-state message if posts.length === 0.


18-21: Wrap header links in a semantic

Minor a11y improvement.

-      <div class="first_links">
-        <a href="/newLanding">Akong'a Labs</a>
-        <a href="/blogSnippets">Blogs</a>
-      </div>
+      <nav class="first_links" aria-label="Primary">
+        <a href="/newLanding">Akong'a Labs</a>
+        <a href="/blogSnippets">Blogs</a>
+      </nav>

47-48: Make the “X” link accessible

The single-letter link text is ambiguous for screen readers.

-        <p><a href="https://x.com/adrianmurage">X</a></p>
+        <p><a href="https://x.com/adrianmurage" aria-label="Akong'a Labs on X (Twitter)">X</a></p>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5dd1241 and 6b35f55.

📒 Files selected for processing (4)
  • landing-panda/src/data/types.ts (1 hunks)
  • landing-panda/src/pages/[slug].astro (1 hunks)
  • landing-panda/src/pages/blogSnippets.astro (1 hunks)
  • landing-panda/src/styles/mylanding.css (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • landing-panda/src/data/types.ts
  • landing-panda/src/styles/mylanding.css
🧰 Additional context used
📓 Path-based instructions (1)
landing-panda/src/pages/**/*.astro

📄 CodeRabbit Inference Engine (.cursorrules)

Create landing pages as Astro files under landing-panda/src/pages/

Files:

  • landing-panda/src/pages/[slug].astro
  • landing-panda/src/pages/blogSnippets.astro
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: AkongaLabs/akongalabs-beta#0
File: .cursorrules:0-0
Timestamp: 2025-08-15T14:47:01.737Z
Learning: Applies to landing-panda/src/pages/**/*.astro : Create landing pages as Astro files under landing-panda/src/pages/
📚 Learning: 2025-08-15T14:47:01.737Z
Learnt from: CR
PR: AkongaLabs/akongalabs-beta#0
File: .cursorrules:0-0
Timestamp: 2025-08-15T14:47:01.737Z
Learning: Applies to landing-panda/src/pages/**/*.astro : Create landing pages as Astro files under landing-panda/src/pages/

Applied to files:

  • landing-panda/src/pages/[slug].astro
  • landing-panda/src/pages/blogSnippets.astro
🔇 Additional comments (2)
landing-panda/src/pages/[slug].astro (1)

1-1: File placement LGTM and aligns with our pages convention

This page is correctly placed under landing-panda/src/pages and follows the guideline for Astro pages.

landing-panda/src/pages/blogSnippets.astro (1)

1-1: File placement LGTM and aligns with our pages convention

This page is correctly placed under landing-panda/src/pages and follows the guideline for Astro landing/blog pages.

Comment on lines +1 to +3
---
import type { BlogPost } from "../data/types";
import "../../src/styles/mylanding.css";

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

Sanitize injected HTML and avoid set:html where plain text will do (XSS hardening)

Title, content and other WP-rendered fields can contain HTML. Injecting them directly with set:html is a high-impact XSS risk if upstream sanitization ever regresses or plugins add unsafe markup.

  • Use sanitize-html on the post body.
  • For titles, prefer plain text rendering instead of set:html.

Apply these diffs:

 ---
-import type { BlogPost } from "../data/types";
-import "../../src/styles/mylanding.css";
+import type { BlogPost } from "../data/types";
+import sanitizeHtml from "sanitize-html";
+import "../styles/mylanding.css";
 export async function getStaticPaths() {
-const { post } = Astro.props as { post: BlogPost };
+const { post } = Astro.props as { post: BlogPost };
+// Avoid injecting raw HTML where not necessary; sanitize rich content.
+const titleText = (post.title?.rendered ?? "").replace(/<[^>]*>/g, "");
+const contentHTML = sanitizeHtml(post.content?.rendered ?? "", {
+  allowedTags: sanitizeHtml.defaults.allowedTags.concat([
+    "img",
+    "figure",
+    "figcaption",
+    "h1",
+    "h2",
+    "h3",
+    "span",
+    "iframe",
+  ]),
+  allowedAttributes: {
+    a: ["href", "name", "target", "rel"],
+    img: ["src", "alt", "loading", "decoding", "width", "height", "srcset", "sizes"],
+    iframe: ["src", "width", "height", "allow", "allowfullscreen", "frameborder"],
+    "*": ["class", "id", "style"],
+  },
+  allowedSchemes: ["http", "https", "mailto"],
+});
-            <h1 set:html={post.title.rendered}></h1>
+            <h1>{titleText}</h1>
-            <div set:html={post.content.rendered}></div>
+            <div set:html={contentHTML}></div>

Also applies to: 14-15, 29-29, 42-42

Comment on lines +4 to +13
export async function getStaticPaths() {
// _embed query param expands related objects like authors
const res = await fetch("https://akongalabs.com/wp-json/wp/v2/posts?_embed");
const posts: BlogPost[] = await res.json();

return posts.map((post) => ({
params: { slug: post.slug },
props: { post },
}));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Handle pagination and failures in getStaticPaths() to avoid silently missing posts or build breaks

WordPress REST defaults to 10 posts per page. As written, older posts won’t get static paths, and any transient network/API error will throw at build time without context.

Apply this diff to fetch all pages and add basic error handling:

 export async function getStaticPaths() {
-  // _embed query param expands related objects like authors
-  const res = await fetch("https://akongalabs.com/wp-json/wp/v2/posts?_embed");
-  const posts: BlogPost[] = await res.json();
-
-  return posts.map((post) => ({
-    params: { slug: post.slug },
-    props: { post },
-  }));
+  // Fetch all posts (WP caps per_page at 100)
+  const posts: BlogPost[] = [];
+  let page = 1;
+  const perPage = 100;
+  while (true) {
+    const res = await fetch(
+      `https://akongalabs.com/wp-json/wp/v2/posts?_embed&per_page=${perPage}&page=${page}`
+    );
+    if (!res.ok) {
+      throw new Error(`Failed to fetch posts (page ${page}): ${res.status} ${res.statusText}`);
+    }
+    const batch: BlogPost[] = await res.json();
+    posts.push(...batch);
+    if (batch.length < perPage) break;
+    page++;
+  }
+  return posts.map((post) => ({
+    params: { slug: post.slug },
+    props: { post },
+  }));
 }
📝 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
export async function getStaticPaths() {
// _embed query param expands related objects like authors
const res = await fetch("https://akongalabs.com/wp-json/wp/v2/posts?_embed");
const posts: BlogPost[] = await res.json();
return posts.map((post) => ({
params: { slug: post.slug },
props: { post },
}));
}
export async function getStaticPaths() {
// Fetch all posts (WP caps per_page at 100)
const posts: BlogPost[] = [];
let page = 1;
const perPage = 100;
while (true) {
const res = await fetch(
`https://akongalabs.com/wp-json/wp/v2/posts?_embed&per_page=${perPage}&page=${page}`
);
if (!res.ok) {
throw new Error(`Failed to fetch posts (page ${page}): ${res.status} ${res.statusText}`);
}
const batch: BlogPost[] = await res.json();
posts.push(...batch);
if (batch.length < perPage) break;
page++;
}
return posts.map((post) => ({
params: { slug: post.slug },
props: { post },
}));
}
🤖 Prompt for AI Agents
In landing-panda/src/pages/[slug].astro around lines 4–13, getStaticPaths
currently fetches only the first 10 posts and has no error handling; update it
to paginate through the WP REST API (e.g., loop pages with a per_page param
until an empty page or by reading X-WP-TotalPages header) and accumulate all
posts, and wrap fetches in try/catch to surface contextual errors (log or
rethrow a descriptive error including URL, page number and response status).
Ensure you return an empty paths array or fail early with a clear message if
requests repeatedly fail, and preserve the existing return shape params: { slug:
post.slug }, props: { post }.

Comment on lines +1 to +7
---
import "../../src/styles/mylanding.css";
import type { BlogPost } from "../data/types";

const res = await fetch("https://akongalabs.com/wp-json/wp/v2/posts");
const posts: BlogPost[] = await res.json();
---

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

Sanitize HTML, avoid unnecessary set:html, and improve heading semantics

  • Excerpt is injected as HTML; sanitize it.
  • Date doesn’t need set:html; render as text.
  • Prefer H2 for each post card to keep a single H1 per page.

Apply these diffs:

 ---
-import "../../src/styles/mylanding.css";
+import "../styles/mylanding.css";
 import type { BlogPost } from "../data/types";
+import sanitizeHtml from "sanitize-html";
 
-const res = await fetch("https://akongalabs.com/wp-json/wp/v2/posts");
-const posts: BlogPost[] = await res.json();
+const res = await fetch("https://akongalabs.com/wp-json/wp/v2/posts?per_page=10");
+let posts: BlogPost[] = [];
+if (res.ok) {
+  posts = (await res.json()) as BlogPost[];
+} else {
+  console.warn("Failed to fetch posts:", res.status, res.statusText);
+}
 ---
-              <p class="bluecolor" set:html={formattedDate}></p>
-              <h1 class="blog-title" set:html={post.title.rendered}></h1>
-              <div class="para_space" set:html={cleanedExcerpt}></div>
+              <p class="bluecolor">{formattedDate}</p>
+              <h2 class="blog-title">
+                {post.title.rendered.replace(/<[^>]*>/g, "")}
+              </h2>
+              <div
+                class="para_space"
+                set:html={sanitizeHtml(cleanedExcerpt, {
+                  allowedTags: ["p", "em", "strong", "a", "code", "pre", "ul", "ol", "li", "span", "br"],
+                  allowedAttributes: { a: ["href", "rel", "target"] },
+                  allowedSchemes: ["http", "https", "mailto"],
+                })}
+              ></div>

Also applies to: 34-38

🤖 Prompt for AI Agents
In landing-panda/src/pages/blogSnippets.astro lines 1-7 (and also apply same
fixes to lines 34-38), the excerpt is being injected unsanitized with set:html,
the post date is rendered using set:html unnecessarily, and headings use H1 per
post; fix by sanitizing the excerpt HTML before rendering (use a sanitizer
library or a safe-html utility and pass the sanitized HTML to set:html), stop
using set:html for the date and render it as plain text (e.g., interpolate the
formatted date string), and change per-post headings from H1 to H2 to preserve a
single page H1; ensure imports include the sanitizer and update markup
accordingly.

- Fixed the Kit.com form import issue (scripts not loading properly).
- Resolved porting issue where visiting the general port(3001) wouldn’t display the react page.
- Fixed stylesheet import issue by adjusting CSP rules to allow external styles.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
server-panda/src/middleware/security.ts (1)

40-41: Add formAction directive to allow ConvertKit form submissions

No static <iframe> or <form> targets were found in the frontend code, and your scriptSrc already permits the ConvertKit embed script (https://akongalabs.kit.com/4e5ba9cc5c/index.js) . However, the ConvertKit JavaScript embed (loaded from that script) dynamically injects a <form> whose action posts to https://app.convertkit.com/forms/{Form ID}/subscriptions (help.convertkit.com). Without a formAction directive, these submissions will be blocked in production.

Please update your CSP configuration in server-panda/src/middleware/security.ts:

• File: server-panda/src/middleware/security.ts
Add under your existing directives:

   frameSrc: ["'none'"],
   workerSrc: ["'self'"],
+    formAction: ["'self'", "https://app.convertkit.com"],

This ensures inline forms post successfully to ConvertKit without broadening your CSP beyond the specific host.

♻️ Duplicate comments (5)
landing-panda/src/styles/mylanding.css (5)

157-172: Make blog layout fluid; avoid fixed widths that overflow on small screens

Fixed widths (710px for .blog-body and 700px for images) cause horizontal overflow on narrow devices. Use a fluid width with a max cap; let images scale to container.

Apply this diff:

 .blog-body {
     display: flex;
     flex-direction: column;
     margin: 10px auto;
     font-size: 110%;
     justify-content: center;
     background-color:var(--bg-color);
     font-family: var(--font-family);
     line-height: 1.6;
     padding: 9px;
     color:var(--text-color);
-    width: 710px;
+    width: min(710px, 100%);
 }
 .blog-post img {
-  max-width: 700px;
+  max-width: 100%;
   height: auto;
   display: block;
 }

1-9: Centralize mylanding.css to a single source of truth; remove duplicate in public/

There are duplicate copies under src/styles and public/styles, and multiple import sites reference each. This will drift and cause hard-to-debug inconsistencies.

Preferred:

  • Keep landing-panda/src/styles/mylanding.css as canonical.
  • Delete public/styles/mylanding.css and update all imports to reference the src file.

Alternative:

  • If a static public file is required, keep only public/styles/mylanding.css and add a build step to copy from src (so one file is edited).

I can generate a quick PR patch to update imports once you confirm the preferred direction.


175-178: Fix selector typo: .blog-post title matches nothing

This selector doesn’t select elements inside .blog-post. It should likely target an element with class "title".

Apply this diff:

-.blog-post title{
+.blog-post .title{
     align-content: center;
     align-self: center;
 }

180-185: Scope heading selectors correctly to avoid global H2/H3 restyling

“.blog-post h1,h2,h3” only scopes h1; h2 and h3 are global. This will unintentionally restyle site-wide headings.

Apply this diff:

-.blog-post h1,h2,h3 {
+.blog-post h1,
+.blog-post h2,
+.blog-post h3 {
   margin-top: 1rem;
   margin-bottom: 0.75rem;
   font-size: 40px;
   font-weight: 200;
 }

217-220: Invalid CSS: font-style used with a font-family variable; replace with font-family

This rule is ignored by browsers; intended font won’t apply.

Apply this diff in all three locations:

 .insider{
-    font-style: var(--font-family);
+    font-family: var(--font-family);
     font-size: 35px;
 }
@@
 .insider{
-    font-style: var(--font-family);
+    font-family: var(--font-family);
     font-size: 40px;
     line-height: 1.2;
     margin: 0;
     padding: 0;
 }
@@
 .insider{
-    font-style: var(--font-family);
+    font-family: var(--font-family);
     font-size: 35px;
     line-height: 1.2;
     margin: 0;
     padding: 0;
 }

Also applies to: 360-366, 394-399

🧹 Nitpick comments (4)
server-panda/src/middleware/security.ts (2)

35-35: Tighten fontSrc to the exact Google Fonts host

Currently fontSrc allows any HTTPS origin, which is broader than needed. Google Fonts files are served from fonts.gstatic.com; restricting to that host reduces exposure.

Apply this diff:

-          fontSrc: ["'self'", "https:", "data:"],
+          fontSrc: ["'self'", "https://fonts.gstatic.com", "data:"],

30-34: Clean up comments and make allowlist stable

Minor clarity:

  • The comment on Line 30 mixes “inline styles” and the Google Fonts CSS endpoint; clarify intent.
  • Path-level allowlisting (…/4e5ba9cc5c/index.js) is brittle; vendor rotations will break CSP. Prefer the origin host and pair with SRI or a nonce.

Proposed tidy-up:

-          // styleSrc: ["'self'", "'unsafe-inline'"], // Allow inline styles for React/Astro https://fonts.googleapis.com
-          styleSrc: ["'self'", "'unsafe-inline'","https://fonts.googleapis.com"], // Allow inline styles for React/Astro
+          // Allow Google Fonts stylesheet; inline styles are controlled via nonce
+          styleSrc: ["'self'", "https://fonts.googleapis.com"],
-          // scriptSrc: ["'self'", "'unsafe-inline'"], // Allow inline scripts for React
-          scriptSrc: ["'self'", "'unsafe-inline'", "https://akongalabs.kit.com/4e5ba9cc5c/index.js"], // Allow inline scripts for React
+          // Allow external kit script host; inline scripts are controlled via nonce
+          scriptSrc: ["'self'", "https://akongalabs.kit.com"],
landing-panda/src/styles/mylanding.css (2)

124-130: Unify .blogs_container sizing; remove repeated fixed widths across breakpoints

Multiple media queries set .blogs_container widths (430px, 720px, 750px), which are brittle and can overflow. Centralize to a single fluid rule and drop per-breakpoint widths.

Apply this diff to set a single fluid width and remove per-breakpoint width overrides:

 .blogs_container{
     display: flex;
     flex-direction: column;
     margin: auto;
-    width: 700px;
+    width: min(750px, 100%);
     gap: 10px;
 }
@@
 @media (max-width: 479px) {
     .blogs_container{
         padding: 2px 30px;
         text-align: left;
-        width: 430px;
         line-height: 1.6;
     }
@@
 @media (min-width: 480px) and (max-width: 769px) {
     .blogs_container{
         padding: 2px 30px;
         text-align: left;
         font-size: 100%;
-        width: 720px;
         line-height: 1;
     }
@@
 @media (min-width: 770px) and (max-width: 1024px) {
     .blogs_container{
         padding: 2px 70px;
         text-align: left;
         font-size: 100%;
-        width: 750px;
         line-height: 1;
     }
@@
 @media (min-width: 1025px) and (max-width: 1439px) {
     .blogs_container{
         padding: 2px 70px;
         text-align: left;
         font-size: 100%;
-        width: 750px;
         line-height: 1;
     }
@@
 @media (min-width: 1440px) and (max-width: 1920px) {
     .blogs_container{
         padding: 2px 70px;
         text-align: left;
         font-size: 100%;
-        width: 750px;
         line-height: 1;
     }
@@
 @media (min-width: 1921px) {
     .blogs_container{
         padding: 2px 70px;
         text-align: left;
         font-size: 100%;
-        width: 750px;
         line-height: 1;
     }

Also applies to: 336-343, 371-377, 404-410, 430-436, 456-463, 484-490


344-351: Remove debug border on .first_links_snips (mobile)

The 1px white border looks like a leftover debug aid and clashes with the dark theme.

Apply this diff:

-    .first_links_snips{
-        border: 1px solid white;
+    .first_links_snips{
         display: flex;
         flex-direction: column;
         font-size: 25px;
         margin-top: 15px;
         text-decoration: underline;
         line-height: 1;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 565bf1e and 7b74943.

📒 Files selected for processing (3)
  • landing-panda/src/pages/blogSnippets.astro (1 hunks)
  • landing-panda/src/styles/mylanding.css (1 hunks)
  • server-panda/src/middleware/security.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • landing-panda/src/pages/blogSnippets.astro
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Use TypeScript across the codebase

Files:

  • server-panda/src/middleware/security.ts

Comment on lines +30 to 34
// styleSrc: ["'self'", "'unsafe-inline'"], // Allow inline styles for React/Astro https://fonts.googleapis.com
styleSrc: ["'self'", "'unsafe-inline'","https://fonts.googleapis.com"], // Allow inline styles for React/Astro
// scriptSrc: ["'self'", "'unsafe-inline'"], // Allow inline scripts for React
scriptSrc: ["'self'", "'unsafe-inline'", "https://akongalabs.kit.com/4e5ba9cc5c/index.js"], // Allow inline scripts for React
imgSrc: ["'self'", "data:", "https:"], // Allow images from self, data URLs, and HTTPS

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Harden CSP: replace 'unsafe-inline' with nonces/hashes; keep external origins minimal

Allowing 'unsafe-inline' for scripts/styles negates most CSP XSS protection. Prefer nonces (or SHA-256 hashes) and restrict external origins to host-level (not paths) only if necessary.

  • Move CSP to a per-request middleware and inject a nonce.
  • Remove 'unsafe-inline' from script/style sources.
  • Keep the external script origin as tight as possible, and consider SRI if the vendor supports it.

Apply this focused diff to drop 'unsafe-inline' (pair with the snippet below to add a nonce):

-          // styleSrc: ["'self'", "'unsafe-inline'"], // Allow inline styles for React/Astro https://fonts.googleapis.com
-          styleSrc: ["'self'", "'unsafe-inline'","https://fonts.googleapis.com"], // Allow inline styles for React/Astro
-          // scriptSrc: ["'self'", "'unsafe-inline'"], // Allow inline scripts for React
-          scriptSrc: ["'self'", "'unsafe-inline'", "https://akongalabs.kit.com/4e5ba9cc5c/index.js"], // Allow inline scripts for React
+          // styleSrc: ["'self'","'nonce-<INJECTED>'","https://fonts.googleapis.com"],
+          styleSrc: ["'self'", "https://fonts.googleapis.com"],
+          // scriptSrc: ["'self'","'nonce-<INJECTED>'","https://akongalabs.kit.com"],
+          scriptSrc: ["'self'", "https://akongalabs.kit.com"],

Then inject a CSP nonce per request and apply CSP dynamically:

// Place above the Helmet call(s)
import crypto from "crypto";

// Generate nonce per request
app.use((req, res, next) => {
  res.locals.cspNonce = crypto.randomBytes(16).toString("base64");
  next();
});

// Split Helmet so CSP can use the per-request nonce
app.use(helmet({
  // ...keep other helmet options...
  // IMPORTANT: temporarily remove contentSecurityPolicy here
}));

app.use((req, res, next) =>
  helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"],
      styleSrc: ["'self'", `'nonce-${res.locals.cspNonce}'`, "https://fonts.googleapis.com"],
      scriptSrc: ["'self'", `'nonce-${res.locals.cspNonce}'`, "https://akongalabs.kit.com"],
      imgSrc: ["'self'", "data:", "https:"],
      fontSrc: ["'self'", "https://fonts.gstatic.com", "data:"],
      connectSrc: ["'self'"],
      objectSrc: ["'none'"],
      // ...keep remaining directives...
      upgradeInsecureRequests: [],
    },
  })(req, res, next)
);

Note: If inline scripts/styles are truly required, add the matching nonce to the tags, e.g. <script nonce={res.locals.cspNonce}>…</script>. If the vendor rotates script paths, stay on the host allowlist and use SRI where possible.

🤖 Prompt for AI Agents
In server-panda/src/middleware/security.ts around lines 30-34 the CSP currently
uses 'unsafe-inline' for script/style and includes full script URL paths; remove
"'unsafe-inline'" from styleSrc and scriptSrc, replace the external script
origin with just the host (e.g., "https://akongalabs.kit.com"), and implement a
per-request nonce: generate a base64 nonce (e.g., crypto.randomBytes(16)) and
store it on res.locals, split Helmet so contentSecurityPolicy is applied
per-request using that nonce in scriptSrc/styleSrc (e.g.,
'nonce-${res.locals.cspNonce}'), update any inline <script>/<style> tags to
include the nonce, and consider adding fontSrc/connectSrc directives and SRI for
vendor scripts if supported.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (4)
landing-panda/src/pages/[slug].astro (4)

2-3: Add sanitize-html import and fix CSS import path

  • Bring in sanitize-html to harden against XSS when rendering WP HTML.
  • The CSS import path is incorrect; from pages/[slug].astro to styles is ../styles/mylanding.css (not ../../src/styles/...).

Apply:

 import type { BlogPost } from "../data/types";
-import "../../src/styles/mylanding.css";
+import sanitizeHtml from "sanitize-html";
+import "../styles/mylanding.css";

5-18: Paginate and add error handling in getStaticPaths (fetches only first page today)

Current code fetches a single page (WP default 10 posts) and lacks failure context. Paginating avoids silently missing older posts; basic checks prevent opaque build errors.

Apply:

 export async function getStaticPaths() {
-  // _embed query param expands related objects like authors
-  const res = await fetch("https://akongalabs.com/wp-json/wp/v2/posts?_embed");
-  const posts: BlogPost[] = await res.json();
-
-  return posts.map((post, index) => ({
-    params: { slug: post.slug },
-    props: {
-      post,
-      prevPost: posts[index + 1] || null,
-      nextPost: posts[index - 1] || null,
-    },
-  }));
+  const posts: BlogPost[] = [];
+  let page = 1;
+  const perPage = 100; // WP caps at 100
+  while (true) {
+    const url = `https://akongalabs.com/wp-json/wp/v2/posts?_embed&orderby=date&order=desc&per_page=${perPage}&page=${page}`;
+    const res = await fetch(url);
+    if (!res.ok) {
+      throw new Error(`Failed to fetch posts (page ${page}): ${res.status} ${res.statusText}`);
+    }
+    const batch: BlogPost[] = await res.json();
+    posts.push(...batch);
+    if (batch.length < perPage) break;
+    page++;
+  }
+  if (posts.length === 0) {
+    return [];
+  }
+  return posts.map((post, index) => ({
+    params: { slug: post.slug },
+    props: {
+      post,
+      // With order=desc, "previous" is the next older post in the list.
+      prevPost: posts[index + 1] || null,
+      nextPost: posts[index - 1] || null,
+    },
+  }));
 }

20-25: Precompute safe title text and sanitized HTML before rendering

Avoid injecting raw HTML. Strip tags for the title; sanitize the content with a conservative allowlist.

Apply:

 const { post, prevPost, nextPost } = Astro.props as {
   post: BlogPost;
   prevPost: BlogPost | null;
   nextPost: BlogPost | null;
 };
 ---
+// Avoid injecting raw HTML where not necessary; sanitize rich content.
+const titleText = (post.title?.rendered ?? "").replace(/<[^>]*>/g, "");
+const contentHTML = sanitizeHtml(post.content?.rendered ?? "", {
+  allowedTags: sanitizeHtml.defaults.allowedTags.concat([
+    "img",
+    "figure",
+    "figcaption",
+    "h1",
+    "h2",
+    "h3",
+    "span",
+    "iframe",
+  ]),
+  allowedAttributes: {
+    a: ["href", "name", "target", "rel"],
+    img: ["src", "alt", "loading", "decoding", "width", "height", "srcset", "sizes"],
+    iframe: ["src", "width", "height", "allow", "allowfullscreen", "frameborder"],
+    "*": ["class", "id", "style"],
+  },
+  allowedSchemes: ["http", "https", "mailto"],
+});

Note: add sanitize-html to deps: npm i sanitize-html (or pnpm add sanitize-html). I can open a quick PR if helpful.


55-55: Sanitize post body before injecting HTML

Injecting post.content.rendered directly is a high-impact XSS risk. Use the sanitized content.

-          <div set:html={post.content.rendered} />
+          <div set:html={contentHTML} />
🧹 Nitpick comments (5)
landing-panda/src/pages/[slug].astro (5)

4-4: Remove unused or invalid import: preview

preview is not used here and is not a typical Astro export for pages. Drop it to avoid dead code or build warnings.

-import { preview } from "astro";

If you intended a preview-only behavior, point me to it and I can help wire it safely behind dev guards.


27-27: Declare document language

Add lang for accessibility and SEO.

-<html>
+<html lang="en">

29-31: Add responsive viewport meta

Without it, mobile layout may render poorly.

   <head>
     <title>{post.title.rendered}</title>
     <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
   </head>

46-51: Stabilize date rendering across environments

Use date_gmt when available and pin the timeZone to avoid build-machine drift.

-                new Date(post.date).toLocaleDateString("en-US", {
+                new Date(post.date_gmt ?? post.date).toLocaleDateString("en-US", {
                   year: "numeric",
                   month: "long",
                   day: "numeric",
+                  timeZone: "UTC",
                 })

27-90: Route design: consider scoping blog to /blog/[slug] to avoid future collisions

A top-level dynamic route ([slug].astro) can shadow future top-level pages. Static routes win today for known pages, but scoping blog posts under /blog/ reduces risk and improves URL clarity.

If you want, I can propose the minimal move: rename this file to pages/blog/[slug].astro and update internal links (e.g., to /blog/{slug}).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7b74943 and 447ed49.

📒 Files selected for processing (2)
  • landing-panda/src/pages/[slug].astro (1 hunks)
  • landing-panda/src/styles/mylanding.css (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • landing-panda/src/styles/mylanding.css
🧰 Additional context used
📓 Path-based instructions (1)
landing-panda/src/pages/**/*.astro

📄 CodeRabbit inference engine (.cursorrules)

Create landing pages as Astro files under landing-panda/src/pages/

Files:

  • landing-panda/src/pages/[slug].astro
🧠 Learnings (1)
📚 Learning: 2025-08-15T14:47:01.751Z
Learnt from: CR
PR: AkongaLabs/akongalabs-beta#0
File: .cursorrules:0-0
Timestamp: 2025-08-15T14:47:01.751Z
Learning: Applies to landing-panda/src/pages/**/*.astro : Create landing pages as Astro files under landing-panda/src/pages/

Applied to files:

  • landing-panda/src/pages/[slug].astro
🔇 Additional comments (3)
landing-panda/src/pages/[slug].astro (3)

1-1: Location and file type align with guidelines

File is correctly added under landing-panda/src/pages/ as an Astro page, per the coding guideline.


57-61: External script: verify CSP allowlist and consider perf guardrails

Confirm CSP includes akongalabs.kit.com. If this is non-critical, consider deferring load until after main content or behind an interaction.

Would you like me to check/update the CSP and suggest a safer loading strategy (e.g., data- attributes plus a small consent/interaction gate)?


65-76: Harden prev/next navigation and improve accessibility

  • Sanitize post titles in the nav links to avoid unescaped HTML and potential XSS
  • Add a descriptive aria-label on the <nav> container
  • Explicitly mark links with rel="prev" and rel="next" for proper semantic relationships
  • Note: the WordPress REST API’s /wp/v2/posts endpoint returns posts in descending date order by default (orderby=date, order=desc), so here
    • prevPost = posts[index + 1] → older posts
    • nextPost = posts[index - 1] → newer posts
      Confirm these align with your intended “Previous”/“Next” labels (developer.wordpress.org).

Suggest applying this diff:

-            <nav class="blog-navigation">
+            <nav class="blog-navigation" aria-label="Post navigation">
               <div class="nav-links">
-                {prevPost && (
-                  <a href={`/${prevPost.slug}`}>
-                    Previous: <span set:html={prevPost.title.rendered} />
+                {prevPost && (
+                  <a href={`/${prevPost.slug}`} rel="prev">
+                    Previous: <span>{(prevPost.title?.rendered ?? "").replace(/<[^>]*>/g, "")}</span>
                   </a>
                 )}
 
-                {nextPost && (
-                  <a href={`/${nextPost.slug}`}>
-                    Next: <span set:html={nextPost.title.rendered} />
+                {nextPost && (
+                  <a href={`/${nextPost.slug}`} rel="next">
+                    Next: <span>{(nextPost.title?.rendered ?? "").replace(/<[^>]*>/g, "")}</span>
                   </a>
                 )}

Comment on lines +40 to +43
<h1 set:html={post.title.rendered} />
<img src={post.jetpack_featured_media_url} />
<p class="author-date">
<span class="author">{post._embedded?.author?.[0]?.name}</span>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Render a safe title and harden featured image (a11y + perf)

  • Avoid set:html for the title; use plain text.
  • Add alt text and lazy/async hints; render image only if URL exists.
-          <h1 set:html={post.title.rendered} />
-          <img src={post.jetpack_featured_media_url} />
+          <h1>{titleText}</h1>
+          {
+            post.jetpack_featured_media_url && (
+              <img
+                src={post.jetpack_featured_media_url}
+                alt={titleText}
+                loading="lazy"
+                decoding="async"
+              />
+            )
+          }

Consider adding width/height to reduce CLS if dimensions are known.

📝 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
<h1 set:html={post.title.rendered} />
<img src={post.jetpack_featured_media_url} />
<p class="author-date">
<span class="author">{post._embedded?.author?.[0]?.name}</span>
<h1>{titleText}</h1>
{post.jetpack_featured_media_url && (
<img
src={post.jetpack_featured_media_url}
alt={titleText}
loading="lazy"
decoding="async"
/>
)}
<p class="author-date">
<span class="author">{post._embedded?.author?.[0]?.name}</span>
🤖 Prompt for AI Agents
In landing-panda/src/pages/[slug].astro around lines 40-43, replace the unsafe
set:html title with a plain-text title binding (so the title is escaped and not
injected as HTML); render the featured image only when
post.jetpack_featured_media_url exists; add an alt attribute (preferably from
post._embedded?.author? or post.jetpack_featured_media_caption, falling back to
post.title.rendered or an empty string), and add loading="lazy" and
decoding="async" attributes for a11y and perf; if image width/height metadata is
available (e.g. post.jetpack_featured_media_width/height or similar), include
those attributes to reduce CLS.

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.

2 participants