Overview#
Orbit is a bright, friendly SaaS website built as a WordPress block theme. The demo company is
Orbit, a fictional shift-scheduling app for restaurants, cafés, hotels and shops. The theme has a
home page that opens on an interactive week schedule (visitors click, drag and auto-fill shifts while
coverage updates live), followed by a product tour, customer results and an integrations orbit; a
features page with six deep-dives and a comparison against spreadsheets; pricing with a
monthly/annual switch, a per-location and per-employee price calculator, a comparison table and an
FAQ; a searchable integrations directory with a detail drawer; filterable customer stories; a
changelog; an about and careers page; a sales form that routes visitors by team size; a three-step
free trial sign-up 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/orbit.
Everything you see is made of core WordPress blocks arranged in block patterns, so you edit text,
links, buttons, lists and images in the block editor without touching code. Colours, fonts and font
sizes are design tokens in theme.json: change them in Appearance > Editor > Styles and the whole
site follows. The schedule demo's rules, the prices the calculator uses and the sales routing are
data at the top of assets/js/main.js (see Script data).
Quick start#
Requirements: WordPress 7.1 or newer and PHP 7.4 or newer. No plugins are needed.
- Download
orbit.zipfrom freeframe.dev/templates/orbit (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 Orbit.
- Go to Appearance > Orbit setup and click Create the demo pages. This creates the pages below 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.
- Set the site title and tagline in Settings > General (the demo uses "Orbit" and "Shift scheduling for restaurants, cafés and shops"), then 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 > Orbit pages) made of section patterns. Every section is also offered on its own in the block inserter under Patterns > Orbit.
| Page | Slug | Page pattern | Sections (pattern files in patterns/) |
|---|---|---|---|
| Home | / |
page-home.php |
home-hero (schedule demo), logo-strip, old-way, highlights, product-tour (tabs), testimonials, integrations-orbit, home-cta (count-up numbers) |
| Features | /features/ |
page-features.php |
features-hero (section links), builder, availability, swaps, labor, time-clock, messages, compare (table), features-cta |
| Pricing | /pricing/ |
page-pricing.php |
pricing-hero (billing switch), plans, calculator, plan-comparison (sticky table), faq |
| Integrations | /integrations/ |
page-integrations.php |
integrations-hero, directory (search, filters, cards), api, integration-drawer |
| Customers | /customers/ |
page-customers.php |
customers-hero, featured-story (chart), stories (industry filter), customers-cta |
| Changelog | /changelog/ |
page-changelog.php |
changelog-hero, releases (topic filter, updates form) |
| About & careers | /about/ |
page-about.php |
about-hero, numbers, values, team, careers (open roles), offices |
| Talk to sales | /contact/ |
page-contact.php |
contact (who you'll talk to, sales form) |
| Start free trial | /signup/ |
page-signup.php |
signup (three-step form) |
| 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. For a plain text page (privacy policy, terms)
choose the Page with title template in the page's settings.
Project structure#
freeframe-orbit/
style.css theme header (name, version, requirements, license); no styles
theme.json design tokens: palette, fonts, font sizes, layout, button
functions.php loads the files in inc/
inc/setup.php stylesheet and script, editor styles, the "js" class script, theme colour,
script strings and page URLs, pattern categories
inc/icons.php registers assets/icons/*.svg for the Icon block
inc/icon-labels.php the icons' names shown in the editor (generated)
inc/block-styles.php the Coral, Ghost, Pill, Ink outline and Light outline button styles
inc/site-setup.php Appearance > Orbit 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 the site's JavaScript and its data (schedule demo, prices, sales routing)
assets/icons/ SVG icons for the Icon block
assets/img/ logo, favicon, portraits (people/), social image
assets/fonts/ Rethink Sans and Gabarito and their licenses (OFL.txt)
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-orbit.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:
| Colours | Used for |
|---|---|
| Base (Paper), Cream, Sand, Line | the warm page background, alternate panels and inputs, hover states and tracks, hairlines and card borders |
| Contrast (Ink), Ink soft, Ink faint | headings, body text and the primary buttons; secondary text; captions (all AA on every surface) |
| Coral 100 to Coral 700 | the brand accent: 500 for fills (the coral call to action, the logo's planet), 700 for links on light surfaces |
| Peach, Mint, Lilac, Butter, Sky, Blush and their inks | the pastel panels, shift blocks, chips and chart colours, each with a deep ink for text on top |
| White | cards and plain white for your own blocks |
The stylesheet reads these colours from the palette (--color-coral-500 is
var(--wp--preset--color--coral-500) in src/theme.css), so changing Coral 500 in Styles changes
every utility that uses it. A few colours are written into artwork: the logo
(assets/img/logo.svg), the portraits, the customer and integration logos and the product
illustrations (Custom HTML), the pastel mesh behind page headers (.ff-mesh in src/theme.css), the
schedule demo's coverage ring (initScheduleDemo() in assets/js/main.js) and the browser bar colour
(freeframe_orbit_head_meta() in inc/setup.php).
Orbit is light only: there is no dark mode, and color-scheme: light is set so form controls and
scrollbars stay light too.
Typography#
Text uses Rethink Sans (variable, weights 400 to 700, with an italic) and headings, numbers and
labels Gabarito (500 to 800, the font-display class). The fonts are bundled in assets/fonts/
and declared in theme.json (settings.typography.fontFamilies), so no request goes to Google. To
use other fonts, install them in Appearance > Editor > Styles > Typography > Fonts (the Font
Library) and select them, or replace the fontFace entries in theme.json; the stylesheet reads
--wp--preset--font-family--rethink-sans and --gabarito, so rename those slugs only together with
src/theme.css.
Font sizes are the presets in theme.json (xs 0.75rem to 9xl 8rem, the Tailwind scale). The
stylesheet uses them too: changing Large in Styles changes every text-lg in the design.
Content#
Edit pages in Pages: click any text to change it, select a button to change its link, select an image and use Replace. Sections are groups; open List View to select a section, move it, duplicate it or delete it. To add a section from another page, use the block inserter (+) > Patterns > Orbit.
Some content is in Custom HTML blocks, because blocks can't express it or a script drives it: edit those in the block's HTML view.
| Pattern | Custom HTML | What it is |
|---|---|---|
home-hero |
the schedule demo and its legend, the avatars and the star rating | see Schedule demo |
logo-strip, featured-story, stories |
the customer wordmarks, the overtime chart | SVG artwork set in the site's fonts |
old-way, highlights, builder to messages, integrations-hero, integrations-orbit, api, releases, about-hero, offices, 404 |
the illustrations | product screens drawn in HTML/SVG; replace with an Image block |
product-tour |
the tabs and their screens | see Product tour |
compare, plan-comparison |
the tables | see Pricing switch and calculator |
pricing-hero, calculator |
the billing switch, the calculator and its result | see Pricing switch and calculator |
directory, integration-drawer |
the search and filters, the integration cards with their details, the drawer | see Integrations directory and drawer |
stories, releases |
the filter buttons, the result line, the empty state | see Customer stories and changelog filters |
contact, signup, releases, footer |
the forms, the routing panel, the plan line | see Forms |
features-cta |
the logo | |
header |
the menu button | driven by assets/js/main.js |
A few blocks carry a class (Block settings > Advanced > Additional CSS class(es)) that the script or stylesheet reads:
revealfades a block in as it scrolls into view;reveal-d1toreveal-d3delay it.link-cardon a group makes the whole group clickable: the first link inside it stretches over the group (the logo in the header and footer, the integration links on the home page, the open roles).ff-doton an eyebrow label draws its coral dot;marker(andmarker-peach,marker-mint,marker-lilac) on a word in a heading draws the highlighter stroke.ff-mesh(withff-mesh-80,-70or-60for a lighter mesh) on a page header section draws the pastel background;ff-hero-ringdraws the home hero's dotted ring;ff-cta-ringsdraws the rings of the coral call to action;ff-timeline-dotdraws a changelog update's dot.ffd-count--4200on a number makes it count up to 4200 when it scrolls into view.ffd-filter-item--customers(or--changelog) andffd-tag--<topic>on a story or update: see Customer stories and changelog filters.
Script data#
assets/js/main.js starts with the data its features use:
| Constant | Contents |
|---|---|
DEMO |
The schedule demo's rules: shiftHours, maxHours (the overtime warning and the auto-fill limit), needs (people per shift per day, Monday first), day names, shift labels, times and spoken descriptions |
PRICING |
Per-location and per-employee prices of the Team and Business plans (monthly, annual), the free Starter limits and the employee count that suggests Enterprise |
CONTACT_ROUTES |
Who answers each team size on the sales form: avatar, name, role, text, time and whether to offer the free trial |
PLAN_LABELS, TRIAL_DAYS |
The plan names shown on /signup/?plan=… and the trial length |
FREE_EMAIL |
Free email providers the sales form rejects |
For example, to need three people on Saturday mornings:
needs: { am: [2, 2, 2, 2, 2, 3, 2], pm: [1, 1, 1, 1, 2, 2, 1] },The schedule's people and starting shifts are the demo's Custom HTML (one tr data-person per
person, data-shift on each cell). The prices shown in the plan cards and the comparison table are
blocks: change them there too when you change PRICING, and the Team and Business prices in the
price text's data-price-monthly and data-price-annual attributes (Code editor view). Make changes
to assets/js/main.js in a child theme (see Child themes) so a theme update doesn't
overwrite them.
Images and artwork#
- Portraits of the customers and the team are SVG illustrations in
assets/img/people/, shown with Image blocks. Replace them with photos with Replace: square, at least 400 × 400. - Illustrations (the schedule and app screens, the integrations orbit, the 404 artwork) are HTML/SVG in Custom HTML blocks: replace them with an Image block (a screenshot of your product, about 4:3).
- Customer and integration logos are SVG in Custom HTML blocks; replace each
<svg>with your logo (an<img>works too). - Icons are Icon blocks: select one and pick another icon from the Orbit collection or
WordPress's own. Arrows in buttons and links are drawn by CSS: the class
icon-after-arrow-rightadds one; the available names are insrc/icons.css. - Logo: the header and footer show
assets/img/logo.svgin an Image block next to the site title (shown in lower case, as in the design). Edit both in Appearance > Editor > Patterns > Header (and Footer). - Social image:
assets/img/og-image.png(1200 × 630, sourceog-image.svg); see SEO and sharing. - Favicon:
assets/img/favicon.svgis used until you set a Site Icon in Settings > General.
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" with Product, Integrations, Customers, Pricing, Company, Changelog and Talk to sales). The last
two links only show in the mobile menu, as in the HTML version, because the desktop header has its
own Talk to sales link and Start free trial button next to the menu
(.site-nav … :nth-child(n+6) 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's menu link (aria-current="page"); the script marks the header's
Talk to sales link and the footer's links the same way. The footer's link columns are List blocks:
click a link to change it, press Enter to add one. The copyright year is the current year.
Features#
Schedule demo#
The hero of the home page has a week schedule (Custom HTML, id schedule-demo) for five people. Each
cell is a button with a data-shift of am, pm, off (approved time off, locked) or empty.
- Click or Enter/Space cycles a cell: empty → AM → PM → empty. A and P set AM or PM, Delete or Backspace clears. Arrow keys, Home and End move between cells (one tab stop for the grid).
- Drag an AM or PM shift onto another cell to move it; if that cell has a shift, the two swap. Time-off cells can't be changed or dropped on.
- The Needs row shows a tick or the number of missing people per day; the ring and percentage
show total coverage; under each name are the scheduled hours, with "over" past
DEMO.maxHours. - Auto-fill gives each open shift to the free person with the fewest hours without going over the limit. Reset restores the starting schedule, and Publish shows a toast (it sends nothing).
The code is initScheduleDemo() in assets/js/main.js. Cells have labels such as "Maya, Friday:
evening shift, 14:00 to 22:00"; the table has a caption with the keyboard instructions, the coverage
note is a polite live region, and drag moves are announced. Dragging is an extra: everything also
works by click or keyboard.
Product tour#
The tour on the home page (Custom HTML, data-tour) is a vertical role="tablist" with four tabs
that swap HTML screens. initTabs() handles click, arrow keys, Home and End with a roving
tabindex; panels are linked with aria-controls. Edit the tab text and the screens in the block's
HTML view.
Pricing switch and calculator#
- Billing switch
#billinginpricing-hero, arole="radiogroup"of two buttons witharia-checked(annual by default). Text withdata-price-monthlyanddata-price-annual(the Team and Business prices in the plan cards) shows one or the other; the note under the switch swaps between itsdata-monthlyanddata-annualtext. - Calculator
#calcwith the locations (1–30) and employees (5–600) sliders and the plan choice. The total is locations × location fee + employees × employee fee fromPRICING, following the billing switch. It shows the yearly saving, suggests Starter for one location with up to 15 people, and suggests sales from 500 people (changing the button link too). The sliders announce readable values and the total is announced after changes stop. - Comparison table in
plan-comparison: the header row sticks below the floating header. Its wrapper usesoverflow-clip(notoverflow-hidden) so the sticky header keeps working; on phones "Unlimited" shows as ∞ with the word kept for screen readers.
FAQ#
The FAQ on the pricing page is an Accordion block with Auto-close on, so one answer is open at a time, as in the HTML version; the first answer starts open (Open by default on its item). Add a question with the block's + button; WordPress's own script opens and closes the answers with the right ARIA states.
Integrations directory and drawer#
The directory (directory pattern) is one Custom HTML block for the search and filters, one for the
grid of cards and one for the empty state. The search (#int-search) matches every word against each
card's data-search text and is kept in the URL as ?q=; the category buttons
(data-filter="integrations") keep the choice as ?category=payroll. Counts, the "Showing 20
integrations" line and the empty state with its Clear search button follow the results.
Each card's name is a button with data-drawer-open; initDrawer() copies the card's
<template data-detail> into the native <dialog id="int-drawer"> (the integration-drawer
pattern) and opens it with showModal(), so focus is trapped and Escape closes it. Clicking the
dimmed backdrop or the close button also closes it, and focus returns to the card. The open
integration is kept in the URL (/integrations/?integration=paywell) and opens on load. To add an
integration, copy a card's <li> in the grid's HTML view, change its data-drawer-open, data-tags,
data-search and text, and edit the details inside its <template>.
Customer stories and changelog filters#
The industry buttons on the customers page (data-filter="customers") and the topic buttons on the
changelog (data-filter="changelog") show the items whose tags match, with counts, an empty state, a
result line for screen readers and the choice in the URL (/customers/?industry=hotels,
/changelog/?tag=mobile), so filtered views can be shared.
Blocks can't hold data attributes, so each story and update carries classes the script turns into
them: ffd-filter-item--customers (or --changelog) and one ffd-tag--<value> per topic, matching a
button's data-filter-value. To add a story or an update, duplicate one in List View, change its
text and its ffd-tag-- classes. "How they did it" on each story is a Details block.
Scroll reveals, header and mobile menu#
Blocks with reveal fade up when scrolled into view, numbers with ffd-count--… count up once, and
the integrations orbit turns slowly. All motion stops with reduced motion. The floating header bar
turns white with a shadow once the page scrolls. The menu button (#menu-toggle) opens the mobile
menu, updates aria-expanded and its label, and closes with Escape or when the window grows to
desktop width; the mobile menu Group starts with the class ff-hidden, which the script turns into
the hidden attribute it toggles.
Back to top#
A button appears after scrolling about one screen down; it scrolls to the top (instantly with
reduced motion) and moves keyboard focus to the main content. On the changelog it hides while it
would cover the sticky sidebar. It is created by assets/js/main.js; to remove it, delete the "Back
to top" part of that file and the .back-to-top styles in src/theme.css, then run pnpm build.
Block styles#
| Block | Styles |
|---|---|
| Button | Fill (default, the ink primary button), Coral, Ghost (WordPress's own Outline looks the same), Pill (the section links and 404 shortcuts), Ink outline (on the coral call to action), Light outline (on dark panels) |
Large and small buttons carry is-large and is-small, which, as in the HTML version, look like the
default size.
Forms#
Form (data-form) |
Where | Checks |
|---|---|---|
newsletter |
Footer | Email required and well-formed |
updates |
Changelog sidebar (releases) |
Email, plus a frequency choice |
contact |
Talk to sales (contact) |
Names, work email (rejects FREE_EMAIL), optional phone, business, industry, team size, locations (whole number), rollout timing (only for 100+ people), at least one interest, optional message of 10+ characters, consent |
signup |
Start free trial (signup) |
Step 1: name, email, password (8+ characters with a number or symbol). Step 2: business, industry, locations, team size. Step 3: optional invite emails (each checked), terms |
Errors appear under each field, fields get aria-invalid and aria-describedby, and the first
problem is focused. Fields inside a hidden container are skipped.
Sales routing. Choosing a team size on the sales form updates the "Who you'll talk to" panel
(#route) from CONTACT_ROUTES and shows the rollout question for 100 people or more.
/contact/?size= accepts a number or small, mid, large, enterprise; ?topic= preselects the
topic (the price calculator links to ?size=500, the careers list to ?topic=careers).
Sign-up steps. Continue validates only the current step. The stepper marks steps as done, current
(aria-current="step") or upcoming, and focus moves to each step's heading. The password field has a
show/hide button and a strength meter. /signup/?plan=team (or starter, business) sets the plan.
The final step shows a summary with the trial end date (TRIAL_DAYS from today).
On success each form is replaced by a message. Nothing is sent anywhere until you connect the forms.
Option 1: a form plugin#
Install a form plugin (WPForms, Gravity Forms, Fluent Forms, Contact Form 7, Jetpack Forms...) and
replace the form's Custom HTML block with the plugin's block or shortcode. Add the theme's classes
where the plugin allows: input on fields, label on labels, btn-primary on the submit button.
Option 2: a form service#
In initForms() in assets/js/main.js, post the data before showing the message:
setupValidation(form, () => {
fetch('https://formspree.io/f/your-id', {
method: 'POST',
body: new FormData(form),
headers: { Accept: 'application/json' }
}).then((r) => {
if (r.ok) successSwap(form, '<p class="font-semibold">Thanks, we’ll be in touch.</p>');
else $('[data-form-status]', form).textContent = 'Something went wrong. Please try again.';
});
});For the sign-up form, send new FormData(form) to your own backend in the last-step branch of
initSignup() (marked with a comment) instead of building the summary. Never create accounts or
store passwords from client-side code alone. Make script changes in a child theme (copy
assets/js/main.js there and load it instead), or they are overwritten when you update the theme.
SEO and sharing#
Page titles come from WordPress: the page title, an em dash and the site name (for example
"Pricing — Orbit"); 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. Consider SoftwareApplication
structured data for your product. WordPress already generates a sitemap at /wp-sitemap.xml.
Accessibility#
Built in: a skip link to the main content (added by WordPress, styled by the theme), labelled
landmarks and sections, one h1 per page, visible coral focus rings, a schedule demo that works by
keyboard with labelled cells and announced changes, tabs following the tabs pattern, a radio group
for the billing switch, sliders with readable values, filter buttons with aria-pressed and result
lines in live regions, a native modal dialog for integration details, form errors linked to their
fields, a stepper with aria-current="step", and reduced-motion support for reveals, the orbit, the
count-up numbers and the drawer. The demo passes axe (WCAG 2.1 A and AA).
When you edit: keep text on the pastel panels in the matching ink colour, give images alt text, label every new form field and keep one Heading 1 per page.
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/ (including the classes inside the HTML the script writes):
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 or template, 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-orbit, 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-orbit. All text in patterns,
templates and PHP goes through WordPress's translation functions; the script's strings (labels, the
schedule demo's days and messages, calculator lines, sales routing, form errors) are translated in
PHP (freeframe_orbit_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-orbit wp-content/themes/freeframe-orbit/languages/freeframe-orbit.potSave freeframe-orbit-de_DE.mo (for example) in wp-content/languages/themes/ or in the theme's
languages/ folder. Page content created by Orbit setup is copied into your pages in the site's
language at that moment; translate it in the editor like any other content.
Child themes#
Use a child theme for changes you want to keep when Orbit is updated. Create
wp-content/themes/orbit-child/style.css:
/*
Theme Name: Orbit Child
Template: freeframe-orbit
*/Templates, parts, patterns and theme.json in the child theme override the parent's files of the
same name. To change the script's data, copy assets/js/main.js to the child theme and load it
instead of the parent's:
add_action( 'wp_enqueue_scripts', function () {
wp_deregister_script( 'freeframe-orbit' );
wp_register_script( 'freeframe-orbit', get_stylesheet_directory_uri() . '/assets/js/main.js', array(), '1.0.0', array( 'in_footer' => true, 'strategy' => 'defer' ) );
wp_enqueue_script( 'freeframe-orbit' );
}, 15 );(Then print the translated strings and page URLs again, as freeframe_orbit_enqueue_assets() in
inc/setup.php does, or the script falls back to English and .html links.) The parent's stylesheet
only contains the classes the parent uses: if your child theme's patterns use 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#
- A story or update doesn't appear under its topic. Its
ffd-tag--<topic>class must match a filter button'sdata-filter-value, and it needsffd-filter-item--customers(or--changelog). - The calculator total doesn't match the cards. The calculator uses
PRICING; the cards and the comparison table are blocks. Update both. - Dragging shifts doesn't work on my phone. Drags start after a small movement; vertical swipes over the grid still scroll the page. Tapping cells always works.
- The comparison table header stops sticking. A parent with
overflow: hiddenbreaks sticky positioning. Keepoverflow-clipon the table's wrapper. - 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 > Orbit.
- The header menu shows other pages, or an old menu. A Navigation block without a chosen menu shows the most recent one. Select it and choose "Main menu" (or yours) in the block settings, in both the desktop and the mobile Navigation block.
- Orbit 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 > Orbit pages.
- The forms 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 logo, portraits, customer and integration logos
and illustrations are included under the same license. Rethink Sans and Gabarito are licensed under
the SIL Open Font License 1.1 (assets/fonts/*/OFL.txt).