Add a top-level "WRNexus" navigation item linking to https://wrnexus.com/
that opens in a new tab. Implemented via the data-driven navLinks array
with an `external` flag; desktop and mobile renderers apply
target="_blank" and rel="noopener noreferrer" and skip prefetch/active-state
for external links.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Generate crisp icon set from WorkRoot SVG: favicon.ico (16/32/48),
favicon-32x32.png, apple-touch-icon.png (180), logo.png (512),
and PWA icon-192.png / icon-512.png
- Add favicon.ico link with recommended <head> tag order in BaseLayout
- Reference icon-192/icon-512 in manifest.json for PWA installs
- JSON-LD Organization logo now resolves to the real 512x512 mark
- Header/Footer already render the new mark via /favicon.svg; dark-mode
wordmark contrast (BUG-5) preserved and verified
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add WorkRoot Icon as public/favicon.svg, regenerate logo.png (512x512)
and apple-touch-icon.png (180x180) from the brand vector; add
favicon-32x32.png raster
- Register 32x32 PNG favicon link in BaseLayout <head> alongside the
SVG and apple-touch-icon
- Replace placeholder "W" logo boxes with the WorkRoot mark in the
header, mobile menu, and footer (preserving "WorkRoot" text spans
required by the dark-mode contrast tests and the home link wrapper)
JSON-LD/SEO logo (/logo.png) and PWA manifest icons now resolve to the
real brand assets. Build passes; BUG-5 dark-mode and navigation tests
green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Addresses contact-page audit points 22–27:
- Confirmed no '200+ companies' credibility claim; canonical stat set retained
- Service dropdown now matches real services, led by ERP/Enterprise + Government IT;
removed Cloud Services and AI & ML, added UI/UX Design
- Backend allowlist + labels updated to accept 'ui-ux' and reflect real service names
- H1 paired with value prop: free 1-page proposal in 24 hours
- '< 24h response' promise badge moved above the form
- Clarified contradictory hours to 'We reply within 24 business hours, Mon–Fri'
- Reduced message textarea height (rows 5→4) and max length (5000→2000)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Apply portfolio CRO audit points 17-21:
- Add a one-line outcome headline above each project card description
(grid + featured cards), styled with the primary accent per the
design system (e.g. "Cut crematorium slot booking from hours to
minutes across 10+ facilities.").
- Remove the "AI & ML" category filter chip — no project genuinely
fits it (Pophealth is health/mobile) — and correct the ItemList
structured-data description to drop the inaccurate AI/ML claim.
- Stats bar already surfaces the canonical proof set (11 Districts
Deployed, 50,000+ Records Managed) shared with the homepage/services
via ProofNumbers; the weak "4 Specializations" stat is gone.
- "View Case Study" CTAs open the inline case-study modal with full
problem -> solution -> outcome (Challenge / Solution / Key Results),
verified working via headless browser.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Replace generic H1 with outcome-led headline ("Custom software for
enterprises and governments — shipped in weeks, not quarters.")
- Rewrite each service description to lead with the outcome and end
with the tech stack
- Reorder service cards so Government IT and ERP/Enterprise lead,
before Web/Mobile
- Add "What's included" label above each pricing tier's bullet list
(Most Popular badge on Professional retained)
- Unify CTAs to one primary ("Get my free proposal") + one secondary
("See our work" → /portfolio)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Rename WhatsApp label from "WhatsApp" (8 chars) to "Chat" (4) so every
visible label fits the ≤7-char action-verb policy and never triggers
the new text-overflow:ellipsis safety net even at 320px (iPhone SE).
- Bump inline SVG icons to 24×24 (was 22), set min-height 64px and
min-width 44px per Apple HIG / WCAG 2.5.5 tap-target requirements.
- Add white-space:nowrap + text-overflow:ellipsis as defensive safety
net, plus a 320-359px breakpoint that nudges label to 11px / padding
to 4px-horizontal so glyph-width drift can't cause overflow.
- Rewrite aria-labels to be action-led + descriptive even when visible
text is terse: "Call us", "Chat with us on WhatsApp", "Get a free
quote" (WCAG 2.5.3 name-in-name).
- Bump BaseLayout bottom-spacer from 64px → 72px so the new
PricingTimelineBand and GuaranteeBand always have an 8px visual
buffer above the fixed sticky bar (no overlap).
Verified: build green, all 6 tests in tests/sticky-cta.spec.ts pass
against the restarted frontend service. Probed live at 320 / 375 /
414 px — every button is 64px tall, ≥103px wide, icons 24×24, labels
never truncate. Footer fully clears the bar at scroll-bottom.
- TrustStrip.astro: single-row, grayscale-on-default / colour-on-hover
client logo strip under the hero. 6 logos via <img> with explicit
width/height + loading=lazy (CLS-safe), wraps to 3+3 on mobile.
Includes sr-only "Trusted by" heading and dark-mode invert filter
vetted against THEME_ACCESSIBILITY_AUDIT.md. Replaces the older
ClientLogos placement on the homepage.
- GuaranteeBand.astro: 3-up risk-reversal band wedged between
PricingTimelineBand and InlineLeadForm. Three claims (30-day
satisfaction guarantee, no long-term contracts, fixed-price quotes)
with icon + headline + supporting body. Stacks vertically on mobile.
- public/images/logos/: 6 placeholder SVG wordmarks (plnr, rentec,
iit-patna, moc-soft, gov-bihar, pscl). Replace at same path with
real client-supplied artwork when handed off.
- index.astro: wires the two new components, repoints the hero
scroll indicator to #trust-strip, preserves legacy #client-logos
anchor for any external deep-links.
The team-member count read as a small-shop signal next to the new ProofNumbers band. Swap it for a stronger value-prop (team seniority) on both
index.astro and about.astro. Rename the about-page "Years of Experience" stat
to "Years in Business" to disambiguate from the new team-experience metric, and
refresh the about-page SEO description accordingly. The new label doesn't
collide with any ProofNumbers entry (Projects Delivered / Client Rating /
Districts Deployed / Avg Page Load), so the two bands stay non-redundant.
Adds a new PricingTimelineBand component that sits directly above the
homepage InlineLeadForm with two side-by-side cards answering the two
final pre-conversion questions every buyer has:
1. "Projects from $X,XXX" — includes discovery, design, build, QA,
and post-launch support.
2. "Typical timeline: 4–8 weeks" — discovery week 1, weekly demos,
launch by week 8.
A subtle "Custom quote available — tell us about your project" line
with a downward chevron visually bridges the band into the form below.
Implementation notes:
- Anchor id="pricing-timeline" so the mobile sticky CTA bar / nav can
deep-link to it.
- grid-cols-1 md:grid-cols-2 → stacks vertically on mobile, side-by-
side on md+ (>=768px).
- Each card has an explicit min-h-[260px] sm:min-h-[280px] so the
band reserves its own vertical space at first paint, keeping
Lighthouse CLS unchanged.
- Uses existing design tokens (primary-* / accent-* / secondary-*,
rounded-3xl, container-wrapper, gradient-br) so the band feels
native to the page.
- Placeholder copy ($X,XXX and 4–8 weeks) is flagged with
data-stakeholder-confirm markers + HTML comments so the marketing/
leadership team knows what still needs sign-off.
- Reduced-motion-respecting CSS animation on the bridging chevron.
Swaps the soft-adjective benefits section (Rapid Development, Enterprise
Security, Built to Scale, 24/7 Support) for a compact horizontal stat
band so the first below-the-fold surface leads with hard, scannable
numbers instead of generic copy.
- New src/components/ProofNumbers.astro renders 4 large gradient numbers
with one-line captions: 20+ Projects Delivered, 5★ Client Rating,
11 Districts Deployed, < 2s Avg Page Load. Numbers carry a TODO for
stakeholder confirmation; defaults mirror existing hero/stat copy.
- Responsive grid: 2×2 on mobile (<md), 4×1 horizontal band on desktop,
with subtle vertical dividers between columns on md+.
- Matches site typography tokens (text-secondary-* / text-primary-*)
with full dark-mode parity (gradients shift to primary-400/300).
- Removes now-unused `benefits` data array and inline SVG icons from
src/pages/index.astro along with the surrounding section markup.
- Add `image`/`imageAlt`/`initials`/`metric`/`metricLabel` fields to the
homepage testimonials data so each card surfaces a concrete client
outcome (e.g. "3× faster loan processing", "+42% organic traffic")
next to the quote.
- Render a 56–64px rounded avatar with lazy-loaded `<img>` (width/height
set to prevent CLS) and a brand-tinted metric badge in the card
header. Initials sit behind the image as an automatic fallback if
the avatar 404s or fails to decode.
- Ship 3 neutral SVG initial-avatars under public/images/testimonials/
(ajay-pruthi, dhirendra-singh, dilip-raj) as placeholders until real
headshots are licensed — flagged in the data-array comment so future
edits know to swap in JPG/WebP at the same path.
- Tighten responsive sizing: card padding scales 8→14, quote text
scales 20→30, avatar 56→64, and the star+metric row now wraps on
narrow viewports so the layout reads cleanly at 360/768/1280.
The homepage rendered two FAQ blocks — an inline "Common Questions" section
plus the <HomepageFaq /> component above the final CTA — which produced two
FAQPage JSON-LD entries and a redundant accordion. Consolidate on
HomepageFaq (self-contained, polished accordion, better a11y) and:
- delete the inline FAQ <section>, the `faqs` array, the `faq={faqs}` prop
on <SEO>, the orphan .faq-question/.faq-answer/.faq-icon CSS, and the
initFAQ() boot script + its call in index.astro
- merge the 4 unique inline questions (support, process, team augmentation,
security) into HomepageFaq's moneyFaqs; the 2 duplicates (technologies,
timeline) were already covered there
- refresh HomepageFaq's lead-in copy and comments to reflect it as the
single canonical homepage FAQ
Result: one FAQ heading + one accordion in the DOM, exactly one FAQPage
JSON-LD with 10 Q&A pairs, no broken anchor links.
Both honeypots now use off-screen positioning (position:absolute; left:-9999px;
width:1px; height:1px; overflow:hidden) instead of relying on a parent's
aria-hidden alone, and the input itself carries tabindex="-1",
autocomplete="off", and aria-hidden="true". Labels are sr-only and sit as
siblings of the input (no nested label/input). Avoid display:none and
visibility:hidden so bots that skip those still trip the trap.
Verified: rendered honeypot HTML matches spec on both /contact and the
homepage inline lead form, and /api/contact still 200s a populated `website`
silently (bot path) while accepting empty `website` payloads as real leads.
Both the contact form (/contact) and the homepage "Tell us about your project"
inline lead form post to /api/contact. Updated that single handler to build
the nodemailer transport from a clean set of SMTP_* env vars per spec:
SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASS
SMTP_FROM + SMTP_FROM_NAME -> "From: Ajay Ghanwat <ghanwat.ajay@workroot.in>"
MAIL_ADMIN_TO -> admin notification recipient
(falls back to SMTP_FROM, then legacy
CONTACT_EMAIL_TO / CONTACT_EMAIL / SMTP_USER)
SMTP_REQUIRE_TLS -> force STARTTLS upgrade on port 587
SMTP_CONNECTION_TIMEOUT_MS -> defaults to 10000
SMTP_GREETING_TIMEOUT_MS -> defaults to 10000
SMTP_SOCKET_TIMEOUT_MS -> defaults to 10000
Behaviour preserved:
- Existing user-facing auto-reply (the block previously at L270) kept.
Subject + body now adapt for project-inquiry sources (homepage-inline,
homepage-hero, homepage-final-cta, mobile-sticky) so the admin inbox
can triage [Project Inquiry] vs [Contact Form] at a glance.
- Graceful degradation per FORM_INTEGRATION.md: missing env vars or a
failed nodemailer import logs a structured warning and returns 200 —
the site never 500s on email config.
- Rate limiting, honeypot, CORS, validation, and fire-and-forget
background dispatch are untouched.
Observability:
- Structured console logs at: transport created, admin accepted (with
messageId), user auto-reply accepted (with messageId), and send-failure
(with smtp code/command/response). SMTP_PASS is never logged.
Misc:
- .env.example updated to document the new variables and the legacy
aliases that are still honored.
Expand the CI/CD env-var table to list all SMTP_*, MAIL_ADMIN_TO,
SMTP_FROM, SMTP_FROM_NAME and STARTTLS/timeout knobs that the contact
and "Tell us about your project" forms now rely on. Adds a note that
the production secrets live in the Default environment's platform
env-var store and that the frontend service must be restarted after
any change.
Mounts a 3-field lead-capture form (name, email-or-phone, project type)
between the FAQ/tech-stack block and the final CTA band so visitors who
are ready to start a project can submit without leaving the homepage.
Cuts the friction step of routing every CTA through /contact.
- New src/components/InlineLeadForm.astro:
* Heading, micro-trust subhead, honeypot, client-side validation
* Smart contact-field routing: detects email vs phone and synthesises
a placeholder email for phone-only leads so the existing /api/contact
validator accepts them (the real phone is preserved and surfaced in
the admin notification)
* In-place success state with phone + WhatsApp fallbacks; no navigation
* 48px touch targets, dark-mode safe, autocomplete + inputmode attrs
- src/pages/api/contact.ts: accept and surface `source` / `projectType`
metadata (allowlisted source values, free-text projectType capped at
80 chars), add `erp-solutions` and `government-systems` subject codes,
and include the source/project info in both the admin email and logs.
- src/pages/index.astro: import + mount InlineLeadForm above the final
CTA section.
- tests/inline-lead-form.spec.ts: 8 specs covering UI render, mobile
attributes, blank-field validation, email-submit + phone-submit
payload routing, and server-side acceptance of the new payload shape,
new subjects, and unknown-source fallback.
- WhatsAppFab: 56px brand-green floating button (wa.me/919561417403), shown
on every page; safe-area aware; lifts above the mobile CTA bar on <md.
- MobileStickyCtaBar: 3-column sticky bottom bar (Call / WhatsApp / Quote)
visible only below the md breakpoint, with safe-area padding, 48px+ touch
targets, and dark-mode-aware styling. Bottom spacer keeps the footer
clear of the bar on mobile.
- Mounted both components globally via BaseLayout.
- Added tests/sticky-cta.spec.ts covering 360px and 1280px viewports,
link integrity, no-overflow, hidden-at-md, and FAB/bar non-overlap.
The stats tiles ("Projects Delivered" etc.) could end up frozen at
0+/0%/0+/0 whenever the IntersectionObserver never fired (tall
sections on mobile, threshold too strict, JS error, prefers-reduced-motion).
- Server-render the final value as the initial textContent so the
numbers are correct on first paint, with JS disabled, and on any
hydration failure.
- Lower observer threshold to 0.1 and add rootMargin so the animation
triggers reliably on tall viewports.
- Detect prefers-reduced-motion and render the final value without
animating.
- Fall back to immediate animation when IntersectionObserver is
unavailable or the section is already in view at load.
- Reset to 0 only at the moment the animation starts (and snap to
the exact target at the end) so a mid-flight failure can never
leave the counter visibly stuck.
- Boot all homepage scripts after DOMContentLoaded.
Hero
- Tightened H1 to a benefit-led, audience-first value prop
("Custom Software That Powers Enterprises & Governments")
- Replaced generic subhead with a ~135-char outcome line that names
the audience (startups, enterprises, government bodies)
- Swapped primary CTA copy to an action verb ("Get a free consultation")
and secondary to "See our work"; added source query params + data-cta
hooks so analytics can attribute CTA clicks
- Added a micro-trust line under the CTAs (free 30-min call, reply within
1 business day, no commitment)
Social proof
- New ClientLogos.astro component rendered below the hero. Grayscale
strip with hover pop, image+wordmark fallback, TODO documenting the
five required SVG assets in public/images/clients/
- Default roster sourced from the live portfolio (PLNR, RENTEC, IIT
Patna, MOC Soft Technologies, Govt. of Bihar)
- Existing testimonials carousel left intact (3 quotes with name/role)
Services preview
- Reframed the 4 cards around outcome headlines and added deep links
to /services#<slug> for each service detail section
- Renamed "Learn More" to "Learn more" and made it a real <a> link
with aria-label for screen readers
Final CTA band
- New conversion-focused headline ("Ready to ship your next production
system?") and a one-line offer with explicit response SLA
- Added a "what you'll get" reassurance row (discovery call, fixed-price
scope, NDA on request)
- Primary CTA now "Get my free consultation" with source attribution;
secondary "See case studies" preserved
- Process-section CTA renamed to "Book a discovery call" and tagged
SEO
- Updated meta description on BaseLayout invocation to match the new
positioning; FAQPage schema and existing structured data untouched