Joist
A project-calculation Shopify theme for paint, tile, flooring, decking, lumber, and fasteners.
Version 0.1.0 · Shopify Online Store 2.0 · Liquid, JSON templates, native CSS and JavaScript
1. Purpose
Joist is built for home-improvement and hardware stores where the customer is not buying a single object. They are buying a whole job: paint and a roller, tile and spacers, deck boards and structural screws, lumber and a fastener pack.
The signature interaction is the project calculator. Choose a project, enter an area, wall, length, or piece count, and the theme adds the waste factor, rounds up to whole units, and points to the material that covers the job. Product pages repeat the maths in a project signature with coverage, finish, dimensions, compatible materials, tools, safety notes, and a native Add the whole project list action.
Every visual decision is derived from a blueprint and a building site: grid paper, ink rules, safety orange, paint-chip blocks, lumber stamps, and measurement ticks. No app, no remote API, and no dead button.
2. What is included
- Complete Online Store 2.0 theme: JSON templates, sections, blocks, header and footer section groups.
- Project-led home page: hero with a live calculator, full project calculator, six project tiles, a curated supply list, how-to guides, trade CTA, FAQ, and newsletter.
- Product page with a coverage calculator, spec rows, compatible materials, tools, safety notes, and whole-project add-to-cart.
- Spec-card product cards with coverage, finish, dimensions, project use, price, and quick add where the variant model allows it.
- Blueprint collection page with native filters for project, material, dimension, finish, coverage, and skill.
- Cart drawer, predictive search, account component, gift card, password, 404, blog, article, and contact templates.
- Responsive images, keyboard access, visible focus, reduced-motion support, and semantic landmarks.
- Theme editor settings for colors, typography, layout, product cards, social links, and SEO.
- Licensed Shopify Burst photography (six product squares, two landscapes) and an importable thirteen-row product CSV in
demo/joist/.
3. Requirements
- A Shopify store with the Online Store channel.
- A Shopify plan that supports the features you want to use (selling plans, pickup, markets).
- Shopify CLI 4.x for local development, or the Shopify admin upload workflow.
- A development store is strongly recommended before publishing.
4. Installation
Option A — Shopify CLI
npx shopify theme dev --store your-store.myshopify.com --path themes/joist
To upload an unpublished theme:
npx shopify theme push --store your-store.myshopify.com --path themes/joist --unpublished
Option B — Admin upload
- Create a ZIP of the
themes/joistdirectory (do not zip the parent folder). - In Shopify admin, go to Online Store → Themes → Add theme → Upload ZIP file.
- Preview the theme, then publish when ready.
5. Configuration
Theme editor
Open Online Store → Themes → Customize. The main settings are:
- Colors — blueprint
#E8EDF2, ink#14202B, safety orange#E4572E, grid#C9D4DD, and white surfaces. - Typography — Space Grotesk headings, Work Sans body, base size, and heading scale.
- Layout — page width, section spacing, corner radius, and the blueprint grid.
- Product cards — coverage, finish, dimensions, project use, and landscape/square/portrait spec images.
- Social media — profile URLs used by the footer.
- SEO — social share image and favicon.
The buttons use the darker #CF451C action orange with white text. Small orange text on the blueprint uses #A93E1B. These derived tones keep the safety-orange identity above normal text contrast requirements.
Home page sections
The default index.json composes:
- Hero — project
- Project calculator
- Project tiles
- Shop the list
- How-to guides
- Trade CTA
- FAQ — Joist
- Newsletter — Joist
Every section can be reordered, hidden, or duplicated in the editor.
Project calculator
The calculator is a section block, so the same component is used in the hero and in the full calculator band. Each block holds:
| Setting | Meaning |
|---|---|
| Project name | Label shown in the select |
| Product or collection | Destination for the CTA |
| Measure | Area, wall area, linear length, or count |
| Coverage per unit | Square metres, linear metres, or pieces covered by one unit |
| Coverage unit | Label beside the coverage number, e.g. m², linear m, pieces |
| Waste factor | Percentage added before rounding up |
| Unit labels | Plural and singular labels, e.g. cans / can |
The formula is:
units = ceil((base measure × (1 + waste / 100)) / coverage per unit)
Area and wall use length × width (or height). Linear uses length. Count uses the entered quantity. The result rounds up to whole units.
When a block has no coverage number, the card shows an Ask the store state instead of inventing a result. Set the help link in the section settings to a contact page.
Without JavaScript, the calculator form submits to the first linked product or collection. The result panel is hidden and a <noscript> path points to the materials. The CTA still works.
Product signature
snippets/product-signature.liquid reads these product metafields, with product-block fallbacks:
| Metafield | Type | Used by |
|---|---|---|
custom.coverage_per_unit |
Number (decimal) | Coverage row and calculator |
custom.coverage_unit |
Single-line text | Coverage unit, e.g. m² |
custom.waste_factor |
Number (integer) | Calculator waste factor |
custom.measure_type |
Single-line text | area, linear, or count; leave blank to detect from coverage unit |
custom.unit_label |
Single-line text | Plural unit, e.g. boxes |
custom.unit_label_singular |
Single-line text | Singular unit, e.g. box |
custom.finish |
Single-line text | Finish row and product card |
custom.dimensions |
Single-line text | Dimensions row and product card |
custom.spec_code |
Single-line text | Spec code row and product card |
custom.project_use |
Single-line text | Project use row and product card |
custom.compatible_materials |
Single-line text | Comma-separated product handles for the project list |
custom.tools_needed |
Multi-line text | Tools list |
custom.safety_notes |
Multi-line text | Safety prose |
The product block includes fallback settings for every field, so a merchant can launch before the metafields are populated. Missing rows are hidden. If no spec, coverage, material, tool, or safety data exists, the signature is not rendered at all. When coverage is missing but other project data exists, the calculator is replaced with an Ask the store note using the block's help link.
The product calculator updates the main product quantity automatically. Add the whole project list adds the calculated main quantity plus one of each available compatible material via cart/add.js, then dispatches cart:updated so the drawer refreshes. Without JavaScript the project-list action is hidden and the normal product form remains usable.
Product card
Each card reads the same coverage, finish, dimensions, and project metafields. It shows a highlighted coverage strip, a spec list, price, and one action:
- Quick add for a single-variant product.
- Choose options for a product with variants.
- Sold out when unavailable.
The first four cards in the collection and home supply list load eagerly.
Demo catalog and tags
demo/joist/products.csv contains six products and thirteen variant rows:
| Handle | Product | Options | Coverage |
|---|---|---|---|
chalk-interior-paint |
Chalk Interior Paint | Colour: Chalk, Bone, Clay | 45 m² per can |
grid-ceramic-tile |
Grid Ceramic Tile | Glaze: Chalk, Ink | 1.44 m² per box |
snap-vinyl-flooring |
Snap Vinyl Flooring | Colour: Oak, Slate | 2.2 m² per box |
cedar-deck-board |
Cedar Deck Board | Finish: Natural, Weathered | 0.336 m² per board |
kiln-dried-lumber |
Kiln-Dried Lumber | Profile: 38 × 89, 38 × 140, 45 × 145 mm | 2.4 linear m per board |
joist-fastener-pack |
Joist Fastener Pack | Default | 250 pieces per pack |
The tags use stable prefixes:
- Project —
project-paint,project-tile,project-flooring,project-decking,project-lumber,project-fasteners. - Material —
material-paint,material-ceramic,material-vinyl,material-cedar,material-spruce,material-steel. - Dimension —
dimension-2-5l,dimension-200x100,dimension-1200x180,dimension-2400x140,dimension-2400,dimension-250. - Finish —
finish-matte,finish-gloss,finish-natural,finish-sawn,finish-zinc. - Coverage —
coverage-area,coverage-linear,coverage-count. - Skill —
skill-easy,skill-medium. - Editorial —
shop-the-liston all six.
The compatible-material relationships in the demo are:
- Deck board → kiln-dried lumber, fastener pack.
- Kiln-dried lumber → cedar deck board, fastener pack.
- Fastener pack → cedar deck board, kiln-dried lumber.
Paint, tile, and flooring keep the spec and coverage calculator but no compatible list, because their projects do not share a material in this small catalog.
Collections and filters
Create these collections:
shop-the-list— all six products.paint-projects,tile-projects,flooring-projects,decking-projects,lumber-projects,fastener-projects— one project shelf each.
In the Search & Discovery app, add tag filters for Project, Material, Dimension, Finish, Coverage, and Skill. The collection page renders Shopify’s native filters, active pills, sorting, and pagination.
Menus and pages
The default section groups expect these menus:
main-menu— Shop, Projects, Guides, Trade, Contact.header-utility— Project guide, Trade account, Contact.footer-shop— Shop the list, Paint, Tile, Flooring, Decking, Lumber, Fasteners.footer-info— About, Project guide, Trade, Contact, Shipping.customer-account-main-menu— account links.
Recommended pages: About, Project guide (use the page template), Trade, Contact (use page.contact), Shipping. Add two articles to the news blog so the guide cards and article template are testable. Add shipping, refund, terms of service, and privacy policies.
6. Customisation
- Design tokens — edit
config/settings_schema.jsondefaults or use the theme editor. CSS variables are generated insnippets/css-variables.liquidand rendered in the theme, password, and gift card layouts. - Theme CSS —
assets/theme.csscontains the blueprint art direction.assets/base.csscontains shared commerce mechanics and content utilities. - Theme JavaScript —
assets/base.jscontains shared cart, search, header, media, and motion behavior.assets/theme.jscontains the project and product calculators and the whole-project add action. - Sections — add or duplicate sections in
sections/. Each section has a{% schema %}block. - Product page blocks — reorder or hide blocks in the editor. The product form, project signature, custom liquid, app blocks, and optional complementary products are separate blocks.
- Translation — edit
locales/en.default.json. The theme usestfilters for storefront strings. - Icons —
snippets/icon.liquidcontains original SVG paths.
7. Validation status
npx shopify theme check --path themes/joist --fail-level error: 0 offenses across 69 inspected files.node tools/validate-themes.mjs: All structural checks passed, with Joist included in the portfolio scan.- Live-store installation, calculator cart behavior, checkout, filters, selling plans, pickup, and Lighthouse were not executed in this environment. Run the commands in section 8 on a development store before submission.
8. Pre-launch checklist
npx shopify theme check --path themes/joist --fail-level error
node tools/validate-themes.mjs
npx shopify theme dev --store your-store.myshopify.com --path themes/joist
Then verify on the development store:
- Hero calculator: area, wall, linear, count, each result, ask-store state, and no-JS fallback.
- Full calculator: all six projects, CTA destinations, and mobile stacking.
- Product signature: metafield rows, calculator quantity sync, compatible materials, tools, safety, and whole-project add.
- Add the whole project list with one unavailable material; confirm the available items still add and the drawer refreshes.
- Variant selection, price, compare-at price, unit price, media, and add-to-cart state.
- Cart page and drawer quantities, remove, note, discounts, selling plans, and accelerated checkout.
- Collection filters for project, material, dimension, finish, coverage, and skill; query preservation on search.
- Gift card recipient toggle and hidden fields.
- Mobile header, menu, search, cart, and horizontal overflow at 390×844.
- Heading order, keyboard access, focus states, plural labels, and reduced motion.
9. Known limitations
- Coverage is product-level in this release. If two variants cover different areas, create separate products or use one coverage value that matches the base unit.
- The calculator uses decimal metres and square metres by default; it does not convert feet and inches. Merchants can change the labels and coverage values for another unit system.
- Compatible materials are a comma-separated handle list, not an automatic recommendation engine.
- Without JavaScript, the project calculator submits to the first linked product or collection and the whole-project action is hidden.
- The demo images use licensed Shopify Burst photography. Original SVGs remain in
demo/joist/images/as offline fallbacks. - The
theme_infodocumentation and support URLs point todeivisoft.eu. Publish those pages before submission. - The theme ships one preset. Additional presets require a
/listingsfolder and separate demo stores. - Shopify Theme Store acceptance is not guaranteed. Review the current requirements and test on a development store before submitting.
10. Support and license
See LICENSE.md for the commercial license terms. See the repository root THIRD_PARTY_NOTICES.md for third-party components. This theme does not bundle third-party JavaScript libraries or font files.
For support, use the contact channel defined by the seller. Theme support covers theme bugs and documented configuration; it does not include custom design or code changes.
FAQ
How do I install the theme?
Install the ZIP from the Theme Store or upload it under Online Store → Themes → Add theme → Upload ZIP file. Then publish or preview the theme.
Does the theme require apps?
No. The core experience uses native Shopify features. App blocks are available for optional integrations such as reviews, subscriptions, or wholesale pricing.
How do I get support?
Use the support form. Include your store URL, theme name, and a description of the issue. We reply within two business days.
How do updates work?
Theme Store purchases include updates. Download the latest version from the Theme Store or your Shopify admin and apply it to a duplicate of your theme before publishing.