Freeframe

Documentation

Clinic

v1.0.1Updated Oct 9, 2026A calm, accessible website for a dental or medical practice, with online booking.

Overview#

Clinic is a calm, accessible website for a dental or medical practice, built as a WordPress block theme. The demo practice is Brightside Dental, a fictional family dental clinic. The theme has a home page with a live open-now badge and the next free appointment, a services page with typical costs, a detailed treatment guide (dental implants), a team page with a specialty filter, a five-step online booking wizard, a patient information page with a searchable insurance list, a contact page and a 404 page, all with larger text and high contrast for easy reading. It is version 1.0.1 (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/clinic.

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, the fonts and font sizes are design tokens in theme.json: change them in Appearance > Editor > Styles and the whole site follows.

All treatment descriptions, prices and aftercare notes are placeholder copy, not medical advice. Replace them with your practice's own information.

Quick start#

Requirements: WordPress 7.1 or newer and PHP 7.4 or newer. No plugins are needed.

  1. Download clinic.zip from freeframe.dev/templates/clinic (the WordPress tab).
  2. 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 Clinic.
  3. Go to Appearance > Clinic setup and click Create the demo pages. This creates the Home, Services & costs, Treatment guide, Our team, Book appointment, Patient info 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.
  4. Set the site title to your practice's name in Settings > General (the demo uses "Brightside Dental"), 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:

sh
pnpm install
pnpm dev     # builds the CSS, then starts WordPress with the theme at http://127.0.0.1:9400

pnpm 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 > Clinic pages) made of section patterns. Every section is also offered on its own in the block inserter under Patterns > Clinic.

Page Slug Page pattern Sections (pattern files in patterns/)
Home / page-home.php home-hero (hero, illustration, next free slot card), home-services, why-us, team-preview, reviews (rating breakdown and quotes), insurers, visit-us (open-now badge, opening hours, map), cta
Services & costs /services/ page-services.php services-hero (with links to each category), services-list (four categories of expandable treatments with typical costs, payment plans prompt)
Treatment guide /service/ page-service.php treatment-hero, treatment-guide (step-by-step timeline, aftercare, FAQ, sticky cost breakdown, clinician card), related-treatments
Our team /team/ page-team.php team-hero, team-grid (specialty filter and eight team members), training
Book appointment /appointments/ page-appointments.php booking-hero, booking-wizard (wizard and live summary)
Patient info /patients/ page-patients.php patients-hero, patients-info (first visit, insurance search, forms, payment options, FAQ, privacy)
Contact /contact/ page-contact.php contact-hero, contact-details (emergency notice, form, opening hours, contact cards, map, directions, accessibility)
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.

Project structure#

freeframe-clinic/
  style.css                 theme header (name, version, requirements, license); no styles
  theme.json                design tokens: palette, fonts, font sizes, spacing, layout widths, button
  functions.php             loads the files in inc/
  inc/setup.php             stylesheet and script, editor styles, the "js" class script, script strings,
                            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/navigation.php        current-page markers (aria-current) in the header
  inc/site-setup.php        Appearance > Clinic 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: settings (hours, clinicians, treatments), hours,
                            forms, team filter, insurance search, booking wizard, back to top
  assets/js/editor.js       block editor tweaks
  assets/icons/             SVG icons for the Icon block
  assets/img/               portraits (<clinician-id>.svg), hero.svg, map.svg, favicon, social image
  assets/fonts/             the Figtree and Fraunces font files 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-clinic.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.txt

Customising#

Brand and colours#

The colours are in theme.json (settings.color.palette) and in Appearance > Editor > Styles > Colors > Palette:

Colours Used for
Brand 50 to Brand 900 the teal of buttons, links, eyebrows, icons, badges, focus rings and the dark footer
Ink headings and strong text
Contrast body text (also the page's text colour)
Muted secondary text
Line borders and dividers
Sky Soft, Cream soft section backgrounds
Sun, Coral warm accents (the emergency bar icon, the hand-drawn underline, the newsletter button)
Base, White, Black the page background, and plain colours for your own blocks

The theme's stylesheet reads these colours from the palette, so changing Brand 700 in Styles recolours every primary button, link and accent at once. Keep a full ramp from light (50) to dark (900), and keep Brand 600 and darker dark enough for white text (WCAG AA). In theme.json:

json
{ "slug": "brand-700", "name": "Brand 700", "color": "#1b625b" }

The browser bar colour (<meta name="theme-color">) is set in freeframe_clinic_head_meta() in inc/setup.php. A few decorative details have their colour written into src/theme.css (the yellow underline under "at ease", the select arrow) and the illustrations in assets/img/ have their own colours.

Typography#

Text uses Figtree (variable, weights 400 to 800) and headings use Fraunces (variable, weights 500 to 700), bundled in assets/fonts/ and declared in theme.json (settings.typography.fontFamilies), so no request goes to Google. The classes h-display, section-title and font-display use Fraunces. 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--figtree and --wp--preset--font-family--fraunces, so rename those slugs only together with src/theme.css.

The base text size is slightly larger than usual (17 px: html { font-size: 106.25% } in src/theme.css) for readability; keep it that way. Font sizes are the presets in theme.json (xs 0.75rem to 9xl 8rem, the Tailwind scale), relative to that base. 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 (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 > Clinic.

The practice name, phone number, email and address appear in the header, footer and several sections: search for them in each page and in the header and footer patterns.

Treatments (services page) and questions (treatment guide, patient info) are Details blocks: the summary line holds the treatment name and its price range, the inside holds the description. To add one, duplicate a Details block in List View.

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
visit-us, contact-details, footer opening hours the printed hours, with today highlighted (see Opening hours)
visit-us, contact-details open-now badge filled in by assets/js/main.js
team-grid the filter buttons and the "Showing …" line see Team filter
booking-wizard the wizard and the summary card see Booking wizard
patients-info the insurance search and its list see Insurance search
contact-details the contact form see Forms
footer the newsletter form, and the toast used for short messages see Forms
header the menu button a 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:

  • reveal fades a block in as it scrolls into view; a class such as [--d:80ms] delays it.
  • link-card on a group makes the whole group clickable: the first link inside it stretches over the group.
  • ff-specialty-<key> on a team member and ff-filter-grid on their container: the team filter (see below).
  • ff-next-slot on the home page paragraph that shows the next free appointment.
  • ff-demo-download on the downloadable forms (patient info): the link shows a message instead of downloading. Upload your PDF to the Media Library, then remove the class and link to the PDF to make it a real download.
  • ff-underline (the hand-drawn line under "at ease"), ff-hero-blobs and ff-cta-blobs (the soft shapes behind the page headers and the call to action) are drawn by the stylesheet.

Images and artwork#

  • Portraits are SVG illustrations in assets/img/ (dr-okoye.svg, jordan-ellis.svg…), shown with Image blocks. Replace them with photos from the Media Library, in the same portrait proportions (6:7, cropped from the top). The booking wizard shows assets/img/<clinician-id>.svg (see Booking wizard): replace those files, keeping their names, to change the pictures there too.
  • Hero illustration (hero.svg) and map (map.svg) are Image blocks: replace them with a photo of your practice and a map image or screenshot (embed an interactive map with the Embed block or a Custom HTML block if you prefer).
  • Logo: the header and footer show assets/img/favicon.svg in an Image block next to the practice name (a paragraph with a link: "Brightside" and "Dental" in two styles). Edit both in Appearance > Editor > Patterns > Header (and Footer).
  • Icons: icons are Icon blocks. Select one and pick another icon from the Clinic collection (the theme's icons) or WordPress's own. Icons inside a button (the calendar and phone) or after a link (the arrows) are drawn by CSS: the class icon-before-calendar or icon-after-arrow-right adds one (icon-size-20 makes it 1.25rem); the available names are in src/icons.css.
  • Social image: assets/img/og-image.png (1200 × 630, source og-image.svg). WordPress doesn't output Open Graph tags by itself; see SEO and sharing.
  • Favicon: assets/img/favicon.svg is used until you set a Site Icon in Settings > General.

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. Above the header is the emergency bar with the phone number.

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 Home, Services, Our team, Patients and Contact). The Home link has the class ff-mobile-only (link settings > Advanced), so it only shows in the mobile menu, as in the HTML version. 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 menu link of the page being viewed (aria-current="page"). The theme also marks the header's buttons that link to the current page (the "Book appointment" buttons on the booking page) and keeps Services current on the treatment guide (freeframe_clinic_menu_parents() in inc/navigation.php, filterable with freeframe_clinic_menu_parents).

The footer's Explore column is a List block: click a link to change it, press Enter to add one.

Features#

Opening hours and the open-now badge#

The opening hours used by the scripts are at the top of assets/js/main.js (section 1, Settings):

js
// Opening hours per weekday (0 = Sunday). Times are 24h decimals: 8.5 = 8:30 am.
var HOURS = {
  0: null,
  1: [8, 19], 2: [8, 19], 3: [8, 19], 4: [8, 19],
  5: [8, 16],
  6: [9, 14]
};
var TIMEZONE = 'America/Los_Angeles'; // the practice's time zone (IANA name)

The open-now badge (data-open-status) shows "Open now · closes at 7:00 pm" or "Closed now · opens tomorrow at 8:00 am" and refreshes every minute. Hours lists (data-hours) highlight today's row with data-today="true" and aria-current="date"; data-day on each row uses the same numbers as HOURS (0 = Sunday … 6 = Saturday). Both use the time in TIMEZONE, so every visitor sees the practice's day and time, wherever their device is. Set TIMEZONE to your practice's zone.

The printed hours are Custom HTML blocks (in the visit-us and contact-details patterns, so in the Home and Contact pages, and in the footer pattern): keep them in step with HOURS.

Next free slot#

On the home page, the paragraph with the class ff-next-slot shows the earliest free 60-minute slot in the next two weeks across all clinicians, for example "Tomorrow, 9:30 am".

Booking wizard#

The Book appointment page contains the wizard (form[data-booking], a Custom HTML block) with five steps: Treatment, Clinician (the people who offer it, plus "First available"), Date and time (a week view, up to WEEKS_AHEAD weeks, and time slots), Your details and Review (every choice with a "Change" link back to its step). Link to /appointments/?service=implant to preselect a treatment. A live summary card follows the choices; each step is validated before moving on, and focus moves to the step's heading. The confirmation says the practice would confirm by email; nothing is booked.

The settings are in section 1 of assets/js/main.js:

js
var LUNCH = [12.5, 13.5];        // no appointments during lunch (weekdays)
var SLOT_STEP = 30;              // minutes between appointment start times
var MIN_NOTICE_MINUTES = 90;     // earliest bookable time from now
var WEEKS_AHEAD = 4;             // how far ahead people can book

var CLINICIANS = {
  'dr-okoye': { name: __('Dr. Amara Okoye'), role: __('General & family dentist'), days: [1, 2, 3, 4, 5] },
  …
};
var SERVICES = [
  { id: 'checkup', name: __('Check-up & cleaning'), minutes: 60, note: __('Exam, clean and polish'), who: ['dr-okoye', 'jordan-ellis', 'sofia-marchetti'] },
  …
];

days lists the weekdays a clinician works (0 = Sunday); minutes sets a treatment's length and who lists the clinician ids who offer it. Slots start every SLOT_STEP minutes from opening as long as the appointment ends by closing time, skip LUNCH on weekdays and anything sooner than MIN_NOTICE_MINUTES, only count clinicians who work that day, and some are marked as taken by isTaken(), a fixed pattern so the demo looks realistic. The wizard shows each clinician's portrait from assets/img/<id>.svg (the theme passes the URLs of its images to the script), so add a portrait with the same file name when you add someone. __() translates the names (see Translations); add new strings to freeframe_clinic_script_strings() in inc/setup.php.

The team page and treatment pages are blocks, so update them separately when you change CLINICIANS or SERVICES, and copy your changes to assets/js/main.js in a child theme (or they are overwritten when you update the theme).

To take real bookings, replace isTaken() with availability from your scheduling system and send the booking in the submit handler (the comment "To take real bookings"). Many practices embed their practice-management or booking provider's widget instead: on the Book appointment page, delete the wizard's Custom HTML block and the summary card and add the provider's embed code in a Custom HTML block.

Team filter#

On the team page, the buttons with data-filter (all, general, ortho, kids, surgery, cosmetic, hygiene, care, in a Custom HTML block) show the team members whose group has the class ff-specialty-<key>, inside the group with the class ff-filter-grid, and update the "Showing …" line. To add a specialty, add a button with a new data-filter value and give the team members the class ff-specialty-<value>.

On the patient info page, the search field (data-plan-search) filters every data-plan item by its text, updates the count (data-plan-count) and shows the "couldn't find that plan" message (data-plan-empty) when nothing matches. Add an insurer by adding another <li … data-plan> in the Custom HTML block.

Treatments and questions#

The Details blocks open and close without JavaScript and are found by the browser's find-in-page. The plus sign that turns into a cross is drawn by the stylesheet (.faq summary::before and ::after in src/theme.css); the class faq gives a Details block that look.

Sticky header, mobile menu and scroll reveals#

The header sticks to the top and gains a shadow once the page scrolls (is-scrolled). Below 1024 px the menu button (data-menu-toggle) opens #mobile-menu, swaps its icon, updates aria-expanded and its label, and closes with Escape (returning focus to the button) or when the window grows past 1024 px. The mobile menu Group starts with the class hidden; the script turns it into the hidden attribute it toggles. Blocks with reveal fade in when scrolled into view (everything above is revealed too). They are only hidden once JavaScript runs (html.js), so the content is there without it, and they appear immediately with reduced motion.

Back to top#

A button appears after scrolling about one screen down; it scrolls to the top (instantly with reduced motion), moves keyboard focus to the main content and lifts above the toast. The sticky cost card on the treatment guide has the class ff-back-to-top-hide, so the button never covers it. 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#

In the block settings' Styles panel:

Block Styles
Button Fill (default, the primary teal), Outline, Ghost, White (on teal), Outline (on teal), Chip (WordPress's own Outline style is replaced by the theme's)

Add the class is-small to a Button block for the small size used in the header.

Forms#

Form Where Notes
Contact Contact page (contact-details pattern) its own thank-you text in data-success-text
Newsletter Footer email only
Booking wizard (data-booking) Book appointment page see Booking wizard

Forms marked data-validate are checked by validateField() in assets/js/main.js: required fields, email format, phone numbers on fields with data-phone (at least 7 digits), minlength, and dates of birth in the future. Errors appear under each field, are linked with aria-describedby, and the first invalid field is focused. On success the [data-success] element shows the form's data-success-text. Nothing is sent anywhere: they are demo forms until you connect them.

Option 1: a form plugin#

The usual way on WordPress. Install a form plugin (WPForms, Gravity Forms, Fluent Forms, Contact Form 7, Jetpack Forms...), build the form there, then on the Contact page delete the form's Custom HTML block and insert the plugin's block or shortcode in its place. The plugin sends the messages and stores them. To make its fields look like the theme's, add the theme's classes where the plugin allows custom classes: field on fields, label on labels, btn btn-primary on the submit button.

Option 2: a form service#

Keep the theme's form and send it to a service such as Formspree:

  1. Create a form on the service and copy its endpoint URL.

  2. Edit the Contact page, open the form's Custom HTML block and add the endpoint to the form tag:

    html
    <form class="card grid gap-5 p-6 sm:p-8" novalidate data-validate data-success-text="Thank you!" action="https://formspree.io/f/your-id" method="post">
  3. In section 5 of assets/js/main.js, replace the success code in the submit handler (after the comment "To send for real") so it posts the form and only shows the thank-you text when the service accepts it:

    js
    fetch(form.action, { method: 'POST', body: new FormData(form), headers: { Accept: 'application/json' } })
      .then(function (res) {
        if (!res.ok) throw new Error('Request failed');
        var success = $('[data-success]', form);
        success.textContent = form.dataset.successText || __('Thank you!');
        success.classList.remove('hidden');
        form.reset();
      })
      .catch(function () { toast('Sorry, that didn’t send. Please call us instead.'); });

    Make this change in a child theme (copy assets/js/main.js there and load it instead), or it will be overwritten when you update the theme.

Health information is sensitive: send forms only over HTTPS to services you trust, ask for the minimum needed, and check your local privacy rules (for example HIPAA in the US or GDPR in the EU) before collecting medical details online.

Saved data (localStorage)#

Clinic stores nothing in the visitor's browser.

SEO and sharing#

Page titles come from WordPress: the page title, an em dash and the site name (for example "Services & costs — Brightside Dental"); 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. Local practices benefit from Dentist or MedicalClinic structured data (address, phone, opening hours), which most SEO plugins can add. WordPress already generates a sitemap at /wp-sitemap.xml.

Accessibility#

Clinic is built for patients of all ages and abilities: larger base text, high contrast, thick focus rings, a skip link to the main content (added by WordPress, styled by the theme), labelled landmarks (header, navigation, main, footer), one h1 per page, the mobile menu button with aria-expanded, filter buttons with aria-pressed, a booking wizard with fieldsets and legends, focus moved to each step's heading, the current step marked with aria-current="step" and each day button labelled with its date and availability, form errors announced and linked to their fields, aria-current on the current page's links and today's opening hours, and reduced-motion support for every animation. The demo passes axe (WCAG 2.1 A and AA).

When you edit: keep one Heading 1 per page, keep text contrast at WCAG AA, give images alt text (or mark them decorative), keep link text meaningful, 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/ (including the classes the booking wizard writes):

sh
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-clinic, 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-clinic. All text in patterns, templates and PHP goes through WordPress's translation functions; the script's strings (status texts, day and month names, treatments, clinicians, form errors, wizard texts) are translated in PHP (freeframe_clinic_script_strings() in inc/setup.php). Create a translation with Loco Translate, or with WP-CLI and Poedit:

sh
wp i18n make-pot wp-content/themes/freeframe-clinic wp-content/themes/freeframe-clinic/languages/freeframe-clinic.pot

Save freeframe-clinic-de_DE.mo (for example) in wp-content/languages/themes/ or in the theme's languages/ folder. Page content created by Clinic 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 Clinic is updated. Create wp-content/themes/clinic-child/style.css:

css
/*
Theme Name: Clinic Child
Template: freeframe-clinic
*/

Templates, parts, patterns and theme.json in the child theme override the parent's files of the same name. To change the booking settings, 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-clinic' );
	wp_register_script( 'freeframe-clinic', get_stylesheet_directory_uri() . '/assets/js/main.js', array(), '1.0.0', array( 'in_footer' => true, 'strategy' => 'defer' ) );
	wp_enqueue_script( 'freeframe-clinic' );
}, 15 );

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#

  • The open-now badge or the booking times are an hour or more out. Set TIMEZONE at the top of assets/js/main.js to your practice's IANA zone name (for example 'America/Chicago').
  • Today's row in the hours list is off by one day. data-day must use the same numbers as HOURS (0 = Sunday … 6 = Saturday).
  • A treatment has no free days. Check that its who clinicians work on open days (days in CLINICIANS) and that the appointment length fits within the hours outside LUNCH.
  • A clinician's portrait is missing in the wizard. Add assets/img/<clinician-id>.svg to the theme (or child theme folder you load the script from).
  • ?service= doesn't preselect a treatment. The value must match an id in SERVICES.
  • The team filter shows nobody. Each team member's group needs the class ff-specialty-<key> with a key used by a filter button, inside the group with ff-filter-grid.
  • The pages look unstyled or new classes do nothing. The stylesheet only contains classes it found when it was built. Run pnpm build after 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 > Clinic.
  • 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.
  • Clinic 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 > Clinic pages.
  • The forms don't send anything. They are demo forms; see Forms.
  • The theme can't be installed on an older WordPress. Clinic uses the Icon block's icon collections from WordPress 7.1; update WordPress first.
  • A page shows the title twice or no title. Pages use a template without a title, because the page patterns start with their own heading. For a plain text page (privacy policy, terms), choose the Page with title template in the page's settings.

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 illustrations, portraits and map are included under the same license. Figtree and Fraunces are licensed under the SIL Open Font License 1.1 (assets/fonts/figtree/OFL.txt, assets/fonts/fraunces/OFL.txt).

Search documentation

Search the guides and every template's documentation