Farholm is a thoughtful, independent travel-planning agency. The site is a
hand-crafted Eleventy static site + a Cloudflare Worker (the /trip portal
and /admin). There is no JS framework — semantic HTML, one stylesheet
(css/styles.css), self-hosted fonts, and a deliberately tight CSP. The brand's
edge is that it looks crafted and consistent, not template-generated. Your job
is to keep it that way.
Always work from the live source, not from memory:
css/styles.css — the single source of truth for tokens and components.brand.njk (renders at /brand) — the visual brand kit: palette, type, logo._data/site.json — name, tagline, contact, social, legal details._includes/ — page layouts/partials. Match existing page structure.If a value here ever disagrees with css/styles.css, the stylesheet wins —
update this skill.
A north-sea sunrise: deep teal anchored by a single rising-gold accent.
Tagline: "Discover your own story." The logo mark is a rising sun over a
horizon line (see the inline SVG in _includes/nav). The recurring visual motif
is the .horizon element — a thin horizon line with a gold sun — used under
hero headings. Reach for first light, coastal, quiet-fjords-to-city imagery,
never busy/loud/stocky travel clichés.
All color comes from CSS custom properties defined in :root in css/styles.css.
Never hardcode a hex value in new markup or styles — reference the token, so
dark mode and future retunes keep working.
| Token | Value | Role |
|---|---|---|
--ink |
#10393F |
Deep north-sea — headings, dark sections, body text |
--ink-2 |
#0C2E33 |
Darker ink — hero gradient base, ink-button hover |
--sea |
#1F5C5F |
Links, secondary accents, card icons |
--gold |
#E3A845 |
Primary CTA, the rising sun, accents on dark |
--gold-2 |
#D2962F |
Gold hover, eyebrow on light |
--slate |
#46605F |
Muted text, captions, card body |
--mist |
#E4EDE9 |
Alternate section background |
--fog |
#F4F7F5 |
Page background |
--white |
#FFFFFF |
Cards, surfaces |
Semantic tokens (--bg, --surface, --surface-alt, --text, --border,
--input-bg, --input-border, --shadow) are what most components should use —
they flip in dark mode. The raw brand colors above stay fixed so the
intentionally-dark sections (hero, footer, .section--ink) look identical in
light and dark. Rule of thumb: for surfaces/text that should adapt, use the
semantic token; only use a fixed brand color when you specifically want it the
same in both themes (e.g. gold accents, the dark bands).
var(--font-display) = Young Serif (with Georgia,
serif fallback). Warm, characterful, used for h1/h2/section titles.var(--font-body) = Albert Sans (system-sans
fallback). Weights in use: 400 / 500 / 600 / 700.letter-spacing: 0.22em./fonts/*.woff2, preloaded). Do not add Google
Fonts or any external font origin — it would violate the CSP and the
self-hosting decision.Sizes come from tokens — don't invent px values:
--size-hero, --size-h1, --size-h2, --size-h3 (1.3rem), --size-body
(1.0625rem), --size-small (0.9rem). Spacing/shape: --space-section,
--width-content (70rem), --width-prose (44rem), --radius (10px),
--shadow.
Compose pages from the existing classes. Before writing new CSS, check whether a
component already exists. Typical page = a stack of .sections, each opening with
an .eyebrow + Young Serif h2, inside a .container.
.section — vertical rhythm wrapper. Variants: .section--mist (alt
background), .section--ink (dark teal band; headings go white, links/eyebrow
go gold automatically)..container — centers content at --width-content. For long-form reading
(blog/advice), constrain text to --width-prose..page-hero — interior-page hero (dark, white h1, a .horizon in fog).
.hero — the homepage-only hero with the animated sun scene..eyebrow — small uppercase kicker above a heading. The brand signature
for section intros..horizon — the sunrise motif (a line + gold sun via ::before/::after).
.horizon--left for left alignment. Use sparingly, as a grace note..cards / .card — responsive card grid. A .card is a --surface panel
with an optional --sea SVG icon, an h3, --slate body copy, and an optional
link. Good for services, value props, testimonials..btn base + one of .btn--gold (gold bg / ink text — the
primary CTA, used once per view), .btn--ink (ink bg / white — secondary),
.btn--ghost (outline, for dark/hero backgrounds). Buttons lift 1px on hover..form — form layout; inputs use --input-bg/--input-border. Match the
existing contact/lookup forms..nav / .footer — site chrome; don't recreate, extend.Example — a standard content section:
<section class="section section--mist">
<div class="container">
<p class="eyebrow">Why Farholm</p>
<h2>Planning that starts with you</h2>
<div class="cards">
<article class="card">
<svg aria-hidden="true"><!-- 1.8 stroke, currentColor --></svg>
<h3>Considered, not packaged</h3>
<p>Every itinerary is built around how you actually like to travel.</p>
</article>
</div>
</div>
</section>
Considered, warm, and understated-premium. Plainspoken — confident without hard-selling. Short sentences. Concrete over superlative. Speak to a discerning traveller who values being known, not upsold.
Honesty in claims is a brand value — keep these established corrections:
Use _data/site.json for any contact detail, phone, social handle, or legal name
so it stays single-sourced. Refer to the company as Farholm (legal:
Farholm LLC).
These aren't optional polish; they're why the site is trustworthy and fast.
:root (and its dark-mode value), not inline.alt
on meaningful images (alt="" for decorative), labelled controls, visible
focus, sufficient contrast (gold-on-ink and ink-on-fog are the safe pairings;
avoid slate-on-mist for body text). Honor prefers-reduced-motion — the
stylesheet already disables smooth scroll under it; don't add motion that
ignores it.onclick=…), no
javascript: URLs, no new external origins for scripts/fonts/styles/images
beyond what the Worker's CSP already allows (see cspFor() in worker.js).
Prefer no JS at all; if behavior is needed, add it in an existing external
js/*.js file. Inline <style>/style attributes are tolerated by the current
policy but still prefer the stylesheet.@11ty/eleventy-img pipeline (responsive AVIF/WebP, lazy, fingerprinted) — see
the image shortcode in eleventy.config.js. Don't drop unoptimized JP/PNG into
templates.hashedAsset filter in templates (e.g. /css/styles.36299604.css),
not hardcoded paths.noindex/robots appropriately — keep new internal/tooling pages out of the
sitemap and search index.Verify with the repo's own gates before calling it done: npm run check
(syntax), npm test (Worker integration), npm run build (Eleventy). If a
web-quality/accessibility skill is installed, a quick a11y/SEO pass on new pages
is worth it. Keep this skill honest — if you change a token or add a core
component, update the relevant section above.