Suds System StudioRelease and design control

Suds Build System 2.0 — Section Catalog

Every section in the library, with a real rendered thumbnail and the metadata that decides when it appears — plus a coverage matrix that shows which client scenarios are fully dressed and which still need sections built.

62 sections 26 categories 9 scenario signals
Built without --base — metadata + coverage matrix only. Re-run with --base=<running-clone-url> to inline real section thumbnails.

A · Section library

About / Story
no thumbnail on this snapshot
About / Story stable
story prose
Fires whenbase — always eligible
Pagesabout, home
UseAbout intro as plain prose. Pick when there is editor copy or you want a simple, text-led lead with no image.
Claim-safeAlways renders; claim-safe generated intro from name/city/areas when no copy.
Service areas
needs option:suds_service_areas</code> <code>signal:service_area_content
Service areas stable
service-area chips
Fires whenservice_area_content
Needsoption:suds_service_areas
Pageshome, about, contact
UseCompact chip row of service-area towns. Pick for a light area touch on home/about/contact.
Claim-safeHides if suds_service_areas is empty.
Pricing & payment
no thumbnail on this snapshot
Pricing & payment stable
pricing payment_callout
Fires whenbase — always eligible
Pagespricing
UsePricing fallback callout ("call for pricing"). Pick on Pricing when no service has public pricing rows.
Claim-safeRenders only when pricing is visible globally and no service has public pricing rows.
Amenities
needs primary_loc:location_amenities
Amenities stable
amenities grid
Fires whenbase — always eligible
Needsprimary_loc:location_amenities
Pagesabout, home, location
UseAmenities grid from the primary location. Pick to showcase confirmed amenities plainly.
Claim-safeHides if location_amenities is empty.
Hours
no thumbnail on this snapshot
Hours stable
hours card
Fires whenbase — always eligible
Pagescontact, about, location
UsePer-day hours card for a SINGLE-LOCATION shop. Pick on contact/about/location when per-day hours exist.
Claim-safeRenders the primary location per-day hours; falls back to the global hours summary, else hides. Self-gates OFF on MULTI-LOCATION builds (>1 published location) — there, hours are per-branch (locations_grid/locations_map <details> + Location pages), so a lone generic hours block would misrepresent branches with different hours. hours_summary_strip (a global operator one-liner) is unaffected.
Map
needs primary_loc:location_map_embed
Map stable
map full
Fires whenbase — always eligible
Needsprimary_loc:location_map_embed
Pagescontact, about, location
UseFull-width Google map embed. Pick on contact/location when an embed is set.
Claim-safeHides if no primary-location map embed.
FAQ
needs cpt:faq
FAQ stable
faq accordion
Fires whenbase — always eligible
Needscpt:faq
Pagesfaq, contact, about, home
UseFAQ accordion from the faq CPT. Pick for collapsible Q&A.
Claim-safeHides if no faq posts.
Commercial / B2B
needs signal:commercial_accounts
Commercial / B2B stable
commercial card
Fires whencommercial_accounts
Pageshome, services, commercial
UseB2B card. Pick to surface commercial accounts when a commercial service exists.
Claim-safeSignal-gated: only renders if a commercial service exists.
CTA — band
no thumbnail on this snapshot
CTA — band stable
cta band
Fires whenbase — always eligible
Pagesservices, pricing, about, contact, location
UseFull-width final CTA band. The default page closer; always safe.
Claim-safeAlways renders; label/sub are signal-aware (no pickup claim on self-service).
Pricing — table
needs cpt:service
Pricing — table stable
pricing table
Fires whenbase — always eligible
Needscpt:service
Pagespricing
UsePer-service rate table. Pick on Pricing when services carry public pricing rows.
Claim-safeHides unless a service has client-confirmed pricing or market-default rows marked for review.
Page header
no thumbnail on this snapshot
Page header stable
hero header
Fires whenbase — always eligible
Pagesabout, services, pricing, contact, faq
UseThe sub-page opener: per-PAGE eyebrow / title override / lead + a background style (none · surface · ink · gradient · image-with-scrim). Fields live on each page/post edit screen.
Claim-safeAlways renders; blank fields fall back to the template default, the page title, and the sentence-bounded auto subtitle. Image bg falls back to the featured image, then degrades to ink (never an empty frame). Agent CLI: `wp suds field-set page_header <field> <v> --page=<type>`.
Services — grid
no thumbnail on this snapshot
Services — grid stable
services grid
Fires whenbase — always eligible
Pageshome, services
UseServices card grid. The default services presentation; image-friendly.
Claim-safeGeneric claim-safe fallback cards; always renders.
Services — list
no thumbnail on this snapshot
Services — list stable
services list
Fires whenbase — always eligible
Pagesservices, home
UseAlternating-row services; a service's featured image renders beside its copy when set. Pick for dense/structured services (value / commercial).
Claim-safeGeneric claim-safe fallback; always renders. Rows without an image stay text-only (no empty frames).
Services — featured
no thumbnail on this snapshot
Services — featured stable
services featured
Fires whenbase — always eligible
Pageshome, services
UseFlagship-led services: the FIRST service (menu_order) renders as a large feature (photo or icon panel + excerpt + CTA), the rest as compact rows. Pick when one service (wash & fold, pickup) leads the business.
Claim-safeThe operator's service ORDER is the emphasis — reorder Services to change the flagship. Same claim-safe generic fallback as the other services variants.
Services — photo grid
no thumbnail on this snapshot
Services — photo grid stable
services photo
Fires whenbase — always eligible
Pageshome, services
UseServices card grid where each card LEADS WITH THE SERVICE FEATURED IMAGE instead of an icon. Pick for image-led services on photo-forward skins (warm / premium / eco).
Claim-safeGeneric claim-safe fallback cards; always renders. A service with no featured image (and every fallback card) shows the claim-safe striped "add a photo" placeholder — NEVER a fabricated photo — so it looks complete during a build and swaps to real photos as service featured images are set.
Pricing — plan cards
needs cpt:service
Pricing — plan cards stable
pricing cards
Fires whenbase — always eligible
Needscpt:service
Pagespricing, services
UseMarketing plan cards per priced service (lowest public price + up to 3 benefits). Pick for a sales-oriented pricing presentation.
Claim-safeHides when no service has client-confirmed pricing or market-default rows marked for review.
Reviews — embed
needs home:suds_reviews_embed
Reviews — embed stable
reviews embed
Fires whenbase — always eligible
Needshome:suds_reviews_embed
Pageshome, about, contact
UseAdmin-entered third-party reviews widget. Pick only when a reviews embed is provided.
Claim-safeRequires suds_reviews_embed; never shows sample quotes. Hides if none.
Reviews — cards
needs home:suds_reviews
Reviews — cards stable
reviews cards
Fires whenbase — always eligible
Needshome:suds_reviews
Pageshome, about
UseReal reviews as cards. Pick when the suds_reviews repeater has entries.
Claim-safeREAL reviews only; hides if none; stars only when a rating is set.
CTA — split
no thumbnail on this snapshot
CTA — split stable
cta split
Fires whenbase — always eligible
Pageshome, services, pricing, about, contact
UseTwo-column CTA: copy + an action card (CTA link + call/text). Pick when you want a contact-action card alongside the CTA.
Claim-safeReal link, no fake form; signal-aware copy. tone targets the OUTER band; the panel itself takes the cta_bg knob (ink|primary|tint|surface) — on tone=dark the default ink panel lifts to the shared card mix so it never sinks ink-on-ink.
Steps — numbered
no thumbnail on this snapshot
Steps — numbered stable
steps numbered
Fires whenbase — always eligible
Pageshome, services, about
UseNumbered "how it works". The default how-it-works; balanced.
Claim-safeSignal-aware claim-safe default flow (self-service vs pickup); always renders.
Steps — icon row
no thumbnail on this snapshot
Steps — icon row stable
steps iconrow
Fires whenbase — always eligible
Pageshome, services, about
UseCompact horizontal numbered steps. Pick for a light, scannable flow (express / value).
Claim-safeSignal-aware default flow; always renders.
About / Story — split
no thumbnail on this snapshot
About / Story — split stable
story split
Fires whenbase — always eligible
Pagesabout, home
UseAbout intro copy beside a photo. Pick for an image-led, warmer lead when a storefront/interior photo exists.
Claim-safeShows a claim-safe striped photo placeholder when no image; always renders.
Amenities — chips
needs primary_loc:location_amenities
Amenities — chips stable
amenities chips
Fires whenbase — always eligible
Needsprimary_loc:location_amenities
Pagesabout, home, location
UseCompact chip row of amenities. Pick for a light amenities touch (express / value).
Claim-safeHides if none.
Service areas — columns
needs option:suds_service_areas</code> <code>signal:service_area_content
Service areas — columns stable
service-area columns
Fires whenservice_area_content
Needsoption:suds_service_areas
Pageshome, about, contact
UseMulti-column town list. Pick when the area list is long and you want a denser, scannable block.
Claim-safeHides if no areas.
Map — split (map + NAP/hours)
needs primary_loc:location_map_embed
Map — split (map + NAP/hours) stable
map split
Fires whenbase — always eligible
Needsprimary_loc:location_map_embed
Pagescontact, about, location
UseMap beside the location name/address/phone + hours. Pick when you want the map plus confirmed contact details.
Claim-safeHides if no map embed; all data confirmed.
Pickup & delivery — form
needs signal:pickup_delivery
Pickup & delivery — form stable
pickup-delivery form
Fires whenpickup_delivery
Pageshome, services
UseZIP lead-in + real scheduling link. Pick as an app-style lead capture when pickup is offered (express).
Claim-safeSignal-gated: pickup_delivery. Never on self-service-only.
Pickup & delivery — steps
needs signal:pickup_delivery
Pickup & delivery — steps stable
pickup-delivery steps
Fires whenpickup_delivery
Pageshome, services
UsePickup flow steps + scheduling CTA. Pick to explain the pickup process.
Claim-safeSignal-gated: pickup_delivery.
Services — icon row
no thumbnail on this snapshot
Services — icon row stable
services iconrow
Fires whenbase — always eligible
Pageshome, services, about
UseCompact icon + label strip of services. Pick for a light services overview (express).
Claim-safeGeneric fallback; always renders. `display=cards` upgrades the bare icons to tappable cards (gradient icon tile + hover lift) when the band feels too plain.
Reviews — quote wall
needs home:suds_reviews
Reviews — quote wall stable
reviews quotewall
Fires whenbase — always eligible
Needshome:suds_reviews
Pageshome, about
UseDense masonry wall of real reviews. Pick when there are many reviews and you want social-proof density.
Claim-safeREAL reviews only; hides if none.
CTA — boxed
no thumbnail on this snapshot
CTA — boxed stable
cta boxed
Fires whenbase — always eligible
Pageshome, services, pricing, about, contact, faq
UseCentered boxed CTA card. Pick for a softer, contained closer (warm / premium / eco).
Claim-safeAlways renders; signal-aware copy.
Newsletter — signup band
no thumbnail on this snapshot
Newsletter — signup band stable
newsletter band
Fires whenbase — always eligible
Pageshome, about, services, pricing, faq, contact
UseEmail-capture band ahead of the footer. Pick when the client has a real list destination (WPForms form or an external signup URL).
Claim-safeSelf-gates: renders NOTHING without a WPForms id (plugin active) or external link — never a dead form. Claim-safe default copy promises no cadence or offers.
Contact — form + info
no thumbnail on this snapshot
Contact — form + info stable
contact form
Fires whenbase — always eligible
Pagescontact, about, location
UseContact block: an inquiry FORM beside a phone/email/address/directions card. Leads the contact page; also fits about/location. The bundled "Contact Us" WPForms form auto-imports so a fresh build works out of the box.
Claim-safeForm column self-gates (WPForms id → external form link → nothing — never a dead form); the NAP card keeps the section useful, so it always renders. Scheduling stays a separate link CTA (suds_cta_url); this captures general inquiries, invents no contact facts.
Team — spotlight
no thumbnail on this snapshot
Team — spotlight stable
team spotlight
Fires whenbase — always eligible
Pageshome, about
UseOwner/attendant spotlight — a person-led trust surface ('meet our guides' shape). Pick on Home/About when the client supplies real people.
Claim-safeSelf-gates on the suds_team_people repeater (empty → renders nothing). Auto-layout by count: 1 person = feature split, 2–3 = card grid. No photo → initials monogram, NEVER a stock face; role is free text (no invented credentials).
FAQ — two columns
needs cpt:faq
FAQ — two columns stable
faq twocol
Fires whenbase — always eligible
Needscpt:faq
Pagesfaq, contact, about, home
UseOpen two-column Q&A. Pick when you want all answers visible (dense / value / commercial).
Claim-safeHides if no faq posts.
Service areas — map
needs option:suds_service_areas</code> <code>signal:service_area_content
Service areas — map stable
service-area map
Fires whenservice_area_content
Needsoption:suds_service_areas
Pageshome, about, contact
UseTown list beside the map embed. Pick on location-focused pages where a map embed exists.
Claim-safeList-only without a map; hides if no areas.
Locations — grid
needs cpt:location</code> <code>signal:multi_location
Locations — grid stable
locations grid
Fires whenmulti_location
Needscpt:location
Pagescontact, about, location
UseOne card per published Location (name, address, phone, directions, page link; primary badged). Pick on Contact/About/Location pages for MULTI-location clients.
Claim-safeSignal-gated (multi_location) AND self-gates below 2 published locations — a single-location site never renders it. Real Location posts only; per-branch hours render behind a native <details> disclosure when confirmed rows exist.
Locations — photo grid
needs cpt:location</code> <code>signal:multi_location
Locations — photo grid stable
locations photo
Fires whenmulti_location
Needscpt:location
Pagescontact, about, location
UseSame as locations_grid but each branch card LEADS WITH THE LOCATION FEATURED IMAGE. Pick for image-led multi-location on photo-forward skins.
Claim-safeSame gating as locations_grid (multi_location + 2+ published locations). A location with no featured image shows the claim-safe striped "add a photo" placeholder — NEVER a fabricated photo — swapping to the real photo when set.
Locations — map
needs cpt:location</code> <code>signal:multi_location
Locations — map stable
locations map
Fires whenmulti_location
Needscpt:location
Pagescontact, about, location
UseCompact branch list beside the primary map embed — the map-led locations variant. Pick on Contact/About/Location for MULTI-location clients on map-forward skins.
Claim-safeSame gating as locations_grid (multi_location + 2+ published locations). Renders the list WITHOUT the map column when no embed exists (never hides a composed locations slot). Per-branch hours render behind a native <details> disclosure when confirmed rows exist.
Gallery — grid
needs home:suds_why_gallery
Gallery — grid stable
gallery grid
Fires whenbase — always eligible
Needshome:suds_why_gallery
Pagesabout, location
UseStandalone photo grid from the shared interior gallery (first photo leads larger). Pick on About/Location for PHOTO-RICH clients.
Claim-safeSelf-gates below 3 real images (the why panel covers 1–2). Renders existing client media only — never stock/placeholder padding. Photos take the archetype photo grade.
Gallery — strip
needs home:suds_why_gallery
Gallery — strip stable
gallery strip
Fires whenbase — always eligible
Needshome:suds_why_gallery
Pagesabout, location
UseThe photo gallery as a slim scroll-snap filmstrip — the compact variant for dense/technical skins. Pick on About/Location where the full grid is too heavy.
Claim-safeSame data + 3+-image self-gate as gallery_grid; keyboard-scrollable (focusable strip). Existing client media only.
Amenities — feature
needs primary_loc:location_amenities
Amenities — feature stable
amenities feature
Fires whenbase — always eligible
Needsprimary_loc:location_amenities
Pagesabout, home, location
UseA few large amenity feature cards. Pick to spotlight 2–4 standout amenities (warm / premium / eco).
Claim-safeHides if none.
Steps — vertical
no thumbnail on this snapshot
Steps — vertical stable
steps vertical
Fires whenbase — always eligible
Pageshome, services, about
UseVertical numbered timeline. Pick for a structured, sequential flow (commercial / premium).
Claim-safeSignal-aware default flow; always renders.
About / Story — values
no thumbnail on this snapshot
About / Story — values stable
story values
Fires whenbase — always eligible
Pagesabout, home
UseGeneric, claim-safe value cards (clean / easy / helpful). Pick when there is no copy or photo and you want a structured, confident block (commercial / premium).
Claim-safeGeneric-safe; invents no facts. Always renders.
Hours — summary strip
needs option:suds_hours_summary
Hours — summary strip stable
hours summary_strip
Fires whenbase — always eligible
Needsoption:suds_hours_summary
Pagescontact, about, home, location
UseOne-line hours strip. Pick for a compact hours mention when only a summary line is set.
Claim-safeHides if suds_hours_summary is empty.
Pickup & delivery — promo
needs signal:pickup_delivery
Pickup & delivery — promo stable
pickup-delivery promo
Fires whenpickup_delivery
Pageshome, services, pricing
UsePunchy pickup promo card + CTA. Pick as a compact pickup highlight.
Claim-safeSignal-gated: pickup_delivery.
Commercial / B2B — split
needs signal:commercial_accounts
Commercial / B2B — split stable
commercial split
Fires whencommercial_accounts
Pageshome, services, commercial
UseCommercial benefits + photo from the commercial service. Pick for a richer B2B showcase.
Claim-safeCommercial-service gated.
Wash & fold — split
needs signal:wash_fold
Wash & fold — split stable
wash-fold split
Fires whenwash_fold
Pageshome, services
UseWash & fold explainer + photo. Pick to feature a wash & fold offering.
Claim-safeSignal-gated: wash_fold.
Wash & fold — steps
needs signal:wash_fold
Wash & fold — steps stable
wash-fold steps
Fires whenwash_fold
Pageshome, services
UseWash & fold drop-off flow. Pick to explain the wash & fold process.
Claim-safeSignal-gated: wash_fold; generic flow fallback.
Trust — badges
no thumbnail on this snapshot
Trust — badges stable
trust badges
Fires whenbase — always eligible
Pageshome, about, services, contact
UseReassurance strip from confirmed amenities, else generic-safe badges. Pick for a light trust row; always safe.
Claim-safeAlways renders; generic-safe when no amenities.
Trust — stats
needs home:suds_hero_stats
Trust — stats stable
trust stats
Fires whenbase — always eligible
Needshome:suds_hero_stats
Pageshome, about, commercial
UseHeadline numbers from confirmed hero stats. Pick only when real stats are entered.
Claim-safeCONFIRMED only — hides if no suds_hero_stats.
Trust — guarantee
no thumbnail on this snapshot
Trust — guarantee stable
trust guarantee
Fires whenbase — always eligible
Pageshome, about, services, contact
UseSoft, claim-safe promise + call CTA. Pick for a reassurance block.
Claim-safeSoft promise only; never a fabricated warranty. Always renders.
Why us — panel (home)
no thumbnail on this snapshot
Why us — panel (home) stable
why panel
Fires whenbase — always eligible
Pageshome
UseHome "why choose us" rich panel (copy + benefits + interior gallery + amenities). The home `why` slot.
Claim-safeHome-only; always renders. Interior gallery shows a slider for 2+ photos, a single photo for one, else a placeholder.
Why us — tiles (home)
no thumbnail on this snapshot
Why us — tiles (home) stable
why tiles
Fires whenbase — always eligible
Pageshome
UseThe why-us home panel as centered intro + icon tiles + amenities, with NO media frame — pick for photo-poor clients or compact skins so the home never shows a placeholder photo box.
Claim-safeShares why_panel content (single owner); the interior gallery fields stay live for the About-page gallery sections. Keeps the .s-why class so band/texture rhythm applies. `align` knob (default center) left-aligns the head + CTA to match pages whose other section heads are left-aligned.
Service area — panel (home)
no thumbnail on this snapshot
Service area — panel (home) stable
areas panel
Fires whenbase — always eligible
Pageshome
UseHome service-area rich panel. The home `areas` slot.
Claim-safeHome-only; always renders.
Reviews — panel (home)
needs signal:has_reviews
Reviews — panel (home) stable
reviews panel
Fires whenhas_reviews
Pageshome
UseHome reviews rich panel. The home `quotes` slot.
Claim-safeHome-only; admin embed → real suds_reviews, with an optional verified Google badge. Self-gates when no real review source exists.
Services — archive grid
needs cpt:service
Services — archive grid stable
services archive
Fires whenbase — always eligible
Needscpt:service
Pagesservices
UseThe /services/ CPT-archive grid (every published service as a card), riding the MAIN archive query. The default grid slot on the services archive — compose a services_* variant to swap it.
Claim-safeArchive-context section: it renders the main query, so outside /services/ it shows the empty state. Promoted from the hardcoded archive part (byte-identical).
Locations — archive grid
needs cpt:location
Locations — archive grid stable
locations archive
Fires whenbase — always eligible
Needscpt:location
Pageslocations
UseThe /locations/ CPT-archive branch grid, riding the MAIN archive query. The default grid slot on the locations archive — compose locations_grid/photo/map to swap it (multi-location clients).
Claim-safeArchive-context section, NOT signal-gated: the archive always shows its branches (single-location clients keep it via the template fallback). Promoted from the hardcoded archive part (byte-identical).
Service page — body
needs cpt:service
Service page — body stable
service-single body
Fires whenbase — always eligible
Needscpt:service
Pagesservice
UseThe single-service main content (description, benefits, process steps, pricing) read from the CURRENT service post. Part of every service single by default.
Claim-safeSingle-context section: reads the queried service post; composable per-type (suds_section_stack_service option) or per-post (suds_section_stack meta).
Service page — related services
needs cpt:service
Service page — related services stable
service-single related
Fires whenbase — always eligible
Needscpt:service
Pagesservice
UseCross-links the OTHER services from a service single. Part of every service single by default; remove per-type or per-post via composition.
Claim-safeSingle-context section: excludes the queried service from its grid.
Location page — info card
needs cpt:location
Location page — info card stable
location-single info
Fires whenbase — always eligible
Needscpt:location
Pageslocation
UseThe single-location NAP block (address, phone, hours, map embed, amenities) read from the CURRENT location post. Part of every location single by default.
Claim-safeSingle-context section: reads the queried location post; composable per-type (suds_section_stack_location option) or per-post (suds_section_stack meta).
Location page — gallery
needs cpt:location
Location page — gallery stable
location-single gallery
Fires whenbase — always eligible
Needscpt:location
Pageslocation
UseThe single-location photo gallery (location_gallery field, Fancybox lightbox) read from the CURRENT location post. Self-gates when the location has no gallery.
Claim-safeSingle-context section: reads the queried location post.
Laundry card — balance check (home)
needs home:suds_cardbalance_url
Laundry card — balance check (home) stable
payment cardbalance
Fires whenbase — always eligible
Needshome:suds_cardbalance_url
Pageshome
UseStored-value laundry-card balance check (Laundroworks/FasCard portal link) as a compact home utility band. Pick when the client uses a card system with a customer portal.
Claim-safeURL-gated on home:suds_cardbalance_url — hidden until the portal link is entered (never a dead CTA). Also surfaces a matching button in the footer hours column when the URL is set. Ported from the t2-laundry fork.

B · Coverage matrix — categories × scenario signals

Each cell counts sections in that category that fire for the scenario. Columns cover two layers: per-section triggers (e.g. pickup_delivery, commercial_accounts) that select individual sections, and site-level signals (e.g. commercial, multi_location, has_reviews) that gate whole categories at render time — so the latter often show no per-section count. Sparse columns are scenarios with thin coverage; flagged categories have only one variant.

category variants base commercialcommercial_accountshas_reviewsmulti_locationpickup_deliveryservice_areaservice_area_contentspanishwash_fold
amenities 3 3 ·········
areas 1 1 ·········
commercial 2 · ·2·······
contact 1 1 ·········
cta 3 3 ·········
faq 2 2 ·········
gallery 2 2 ·········
hero 1 1 ·········
hours 2 2 ·········
location-single 2 2 ·········
locations 4 1 ···3·····
map 2 2 ·········
newsletter 1 1 ·········
payment 1 1 ·········
pickup-delivery 3 · ····3····
pricing 3 3 ·········
reviews 4 3 ··1······
service-area 3 · ······3··
service-single 2 2 ·········
services 6 6 ·········
steps 3 3 ·········
story 3 3 ·········
team 1 1 ·········
trust 3 3 ·········
wash-fold 2 · ········2
why 2 2 ·········
2+ sections 1 section none thin — build next

Generated from docs/manifest.json by tools/build-catalog.php. Do not hand-edit — re-run after section or manifest changes. Prefix: {prefix}.