Overview#
Compass is a website for a leadership coach or consultant, built as a WordPress block theme. The
fictional brand is Bearing, the Pittsburgh coaching practice of Nadia Whitcombe, who coaches new
managers, founders and senior leaders. The theme has a home page with a cut-paper portrait, press
wordmarks, client types, count-up outcomes, a programs preview, the four-point method, a testimonial
carousel and a free guide sign-up; a programs page with 1:1 packages, a group cohort, team
workshops, a comparison table and an FAQ; a method page with an interactive compass and tabs, the
shape of a session and a six-month timeline; client results with filters and before-and-after
numbers; an about page; a resource library with a leadership self-check that recommends a program,
topic filters and a podcast; a sample article; a four-step booking flow with a calendar in the
visitor's time zone; a contact page with a map and a form; and a 404 page. It is version 1.0.0 (see
template.json and style.css), works with WordPress 7.1 and PHP 7.4 or newer, and is the
WordPress version of the HTML template of the same name. See it live at
freeframe.dev/templates/compass.
Headings, copy, cards, lists, buttons and images are core WordPress blocks arranged in block
patterns, so you edit them in the block editor without touching code. The interactive parts (the
testimonial carousel, the method compass, the filter chips, the self-check, the booking flow and
the forms) work as in the HTML version: they are small Custom HTML blocks driven by
assets/js/main.js. Colours and fonts are design tokens in theme.json: change them in
Appearance > Editor > Styles and the whole site follows.
Quick start#
Requirements: WordPress 7.1 or newer and PHP 7.4 or newer. No plugins are needed.
- Download
compass.zipfrom freeframe.dev/templates/compass (the WordPress tab). - In your WordPress admin go to Appearance > Themes > Add New Theme > Upload Theme, choose the zip and click Install Now, then Activate. The theme is listed as Freeframe Compass.
- Go to Appearance > Compass setup and click Create the demo pages. This creates the Home, Programs, Method, Results, About, Resources, the sample article ("How to delegate without disappearing"), Book a call and Contact pages from the theme's page patterns, sets Home as the front page (Settings > Reading) and creates the header menu. Pages that already exist with the same slug are left alone, so it is safe to click it again.
- Visit your site. Edit any page in Pages, and the header, footer and templates in Appearance > Editor.
You can also try the theme without installing anything: the Try it in WordPress button on freeframe.dev opens it in WordPress Playground (WordPress running in your browser) with the demo pages already set up.
To work on the theme's files locally you need Node.js 24 and pnpm; WordPress itself runs in WordPress Playground, so there is no PHP, web server or database to install:
pnpm install
pnpm dev # builds the CSS, then starts WordPress with the theme at http://127.0.0.1:9400pnpm dev signs you in as admin (password password) and creates the demo pages. The site is
rebuilt from scratch every time you start it; your edits to theme files are live, edits made in the
WordPress admin are not kept.
Pages#
Each page is a page pattern (in Patterns > Compass pages) made of section patterns. Every section is also offered on its own in the block inserter under Patterns > Compass.
| Page | Slug | Page pattern | Sections (pattern files in patterns/) |
|---|---|---|---|
| Home | / |
page-home.php |
home-hero (portrait, intro call and 92% cards), press, who-its-for, outcomes (count-up stats), programs-preview, method-preview, testimonials (carousel), lead-magnet (guide sign-up), home-cta |
| Programs | /programs/ |
page-programs.php |
programs-hero (section links), one-to-one (Foundations and Executive, strategy session), cohort, teams, compare (table), faq, programs-cta |
| Method | /method/ |
page-method.php |
method-hero, framework (compass and tabs), session, timeline, bring |
| Results | /results/ |
page-results.php |
results-hero (ratings), stories (filters and eight client stories), pull-quote, results-cta |
| About | /about/ |
page-about.php |
about-hero, story (studio illustration and quote), path, credentials, values, outside (with the closing call to action) |
| Resources | /resources/ |
page-resources.php |
resources-hero, quiz (the self-check), library (topic filters and twelve resources), podcast, guide (sign-up) |
| How to delegate without disappearing | /article/ |
page-article.php |
article-body (header, illustration, the article and the author card), related |
| Book a call | /book/ |
page-book.php |
book-hero, booking (the four steps and the summary) |
| Contact | /contact/ |
page-contact.php |
contact-hero, contact-form (map, details and form), other-ways |
| 404 | any missing URL | templates/404.html |
404 |
Posts use templates/single.html; the blog, archives and search results use
templates/index.html, templates/archive.html and templates/search.html. The sample article is
a page, like the HTML version's article.html; write your own articles as posts or as pages with
the Page with title template.
Project structure#
freeframe-compass/
style.css theme header (name, version, requirements, license); no styles
theme.json design tokens: palette, fonts, spacing, layout widths, button
functions.php loads the files in inc/
inc/setup.php stylesheet and script (with its strings and page links), editor
styles, the `js` class script, theme colour and favicon, pattern
categories
inc/icons.php registers assets/icons/*.svg for the Icon block
inc/icon-labels.php the icons' names shown in the editor
inc/block-styles.php button block styles
inc/site-setup.php Appearance > Compass setup: creates the demo pages and the menu
templates/ page.html (pages), page-with-title.html, single.html, index.html,
archive.html, search.html, 404.html
parts/ header.html and footer.html (they show the header and footer patterns)
patterns/ every section and page (PHP files with block markup)
assets/css/theme.css the compiled stylesheet (do not edit: built from src/)
assets/css/editor.css the same for the block editor (generated by src/editor-css.mjs)
assets/js/main.js menu, carousel, filters, method compass, self-check, booking, forms...
assets/icons/ SVG icons for the Icon block
assets/img/ portrait, studio, guide cover, logo, favicon, social image
assets/fonts/ Source Serif 4 and Instrument Sans, with their licenses
src/theme.css the Tailwind CSS source of assets/css/theme.css
src/icons.css icons drawn before or after text with CSS (generated)
src/editor-css.mjs writes assets/css/editor.css after each build
languages/ freeframe-compass.pot, the template for translations
blueprint.json WordPress Playground setup used by `pnpm dev`
screenshot.png the picture shown in Appearance > Themes
package.json the CSS build and the local WordPress (Node.js tooling)
readme.txt, README.md, DOCS.md, CHANGELOG.md, LICENSE.txtCustomising#
Brand and colours#
The colours are in theme.json (settings.color.palette) and in Appearance > Editor > Styles >
Colors > Palette:
| Colour | Default | Used for |
|---|---|---|
| Ivory | #fbf8f3 |
the page background |
| Linen 50 to 300 | #f6f1e8 to #cfbfa6 |
soft section backgrounds, cards, borders |
| Stone 500 to 800 | #857a6b to #342e26 |
body copy and muted text (600 or darker for small text) |
| Dusk 50 to 950 | #eef0f7 to #151a31 |
the brand indigo: buttons (800), links (700), dark sections (900) and the footer (950) |
| Marigold 100 to 700 | #fbecc9 to #855712 |
the warm accent: stars, highlights, buttons on dark backgrounds (300); text on light backgrounds (700) |
| Clay 100 to 700 | #f5e3da to #8a4a33 |
tags and illustrations |
| White, Black | for your own blocks |
The theme's stylesheet reads these colours from the palette (bg-dusk-800, text-marigold-700...),
so changing Dusk 800 in Styles recolours every primary button at once. To move to another brand
colour, change the whole Dusk scale together, and keep Marigold 700 and Stone 600 dark enough for
text on Ivory (4.5:1). The illustrations (assets/img/*.svg) and the SVGs in Custom HTML blocks
(the method compass, the press wordmarks, the map, the podcast cover, the article illustration, the
404 compass and the footer wordmark) carry their own hex colours: search for the old values (for
example #2a3259 and #f0c464) to change them too.
The dark sections with a warm glow use the class on-dark dusk-glow (a gradient in
src/theme.css): add both to a Group's Additional CSS class(es). card gives a group the white
card look and ff-grain the dotted paper texture of the page headers.
Typography#
Two fonts are bundled in assets/fonts/ and declared in theme.json
(settings.typography.fontFamilies), so no request goes to Google: Source Serif 4 (variable,
300 to 600, with italics; preset serif) for headings, numbers and quotes, and Instrument Sans
(variable, 400 to 700; preset sans) for text. To use other fonts, install them in Styles >
Typography > Fonts (the Font Library) and select them, or replace the fontFace entries in
theme.json. The utility classes read the presets (--wp--preset--font-family--serif and
--sans), so keep those slugs. The SVGs with text name the fonts directly
(font-family="'Source Serif 4', Georgia, serif").
The classes display (the serif with tight tracking, for big headings), accent-em (the indigo or
marigold italic accent inside a heading), eyebrow (small caps label with a compass star) and
lede (the larger intro paragraph) give text the template's styles.
Content#
Edit pages in Pages: click any text to change it, select a button to change its link. Sections are groups; open List View (the stacked lines icon at the top left) to select a section, move it, duplicate it or delete it. To add a section from another page, use the block inserter (+) > Patterns > Compass.
What the script drives, and pictures drawn in SVG with text, are Custom HTML blocks: edit those
in the block's HTML view, and keep their ids and data- attributes.
| Pattern | Custom HTML | What it is |
|---|---|---|
home-hero |
the compass ring, the client initials, the star rating line, the 92% bar | decorative pictures and text |
press |
the five wordmarks | SVG logos drawn with the theme's fonts |
testimonials |
the carousel buttons and the six testimonials | see Testimonial carousel |
lead-magnet, guide |
the sign-up form and its success message | see Forms |
compare |
the comparison table | a table in a scrollable region |
framework |
the compass drawing, the four tabs and their panels | see Method compass |
session, stories |
the coloured bars | bars drawn with empty elements |
stories, library |
the filter chips, the count and the empty message | see Filters |
quiz |
the self-check | see Leadership self-check |
podcast, article-body, contact-form, 404 |
the podcast cover, the article illustration, the map, the 404 compass | SVG pictures |
article-body |
the breadcrumb | a short list of links |
booking |
the four steps and the summary | see Booking flow |
contact-form |
the form and its success message | see Forms |
header, footer |
the menu button, the Bearing wordmark | driven by the script; decorative |
Some blocks carry classes (Block settings > Advanced > Additional CSS class(es)) that the script
reads. Blocks can't store data- attributes or hidden, so the script turns classes starting with
ffd- into attributes when the page loads, and ff-hidden into hidden: ffd-tags--founders on
a client story becomes data-tags="founders", and ffd-tags--executives_teams becomes
data-tags="executives teams".
revealfades a block in as it scrolls into view (reveal-delay-1to-3stagger it).link-cardon a group makes the whole group clickable: the first link inside it stretches over the group (the related reads under the article, the logo).card,tag,tag-dusk,tag-marigold,tag-clay,chipandlink-arroware the template's card, tag, chip and arrow link looks.
Programs and prices appear on the Programs page, in the home page preview, in the comparison table
and in PROGRAMS in assets/js/main.js (used by the self-check result); keep them in step when you
change a price.
Cohort dates. First 90 Days cohorts start on the second Wednesday of January, April, July and
October. COHORT_DATES near the top of assets/js/main.js is null in the demo, which shows rolling
dates: the first start at least COHORT_MIN_WEEKS (6) weeks away and the one after it, so the demo
never advertises a cohort that has started. Set { next: '2027-01-13', after: '2027-04-14' } for your
real dates. The script fills in every <span data-cohort="next"> (or "after") in the format of
data-cohort-format: full ("Wednesday, January 13, 2027"), long, month ("April 2027") or
season ("Winter 2027"). They are in the Programs preview and Cohort patterns; the dates written there
are shown without JavaScript, so keep them in step once you set real dates.
Adding a client story
On the Results page, select a story card (an Article group with the class
card reveal ... ffd-tags--founders, for example) in List View and duplicate it. Change the tag,
the program line, the headline, the text, the three before/after numbers and the client. The
ffd-tags-- value must be one of the chip filters (managers, founders, executives, teams,
career); join several with an underscore (ffd-tags--executives_teams). The counts on the chips
are worked out by the script; update the "8 stories" text in the count's Custom HTML, which shows
before the script runs. The bars under each number are a Custom HTML block: set their width
percentages to match.
Adding a resource
On the Resources page, duplicate a library card the same way. Its topic class is ffd-tags-- with
one of delegation, feedback, confidence, strategy or career. The "Read →" link at the
bottom of the card stretches over the whole card.
Images and artwork#
The portrait (nadia-portrait.svg, 480 × 600, used on the home, about, article and booking pages),
the studio illustration (studio.svg, 800 × 560) and the guide cover (guide-cover.svg,
360 × 460) are SVG files in assets/img/, used by Image blocks: select one and Replace it with a
photo of the same proportions. The portraits inside the article byline, the author card and the
booking summary are in Custom HTML (the booking flow) or Image blocks; replace them the same way.
Icons are Icon blocks: select one and pick another from the Compass collection or WordPress's
own. The logo is assets/img/logo.svg in an Image block next to the Bearing name in the header and
footer patterns. The social image is assets/img/og-image.png (1200 × 630, source
og-image.svg); the favicon assets/img/favicon.svg is used until you set a Site Icon in
Settings > General.
The press wordmarks, the method compass, the map, the podcast cover, the article illustration and the 404 compass are inline SVG in Custom HTML blocks, so their labels use the theme's fonts. Replace any of them with an Image block if you prefer a picture, and only list publications that have really featured you.
Navigation, header and footer#
The header and footer are template parts (parts/header.html, parts/footer.html) showing the
header and footer patterns. Edit them in Appearance > Editor > Patterns > Header / Footer.
The header has two Navigation blocks showing the same menu: the desktop one and the one in the
mobile menu. Edit the menu once in Appearance > Editor > Navigation (the setup creates "Main
menu": Home, Programs, Method, Results, About, Resources, Contact, Book a free intro call). Its
first link (Home) and last link (Book a free intro call) are hidden in the desktop header,
which has the logo and its own "Book a free call" button; keep them first and last, or remove the
.site-nav … :first-child and :last-child rules in src/theme.css. A Navigation block that
doesn't point at a menu shows the most recently created one; to pin a menu, select the Navigation
block and choose it in the block settings, for both blocks. WordPress marks the current page in the
menu; on the article, the script marks Resources, and on the booking page the header button.
The footer's Coaching and Practice menus are List blocks: click a link to change it, press Enter to
add one. The social links are Button blocks with the Icon only style; their text stays for
screen readers, and the icon comes from the class (icon-before-linkedin, icon-before-instagram,
icon-before-podcast). The email address, phone number and studio address also appear on the
contact page; search for them when you change them.
Features#
Booking flow#
The Book a call page walks through four steps: call type, date and time, your details, and a confirmation, with a summary card beside them that follows every choice.
-
Where the code is: the
CALL_TYPESandAVAILABILITYsettings near the top ofassets/js/main.jsandinitBooking()further down. The markup is thebookingpattern's Custom HTML ([data-booking]). -
The data:
jsvar CALL_TYPES = { intro: { label: __('Free intro call'), minutes: 20, price: __('Free'), where: __('Video call') }, strategy: { label: __('Strategy session'), minutes: 60, price: __('$180'), where: __('Video call or the Pittsburgh studio') }, team: { label: __('Team workshop discovery'), minutes: 30, price: __('Free'), where: __('Video call') } }; var AVAILABILITY = { timeZone: 'America/New_York', zoneName: __('Eastern Time'), hours: { 1: [['09:00', '12:00'], ['13:30', '17:00']], /* ... */ 5: [['09:00', '12:30']] }, slotStep: 30, minNoticeHours: 24, daysAhead: 45, closed: ['2026-11-26', '2026-11-27', /* ... */ '2027-01-01'], demoBusyShare: 0.35 };hoursis keyed by weekday (0 is Sunday) in the studio's time zone; a slot fits when the whole call ends before its window closes.demoBusySharehides a stable share of the slots so the demo looks booked; set it to0when you connect real availability. Keep the call type cards in the pattern (name="call-type",value="intro"...) in step withCALL_TYPES. -
Time zones: times are shown in the visitor's time zone, with the studio time underneath and a Show times in menu to switch to studio time; a slot that falls on another day there is marked
(+1 day)or(−1 day). -
Links in:
/book/?type=strategy(orteam) preselects a call type, as the programs page does. -
The last step shows the request, says that nothing was booked, and offers Save a calendar hold (.ics), an event file made in the browser.
-
Accessibility: each step's heading receives focus when the step changes, and the step list marks the current step with
aria-current="step". Calendar days are buttons with full-date labels that include the number of open times; only one day is in the tab order, the arrow keys move by day and week, Home and End go to the start and end of the week, and Page Up and Page Down move four weeks. Times are radio buttons in a fieldset, and a missing date or time shows arole="alert"message.
To take real bookings, replace the booking section with an embed from Cal.com or Calendly (a
Custom HTML block with their inline embed code), or keep the flow and send the details from step 3
to a form service, see Forms.
Leadership self-check#
The quiz section on the Resources page (/resources/#quiz) asks six questions, one at a time
with a progress bar and Back and Next buttons, and shows one of four leadership patterns, three
things to try this week, a bar for each pattern and the recommended program.
- Where the code is:
QUIZ_QUESTIONS,QUIZ_RESULTSandPROGRAMSat the top ofassets/js/main.js, and the "Self-check quiz" block further down. - Scoring: each answer points to a result type (
doer,pleaser,firefighter,island); the type with the most answers wins, and ties go to the type listed first inQUIZ_RESULTS. Each result'sprogramis a key ofPROGRAMS, whose link goes to the matching section of the Programs page. - Changing it: edit the arrays (in a child theme, see Child themes); the four
pattern cards on the intro screen are text in the
quizpattern's Custom HTML. If you change the questions, renameQUIZ_KEYso old saved answers are ignored. - Recommended badges: on the Programs page, the badges "Recommended by your self-check" (class
ffd-recommended ff-hidden) are shown inside the block whoseffd-program--class matches the saved result:foundations,executive,cohortorteams. - Accessibility: each question is a fieldset of radio buttons whose legend receives focus;
choosing nothing shows an inline
role="alert"message; the result heading receives focus.
Method compass#
On the Method page the four tabs (role="tablist", with arrow keys, Home and End) show one panel
each, and the compass drawing turns its needle to the selected point by the shortest route.
Clicking a point in the drawing selects its tab. The drawing is hidden from assistive technology,
which uses the tabs. Both are the framework pattern's Custom HTML; edit the panels there.
Filters#
The Results and Resources pages filter their cards with chip buttons (aria-pressed): the count
(aria-live="polite") says how many are shown, and the choice is written to the URL (?type= on
Results, ?topic= on Resources), so filtered views can be shared and linked (the programs page
links to /results/?type=founders, the article to /resources/?topic=delegation#library). The
chips are in the sections' Custom HTML (data-filter="founders"); the cards carry their tags as
classes, see Adding a client story.
Testimonial carousel#
The home page carousel is a horizontal scroll-snap list, so swiping, trackpads and the arrow keys
(once the list is focused) all work; the Previous and Next buttons move by one card and switch off
at the ends, and the "1 / 6" counter is visual only. It never moves on its own. To add a
testimonial, copy an <li> in the testimonials pattern's Custom HTML and update the
aria-labels ("7 of 7").
FAQ accordion#
The FAQ on the Programs page is an Accordion block (WordPress's own, with its keyboard support
and ARIA): add a question by duplicating an item in List View. The first answer is open when the
page loads (Open by default in the item's settings). The round plus/minus button is drawn by
CSS (.wp-block-accordion-heading__toggle::after in src/theme.css).
Count-up stats, scroll reveals and motion#
Blocks with reveal fade and rise into view. Numbers inside <span data-count="340">340</span>
(with data-decimals="1" for one decimal) count up once when they appear: edit the number and its
data-count together in the paragraph's HTML view. The 404 needle wanders with a CSS animation and
the hero compass ring turns in once. All motion is skipped when the visitor prefers reduced motion,
and nothing is hidden without JavaScript.
Header, mobile menu and back to top#
The header is sticky and gains a border and shadow after scrolling. Below 1024 px the menu button
opens the mobile menu, updating aria-expanded and its label; Esc closes it and returns focus to
the button. A back-to-top button appears after about one screen of scrolling and steps aside while
the footer's "Back to top" link is visible. To remove it, delete the "Back to top" part at the end
of assets/js/main.js and the .back-to-top styles in src/theme.css, then run pnpm build.
Block styles#
In the block settings' Styles panel:
| Block | Styles |
|---|---|
| Button | Fill (default, the dusk button), Marigold, Outline, Outline (on dark), Icon only |
The classes is-large and is-small on a Button block make it the hero or compact size. Icons on
buttons and links are classes too (icon-before-calendar, icon-after-arrow-right, with
icon-size-20); see src/icons.css for the available icons.
Forms#
There are four forms. All validate in the browser and none sends anything until you connect it; their success messages say so.
| Form | Where | Validation |
|---|---|---|
Guide sign-up (data-guide-form) |
Home, Resources | first name, email |
Contact (data-contact-form) |
Contact | name, email, optional phone (7+ digits if filled), topic, message (20+ characters) |
Booking details (data-booking-form) |
Book a call, step 3 | name, email, role, message (20+ characters), consent box |
Self-check (data-quiz-form) |
Resources | an answer before moving on |
Validation reads the data-validate attributes (required, email, phone-optional, message,
consent) in the forms' Custom HTML; the messages are in fieldMessage() in
assets/js/main.js. Errors appear under each field, linked with aria-describedby, and the first
invalid field gets focus.
To collect messages, use a form plugin (replace the form's Custom HTML block with the plugin's
block; add the classes label, input and btn btn-primary to its labels, fields and button), or
send the form in assets/js/main.js (in a child theme). Find the comment "Connect a real endpoint
here" in the guide and contact form handler, for example for Formspree:
form.addEventListener('submit', function (e) {
e.preventDefault();
if (!validateForm(form)) return;
fetch('https://formspree.io/f/your-form-id', { method: 'POST', body: new FormData(form), headers: { Accept: 'application/json' } })
.then(function (res) {
if (!res.ok) throw new Error('Send failed');
form.hidden = true;
success.classList.remove('hidden');
success.focus();
})
.catch(function () { alert('Sorry, something went wrong. Please email hello@bearing.example.'); });
});For the guide sign-up you can instead post to your email tool (Kit, Mailchimp, Buttondown). For the
booking request, post the details plus state.type and state.slot.at.toISOString() in the
[data-booking-form] submit handler in initBooking() before goTo(4). Then change the "This is
a demo, so nothing was sent" text in the patterns.
Saved data (localStorage)#
| Key | Shape | Written |
|---|---|---|
compass-quiz-v1 |
{"answers": [0, 2, 1, 0, 3, 2], "date": "2026-10-12"} |
when the self-check is finished |
This is the HTML version's key. readQuiz() validates it on every read: answers must be an array
with exactly one whole-number answer index per question, each in range; anything else is ignored.
The result is always recalculated from the answers. Retake the self-check removes the key; to
clear it yourself, delete it in your browser's developer tools (Application > Local Storage). If
storage is blocked, the self-check still works but isn't remembered.
SEO and sharing#
Page titles come from WordPress: the page title, an em dash and the site name (for example
"Programs — Bearing Leadership Coaching"); the home page shows the site name and tagline
(Settings > General). The theme doesn't output meta descriptions or Open Graph tags; use an SEO
plugin such as Yoast SEO, Rank Math or The SEO Framework, and give it assets/img/og-image.png (or
your own 1200 × 630 image) as the default social image. WordPress already generates a sitemap at
/wp-sitemap.xml. A coaching practice benefits from ProfessionalService or Person structured
data with your name, address and services; most SEO plugins can add it.
Accessibility#
Built in: a skip link to the main content (added by WordPress, styled by the theme), landmarks
(header, labelled navigation, main, footer), one h1 per page, labelled sections, visible focus
rings, the menu button with aria-expanded and a label that changes with its state, filter chips
with aria-pressed and a live count, accessible tabs for the method, the Accordion block for the
FAQ, a carousel that never moves on its own, a keyboard-operable calendar, form errors announced
through aria-describedby and aria-invalid, alt text or aria-hidden on every picture, and
reduced-motion support for every animation. Small text uses Stone 600 or darker for contrast. The
demo passes axe (WCAG 2.1 A and AA).
When you edit: keep one Heading 1 per page, give images alt text (or mark them decorative), keep
link text meaningful, keep the aria-controls ids of the tabs in step with their panels, and label
any field you add to a form (<label for="...">).
Building and deploying#
You only need this if you change the theme's files. The stylesheet assets/css/theme.css is
compiled with Tailwind CSS from src/theme.css and the classes used in patterns/, parts/,
templates/, inc/ and assets/js/:
pnpm install
pnpm build # compile assets/css/theme.css and assets/css/editor.css
pnpm watch # recompile assets/css/theme.css on every change (run pnpm build before you commit)Run pnpm build after adding a utility class to a pattern, template or the script's markup,
otherwise the class has no style. Classes you type in the editor's Additional CSS class(es)
field are only styled if the stylesheet already contains them.
To deploy, zip the theme folder (named freeframe-compass, without node_modules/) and upload it
in Appearance > Themes, or copy the folder to wp-content/themes/ on your server.
Translations#
The theme is translation-ready with the text domain freeframe-compass. All text in patterns,
templates and PHP goes through WordPress's translation functions; the script's strings (the
self-check questions and results, the programs, the call types, the booking lines, form errors and
messages) are translated in PHP (freeframe_compass_script_strings() in inc/setup.php). Create a
translation with Loco Translate, or with WP-CLI and Poedit:
wp i18n make-pot wp-content/themes/freeframe-compass wp-content/themes/freeframe-compass/languages/freeframe-compass.potSave freeframe-compass-de_DE.mo (for example) in wp-content/languages/themes/ or in the theme's
languages/ folder. Page content created by Compass setup is copied into your pages in the site's
language at that moment; translate it in the editor like any other content. Dates in the booking
flow and the self-check are formatted in US English by the script (toLocaleDateString('en-US')).
Child themes#
Use a child theme for changes you want to keep when Compass is updated (your availability, call
types and self-check in particular). Create wp-content/themes/compass-child/style.css:
/*
Theme Name: Compass Child
Template: freeframe-compass
*/Templates, parts, patterns and theme.json in the child theme override the parent's files of the
same name. To use your own copy of assets/js/main.js, dequeue the parent's script
(freeframe-compass) and enqueue yours in the child's functions.php, keeping the inline
window.freeframeCompass strings and page links (or copy them). The parent's stylesheet only
contains the classes the parent uses: if your child theme uses new utility classes, compile a
stylesheet for the child (copy package.json and src/theme.css, point the @source lines at the
child's folders) and enqueue it.
Troubleshooting#
- The pages look unstyled or new classes do nothing. The stylesheet only contains classes it
found when it was built. Run
pnpm buildafter editing patterns, then reload. - "This block contains unexpected or invalid content". A pattern or page was edited by hand with markup that doesn't match the block. Click Attempt recovery, or re-insert the section from Patterns > Compass.
- No time slots on any day. Check that
AVAILABILITY.hoursuses weekday numbers 0 to 6 and"HH:MM"strings, that the call lengths fit inside each window, and thatdaysAheadis larger thanminNoticeHours/ 24. Use an IANA time zone such asAmerica/New_York, not an offset. - A new story or resource doesn't show up under a filter. Its group needs the class
ffd-tags--<value>with one of the chips'data-filtervalues. See Adding a client story. - The self-check always shows an old result. It is saved in the browser: click Retake the
self-check, and rename
QUIZ_KEYwhen you change the questions. See Saved data. - Home or Book a free intro call is missing from the desktop menu. The desktop header hides the menu's first and last links. See Navigation, header and footer.
- Compass setup says the pages exist, but they are empty. It never overwrites existing pages. Delete (and empty the trash of) the pages with those slugs, or open each page and insert its page pattern from Patterns > Compass pages.
- The forms or the booking flow don't send anything. They are demo forms; see Forms.
License#
MIT, which is compatible with the GPL that WordPress requires (see LICENSE.txt in the theme
folder). Free for personal and commercial use. The portrait, studio, guide cover, compass, map,
podcast cover and logo illustrations are included under the same license. Source Serif 4 and
Instrument Sans are licensed under the SIL Open Font License 1.1 (OFL.txt in each folder of
assets/fonts/). All people, clients, companies and publications named in the demo are fictional.