domma-cms 1.8.44 → 1.8.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/admin/js/lib/code-format.js +50 -40
- package/admin/js/templates/docs/usage-blocks.html +29 -0
- package/admin/js/views/page-editor.js +10 -8
- package/docs/configuration.md +19 -7
- package/docs/starter-blocks.md +203 -0
- package/package.json +1 -1
- package/server/blocks/catalog.json +98 -0
- package/server/blocks/domma-block-banner.css +65 -0
- package/server/blocks/domma-block-banner.html +22 -0
- package/server/blocks/domma-block-banner.meta.json +7 -0
- package/server/blocks/domma-block-contact.css +18 -0
- package/server/blocks/domma-block-contact.html +15 -0
- package/server/blocks/domma-block-contact.meta.json +7 -0
- package/server/blocks/domma-block-cta.css +8 -0
- package/server/blocks/domma-block-cta.html +17 -0
- package/server/blocks/domma-block-cta.meta.json +7 -0
- package/server/blocks/domma-block-faq.css +13 -0
- package/server/blocks/domma-block-faq.html +17 -0
- package/server/blocks/domma-block-faq.meta.json +7 -0
- package/server/blocks/domma-block-features.css +18 -0
- package/server/blocks/domma-block-features.html +19 -0
- package/server/blocks/domma-block-features.meta.json +7 -0
- package/server/blocks/domma-block-hero.css +15 -0
- package/server/blocks/domma-block-hero.html +13 -0
- package/server/blocks/domma-block-hero.meta.json +7 -0
- package/server/blocks/domma-block-image.css +8 -0
- package/server/blocks/domma-block-image.html +12 -0
- package/server/blocks/domma-block-image.meta.json +7 -0
- package/server/blocks/domma-block-logos.css +13 -0
- package/server/blocks/domma-block-logos.html +18 -0
- package/server/blocks/domma-block-logos.meta.json +7 -0
- package/server/blocks/domma-block-pricing-card.css +20 -0
- package/server/blocks/domma-block-pricing-card.html +15 -0
- package/server/blocks/domma-block-pricing-card.meta.json +7 -0
- package/server/blocks/domma-block-service-card.css +17 -0
- package/server/blocks/domma-block-service-card.html +15 -0
- package/server/blocks/domma-block-service-card.meta.json +7 -0
- package/server/blocks/domma-block-split.css +26 -0
- package/server/blocks/domma-block-split.html +22 -0
- package/server/blocks/domma-block-split.meta.json +7 -0
- package/server/blocks/domma-block-stats.css +20 -0
- package/server/blocks/domma-block-stats.html +16 -0
- package/server/blocks/domma-block-stats.meta.json +7 -0
- package/server/blocks/domma-block-steps.css +19 -0
- package/server/blocks/domma-block-steps.html +17 -0
- package/server/blocks/domma-block-steps.meta.json +7 -0
- package/server/blocks/domma-block-team-card.css +13 -0
- package/server/blocks/domma-block-team-card.html +14 -0
- package/server/blocks/domma-block-team-card.meta.json +7 -0
- package/server/blocks/domma-block-testimonial.css +13 -0
- package/server/blocks/domma-block-testimonial.html +12 -0
- package/server/blocks/domma-block-testimonial.meta.json +7 -0
- package/server/blocks/domma-block-text.css +9 -0
- package/server/blocks/domma-block-text.html +11 -0
- package/server/blocks/domma-block-text.meta.json +7 -0
- package/server/services/blocks.js +2 -0
- package/server/services/starter-blocks.js +18 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.db-logos {
|
|
2
|
+
margin-block: 1.5rem;
|
|
3
|
+
color: var(--dm-text, #152832);
|
|
4
|
+
overflow-wrap: anywhere;
|
|
5
|
+
text-align: center;
|
|
6
|
+
}
|
|
7
|
+
.db-logos-heading { margin: 0 0 1rem; color: inherit; font-size: clamp(1.6rem, 3vw, 2.4rem); line-height: 1.2; }
|
|
8
|
+
.db-logos-blurb { margin: 0; line-height: 1.75; white-space: pre-line; }
|
|
9
|
+
.db-logos-blurb:empty { display: none; }
|
|
10
|
+
.db-logos-heading:empty { display: none; }
|
|
11
|
+
.db-logos-grid { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 2rem; padding: 1.5rem; }
|
|
12
|
+
.db-logos-grid img { display: block; width: 10rem; max-width: 100%; height: 5rem; object-fit: contain; }
|
|
13
|
+
.db-logos-grid img[src=""], .db-logos-grid img:not([src]) { display: none; }
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
domma-block-logos - A responsive row of up to four organisation logos.
|
|
3
|
+
|
|
4
|
+
Parameters:
|
|
5
|
+
header - Optional heading (h2)
|
|
6
|
+
image1 - Logo 1 image address
|
|
7
|
+
alt1 - Logo 1 organisation name
|
|
8
|
+
image2 - Logo 2 image address
|
|
9
|
+
alt2 - Logo 2 organisation name
|
|
10
|
+
image3 - Logo 3 image address
|
|
11
|
+
alt3 - Logo 3 organisation name
|
|
12
|
+
image4 - Logo 4 image address
|
|
13
|
+
alt4 - Logo 4 organisation name
|
|
14
|
+
|
|
15
|
+
Example:
|
|
16
|
+
[domma-block-logos header="Who we work with" image1="/media/partner-logo.svg" alt1="Partner name" /]
|
|
17
|
+
-->
|
|
18
|
+
<section class="db-logos"><h2 class="db-logos-heading">{{header}}</h2><div class="db-logos-grid"><img src="{{image1}}" alt="{{alt1}}" loading="lazy" decoding="async"><img src="{{image2}}" alt="{{alt2}}" loading="lazy" decoding="async"><img src="{{image3}}" alt="{{alt3}}" loading="lazy" decoding="async"><img src="{{image4}}" alt="{{alt4}}" loading="lazy" decoding="async"></div></section>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.db-price {
|
|
2
|
+
margin-block: 1.5rem;
|
|
3
|
+
color: var(--dm-text, #152832);
|
|
4
|
+
overflow-wrap: anywhere;
|
|
5
|
+
padding: clamp(1.25rem, 3vw, 2rem);
|
|
6
|
+
border: 1px solid var(--dm-card-border, var(--dm-border, #d5e0e5));
|
|
7
|
+
border-radius: var(--dm-radius-xl, 1rem);
|
|
8
|
+
background: var(--dm-card-bg, var(--dm-surface, #f5f8fa));
|
|
9
|
+
}
|
|
10
|
+
.db-price-heading { margin: 0 0 1rem; color: inherit; font-size: clamp(1.6rem, 3vw, 2.4rem); line-height: 1.2; }
|
|
11
|
+
.db-price-blurb { margin: 0; line-height: 1.75; white-space: pre-line; }
|
|
12
|
+
.db-price-blurb:empty { display: none; }
|
|
13
|
+
.db-price-heading { font-size: 1.4rem; }
|
|
14
|
+
.db-price-amount { margin: 0 0 .5rem; font-size: clamp(2rem, 4vw, 3rem); font-weight: 700; line-height: 1.2; }
|
|
15
|
+
.db-price-period { margin: 0 0 1.5rem; line-height: 1.6; }
|
|
16
|
+
.db-price-period:empty { display: none; }
|
|
17
|
+
.db-price a.db-price-link { display: inline-block; max-width: 100%; box-sizing: border-box; margin-top: 1.5rem; padding: .8rem 1.25rem; border: 2px solid currentColor; border-radius: var(--dm-radius, .5rem); color: inherit; font-weight: 600; text-decoration: none; line-height: 1.4; }
|
|
18
|
+
.db-price a.db-price-link:hover { text-decoration: underline; }
|
|
19
|
+
.db-price a.db-price-link:focus-visible { outline: 3px solid currentColor; outline-offset: 4px; }
|
|
20
|
+
.db-price a.db-price-link[href=""], .db-price a.db-price-link:not([href]), .db-price a.db-price-link:empty { display: none; }
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
domma-block-pricing-card - A clear price or package card with an optional enquiry button.
|
|
3
|
+
|
|
4
|
+
Parameters:
|
|
5
|
+
header - Package heading (h3)
|
|
6
|
+
blurb - What is included, as plain text
|
|
7
|
+
price - Price text, including currency and any tax wording
|
|
8
|
+
period - Optional billing period or pricing note
|
|
9
|
+
link - Optional button destination
|
|
10
|
+
label - Optional button text
|
|
11
|
+
|
|
12
|
+
Example:
|
|
13
|
+
[domma-block-pricing-card header="Your package" price="Ask for a quote" blurb="Describe exactly what is included." link="/contact" label="Talk it through" /]
|
|
14
|
+
-->
|
|
15
|
+
<article class="db-price"><h3 class="db-price-heading">{{header}}</h3><p class="db-price-amount">{{price}}</p><p class="db-price-period">{{period}}</p><p class="db-price-blurb">{{blurb}}</p><a class="db-price-link db-price-btn" href="{{link}}">{{label}}</a></article>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
.db-service {
|
|
2
|
+
margin-block: 1.5rem;
|
|
3
|
+
color: var(--dm-text, #152832);
|
|
4
|
+
overflow-wrap: anywhere;
|
|
5
|
+
overflow: hidden; border: 1px solid var(--dm-card-border, var(--dm-border, #d5e0e5)); border-radius: var(--dm-radius-xl, 1rem); background: var(--dm-card-bg, var(--dm-surface, #f5f8fa));
|
|
6
|
+
}
|
|
7
|
+
.db-service-image { display: block; width: 100%; aspect-ratio: 16 / 10; object-fit: cover; }
|
|
8
|
+
.db-service-image[src=""], .db-service-image:not([src]) { display: none; }
|
|
9
|
+
.db-service-body { padding: 1.5rem; }
|
|
10
|
+
.db-service-heading { margin: 0 0 1rem; color: inherit; font-size: clamp(1.6rem, 3vw, 2.4rem); line-height: 1.2; }
|
|
11
|
+
.db-service-blurb { margin: 0; line-height: 1.75; white-space: pre-line; }
|
|
12
|
+
.db-service-blurb:empty { display: none; }
|
|
13
|
+
.db-service-heading { font-size: 1.4rem; }
|
|
14
|
+
.db-service a.db-service-link { display: inline-block; max-width: 100%; box-sizing: border-box; margin-top: 1.5rem; padding: .8rem 1.25rem; border: 2px solid currentColor; border-radius: var(--dm-radius, .5rem); color: inherit; font-weight: 600; text-decoration: none; line-height: 1.4; }
|
|
15
|
+
.db-service a.db-service-link:hover { text-decoration: underline; }
|
|
16
|
+
.db-service a.db-service-link:focus-visible { outline: 3px solid currentColor; outline-offset: 4px; }
|
|
17
|
+
.db-service a.db-service-link[href=""], .db-service a.db-service-link:not([href]), .db-service a.db-service-link:empty { display: none; }
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
domma-block-service-card - A reusable service card with an optional photo and button.
|
|
3
|
+
|
|
4
|
+
Parameters:
|
|
5
|
+
header - Card heading (h3)
|
|
6
|
+
blurb - Service description, as plain text
|
|
7
|
+
image - Image address from your Media library
|
|
8
|
+
alt - Image description; empty for a decorative image
|
|
9
|
+
link - Optional button destination
|
|
10
|
+
label - Optional button text
|
|
11
|
+
|
|
12
|
+
Example:
|
|
13
|
+
[domma-block-service-card header="Your service" blurb="Explain the benefit in a sentence or two." link="/services" label="Find out more" /]
|
|
14
|
+
-->
|
|
15
|
+
<article class="db-service"><img class="db-service-image" src="{{image}}" alt="{{alt}}" loading="lazy" decoding="async"><div class="db-service-body"><h3 class="db-service-heading">{{header}}</h3><p class="db-service-blurb">{{blurb}}</p><a class="db-service-link db-service-btn" href="{{link}}">{{label}}</a></div></article>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
.db-split {
|
|
2
|
+
margin-block: 1.5rem;
|
|
3
|
+
display: grid;
|
|
4
|
+
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
|
5
|
+
align-items: center;
|
|
6
|
+
gap: clamp(1.5rem, 4vw, 3.5rem);
|
|
7
|
+
color: var(--dm-text, #152832);
|
|
8
|
+
}
|
|
9
|
+
.db-split-image {
|
|
10
|
+
display: block;
|
|
11
|
+
width: 100%;
|
|
12
|
+
aspect-ratio: 4 / 3;
|
|
13
|
+
object-fit: cover;
|
|
14
|
+
border-radius: var(--dm-radius-xl, 1rem);
|
|
15
|
+
}
|
|
16
|
+
.db-split-image[src=""], .db-split-image:not([src]) { display: none; }
|
|
17
|
+
.db-split-body { min-width: 0; padding: .5rem 0; }
|
|
18
|
+
.db-split-heading { margin: 0 0 1rem; font-size: clamp(1.75rem, 3vw, 2.5rem); line-height: 1.2; color: inherit; overflow-wrap: anywhere; }
|
|
19
|
+
.db-split-blurb { margin: 0; font-size: 1.1rem; line-height: 1.75; white-space: pre-line; overflow-wrap: anywhere; }
|
|
20
|
+
.db-split a.db-split-link { display: inline-block; margin-top: 1.5rem; padding: .8rem 1.25rem; border: 2px solid currentColor; border-radius: var(--dm-radius, .5rem); color: inherit; font-weight: 600; text-decoration: none; overflow-wrap: anywhere; }
|
|
21
|
+
.db-split a.db-split-link:hover { text-decoration: underline; }
|
|
22
|
+
.db-split a.db-split-link:focus-visible { outline: 3px solid currentColor; outline-offset: 4px; }
|
|
23
|
+
.db-split a.db-split-link[href=""], .db-split a.db-split-link:not([href]), .db-split a.db-split-link:empty { display: none; }
|
|
24
|
+
@media (max-width: 767px) {
|
|
25
|
+
.db-split { grid-template-columns: minmax(0, 1fr); }
|
|
26
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
domma-block-split - A simple image and text section that stacks on phones.
|
|
3
|
+
|
|
4
|
+
Parameters:
|
|
5
|
+
header - Section heading (h2)
|
|
6
|
+
blurb - Section introduction, as plain text
|
|
7
|
+
image - Image address from your media library
|
|
8
|
+
alt - Description of the image
|
|
9
|
+
link - Optional button destination
|
|
10
|
+
label - Optional button text
|
|
11
|
+
|
|
12
|
+
Example:
|
|
13
|
+
[domma-block-split header="Made for your business" blurb="Tell visitors how you can help." image="/media/about.jpg" alt="Our workspace" link="/about" label="Meet us" /]
|
|
14
|
+
-->
|
|
15
|
+
<section class="db-split">
|
|
16
|
+
<img class="db-split-image" src="{{image}}" alt="{{alt}}" loading="lazy" decoding="async">
|
|
17
|
+
<div class="db-split-body">
|
|
18
|
+
<h2 class="db-split-heading">{{header}}</h2>
|
|
19
|
+
<p class="db-split-blurb">{{blurb}}</p>
|
|
20
|
+
<a class="db-split-link db-split-btn" href="{{link}}">{{label}}</a>
|
|
21
|
+
</div>
|
|
22
|
+
</section>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.db-stats {
|
|
2
|
+
margin-block: 1.5rem;
|
|
3
|
+
color: var(--dm-text, #152832);
|
|
4
|
+
overflow-wrap: anywhere;
|
|
5
|
+
text-align: center;
|
|
6
|
+
}
|
|
7
|
+
.db-stats-heading { margin: 0 0 1rem; color: inherit; font-size: clamp(1.6rem, 3vw, 2.4rem); line-height: 1.2; }
|
|
8
|
+
.db-stats-blurb { margin: 0; line-height: 1.75; white-space: pre-line; }
|
|
9
|
+
.db-stats-blurb:empty { display: none; }
|
|
10
|
+
.db-stats-heading:empty { display: none; }
|
|
11
|
+
.db-stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); gap: 1.25rem; margin: 0; }
|
|
12
|
+
.db-stats-item { display: flex; flex-direction: column; gap: .5rem;
|
|
13
|
+
padding: clamp(1.25rem, 3vw, 2rem);
|
|
14
|
+
border: 1px solid var(--dm-card-border, var(--dm-border, #d5e0e5));
|
|
15
|
+
border-radius: var(--dm-radius-xl, 1rem);
|
|
16
|
+
background: var(--dm-card-bg, var(--dm-surface, #f5f8fa));
|
|
17
|
+
}
|
|
18
|
+
.db-stats-item dt { order: 2; font-weight: 400; line-height: 1.6; }
|
|
19
|
+
.db-stats-item dd { order: 1; margin: 0; font-size: clamp(2rem, 4vw, 3rem); font-weight: 700; line-height: 1.2; }
|
|
20
|
+
.db-stats-item:has(dd:empty) { display: none; }
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
domma-block-stats - Up to three useful figures with clear labels.
|
|
3
|
+
|
|
4
|
+
Parameters:
|
|
5
|
+
header - Optional section heading (h2)
|
|
6
|
+
value1 - Figure 1, including any unit
|
|
7
|
+
label1 - Figure 1 explanation
|
|
8
|
+
value2 - Figure 2, including any unit
|
|
9
|
+
label2 - Figure 2 explanation
|
|
10
|
+
value3 - Figure 3, including any unit
|
|
11
|
+
label3 - Figure 3 explanation
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
[domma-block-stats header="A few useful facts" value1="Your figure" label1="Explain what it represents" /]
|
|
15
|
+
-->
|
|
16
|
+
<section class="db-stats"><h2 class="db-stats-heading">{{header}}</h2><dl class="db-stats-grid"><div class="db-stats-item"><dt>{{label1}}</dt><dd>{{value1}}</dd></div><div class="db-stats-item"><dt>{{label2}}</dt><dd>{{value2}}</dd></div><div class="db-stats-item"><dt>{{label3}}</dt><dd>{{value3}}</dd></div></dl></section>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.db-steps {
|
|
2
|
+
margin-block: 1.5rem;
|
|
3
|
+
color: var(--dm-text, #152832);
|
|
4
|
+
overflow-wrap: anywhere;
|
|
5
|
+
}
|
|
6
|
+
.db-steps-heading { margin: 0 0 1rem; color: inherit; font-size: clamp(1.6rem, 3vw, 2.4rem); line-height: 1.2; }
|
|
7
|
+
.db-steps-blurb { margin: 0; line-height: 1.75; white-space: pre-line; }
|
|
8
|
+
.db-steps-blurb:empty { display: none; }
|
|
9
|
+
.db-steps-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); gap: 1.25rem; counter-reset: db-step; list-style: none; margin: 1.5rem 0 0; padding: 0; }
|
|
10
|
+
.db-steps-item { counter-increment: db-step;
|
|
11
|
+
padding: clamp(1.25rem, 3vw, 2rem);
|
|
12
|
+
border: 1px solid var(--dm-card-border, var(--dm-border, #d5e0e5));
|
|
13
|
+
border-radius: var(--dm-radius-xl, 1rem);
|
|
14
|
+
background: var(--dm-card-bg, var(--dm-surface, #f5f8fa));
|
|
15
|
+
}
|
|
16
|
+
.db-steps-item::before { content: counter(db-step, decimal-leading-zero); display: block; margin-bottom: 1rem; font-size: 1.75rem; font-weight: 700; }
|
|
17
|
+
.db-steps-item h3 { margin: 0 0 .75rem; color: inherit; font-size: 1.25rem; }
|
|
18
|
+
.db-steps-item p { margin: 0; line-height: 1.7; white-space: pre-line; }
|
|
19
|
+
.db-steps-item:has(h3:empty) { display: none; }
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
domma-block-steps - A clear, numbered process with up to three steps.
|
|
3
|
+
|
|
4
|
+
Parameters:
|
|
5
|
+
header - Section heading (h2)
|
|
6
|
+
blurb - Introduction, as plain text
|
|
7
|
+
title1 - Step 1 heading
|
|
8
|
+
text1 - Step 1 description
|
|
9
|
+
title2 - Step 2 heading
|
|
10
|
+
text2 - Step 2 description
|
|
11
|
+
title3 - Step 3 heading
|
|
12
|
+
text3 - Step 3 description
|
|
13
|
+
|
|
14
|
+
Example:
|
|
15
|
+
[domma-block-steps header="Getting started" blurb="A simple way forward." title1="Say hello" text1="Tell us what you need." title2="Make a plan" text2="Agree the details together." title3="Get going" text3="Put your plan into action." /]
|
|
16
|
+
-->
|
|
17
|
+
<section class="db-steps"><h2 class="db-steps-heading">{{header}}</h2><p class="db-steps-blurb">{{blurb}}</p><ol class="db-steps-list"><li class="db-steps-item"><h3>{{title1}}</h3><p>{{text1}}</p></li><li class="db-steps-item"><h3>{{title2}}</h3><p>{{text2}}</p></li><li class="db-steps-item"><h3>{{title3}}</h3><p>{{text3}}</p></li></ol></section>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.db-team {
|
|
2
|
+
margin-block: 1.5rem;
|
|
3
|
+
color: var(--dm-text, #152832);
|
|
4
|
+
overflow-wrap: anywhere;
|
|
5
|
+
border: 1px solid var(--dm-card-border, var(--dm-border, #d5e0e5)); border-radius: var(--dm-radius-xl, 1rem); overflow: hidden; background: var(--dm-card-bg, var(--dm-surface, #f5f8fa));
|
|
6
|
+
}
|
|
7
|
+
.db-team-image { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; }
|
|
8
|
+
.db-team-image[src=""], .db-team-image:not([src]) { display: none; }
|
|
9
|
+
.db-team-body { padding: 1.5rem; }
|
|
10
|
+
.db-team-name { margin: 0 0 .5rem; font-size: 1.4rem; color: inherit; }
|
|
11
|
+
.db-team-role { margin: 0 0 1rem; font-weight: 600; }
|
|
12
|
+
.db-team-blurb { margin: 0; white-space: pre-line; line-height: 1.7; }
|
|
13
|
+
.db-team-role:empty, .db-team-blurb:empty { display: none; }
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
domma-block-team-card - A team member photo, role and short introduction.
|
|
3
|
+
|
|
4
|
+
Parameters:
|
|
5
|
+
name - Person name (h3)
|
|
6
|
+
role - Role or specialism
|
|
7
|
+
blurb - Short introduction, as plain text
|
|
8
|
+
image - Image address from your Media library
|
|
9
|
+
alt - Image description; empty for a decorative image
|
|
10
|
+
|
|
11
|
+
Example:
|
|
12
|
+
[domma-block-team-card name="Team member" role="Role or specialism" blurb="A short, friendly introduction." image="/media/team-member.jpg" alt="Portrait of your team member" /]
|
|
13
|
+
-->
|
|
14
|
+
<article class="db-team"><img class="db-team-image" src="{{image}}" alt="{{alt}}" loading="lazy" decoding="async"><div class="db-team-body"><h3 class="db-team-name">{{name}}</h3><p class="db-team-role">{{role}}</p><p class="db-team-blurb">{{blurb}}</p></div></article>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.db-testimonial {
|
|
2
|
+
margin-block: 1.5rem;
|
|
3
|
+
color: var(--dm-text, #152832);
|
|
4
|
+
overflow-wrap: anywhere;
|
|
5
|
+
padding: clamp(1.25rem, 3vw, 2rem);
|
|
6
|
+
border: 1px solid var(--dm-card-border, var(--dm-border, #d5e0e5));
|
|
7
|
+
border-radius: var(--dm-radius-xl, 1rem);
|
|
8
|
+
background: var(--dm-card-bg, var(--dm-surface, #f5f8fa));
|
|
9
|
+
}
|
|
10
|
+
.db-testimonial-quote { margin: 0; padding: 0; border: 0; color: inherit; font-size: clamp(1.15rem, 2vw, 1.6rem); line-height: 1.65; white-space: pre-line; }
|
|
11
|
+
.db-testimonial-attribution { display: grid; gap: .3rem; margin-top: 1.25rem; }
|
|
12
|
+
.db-testimonial-attribution span { font-size: .95rem; }
|
|
13
|
+
.db-testimonial-attribution strong:empty, .db-testimonial-attribution span:empty, .db-testimonial-attribution:has(strong:empty):has(span:empty) { display: none; }
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
domma-block-testimonial - A customer quotation with an optional attribution.
|
|
3
|
+
|
|
4
|
+
Parameters:
|
|
5
|
+
quote - An approved customer quotation, as plain text
|
|
6
|
+
name - Customer name
|
|
7
|
+
detail - Optional role or business
|
|
8
|
+
|
|
9
|
+
Example:
|
|
10
|
+
[domma-block-testimonial quote="Replace this with a customer quotation you have permission to share." name="Customer name" detail="Business or role" /]
|
|
11
|
+
-->
|
|
12
|
+
<figure class="db-testimonial"><blockquote class="db-testimonial-quote">{{quote}}</blockquote><figcaption class="db-testimonial-attribution"><strong>{{name}}</strong><span>{{detail}}</span></figcaption></figure>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
.db-text {
|
|
2
|
+
margin-block: 1.5rem;
|
|
3
|
+
color: var(--dm-text, #152832);
|
|
4
|
+
overflow-wrap: anywhere;
|
|
5
|
+
max-width: 48rem; margin-inline: auto; padding-block: 1rem;
|
|
6
|
+
}
|
|
7
|
+
.db-text-heading { margin: 0 0 1rem; color: inherit; font-size: clamp(1.6rem, 3vw, 2.4rem); line-height: 1.2; }
|
|
8
|
+
.db-text-blurb { margin: 0; line-height: 1.75; white-space: pre-line; }
|
|
9
|
+
.db-text-blurb:empty { display: none; }
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
domma-block-text - A readable text section for your story or an introduction.
|
|
3
|
+
|
|
4
|
+
Parameters:
|
|
5
|
+
header - Section heading (h2)
|
|
6
|
+
blurb - Introduction, as plain text
|
|
7
|
+
|
|
8
|
+
Example:
|
|
9
|
+
[domma-block-text header="Our story" blurb="Share a little about your business and the people behind it." /]
|
|
10
|
+
-->
|
|
11
|
+
<section class="db-text"><h2 class="db-text-heading">{{header}}</h2><p class="db-text-blurb">{{blurb}}</p></section>
|
|
@@ -7,6 +7,7 @@ import fs from 'fs/promises';
|
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import {fileURLToPath} from 'url';
|
|
9
9
|
import * as cache from './cache/index.js';
|
|
10
|
+
import {seedStarterBlocks} from './starter-blocks.js';
|
|
10
11
|
|
|
11
12
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
12
13
|
const BLOCKS_DIR = path.resolve(__dirname, '../../content/blocks');
|
|
@@ -427,6 +428,7 @@ export async function deleteBlock(name) {
|
|
|
427
428
|
* Skips any file that already exists to preserve user customisations.
|
|
428
429
|
*/
|
|
429
430
|
export async function seedDefaultBlocks() {
|
|
431
|
+
await seedStarterBlocks(BLOCKS_DIR);
|
|
430
432
|
for (const [name, content] of Object.entries(BLOCKS)) {
|
|
431
433
|
await seedBlock(name, content);
|
|
432
434
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Editable starting points for new pages, copied without replacing site edits. */
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import {fileURLToPath} from 'node:url';
|
|
5
|
+
|
|
6
|
+
const sourceDir = fileURLToPath(new URL('../blocks/', import.meta.url));
|
|
7
|
+
|
|
8
|
+
export async function seedStarterBlocks(destination) {
|
|
9
|
+
await fs.mkdir(destination, {recursive: true});
|
|
10
|
+
for (const name of await fs.readdir(sourceDir)) {
|
|
11
|
+
if (!/^domma-block-[a-z-]+\.(html|css|meta\.json)$/.test(name)) continue;
|
|
12
|
+
try {
|
|
13
|
+
await fs.copyFile(path.join(sourceDir, name), path.join(destination, name), fs.constants.COPYFILE_EXCL);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
if (error.code !== 'EEXIST') throw error;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|