/* Work, About, Contact, Footer */ const PROJECTS = [ { num: "01", name: "Growers Marketplace", role: "Identity, platform, ongoing build", year: "2024 — ongoing", sector: "Rural classifieds · Canada-wide", summary: "A Canadian rural classifieds marketplace connecting growers, farmers, homesteaders and rural service providers. Custom WordPress + HivePress build with a hand-rolled child theme, tuned for slow rural connections.", visual: "growers", color: "#1b3225", url: "dev.growersmarketplace.ca", stack: ["WordPress", "HivePress", "Custom theme"], }, { num: "02", name: "Drift Overland", role: "Brand, web, e-commerce", year: "2025", sector: "Adventure rentals · Vancouver Island", summary: "Jeep and trailer rentals for BC overlanders. A confident identity, Outdoorsy integration, a WooCommerce sales layer, and route-planning content built for back-roads research.", visual: "drift", color: "#1a1a1c", url: "driftoverland.ca", stack: ["WordPress", "WooCommerce", "Slider Revolution"], }, { num: "03", name: "Alternate Roots Farm", role: "Identity, web", year: "2023 — ongoing", sector: "Market garden · Gabriola Island", summary: "A sister project. Small market garden and livestock farm on the south end of Gabriola — Wordpress built, conveys values and ethics of the growers through content and feel, updated info on available products in a menu (a la carte) format.", visual: "roots", color: "#2a3a1f", url: "alternaterootsfarm.ca", stack: ["Identity", "Web", "E-commerce"], }, { num: "04", name: "Gabriola Men's Group", role: "Identity, web — in progress", year: "2026 — current", sector: "Community group · Gabriola Island", summary: "A new circle for mutual support, honest conversation and personal wellness — meetings every Tuesday at the Commons. Identity and a quiet, welcoming site, currently in build.", visual: "mens", color: "#2a2118", url: "gabriolamensgroup.ca", stack: ["Identity", "Web (in build)"], }, ]; const Work = () => { return (

Selected work

Quiet projects that
kept going.

{PROJECTS.map((p, i) => ( ))}

Always something else in the pipeline. Get in touch if you'd like to talk about a project of your own.

Start a conversation
); }; const ProjectCard = ({ num, name, role, year, sector, summary, visual, color, url, stack, idx }) => { const href = url ? `https://${url}` : "#"; return (
{num} {year}

{name}

{role}

{sector}

{summary}

{stack.map(s => {s})}
{url}
); }; const ProjectVisual = ({ kind }) => { if (kind === "growers") { /* Growers Marketplace — forest green, DM Serif Display feel, gridded listing cards motif */ return ( Growers Marketplace. LIVESTOCK · PLANTS & SOIL · EQUIPMENT · SERVICES {/* mini listing tiles */} {Array.from({length:4}).map((_,i)=>( ))} ); } if (kind === "drift") { /* Drift Overland — rugged, black/cream, condensed type */ return ( DRIFT. OVERLAND ADVENTURE RENTALS · BC · EST. 2025 {/* horizon / mountain ridge */} {/* coords */} 49.16°N / 123.93°W ); } if (kind === "roots") { /* Alternate Roots Farm — warm earthy green, serifed wordmark, botanical hand-drawn lines */ return ( Alternate Roots SMALL FARM LIVESTOCK AND GARDENS · GABRIOLA ISLAND {/* botanical/root lines */} ); } /* mens — Gabriola Men's Group, warm, communal */ return ( Gabriola Men's Group. TUESDAYS · 7PM · THE COMMONS {/* circle of figures */} {Array.from({length:8}).map((_,i)=>{ const a = (i / 8) * Math.PI * 2 - Math.PI/2; const r = 38; const x = Math.cos(a) * r; const y = Math.sin(a) * r * 0.6; return ( ); })} ); }; /* ---------- ABOUT ---------- */ const About = () => { return (

About

A studio of one, on
a small island.

AR Communications is a one-person studio on Gabriola Island, off the east coast of Vancouver Island. It exists to make good design and reliable technology affordable for the kinds of organisations that hold rural communities together — co-ops, land trusts, community health organizations, libraries, small farms, family shops.

The work crosses two trades. Half of it is{" "} design — identity, websites, the printed things that go on a wall. The other half is{" "} tech — setting up small offices, running the cabling, untangling the email, keeping the backups honest. They sound like different jobs. They aren't. They're both the same answer to the same question: how do small organisations look and feel like they belong in this decade, without a corporate budget?

); }; /* ---------- CONTACT ---------- */ const Contact = () => { const [form, setForm] = React.useState({ name: "", org: "", email: "", scope: "Brand identity", message: "", }); const [status, setStatus] = React.useState("idle"); // idle | sending | sent | error const [errMsg, setErrMsg] = React.useState(""); const set = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value })); const submit = async (e) => { e.preventDefault(); if (status === "sending") return; setStatus("sending"); setErrMsg(""); try { const res = await fetch("https://formsubmit.co/ajax/hello@arcomm.ca", { method: "POST", headers: { "Content-Type": "application/json", "Accept": "application/json" }, body: JSON.stringify({ name: form.name, organisation: form.org, email: form.email, scope: form.scope, message: form.message, _subject: `New brief from ${form.name || "the website"} — ${form.scope}`, _template: "table", _captcha: "false", }), }); const data = await res.json().catch(() => ({})); if (res.ok && (data.success === "true" || data.success === true)) { setStatus("sent"); } else { throw new Error(data.message || "Couldn't send right now."); } } catch (err) { setStatus("error"); setErrMsg(err.message || "Couldn't send right now. Try email instead."); } }; return (

Contact

Tell me about
the work.

The best projects start with a phone call or a long email. Tell me what you're trying to do, and I'll write back within a working day.

hello@arcomm.ca Send a project brief
Studio

Gabriola Island, BC
Canada
By appointment

Hours

Tue — Fri · 09:00 — 17:00 PT
Reply within one working day

{status === "sent" ? (
Project brief — received

Thanks, {form.name || "friend"}.

Your brief is on its way. I'll get back to you at {" "}{form.email || "the email you provided"}{" "} within one working day.

) : (
Project brief
{["Brand identity","Web design","Office tech","Installation","Not sure yet"].map(s => ( ))}