Freeframe

Documentation

Slatework

v1.0.0Updated Nov 13, 2026A crisp, corporate SaaS website for recruiting software, with a live drag-and-drop hiring pipeline in the hero.

Overview#

Slatework is a website for a recruiting software company, built as a WordPress block theme. The fictional Slatework, Inc. makes an applicant tracking system (ATS) for companies with 50 to 1,000 employees, is based at 418 West Short Street in Lexington, Kentucky, and works in Eastern time (America/New_York). The theme has a home page whose hero is a live hiring pipeline board, a product tour (job board picker and posting preview, stage rules, a weighted interview scorecard, a panel scheduler across US time zones, an offer pay band check and report charts), per-employee pricing with a monthly or yearly switch and a cost-per-hire calculator, filterable customer stories, a searchable integrations directory with a detail dialog, a security and compliance page with a data retention example, resources with rolling monthly webinars and articles, a demo request 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/slatework.

Headings, copy, lists, cards, quotes, buttons and the billing questions are core WordPress blocks arranged in block patterns, so you edit them in the block editor without touching code. The parts that are worked out in the browser (the pipeline board, the scorecards, the job board picker, the scheduler, the offer check, the pricing calculator, the customer story list, the integrations directory and dialog, the retention example, the webinars and their registration form, the article list and the demo request form) work as in the HTML version: they are Custom HTML blocks driven by assets/js/main.js, which reads Slatework's content from assets/js/data.js. The drawings and charts are Custom HTML blocks with inline SVG, so their colors follow the light and dark themes. Colors and fonts are design tokens in theme.json: change them in Appearance > Editor > Styles and the whole site follows. Every upcoming date is worked out in Eastern time from rules rather than fixed dates, so the demo never goes stale.

The look is corporate and structured: white paper with hairline grids, a deep indigo brand color, a marigold highlight, Hubot Sans headings and Fira Sans body text, with a full dark mode.

Quick start#

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

  1. Download slatework.zip from freeframe.dev/templates/slatework (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 Slatework.
  3. Go to Appearance > Slatework setup and click Create the demo pages. This creates the Home, Product, Pricing, Customers, Integrations, Security, Resources and Book a demo 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. 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:

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

Page Slug Page pattern Sections (pattern files in patterns/)
Home / page-home.php home-hero (pipeline board), customer-logos, pillars, home-scorecard, results, home-cta
Product /product/ page-product.php product-hero, sourcing (#sourcing), pipeline-rules (#pipeline), interviews (#interviews), scheduling (#scheduling), offers (#offers), reports (#reports), product-cta
Pricing /pricing/ page-pricing.php pricing-hero (billing switch), plans, calculator (#calculator), compare-plans, billing-faq
Customers /customers/ page-customers.php customers-hero, stories (filters and the list from CASES), customers-cta
Integrations /integrations/ page-integrations.php integrations-hero, directory (from INTEGRATIONS), api, integration-dialog
Security /security/ page-security.php security-hero, controls, retention (#retention), self-id, subprocessors
Resources /resources/ page-resources.php resources-hero, webinars (with registration), articles (from POSTS)
Book a demo /demo/ page-demo.php demo-request
404 any missing URL templates/404.html 404

WordPress 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-slatework/
  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 scripts (with the script's strings and page URLs), editor
                            styles, the dark mode script, theme colors and favicon, page titles,
                            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 > Slatework 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/data.js         Slatework's content (window.SLATEWORK): STAGES, CANDIDATES, COMPETENCIES,
                            BOARDS, INTERVIEWERS, OFFER_BAND, PLANS, CASES, INTEGRATIONS, POSTS and more
  assets/js/main.js         every interaction (the HTML version's script plus a WordPress adapter)
  assets/icons/             the icons used by Icon blocks (outline SVG paths)
  assets/img/               logo.svg, favicon.svg and the social image
  assets/fonts/             Hubot Sans and Fira Sans, with their licenses
  src/theme.css             the Tailwind CSS source of assets/css/theme.css (also the dark colors)
  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-slatework.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

Customizing#

Brand and colors#

The light palette is in theme.json (settings.color.palette) and shows in Appearance > Editor > Styles > Colors. The stylesheet maps every Tailwind color to these presets (--color-brand: var(--wp--preset--color--brand) in src/theme.css), so changing Brand in Styles changes every button, link and focus ring that uses brand.

Color Light Dark Used for
Paper #ffffff #0f1117 Page and card background
Canvas / Canvas 2 #f4f4f1 / #e9e9e3 #161922 / #1f2330 Alternate bands, board columns / tracks
Line / Line strong #dddfd7 / #878b7f #2b303f / #707790 Hairlines / inputs and chart axes
Ink, Ink soft, Ink faint #15171e, #454955, #595d69 #eceef5, #b6bbcb, #9ba1b4 Text
Brand / Brand strong #3a3fd0 / #2b2fa8 #a3a9ff / #c2c6ff Buttons, links, focus / hover
Brand soft / Brand line #ecedfc / #c9ccf5 #23264a / #3c4180 Tinted chips and borders
Applied, Screen, Interview, Offer, Hired (and Soft) stage colors lighter stage colors Board dots, chips, funnel bars
Danger / Danger soft #b42318 / #fde8e6 #ff9b8f / #3a1714 Form errors
Night, Night 2, Night line, Mist #13151d, #1d2030, #31364a, #c3c8d8 same Footer and call-to-action bands, text on them
Marigold #f2b33d same Highlight fills, the button on dark bands

The dark values are in src/theme.css (html.dark { --wp--preset--color--brand: #a3a9ff; ... }): when you change a color in Styles, change its dark value there too and run pnpm build. The logo (assets/img/logo.svg), favicon.svg, og-image.svg, the integration and customer marks in data.js and a few drawings use hex values directly (#3a3fd0, #f2b33d); search for them if you change the brand completely.

The repeated pieces are classes in src/theme.css: .panel and .panel-lift (cards with a soft shadow), .gridlines, .eyebrow, .h-display, .h-section, .lead, .link, .chip and the stage tones (.tone-hired, .dot-offer...), .seg, .filter-btn, .rate and the form fields (.field, .field-label, .field-error, .field-hint). Add them to any block under Advanced > Additional CSS class(es).

Typography#

Two families are bundled in assets/fonts/ and declared in theme.json (no requests to Google), the same files Google Fonts serves to the HTML version:

  • Hubot Sans (font-display, headings; weights 500–800, widths 100–125%) is a variable font. Headings are set a little wider with font-stretch: 112%, the logo at 115%. It draws its zero with a bar; that is the font's design.
  • Fira Sans (font-sans, the body font; 400, 500, 600 and italic 400).

Swap a family in Styles > Typography, or add your own fontFace files to theme.json.

Content#

Page copy (headings, paragraphs, the feature pillars, the results, quotes, plans, the questions, the security controls) is in the pages: edit it in the block editor. Everything the script renders lives in assets/js/data.js on window.SLATEWORK, as in the HTML version:

Constant What it holds
COMPANY Name, timeZone (America/New_York) and contact details
STAGES The five pipeline stages, in order: applied, screen, interview, offer, hired
REQ The requisition shown on the board (title, openings: 2)
STAGE_BASE Candidates in each stage not shown as cards: applied: 38, screen: 9, interview: 3, offer: 0, hired: 0
CANDIDATES Board cards: id, name, source, age (days since applying), starting stage, avatar hue, optional score
STAGE_REMAINING, TIME_TO_HIRE_TARGET Time-to-hire projection (offer: 4, hired: 0; target 30 days)
COMPETENCIES, RATING_LABELS, RECOMMENDATIONS Scorecard competencies, weights and default ratings; score thresholds
BOARDS, POSTING_LOCATIONS Job boards with 30-day price and typical applicants; posting locations
INTERVIEWERS, WORK_HOURS, SCHEDULE_*, DISPLAY_ZONES Scheduler panel, working hours, busy blocks and time zones
OFFER_BAND Pay band, slider range and approval rules for the offer check
PLANS, ANNUAL_DISCOUNT, MIN_EMPLOYEES, MAX_EMPLOYEES, ENTERPRISE_HINT, DEFAULT_PRICING Pricing
INDUSTRIES, SIZES, CASES Customer story filters and stories
INT_CATEGORIES, INTEGRATIONS Integration categories and directory entries
RETENTION, DEFAULT_RETENTION Data retention choices on the security page
TOPICS, POSTS Article topics and articles (fixed past dates)
WEBINAR_* Webinar rule, time and topics
PERSONAL_DOMAINS, COMPANY_SIZES, DEMO_LEAD_DAYS, DEMO_TIMES Demo form checks and proposed meeting time

Example: add an integration. Give it a unique id, an existing category, a tile color and a small mark drawn in white inside a 40×40 box:

js
{ id: 'shiftnote', name: 'Shiftnote', category: 'messaging', bg: '#0f766e', setup: '2 minutes', direction: 'One-way',
  blurb: 'Post interview reminders to the hiring team channel.',
  syncs: ['Interview reminders', 'Scorecard due alerts'],
  mark: '<circle cx="20" cy="20" r="9" fill="#fff"/>' }

Category counts, search and the detail dialog pick it up automatically. The "22 integrations" line in the directory pattern is the text shown before the script runs; update it if you want it exact.

Example: add a customer story to CASES with industry set to a key of INDUSTRIES and size to s, m or l. metrics[0] draws the before-and-after chart. The home page logo row and quotes are blocks in the customer-logos and results patterns; edit them there if you change customers.

The pricing calculator's "Book a demo with this estimate" link goes to the Book a demo page: the script turns the HTML file name demo.html into your WordPress page URL with freeframe_slatework_page_urls() in inc/setup.php. Edit data.js in a child theme (see Child themes) so an update doesn't overwrite it.

Images and artwork#

All artwork is SVG drawn for this template; there are no photos. The header and footer logo is an Image block (assets/img/logo.svg): select it and Replace to use your own. The feature pillar drawings, the customer logo marks, the report charts, the integrations and security drawings, the most-read chart and the 404 board are Custom HTML blocks with inline SVG whose fills use the theme's colors (fill-brand, stroke-line-strong), so they switch with dark mode; replace a block with an Image block (keep roughly the same aspect ratio) when you have real pictures. The integration and customer marks are drawn by the script from the mark strings in data.js.

The social image is assets/img/og-image.png (1200 x 630, source og-image.svg); the 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.

The header has two Navigation blocks showing the same menu: the desktop one (from 1024 px) and the one in the phone menu. Edit the menu once in Appearance > Editor > Navigation (the setup creates "Main menu": Product, Pricing, Customers, Integrations, Security and Resources). WordPress marks the current page's link with aria-current="page" (drawn as an indigo bar under it). The "Book a demo" buttons in the header and the phone menu are Button blocks. 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.

The footer's link columns are List blocks: click a link to change it, press Enter to add one. The copyright year is written by PHP and kept current by the script. The phone number and email appear in the footer and on the pricing and demo pages; search for them when you change them.

Dark mode#

The theme switch in the header ([data-theme-toggle]) toggles the dark class on <html> and saves the choice as slatework:theme. A short script printed first in <head> (freeframe_slatework_head_script() in inc/setup.php) applies the saved choice, or the visitor's system setting, before the page paints. To make light the default regardless of the system setting, remove the matchMedia(...) check from that script. To remove dark mode, remove that function and the switch's Custom HTML block from the header pattern.

Features#

Hero pipeline board#

Home page (home-hero pattern), section 5 of main.js (initPipeline). The board shows the requisition REQ with five columns from STAGES. Each column's count is STAGE_BASE[stage] plus the cards in it.

  • Drag and drop: with a mouse or pen, drag a card anywhere; on touch screens, drag by the card's initials (data-grip), so swiping the board still scrolls it. The board scrolls sideways when you drag near its edge. Escape cancels a drag.
  • Keyboard and screen readers: each card has a "Move" button (data-move) that opens a menu of stages (role="menu"; arrow keys, Home, End, Escape). Choosing a stage moves the card, returns focus to it and announces the new count and time to hire.
  • Funnel: "reached" counts each stage plus every later stage. With the starting data: Applied 61, Screen 19, Interview 7, Offer 2, Hired 1, so Applied to Hired is 1.6%.
  • Projected time to hire: the average of age + STAGE_REMAINING[stage] over cards in Offer and Hired, rounded. Start: 25 days, "5 days under the 30-day target". Moving Ramona D. to Offer makes it 23 days; then dragging Esmeralda P. to Hired makes "2 of 2 openings filled" and 22 days.
  • Moves are saved (slatework:pipeline); "Reset board" restores the starting data.

Interview scorecard#

Home (home-scorecard) and product (interviews) pages, initScorecards. Every [data-scorecard] panel lists COMPETENCIES with 1–4 rating buttons (role="radio", arrow keys change the rating). The weighted score is sum(weight × rating) / 100. The defaults give 3.25, Hire; rating Product knowledge 4 gives 3.55, Strong hire. Thresholds are in RECOMMENDATIONS.

Job boards and posting preview#

Product page #sourcing, initBoards. Checking boards updates the board count, the 30-day cost and typical applicants (default 3 boards, $0, 60 applicants; adding Talentcast makes $179, 76). The posting preview follows the title, location and pay range fields and flags a maximum below the minimum.

Panel scheduler#

Product page #scheduling, initScheduler. For each of the next SCHEDULE_DAYS (5) weekdays after today in Eastern time, it intersects every chosen interviewer's working hours (9:00 a.m. to 5:00 p.m. in their own zone) minus their busy blocks and proposes up to 3 slots, at most two per day. Times show in the visitor's zone by default; "Show times in" switches between US zones.

Offer pay band check#

Product page #offers, initOffer. Inside the band ($68,000–$84,000) only the hiring manager approves; below it the people team is added; above it the VP and Finance are added (OFFER_BAND.rules).

Pricing and calculator#

Pricing page, initPricing. Monthly prices per employee are in PLANS (Essentials $5, Growth $8); yearly billing takes ANNUAL_DISCOUNT (20%) off: $4 and $6.40. Companies under MIN_EMPLOYEES (50) are billed as 50. Default (200 employees, Growth, yearly, 40 hires): $1,280 a month, $15,360 a year, $384 per hire. The choice is saved (slatework:pricing); URL parameters override it: ?billing=monthly|annual, ?plan=essentials|growth, ?employees=1–1000, ?hires=1–2000. The billing questions are Details blocks with the class faq.

Customer stories#

Customers page, initCustomers. Industry buttons and a company size select filter CASES; the URL keeps them as ?industry= and ?size=s|m|l.

Integrations directory#

Integrations page, initIntegrations. Search matches name, description and category; category buttons show counts. The URL keeps ?category= and ?q=. Each card opens a <dialog> (the integration-dialog pattern) with what syncs; Escape or Close returns focus to the card.

Data retention example#

Security page #retention, initRetention. Choosing 12, 24 or 36 months shows the date a candidate rejected today would be anonymized and the reminder a month earlier, worked out from today in Eastern time.

Webinars and articles#

Resources page, initResources. Webinars are on the second Thursday of each month at 1:00 p.m. Eastern, the next 3 at least 3 days away. Articles in POSTS keep their real dates and can be filtered by topic (?topic=).

The menu button (#menu-toggle) opens the phone menu with aria-expanded; Escape closes it and returns focus. The header gets a soft shadow once the page scrolls. Elements with .reveal fade in once as they scroll into view. With prefers-reduced-motion: reduce there is no reveal or drag animation.

Keeping the demo current#

Nothing dated goes stale. All upcoming dates are computed from today in Eastern time (COMPANY.timeZone):

Content Rule Switch
Interview slots Next 5 weekdays after today Busy blocks use business day numbers
Webinars Second Thursday of the month, at least 3 days away WEBINAR_DATES = null; set an array of 'YYYY-MM-DD' strings for fixed dates
Proposed demo time First weekday at least DEMO_LEAD_DAYS (1) after today, at 10:00 a.m. or 2:00 p.m. Eastern DEMO_TIMES
Retention example Today plus 12, 24 or 36 months
Copyright year Current year written by PHP, filled again by the script

Articles keep their fixed past dates. For reviews and screenshots, ?now=YYYY-MM-DDTHH:MM (read as Eastern time) pretends it is another moment, for example /resources/?now=2027-11-10T09:00; turn it off with ALLOW_NOW_PARAM = false at the top of main.js.

Block styles#

In the block settings' Styles panel:

Block Styles
Button Fill (default, the indigo button), Outline, Marigold (on dark), Ghost (on dark)

The class is-small on a Button block makes it the smaller size. The arrow after button text is drawn with CSS (icon-after-arrow-right, from src/icons.css).

Forms#

All forms validate in the browser with inline messages linked by aria-describedby, focus the first problem and then show a success panel. No form sends anything until you connect it.

Form Page Checks Success
Demo request (data-demo-form) Book a demo Names, work email (format, and not a personal domain from PERSONAL_DOMAINS), company, role, size "Thanks, {name}. Your demo request is in.", reference SW-XXXXXX, proposed time in the visitor's zone and in Eastern, next steps
Webinar registration (data-webinar-form) Resources Name, email Registration reference WB-XXXXX and the session time

The Book a demo page also reads ?plan=essentials|growth|enterprise&employees= to preselect the plan and company size, and ?topic=security to tick "Security and reporting".

To connect a form service such as Formspree, add the request inside setupForm in assets/js/main.js (in a child theme), where it calls onSuccess, and show the success panel only when the service answers OK:

js
fetch('https://formspree.io/f/your-id', { method: 'POST', body: new FormData(form), headers: { Accept: 'application/json' } })
  .then(function (r) { if (r.ok) { /* run the existing success code */ } else { /* show an error */ } });

You can also replace a form's Custom HTML block with a form plugin's block; add the classes field-label, field and btn-primary to its labels, fields and button so it matches.

Saved data (localStorage)#

All storage goes through safeStorage in main.js, which falls back to memory when localStorage is blocked (private modes, sandboxed frames), so the features keep working for the visit.

Key Shape Validation
slatework:theme "light" or "dark" Anything else is ignored
slatework:pipeline { "v": 1, "stages": { "ramona": "offer", ... }, "order": ["ramona", ...] } Unknown candidates or stages are dropped; missing cards keep their starting stage
slatework:pricing { "billing": "annual", "employees": 200, "plan": "growth", "hires": 40 } Each field checked against its allowed values and range

These are the HTML version's keys. All values read from the URL are checked with own-key lookups, so ?plan=toString is ignored.

SEO and sharing#

Page titles come from WordPress: the page title, a vertical bar and the site name (for example "Pricing: per-employee plans for growing companies | Slatework"); the home page shows "Slatework: applicant tracking and hiring software for growing companies", built from the site title and tagline (Settings > General) by freeframe_slatework_front_title(). 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 x 630 image) as the default social image. 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), landmarks (header, labeled navigation, main, footer), one h1 per page, sections labeled by their headings, visible focus outlines, AA contrast in both themes, a full keyboard path for the pipeline board (the Move menu) with announcements in a live region, scorecard ratings as radio groups, filters with aria-pressed, a native <dialog> for integrations, form errors linked with aria-describedby, charts with role="img" and a description, and reduced-motion support. The demo passes axe (WCAG 2.1 A and AA) in light and dark in its checks.

When you edit: keep one Heading 1 per page, give images alt text (or mark them decorative), label every field you add, and keep body text at the Ink soft color or darker.

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/:

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, template or the script's markup, otherwise the class has no style; keep each class name whole in the script (not built from pieces). 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-slatework, without node_modules/) and upload it in Appearance > Themes, or copy the folder to wp-content/themes/ on your server. Use HTTPS, and connect the forms before you go live.

Translations#

The theme is translation-ready with the text domain freeframe-slatework. All text in patterns, templates and PHP goes through WordPress's translation functions; the script's own labels and messages (validation errors, the menu button, status lines) are translated in PHP (freeframe_slatework_script_strings() in inc/setup.php). Sentences the script builds from pieces (dates, counts, prices, announcements) are written in English in main.js; translate them there. Slatework's content in assets/js/data.js is edited there directly. Create a translation with Loco Translate, or with WP-CLI and Poedit:

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

Save freeframe-slatework-es_ES.mo (for example) in wp-content/languages/themes/ or in the theme's languages/ folder. Page content created by Slatework 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 Slatework is updated (your candidates, plans, stories and integrations in particular). Create wp-content/themes/slatework-child/style.css:

css
/*
Theme Name: Slatework Child
Template: freeframe-slatework
*/

Templates, parts, patterns and theme.json in the child theme override the parent's files of the same name. To use your own data.js, replace the parent's data script (freeframe-slatework-data) under the same handle in the child's functions.php:

add_action( 'wp_enqueue_scripts', function () {
	wp_deregister_script( 'freeframe-slatework-data' );
	wp_register_script( 'freeframe-slatework-data', get_stylesheet_directory_uri() . '/data.js', array(), '1.0', array( 'in_footer' => true, 'strategy' => 'defer' ) );
}, 15 );

Do the same for assets/js/main.js (handle freeframe-slatework), keeping the inline window.freeframeSlatework strings and URLs. 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 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 > Slatework.
  • The board keeps an old arrangement. It's saved in slatework:pipeline; click "Reset board".
  • The scheduler shows no slots. The panel has no shared time in the next five weekdays. Check busy blocks and WORK_HOURS in data.js, or pick a shorter interview.
  • Dates look a day off. Dates are computed in Eastern time; change COMPANY.timeZone in data.js for another home zone. Check for a leftover ?now= in the URL.
  • "Book a demo with this estimate" goes to the wrong page. The script links to /demo/. If you renamed the page, change its URL in freeframe_slatework_page_urls() in inc/setup.php.
  • A form says "received" but nothing arrives. The demo forms are not connected; see Forms.
  • Slatework 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 > Slatework pages.

License#

Split license: the PHP code and block markup are licensed under the GNU GPL, version 2 or later, and the CSS, JavaScript, images and design under the Freeframe Commercial License (unlimited sites for you and your clients; no resale or redistribution as a theme). The full terms, with your licensee details, are in LICENSE.txt and at https://freeframe.dev/license#commercial. Third-party components keep their own licenses. Fonts: Hubot Sans and Fira Sans are licensed under the SIL Open Font License 1.1 (OFL.txt in each folder of assets/fonts/). Slatework, its customers, integrations, interviewers and people are fictional.

Search documentation

Search the guides and every template's documentation