Component showcase

Contact blocks

Six contact layouts and the parts they share. 7 variants, 6 rendered live.

editorial

contactin useOpen live
desktop preview
desktop 1280px
mobile preview
mobile 390px
Files
  • src/components/sections/contact/Editorial.astro
  • src/components/sections/Contact.astro
  • src/components/closing.ts
  • src/components/contact-parts.ts
How to pin
{
  "variants": {
    "contact": "editorial"
  }
}

HEAD: no. WORKING TREE: yes, theme.json variants.contact="editorial" (closing.ts CONTACTS; pin bypasses contactFits)

Reads
content.contact (not a section; role=contact pages render it first) | contact{phones,whatsapp,emails,address,mapQuery,geo,hours,branches,socials}; page.form.prompt as intro; copy.contactTitle from lib/closing-copy.ts
Used by
cucchiettiboats, donmario, losvallessalud, muebleriaheredia, parrisur
Quality gates
18 codes

contact: duplicate-contact contact-no-icons contact-no-actions contact-channel-overflow repeated-cta tiny-text channel-repeat-in-section email-break placeholder-phone unlinked-contact contact-form contact-value-size contact-value-tracking map-missing iframe-map

mobile: mobile-overflow fab-overlap tiny-text

Selected by
seeded: chooseContact = pick(seed, contact+CLOSING_SALT(50033), CONTACT_TASTE[vertical] filtered by contactFits); Contact.astro reads closingPlan().contact; DOM section#contacto[data-layout]
Notes
Magazine spread: arched photo or map beside display-type channels, week-hours table

dark-map

contactin useOpen live
desktop preview
desktop 1280px
mobile preview
mobile 390px
Files
  • src/components/sections/contact/DarkMap.astro
  • src/components/sections/Contact.astro
  • src/components/closing.ts
  • src/components/contact-parts.ts
How to pin
{
  "variants": {
    "contact": "dark-map"
  }
}

HEAD: no. WORKING TREE: yes, theme.json variants.contact="dark-map" (closing.ts CONTACTS; pin bypasses contactFits)

Reads
content.contact (not a section; role=contact pages render it first) | contact{phones,whatsapp,emails,address,mapQuery,geo,hours,branches,socials}; page.form.prompt as intro; copy.contactTitle from lib/closing-copy.ts
Used by
artesanias-delta, francescoristorante, jlopezluthier
Quality gates
18 codes

contact: duplicate-contact contact-no-icons contact-no-actions contact-channel-overflow repeated-cta tiny-text channel-repeat-in-section email-break placeholder-phone unlinked-contact contact-form contact-value-size contact-value-tracking map-missing iframe-map

mobile: mobile-overflow fab-overlap tiny-text

Selected by
seeded: chooseContact = pick(seed, contact+CLOSING_SALT(50033), CONTACT_TASTE[vertical] filtered by contactFits); Contact.astro reads closingPlan().contact; DOM section#contacto[data-layout]
Notes
Night band, glass channel cards, big inverted map; needs mappable mapQuery/address

ticket

contactunusedOpen live
desktop preview
desktop 1280px
mobile preview
mobile 390px
Files
  • src/components/sections/contact/Ticket.astro
  • src/components/sections/Contact.astro
  • src/components/closing.ts
  • src/components/contact-parts.ts
How to pin
{
  "variants": {
    "contact": "ticket"
  }
}

HEAD: no. WORKING TREE: yes, theme.json variants.contact="ticket" (closing.ts CONTACTS; pin bypasses contactFits)

Reads
content.contact (not a section; role=contact pages render it first) | contact{phones,whatsapp,emails,address,mapQuery,geo,hours,branches,socials}; page.form.prompt as intro; copy.contactTitle from lib/closing-copy.ts
Used by
unused
Quality gates
18 codes

contact: duplicate-contact contact-no-icons contact-no-actions contact-channel-overflow repeated-cta tiny-text channel-repeat-in-section email-break placeholder-phone unlinked-contact contact-form contact-value-size contact-value-tracking map-missing iframe-map

mobile: mobile-overflow fab-overlap tiny-text

Selected by
seeded: chooseContact = pick(seed, contact+CLOSING_SALT(50033), CONTACT_TASTE[vertical] filtered by contactFits); Contact.astro reads closingPlan().contact; DOM section#contacto[data-layout]
Notes
Paper reservation ticket over photo, live open badge; needs hours or (restaurant/events with whatsapp/phones)

numbered

contactin useOpen live
desktop preview
desktop 1280px
mobile preview
mobile 390px
Files
  • src/components/sections/contact/Numbered.astro
  • src/components/sections/Contact.astro
  • src/components/closing.ts
  • src/components/contact-parts.ts
How to pin
{
  "variants": {
    "contact": "numbered"
  }
}

HEAD: no. WORKING TREE: yes, theme.json variants.contact="numbered" (closing.ts CONTACTS; pin bypasses contactFits)

Reads
content.contact (not a section; role=contact pages render it first) | contact{phones,whatsapp,emails,address,mapQuery,geo,hours,branches,socials}; page.form.prompt as intro; copy.contactTitle from lib/closing-copy.ts
Used by
bellevue, dolium, web-express
Quality gates
18 codes

contact: duplicate-contact contact-no-icons contact-no-actions contact-channel-overflow repeated-cta tiny-text channel-repeat-in-section email-break placeholder-phone unlinked-contact contact-form contact-value-size contact-value-tracking map-missing iframe-map

mobile: mobile-overflow fab-overlap tiny-text

Selected by
seeded: chooseContact = pick(seed, contact+CLOSING_SALT(50033), CONTACT_TASTE[vertical] filtered by contactFits); Contact.astro reads closingPlan().contact; DOM section#contacto[data-layout]
Notes
Numbered bento on white dot grid, outlined numerals, brand action tile

poster

contactin useOpen live
desktop preview
desktop 1280px
mobile preview
mobile 390px
Files
  • src/components/sections/contact/Poster.astro
  • src/components/sections/Contact.astro
  • src/components/closing.ts
  • src/components/contact-parts.ts
How to pin
{
  "variants": {
    "contact": "poster"
  }
}

HEAD: no. WORKING TREE: yes, theme.json variants.contact="poster" (closing.ts CONTACTS; pin bypasses contactFits)

Reads
content.contact (not a section; role=contact pages render it first) | contact{phones,whatsapp,emails,address,mapQuery,geo,hours,branches,socials}; page.form.prompt as intro; copy.contactTitle from lib/closing-copy.ts
Used by
gonzalezorfebre
Quality gates
18 codes

contact: duplicate-contact contact-no-icons contact-no-actions contact-channel-overflow repeated-cta tiny-text channel-repeat-in-section email-break placeholder-phone unlinked-contact contact-form contact-value-size contact-value-tracking map-missing iframe-map

mobile: mobile-overflow fab-overlap tiny-text

Selected by
seeded: chooseContact = pick(seed, contact+CLOSING_SALT(50033), CONTACT_TASTE[vertical] filtered by contactFits); Contact.astro reads closingPlan().contact; DOM section#contacto[data-layout]
Notes
Film-poster closer, full-bleed photo, glass strip; needs >=1 contact photo

color-block

contactin useOpen live
desktop preview
desktop 1280px
mobile preview
mobile 390px
Files
  • src/components/sections/contact/ColorBlock.astro
  • src/components/sections/Contact.astro
  • src/components/closing.ts
  • src/components/contact-parts.ts
How to pin
{
  "variants": {
    "contact": "color-block"
  }
}

HEAD: no. WORKING TREE: yes, theme.json variants.contact="color-block" (closing.ts CONTACTS; pin bypasses contactFits)

Reads
content.contact (not a section; role=contact pages render it first) | contact{phones,whatsapp,emails,address,mapQuery,geo,hours,branches,socials}; page.form.prompt as intro; copy.contactTitle from lib/closing-copy.ts
Used by
cuchilloselchaja, dolzhnos, emag, juguetesrasti, rosarioagroindustrial, sialle
Quality gates
18 codes

contact: duplicate-contact contact-no-icons contact-no-actions contact-channel-overflow repeated-cta tiny-text channel-repeat-in-section email-break placeholder-phone unlinked-contact contact-form contact-value-size contact-value-tracking map-missing iframe-map

mobile: mobile-overflow fab-overlap tiny-text

Selected by
seeded: chooseContact = pick(seed, contact+CLOSING_SALT(50033), CONTACT_TASTE[vertical] filtered by contactFits); Contact.astro reads closingPlan().contact; DOM section#contacto[data-layout]
Notes
Brand-colour block, hatch+grain, spinning text seal (ColorBlockSeal/SealMark), glass cards

shared parts

contact-partsin use

not rendered: shared parts that render inside every contact layout (see the contact blocks)

Files
  • src/components/sections/contact/ActionButton.astro
  • src/components/sections/contact/Backdrop.astro
  • src/components/sections/contact/Breakable.astro
  • src/components/sections/contact/ChannelCard.astro
  • src/components/sections/contact/ChannelIcon.astro
  • src/components/sections/contact/ColorBlockSeal.astro
  • src/components/sections/contact/ContactIntro.astro
  • src/components/sections/contact/CopyButton.astro
  • src/components/sections/contact/FitLine.astro
  • src/components/sections/contact/Hours.astro
  • src/components/sections/contact/HoursRanges.astro
  • src/components/sections/contact/Kicker.astro
  • src/components/sections/contact/MapPanel.astro
  • src/components/sections/contact/MoreChannels.astro
  • src/components/sections/contact/NumberedAction.astro
  • src/components/sections/contact/SealMark.astro
  • src/components/sections/contact/Socials.astro
How to pin

no

Used by
not tracked (layout is seeded per site)
Quality gates
15 codes

contact: duplicate-contact contact-no-icons contact-no-actions contact-channel-overflow repeated-cta tiny-text channel-repeat-in-section email-break placeholder-phone unlinked-contact contact-form contact-value-size contact-value-tracking map-missing iframe-map

Selected by
internal
Notes
MapPanel also used by About (location-titled copy) and LocationSection; Hours vs HoursRanges are two hours renderers