@dloizides/marketing-astro-kit 1.3.3 → 1.4.0
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/package.json +54 -53
- package/src/DemoFrame.astro +268 -264
- package/src/PricingComparison.astro +433 -428
- package/src/PrimaryCta.astro +146 -138
- package/src/TrustSection.astro +524 -516
- package/src/a11y.css +22 -0
package/src/DemoFrame.astro
CHANGED
|
@@ -1,264 +1,268 @@
|
|
|
1
|
-
---
|
|
2
|
-
// Reusable interactive "try it" demo shell for product marketing sites — a
|
|
3
|
-
// themeable chrome around client-side, curated example data. The marketing
|
|
4
|
-
// sites are static (nginx, no backend), so the demo runs ENTIRELY in the
|
|
5
|
-
// browser over honest, clearly-labelled sample data. This component owns the
|
|
6
|
-
// shared parts:
|
|
7
|
-
//
|
|
8
|
-
// • eyebrow / title / intro
|
|
9
|
-
// • a row of clickable example "chips"
|
|
10
|
-
// • a result-panel area — the host supplies one bespoke, product-owned panel
|
|
11
|
-
// per example in the default slot, each tagged `data-demo-result="<id>"`
|
|
12
|
-
// (matching an example id) and the FIRST one also `data-active`
|
|
13
|
-
// • a clearly-visible "sample data" disclaimer line
|
|
14
|
-
// • a primary CTA (reuses PrimaryCta) driving to signup
|
|
15
|
-
//
|
|
16
|
-
// <DemoFrame data={demo}>
|
|
17
|
-
// <div data-demo-result="flagged" data-active
|
|
18
|
-
// id="demo-panel-flagged" role="tabpanel" aria-labelledby="demo-chip-flagged">
|
|
19
|
-
// …your bespoke high-risk result markup…
|
|
20
|
-
// </div>
|
|
21
|
-
// <div data-demo-result="clean"
|
|
22
|
-
// id="demo-panel-clean" role="tabpanel" aria-labelledby="demo-chip-clean">…</div>
|
|
23
|
-
// </DemoFrame>
|
|
24
|
-
//
|
|
25
|
-
// The per-example RESULT markup is inherently product-specific (it mirrors the
|
|
26
|
-
// product's real output), so it comes in via the default slot (Astro forbids a
|
|
27
|
-
// dynamic `slot[name]`, so panels are keyed by a `data-demo-result` attribute
|
|
28
|
-
// instead) while the frame stays shared. The frame's chip ids are
|
|
29
|
-
// `<id>-chip-<exampleId>` and it wires `aria-controls` to `<id>-panel-<exampleId>`,
|
|
30
|
-
// so a host panel should use `id="<id>-panel-<exampleId>"` +
|
|
31
|
-
// `aria-labelledby="<id>-chip-<exampleId>"`. Minimal inline vanilla JS toggles
|
|
32
|
-
// which panel shows on chip click — no framework. Progressive enhancement: the
|
|
33
|
-
// FIRST panel (`data-active`) is visible without JS; the script just moves it.
|
|
34
|
-
import type { DemoFrameData } from './schema';
|
|
35
|
-
import
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
aria-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
data-
|
|
65
|
-
data-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
</
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
chip.
|
|
102
|
-
chip.
|
|
103
|
-
chip.setAttribute('
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
chip.addEventListener('
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
next.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
--_brand
|
|
128
|
-
--
|
|
129
|
-
--
|
|
130
|
-
--
|
|
131
|
-
--
|
|
132
|
-
--_bg
|
|
133
|
-
--
|
|
134
|
-
--
|
|
135
|
-
--
|
|
136
|
-
--_r-
|
|
137
|
-
--
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
border-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
font-
|
|
150
|
-
font-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
font-
|
|
159
|
-
font-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
.dmk-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
color: var(--
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
@
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
1
|
+
---
|
|
2
|
+
// Reusable interactive "try it" demo shell for product marketing sites — a
|
|
3
|
+
// themeable chrome around client-side, curated example data. The marketing
|
|
4
|
+
// sites are static (nginx, no backend), so the demo runs ENTIRELY in the
|
|
5
|
+
// browser over honest, clearly-labelled sample data. This component owns the
|
|
6
|
+
// shared parts:
|
|
7
|
+
//
|
|
8
|
+
// • eyebrow / title / intro
|
|
9
|
+
// • a row of clickable example "chips"
|
|
10
|
+
// • a result-panel area — the host supplies one bespoke, product-owned panel
|
|
11
|
+
// per example in the default slot, each tagged `data-demo-result="<id>"`
|
|
12
|
+
// (matching an example id) and the FIRST one also `data-active`
|
|
13
|
+
// • a clearly-visible "sample data" disclaimer line
|
|
14
|
+
// • a primary CTA (reuses PrimaryCta) driving to signup
|
|
15
|
+
//
|
|
16
|
+
// <DemoFrame data={demo}>
|
|
17
|
+
// <div data-demo-result="flagged" data-active
|
|
18
|
+
// id="demo-panel-flagged" role="tabpanel" aria-labelledby="demo-chip-flagged">
|
|
19
|
+
// …your bespoke high-risk result markup…
|
|
20
|
+
// </div>
|
|
21
|
+
// <div data-demo-result="clean"
|
|
22
|
+
// id="demo-panel-clean" role="tabpanel" aria-labelledby="demo-chip-clean">…</div>
|
|
23
|
+
// </DemoFrame>
|
|
24
|
+
//
|
|
25
|
+
// The per-example RESULT markup is inherently product-specific (it mirrors the
|
|
26
|
+
// product's real output), so it comes in via the default slot (Astro forbids a
|
|
27
|
+
// dynamic `slot[name]`, so panels are keyed by a `data-demo-result` attribute
|
|
28
|
+
// instead) while the frame stays shared. The frame's chip ids are
|
|
29
|
+
// `<id>-chip-<exampleId>` and it wires `aria-controls` to `<id>-panel-<exampleId>`,
|
|
30
|
+
// so a host panel should use `id="<id>-panel-<exampleId>"` +
|
|
31
|
+
// `aria-labelledby="<id>-chip-<exampleId>"`. Minimal inline vanilla JS toggles
|
|
32
|
+
// which panel shows on chip click — no framework. Progressive enhancement: the
|
|
33
|
+
// FIRST panel (`data-active`) is visible without JS; the script just moves it.
|
|
34
|
+
import type { DemoFrameData } from './schema';
|
|
35
|
+
import './a11y.css';
|
|
36
|
+
import PrimaryCta from './PrimaryCta.astro';
|
|
37
|
+
|
|
38
|
+
interface Props {
|
|
39
|
+
data: DemoFrameData;
|
|
40
|
+
id?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const { data, id = 'demo' } = Astro.props as Props;
|
|
44
|
+
const { examples } = data;
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
<section class="dmk-demo" id={id} aria-labelledby={`${id}-title`} data-demo-frame>
|
|
48
|
+
<div class="dmk-container">
|
|
49
|
+
<p class="dmk-eyebrow" data-reveal>{data.eyebrow}</p>
|
|
50
|
+
<h2 class="dmk-title" id={`${id}-title`} data-reveal>{data.title}</h2>
|
|
51
|
+
{data.intro && <p class="dmk-intro" data-reveal>{data.intro}</p>}
|
|
52
|
+
|
|
53
|
+
<div class="dmk-panel" data-reveal>
|
|
54
|
+
<div class="dmk-chips" role="tablist" aria-label="Example inputs">
|
|
55
|
+
{examples.map((ex, i) => (
|
|
56
|
+
<button
|
|
57
|
+
type="button"
|
|
58
|
+
class="dmk-chip"
|
|
59
|
+
role="tab"
|
|
60
|
+
id={`${id}-chip-${ex.id}`}
|
|
61
|
+
aria-controls={`${id}-panel-${ex.id}`}
|
|
62
|
+
aria-selected={i === 0 ? 'true' : 'false'}
|
|
63
|
+
tabindex={i === 0 ? '0' : '-1'}
|
|
64
|
+
data-demo-chip={ex.id}
|
|
65
|
+
data-active={i === 0 ? '' : undefined}
|
|
66
|
+
data-umami-event={ex.analyticsEvent}
|
|
67
|
+
>
|
|
68
|
+
<span class="dmk-chip__label">{ex.label}</span>
|
|
69
|
+
{ex.sublabel && <span class="dmk-chip__sub">{ex.sublabel}</span>}
|
|
70
|
+
</button>
|
|
71
|
+
))}
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<div class="dmk-results">
|
|
75
|
+
<slot />
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<p class="dmk-disclaimer" data-reveal>
|
|
79
|
+
<span class="dmk-disclaimer__dot" aria-hidden="true"></span>
|
|
80
|
+
{data.disclaimer}
|
|
81
|
+
</p>
|
|
82
|
+
|
|
83
|
+
<div class="dmk-cta" data-reveal>
|
|
84
|
+
<PrimaryCta cta={data.cta} secondary={data.secondaryCta} size="md" />
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
</section>
|
|
89
|
+
|
|
90
|
+
<script>
|
|
91
|
+
// Chip → result toggle for every DemoFrame on the page. Progressive
|
|
92
|
+
// enhancement: without JS the CSS already shows the first ([data-active])
|
|
93
|
+
// result; this just moves `data-active` on click (and arrow-key roving so the
|
|
94
|
+
// tablist is keyboard-navigable).
|
|
95
|
+
document.querySelectorAll('[data-demo-frame]').forEach((frame) => {
|
|
96
|
+
const chips = Array.from(frame.querySelectorAll('[data-demo-chip]'));
|
|
97
|
+
const results = Array.from(frame.querySelectorAll('[data-demo-result]'));
|
|
98
|
+
|
|
99
|
+
const activate = (key) => {
|
|
100
|
+
chips.forEach((chip) => {
|
|
101
|
+
const on = chip.getAttribute('data-demo-chip') === key;
|
|
102
|
+
chip.toggleAttribute('data-active', on);
|
|
103
|
+
chip.setAttribute('aria-selected', on ? 'true' : 'false');
|
|
104
|
+
chip.setAttribute('tabindex', on ? '0' : '-1');
|
|
105
|
+
});
|
|
106
|
+
results.forEach((result) => {
|
|
107
|
+
result.toggleAttribute('data-active', result.getAttribute('data-demo-result') === key);
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
chips.forEach((chip, index) => {
|
|
112
|
+
chip.addEventListener('click', () => activate(chip.getAttribute('data-demo-chip')));
|
|
113
|
+
chip.addEventListener('keydown', (event) => {
|
|
114
|
+
const delta = event.key === 'ArrowRight' ? 1 : event.key === 'ArrowLeft' ? -1 : 0;
|
|
115
|
+
if (!delta) return;
|
|
116
|
+
event.preventDefault();
|
|
117
|
+
const next = chips[(index + delta + chips.length) % chips.length];
|
|
118
|
+
activate(next.getAttribute('data-demo-chip'));
|
|
119
|
+
next.focus();
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
</script>
|
|
124
|
+
|
|
125
|
+
<style>
|
|
126
|
+
.dmk-demo {
|
|
127
|
+
--_brand: var(--brand, #d8332a);
|
|
128
|
+
--_brand-deep: var(--brand-deep, #a8231c);
|
|
129
|
+
--_accent: var(--accent, #f5a300);
|
|
130
|
+
--_ink: var(--ink, #0a0a1f);
|
|
131
|
+
--_paper: var(--paper, #fff);
|
|
132
|
+
--_bg: var(--bg, #fbf9f4);
|
|
133
|
+
--_bg-tint: var(--bg-tint, #f1ede1);
|
|
134
|
+
--_muted: var(--muted, rgba(10, 10, 31, 0.62));
|
|
135
|
+
--_hairline: var(--hairline, rgba(10, 10, 31, 0.1));
|
|
136
|
+
--_r-md: var(--radius-md, 14px);
|
|
137
|
+
--_r-lg: var(--radius-lg, 24px);
|
|
138
|
+
--_shadow: var(--shadow, 0 30px 60px -30px rgba(10, 10, 31, 0.4));
|
|
139
|
+
padding: 96px 0;
|
|
140
|
+
background: var(--_paper);
|
|
141
|
+
border-top: 1px solid var(--_hairline);
|
|
142
|
+
border-bottom: 1px solid var(--_hairline);
|
|
143
|
+
}
|
|
144
|
+
.dmk-container {
|
|
145
|
+
width: min(1200px, 100% - 48px);
|
|
146
|
+
margin-inline: auto;
|
|
147
|
+
}
|
|
148
|
+
.dmk-eyebrow {
|
|
149
|
+
font-family: 'Oswald', sans-serif;
|
|
150
|
+
font-size: 12px;
|
|
151
|
+
font-weight: 600;
|
|
152
|
+
letter-spacing: 0.22em;
|
|
153
|
+
text-transform: uppercase;
|
|
154
|
+
color: var(--_brand);
|
|
155
|
+
margin: 0;
|
|
156
|
+
}
|
|
157
|
+
.dmk-title {
|
|
158
|
+
font-family: 'Oswald', 'Inter', sans-serif;
|
|
159
|
+
font-size: clamp(30px, 3.8vw, 46px);
|
|
160
|
+
font-weight: 700;
|
|
161
|
+
line-height: 1.08;
|
|
162
|
+
letter-spacing: -0.01em;
|
|
163
|
+
margin: 12px 0 14px;
|
|
164
|
+
max-width: 24ch;
|
|
165
|
+
color: var(--_ink);
|
|
166
|
+
}
|
|
167
|
+
.dmk-intro {
|
|
168
|
+
color: var(--_muted);
|
|
169
|
+
max-width: 62ch;
|
|
170
|
+
margin: 0 0 36px;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* Panel --------------------------------------------------------------- */
|
|
174
|
+
.dmk-panel {
|
|
175
|
+
padding: 26px;
|
|
176
|
+
border-radius: var(--_r-lg);
|
|
177
|
+
background: var(--_bg);
|
|
178
|
+
border: 1px solid var(--_hairline);
|
|
179
|
+
}
|
|
180
|
+
@media (max-width: 560px) {
|
|
181
|
+
.dmk-panel { padding: 18px; }
|
|
182
|
+
.dmk-demo { padding: 64px 0; }
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* Chips (tablist) ----------------------------------------------------- */
|
|
186
|
+
.dmk-chips {
|
|
187
|
+
display: flex;
|
|
188
|
+
flex-wrap: wrap;
|
|
189
|
+
gap: 10px;
|
|
190
|
+
margin-bottom: 22px;
|
|
191
|
+
}
|
|
192
|
+
.dmk-chip {
|
|
193
|
+
box-sizing: border-box;
|
|
194
|
+
min-height: var(--tmk-min-target);
|
|
195
|
+
min-width: var(--tmk-min-target);
|
|
196
|
+
display: flex;
|
|
197
|
+
flex-direction: column;
|
|
198
|
+
align-items: flex-start;
|
|
199
|
+
gap: 2px;
|
|
200
|
+
padding: 11px 16px;
|
|
201
|
+
border-radius: var(--_r-md);
|
|
202
|
+
background: var(--_paper);
|
|
203
|
+
border: 1px solid var(--_hairline);
|
|
204
|
+
cursor: pointer;
|
|
205
|
+
text-align: left;
|
|
206
|
+
font-family: inherit;
|
|
207
|
+
transition: border-color 0.14s ease, box-shadow 0.14s ease, transform 0.14s ease,
|
|
208
|
+
background 0.14s ease;
|
|
209
|
+
}
|
|
210
|
+
.dmk-chip:hover { transform: translateY(-1px); border-color: color-mix(in srgb, var(--_brand) 40%, var(--_hairline)); }
|
|
211
|
+
.dmk-chip:focus-visible { outline: 2px solid var(--_brand); outline-offset: 2px; }
|
|
212
|
+
.dmk-chip[data-active] {
|
|
213
|
+
border-color: var(--_brand);
|
|
214
|
+
background: color-mix(in srgb, var(--_brand) 8%, var(--_paper));
|
|
215
|
+
box-shadow: 0 8px 22px -14px color-mix(in srgb, var(--_brand) 80%, transparent);
|
|
216
|
+
}
|
|
217
|
+
.dmk-chip__label {
|
|
218
|
+
font-family: 'Oswald', 'Inter', sans-serif;
|
|
219
|
+
font-weight: 600;
|
|
220
|
+
font-size: 14px;
|
|
221
|
+
letter-spacing: 0.01em;
|
|
222
|
+
color: var(--_ink);
|
|
223
|
+
}
|
|
224
|
+
.dmk-chip__sub {
|
|
225
|
+
font-size: 11.5px;
|
|
226
|
+
color: var(--_muted);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/* Results ------------------------------------------------------------- */
|
|
230
|
+
/* The panels are host-supplied slot content, so the show/hide toggle is
|
|
231
|
+
:global (keyed by data attributes) to reach across the slot boundary; it
|
|
232
|
+
stays scoped under .dmk-results so it can't leak to the wider page. */
|
|
233
|
+
.dmk-results { min-height: 10px; }
|
|
234
|
+
.dmk-results :global([data-demo-result]) { display: none; }
|
|
235
|
+
.dmk-results :global([data-demo-result][data-active]) {
|
|
236
|
+
display: block;
|
|
237
|
+
animation: dmk-fade 0.28s cubic-bezier(0.2, 0.7, 0.2, 1);
|
|
238
|
+
}
|
|
239
|
+
@keyframes dmk-fade {
|
|
240
|
+
from { opacity: 0; transform: translateY(6px); }
|
|
241
|
+
to { opacity: 1; transform: none; }
|
|
242
|
+
}
|
|
243
|
+
@media (prefers-reduced-motion: reduce) {
|
|
244
|
+
.dmk-results :global([data-demo-result][data-active]) { animation: none; }
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* Disclaimer ---------------------------------------------------------- */
|
|
248
|
+
.dmk-disclaimer {
|
|
249
|
+
display: flex;
|
|
250
|
+
align-items: baseline;
|
|
251
|
+
gap: 9px;
|
|
252
|
+
margin: 22px 0 0;
|
|
253
|
+
font-size: 12.5px;
|
|
254
|
+
line-height: 1.5;
|
|
255
|
+
color: var(--_muted);
|
|
256
|
+
font-style: italic;
|
|
257
|
+
}
|
|
258
|
+
.dmk-disclaimer__dot {
|
|
259
|
+
flex-shrink: 0;
|
|
260
|
+
width: 8px;
|
|
261
|
+
height: 8px;
|
|
262
|
+
border-radius: 50%;
|
|
263
|
+
background: var(--_accent);
|
|
264
|
+
transform: translateY(1px);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.dmk-cta { margin-top: 22px; }
|
|
268
|
+
</style>
|