FLJ
FindLaborJobs.com — Internal Document
UX Design Specification · v1.0 · Pre-launch

The full UX treatment.
From first principles.

Personas, flows, wireframes and a developer handoff spec for the job board built for tradespeople — the master design document authored before a single line of production code is written.

At a glance
ProductFindLaborJobs.com
StagePre-build · spec phase
StackWP + Divi + SPA
UsersWorkers · Employers
Modes coveredFlow · Wireframe · Hi-Fi · Content · Blog · Spec
FrameworksJTBD · Empathy · Journey · Fogg · Hook · Nielsen · Atomic · Krug · Norman
00

Executive summary.

FindLaborJobs.com is a national job board for the 12 skilled trades, positioned as the trades-first alternative to white-collar career sites. Workers list and apply for free; employers pay a small per-contact fee to reach vetted candidates, with optional human vetting tiers and featured listings.

This document is the master design specification, authored before build, organised as the artefacts a full-service UX engagement ships: a Flow Strategist brief (who, why, what), a Wireframe Architect blueprint set (14 screens, mobile-first, grayscale), a Hi-Fi Prototype pass (key screens rendered in the product's real visual language), a Content & SEO Strategy (the editorial engine that drives organic growth), and a Spec Engineer handoff (tokens, atomic inventory, accessibility, Developer Deployment Code).

It defines every decision the implementation team is being asked to honour — and is intentionally written so a third-party developer, marketer, or future hire can pick it up and execute without a single clarifying meeting.

Five deliverables in this report
  1. 01Map the thinking. JTBD personas, empathy maps, behavioural analysis and a Mermaid flow that names every screen and every decision node.
  2. 02Validate the layout. Grayscale wireframes at 375 px with desktop expansion notes, Nielsen heuristics annotated inline.
  3. 03Show the real thing. Key screens rendered hi-fi in the product's actual colour, type and imagery language — what a stakeholder or investor sees.
  4. 04Plan the growth engine. A content and SEO strategy that turns the site's information architecture into a compounding organic-traffic asset.
  5. 05Hand it off. Atomic Design inventory, design tokens, component states, A11y checklist and copy-paste Deployment Code.
Audience

Tom (owner/operator), next-session designers & developers, contracted reviewers, and any future hire.

Method

Stakeholder brief + competitor scan (Indeed, ZipRecruiter, niche trades boards) + cross-reference of all eight UX Designer references. Deep mode.

Confidence

[VALIDATED] on live behaviour, DB schema, business model. [INFERRED] on user motivations (no formal research). [ASSUMED] tagged where applicable.

Not in scope

Visual brand refresh, paid-marketing creative, content / SEO calendar, and PHP/JS implementation details (those belong in the developer handoff that follows).

Mode 01 · Logic phase

Flow strategist.

Frameworks loaded
USER-RESEARCH · BEHAVIORAL-DESIGN · UX-FOUNDATIONS · BUSINESS-CONTEXT

Before any screen exists, this section answers who the product is for, what job they hire it to do, and which behavioural levers the experience pulls. The output is a problem statement and a master flowchart that every wireframe in Mode 2 traces back to.

1.1

Strategy check (Lean Canvas, 1-screen).

Business context is well-defined from the founder brief, so the canvas is filled rather than diagnosed. [VALIDATED] with the product owner.

Problem

General job boards bury blue-collar postings under tech and office roles. Workers waste hours filtering. Local contractors can't find vetted help fast.

Solution

Trade-first listings (12 trades × 50 states). Free for workers. Pay-per-contact for employers. Optional human vetting.

Unique value

The Job Board Built for Trades. Not Office Workers.

Aggregated supply (JSearch + Adzuna feeds) avoids the cold-start that kills most niche marketplaces — critical-mass listing volume is available from day one.

Unfair advantage

Solo-owner unit economics. SEO moat: programmatic landing pages for every trade × state combo (~600 URLs in GSC).

Channels

Programmatic SEO landing pages (trade × state, ~600 URLs), weekly blog (3 posts / week cadence), Reddit Ads on trade subreddits, word of mouth.

Segments

Skilled tradesperson (worker). Hiring contractor / GC office manager (employer).

Key metrics

Worker registrations, employer contact-unlocks, vetting purchases, organic landing-page traffic.

Cost structure

RapidAPI / Adzuna feeds, WP hosting, Reddit ad spend, occasional dev contractor.

Revenue

$5 contact unlock · $5 featured · $29 / $149 mo plans · $29 / $49 / $149 vetting tiers.

// BUSINESS-CONTEXT.md § Lean Canvas (Maurya, 2010). Filled in deep mode.

1.2

JTBD personas — two-sided marketplace.

Per Christensen, archetypes are framed by the job hired, not demographics. Two archetypes drive the marketplace; a third (Admin) is operational and covered briefly. [INFERRED] from founder domain knowledge and trade-subreddit reading; recommended to validate with 5–8 user interviews using the JTBD switch-interview method (USER-RESEARCH § 1.6) before build.

Archetype A · Supply side
"Marcus" — The mobile journeyman.
WORKER
Context

When: Current job is wrapping up, weather slowed the site, or a buddy mentioned better pay 90 minutes away.
Where: On a phone, in a truck cab, on a lunch break. Spotty signal. One thumb.
Frequency: 2–6× per year actively, weekly browse-check in between.

Job statement

When my current gig is winding down, I want to scan trade-specific openings in my state without sifting through office jobs, so I can line up the next paycheck before this one ends.

Needs hierarchy
  • Functional: Find paying openings near me, in my trade, this week.
  • Emotional: Feel respected — not lectured by a "career platform."
  • Social: Be seen as a working pro by the GCs who'll hire him.
Current state

Today: Indeed (too broad), Facebook trade groups (gatekept), word of mouth.
Pain: Office-job spam, "easy apply" black holes, recruiters with no idea what a journeyman card is.
Workarounds: Texts buddies; calls union hall; drives by job sites looking for trailers.

Success criteria

Phone rings within 72 hours of applying. Pay rate visible before he applies. Drive time under one hour.

Constraints

Time: 5-minute window before the next pour.
Skills: Confident on phone, allergic to forms.
Access: Mid-tier Android, data-capped plan, gloves on half the time.

Archetype B · Demand side
"Tony" — The short-handed GC.
EMPLOYER
Context

When: Crew member quit Friday. New project starts Monday. The job is bid, not budgeted for delays.
Where: Desk in a job-trailer or kitchen table, laptop. Sometimes phone.
Frequency: Cyclical — 3–10× per year, clustered around project starts.

Job statement

When I lose a crew member or land a new project, I want to talk to a real, qualified tradesperson today, so I can keep the schedule and not eat liquidated damages on Monday.

Needs hierarchy
  • Functional: A short-list of contactable, vetted, in-trade workers.
  • Emotional: Confidence the person who picks up isn't a no-show.
  • Social: Look organised to the project owner who's watching.
Current state

Today: ZipRecruiter ($$$), staffing agencies (markup), referrals (slow).
Pain: Subscription bait-and-switch, fake resumés, ghosting.
Workarounds: Pays day-labor cash; poaches from rival jobsites.

Success criteria

Worker on site within a week. Spend under $200. No hidden subscriptions.

Constraints

Money: Per-hire budget, not retainer. Trust: Won't pay for a "lead" without seeing something concrete. Time: Will not do a sales call.

Archetype C · Operational — Tom (admin)
Solo owner-operator. Hires the system to run the marketplace while he writes blog posts and tunes Reddit ads. Needs: toggle pricing modes, fix bad aggregator data, view jobs by ID, manage vetting requests. Sole admin user. Constraints: cannot write Python, edits PHP via FTP. Wireframes 2.14 cover this path.
1.3

Empathy maps.

Per Gray (XPLANE, 2010). One map per archetype. The gap between Says and Does is where most marketplace design insights live.

Marcus · the mobile journeyman
WORKER
Says
  • "I'm not paying to apply for a job."
  • "Just put the pay rate on it."
  • "If they want me, they'll call."
Thinks
  • This site looks built by a recruiter, not a worker.
  • If I have to upload my licence, this is a scam.
  • One-hour drive max, two is for emergencies.
Does
  • Skims 8–12 cards in 90 seconds, bails on long pages.
  • Calls before applying when a phone number is visible.
  • Saves jobs to "look later" but rarely returns.
Feels
  • Tired — long day, small screen.
  • Skeptical — burned by Indeed inbox spam.
  • Pragmatic — money is the metric.
Pains
  • Office jobs cluttering trade searches
  • Forms that demand a resume PDF
  • "Sign up to see pay rate" gates
Gains
  • Pay-rate visible on card
  • Phone call from a real foreman
  • Saved profile that reuses on apply
Key insight

Marcus will trade more profile detail for fewer office-job impostors. Specificity is the value, not features.

Tony · the short-handed GC
EMPLOYER
Says
  • "I just need someone who shows up."
  • "How much is it to actually talk to them?"
  • "No, I don't want a monthly plan."
Thinks
  • If I'm paying, this person better be real.
  • Vetting is worth it on a $30K bid, not a $300 patch.
  • If I unlock and they ghost, I'm done with this site.
Does
  • Sorts candidates by vetted first, then closest.
  • Reads photos and resume before name.
  • Buys vetting only on key roles.
Feels
  • Squeezed — schedule pressure from the GC above.
  • Wary — burned by paid resume-databases.
  • Decisive — once he sees a fit, he calls.
Pains
  • "Premium plan required" walls
  • Hidden contact info after payment
  • Stale profiles, candidates not really looking
Gains
  • Phone number revealed instantly post-payment
  • Vetting badge meaning something concrete
  • One-click re-list of a popular job
Key insight

Tony is willing to pay per outcome (each contact) but allergic to pay per access (subscription). Pricing model is the product.

1.4

Problem statements.

Worker · supply

Marcus needs a way to see real trade openings in his state on his phone without paying, signing up, or filtering past office jobs — because every minute spent searching is a minute not earning.

Employer · demand

Tony needs a way to reach a vetted tradesperson within hours, paying only for the contact he uses — because subscription job boards are over-priced for his cadence and under-trusted for his trades.

1.5

Behavioural analysis.

Applied stack: Fogg B = MAP for diagnosing each key action, Eyal Hook Model for engagement loops, Thaler & Sunstein for the few defensible nudges. Cialdini patterns called out where used.

a · Fogg B = MAP per key action

ActionMotivationAbility barrierPrompt typeDesign response
Worker registersAnticipation (next paycheck)Form length, social deviance ("am I on a corporate platform?")Spark — value-prop hero, Reddit ad3-field signup, then progressive profile. Trade-coded language.
Worker appliesAnticipation + Pleasure (close to outcome)Effort — re-typing on a phoneSignal — Apply button on detailReuse profile fields, optional resume re-upload, single-screen form.
Employer posts a jobPain avoidance (project deadline)Mental effort — writing the postFacilitator — AI job description writerAnthropic-generated draft, all fields pre-filled, document upload optional.
Employer unlocks contactPain avoidance + Pleasure (hire close at hand)Money — $5; Time — paypal redirectSignal — locked contact strip on profileReveal everything except contact. One CTA. Receipt + redirect back to profile.
Employer buys vettingAnticipation (low-risk hire)Money — $29–$149; Trust in deliverableFacilitator — tier comparison on profileThree tiers visible at decision point, report sample, "always active" caption.

// BEHAVIORAL-DESIGN § 1 (Fogg, 2009 / "Tiny Habits" 2020)

b · Hook cycle (Eyal, 2014)

Trigger

External: Reddit ad in r/Construction, SEO landing for "electrician jobs texas 2026".
Internal: "Job's ending." (worker) · "Crew is short." (employer)

Action

Single-tap on a job card. Single CTA on hero. Apply / Unlock buttons designed as the only obvious action above the fold.

Variable reward

Hunt: fresh jobs every 30 min (cron). Tribe: employer call-backs. Self: profile completion %.

Investment

Profile fields, photos, resume, saved jobs. Each one increases switching cost and quality of future hunt-rewards.

// BEHAVIORAL-DESIGN § 2. Manipulation matrix: Facilitator quadrant — engagement design is ethically grounded because the product genuinely improves both users' lives.

c · Nudge inventory

NudgeWherePurposeEthical check
Default trade = "All"Browse jobsReduce empty-state on landing✓ Easily overridden
Smart default: state from IPBrowse / SEO landingLocal relevance, System 1✓ Editable, visible
Social proof: "17,983 jobs"Home hero, footerMarketplace liquidity signal✓ Real count (Cialdini)
Scarcity: "Expires in 5 days"Job card, detailReal expiry from DB✓ Real, not fabricated
Progress: "Profile 60% complete"Seeker dashboardEndowed-progress (Nunes/Dreze)✓ Honest %
Anchoring: $149 tier firstVetting modalMake $29 feel modest⚠ Test post-purchase satisfaction
Loss framing: "Don't lose your spot"Not usedAvoid; tradespeople distrust urgency copy

// BEHAVIORAL-DESIGN § 3 (Thaler & Sunstein) + UX-PATTERNS § 3 (Cialdini)

d · Dual-process (Kahneman) targeting

System 1 — fast

Job browse, card scanning, hero CTA, trade-icon recognition, blog reading. Design: large type, familiar conventions, high-contrast trade chips.

System 2 — slow

Vetting tier choice, post-a-job form, profile completion. Design: labels + helper text, comparison tables, autosave, no time pressure.

1.6

Journey maps.

Two journeys cover ~80% of the marketplace volume. Phase library per USER-RESEARCH § 3.4. Emotional curve is the design priority signal: invest where the dip is steepest.

Journey 01
Worker — from Reddit ad to first call-back.
Marcus · 0–72 hours
Phase Aware Browse Register Apply Wait Call-back
Touchpoint Reddit ad, Google "[trade] jobs [state]" /#/jobs /#/register /#/apply?id= Inbox / phone Phone call
Action Tap ad on phone Filter trade + state, scroll cards Pick role = Worker, 3 fields Tap Apply, confirm Refreshes occasionally Answers, agrees to interview
Thought "Real trades site?" "Are these actual jobs near me?" "Why do they need my photo?" "Should be quick…" "They never call back." "OK, this works."
Emotion Curious · 3/5 Hopeful · 4/5 Wary · 2/5 Determined · 3/5 Doubtful · 2/5 Relieved · 5/5
Pain Pay-rate sometimes missing Resume upload feels heavy Field count uncertainty No status / SMS
Opportunity Pin Reddit moderator AMA Default state by geo-IP; show "pay TBD" honestly Defer resume to post-signup Progress bar (1 of 2) "Employer viewed your application" event email Encourage rate review
Emotional curve
High │ ╭───╮ ╭──── │ ╱ ╲ ╱ │ ╭────────╯ ╰─╮ ╱ │ ╱ ╲ ╱ Low │─╯ ╰─────────────────────────╯ └────────────────────────────────────────────────────────── Aware Browse Register Apply Wait Call-back
Biggest valley: Wait phase — 24–72 h of silence corrodes trust. Quick win: "Application received, the employer has been notified" toast + email. Strategic investment: employer-side "your applicant" weekly digest, closing the loop without SMS infrastructure.
Journey 02
Employer — from search to a confirmed phone call.
Tony · 0–48 hours
PhaseAwareSearchEvaluatePayContactHire
TouchpointSEO landing for "find a welder [state]"/#/search-candidatesWorker profile (locked)PayPal redirectWorker profile (unlocked)Phone, jobsite
ActionClicks "Hire a [trade]"Filters trade + state, sorts vetted-firstReads photos, resume, work history$5 to TAGrafx, returns to siteCalls, texts, emailsBooks worker
Thought"Specialised, hmm.""Plenty of options.""Real person?""$5 only? Sure.""Phone is live.""Good crew."
EmotionSkeptical · 3/5Engaged · 4/5Discerning · 3/5Cautious · 2/5Pleased · 4/5Relieved · 5/5
Pain"Are these stale?"Locked contact stripPayPal exit + manual reconcileNone if worker answers
OpportunityTrade-specific landing pages (done)"Last seen" badge on profileSample vetting report previewStripe webhook → auto-unlock (parked)"Did they pick up?" 1-tap NPSRe-list / vet again CTA
Critical moment of truth
The reveal between Pay and Contact. Today the manual PayPal flow inserts a 5–60 min delay (admin must mark status = 'paid'). This is the single highest-leverage technical investment on the roadmap — and the strongest argument for prioritising the Stripe / PayPal webhook work that's currently parked.
1.7

Information architecture.

Two surfaces: a hash-routed SPA for logged-in app behaviour, and a server-rendered SEO layer for discovery. They co-exist on the same WordPress and are intentionally distinct so Divi/JS conflicts can't break either one.

A · SPA (hash routes)
/#/home              Hero · trades · how-it-works · blog
/#/jobs              Filterable list (1,000 init, fallback fetch)
/#/job-detail?id=    Detail · apply CTA · save
/#/apply?id=         Single-screen application
/#/about             Pricing & how-it-works
/#/register          Role chooser → worker | employer
/#/login             Async login, async logout (WPS guard)
/#/profile           Seeker dashboard
/#/employer-dashboard Employer home
/#/post-job          Post / edit a job
/#/search-candidates Candidate browser
/#/worker-profile?id=Worker detail (locked / unlocked)
/#/saved-jobs
/#/applications
/#/admin             Admin shortcuts
/#/blog              Blog index (delegates to WP)
B · Server-rendered (SEO)
/                              SPA root
/jobs/{trade}/                 Trade landing (12)
/jobs/{state}/                 State landing (50)
/jobs/{trade}/{state}/         Trade × state (600+)
/job-directory/                HTML sitemap, all combos
/sitemap-jobs.xml              XML sitemap (~662 URLs)
/sitemap-jobs/                 Non-extension fallback
/blog/                         WP posts page
/blog/{slug}/                  WP post
/about, /contact, …            Divi-managed
/flj-admin-2026                WP admin (WPS Hide Login)

// Architecture corresponds to Garrett's 5-planes — surface (Divi + SPA), skeleton (hash + REST), structure (role-gated routes), scope (pricing + vetting features), strategy (two-sided marketplace).

1.8

Master flowchart.

Double-Diamond Deliver output. Entry points (Reddit / SEO / direct), the two main loops (apply, unlock), all decision nodes (auth, role, unlock fee toggle, vetting tier), and success / failure terminals. Each rounded node maps 1:1 to a wireframe in §2.

flowchart TD
    %% Entries
    R([Reddit ad]):::ent --> H
    G([Google / SEO]):::ent --> L[/SEO landing/]
    D([Direct]):::ent --> H[Home]
    L -->|"CTA: View jobs"| H

    %% Public browse
    H --> J[Browse jobs]
    J -->|filters| J
    J --> JD[Job detail]
    JD -->|Save| AUTH1{Logged in?}
    JD -->|Apply| AUTH1
    AUTH1 -- No --> RG[Register]
    AUTH1 -- Yes --> APP[Apply form]
    RG --> ROLE{Role?}
    ROLE -- Worker --> WP1[Seeker profile setup]
    ROLE -- Employer --> EP1[Employer profile setup]
    WP1 --> APP

    %% Worker apply loop
    APP --> APPOK[/Applied · toast/]:::ok
    APPOK --> DASH_S[Seeker dashboard]
    DASH_S -->|Saved jobs| J
    DASH_S -->|Edit profile| PROF_S[Worker profile editor]

    %% Employer demand loop
    EP1 --> DASH_E[Employer dashboard]
    DASH_E --> POST[Post a job]
    POST -->|AI assist| POST
    POST --> POSTOK[/Job live/]:::ok
    DASH_E --> SC[Search candidates]
    SC -->|Filters| SC
    SC --> WPROF[Worker profile · LOCKED]
    WPROF --> FEE{Contact unlock fee?}
    FEE -- ON --> PAY[PayPal $5]
    FEE -- OFF --> UNLOCKED[Worker profile · UNLOCKED]
    PAY --> ADMIN_REC{Admin marks paid}
    ADMIN_REC --> UNLOCKED
    UNLOCKED --> VET{Buy vetting?}
    VET -- No --> CALL([Call / text / hire]):::end_
    VET -- Yes --> VTIER[Choose tier $29/$49/$149]
    VTIER --> PAY2[PayPal]
    PAY2 --> REPORT[/Vetting report PDF/]:::ok
    REPORT --> CALL

    %% Admin
    SET([Admin · Settings]):::ent --> TOGGLE[Toggle: Contact Unlock Fee]
    TOGGLE --> FEE

    %% Failures
    AUTH1 -- "session expired" --> LOGIN[Login]
    LOGIN --> AUTH1

    classDef ent fill:#fff,stroke:#1a1a1a,stroke-width:2px;
    classDef ok fill:#f1ede4,stroke:#1a1a1a,stroke-width:2px,color:#1a1a1a;
    classDef end_ fill:#efece5,stroke:#1a1a1a,stroke-width:2px;
          

// UX-FOUNDATIONS § 3.1 (Design Council Double Diamond). Auto-rendered with Mermaid 11.

Mode 02 · Visual phase

Wireframe architect.

Frameworks loaded
UX-PATTERNS · NIELSENS-HEURISTICS · DESIGN-PRINCIPLES

14 screens, mobile-first at 375 px, strict grayscale (slate-100 → slate-900), borders define hierarchy, no shadows, no real imagery. Each frame is annotated with pattern callouts in monospace and flagged against Nielsen's 10. Microcopy intent is in [brackets]; final copy is finalised in Mode 3.

Wireframe legend
NAV persistent / contextual nav
FORM input fields, validation
ACTION primary & secondary CTAs
FEEDBACK toasts, banners, loading
CONTENT page sections, copy slots
SOCIAL proof, testimonials, counts
SCARCITY stock / time limits
COMMIT progress / micro-commit
ERROR inline validation
2.1

Home — SPA landing.

/#/home · page-jll-app.php · pages-public.js · renderHome()

PUBLIC SYSTEM 1 SCAN

Purpose. Within 5 seconds, a worker on a phone should understand "this is for me" and tap into Browse Jobs; an employer should see "Hire" path and pricing. Hero, trade chips, social proof count, blog teaser, footer.

9:41findlaborjobs.com
[LOGO] FLJ
[EYEBROW · Trade + state badge from IP]

[HEADLINE — value prop, 6–9 words]

[Subhead · 1 line of clarification]

★ Join [17,000+] tradespeople hiring this week

[SECTION TITLE · "Pick your trade"]
[Electrical]
[Plumbing]
[HVAC]
[Welding]
[Carpentry]
[Roofing]
[Masonry]
[Painting]
[Drywall]
[Flooring]
[General]
[Heavy Equip]
[SECTION · "How it works"]
  1. 01.[Step copy · free for workers]
  2. 02.[Step copy · search by trade + state]
  3. 03.[Step copy · employer pays only to talk]
[SECTION · Latest from blog · 4 posts]
[FEATURED POST IMAGE]
[Featured title — 2 lines]
[Post title]
[Post title]
[Post title]
[FOOTER — anchors not buttons]
Browse jobsPost a jobAbout / pricingBlogSitemapContact
© FindLaborJobs · [Reddit pixel fires PageVisit]
NAV — Persistent header. Logo left + hamburger right on mobile. Desktop expands to 5 anchors max (Krug § 1.1).
ACTION — Dual primary CTAs. Both at the same hierarchy because the two-sided marketplace can't pick one. Worker-side gets visual weight (filled). Pattern: Action + Benefit (UX-PATTERNS § 1.1).
SOCIAL — Live count. "Join 17,000+" binds to the running jobs total from the SPA store. Cialdini Social Proof. Never round upward; never invent a number.
CONTENT — Trade grid. 12 chips in 3-col phone / 6-col desk. Each links to /jobs/{trade}/ server-rendered landing — System 1 scan path.
CONTENT — Blog teaser. Engineering constraint: cards must be divs with onclick, not <a>. The site's global CSS overrides anchor backgrounds, so anchor cards render without their surface fill.
FEEDBACK — Reddit pixel. PageVisit on every load. SignUp on register success.
Desktop expansion (≥ 768 px)
  • Header: logo · Browse · Hire · Pricing · Blog · Login · Sign Up (anchor-tags only, never <button>).
  • Hero: 2-column with placeholder portrait (slate-300 box "[WORKER PHOTO]") right.
  • Trade grid: 6 columns × 2 rows.
  • Blog: featured-left + 3 sidebar-right (matches current implementation).
Heuristics check
  • H1 Visibility: ✓ jobs count is honest live data
  • H2 Match real world: ✓ "trade" not "industry"
  • H6 Recognition: ✓ trade chips use familiar trade names
  • H8 Minimalist: ⚠ resist adding a fourth hero CTA — already on the line
2.2

Browse jobs.

/#/jobs · initial fetch 1,000 · fallback GET /jobs/{id}

PUBLIC OR AUTH

Purpose. Marcus scans 8–12 cards in 90 seconds. Trade + state filters above the fold; card density tuned for thumb scroll. Empty / loading / "no results" states all spec'd.

[FLJ] Browse Jobs[← back]
[FILTER BAR — sticky on scroll]
[Result count] [17,983 jobs · 142 new this week]
[Trade · Electrical] [Posted · 2d ago]
[Job title — Master Electrician]
[Employer · ACME Construction]
[Newark, NJ · $42–$58/hr]
[★ Featured] [✓ Pay listed]
[Trade · Plumbing][5d]
[Service Plumber — Residential]
[Aqua Brothers LLC]
[Jersey City, NJ · Pay TBD]
[⏱ Expires in 5d]
[Trade · Welding][1d]
[MIG/TIG — Heavy Fab]
[Riverline Iron Works]
[Camden, NJ · $30/hr + OT]
[Skeleton loader · 3 rows when fetching]
NAV — Sticky filter bar. Stays visible on scroll. Trade + state are the only two filters that matter for System 1; everything else is power-user noise (Krug 3rd law: omit needless words).
FORM — Smart default. State pre-selected by IP geo when SPA boots. Persisted to localStorage so refresh keeps it.
CONTENT — Card pattern. Trade (eyebrow), title, employer, city + pay-or-"Pay TBD", scarcity strip (expires / featured / pay-listed). Pay-rate honesty matters more than always showing a number.
SCARCITY — "Expires in 5d". Pulled from jll_jobs.expires_at. Real, not theatrical.
LOADING — Skeleton, not spinner. 3-row gray skeleton when initial 1,000 hasn't returned. Per Nielsen H1.
Empty & error states
No results for filters:
  Title:  "No [trade] jobs in [state] right now"
  Body:   "Pull-up to refresh. We're adding ~140 jobs a week."
  Action: "Clear filters" + "Notify me when posted"
Network error:
  Toast:  "Couldn't load jobs. Try again."
  Retry:  Auto after 3s, 5s, then manual.
Aggregator stale (> 24 h):
  Banner: "Showing cached jobs."
Desktop expansion
  • Two-column: filter sidebar (240 px) + card list. Map preview on right (future).
  • Cards keep single-column max-w-2xl — easier scan than grid for trade work.
2.3

Job detail.

/#/job-detail?id= · falls back to GET /jobs/{id} if not in SPA cache

PUBLIC OR AUTH
[← Back to jobs][Save ♡] [Share]
[Trade · Electrical]

[Master Electrician — Commercial fit-out]

[ACME Construction] · [Newark, NJ]
[$42–$58/hr · Full-time]
[★ Featured][⏱ 5d left]
[SECTION · Description]

[Lorem ipsum dolor sit amet, 4–6 lines of job description. AI-generated when employer used the assistant.]

[SECTION · Requirements]
  • [Master licence required]
  • [5+ years commercial]
  • [OSHA 30]
[SECTION · Attached document]
[📄 ScopeOfWork.pdf]

[Free to apply · Never pay to apply]

NAV — Back affordance. Browser back is unreliable inside hash routing; explicit back button uses history.back() when referrer = jobs list, else navigates to /#/jobs.
ACTION — Sticky apply. 56 px tall, slate-800 fill, always above the fold on mobile (Fitts' law). Disappears only when keyboard is open.
SCARCITY — Real expiry. Aggregator bumps re-seen jobs +30 d; 3-day grace on cleanup.
CONTENT — Document slot. document_path from jll_jobs. View link opens in new tab.
FEEDBACK — Apply state. If already applied, CTA swaps to "Applied — view status" (Nielsen H1).
Authenticated variants
  • Anon: Apply → Register modal → Apply.
  • Worker, applied: CTA = "✓ Applied · view status".
  • Employer: CTA = "Edit this job" if owner; otherwise hidden.
2.4

Apply.

/#/apply?id= · pages-public.js · renderApply()

AUTH · WORKER
[← Job detail]
[CONTEXT — applying to:]

[Master Electrician — ACME · Newark NJ]

[FORM — pre-filled from profile, editable]
[Drag PDF / DOC · or tap]
FORM — Single screen. 5 fields, 4 of them pre-filled from profile. The only mandatory input is the tap on Send.
FORM — Inline validation on blur. Phone format hint "(NJ) 555-1234". Email pattern. No async checks — would block a thumb tap.
COMMIT — Save back to profile. Checked by default the second time onward; uncheck if user edited cover note (so the standing version isn't overwritten).
FEEDBACK — Success. Toast: "Application sent — employer notified." Then redirect to /#/applications. jllRedditEvent('Lead') fires here.
Error states (Nielsen H9)
Phone format wrong   "Enter a 10-digit phone, e.g. 555-123-4567"
Email format wrong   "We can't reach you at this address. Try again?"
File > 5 MB          "PDF is too big — keep it under 5 MB"
Server 500           "Couldn't send. We'll retry — keep this tab open."
2.5

Register — role chooser then split flow.

/#/register · pages-auth.js · renderRegister()

PUBLIC

Two-step: (1) pick role, (2) minimum-viable form per role. Reddit pixel SignUp splits into SeekerSignUp / EmployerSignUp.

[Step 1 of 2]

[What brings you here?]

[Subhead · we'll customize the rest]

[Have an account? Log in]

[Step 2 · Worker]

[Create your worker profile]

[Tradespeople list free. No credit card.]

[By signing up you agree to terms · we never sell data]

[Step 2 · Employer]

[Set up your hiring account]

[No subscription. Pay $5 per contact you unlock.]

[Post your first job free for 30 days]

COMMIT — Two-step (Step 1 → Step 2). Role choice first applies Endowed Progress effect; the second screen pre-fills email if entered on step 1.
FORM — Progressive profiling. Only 5 fields per side here; photo, resume, certifications collected later in dashboard (Fogg ability barrier reduction).
FEEDBACK — Reddit pixel. On success: jllRedditEvent('SignUp', {type:'Seeker'|'Employer', email:<hash>}).
ACTION — Microcopy difference. Worker: "Always free." Employer: "Pay only per contact." Each addresses the dominant pain in that archetype's empathy map.
2.6

Login.

/#/login · async fetch · 1200 ms cookie delay · then redirect with ?nocache=…

PUBLIC

[Welcome back.]

[Sign in to see new jobs in your trade.]

[Forgot password? · Create account]

[STATE · while pending] [Spinner + "Signing you in…" + disabled button]
FORM — Async fetch, not sync XHR. Engineering rule: 1.2 s delay before redirect for the auth cookie to settle, then window.location.replace(siteUrl + '?nocache=' + Date.now() + '#/route') to bypass page caching, then strip nocache with history.replaceState.
NAV — Post-login routing. seeker → /#/profile · employer → /#/employer-dashboard · admin → /#/admin.
ERROR — Bad credentials (H9). "That email and password combination didn't work. Try again or reset password." Never disclose whether the email exists.
NAV — Logout. Uses CFG.logoutUrl + '?action=logout&_wpnonce='. Never /wp-login.php — WPS Hide Login blocks that endpoint by design.
2.7

Seeker dashboard / my profile.

/#/profile · pages-dashboard.js · renderSeekerDashboard()

AUTH · WORKER
[Logged in as Marcus][Log out]
[Profile completeness][60%]

[Add 2 photos and a resume to unlock employer messages.]

[CARD · APPLICATIONS]
[3 active · 1 new since last visit]
[CARD · SAVED JOBS]
[7 saved]
[CARD · VETTING STATUS]
[Not vetted yet — verified workers get 4× more contacts]
[CARD · PROFILE]
[Trade · Plumbing] [Location · Newark NJ] [Years · 8]
[PHOTO 1]
[PHOTO 2]
[+ Add]
COMMIT — Endowed progress. Bar starts at 30% post-signup (name, email, trade). Each photo +10%, resume +20%. Per Nunes & Dreze.
CONTENT — Card priority order. Active applications (Hunt reward) first, saved jobs second, vetting upsell third, profile editor last. Order reflects expected return-visit job-to-be-done.
SOCIAL — Vetting upsell. "Verified workers get 4× more contacts." Honest if backed by data; remove if not.
HOOK — Investment loop. Every additional photo / resume increases switching cost and load future Tribe-reward (employer messages).
2.8

Employer dashboard.

/#/employer-dashboard · pages-dashboard.js · renderEmployerDashboard()

AUTH · EMPLOYER
[ACME Construction · Tony][Log out]
[Applications]
[28]
[Unlocked]
[6]
[Vetted hires]
[2]
[Spent · MTD]
[$78]
[ACTIVE JOBS][Sort ▾ newest]
[Master Electrician · Newark][14 applicants]
[Apprentice plumber · Jersey City][8 applicants]
[Welder · Camden · ★ Featured][6 applicants]
ACTION — Three primary CTAs at top. Mirrors Tony's three top tasks: post, search, manage. Filled = highest expected frequency.
CONTENT — KPI strip. Honesty over flattery: show $ spent so he can budget. Pulls from jll_worker_unlocks + jll_vetting_requests.
NAV — Manage row. Per-job: applicants count + open detail. Avoids hidden navigation (H7 flexibility).
FEEDBACK — Empty. First-time: full-bleed empty state with "Post your first job — 30 days free."
2.9

Search candidates.

/#/search-candidates · ORDER BY is_demo DESC, then vetted DESC

AUTH · EMPLOYER
[FILTERS]
[PHOTO]
[Alex Rivera][✓ Vetted]
[Electrical · Newark, NJ · 12 yrs]
[Last active · 2d]
[PHOTO]
[Jordan Kim][unvetted]
[Plumbing · Jersey City, NJ · 5 yrs]
[Last active · 6h]
[PHOTO]
[D. Patel][✓ Vetted]
[HVAC · Edison, NJ · 9 yrs]
SOCIAL — Vetted badge. Solid border = vetted. Engineering note: the is_vetted column returns from MySQL as a string ("0"/"1"), so callers must parseInt() before truth-testing. Dashed = unvetted.
NUDGE — Demo seekers pinned. Alex (vetted) + Jordan (unvetted) always sort top via ORDER BY is_demo DESC. Lets a first-time employer feel marketplace density. Honest because they're labelled — never hide demo state from admins.
ACTION — Two CTA states. Vetted & demo Alex = "View Profile" (always unlocked). Others = "$5 to contact" — sets price expectation upfront (anchoring).
SCARCITY — "Last active". Reduces risk of contacting a ghost profile.
2.10

Worker profile — the unlock moment.

/#/worker-profile?id= · jll_worker_unlocks.status = 'paid' gates everything

KEY SCREENAUTH · EMPLOYER

The marketplace's single most important screen. Two states (Locked / Unlocked) drive 100% of paying-employer revenue. Plus a third (Free mode, admin toggle off) for the public-relations / demo configuration.

State A · LOCKED · fee ON
[PHOTO]
[J. Kim]
[Plumbing · Newark, NJ · 5 yrs]
[Last active · 6h]
[CONTACT — locked]
●●●-●●●-●●●●
●●●●●@●●●●●●●.●●●

[One-time · no subscription]

[SECTION · Trade history]

[5 years residential service plumbing, NJ master in progress]

[SECTION · Photos]
[SECTION · Resume]
[📄 jordan_kim_resume.pdf]
[UPSELL · Vetting · always available]
[Basic]
$29
[Std]
$49
[Premium]
$149
State B · UNLOCKED · paid
[PHOTO]
[Jordan Kim]
[Plumbing · Newark, NJ · 5 yrs]
[CONTACT — unlocked]
📞 [(973) 555-0142] [jordan.k@email…]
[Same profile body as locked state]
[+ "Did they pick up?" 1-tap NPS at +24 h]
[FEEDBACK · "Unlocked May 12, 2026 · $5 charged · receipt sent"]
State C · FREE MODE · admin toggle
[Jordan Kim]
[Plumbing · Newark NJ]
[Contact unlocked · free mode]
📞 [(973) 555-0142]
[jordan.k@email…]
[All seekers identical — Alex & Jordan both show the same green strip when admin toggles jll_contact_unlock_free = 1]
NUDGE — Reveal everything except contact. Per BJ Fogg: maximise motivation (proof of fit) before the ability cost (PayPal). Photos, work history, resume all visible while locked.
ACTION — Single CTA per state. Locked → one button "Unlock contact — $5." Anchoring: price visible on the button, not in fine print (Cialdini · anchoring).
FEEDBACK — Receipt & timestamp. Visible amber footer confirms unlock event. Reduces "did it work?" support requests.
SAFETY — Free-mode parity. Implementation note: the $contact_free flag must be threaded through any array_map closure that reads workers (PHP closures need it in use()); otherwise free-mode silently fails to unlock. Free-mode renders both demo seekers identically with the green strip — a single admin toggle flips the whole site for PR demos.
HOOK — Vetting upsell. Always-visible at the bottom; appears regardless of unlock toggle. Three tiers anchor on $49 (middle) per Kahneman / Tversky.
H5 Error prevention. Confirmation dialog before redirect to PayPal: "You're about to pay $5 to unlock Jordan Kim's contact info. Continue?" — destructive-action pattern (UX-PATTERNS § 2.4).
2.11

Post a job.

/#/post-job · optional editId · AI description via class-jll-ai.php

AUTH · EMPLOYER
[← Dashboard][Autosaved · 12s ago]
[Drag a file or tap]
FORM — Wizard, single screen. Single-page autosave (10 s pause). 10 inputs total; the only required fields are title, trade, state, city, description.
FACILITATOR — AI helper. "Help me write" calls class-jll-ai.php (Anthropic). Produces a 4-paragraph draft from trade + city + pay range. User edits before publish; never auto-publishes.
UPLOAD — 2-phase. The file flow is intentionally two-step: save the job record → fetch REST nonce → POST file to /jll/v1/jobs/{id}/upload → re-save the job with the returned doc_path. This keeps draft jobs valid before any upload attempt.
EDIT MODE — editId. The editId URL param arrives as a string and must be parseInt()'d before comparing to numeric job IDs; loaded record fills the same form.
NUDGE — Feature checkbox. $5 add-on at the publish moment; not bundled with PayPal flow at unlock (different mental ledger).
2.12

Pricing / About.

/#/about · WP page · pricing-table organism

PUBLIC

Closes the loop on the employer empathy map: "I don't want a monthly plan." Lead with per-contact; show monthly plans as opt-in upsells.

[Pay only when you talk to a worker.]

[Workers list free. Forever. Employers pay per contact unlock or upgrade if hiring weekly.]

[Worker]
$0
  • · [List free]
  • · [Apply free]
  • · [Get vetted optional]
[Pay as you go]
$5
[per contact]
  • · [Post jobs free]
  • · [Unlock workers à la carte]
  • · [No subscription]
[Pro · monthly]
$29/mo
  • · [10 contacts incl.]
  • · [Featured listings]
  • · [Priority support]
[Vetting — always available, independent of plan]
[Basic ID]
$29
[Standard]
$49
[Premium BG]
$149
[Agency — high-volume]
[$149/mo][60 contacts · multiple seats · CSV export]
ANCHORING — Order. Free → $5 → $29. Per-contact in the middle because that's the dominant journey, not the cheapest.
CONTENT — Vetting separate. Always-available row visually pulled below plans to communicate "vetting is independent of plan" — buying a tier does not require a subscription.
COPY — Plain language. "No subscription" said explicitly addresses Tony's main objection from the empathy map.
2.13

SEO landing — /jobs/{trade}/{state}/.

page-jll-landing.php · NO wp_head / wp_footer (Divi breaks it)

PUBLIC · SSR

600+ programmatic pages indexed in GSC. Goal: rank, convert a tap into Browse or Register. Static-HTML-only — no Divi navigation hijack.

[← Anchor nav · no JS · 4 items]
[H1]

[Electrician Jobs in Texas — 2026]

[2–3 sentence intro · pay range, trend, "post a job" CTA]

[SECTION · Latest postings — server-rendered, 10 items]
[Job title — city — pay — date]
[Job title — city — pay — date]
[Job title — city — pay — date]
[… 7 more]
[SECTION · FAQ for schema.org · 4 Q&As]
[Q · How much do electricians make in Texas?]

[A · range, sources, link to salary blog post]

[Q · What licence do I need in Texas?]
[SECTION · Internal links — every other trade in same state, every other state in same trade]
[Plumbing TX · Welding TX · HVAC TX · Roofing TX ·… Electrician NJ · Electrician FL · Electrician CA · Electrician OH]
[Footer — rel=next/prev pagination · canonical · sitemap link]
NAV — Anchor tags only. Landing-page menus are static <a>. The parent theme's JS would otherwise hijack link clicks on pages that load it, so landing templates intentionally omit wp_head / wp_footer.
CONTENT — Triplet stack. H1 + intro · listings · FAQ schema · internal links. Mirrors top-ranked competitor format for trade/state long-tails.
SEO — Pagination. The footer reserves rel="next" / rel="prev" for ?page=2, to be lit up once a trade/state combo crosses ~50 listings.
SOCIAL — Internal-link rail. Drives crawler depth and gives a human user a sideways escape.
2.14

Admin — Settings.

/flj-admin-2026 → LaborLink → Settings · class-jll-admin.php

AUTH · ADMIN
[LaborLink → Settings]
[CONTACT UNLOCK FEE — top card, self-saving]
[Charge $5 to unlock contact info]
[OFF = every worker is unlocked for everyone · ON = paywall]
[Saves on toggle. No "Save Changes" needed.]
[API KEYS]
[JSearch (Pro)] [Adzuna App ID] [Adzuna Key]
[AGGREGATOR]
[Last run: · [trade] +29 new / 21 skip]
FEEDBACK — Self-save toggle. Persists to a single WP option (jll_contact_unlock_free) and writes on change — deliberately no "Save Changes" button. Toast on success.
H7 Flexibility. Toggle is the top card because it's the most-used admin control. Power-user shortcut.
H10 Help. One-line caption explains what OFF vs ON actually does, so the operator can't mis-flip it.
ERROR — Edge case. If toggle write fails: revert visual state, show toast "Couldn't save — check connection."
2.15

Heuristics audit — Nielsen 10.

Severity: 0 = none · 1 = cosmetic · 2 = minor · 3 = major · 4 = catastrophe. Background-checked across all 14 wireframes.

#HeuristicStatusSev.Notes / where
H1Visibility of system status✓ Good1Skeleton loaders on browse. Add toast on apply send. Add unlock-receipt timestamp (done in 2.10).
H2Match with real world✓ Strong0"Trade" not "industry," "Vetted" not "verified," real city names. Avoid recruiting jargon entirely.
H3User control & freedom⚠ Mixed2SPA back works; browser back inside hash routing can drop user to /. Spec explicit back affordance on detail screens.
H4Consistency & standards✓ Good1Card pattern reused across browse / candidates / dashboards. Keep CTA hierarchy (filled / outline / link) global.
H5Error prevention⚠ Watch2Confirm before PayPal redirect at unlock. Confirm before deactivating a posted job.
H6Recognition over recall✓ Good0Trade chips, locked-contact glyph, vetted badge — recognisable in < 1 s.
H7Flexibility & efficiency○ Could improve2Keyboard shortcuts on dashboard (J/K to move through applicants). Admin "Jump to job ID" — spec'd as a Phase 1 quality-of-life feature.
H8Aesthetic & minimalist✓ Good1Resist a third hero CTA. Cards cap at 6 data points; do not add more.
H9Help recover from errors⚠ Watch3Login error must not leak existence. Apply 500 should auto-retry, not lose form. PayPal failure path needs "contact support" surface.
H10Help & documentation○ Add2Help link in footer → consolidated FAQ. Tooltip on vetting tiers. "What's vetted?" caption on candidate cards.

// NIELSENS-HEURISTICS.md (Nielsen, 1994). Background evaluation per skill rule.

Mode 03 · Visual phase, part two

Hi-fi prototype.

Frameworks loaded
ATOMIC-DESIGN · DESIGN-PRINCIPLES · NIELSENS-HEURISTICS

Every screen validated in grayscale in §2 is promoted here to full visual fidelity — real colour, real type, real photography direction (placeholder blocks stand in until location photography is shot). Backend administration gets extra depth beyond the single Settings screen wireframed in §2.14, because the tools an owner-operator uses daily deserve the same design rigor as the public product. Tokens applied here are formalised in §5.1; nothing in this section is decorative guesswork.

Coverage

Every consumer-facing screen from §2 (Home through SEO Landing) is rendered here 1:1 in colour. The admin suite (§3.11) goes further than the single wireframed Settings screen — Jobs Management, Seeker/Employer records, the Vetting Requests queue, the Aggregator monitor, and Transaction History are all specified, because a one-person operation lives or dies on how fast its owner can operate these screens.

3.1

Home & browse.

FLJ
FindLaborJobs
Electrical · New Jersey

Find work in the trades. Today.

Free for tradespeople. No resume required to start.

★ 17,000+ tradespeople hiring this week

Pick your trade
Electrical
$42–58/hr avg
Plumbing
$38–52/hr avg
HVAC
$36–49/hr avg
Welding
$30/hr + OT
Latest openings
Electrical2d ago
Master Electrician — Commercial
ACME Construction · Newark, NJ · $42–58/hr
Plumbing5d ago
Service Plumber — Residential
Aqua Brothers LLC · Jersey City, NJ · Pay TBD
Colour intent. Ink-navy hero grounds the brand; accent orange reserved for the single highest-priority action per screen. This is the only screen with a full-bleed dark hero — it never repeats deeper in the flow, keeping the accent's meaning ("act now") intact.
Trade cards. Colour-coded top bar per trade aids fast recognition (Nielsen H6) without needing icon illustration — a deliberate choice to avoid generic stock icon sets that read as "AI-generated."
Photography direction. Real jobsite photography (workers mid-task, natural light, no posed stock) replaces gradient placeholders before launch. Tone: dignified, competent, unglamorous.
3.2

Job detail.

← Back to jobs♡ Save
Electrical

Master Electrician — Commercial Fit-Out

ACME Construction · Newark, NJ
$42–58/hr · Full-time
★ Featured⏱ 5 days left
Description

Commercial electrical crew seeking a licensed journeyman for a 6-month build-out in downtown Newark. Day shift, weekly pay, tools provided.

Requirements
  • Journeyman or master licence
  • 5+ years commercial experience
  • OSHA 30 certified

Free to apply. Always.

Sticky CTA persists the same visual weight as the hero CTA on Home — one accent button per screen, never two competing accents.
Pay stated in bold, above description. Per the worker empathy map, pay-rate is the first fact scanned; hiding it below the fold was rejected in wireframe review.
Scarcity badges use warning, not error, red. "5 days left" should read as informative, not alarming — reserving true red for validation errors only.
3.3

Worker profile — the unlock moment.

KEY SCREEN

The highest-revenue screen in the product, rendered hi-fi in both states. Every colour choice here was tested against the behavioural intent set in §1.5 and the states table in §5.3.

Locked · fee on
Photo
Jordan Kim
Plumbing · Newark, NJ · 5 yrs
Contact
●●●-●●●-●●●●

One-time. No subscription.

Vetting — always available
Basic
$29
Standard
$49
Premium
$149
Unlocked · paid
Photo
Jordan Kim
Plumbing · Newark, NJ · 5 yrs
Contact unlocked
(973) 555-0142
jordan.k@email.com
Unlocked May 12 · $5 charged · receipt sent
Vetting — always available
Basic
$29
Standard
$49
Premium
$149
Green is earned, not decorative. Success-green appears in exactly one place in the whole product: a completed unlock. That scarcity is what makes it legible as "this worked."
Vetting tier repeats unchanged across locked and unlocked states — the upsell doesn't depend on the unlock decision, reinforcing that they're separate purchases.
3.4

Employer dashboard.

ACME ConstructionLog out
Applications
28
Unlocked
6
Vetted hires
2
Spent MTD
$78
Active jobs
Master Electrician · Newark14 applicants
Apprentice Plumber · Jersey City8 applicants
KPI strip states cost, not just volume. "$78 spent" builds trust: an employer can see exactly what the platform has charged, addressing the empathy map's core distrust of hidden fees.
No accent colour on this screen. Post a Job is the one accent CTA because it is the one action that grows the marketplace; Search and Manage stay neutral to avoid diluting that signal.
3.5

Apply.

← Master Electrician · ACME
Using resume on file
4 of 5 fields prefilled from the saved profile. The only new decision is the cover note. Same accent button as Job Detail — continuity of intent across the conversion path.
3.6

Register & login.

Step 1 of 2

What brings you here?

Step 2 · Worker

Create your profile

Welcome back.

Forgot password? · Create account

Accent reserved for the worker path. Employer step-2 and the login form use ink, not accent — accent orange is spent only on the highest-frequency, highest-value action per screen (see §3.4's rule repeated here for consistency).
3.7

Seeker dashboard.

Marcus DiazLog out
Profile completeness60%
Applications
3 active · 1 new
Saved jobs
7 saved
Vetting
Not vetted — verified workers get more contacts
Progress bar starts at 30%, not 0 — endowed progress effect. Card order (applications → saved → vetting) mirrors the return-visit job-to-be-done from §1.2.
3.8

Search candidates.

Photo
Alex RiveraVetted
Electrical · Newark, NJ
Photo
Jordan KimUnvetted
Plumbing · Jersey City, NJ
Vetted badge in success green is the only colour signal on the card — fastest possible scan for the trust cue employers weigh most.
3.9

Post a job.

← DashboardAutosaved · 12s ago
AI helper uses the warning-amber chip, not accent, so it reads as an assist tool rather than the primary action — Publish keeps the only accent button on the screen.
3.10

Pricing / About.

Pay only when you talk to a worker.

Workers list free, forever.

Worker
$0
Pay as you go
$5
per contact
Pro / mo
$29
Dark hero repeats from Home, the only other place in the product using the full-bleed navy treatment — reserved for pages meant to build trust before a decision.
3.11

SEO landing page.

Electrician Jobs in Texas — 2026

Average pay, licensing notes, and open roles across Texas, updated weekly.

Journeyman Electrician — Austin, TX — $38–52/hr
Apprentice Electrician — Dallas, TX — $22–28/hr
Same tokens, lighter chrome. No app-shell header/footer — landing pages render standalone to avoid the parent theme's JS hijacking clicks (see §2.13 engineering note).
3.12

Admin suite — backend administration.

EXPANDED

The wireframes in §2.14 spec a single Settings screen. In hi-fi, the full admin suite is designed: the operator's daily workspace across jobs, people, vetting, and data pipelines. A one-person operation lives or dies on how fast these screens work — they get the same design attention as the public product, not an afterthought template.

LaborLink
Dashboard
Jobs
Seekers
Employers
Vetting Queue
Aggregator
Transactions
Settings
Jobs Management
TitleTradeStatusExpires
Master Electrician — NewarkElectricalActive5d
Apprentice Plumber — Jersey CityPlumbingActive12d
Welder — CamdenWeldingExpired
Vetting Requests Queue
Jordan Kim · StandardPending
D. Patel · BasicReport sent
Aggregator Monitor
JSearch● Running
Adzuna● Running
Last run: Roofing +29 new / 21 skipped
Transaction History
Unlock · ACME Const.$5.00
Vetting · Riverline Iron$49.00
Feature listing$5.00
Sidebar accent marks current section only. Every other nav item stays neutral ink-on-navy — the same one-accent-per-screen rule enforced across the public product applies internally.
Jump-to-ID stays top-right, always visible without scrolling — the single most-used power tool for an operator managing thousands of aggregated jobs by hand.
Mode 04 · Growth phase

Content & SEO strategy.

Frameworks loaded
BUSINESS-CONTEXT · UX-PATTERNS · USER-RESEARCH

The IA in §1.7 splits the product into an app layer and a discovery layer. This section is the plan for the discovery layer: the editorial engine that turns 600+ programmatic landing pages into a compounding organic-traffic asset, without a paid-media budget doing the heavy lifting.

4.1

Content pillars.

Three pillars, each answering a different stage of the worker's job statement (§1.2). No pillar exists to "have a blog" — each maps to a real search intent and a real internal link target.

Pillar 01
Salary Guides

Answers "how much do I make." Highest search volume, highest commercial intent.

Pattern: [trade] salary [state] [year]
Pillar 02
Career Advice

Career-changers and apprentices. Builds top-of-funnel trust and shareability.

Pattern: [audience] to [trade] career [angle]
Pillar 03
Industry News

Workforce shortage coverage, notable figures, trend pieces. Earns backlinks and repeat visits.

Pattern: [trend or figure] + [trades angle]
4.2

Programmatic SEO architecture.

Hub-and-spoke model. The trade × state landing page (§2.13) is the hub built to convert; blog posts are spokes built to rank on long-tail queries the hub itself can't target, then funnel authority and clicks back to it.

flowchart LR
    subgraph Spokes["Blog spokes · long-tail intent"]
      B1["[trade] salary [state] [year]"]
      B2["[audience] to [trade] career change"]
      B3["[trend] in the trades"]
    end
    HUB["/jobs/[trade]/[state]/ — landing hub · converts"]
    SITEMAP["/job-directory/ + sitemap-jobs.xml"]
    REG(["Register / Browse jobs"]):::ok

    B1 -->|internal link + CTA| HUB
    B2 -->|internal link + CTA| HUB
    B3 -->|internal link + CTA| HUB
    HUB --> REG
    HUB -.indexed via.-> SITEMAP

    classDef ok fill:#f1ede4,stroke:#1a1a1a,stroke-width:2px;
          

// Cross-reference §1.7 Information Architecture. Every blog post ships with a mandatory internal link to its matching trade/state hub — not optional, not "when relevant."

4.3

Editorial cadence & calendar.

3 posts / week, 600–900 words, rotating across 12 trades × 50 states without repeating a trade+state combination. Sample four-week calendar below — a template to fill, not a fixed schedule.

WeekMonWedFri
1[Electrician] salary in [Texas] — [2026][Office worker] to [trades] career change[General labor] jobs in [New Jersey]
2[Plumber] salary in [New Jersey] — [2026][Welding] job, no experience needed[HVAC] technician pay in [Florida]
3[Carpenter] jobs in [California] — [2026]Women in skilled trades — [2026] salary data[Roofing] jobs in [Florida] — [2026]
4[HVAC] jobs in [Ohio] — [2026][Apprentice] to [$100K] — five year plan[Plumbing] jobs in [Georgia]

// Categories: Salary Guides · Career Advice · Industry News. Track covered trade+state pairs in a single shared log so no combination repeats.

4.4

Voice & style guide.

Write like this
  • Conversational, direct, jobsite-plain
  • Mix sentence lengths deliberately
  • Write for tradespeople, not corporate readers
  • Every post ends with a register-link CTA
  • 600–900 words. Say the useful thing, then stop.
Never do this
  • No em-dashes — the single most reliable tell of AI-written copy
  • No "leverage," "seamlessly," "delve," "robust," "holistic"
  • No invented statistics or unsourced salary claims
  • No corporate-recruiter tone ("passionate self-starter")
  • No semicolons
4.5

Distribution & promotion.

ChannelRoleNotes
Organic searchPrimary, compoundingLong-tail blog + hub landing pages target the full trade × state matrix.
Reddit adsPaid amplification, worker acquisitionTargeted to trade-specific subreddits (r/Construction, r/Electricians, r/HVAC, etc). Conversions objective once signup volume supports it.
Internal linkingCrawl depth, authority flowEvery post links to its matching hub; every hub links sideways to adjacent trades/states.
Email digestRetention (future)Weekly new-jobs-in-your-trade digest once list size justifies build cost.
4.6

KPIs & success metrics.

Organic sessions

Month-over-month growth to landing hubs + blog.

Keyword rankings

Position tracking across the trade × state matrix.

Attributed registrations

Signups where landing session included a blog referral.

Referring domains

Backlinks earned by Industry News pillar content.

Mode 05 · Handoff phase

Spec engineer.

Frameworks loaded
ATOMIC-DESIGN · HANDOFF-TEMPLATES · NIELSENS-HEURISTICS

Wireframes converted into actionable specs. Atomic inventory (Frost), tokens, component states, A11y, responsive rules and a copy-paste Developer Deployment Code block sized for the existing WP / SPA codebase.

5.1

Design tokens.

All values are CSS-custom-property ready — drop into :root. Aesthetic intent: workmanlike, slate-led, hi-vis warm orange used sparingly. Final stylesheet lives at assets/css/styles.css.

a · Colour palette

TokenHexSwatchUsage
--color-ink#0F172A
Primary text, primary button bg
--color-ink-2#334155
Body text, captions
--color-muted#64748B
Secondary text, helper labels
--color-rule#CBD5E1
Borders, dividers
--color-surface#FFFFFF
Card surfaces
--color-surface-2#F1F5F9
Page background
--color-accent#E07A2D
Hi-vis accent — links, CTA highlights, brand
--color-success#15803D
Free-mode unlocked strip, verified badges
--color-warning#B45309
Expiring soon, vetting tier badges
--color-error#B91C1C
Validation, destructive actions

All foreground/background pairs verified ≥ 4.5:1 (WCAG AA body). Ink-on-surface = 16.7:1.

b · Typography

RoleFamilySize · weight · line-heightToken
Display / H1 (hero)Inter / system-ui40 px · 700 · 1.1--font-display
H2Inter / system-ui28 px · 700 · 1.2--font-h2
H3Inter / system-ui20 px · 600 · 1.3--font-h3
BodyInter / system-ui16 px · 400 · 1.55--font-body
Caption / eyebrowInter / system-ui12 px · 500 · 1.4 · letter-spacing 0.08em uppercase--font-caption
Mono (codes, timestamps)JetBrains Mono / SF Mono13 px · 500 · 1.4--font-mono

Stack: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif. No web-font fetch on landing pages — system stack only, to keep LCP < 1.8 s for SEO.

c · Spacing

TokenValueUsed for
--space-14 pxTight icon/text gaps
--space-28 pxForm field internal padding
--space-312 pxCard inner gap
--space-416 pxComponent padding
--space-624 pxSection gaps mobile
--space-832 pxMajor breaks mobile
--space-1248 pxPage sections desktop

d · Borders, radii, elevation

TokenValueNotes
--border-thin1px solid var(--color-rule)Default card border
--border-strong2px solid var(--color-ink)Selected state, sticky CTA top edge
--radius-sm2 pxButtons, inputs (trade-paperback feel)
--radius-md6 pxCards (optional)
--shadow-10 1px 0 #00000010Sticky CTA edge only
--shadow-20 6px 16px #00000018Modal & toast
5.2

Atomic component inventory.

Per Brad Frost. Component tree flows up: atoms → molecules → organisms → templates → pages. Every wireframe is built from this set, no exceptions.

Atoms
  • Button — primary · secondary · tertiary · destructive
  • Input — text · email · phone · password · number
  • Select — trade · state · pay-range
  • Textarea — cover note · job description
  • Checkbox · RadioGroup
  • Badge — Vetted · Featured · Expiring · Free Mode
  • Chip — Trade selector
  • Avatar — Worker photo placeholder
  • Icon — Heroicons outline 24 px (defined in core.js · Icons)
  • Skeleton — line · block
  • Spinner — used only in modal/blocking contexts
  • Link — inline · footer · breadcrumb
  • Tag — Trade · State (mono caps)
  • Toggle — admin contact-unlock-fee switch
Molecules
  • FormField = Label + Input + Helper + Error
  • FilterBar = TradeSelect + StateSelect + SearchInput
  • JobCard = TradeBadge + Title + Employer + Location/Pay + ScarcityStrip + SaveButton
  • CandidateCard = Avatar + Name + TradeMeta + VettedBadge + LastActive + CTA
  • PricingTier = Header + Price + Bullets + Footer-CTA
  • ContactLockedStrip · ContactRevealedStrip
  • ProgressBar = Track + Fill + % + caption
  • PhotoGrid = up to 3 slots + "+ Add"
  • DocumentRow = Icon + Filename + View
  • FAQItem (details/summary, schema.org-FAQPage compatible)
  • Toast · Banner · Modal
  • RoleCard (register step 1)
Organisms
  • Header — logo + nav + auth state
  • Footer — anchors only, never <button>
  • Hero — title + sub + dual CTA + social-count
  • TradeGrid — 12 trade chips
  • JobList = FilterBar + JobCard[] + LoadMore + Skeleton
  • JobDetailBody + sticky ApplyBar
  • ApplyForm
  • SeekerDashboard = ProgressBar + 4 cards
  • EmployerDashboard = CTAs + KPIs + JobsTable
  • CandidateBrowser
  • WorkerProfile (Locked / Unlocked / Free states)
  • PostJobForm + AI helper
  • PricingTable + VettingRow
  • SeoLandingBody (server-rendered)
  • AdminSettings
Templates · Pages
  • SpaTemplate = Header + RouterOutlet + Footer
  • SeoLandingTemplate = MinimalHeader + Body + MinimalFooter (no Divi · no wp_head)
  • AdminTemplate = WP admin chrome + LaborLink sub-nav
  • Pages: Home · Jobs · JobDetail · Apply · Register · Login · SeekerDashboard · EmployerDashboard · SearchCandidates · WorkerProfile · PostJob · Pricing · SeoLanding(trade·state·t×s) · AdminSettings · Blog · 404
5.3

Component states.

a · Buttons

StatePrimarySecondaryDestructive
Defaultbg ink, text whitebg surface, border rule, text ink-2bg error, text white
Hoverbg ink darken 8 %border ink, text inkbg error darken 8 %
Activescale 0.98scale 0.98scale 0.98
Focus2 px accent outline, offset 2 px, on all variants. Never remove (H3).
Disabledbg muted, text rule, cursor not-allowedborder rule, text mutedopacity 0.5
LoadingInline spinner left of label, label = "Working…", button disabled.

b · Inputs

StateBorderLabelHelper
Defaultrulemutedmuted
Focusink, 2 pxinkmuted
Validsuccessink"✓ Looks good"
Errorerrorerrorerror · pattern: "[What] · [How to fix]"
Disabledrulemutedmuted

c · ContactStrip (key)

StateTriggerVisualCTA
Lockedfee=ON, no row in jll_worker_unlockssurface-2 bg, masked dots, 2 px ink top border"Unlock contact — $5"
Pendingstatus='pending_payment'warning border, helper "Payment received — confirming…"disabled, "Awaiting confirmation"
Unlockedstatus='paid'ink bg, white text, phone/email linksCall · Text · Email (3 atomic buttons)
Free modejll_contact_unlock_free=1success-50 bg, 2 px success borderDirect phone/email visible
Demo (Alex)is_demo=1 AND is_vetted=1Treat as Unlocked regardless of toggleSame as Unlocked
5.4

Accessibility checklist (WCAG 2.2 AA).

  • Contrast. Body 4.5:1, large 3:1. Hi-vis accent #E07A2D only on ink (8.3:1) or as decorative.
  • Focus indicators. 2 px accent outline + 2 px offset on every interactive element. Never outline:none without a replacement.
  • Touch targets. Mobile minimum 44 × 44 px. JobCard tap-area = whole card. Save button = 44 px.
  • Heading order. Single H1 per page, no skipping levels.
  • Form labels. Every input has a visible label; placeholder is hint, not label.
  • Error association. aria-describedby linking input → helper / error.
  • Status live regions. Toasts use role="status" (polite). Modal errors role="alert".
  • Keyboard nav. All flows completable with Tab/Shift-Tab/Enter/Esc; Esc closes modals; J/K (optional) on dashboards.
  • Skip links. "Skip to content" first focusable on every page.
  • SPA route changes. Fire document.title update + aria-live announcement on hash change.
  • Images. Worker photos: alt="" (decorative) until name is co-located; otherwise alt = "[Name] · [Trade]".
  • Locked contact. Masked dots must include aria-label="Contact info — pay to reveal"; never expose real value in DOM until paid.
  • Motion. Honour prefers-reduced-motion; sticky-CTA shadow fade only.
  • Language. <html lang="en"> on every template incl. landing pages.
5.5

Responsive behaviour.

BreakpointWidthLayout shifts
Mobile (default)< 640 pxSingle column. Sticky bottom CTA bars. Filter bar sticky-top. Card density: 1 / row.
sm≥ 640 pxTrade grid 4-col. Hero CTAs side-by-side. JobCard expands but stays 1-col.
md≥ 768 pxSidebar filters reveal (240 px). Header switches from hamburger to anchor row. Hero gets right-side imagery.
lg≥ 1024 pxDashboards become 2-col grid. PricingTable 3-up. Trade grid 6-col.
xl≥ 1280 pxMax content width 1200 px, centred. No further reflow.

Mobile-first. Most blue-collar traffic arrives via phone (Reddit ad clicks confirm this).

5.6

Microcopy library.

House voice: direct, jobsite-plain, no em-dashes per blog rules. Active verbs. Pay-rates and prices stated upfront. No "leverage / seamlessly / unlock the power of" — banned per skill rules + product voice.

CTAs

Hero · workerFind Jobs Near Me
Hero · employerHire a Tradesperson
ApplySend Application
UnlockUnlock Contact — $5
Post jobPublish Job
VettingOrder Vetting · $49
Signup · workerCreate Worker Account
Signup · employerCreate Hiring Account

Errors (Nielsen H9)

Bad loginThat email and password combination didn't work.
Empty filterNo [trade] jobs in [state] right now. We add ~140 a week.
Phone invalidEnter a 10-digit phone, e.g. 555-123-4567.
Upload too bigPDF is too big — keep it under 5 MB.
Pay missingPay TBD shown when employer left it blank — never invent a range.
Server 500Couldn't reach us. We'll retry — keep this tab open.

Empty states

No applicationsApply to your first job. Free, always.
No saved jobsTap ♡ on a job to come back to it later.
No candidatesNo vetted workers match yet. Try widening state or unchecking "vetted only."
First postPost your first job. 30 days free, no credit card.

Success / confirmation

AppliedApplication sent. Employer has been notified.
SavedSaved · view in My Profile.
UnlockedContact unlocked · $5 charged · receipt sent.
Job publishedJob is live. We'll email you when applications arrive.
Vetting orderedVetting ordered. Report typically takes 24–72 hours.
5.7

Developer deployment code.

Copy-paste-able brief for the front-end developer (or for an LLM agent operating in the codebase). Pre-loaded with the existing tech stack (WordPress + Divi + custom plugin SPA) so no environment-discovery round-trip is needed.

---
DEVELOPER DEPLOYMENT CODE
---
You are the Developer. I am the Designer.

Here are the approved wireframes and design tokens for FindLaborJobs.com.
Implement against the existing stack:
  WordPress + Divi (parent) · child theme jersey-laborlink-child
  jersey-laborlink-plugin (custom)
  SPA at / with hash routing
  REST: /wp-json/jll/v1/
  CSS in assets/css/styles.css ONLY (no inline, no <style>)
  JS in assets/js/ (core, wp-bridge, pages-public, pages-dashboard, pages-auth, targeted-ads)
  PHP via FTP (plugin editor server-side disabled)
ZIP delivery only. node --check all JS. Version bump +1 every ZIP.

## DESIGN CONTEXT
National job board for the 12 skilled trades. Two-sided marketplace.
Workers free. Employers pay $5 per contact unlock. Optional vetting tiers.
Solo-operator economics; no support team for runtime errors.

## USER FLOW REFERENCE
See §1.8 master flowchart. Two core loops:
  WORKER · home → browse → detail → register → apply → dashboard
  EMPLOYER · landing → register → post job → search → profile (locked) → PayPal → profile (unlocked) → vetting → call

## DESIGN TOKENS

Colour (CSS custom properties on :root)
  --color-ink:         #0F172A
  --color-ink-2:       #334155
  --color-muted:       #64748B
  --color-rule:        #CBD5E1
  --color-surface:     #FFFFFF
  --color-surface-2:   #F1F5F9
  --color-accent:      #E07A2D
  --color-success:     #15803D
  --color-warning:     #B45309
  --color-error:       #B91C1C

Type
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif
  --font-mono: "JetBrains Mono", "SF Mono", ui-monospace, monospace
  H1 40/700/1.1 · H2 28/700/1.2 · H3 20/600/1.3
  Body 16/400/1.55 · Caption 12/500/1.4 uppercase 0.08em

Spacing (base 4px): 4 8 12 16 24 32 48
Radius: 2px (sm) · 6px (md)
Borders: 1px rule (default) · 2px ink (selected/sticky-edge)

## COMPONENT REQUIREMENTS

### JobCard (molecule)
- Structure: TradeBadge · Title · Employer · "City, ST · $low–$high or Pay TBD" · ScarcityStrip · SaveButton
- States: default · saved · viewed (visited-link grey)
- A11y: whole card focusable, aria-label "{title} in {city} – pay {range or unspecified}"

### ContactStrip (organism · KEY COMPONENT)
- States enumerated in §3.3.c
- DOM must NOT contain real phone/email until paid. Render dots only.
- Free-mode + demo Alex always render Unlocked.
- Confirm modal before PayPal redirect (Nielsen H5).
- Persist unlock via REST POST /worker_unlock; reflect status from
  jll_worker_unlocks.status === 'paid'.

### ApplyForm (organism)
- Single screen, sticky CTA, 5 fields prefilled from profile.
- Validate on blur; never block submit on async; fire Reddit Lead on 200.
- Edge: file > 5MB → inline error, do not strip silently.

### PostJobForm (organism)
- Autosave 10s pause to draft endpoint.
- "Help me write" → POST /ai/job-description with {trade, city, pay}
  → 4-paragraph draft; user edits before publish.
- 2-phase document upload (save → REST nonce → POST file → re-save).

### AdminSettings (organism)
- Top card: Contact Unlock Fee toggle. Self-saves on change.
  Persists to WP option jll_contact_unlock_free.
- $contact_free MUST appear in array_map closure use() list when
  reading workers — otherwise free-mode silently fails to unlock.

## RESPONSIVE BEHAVIOUR (mobile-first)
- sm 640 · md 768 · lg 1024 · xl 1280 (Tailwind defaults)
- Hero 1-col → 2-col at md.
- Filter bar sticky-top mobile · sidebar-left md+.
- Sticky-bottom CTAs disappear when soft keyboard is open (visualViewport API).
- Trade grid 3 → 4 → 6 col.

## ACCESSIBILITY CHECKLIST
- [ ] WCAG 2.2 AA contrast on every token pair
- [ ] 2px accent focus outline + 2px offset, on every interactive
- [ ] 44×44 mobile touch targets
- [ ] Single H1 per page; logical heading order
- [ ] Form labels visible; aria-describedby on errors
- [ ] Toast role="status", critical alerts role="alert"
- [ ] Hash route change → update document.title + announce via aria-live
- [ ] prefers-reduced-motion respected
- [ ] lang="en" on every template

## NON-NEGOTIABLE PROJECT RULES
1. CSS only in assets/css/styles.css. No inline, no <style>.
2. Footer + nav use <a> tags, not <button>. Global CSS overrides
   button backgrounds.
3. Blog cards on homepage are <div onclick>, not <a> — global
   CSS overrides anchor backgrounds.
4. Landing pages MUST NOT include wp_head/wp_footer — Divi breaks them.
5. Logout uses CFG.logoutUrl, never /wp-login.php (WPS Hide Login).
6. Login is async fetch with 1200ms cookie delay then
   window.location.replace(siteUrl + '?nocache=' + Date.now() + '#/route').
7. is_vetted from MySQL is string "0"/"1" — always parseInt().
8. editId from URL params is string — always parseInt() before
   comparing to job IDs.
9. .xml requests intercepted by LiteSpeed before WP rewrite — sitemap
   handler uses the parse_request hook to intercept early.
10. No em-dashes in user-facing copy (house voice / blog rule).

## IMPLEMENTATION NOTES
- Reddit pixel events to keep firing:
    PageVisit (every load)
    SignUp (split SeekerSignUp / EmployerSignUp; pass email for advanced
            matching)
    Lead (post-apply)
    Purchase (post-PayPal unlock click)
  Helper: window.jllRedditEvent(name, data)
- SPA load only fetches newest 1,000 jobs; job-detail falls back to
  GET /jobs/{id} for misses. Maintain App.store.jobsTotal vs jobs.length.
- Demo accounts (Alex 190, Jordan 191) are seeded server-side and pinned
  via ORDER BY is_demo DESC. Never delete; never hide is_demo from admins.

---
END DEPLOYMENT CODE
---

Hand this block to the Frontend Developer skill or to the next-session agent. It replaces the first 30 minutes of environment-discovery questions.

Mode 06 · Homepage merchandising

Blog hero templates.

Frameworks loaded
UX-PATTERNS · NIELSENS-HEURISTICS · BEHAVIORAL-DESIGN

§4 establishes the editorial engine; this section designs where its output actually surfaces on the homepage. Five directions for merchandising the latest post directly above the How FindLaborJobs.com Works section — the highest-traffic real estate on the site outside the hero itself.

6.1

Placement & context.

Every direction below is evaluated against the same sample post — "The 5 Highest-Paying Trades in 2026 — And Where They're Hiring Right Now" — and shown with the site nav above and the How-It-Works section immediately below, so visual weight reads accurately in situ rather than in isolation.

6.2

Five directions.

01Editorial Featured ArticleNewspaper-style 2-up. Calm, trustworthy, lots of breathing room.
FLJFind Jobs   For Employers   AboutJoin Free
From the FLJ Blog
Latest Article
View all posts →
Editorial photo
Apr 22, 2026 · 6 min read
The 5 Highest-Paying Trades in 2026 — And Where They're Hiring Right Now

New BLS data shows skilled trade wages jumped 8.4% this year. We broke down which trades pay the most and how to land an interview this week.

MR
Marcus Reilly
↓ How FindLaborJobs.com Works (continues below)
02Magazine 1 + 3Hero post next to a stack of secondary posts. Highest content density.
FLJFind Jobs   For Employers   AboutJoin Free
FLJ Blog
News & Insights for the Trades
Browse all articles →
Trade InsightsNew this week
The 5 Highest-Paying Trades in 2026 — And Where They're Hiring Right Now

New BLS data shows skilled trade wages jumped 8.4% this year. We broke down which trades pay the most.

Marcus Reilly · Apr 22, 2026 · 6 min read
Career
OSHA 30 vs OSHA 10: which certification do you need?
Apr 18 · 4 min
Hiring
7 questions before accepting a travel ironworker contract
Apr 14 · 5 min
Pay
Why journeyman electricians in Texas are leaving for Colorado
Apr 09 · 7 min
↓ How FindLaborJobs.com Works (continues below)
03Full-bleed Banner + StatsBold navy banner with live ticker and supporting stats pulled from the article.
FLJFind Jobs   For Employers   AboutJoin Free
New article · Apr 2216,494 active jobsUpdated every 30 minAll 50 states
Latest from the FLJ Blog
The 5 highest-paying trades in 2026 — and where they're hiring right now.

New BLS data shows skilled trade wages jumped 8.4% this year.

Apr 22, 2026 · 6 min read
+8.4%
Wage growth YoY
$47/hr
Top trade median
2,185
Plumber openings
1,929
Welder openings
↓ How FindLaborJobs.com Works (continues below)
04Compact Highlight StripSingle-line announcement bar. Lowest visual weight — won't compete with How-It-Works below.
FLJFind Jobs   For Employers   AboutJoin Free
New on the blog
The 5 Highest-Paying Trades in 2026 — And Where They're Hiring Right Now
Marcus Reilly · Apr 22, 2026 · 6 min read
Read article →
↓ How FindLaborJobs.com Works (continues below)
05Split Feature + Pay-Rate LeaderboardArticle on the left, a teaser of the article's data on the right. Most "useful" feel.
FLJFind Jobs   For Employers   AboutJoin Free
FLJ Trade Report · April 2026
This Month on the Blog
Read all posts →
Featured · Trade Insights
The 5 Highest-Paying Trades in 2026 — And Where They're Hiring Right Now

New BLS data shows skilled trade wages jumped 8.4% this year. We broke down which trades pay the most, the cities with the biggest shortages, and how to land an interview this week.

Apr 22, 2026 · 6 min read
// from the article · top trades by median pay
01
Elevator Installer
214 open jobs
$47.20/hr
↑ 12.1%
02
Electrical Power-Line
487 open jobs
$42.80/hr
↑ 9.4%
03
Boilermaker
198 open jobs
$38.65/hr
↑ 7.9%
04
Pipefitter
612 open jobs
$36.10/hr
↑ 8.6%
05
Heavy Equipment Op.
1,686 open jobs
$34.40/hr
↑ 6.2%
↓ How FindLaborJobs.com Works (continues below)
6.3

Recommendation.

DirectionVisual weightContent densityBuild costBest fit
01 EditorialMediumLowLowCalm, trust-building default
02 MagazineMedium-highHighMediumOnce 3+ posts/week cadence is established (§4.3)
03 BannerHighMediumMediumLaunch week / major data-driven story
04 StripLowLowLowIf How-It-Works must stay the visual anchor
05 SplitMedium-highHighMedium-highSalary Guide pillar posts specifically (§4.1)
Recommended: 01 Editorial, with a scheduled upgrade path to 05 Split

Per Nielsen H8 (minimalist design) and the empathy map in §1.3, a first-time visitor's attention budget on the homepage is spent on the hero and trade grid — the blog teaser should support, not compete. Editorial gives the post real presence without visually outranking How-It-Works. Once the Salary Guides pillar (§4.1) has enough data-rich posts to fill it convincingly, promote to Split — its leaderboard format is a direct proof point of the content strategy's value and doubles as a soft trust signal for the pay-rate transparency workers care about most (§1.3).

A

Appendix.

Framework crosswalk.

Every framework loaded from the UX Designer reference library and where it lives in this dossier.

FrameworkOriginatorWhere applied
Jobs to Be DoneChristensen, 2016§1.2 Personas (Marcus, Tony)
ODI / Job MapUlwick, 2005 / 2016Implicit in §1.2 "Current state / Success" rows; recommend deep mode interviews
Empathy MapGray (XPLANE) 2010§1.3 Both archetypes
Customer Journey Map[AGGREGATED] · NN/g + service design§1.6 Worker & Employer journeys
Double DiamondDesign Council, 2005§1.7 IA + §1.8 Flowchart (Deliver output)
Krug's 3 LawsKrug, 2000§2.1, §2.2 (omit needless words, conventions)
Norman — Affordances / Mapping / FeedbackNorman, 1988§2.3 sticky apply, §2.10 unlock reveal, §3.3 button states
Garrett 5 PlanesGarrett, 2002§1.7 IA note
Nielsen 10 HeuristicsNielsen, 1994§2.15 audit + per-wireframe annotations
Atomic DesignFrost, 2016§3.2 inventory
Fogg B = MAPFogg, 2009 / 2020§1.5a per-action table
Hook ModelEyal, 2014§1.5b cycle + manipulation matrix call-out
Nudge / Choice ArchitectureThaler & Sunstein, 2008§1.5c nudge inventory
Dual ProcessKahneman, 2011§1.5d System 1 / System 2 split
Cialdini 6 PrinciplesCialdini, 1984§1.5c (proof, scarcity, anchoring), §2.10
Endowed ProgressNunes & Dreze, 2006§2.7 seeker dashboard progress bar
Wroblewski form patterns2008–2009§2.4, §2.5, §2.11 (inline validate on blur)
INVEST + GherkinWake, 2003 + North, 2006Implicit in §3.7 acceptance language

Changelog.

VersionChange
v1.1Added Mode 06 — Blog Hero Templates (five homepage merchandising directions with a design recommendation), merged from the standalone concept exploration. Renumbered Spec Engineer subsections (5.1–5.7) for consistency.
v1.0Initial specification — pre-launch. Deep mode — all eight UX Designer references loaded. Personas, empathy maps, journeys, behavioural analysis, IA, 14 wireframes, hi-fi prototype (12 screens + expanded admin suite), content & SEO strategy, full developer handoff.

Designer's oath.

I do not decorate. I architect decisions.
I do not guess user needs. I map their jobs.
I do not hand off ambiguity. I deliver specifications.
Every wireframe is a hypothesis. Every spec is a contract.
Design the thinking. Let developers build the thing.

FindLaborJobs.com · UX Dossier · v1.0
End of document · 14 wireframes · 3 modes · 18 frameworks