Skip to content

Add TinyPaws three-entry landing pages#1

Open
simplebytes-agent wants to merge 3 commits into
nutrified:mainfrom
simplebytes-agent:feature/three-entry-landing-pages
Open

Add TinyPaws three-entry landing pages#1
simplebytes-agent wants to merge 3 commits into
nutrified:mainfrom
simplebytes-agent:feature/three-entry-landing-pages

Conversation

@simplebytes-agent

@simplebytes-agent simplebytes-agent commented Jun 9, 2026

Copy link
Copy Markdown

Summary

  • Reposition the main TinyPaws page around the private hub for care, memories, and trusted people
  • Add dedicated TinyPaws Care and TinyPaws Share entry pages with Cloudflare redirects for /care and /share
  • Add care/share waitlist preference capture and persist updates opt-in in the waitlist worker
  • Update analytics script host and fix the nav paw asset path

Verification

  • Served locally with python3 -m http.server and checked index.html, care.html, and share.html return 200
  • Parsed index.html, care.html, and share.html with Python HTMLParser
  • Checked internal links across all three pages
  • Ran node --check on script.js and functions/api/join-waitlist.js
  • Ran git diff --check
  • Ran a review agent and fixed its findings around waitlist submission, missing preference capture, ignored opt-in, care page copy, and missing paw asset path

Notes

Direct push to nutrified/tinypaws.com was denied for the local simplebytes-agent token, so this PR is opened from a fork branch.

Summary by CodeRabbit

  • New Features
    • Added new Care and Memories/Share landing pages with updated privacy-first messaging and simplified FAQ.
    • Updated calls-to-action to “Start free” and improved footer email capture for signup.
    • Added routing so /care and /share correctly open their respective pages.
  • Documentation
    • Refreshed README launch timeline and clarified the three main entry points.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds Care and Share landing pages, refreshes the homepage to a private-hub layout, updates routing and crawl access, and rewires the shared signup flow so footer email capture works across the new pages.

Changes

Private Hub Launch with Care and Share Landing Pages

Layer / File(s) Summary
Infrastructure and route configuration
_redirects, styles.css, README.md, robots.txt
Redirects map /care and /share to their HTML pages, the nav icon asset path changes, the README describes the new entry points and 2026 beta timing, and crawler access is opened at the root.
Homepage refresh
index.html
The homepage metadata, sections, pricing, FAQ, CTA, and footer are rewritten for the private-hub positioning and updated signup entry points.
Care landing page implementation
care.html
The Care page is rebuilt with updated metadata, navigation, hero, feature sections, FAQ, CTA, and footer email capture.
Share landing page implementation
share.html
The Share page is added with updated metadata, navigation, hero, privacy and trial sections, FAQ, CTA, and footer email capture.
Signup link and API handling
script.js, functions/api/join-waitlist.js
Client-side door links and mobile navigation are handled in script.js, footer email signup posts to the waitlist API, and the API accepts extra fields, normalizes subscriber data, updates CORS, and returns a new success message.

Estimated code review effort: 4 (Complex) | ~45 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding TinyPaws landing pages centered on three entry points.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

…kens/type, privacy-first positioning (no false EU-hosting claim), 'Start free' CTAs wired to app.tinypaws.com/start?door= attribution, honest no-fabricated-testimonials placeholder; waitlist handler kept as email-capture fallback. Not pushed — review before deploy.

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

Caution

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

⚠️ Outside diff range comments (1)
functions/api/join-waitlist.js (1)

76-95: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Preserve existing KV fields on re-submission

Email-only submissions still overwrite the whole record for an address, so a later footer signup can clear previously stored name/petName/petType/interest/updates. Merge with the existing KV value and only replace fields that are actually present.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@functions/api/join-waitlist.js` around lines 76 - 95, The join-waitlist
handler is overwriting the full KV record on repeated submissions, which can
erase previously stored subscriber fields. Update join-waitlist.js in the
join-waitlist function to read the existing value from env[KV_NAMESPACE_BINDING]
before writing, merge it with the new subscriberData, and only replace fields
that are actually present so email-only signups preserve prior name, petName,
petType, interest, and updates values.
🧹 Nitpick comments (1)
index.html (1)

236-291: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider marking plan names as headings for accessibility.

<span class="plan-name"> (Free/Plus/Premium) are the primary identifiers for each pricing card but aren't exposed as headings, so screen-reader users navigating by heading can't jump directly between plans.

♻️ Proposed fix
-                        <span class="plan-name">Free</span>
+                        <h3 class="plan-name">Free</h3>

(repeat for Plus and Premium plan cards)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@index.html` around lines 236 - 291, Mark the plan labels in the pricing cards
as real headings so screen-reader users can navigate between plans more easily;
update the Free, Plus, and Premium identifiers currently rendered via
`span.plan-name` in the pricing section to use heading semantics while keeping
their visual styling intact. Make the change consistently across all three plan
cards in the pricing markup so the cards have accessible structure without
changing the surrounding layout.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@care.html`:
- Around line 42-49: The mobile menu duplicate link for the current page is
missing the same active-page indicator used in the desktop nav. Update the Care
link inside the mobile-menu block in care.html so it matches the existing
desktop Care navigation by including aria-current="page" on the care.html
anchor, keeping the mobile and desktop navigation semantics consistent.

In `@index.html`:
- Around line 353-392: The footer email form in the `email-form` block currently
defaults to a GET navigation when JavaScript is unavailable, which can expose
the submitted email in the URL. Update the `form` markup to use an explicit
POST-based fallback or otherwise prevent a GET submission from the
`email-form`/`email-input` flow. Keep the fix localized to the footer form in
`index.html` so the no-script path is safe without relying on `script.js`.

In `@script.js`:
- Around line 46-50: The footer waitlist submission is missing the updates
opt-in flag, so subscribers are always saved as not opted in. Update the payload
in the join-waitlist request within the footer signup flow to include the
updates value alongside email, source, and page, and make sure the footer’s
opt-in handler passes the correct truthy updates state into that request so the
API’s updates field is persisted correctly.

In `@share.html`:
- Around line 42-49: The mobile menu in share.html is missing the current-page
accessibility state that the desktop nav already has. Update the Memories link
inside the mobile-menu navigation duplicate so it uses aria-current="page"
consistently with the corresponding desktop navigation item, and keep the rest
of the mobile nav links unchanged.

---

Outside diff comments:
In `@functions/api/join-waitlist.js`:
- Around line 76-95: The join-waitlist handler is overwriting the full KV record
on repeated submissions, which can erase previously stored subscriber fields.
Update join-waitlist.js in the join-waitlist function to read the existing value
from env[KV_NAMESPACE_BINDING] before writing, merge it with the new
subscriberData, and only replace fields that are actually present so email-only
signups preserve prior name, petName, petType, interest, and updates values.

---

Nitpick comments:
In `@index.html`:
- Around line 236-291: Mark the plan labels in the pricing cards as real
headings so screen-reader users can navigate between plans more easily; update
the Free, Plus, and Premium identifiers currently rendered via `span.plan-name`
in the pricing section to use heading semantics while keeping their visual
styling intact. Make the change consistently across all three plan cards in the
pricing markup so the cards have accessible structure without changing the
surrounding layout.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1506024d-e960-4a19-8a1b-5b31ffc4dceb

📥 Commits

Reviewing files that changed from the base of the PR and between 9c88187 and 8fff54e.

📒 Files selected for processing (7)
  • care.html
  • functions/api/join-waitlist.js
  • index.html
  • robots.txt
  • script.js
  • share.html
  • styles.css
✅ Files skipped from review due to trivial changes (1)
  • robots.txt

Comment thread care.html
Comment on lines +42 to +49
<div class="mobile-menu" id="mobile-menu">
<ul>
<li><a href="care.html">Care pages</a></li>
<li><a href="share.html">Memories</a></li>
<li><a href="index.html#privacy">Privacy</a></li>
<li><a href="index.html#pricing">Pricing</a></li>
</ul>
</div>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Mobile nav duplicate is missing aria-current="page".

Desktop nav marks the active page (<a href="care.html" aria-current="page">, line 31), but the mobile menu's duplicate link (line 44) omits it, so assistive tech using the mobile menu won't get the same "current page" signal.

♿ Proposed fix
                 <ul>
-                    <li><a href="care.html">Care pages</a></li>
+                    <li><a href="care.html" aria-current="page">Care pages</a></li>
                     <li><a href="share.html">Memories</a></li>
📝 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
<div class="mobile-menu" id="mobile-menu">
<ul>
<li><a href="care.html">Care pages</a></li>
<li><a href="share.html">Memories</a></li>
<li><a href="index.html#privacy">Privacy</a></li>
<li><a href="index.html#pricing">Pricing</a></li>
</ul>
</div>
<div class="mobile-menu" id="mobile-menu">
<ul>
<li><a href="care.html" aria-current="page">Care pages</a></li>
<li><a href="share.html">Memories</a></li>
<li><a href="index.html#privacy">Privacy</a></li>
<li><a href="index.html#pricing">Pricing</a></li>
</ul>
</div>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@care.html` around lines 42 - 49, The mobile menu duplicate link for the
current page is missing the same active-page indicator used in the desktop nav.
Update the Care link inside the mobile-menu block in care.html so it matches the
existing desktop Care navigation by including aria-current="page" on the
care.html anchor, keeping the mobile and desktop navigation semantics
consistent.

Comment thread index.html
Comment on lines 353 to 392
<footer class="footer">
<div class="container">
<div class="footer-top">
<div class="footer-logo">
<img src="images/logo.svg" alt="TinyPaws Logo">
<p class="mt-4 text-gray-600">Preserving precious pet memories that last a lifetime.</p>
<div class="social-links mt-6">
<a href="https://www.facebook.com/tinypawsapp" aria-label="Facebook">
<i data-feather="facebook"></i>
</a>
<a href="https://www.instagram.com/tinypaws.app" aria-label="Instagram">
<i data-feather="instagram"></i>
</a>
<a href="https://www.twitter.com/tinypawsapp" aria-label="Twitter">
<i data-feather="twitter"></i>
</a>
</div>
</div>

<div class="footer-links">
<h3>Company</h3>
<ul>
<li><a href="coming-soon">About Us</a></li>
<li><a href="coming-soon">Blog</a></li>
<li><a href="mailto:press@tinypaws.com">Press</a></li>
</ul>
<div class="footer-grid">
<div>
<h2>Not ready yet?</h2>
<p>Leave your email and we'll write when there's something genuinely worth telling you — big features, launch news. No drip campaigns.</p>
<form class="email-form" id="email-form" novalidate>
<label for="email-input">Email address</label>
<input type="email" id="email-input" name="email" autocomplete="email" placeholder="you@example.com" required>
<button type="submit" class="btn btn-primary on-dark-btn">Keep me posted</button>
</form>
<p class="form-status" id="form-status" role="status" aria-live="polite"></p>
</div>

<div class="footer-links">
<h3>Resources</h3>
<ul>
<li><a href="https://www.nutrified.com?ref=tinypaws-footer" target="_blank" rel="dofollow">Pet Nutrition</a></li>
<li><a href="https://www.ampawssadors.com?ref=tinypaws-footer" target="_blank" rel="dofollow">Ampawssadors</a></li>
<li><a href="mailto:web@tinypaws.com">Contact Support</a></li>
</ul>
</div>

<div class="footer-links">
<h3>Legal</h3>
<ul>
<li><a href="coming-soon">Privacy Policy</a></li>
<li><a href="coming-soon">Terms of Service</a></li>
<li><a href="coming-soon">Cookie Policy</a></li>
</ul>
<div>
<h3>Product</h3>
<ul>
<li><a href="care.html">Care pages</a></li>
<li><a href="share.html">Memories</a></li>
<li><a href="index.html#pricing">Pricing</a></li>
<li><a href="index.html#privacy">Privacy promises</a></li>
</ul>
</div>
<div>
<h3>Company</h3>
<ul>
<li><a href="https://www.nutrified.com?ref=tinypaws">Nutrified</a></li>
<li><a href="https://ampawssadors.com?ref=tinypaws">Ampawssadors</a></li>
<li><a href="mailto:support@tinypaws.com">support@tinypaws.com</a></li>
</ul>
</div>
</div>


</div>

<div class="footer-bottom">
<p class="copyright">© 2025 TinyPaws. All rights reserved.</p>
<div class="nutrified-partnership">
<p>Brought to you by <a href="https://www.nutrified.com?ref=tinypaws-footer" target="_blank" rel="dofollow">Nutrified</a></p>
</div>
<span>© 2026 Nutrified Media. TinyPaws is a private place — it stays that way.</span>
<span>Made for the people your pet loves.</span>
</div>
</div>
</footer>

<!-- Waitlist Popup Overlay -->
<div id="waitlist-overlay" class="overlay">
<div class="popup">
<div class="popup-header">
<h3>Join Our Pack</h3>
<button id="close-popup" class="close-popup">&times;</button>
</div>
<div class="popup-content">
<p>Be among the first to preserve your pet's legacy when TinyPaws launches.</p>
<form id="waitlist-form" class="popup-form">
<div class="form-group">
<label for="popup-email">Email Address*</label>
<input type="email" id="popup-email" name="email" required>
</div>

<div class="form-group">
<label for="popup-name">Your Name*</label>
<input type="text" id="popup-name" name="name" required>
</div>

<div class="form-group">
<label for="popup-pet-name">Pet's Name*</label>
<input type="text" id="popup-pet-name" name="pet-name" required>
</div>

<div class="form-group">
<label for="popup-pet-type">Pet Type*</label>
<select id="popup-pet-type" name="pet-type" required>
<option value="">Select pet type</option>
<option value="dog">Dog</option>
<option value="cat">Cat</option>
<option value="rabbit">Rabbit</option>
<option value="other">Other</option>
</select>
</div>

<div class="form-group checkbox">
<input type="checkbox" id="popup-updates" name="updates" checked>
<label for="popup-updates">I'd like to receive updates about TinyPaws and pet wellness tips</label>
</div>

<div id="form-error" class="error-message"></div>
<div id="form-success" class="success-message"></div>

<button type="submit" class="btn btn-primary btn-large plausible-event-name=join_waitlist_popup_form">JOIN THE WAITLIST</button>
</form>

<div class="waitlist-perks">
<h4>Waitlist Perks:</h4>
<ul>
<li>Priority access when we launch</li>
<li>3 months of Premium features free</li>
<li>Exclusive founding member badge</li>
<li>Input on future features through our VIP feedback community</li>
</ul>
</div>
</div>
</div>
</div>
<script src="script.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
feather.replace();
});
</script>
</body>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the relevant files and inspect the form + handler.
git ls-files | rg '(^|/)(index\.html|script\.js)$'

printf '\n--- index.html (form area) ---\n'
rg -n -C 4 '<form class="email-form"|id="email-form"|form-status|novalidate' index.html

printf '\n--- script.js (email form handling) ---\n'
rg -n -C 6 'email-form|form-status|preventDefault|submit|DOMContentLoaded' script.js

Repository: nutrified/tinypaws.com

Length of output: 3769


Add a POST fallback for the footer email form (index.html:359-364) The form still falls back to a GET navigation to the current page when script.js doesn’t run, so the email can end up in the URL/history/logs. Give it an explicit POST action or block submission at the markup level.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@index.html` around lines 353 - 392, The footer email form in the `email-form`
block currently defaults to a GET navigation when JavaScript is unavailable,
which can expose the submitted email in the URL. Update the `form` markup to use
an explicit POST-based fallback or otherwise prevent a GET submission from the
`email-form`/`email-input` flow. Keep the fix localized to the footer form in
`index.html` so the no-script path is safe without relying on `script.js`.

Comment thread script.js
Comment on lines +46 to +50
fetch("/api/join-waitlist", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email: email, source: "footer_updates", page: location.pathname })
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Footer signup never records the updates opt-in.

The footer form is an updates opt-in (source: "footer_updates", plausible("email_updates_signup")), but the payload omits updates. The API stores updates: Boolean(updates), so every footer subscriber is persisted with updates: false, contradicting the stated goal of persisting opt-in.

🛠️ Proposed fix
-        body: JSON.stringify({ email: email, source: "footer_updates", page: location.pathname })
+        body: JSON.stringify({ email: email, updates: true, source: "footer_updates", page: location.pathname })
📝 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
fetch("/api/join-waitlist", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email: email, source: "footer_updates", page: location.pathname })
})
fetch("/api/join-waitlist", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email: email, updates: true, source: "footer_updates", page: location.pathname })
})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@script.js` around lines 46 - 50, The footer waitlist submission is missing
the updates opt-in flag, so subscribers are always saved as not opted in. Update
the payload in the join-waitlist request within the footer signup flow to
include the updates value alongside email, source, and page, and make sure the
footer’s opt-in handler passes the correct truthy updates state into that
request so the API’s updates field is persisted correctly.

Comment thread share.html
Comment on lines +42 to +49
<div class="mobile-menu" id="mobile-menu">
<ul>
<li><a href="care.html">Care pages</a></li>
<li><a href="share.html">Memories</a></li>
<li><a href="index.html#privacy">Privacy</a></li>
<li><a href="index.html#pricing">Pricing</a></li>
</ul>
</div>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Mobile nav duplicate is missing aria-current="page".

Same gap as care.html: desktop nav marks the current page (line 32), but the mobile menu duplicate (line 45) doesn't.

♿ Proposed fix
                 <ul>
                     <li><a href="care.html">Care pages</a></li>
-                    <li><a href="share.html">Memories</a></li>
+                    <li><a href="share.html" aria-current="page">Memories</a></li>
📝 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
<div class="mobile-menu" id="mobile-menu">
<ul>
<li><a href="care.html">Care pages</a></li>
<li><a href="share.html">Memories</a></li>
<li><a href="index.html#privacy">Privacy</a></li>
<li><a href="index.html#pricing">Pricing</a></li>
</ul>
</div>
<div class="mobile-menu" id="mobile-menu">
<ul>
<li><a href="care.html">Care pages</a></li>
<li><a href="share.html" aria-current="page">Memories</a></li>
<li><a href="index.html#privacy">Privacy</a></li>
<li><a href="index.html#pricing">Pricing</a></li>
</ul>
</div>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@share.html` around lines 42 - 49, The mobile menu in share.html is missing
the current-page accessibility state that the desktop nav already has. Update
the Memories link inside the mobile-menu navigation duplicate so it uses
aria-current="page" consistently with the corresponding desktop navigation item,
and keep the rest of the mobile nav links unchanged.

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