Pillar PEO Advisors — CRO and design scorecard
Scored against cro-rubric.md, 40 items, on mockups/home.html, mockups/hr-audit.html,
mockups/charlotte.html with shared mock.css.
Method. Every page rendered in headless Chrome 152 at 1440×900 and at a true 390×844
viewport (CDP Emulation.setDeviceMetricsOverride, mobile:true, deviceScaleFactor 2).
Contrast computed per text node against its composited background. Tap targets, CTA cadence,
section padding, green coverage, proof adjacency and layout shift measured in the DOM, not by eye.
npx @axe-core/cli run against all three pages. Core Web Vitals measured with a
PerformanceObserver injected before navigation, 4× CPU throttle and Fast-3G network, cache
disabled. Baseline numbers come from the pre-fix files re-served on a second port, so the
"before" column is measured, not remembered.
Result: 34 → 97 passes across the three pages.
| Page | Applicable items | Before | After |
|---|---|---|---|
| home.html | 33 | 9 | 31 |
| hr-audit.html | 37 | 15 | 35 |
| charlotte.html | 34 | 10 | 31 |
| Total | 104 | 34 | 97 |
n/a marks an item that does not apply to that page type: item 22 is a homepage item,
23–27 are HR Audit service-page items, 28–29 are city-page items. n/a items are excluded
from the per-page totals.
1. Scorecard
| # | Item | home | hr-audit | charlotte |
|---|---|---|---|---|
| A | Above the fold | |||
| 1 | Headline ≤10 words, states an outcome not a category | pass | pass | pass |
| 2 | Subhead names who it's for and the mechanism | pass | pass | pass |
| 3 | Primary CTA visible without scrolling at 1440 and 390; subhead ≤3 lines on mobile | pass | pass | pass |
| 4 | Risk reducer within 24px of the primary CTA | pass | pass | pass |
| 5 | Hero visual is a person, a deliverable, or an outcome | pass | pass | pass |
| 6 | At least one proof element inside the first viewport | pass | pass | pass |
| 7 | Header shows the phone as a tap-to-call link on every page | pass | pass | pass |
| B | CTA system | |||
| 8 | One primary action label sitewide, unchanged | pass | pass | pass |
| 9 | One primary button style, ≥48px; every secondary action is a text link | pass | pass | pass |
| 10 | Primary CTA in the hero and again every ≤2 screen heights | pass | pass | pass |
| 11 | Sticky mobile bar with the CTA and phone, appearing once the hero scrolls off | pass | pass | pass |
| 12 | Every CTA block carries a micro-line | pass | pass | pass |
| 13 | Final section is a CTA block with the founder's face | pass | pass | pass |
| C | Proof and trust | |||
| 14 | Proof strip of 3–5 quantified, true items directly under the hero | pass | pass | pass |
| 15 | Testimonials carry name/role/firm/photo; proof within one screen of every CTA | pass | pass | pass |
| 16 | Founder section: photo, certifications, years in HR, industries served | fail | fail | fail |
| 17 | Process guarantees stated in specifics | pass | pass | pass |
| 18 | Provider-paid disclosure in plain words | pass | pass | pass |
| 19 | No fabricated proof of any kind | pass | pass | pass |
| D | Page structure and message flow | |||
| 20 | Section order: problem, offer, proof, process, price, objections, CTA | pass | pass | pass |
| 21 | One job and one heading per section; headings alone tell the story | pass | pass | pass |
| 22 | Offer ladder visible on the homepage in one section | pass | n/a | n/a |
| E | HR Audit service page | |||
| 23 | Price tiers with headcount bands above the fold or within one scroll | n/a | pass | n/a |
| 24 | Deliverable shown, not described | n/a | pass | n/a |
| 25 | "What we check" covers what a managing partner expects | n/a | pass | n/a |
| 26 | Timeline: days to kickoff, days to report, what the client supplies | n/a | pass | n/a |
| 27 | FAQ answers the four real objections | n/a | pass | n/a |
| F | Charlotte city page | |||
| 28 | H1 and hero name Charlotte and the firm types | n/a | n/a | pass |
| 29 | Local specifics incl. Charlotte office address with map | n/a | n/a | fail |
| G | Forms and booking | |||
| 30 | Booking form has 4 fields or fewer | pass | pass | pass |
| 31 | Embedded scheduler, or a promised reply window and a named person with a photo | pass | pass | pass |
| H | Mobile | |||
| 32 | No horizontal scroll, 44px tap targets, sticky CTA clears fields and footer phone | pass | pass | pass |
| 33 | Hero image under 150KB; LCP under 2.5s on a mid-range phone | pass | pass | pass |
| I | Design craft | |||
| 34 | Section padding 80–120 desktop, 56–72 mobile, consistent | pass | pass | pass |
| 35 | Body 16–18px, line height 1.5–1.6, measure 60–75 characters | pass | pass | pass |
| 36 | At most four sizes per page; League Spartan headings only | pass | pass | pass |
| 37 | Green for CTAs and small accents only, under 5%; white plus one neutral | pass | pass | pass |
| 38 | Every screen has a photo or a real deliverable; ≤1 icon grid per page | fail | fail | fail |
| J | Accessibility | |||
| 39 | Text contrast ≥4.5:1; green is fill-only | pass | pass | pass |
| 40 | Alt text, visible labels, focus states, one H1, sequential H2s, honest link text | pass | pass | pass |
2. What was failing, and what was done
A · Above the fold
- 3 — hero subhead ran 5 lines on home and 6 on both hr-audit and charlotte at 390px.
Ledes rewritten and the trailing sentence wrapped in
.hide-sm, which is dropped under 700px. Now 3 / 3 / 2 lines, measured. - 7 — the phone number was inside the hamburger on mobile, so no page showed tap-to-call
in the header below 940px. Added
.tel-mini, a 46px outlined icon button, next to the menu. - 1, 2, 28 — Charlotte's H1 was "HR consulting in Charlotte, NC.", a category with no audience. Now "HR consulting for Charlotte law, CPA, and medical firms." (8 words). hr-audit's subhead never named the audience; it does now.
- 4 — risk reducers rewritten to the rubric's own line: "Free. 20 minutes. No pitch deck. You leave with a scope, a price, and a date."
B · CTA system
- 8 — the mobile bar said "Book a call" while everything else said "Book a free 20-min call". One label now, on all 41 primary buttons across the three pages.
- 9 — there were two primary button styles (navy fill on white, green fill on navy) plus
.btn.ghostused as a competing filled-looking button in two of three pricing tiers and in the Charlotte hero. There is now one: green#2ECC70fill, navy text, 52px, 8.8:1 contrast. Secondary actions are.tlinktext links with an arrow. The only remaining ghost button is the icon-only call button in the sticky bar, which item 11 requires. - 10 — largest gap between primary CTAs at 1440 was 3097px (home), 4213px (hr-audit), 3710px (charlotte) against a 1800px budget. Now 1719 / 1776 / 1422.
- 11 — the sticky bar was visible from scroll position 0 and ate the mobile fold. It now
starts translated off-screen and an IntersectionObserver reveals it once the hero passes.
A second observer stands it down over
#bookand the footer, so it no longer covers the form (verified: it overlapped the submit button before, zero overlaps now). - 12 — micro-lines added under every CTA block that lacked one.
- 13 — no page ended with a face. All three final CTA bands now open with Caleb Sherrill's photo, name and role, and close with three written guarantees.
C · Proof and trust
- 19, 14 — the homepage carried a dashed placeholder membership row (NAPEO / SHRM / CRBA / BBB, each tagged "to confirm") under the heading "Trusted by firms in NC, SC, and beyond" — a placeholder logo row plus an unverifiable claim plus a banned phrase. Replaced with a quantified proof strip of four true, checkable numbers: 9 areas, $2,500–$6,000, 2–3 weeks, ~4 hours. Charlotte got a local version: 45 min, 2 states, 9 areas, $2,500–$6,000.
- 19, 15 — home and charlotte both shipped three placeholder testimonial cards with empty
star outlines, "[Name], Managing Partner", "[Firm]", a dashed "PHOTO" avatar and the line
"Google rating once 5 reviews exist". The rubric scores that as a fail outright. Each card
was converted in place, keeping the identical
.tcardshell so a real quote drops in later with no layout change: - Process guarantee — "Fixed fee quoted on the scope call, never changed mid-engagement."
- What the document does — "Every finding cites the rule, so your counsel can verify it in minutes."
- Who you deal with — "You talk to the founders, not a rep." Each carries three checkable specifics and a real named person with a real photo. One honest note sits below: "Client quotes are being collected now. Each one replaces a card above, in place, with a name, a role, a firm, and a number." hr-audit had no proof section at all and now has the same three cards.
- 15, second clause — 3 CTAs on home, 2 on hr-audit and 2 on charlotte had no proof block within one screen. Proof chip rows added beside them; now zero on all three pages.
- 18 — the plain-words disclosure "you pay us nothing; the PEO does" is now on all three pages verbatim.
D · Structure
- 21, 22 — the homepage's four service cards were a feature list with "Learn more" on each,
three of which pointed at
#book. Rebuilt as the four-rung offer ladder the rubric asks for: 1 Scope call (free, 20 min) → 2 HR Audit (from $2,500) → 3 Projects and fractional HR → 4 PEO brokerage and transitions. Link text now says where it goes. - 21 — hr-audit had two separate sections about the same checks ("Nine areas, 41 checks, one score each" and "The 41 checks, by area"). Merged into one section with one heading. The empty-proof headings ("Proof goes here, and only when it's real.") are gone, so the headings alone now read as a story.
- 20 — homepage reordered so "who we serve" sits next to the problem section and pricing follows the proof block. hr-audit gained a "What happens after the report" section.
E · HR Audit page
- 23 — price tiers were the third section: fine at 1440, but 2130px down at 390px, well past one scroll. All three bands with their headcount ranges are now chips in the hero itself ($2,500 · 10–25, $4,000 · 26–75, $6,000 · 76–150), and the pricing section moved directly under the hero.
- 27 — the FAQ answered "we already have a PEO" but none of the other three objections. Added "Is this a pitch for a retainer?", "What if you find nothing?" and "Do you work outside North Carolina?", plus the "What happens after the report" section that kills the same fear structurally.
- 26 — what the client must supply is now an explicit panel: handbook and acknowledgments, last two payroll registers, I-9 files, benefit documents and 1095s, job descriptions, separation files from the last 12 months.
F · Charlotte
- 29 — the North Carolina Wage and Hour Act (NCGS 95-25) is now named, and an office block with phone, email, hours and an in-person-by-appointment line sits beside the map slot. Still failing on the address itself — see the remaining list.
G · Booking
- 31 — the confirmation loop was open on all three pages. Each booking block now shows the person who makes contact with a real photo ("You'll hear from Josiah Sherrill, Founding Account Executive"), the reply promise tightened to "within one business day", and the scheduler slot spec now includes the confirmation-screen requirement.
- 30 — home and hr-audit gained a Firm field (3 → 4 fields, still at the limit).
H · Mobile
- 32 — footer links were 21px tall, the menu panel 41px and text links 30px. Everything interactive now clears 44px at 390px; the automated sweep reports zero undersized targets on all three pages. The sticky bar overlapped the submit button; it now stands down over the booking block and the footer.
- 33 —
founders.jpgwas 266KB. Re-encoded to 137KB with no visible loss. Every non-hero photo now usesloading="lazy"anddecoding="async". Page weight on home fell 418KB → 252KB and load time 2.86s → 1.97s on the throttled profile.
I · Design craft
- 34 — hero padding was 60/68px, under the 80–120 floor, and
.tightsections were 48px on mobile, under the 56 floor. Now 80/96 and 56. - 35 —
.secand.price-noteran the full 1200px container, about 120 characters a line. Capped at 70–74ch. - 36 — the sheet carried fourteen near-duplicate text sizes (17.5 / 16.5 / 16 / 15.5 / 15 /
14.5 / 14 / 13.5 / 13 / 12.5 / 12 / 11.5 / 10.5 / 10px) and
--labelwas League Spartan, so every eyebrow, table header, price label and footer heading was set in the display face. Collapsed to a four-token scale —--t-lede19,--t-body17,--t-cap14.5,--t-label12.5, all Nunito Sans — and 84 declarations rewritten onto it. League Spartan is now confined to h1–h4, card titles, step numerals, the price figures and FAQ question rows, all heading-role. - 37 — the pricing section used a full-bleed green tint (
#EEF9F2), giving the site three background fields..tintgnow resolves to the one neutral, so backgrounds are white plus#F7F8FB. Measured green fill in the rendered screenshots: 1.0% / 2.0% / 1.0% at 1440 and 3.9% / 3.9% / 3.8% at 390, all under the 5% ceiling. - 38 — home had three icon grids (pain cards, service cards, industries). Icons removed from
the first two; exactly one icon grid per page now (
ind-gridon home,area-liston hr-audit, none on charlotte). The "photo or deliverable on every screen" half of this item still fails — see remaining.
J · Accessibility
- 39 — a real bug:
mock.cssline 564 carried a barefooter .legal{color:var(--ink-70)}rule intended for the report's light footer. It overrode the dark-footer rule, so the copyright and "Not a law firm" line rendered navy-on-navy at 1:1 contrast — invisible on all three pages. Scoped to.rep~footer .legal. Every text node on every page now clears its threshold at both widths; the automated sweep reports zero contrast failures. - 40 — "Learn more" appeared four times on the homepage as the only link text on cards, three
of which went to the booking anchor rather than anywhere to learn more. Industry cards were
links to
#booklabelled with the industry name. Both fixed: real link text, and the purely informational cards are no longer links. - Landmarks — axe flagged the mockbar, skip link and sticky bar as content outside any
landmark on all three pages. The mockbar is now an
<aside aria-label="Mockup navigation">(same class, same strip), the sticky bar a<nav aria-label="Quick actions">, and the skip link moved inside<header>. axe-core 4.10.3: 0 violations on all three pages. - Focus verified by dispatching real Tab keystrokes: every stop has a 3px solid ring (navy on
light, green on dark), the skip link becomes visible on focus at 8px/8px and
#mainexists.
3. Measured before / after
| Check | home | hr-audit | charlotte |
|---|---|---|---|
| Contrast failures (1440 + 390) | 1 → 0 | 1 → 0 | 1 → 0 |
| axe-core violations | 3 → 0 | 3 → 0 | 3 → 0 |
| Tap targets under 44px at 390 | 3 → 0 | 3 → 0 | 5 → 0 |
| Horizontal scroll at 1440 / 390 | none → none | none → none | none → none |
| Hero subhead lines at 390 | 5 → 3 | 6 → 3 | 6 → 2 |
| Largest gap between primary CTAs, 1440 | 3097px → 1719px | 4213px → 1776px | 3710px → 1422px |
| Primary CTAs on the page | 8 → 12 | 7 → 14 | 5 → 9 |
| CTAs with no proof block within one screen | 3 → 0 | 2 → 0 | 2 → 0 |
| Icon grids | 3 → 1 | 1 → 1 | 0 → 0 |
| Distinct non-heading type sizes | 14 → 4 | 14 → 4 | 14 → 4 |
| Green fill, share of rendered area (1440 / 390) | — → 1.0% / 3.9% | — → 2.0% / 3.9% | — → 1.0% / 3.8% |
| LCP (390px, 4× CPU, Fast 3G) | 1.05s → 1.06s | 0.78s → 0.92s | 0.94s → 1.03s |
| CLS | 0.110 → 0.0008 | 0 → 0 | 0.0007 → 0.017 |
| Page weight | 418KB → 252KB | 110KB → 117KB | 371KB → 252KB |
| Load complete | 2.86s → 1.97s | 1.26s → 1.37s | 2.63s → 1.93s |
The homepage CLS of 0.110 was the League Spartan and Nunito Sans swap reflowing the hero copy
block (the observer named UL.proof-strip, DIV.cta-row and P.lede as the sources).
League Spartan measures 8.3% narrower than Helvetica and Nunito Sans 1.1% wider, so two
metric-matched @font-face fallbacks with size-adjust:91.7% and 101.1% were added ahead of
the generic stack. That took the homepage to 0.0008 with no change to how the type looks once
the webfonts land.
Constraints held: mock.css still defines every required custom property (--navy, --green,
--green-ink, --green-soft, --ground, --sheet, --sheet-2, --ink, --ink-70,
--ink-50, --hatch, --hatch-2, --pass, --pass-soft, --watch, --watch-soft,
--fail, --fail-soft, --display, --body, --mono, --max, --r, --ease) and every
required class (.wrap, .mono, .pill with .pass/.watch/.fail, .slot, .mockbar,
.btn with .fill/.ghost, .dim, .legal, footer). index.html re-rendered and is
unchanged. All three pages keep their JSON-LD, the mockbar strip and
<meta name="robots" content="noindex,nofollow">. No testimonial, logo, rating or number was
invented; every figure on the pages is a term of the offer, checkable against the engagement
letter and the report.
4. Remaining — what the founder has to supply
Three items cannot be closed inside a mockup. Each is listed with exactly what unblocks it.
R1 · Item 16 — founder certifications and years in HR (all three pages)
Why it fails. The item requires certifications (SHRM-SCP, SPHR or equivalent) and years in HR. The originals carried "SHRM-CP / PHR / NAPEO membership" tagged to confirm, which is an unverified credential claim. Publishing it would be a worse failure (item 19) than leaving it out, so the block was left explicitly empty rather than guessed. Photo and industries served are done.
Founder must supply: - Certification names, certificate numbers and expiry dates for Caleb Sherrill (SHRM-CP or SHRM-SCP, PHR or SPHR), plus the certificate PDFs. - NAPEO membership number and the member-since year, or confirmation that there is no membership. - Years in HR as a single number, and the date it was counted from. - Whether Josiah Sherrill and Emily Snooks hold credentials worth listing.
Where it goes. The dashed slot in #about on home.html and in #who on hr-audit.html,
both labelled "Certifications — founder to supply before launch". Drop the facts in and delete
the slot wrapper; no layout change. Add a matching credentials line to the Charlotte founder block.
R2 · Item 29 — Charlotte office address, map and verified Business Profile
Why it fails. The item requires a Charlotte office address with a map. The address is
[Street address], Charlotte, NC 282xx in the footer, the address block and the JSON-LD
PostalAddress, and the map is a dashed slot. Everything else in item 29 is done: NC E-Verify
at 25, NC Wage and Hour Act (NCGS 95-25), the SC cross-border obligations, the local phone and
the in-person option.
Founder must supply: - The street address and ZIP that will be used on the Google Business Profile, and confirmation it is a location that can receive the verification postcard. - The claimed and verified GBP listing, so the map embed points at a real pin with a working directions link. - Confirmation of whether clients can actually be met there, or whether it is a mailing address and in-person means client-site only.
Where it goes. mockups/charlotte.html — the .mapslot in #areas (swap for the Maps
iframe with a title attribute), the .office address block beside it, the <address> in the
footer of all three pages, and the streetAddress / postalCode fields in the JSON-LD on
home.html and charlotte.html. Once the address is in, delete the three .tbd "to confirm" tags.
R3 · Item 38 — photography for the screens that have neither a person nor a deliverable
Why it fails. The item asks that every screen contain a photo of a person or a real
deliverable, from one photographic world. There are four usable photos in img/
(founders.jpg, caleb.jpg, josiah.jpg, emily.jpg) and one deliverable (the Load Report
card). They have been placed at as many depths as is honest — hero, process, founder section,
proof cards, final CTA and the form. Measured at a 900px screen height, screens still with
neither are 7 of 13 on home, 8 of 16 on hr-audit, 5 of 11 on charlotte. Closing it needs
photographs that do not exist; inventing stock would fail the same item's "no blue-tinted
stock, no clip-art" clause. The icon-grid half of item 38 is passing.
Founder must supply, one half-day shoot, natural light, real offices, no stock: - Caleb and Josiah working: at a desk with documents, on a call, at a whiteboard. - Emily in delivery: reviewing a report, on a walkthrough call. - A real client-site or office interior for the Charlotte page, and an exterior if the address in R2 is a real office. - One overhead of a printed Load Report on a table, for the deliverable sections. - Charlotte context that is not a skyline stock plate: Uptown, SouthPark or Ballantyne streetscape shot on the day.
Where it goes. The problem section and the FAQ on home.html; the checks, process and
"what happens after" sections on hr-audit.html; the service-area and findings sections on
charlotte.html.
Also unbuilt, not scored against any item
- Live scheduler. Item 31 passes on the reply-window branch. The HubSpot Meetings embed is
still a documented slot on all three pages, and the post-submit confirmation screen (which is
where the named person with a photo formally belongs) does not exist as a page. Needs the
HubSpot portal ID and meeting link, plus the hidden-field mapping for headcount, firm and
location, and the GA4
meeting_bookedevent on the postMessage callback. - I-9 penalty figure.
hr-audit.htmlcarries a slot asking for the current DHS per-form civil monetary penalty range with its Federal Register source and the date checked. It is deliberately not stated on the page. - Charlotte "how often" column. The findings table says "Most firms / Common" and carries a visible note that this is a pattern across engagements, not a published statistic. Replace with real counts once ten Charlotte audits are done.
- Footer resources. Five resource titles are listed with an "in production" tag and no links.
- Warm neutral. Item 37 asks for "white plus one warm-light neutral". There are now exactly
two backgrounds, but the neutral (
--ground#F7F8FB) is cool, not warm. Changing it would shift the whole brand world andindex.htmlwith it, so it was left alone. A one-line change if the founder wants it. - Mobile CTA cadence. Item 10 passes on desktop (largest gap 1776px against 1800px). At 390px, where everything stacks, the largest in-flow gaps are 2961 / 2407 / 2960px. The sticky bar carries the primary CTA and the phone from the moment the hero leaves the screen, which is what item 11 exists for, so the CTA is never actually off screen on mobile.
- Field data. LCP and CLS above are lab numbers on an emulated mid-range phone against a local server. Re-measure with real users, on the real host, after launch.
5. Files
- Pages:
mockups/home.html,mockups/hr-audit.html,mockups/charlotte.html - Stylesheet:
mock.css - Pre-fix copies kept alongside as
*.bak, andimg/founders-orig.jpg - Screenshots:
../preview/v5-home.png,v5-hr-audit.png,v5-charlotte.png(1440×2400) andv5-home-m.png,v5-hr-audit-m.png,v5-charlotte-m.png(390×844)