Commit Graph

59 Commits

Author SHA1 Message Date
Scarlett 231f07c62d fix(ui): header CTA clipped at iPad portrait, and reCAPTCHA cut off at 320px
Two real defects, found by rendering the site rather than reading it. Neither
was among the twenty issues filed for Batches 10 and 11.

#214 (P1) — at exactly 768px, iPad portrait, the header's "Request
Consultation" CTA measured x 676-778 against a 768px viewport: 10px sliced off,
with no scrollbar to reveal it because html/body carry overflow-x:hidden. At
that width the burger menu is already hidden, so the primary conversion action
was simply unreachable. The nav's five gap-6 gaps were the slack; gap-4 at md
(gap-6 from lg) frees 40px, keeping the CTA on screen at md rather than
deferring it to lg and leaving 768-1023px with no CTA at all.

#215 (P2) — Google's reCAPTCHA checkbox iframe is a fixed 304px that cannot be
resized. At 320px it measured x 41-345, so 25px of branding and the privacy and
terms links were clipped. Scaled to 0.85 below 360px with the wrapper height
reduced to match, since transform does not affect layout and the form would
otherwise gain dead space.

Also adds scripts/qa-browser.mjs, which found them. It measures horizontal
scroll, broken images, elements past the right edge, CLS and LCP across pages
and viewports. Written because seven of the ten issues in Batches 10 and 11
misstated their own evidence, and two of those would have made the site worse
if actioned.

Two false positives in the tool itself, both fixed before trusting it:
- Lazy images below the fold read as broken. It now scrolls the page AND chases
  each un-loaded image individually, and reports observed HTTP failures apart
  from never-rendered images.
- `--paths / --viewports 320` swallowed "320" as a path. Argument collection now
  stops at the next flag.

Verified against a local production build: 5 paths x 5 viewports, zero findings.
Before the fix the same run reported the CTA overflow at 768 on four pages and
the reCAPTCHA overflow at 320 on /contact.

Not yet live — this needs a release and a deploy.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 04:05:37 -05:00
Scarlett 9fdc6b6032 fix(a11y): visible focus indicator, aria-expanded, and six Label-in-Name failures
Batch 10, and only three of its six issues were real. The other three are
answered on the tracker with the arithmetic.

#189 — focus indicator. Footer and Home carried zero focus styling across 17
links. Added one global :focus-visible rule rather than sprinkling classes,
because the issue's own scope was "all interactive <a> and <Link> elements".

Not the ring the issue asked for. It suggested ring-primary-cyan; #22D3EE is
6.26:1 on navy and 2.38:1 on white, so on this light-first design that ring
would have failed WCAG 1.4.11 across most of the site. Two rings instead — white
inside, navy outside — so the white carries the dark bands and the navy carries
the light sections. Worst case across every background in the palette is
13.62:1. box-shadow so both rings follow each element's own border-radius, plus
a transparent outline for forced-colors mode.

#192 — aria-expanded={isOpen} and aria-controls on the mobile nav trigger, and
the id on SheetContent it now points at. Confirmed as "false" in the
prerendered HTML.

#193 — INVERTED. The issue asked for aria-labels to be added consistently to
hero CTAs. The aria-labels already there were WCAG 2.5.3 Label in Name failures,
Level A: "Schedule a consultation" is not a superset of the visible "Schedule
Consultation", so a voice-control user saying what they see cannot activate the
link. Doing what the issue asked would have spread a Level A failure. Removed
the six that broke it; kept the eight that genuinely add context and do contain
their visible text, including the icon-only header logo link that needs one.

Audit now reports 0 failures across Home, Services, Footer and Header.

Verified: npm run build; the ring is in the built CSS, aria-expanded="false" and
id="mobile-nav-content" are in the prerendered HTML, all six removed labels are
absent from it, and the visible CTA text still renders.

NOT verified: nothing has been walked keyboard-only in a browser, and no screen
reader has been used. That gap is recorded in docs/qa/ClaudeQACoverage.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 02:31:13 -05:00
null ac6f5d1f78 feat(seo): publish privacy policy, remove street address, prerender all routes (batch 0.9.3)
Client directive (Levi Halford, 2026-08-01) ahead of Google/Meta lead forms.

Privacy policy:
- Publish approved policy verbatim at /privacy-policy (src/data/privacyPolicy.js
  is the single source of truth; 292/292 source lines verified present)
- Privacy Policy link in the footer of every page
- Effective/Last Updated 2026-07-31, privacy@queuenorth.com as mailto

Remove St. Petersburg street address from every surface named in the brief:
footer, contact page, schema markup, SEO metadata, Google Maps links. Collapse
ProfessionalService + Organization schema into a single Organization with
areaServed: United States; drop geo coordinates, priceRange, openingHours.
Add the approved US-coverage sentence to About. No replacement address.

Crawler visibility (the site previously served 0 bytes of body HTML without JS):
- Prerender all 19 routes at build time via src/entry-server.jsx + scripts/prerender.js
- Hoist title/meta/canonical/JSON-LD into <head>; renderToString does not do this
  and react-helmet-async's context is empty under React 19
- Serve prerendered HTML; return a real 404 for unknown paths instead of 200
- Hydrate instead of discarding the prerendered markup

SEO/perf:
- Titles <=60 and descriptions <=160 chars across all pages
- Add BreadcrumbList to interior pages, WebSite to home
- Generate sitemap.xml from the route list with git-derived lastmod
- 301 duplicate URL forms (trailing slash, //, /index.html), preserving query
- Immutable caching for content-hashed assets; no-cache for HTML
- Split the 522 KB bundle into app/react-vendor/router/icons
- loading/decoding/fetchpriority + per-route hero preload; drop unused asset

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 01:45:52 -05:00
null d074e597b2 feat(zoho): WebToLead forwarding mode, veteran-owned certified badge, Docker/env/CI updates (batch 0.9.1) 2026-06-14 16:08:29 -05:00
null 05b27d216a feat: Dockerfile/docker-compose updates, server improvements, contact form with recaptcha, API integration (batch 0.9.0) 2026-06-14 15:37:26 -05:00
null a8d9492a80 added 404 2026-05-28 00:41:24 -05:00
null 0f272fcf19 error and injection 2026-05-28 00:18:08 -05:00
null 3a61000c12 fix scroll 2026-05-27 23:40:09 -05:00
null e625a24b6e redirect to contact form 2026-05-27 22:33:54 -05:00
null f35de43952 fix footer 2026-05-27 22:19:04 -05:00
null c43d3bc955 company name footer one line 2026-05-27 22:08:46 -05:00
null ec14701795 center footer 2026-05-27 21:54:44 -05:00
null 78967ff56f phone 2026-05-27 21:49:21 -05:00
null cc1970fd1d added phone numebr hamburger 2026-05-27 21:44:06 -05:00
null 8c1e0f4c3d ui 2026-05-27 21:35:12 -05:00
null f59d053afd mobile navbar text per owner 2026-05-27 21:04:30 -05:00
null 4410f01d48 Missing `Description` or `aria-describedby={undefined}` for {DialogContent}. 2026-05-27 14:11:48 -05:00
null a81e97fb31 mobile view 2026-05-27 12:42:25 -05:00
null f0f0cfd599 #181 2026-05-26 13:04:57 -05:00
null 85d7ae4bb1 logo enlarge 2026-05-26 12:44:10 -05:00
null afec6547c1 RECAPTCHA 2026-05-25 20:20:15 -05:00
null 9b5f9f885c text 2026-05-25 20:02:36 -05:00
null e489245104 service military 2026-05-25 19:51:03 -05:00
null 80b1747ffe branding 2026-05-25 19:44:10 -05:00
null bc6bc9a787 logo 2026-05-25 19:40:18 -05:00
null 1d687c5fa1 branch footer 2026-05-25 19:23:37 -05:00
null 52d9a16462 branch footer 2026-05-25 18:35:40 -05:00
null c17ac83b52 services 2026-05-25 18:33:19 -05:00
null a293d0fa9a feat(seo): add canonical URLs, close SEO audit (#175) 2026-05-18 13:58:35 -05:00
null f378233328 fix: seo 2026-05-18 13:55:06 -05:00
null de61d5e625 fix(ui): UI fixes across header, contact, home, about, support, services, industries (#132 #133 #134 #154 #165 #172 #173) 2026-05-18 13:12:18 -05:00
null 928527b908 fix: remove all email addresses from site, redesign contact page, update footer, about, header, support (#165 #172 #134 #173) 2026-05-18 12:11:56 -05:00
null b04e5bbb04 spacing 2026-05-18 10:57:06 -05:00
null fff92a40df close 134 2026-05-18 09:46:56 -05:00
null 990139b77f fix(ui): remove duplicate trust section (#173), enlarge logo and add home link (#154) 2026-05-18 09:44:44 -05:00
null d8a975431f fix(ui): dropdown hover gap fix (#132) and remove contact form button (#133) 2026-05-18 09:35:29 -05:00
null e1604ee28f fix: add aria-labels for accessibility, fix JSX template literal syntax (#101) (batch 10.2) 2026-05-17 22:47:03 -05:00
null 5c17019931 fix: remove unused assets (24MB), Dialog component, CardDescription dup, zustand dep (#95 #113 #114 #115 #116) (batch 9.9) 2026-05-17 22:08:21 -05:00
null 829362fb79 fix: Cisco/Veteran icons, sidebar slug, JointLogo placeholder, Footer copy (#98 #100 #103 #107) (batch 9.8) 2026-05-17 22:05:08 -05:00
null 6e975b869b fix: favicon/manifest, og:image PNG, logo optimized to 44KB PNG (#99 #117 #118) (batch 9.7) 2026-05-17 22:01:27 -05:00
null 00f5356db4 fix: Support CTA bg color, clickable phone/email, Footer tel: +1 (#112 #106 #90) (batch 9.4) 2026-05-17 21:48:27 -05:00
null 8adb9cdb76 fix: desktop dropdown nav, Button→Link, Contact scroll-to-form (#109 #102 #105) (batch 9.3) 2026-05-17 21:44:48 -05:00
null bdef2684bb fix: header CTA visibility, scroll-to-top, 404 page (#104 #89 #88) (batch 9.1) 2026-05-17 21:37:42 -05:00
null 4fe31ed9b6 fix: correct contact info and remove unverified location claims (batch 8.9)
- Phone: (906) 482-6616 → (321) 730-8020 direct, (888) 656-2850 toll-free
- Add toll-free number to Footer and Contact page
- Add LinkedIn link to footer
- Add 8x8 trademark disclaimer to footer legal section
- Fix JSON-LD phone numbers in Home.jsx
- Add support phone to Support page
- Strip all Houghton, MI and Upper Peninsula location references
  from meta tags, JSON-LD, and fallback descriptions
  (not present on original site, unverified)
- Change JSON-LD areaServed from Houghton/UP to United States
- Update Support.jsx Zoho Desk link placeholder
2026-05-17 20:44:18 -05:00
null 1437b2af07 fix: 10 bug fixes from code review (batch 0.6.5)
- #63: Fix industry.href undefined → use industry.id for navigation
- #50: Fix sanitized scope error in catch block (let before try)
- #58: Footer.jsx: convert all internal <a href> to <Link to>
- #61: Textarea.jsx: fix className interpolation (quotes → backticks)
- #59: About.jsx: convert CTA <a href> to <Link to>
- #60: Support.jsx: convert Contact button <a href> to <Link to>
- #62: Badge.jsx: text-foreground → text-text
- #64: Support.jsx: hover:bg-navy-darker → hover:bg-primary-navy-dark
- #65: Server: move timeoutMiddleware before catch-all routes
- #66: Contact.jsx: convert self-referencing <a href> to <Link to>
2026-05-17 18:03:55 -05:00
null 4f3e20b7a0 fix: dead code cleanup, timeout middleware, Zoho error handling (closes #53, #54, #55, #56, #57)
- Delete broken barrel exports ui/index.jsx and ui/all.jsx (#53)
- Remove duplicate QueryClient instance and dead queryClient.js (#55)
- Remove unused queryClient import/export from api.js (#55)
- Move timeoutMiddleware before catch-all routes so it actually fires (#54)
- Fix async error handling in forwardToZoho - add .catch() (#56)
- Add ZOHO_CLIENT_ID to credential guard, normalize defaults to null (#57)
(batch 0.6.4)
2026-05-17 17:46:54 -05:00
null 9cdc299ade fix: undefined Tailwind classes, SPA navigation, phone/email links (closes #51, #52)
- Replace all undefined shadcn/ui Tailwind classes with correct config values
  (text-muted-foreground→text-muted, text-card-foreground→text-text,
   bg-secondary→bg-section-alt, ring-ring→ring-primary-navy, etc.)
- Replace text-cyan/bg-cyan with text-primary-cyan/bg-primary-cyan
- Convert all internal <a href> to React Router <Link to> for SPA navigation
- Remove self-referencing /contact button on Contact page
- Add tel: links for phone numbers, mailto: links for emails in
  Contact.jsx and Support.jsx hero badges and info sections
- Fix Header.jsx mobile menu button hover:text-cyan→hover:text-primary-cyan (batch 0.6.3)
2026-05-17 17:42:03 -05:00
null 32a2b905a1 fix: add missing CardDescription component and import (batch 0.6.2) 2026-05-17 16:39:54 -05:00
null 56bdf07216 fix: close issues #12 #15 #17 #18 — CSP nonce, API retry, input debounce, caching verified (batch 0.6.1) 2026-05-17 16:10:10 -05:00
null 80969e5aee feat: merge 8x8 page into UCaaS/CCaaS service pages, remove standalone route (batch 0.6.6) 2026-05-17 15:44:27 -05:00