The personal site of Nick Poole — SEO Specialist (Baltimore, MD), with a web development and IT foundation. It doubles as supplemental material for a job search: the link sits on the resume, and every page answers one of three questions — what does he know, what can he do, and why is he in a separate category from other candidates.
A hand-built, multi-page static site focused on accessibility (WCAG 2.1 AA),
clean semantics, and a design system carried consistently across every page.
Its signature is a visible-schema motif: each content page pairs real
JSON-LD in the <head> with an on-page styled excerpt of that same data, so
the structured data is legible to both people and machines.
Built with:
- HTML (static pages in
public/) - Sass / SCSS (compiled and minified to
public/css/styles.css) - Vanilla JavaScript (theme toggle, mobile nav, two IntersectionObservers)
- Self-hosted fonts in
public/fonts/, and Remixicon paths inlined per page as an SVG<symbol>sprite — no third-party runtime requests at all - Deployed on Netlify (redirects in
public/_redirects, headers inpublic/_headers); the contact form posts to FormSubmit
| Route | Page |
|---|---|
/ |
Home — hub hero, routing cards, statement, schema, contact |
/expertise/seo/ |
SEO expertise — diagnosis, the build, governance, method |
/portfolio/ |
Portfolio — shipped work, the ownership stack |
/credentials/ |
Credentials — degrees & certs, what each one trained |
/resume/ |
On-domain resume (print-friendly) |
/colophon/ |
Colophon — stack, tokens, entity graph, the files for machines |
/accessibility/ |
Accessibility statement — conformance, scope, how to report |
/thank-you.html |
Post-contact-form confirmation (excluded from indexing) |
Nav: Home · SEO · Portfolio · Credentials · Resume · Contact. Colophon and the accessibility statement are reachable from the footer on every page; the main nav deliberately stays at five destinations.
- Tokens in
src/scss/config/_variables.scss; light/dark themes insrc/scss/theme/_theme.scss(body.dark-theme), persisted via localStorage. - Accent split:
--first-colorfor decorative borders/blocks,--accent-textfor accessible accent text. Section titles carry the offset accent block. - Signature patterns: offset-border cards, the schema panel, chapter rows, and the letter/icon tiles — all built on the same tokens.
- Each color token has a matching
--*-labelstring token declared beside it. The colophon swatches render those, so the documented value follows the theme and cannot drift from the declaration. --accent-textand--text-color-lightare tuned for AA against--body-color. On the darker--container-colorsurface they drop below 4.5:1, so new components put text on--body-colorwith a--black-colorborder, which is the existing card treatment.
npm install
npm run sass # watch src/scss/styles.scss -> public/css/styles.css
npm run build # one-shot compileBoth scripts emit compressed CSS, so the committed stylesheet is the same
whichever one produced it. The readable version is the Sass under src/scss.
Serve public/ with any static server for local preview.
There is no server-side build. Sass compiles locally, public/css/styles.css
is committed, and Netlify publishes public/ exactly as it lands in the repo.
- Heroes export at 1920px wide, portfolio cards at 640x425, social cards at 1200x630. Every content image ships as WebP; the OG cards stay PNG because not every platform scraper renders WebP.
- Budget: 60 KB for a card, 250 KB for a full-bleed hero. Nothing referenced on the site is over it. Cards currently land between 18 and 52 KB.
public/holds only what a page actually references. Masters and superseded JPG/PNG versions are not shipped; git history is the archive.- The hero headshot ships at two widths (200 and 400) behind
srcset, because it renders at 200 CSS px and only a 2x screen needs the larger file.
| File | Purpose |
|---|---|
public/robots.txt |
Open to all; declares the sitemap |
public/sitemap.xml |
The seven indexable routes with lastmod |
public/llms.txt |
Markdown brief for language models |
public/_redirects |
Netlify redirects |
public/_headers |
Pins /llms.txt to text/plain; year-long font cache |
/thank-you.html is kept out of the index with an on-page noindex rather than
a Disallow, so crawlers can actually read the directive.
“Make it resonate. Then refine.”
- Multi-page rebuild around the SEO-specialist identity
- Light/Dark mode with persistence
- Accessibility pass (WCAG 2.1 AA, 44px tap targets, heading order)
- Visible-schema motif + validated JSON-LD on every content page
- On-domain resume (print stylesheet) replacing the external PDF link
- Contact form with honeypot +
/thank-you.html - Sitemap, canonicals, robots.txt, per-page OG cards
- Single-source entity graph: one Person
@id, referenced by every page - Colophon and accessibility statement, plus
llms.txt - Image pipeline: every content image WebP and sized to its slot
- Consulting flip (parked): hero swap + CTA change when ready
Last full sweep: 20 August 2026, against the working tree.
| Check | Result |
|---|---|
| W3C Nu HTML validator, 8 pages | 0 errors, 0 warnings |
| W3C Jigsaw CSS validator | 0 errors |
| axe-core WCAG 2.1 A/AA, 8 pages x 2 themes | 0 violations |
| Titles / descriptions / canonicals | unique, self-referencing, in range |
| Open Graph + Twitter, all pages | complete |
Entity graph @id references |
no dangling refs, no type conflicts |
| Schema panels vs live JSON-LD | no drift |
| Internal links and in-page anchors | all resolve |
| External links | all target="_blank" + rel="noopener noreferrer" |
The CSS validator reports 32 warnings; all are inherent (CSS custom properties cannot be statically checked, and the vendor-prefixed scrollbar and autofill rules are deliberate).
[8/20/26 v3]
- content: colophon trims, mobile quote overflow, even card grids
- The statement blockquote overflowed small screens: its
max-width: 100%resolved against a shrink-wrapped inline-block anchor, so the cap did nothing. The anchor now carriesmax-width: 100%and the quote wraps - Rich Results tile removed from the colophon audit list — the site's Person/WebSite/WebPage graph is not rich-result-eligible, so the tool only ever reads as a failure
- Lighthouse-scores PENDING block and the dev banner removed; that item is dropped from the plan rather than left as a permanent placeholder
- Card copy balanced inside every grid (the Images card ran ~2x its siblings, the Sass card ~3x): Stack 276-302px, Design System 302-327px, Accessibility 276-306px, Inside Part 128-154px — no more tall card stretching short neighbours into empty space
- The statement blockquote overflowed small screens: its
[8/20/26 latest]
- perf: drop every third-party request; a11y, W3C, and lean-out sweep
- Google Fonts and the Remixicon CDN are gone. Both families are self-hosted
latin subsets in
public/fonts/; the 42 icons in use are inlined per page as an SVG<symbol>sprite. Removes two render-blocking stylesheets (~1,810 ms of critical path) and a 174 KB icon webfont - ScrollReveal (16.6 KB, on every page, animating three elements on one)
replaced by an IntersectionObserver reveal; scroll-spy moved off
offsetTop/offsetHeight, which was the flagged forced reflow - CSS minified: 61 KB -> 39 KB on disk, 14.4 KB -> 7.6 KB gzipped
- Dead CSS removed: the
home__*,about__*,services__*,projects__*template leftovers, plus.highlights/.hl,.visually-hidden,.font-heading,.d-none/.d-block, and a.this-class-does-nothing - 42 unreferenced images deleted: 25 MB -> 1.4 MB in
public/images - Trailing slashes stripped from 259 void-element start tags
- Contact input borders were 1.95:1 against the dark-theme panel; now 3.48:1 dark and 4.43:1 light, clearing WCAG 1.4.11
- Honeypot given a real
<label>; hero CTA repointed so the SEO card is no longer an adjacent duplicate link;width/heighton the last two images - Interlinking: portfolio, credentials, and the accessibility statement all gained contextual inbound links instead of footer-only routes
- Resume
.resume-wrapoverrode the container gutter — body copy ran to both screen edges on mobile - Seventh OG card wired up for
/accessibility/; the Rich Results tile on the colophon now says why an empty report is the correct result
- Google Fonts and the Remixicon CDN are gone. Both families are self-hosted
latin subsets in
[8/20/26 later]
-
perf: every content image re-exported to WebP, sized to its slot
- Portfolio page 3,414 KB -> 641 KB; all seven pages 4,817 KB -> 1,941 KB
- DAP screenshot 901 KB -> 27 KB, Next Metro 347 KB -> 22 KB, nav logo 18 KB -> 4 KB
- Heroes deliberately untouched; re-encoding them produced larger files
- Crops replicate what the CSS already did, so the render is unchanged
-
chore: full SEO, accessibility, and W3C sweep
- W3C Nu 0/0 across 8 pages after dropping a redundant
role="list" /aboutwas redirecting to/#about, an id that no longer exists; now/#arsenal- Added
/expertise->/expertise/seo/; that directory had no index - CAPTCHA disclosed as a known limitation on the accessibility statement
- W3C Nu 0/0 across 8 pages after dropping a redundant
[8/20/26]
- feat: colophon, accessibility statement, and a single-source entity graph
- New
/colophon/: the stack, live token swatches, the entity-graph diagram, the three files written for machines (peeled-cornerllms.txtcard), and audit links - New
/accessibility/: WCAG 2.1 AA target, scope, measures, feedback, dates - Person declared once as
https://nickpoole.dev/#nick-poole; every other page references it by@idinstead of redeclaring it. Added a WebSite node at#websitethat pages join viaisPartOf - Every schema panel rewritten to match its page's live JSON-LD
- Portfolio: added the
nickpoole.devand DAP Global cards, renamed "Enterprise Healthcare" to "Enterprise", extended the ItemList to 14 - Footer nav carries Colophon and Accessibility on all pages; main nav unchanged
- Breadcrumb links underlined (color alone was the only cue distinguishing them from the surrounding label)
- Outstanding content Nick owns is marked with visible
PENDINGblocks rather than filled in
- New
[8/17/26]
-
feat: adds Enterprise Healthcare row (CareFirst) and links the therapist site
-
fix: hides the nav close X on desktop; aligns the resume meta line
-
chore: a11y, SEO, semantic HTML, and W3C validation pass
- axe-core clean (WCAG 2.1 A/AA + best-practice) across 6 pages × 2 themes × 2 viewports
- W3C Nu HTML + Jigsaw CSS validators: 0 errors, 0 warnings
- Nav controls rebuilt as real
<button>s witharia-expanded, Escape-to-close, focus return - Closed mobile menu removed from the tab order; scrollable schema panels made keyboard reachable
- Theme class moved to
<html>and applied pre-paint (no light flash for dark-mode users) - Hero imagery re-encoded to WebP (12.4 MB → 594 KB); unused Google Fonts families dropped
- Type scale raised; micro sizes tokenised as
--micro-font-size/--micro-font-size-lg
[10/1/25]
- refactor: Removes CFBCBS
[9/22/25]
- feat: adds pregnancy and next metro cards
[7/29/25]
-
chore: adds meta description and head tags
-
chore: adds robots.txt
-
feat: polished home and about web copy content
-
fix: refactors icons to meet minimum tap target standards
-
fix: iOS icon and menu display issues
[7/28/25]
-
fix: stabilize nav logo layout and update remixicon CDN config
-
chore: adds redirects
-
chore: adds sitemap
-
feat: migrate contact form from Formspree to Netlify Forms
-
feat: Sets up Formspree contact form with honeypot spam check, localStorage flag for post-submit message, and graceful form reset on return
[7/22/25]
- feat: finalizes nav icon toggle, polished buttons, links, and site copy
[7/19/25]
- feat: adds images and logo
[5/5/25]
-
feat: adds certs section + polished copy to make it resonate
-
chore: reconfigures boxicons to font injection via CDN
[5/2/25]
- chore: adds project card images, reshuffled layout, and dropped in fresh copy
[4/24/25]
- feat: adds icons to About section and curated Services content
[4/20/25]
- chore: updates project section text, refine fonts, and swap icons for cleaner look
[4/19/25]
- refactor: improves semantic HTML and WCAG 2.1 AA accessibility
- Added skip link and main landmark region for screen reader navigation
- Refactored all headings to follow semantic hierarchy (h1 → h4)
- Added aria-labels to icon-only links (GitHub, LinkedIn, social icons)
- Marked decorative images and divs with aria-hidden="true"
- Updated nav toggle and theme button to be keyboard accessible
- Implemented rel="noopener noreferrer" for all target="_blank" links
- Removed title attributes and avoided unnecessary tooltip clutter
- Standardized aria-label tone to 3rd person ("Nick's profile") for clarity
- Ensured all form inputs have proper labels and required attributes
- Improved dark theme toggle state tracking with aria-pressed
- Cleaned up redundant JS and began exploring performance optimizations
[4/18/25]
-
Initial project setup with Sass, folder structure, and live compiler config
-
INIT
This project is licensed under the MIT License.