@dloizides/marketing-astro-kit 1.5.0 → 1.5.2

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.5.2
4
+
5
+ ### Fixed
6
+
7
+ - `.dmk-disclaimer` (DemoFrame) and `.pmk-footnote` (PricingComparison) cap their measure at 65ch; at 1280 px they ran 102-113 characters per line. Mobile is unaffected.
8
+
3
9
  ## 1.3.0
4
10
 
5
11
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dloizides/marketing-astro-kit",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
4
4
  "description": "Reusable, themeable Astro marketing sections for product sites — a Free-vs-Pro pricing comparison table, a trust / credibility section (security cards, customer-logo + testimonial placeholders, discreet built-by), a client-side \"try it\" demo shell, and an SEO guides/content-hub card + frontmatter schema. Data-driven via a shared TypeScript schema; themed entirely through the host site's CSS custom properties.",
5
5
  "keywords": [
6
6
  "astro",
@@ -254,6 +254,7 @@ const { examples } = data;
254
254
  line-height: 1.5;
255
255
  color: var(--_muted);
256
256
  font-style: italic;
257
+ max-width: 65ch;
257
258
  }
258
259
  .dmk-disclaimer__dot {
259
260
  flex-shrink: 0;
@@ -345,6 +345,7 @@ const { tiers, groups } = data;
345
345
  color: var(--_muted);
346
346
  font-size: 13.5px;
347
347
  margin: 18px 2px 0;
348
+ max-width: 65ch;
348
349
  }
349
350
 
350
351
  /* Concierge / one-time callout --------------------------------------- */
@@ -1,524 +1,530 @@
1
- ---
2
- // Reusable trust / credibility section for product marketing sites — the
3
- // markers an executive scans for: security & compliance cards, a discreet
4
- // "built by" line, plus clearly-labeled PLACEHOLDER slots for customer logos
5
- // and testimonials the site owner fills in with real ones.
6
- //
7
- // Data-driven (schema.ts → TrustSectionData); themed via host CSS vars.
8
- //
9
- // <TrustSection data={trust} id="trust" />
10
- import type { TrustSectionData } from './schema';
11
- import './a11y.css';
12
- import { ctaAttrs } from './schema';
13
- import { TRUST_ICONS } from './icons';
14
-
15
- interface Props {
16
- data: TrustSectionData;
17
- id?: string;
18
- }
19
-
20
- const { data, id = 'trust' } = Astro.props as Props;
21
-
22
- // A product can inject bespoke mock markup for the sample-deliverable showcase
23
- // via <TrustSection><Fragment slot="sample-deliverable">…</Fragment></TrustSection>
24
- // while the eyebrow/title/caption chrome stays shared.
25
- const hasSampleSlot = Astro.slots.has('sample-deliverable');
26
- ---
27
-
28
- <section class="tmk-trust" id={id} aria-labelledby={`${id}-title`}>
29
- <div class="tmk-container">
30
- <p class="tmk-eyebrow" data-reveal>{data.eyebrow}</p>
31
- <h2 class="tmk-title" id={`${id}-title`} data-reveal>{data.title}</h2>
32
- {data.subtitle && <p class="tmk-sub" data-reveal>{data.subtitle}</p>}
33
-
34
- <div class="tmk-grid">
35
- {data.items.map((item, i) => (
36
- <article class="tmk-card" data-reveal style={`--d:${(i % 4) + 1}`}>
37
- <span class="tmk-ico" set:html={TRUST_ICONS[item.icon]} />
38
- <h3 class="tmk-card-t">{item.title}</h3>
39
- <p class="tmk-card-b">{item.body}</p>
40
- </article>
41
- ))}
42
- </div>
43
-
44
- {data.sampleDeliverable && (
45
- <div class="tmk-sample" data-reveal>
46
- <div class="tmk-sample-copy">
47
- <p class="tmk-sample-eyebrow">{data.sampleDeliverable.eyebrow}</p>
48
- <h3 class="tmk-sample-t">{data.sampleDeliverable.title}</h3>
49
- <p class="tmk-sample-cap">{data.sampleDeliverable.caption}</p>
50
- </div>
51
- <div class="tmk-sample-media">
52
- {hasSampleSlot ? (
53
- <slot name="sample-deliverable" />
54
- ) : data.sampleDeliverable.image ? (
55
- <img class="tmk-sample-img" src={data.sampleDeliverable.image} alt={data.sampleDeliverable.title} loading="lazy" />
56
- ) : null}
57
- </div>
58
- </div>
59
- )}
60
-
61
- {data.logos && (
62
- <div class="tmk-logos" data-reveal>
63
- <p class="tmk-logos-label">{data.logos.label}</p>
64
- <div class="tmk-logos-row">
65
- {data.logos.items.map((logo) =>
66
- logo.placeholder ? (
67
- <span class="tmk-logo tmk-logo--ph" aria-hidden="true">Your logo</span>
68
- ) : logo.href ? (
69
- <a class="tmk-logo" href={logo.href} target="_blank" rel="noopener">{logo.name}</a>
70
- ) : (
71
- <span class="tmk-logo">{logo.name}</span>
72
- ),
73
- )}
74
- </div>
75
- {data.logos.note && <p class="tmk-ph-note">{data.logos.note}</p>}
76
- </div>
77
- )}
78
-
79
- {data.testimonials && (
80
- <div class="tmk-quotes" data-reveal>
81
- <p class="tmk-logos-label">{data.testimonials.label}</p>
82
- <div class="tmk-quotes-row">
83
- {data.testimonials.items.map((t) => (
84
- <figure class={`tmk-quote${t.placeholder ? ' tmk-quote--ph' : ''}`}>
85
- {t.placeholder && <span class="tmk-ph-tag">Placeholder</span>}
86
- <blockquote class="tmk-quote-b">{t.quote}</blockquote>
87
- <figcaption class="tmk-quote-cite">
88
- <span class="tmk-quote-name">{t.authorName}</span>
89
- {t.authorRole && <span class="tmk-quote-role">{t.authorRole}</span>}
90
- </figcaption>
91
- </figure>
92
- ))}
93
- </div>
94
- {data.testimonials.note && <p class="tmk-ph-note">{data.testimonials.note}</p>}
95
- </div>
96
- )}
97
-
98
- {data.foundingPartner && (
99
- <aside class="tmk-founding" data-reveal>
100
- <div class="tmk-founding-body">
101
- <p class="tmk-founding-eyebrow">{data.foundingPartner.eyebrow}</p>
102
- <h3 class="tmk-founding-t">{data.foundingPartner.title}</h3>
103
- <p class="tmk-founding-b">{data.foundingPartner.body}</p>
104
- <ul class="tmk-founding-perks">
105
- {data.foundingPartner.perks.map((perk) => <li>{perk}</li>)}
106
- </ul>
107
- </div>
108
- {data.foundingPartner.cta && (
109
- <a class="tmk-founding-cta" {...ctaAttrs(data.foundingPartner.cta)}>
110
- {data.foundingPartner.cta.label}
111
- </a>
112
- )}
113
- </aside>
114
- )}
115
-
116
- {data.founder && (
117
- <figure class="tmk-founder" data-reveal>
118
- {data.founder.avatar ? (
119
- <img class="tmk-founder-av" src={data.founder.avatar} alt={data.founder.name ?? 'Founder'} loading="lazy" />
120
- ) : (
121
- <span class="tmk-founder-av tmk-founder-av--ph" aria-hidden="true">
122
- {(data.founder.name ?? '·').trim().charAt(0)}
123
- </span>
124
- )}
125
- <figcaption class="tmk-founder-cap">
126
- <p class="tmk-founder-line">{data.founder.line}</p>
127
- {(data.founder.name || data.founder.role) && (
128
- <p class="tmk-founder-cite">
129
- {data.founder.name && <span class="tmk-founder-name">{data.founder.name}</span>}
130
- {data.founder.role && <span class="tmk-founder-role">{data.founder.role}</span>}
131
- </p>
132
- )}
133
- </figcaption>
134
- </figure>
135
- )}
136
-
137
- {data.builtBy && (
138
- <p class="tmk-builtby" data-reveal>
139
- {data.builtBy.label}
140
- <a href={data.builtBy.href} target="_blank" rel="noopener">{data.builtBy.name}</a>
141
- </p>
142
- )}
143
- </div>
144
- </section>
145
-
146
- <style>
147
- .tmk-trust {
148
- --_brand: var(--brand, #d8332a);
149
- --_accent: var(--accent, #f5a300);
150
- --_ink: var(--ink, #0a0a1f);
151
- --_paper: var(--paper, #fff);
152
- --_bg: var(--bg, #fbf9f4);
153
- --_bg-tint: var(--bg-tint, #f1ede1);
154
- --_muted: var(--muted, rgba(10, 10, 31, 0.62));
155
- --_hairline: var(--hairline, rgba(10, 10, 31, 0.1));
156
- --_r-md: var(--radius-md, 14px);
157
- --_r-lg: var(--radius-lg, 24px);
158
- --_shadow: var(--shadow, 0 30px 60px -30px rgba(10, 10, 31, 0.4));
159
- padding: 96px 0;
160
- background: var(--_paper);
161
- border-top: 1px solid var(--_hairline);
162
- border-bottom: 1px solid var(--_hairline);
163
- }
164
- .tmk-container {
165
- width: min(1200px, 100% - 48px);
166
- margin-inline: auto;
167
- }
168
- .tmk-eyebrow {
169
- font-family: 'Oswald', sans-serif;
170
- font-size: 12px;
171
- font-weight: 600;
172
- letter-spacing: 0.22em;
173
- text-transform: uppercase;
174
- color: var(--_brand);
175
- margin: 0;
176
- }
177
- .tmk-title {
178
- font-family: 'Oswald', 'Inter', sans-serif;
179
- font-size: clamp(30px, 3.8vw, 46px);
180
- font-weight: 700;
181
- line-height: 1.08;
182
- letter-spacing: -0.01em;
183
- margin: 12px 0 14px;
184
- max-width: 22ch;
185
- color: var(--_ink);
186
- }
187
- .tmk-sub {
188
- color: var(--_muted);
189
- max-width: 60ch;
190
- margin: 0 0 44px;
191
- }
192
-
193
- /* Cards --------------------------------------------------------------- */
194
- .tmk-grid {
195
- display: grid;
196
- grid-template-columns: repeat(4, 1fr);
197
- gap: 18px;
198
- }
199
- @media (max-width: 1024px) { .tmk-grid { grid-template-columns: repeat(2, 1fr); } }
200
- @media (max-width: 560px) { .tmk-grid { grid-template-columns: 1fr; } }
201
- .tmk-card {
202
- position: relative;
203
- padding: 26px 22px;
204
- border-radius: var(--_r-md);
205
- background: var(--_bg);
206
- border: 1px solid var(--_hairline);
207
- transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
208
- }
209
- .tmk-card:hover {
210
- transform: translateY(-4px);
211
- box-shadow: var(--_shadow);
212
- border-color: transparent;
213
- }
214
- .tmk-ico {
215
- display: inline-grid;
216
- place-items: center;
217
- width: 44px;
218
- height: 44px;
219
- border-radius: 12px;
220
- background: color-mix(in srgb, var(--_brand) 10%, transparent);
221
- color: var(--_brand);
222
- margin-bottom: 16px;
223
- }
224
- .tmk-ico :global(svg) { width: 22px; height: 22px; }
225
- .tmk-card-t {
226
- font-family: 'Oswald', 'Inter', sans-serif;
227
- font-size: 18px;
228
- font-weight: 600;
229
- margin: 0 0 8px;
230
- color: var(--_ink);
231
- }
232
- .tmk-card-b { color: var(--_muted); margin: 0; font-size: 14.5px; }
233
-
234
- /* Logos --------------------------------------------------------------- */
235
- .tmk-logos { margin-top: 52px; }
236
- .tmk-logos-label {
237
- font-family: 'Oswald', sans-serif;
238
- font-size: 12px;
239
- letter-spacing: 0.2em;
240
- text-transform: uppercase;
241
- color: var(--_muted);
242
- margin: 0 0 18px;
243
- text-align: center;
244
- }
245
- .tmk-logos-row {
246
- display: flex;
247
- align-items: center;
248
- justify-content: center;
249
- flex-wrap: wrap;
250
- gap: 14px 18px;
251
- }
252
- .tmk-logo {
253
- font-family: 'Oswald', sans-serif;
254
- font-weight: 600;
255
- font-size: 17px;
256
- letter-spacing: 0.02em;
257
- color: var(--_ink);
258
- padding: 12px 22px;
259
- border-radius: var(--_r-md);
260
- background: var(--_bg-tint);
261
- border: 1px solid var(--_hairline);
262
- transition: color 0.14s ease, border-color 0.14s ease;
263
- }
264
- a.tmk-logo:hover { color: var(--_brand); border-color: var(--_brand); }
265
- .tmk-logo--ph {
266
- color: var(--_muted);
267
- background: transparent;
268
- border: 1px dashed var(--_hairline);
269
- opacity: 0.75;
270
- }
271
-
272
- /* Testimonials -------------------------------------------------------- */
273
- .tmk-quotes { margin-top: 52px; }
274
- .tmk-quotes-row {
275
- display: grid;
276
- grid-template-columns: repeat(3, 1fr);
277
- gap: 18px;
278
- }
279
- @media (max-width: 900px) { .tmk-quotes-row { grid-template-columns: 1fr; } }
280
- .tmk-quote {
281
- position: relative;
282
- padding: 26px 24px 22px;
283
- border-radius: var(--_r-md);
284
- background: var(--_bg);
285
- border: 1px solid var(--_hairline);
286
- }
287
- .tmk-quote--ph { border-style: dashed; background: transparent; }
288
- .tmk-ph-tag {
289
- position: absolute;
290
- top: 14px;
291
- right: 14px;
292
- font-family: 'Oswald', sans-serif;
293
- font-size: 9.5px;
294
- font-weight: 600;
295
- letter-spacing: 0.14em;
296
- text-transform: uppercase;
297
- color: var(--_muted);
298
- background: var(--_bg-tint);
299
- padding: 3px 8px;
300
- border-radius: 999px;
301
- }
302
- .tmk-quote-b {
303
- margin: 0 0 16px;
304
- font-size: 16px;
305
- line-height: 1.5;
306
- color: var(--_ink);
307
- }
308
- .tmk-quote--ph .tmk-quote-b { color: var(--_muted); }
309
- .tmk-quote-b::before { content: '“'; color: var(--_brand); font-weight: 700; }
310
- .tmk-quote-cite { font-style: normal; }
311
- .tmk-quote-name {
312
- display: block;
313
- font-family: 'Oswald', sans-serif;
314
- font-weight: 600;
315
- font-size: 14.5px;
316
- color: var(--_ink);
317
- }
318
- .tmk-quote-role { display: block; font-size: 12.5px; color: var(--_muted); }
319
-
320
- .tmk-ph-note {
321
- text-align: center;
322
- color: var(--_muted);
323
- font-size: 12.5px;
324
- margin: 16px 0 0;
325
- font-style: italic;
326
- }
327
-
328
- /* Sample deliverable -------------------------------------------------- */
329
- .tmk-sample {
330
- margin-top: 52px;
331
- display: grid;
332
- grid-template-columns: 0.92fr 1.08fr;
333
- gap: 34px;
334
- align-items: center;
335
- padding: 30px;
336
- border-radius: var(--_r-lg);
337
- background: var(--_bg);
338
- border: 1px solid var(--_hairline);
339
- }
340
- @media (max-width: 860px) {
341
- .tmk-sample { grid-template-columns: 1fr; gap: 24px; padding: 24px; }
342
- }
343
- .tmk-sample-eyebrow {
344
- font-family: 'Oswald', sans-serif;
345
- font-size: 11px;
346
- font-weight: 600;
347
- letter-spacing: 0.2em;
348
- text-transform: uppercase;
349
- color: var(--_brand);
350
- margin: 0 0 8px;
351
- }
352
- .tmk-sample-t {
353
- font-family: 'Oswald', 'Inter', sans-serif;
354
- font-size: clamp(20px, 2.4vw, 26px);
355
- font-weight: 700;
356
- line-height: 1.14;
357
- margin: 0 0 10px;
358
- color: var(--_ink);
359
- }
360
- .tmk-sample-cap { color: var(--_muted); margin: 0; font-size: 14.5px; }
361
- .tmk-sample-media { min-width: 0; }
362
- .tmk-sample-img {
363
- display: block;
364
- width: 100%;
365
- height: auto;
366
- border-radius: var(--_r-md);
367
- border: 1px solid var(--_hairline);
368
- }
369
-
370
- /* Founding-partner panel ---------------------------------------------- */
371
- .tmk-founding {
372
- margin-top: 52px;
373
- display: flex;
374
- align-items: center;
375
- justify-content: space-between;
376
- gap: 30px;
377
- flex-wrap: wrap;
378
- padding: 30px 32px;
379
- border-radius: var(--_r-lg);
380
- background: var(--_ink);
381
- color: var(--_paper);
382
- border: 1px solid var(--_ink);
383
- }
384
- .tmk-founding-body { flex: 1 1 420px; }
385
- .tmk-founding-eyebrow {
386
- font-family: 'Oswald', sans-serif;
387
- font-size: 11px;
388
- font-weight: 600;
389
- letter-spacing: 0.2em;
390
- text-transform: uppercase;
391
- color: var(--_accent);
392
- margin: 0 0 8px;
393
- }
394
- .tmk-founding-t {
395
- font-family: 'Oswald', 'Inter', sans-serif;
396
- font-size: clamp(22px, 2.6vw, 28px);
397
- font-weight: 700;
398
- line-height: 1.12;
399
- margin: 0 0 10px;
400
- color: var(--_paper);
401
- }
402
- .tmk-founding-b {
403
- color: rgba(255, 255, 255, 0.78);
404
- margin: 0 0 16px;
405
- font-size: 14.5px;
406
- max-width: 60ch;
407
- }
408
- .tmk-founding-perks {
409
- list-style: none;
410
- padding: 0;
411
- margin: 0;
412
- display: grid;
413
- grid-template-columns: repeat(2, minmax(0, 1fr));
414
- gap: 8px 22px;
415
- }
416
- @media (max-width: 560px) { .tmk-founding-perks { grid-template-columns: 1fr; } }
417
- .tmk-founding-perks li {
418
- position: relative;
419
- padding-left: 22px;
420
- color: rgba(255, 255, 255, 0.9);
421
- font-size: 13.8px;
422
- }
423
- .tmk-founding-perks li::before {
424
- content: '';
425
- position: absolute;
426
- left: 0;
427
- top: 7px;
428
- width: 8px;
429
- height: 8px;
430
- border-radius: 50%;
431
- background: var(--_accent);
432
- }
433
- .tmk-founding-cta {
434
- box-sizing: border-box;
435
- min-height: var(--tmk-min-target);
436
- min-width: var(--tmk-min-target);
437
- display: inline-flex;
438
- align-items: center;
439
- justify-content: center;
440
- flex-shrink: 0;
441
- padding: 14px 24px;
442
- border-radius: 999px;
443
- background: var(--_accent);
444
- color: var(--_ink);
445
- font-family: 'Inter', system-ui, sans-serif;
446
- font-weight: 700;
447
- font-size: 14.5px;
448
- letter-spacing: 0.01em;
449
- text-decoration: none;
450
- border: 1px solid transparent;
451
- transition: transform 0.12s ease, box-shadow 0.12s ease;
452
- cursor: pointer;
453
- }
454
- .tmk-founding-cta:hover {
455
- transform: translateY(-1px);
456
- box-shadow: 0 12px 26px -12px rgba(0, 0, 0, 0.6);
457
- }
458
- .tmk-founding-cta:focus-visible {
459
- outline: 2px solid var(--_accent);
460
- outline-offset: 3px;
461
- }
462
-
463
- /* Founder line -------------------------------------------------------- */
464
- .tmk-founder {
465
- margin: 40px 0 0;
466
- display: flex;
467
- align-items: center;
468
- gap: 16px;
469
- max-width: 78ch;
470
- }
471
- .tmk-founder-av {
472
- flex-shrink: 0;
473
- width: 52px;
474
- height: 52px;
475
- border-radius: 50%;
476
- object-fit: cover;
477
- border: 1px solid var(--_hairline);
478
- }
479
- .tmk-founder-av--ph {
480
- display: inline-grid;
481
- place-items: center;
482
- background: color-mix(in srgb, var(--_brand) 12%, transparent);
483
- color: var(--_brand);
484
- font-family: 'Oswald', sans-serif;
485
- font-weight: 700;
486
- font-size: 20px;
487
- text-transform: uppercase;
488
- }
489
- .tmk-founder-cap { margin: 0; }
490
- .tmk-founder-line {
491
- margin: 0;
492
- color: var(--_ink);
493
- font-size: 15.5px;
494
- line-height: 1.5;
495
- }
496
- .tmk-founder-cite { margin: 4px 0 0; }
497
- .tmk-founder-name {
498
- font-family: 'Oswald', sans-serif;
499
- font-weight: 600;
500
- font-size: 13.5px;
501
- color: var(--_ink);
502
- }
503
- .tmk-founder-role {
504
- font-size: 12.5px;
505
- color: var(--_muted);
506
- margin-left: 8px;
507
- }
508
-
509
- /* Built by ------------------------------------------------------------ */
510
- .tmk-builtby {
511
- margin: 48px 0 0;
512
- text-align: center;
513
- color: var(--_muted);
514
- font-size: 13px;
515
- }
516
- .tmk-builtby a {
517
- color: var(--_ink);
518
- border-bottom: 1px dotted var(--_muted);
519
- margin-left: 5px;
520
- }
521
- .tmk-builtby a:hover { color: var(--_brand); }
522
-
523
- @media (max-width: 560px) { .tmk-trust { padding: 64px 0; } }
524
- </style>
1
+ ---
2
+ // Reusable trust / credibility section for product marketing sites — the
3
+ // markers an executive scans for: security & compliance cards, a discreet
4
+ // "built by" line, plus clearly-labeled PLACEHOLDER slots for customer logos
5
+ // and testimonials the site owner fills in with real ones.
6
+ //
7
+ // Data-driven (schema.ts → TrustSectionData); themed via host CSS vars.
8
+ //
9
+ // <TrustSection data={trust} id="trust" />
10
+ import type { TrustSectionData } from './schema';
11
+ import './a11y.css';
12
+ import { ctaAttrs } from './schema';
13
+ import { TRUST_ICONS } from './icons';
14
+
15
+ interface Props {
16
+ data: TrustSectionData;
17
+ id?: string;
18
+ }
19
+
20
+ const { data, id = 'trust' } = Astro.props as Props;
21
+
22
+ // A product can inject bespoke mock markup for the sample-deliverable showcase
23
+ // via <TrustSection><Fragment slot="sample-deliverable">…</Fragment></TrustSection>
24
+ // while the eyebrow/title/caption chrome stays shared.
25
+ const hasSampleSlot = Astro.slots.has('sample-deliverable');
26
+ ---
27
+
28
+ <section class="tmk-trust" id={id} aria-labelledby={`${id}-title`}>
29
+ <div class="tmk-container">
30
+ <p class="tmk-eyebrow" data-reveal>{data.eyebrow}</p>
31
+ <h2 class="tmk-title" id={`${id}-title`} data-reveal>{data.title}</h2>
32
+ {data.subtitle && <p class="tmk-sub" data-reveal>{data.subtitle}</p>}
33
+
34
+ <div class="tmk-grid">
35
+ {data.items.map((item, i) => (
36
+ <article class="tmk-card" data-reveal style={`--d:${(i % 4) + 1}`}>
37
+ <span class="tmk-ico" set:html={TRUST_ICONS[item.icon]} />
38
+ <h3 class="tmk-card-t">{item.title}</h3>
39
+ <p class="tmk-card-b">{item.body}</p>
40
+ </article>
41
+ ))}
42
+ </div>
43
+
44
+ {data.sampleDeliverable && (
45
+ <div class="tmk-sample" data-reveal>
46
+ <div class="tmk-sample-copy">
47
+ <p class="tmk-sample-eyebrow">{data.sampleDeliverable.eyebrow}</p>
48
+ <h3 class="tmk-sample-t">{data.sampleDeliverable.title}</h3>
49
+ <p class="tmk-sample-cap">{data.sampleDeliverable.caption}</p>
50
+ </div>
51
+ <div class="tmk-sample-media">
52
+ {hasSampleSlot ? (
53
+ <slot name="sample-deliverable" />
54
+ ) : data.sampleDeliverable.image ? (
55
+ <img class="tmk-sample-img" src={data.sampleDeliverable.image} alt={data.sampleDeliverable.title} loading="lazy" />
56
+ ) : null}
57
+ </div>
58
+ </div>
59
+ )}
60
+
61
+ {data.logos && (
62
+ <div class="tmk-logos" data-reveal>
63
+ <p class="tmk-logos-label">{data.logos.label}</p>
64
+ <div class="tmk-logos-row">
65
+ {data.logos.items.map((logo) =>
66
+ logo.placeholder ? (
67
+ <span class="tmk-logo tmk-logo--ph" aria-hidden="true">Your logo</span>
68
+ ) : logo.href ? (
69
+ <a class="tmk-logo" href={logo.href} target="_blank" rel="noopener">{logo.name}</a>
70
+ ) : (
71
+ <span class="tmk-logo">{logo.name}</span>
72
+ ),
73
+ )}
74
+ </div>
75
+ {data.logos.note && <p class="tmk-ph-note">{data.logos.note}</p>}
76
+ </div>
77
+ )}
78
+
79
+ {data.testimonials && (
80
+ <div class="tmk-quotes" data-reveal>
81
+ <p class="tmk-logos-label">{data.testimonials.label}</p>
82
+ <div class="tmk-quotes-row">
83
+ {data.testimonials.items.map((t) => (
84
+ <figure class={`tmk-quote${t.placeholder ? ' tmk-quote--ph' : ''}`}>
85
+ {t.placeholder && <span class="tmk-ph-tag">Placeholder</span>}
86
+ <blockquote class="tmk-quote-b">{t.quote}</blockquote>
87
+ <figcaption class="tmk-quote-cite">
88
+ <span class="tmk-quote-name">{t.authorName}</span>
89
+ {t.authorRole && <span class="tmk-quote-role">{t.authorRole}</span>}
90
+ </figcaption>
91
+ </figure>
92
+ ))}
93
+ </div>
94
+ {data.testimonials.note && <p class="tmk-ph-note">{data.testimonials.note}</p>}
95
+ </div>
96
+ )}
97
+
98
+ {data.foundingPartner && (
99
+ <aside class="tmk-founding" data-reveal>
100
+ <div class="tmk-founding-body">
101
+ <p class="tmk-founding-eyebrow">{data.foundingPartner.eyebrow}</p>
102
+ <h3 class="tmk-founding-t">{data.foundingPartner.title}</h3>
103
+ <p class="tmk-founding-b">{data.foundingPartner.body}</p>
104
+ <ul class="tmk-founding-perks">
105
+ {data.foundingPartner.perks.map((perk) => <li>{perk}</li>)}
106
+ </ul>
107
+ </div>
108
+ {data.foundingPartner.cta && (
109
+ <a class="tmk-founding-cta" {...ctaAttrs(data.foundingPartner.cta)}>
110
+ {data.foundingPartner.cta.label}
111
+ </a>
112
+ )}
113
+ </aside>
114
+ )}
115
+
116
+ {data.founder && (
117
+ <figure class="tmk-founder" data-reveal>
118
+ {data.founder.avatar ? (
119
+ <img class="tmk-founder-av" src={data.founder.avatar} alt={data.founder.name ?? 'Founder'} loading="lazy" />
120
+ ) : (
121
+ <span class="tmk-founder-av tmk-founder-av--ph" aria-hidden="true">
122
+ {(data.founder.name ?? '·').trim().charAt(0)}
123
+ </span>
124
+ )}
125
+ <figcaption class="tmk-founder-cap">
126
+ <p class="tmk-founder-line">{data.founder.line}</p>
127
+ {(data.founder.name || data.founder.role) && (
128
+ <p class="tmk-founder-cite">
129
+ {data.founder.name && <span class="tmk-founder-name">{data.founder.name}</span>}
130
+ {data.founder.role && <span class="tmk-founder-role">{data.founder.role}</span>}
131
+ </p>
132
+ )}
133
+ </figcaption>
134
+ </figure>
135
+ )}
136
+
137
+ {data.builtBy && (
138
+ <p class="tmk-builtby" data-reveal>
139
+ {data.builtBy.label}
140
+ <a href={data.builtBy.href} target="_blank" rel="noopener">{data.builtBy.name}</a>
141
+ </p>
142
+ )}
143
+ </div>
144
+ </section>
145
+
146
+ <style>
147
+ .tmk-trust {
148
+ --_brand: var(--brand, #d8332a);
149
+ --_accent: var(--accent, #f5a300);
150
+ --_ink: var(--ink, #0a0a1f);
151
+ --_paper: var(--paper, #fff);
152
+ --_bg: var(--bg, #fbf9f4);
153
+ --_bg-tint: var(--bg-tint, #f1ede1);
154
+ --_muted: var(--muted, rgba(10, 10, 31, 0.62));
155
+ --_hairline: var(--hairline, rgba(10, 10, 31, 0.1));
156
+ --_r-md: var(--radius-md, 14px);
157
+ --_r-lg: var(--radius-lg, 24px);
158
+ --_shadow: var(--shadow, 0 30px 60px -30px rgba(10, 10, 31, 0.4));
159
+ padding: 96px 0;
160
+ background: var(--_paper);
161
+ border-top: 1px solid var(--_hairline);
162
+ border-bottom: 1px solid var(--_hairline);
163
+ }
164
+ .tmk-container {
165
+ width: min(1200px, 100% - 48px);
166
+ margin-inline: auto;
167
+ }
168
+ .tmk-eyebrow {
169
+ font-family: 'Oswald', sans-serif;
170
+ font-size: 12px;
171
+ font-weight: 600;
172
+ letter-spacing: 0.22em;
173
+ text-transform: uppercase;
174
+ color: var(--_brand);
175
+ margin: 0;
176
+ }
177
+ .tmk-title {
178
+ font-family: 'Oswald', 'Inter', sans-serif;
179
+ font-size: clamp(30px, 3.8vw, 46px);
180
+ font-weight: 700;
181
+ line-height: 1.08;
182
+ letter-spacing: -0.01em;
183
+ margin: 12px 0 14px;
184
+ max-width: 22ch;
185
+ color: var(--_ink);
186
+ }
187
+ .tmk-sub {
188
+ color: var(--_muted);
189
+ max-width: 60ch;
190
+ margin: 0 0 44px;
191
+ }
192
+
193
+ /* Cards --------------------------------------------------------------- */
194
+ .tmk-grid {
195
+ display: grid;
196
+ grid-template-columns: repeat(4, 1fr);
197
+ gap: 18px;
198
+ }
199
+ @media (max-width: 1024px) { .tmk-grid { grid-template-columns: repeat(2, 1fr); } }
200
+ @media (max-width: 560px) { .tmk-grid { grid-template-columns: 1fr; } }
201
+ .tmk-card {
202
+ position: relative;
203
+ padding: 26px 22px;
204
+ border-radius: var(--_r-md);
205
+ background: var(--_bg);
206
+ border: 1px solid var(--_hairline);
207
+ transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
208
+ }
209
+ .tmk-card:hover {
210
+ transform: translateY(-4px);
211
+ box-shadow: var(--_shadow);
212
+ border-color: transparent;
213
+ }
214
+ .tmk-ico {
215
+ display: inline-grid;
216
+ place-items: center;
217
+ width: 44px;
218
+ height: 44px;
219
+ border-radius: 12px;
220
+ background: color-mix(in srgb, var(--_brand) 10%, transparent);
221
+ color: var(--_brand);
222
+ margin-bottom: 16px;
223
+ }
224
+ .tmk-ico :global(svg) { width: 22px; height: 22px; }
225
+ .tmk-card-t {
226
+ font-family: 'Oswald', 'Inter', sans-serif;
227
+ font-size: 18px;
228
+ font-weight: 600;
229
+ margin: 0 0 8px;
230
+ color: var(--_ink);
231
+ }
232
+ .tmk-card-b { color: var(--_muted); margin: 0; font-size: 14.5px; }
233
+
234
+ /* Logos --------------------------------------------------------------- */
235
+ .tmk-logos { margin-top: 52px; }
236
+ .tmk-logos-label {
237
+ font-family: 'Oswald', sans-serif;
238
+ font-size: 12px;
239
+ letter-spacing: 0.2em;
240
+ text-transform: uppercase;
241
+ color: var(--_muted);
242
+ margin: 0 0 18px;
243
+ text-align: center;
244
+ }
245
+ .tmk-logos-row {
246
+ display: flex;
247
+ align-items: center;
248
+ justify-content: center;
249
+ flex-wrap: wrap;
250
+ gap: 14px 18px;
251
+ }
252
+ .tmk-logo {
253
+ font-family: 'Oswald', sans-serif;
254
+ font-weight: 600;
255
+ font-size: 17px;
256
+ letter-spacing: 0.02em;
257
+ color: var(--_ink);
258
+ padding: 12px 22px;
259
+ border-radius: var(--_r-md);
260
+ background: var(--_bg-tint);
261
+ border: 1px solid var(--_hairline);
262
+ transition: color 0.14s ease, border-color 0.14s ease;
263
+ }
264
+ a.tmk-logo:hover { color: var(--_brand); border-color: var(--_brand); }
265
+ .tmk-logo--ph {
266
+ color: var(--_muted);
267
+ background: transparent;
268
+ border: 1px dashed var(--_hairline);
269
+ opacity: 0.75;
270
+ }
271
+
272
+ /* Testimonials -------------------------------------------------------- */
273
+ .tmk-quotes { margin-top: 52px; }
274
+ .tmk-quotes-row {
275
+ display: grid;
276
+ grid-template-columns: repeat(3, 1fr);
277
+ gap: 18px;
278
+ }
279
+ @media (max-width: 900px) { .tmk-quotes-row { grid-template-columns: 1fr; } }
280
+ .tmk-quote {
281
+ position: relative;
282
+ padding: 26px 24px 22px;
283
+ border-radius: var(--_r-md);
284
+ background: var(--_bg);
285
+ border: 1px solid var(--_hairline);
286
+ }
287
+ .tmk-quote--ph { border-style: dashed; background: transparent; }
288
+ .tmk-ph-tag {
289
+ position: absolute;
290
+ top: 14px;
291
+ right: 14px;
292
+ font-family: 'Oswald', sans-serif;
293
+ font-size: 9.5px;
294
+ font-weight: 600;
295
+ letter-spacing: 0.14em;
296
+ text-transform: uppercase;
297
+ color: var(--_muted);
298
+ background: var(--_bg-tint);
299
+ padding: 3px 8px;
300
+ border-radius: 999px;
301
+ }
302
+ .tmk-quote-b {
303
+ margin: 0 0 16px;
304
+ font-size: 16px;
305
+ line-height: 1.5;
306
+ color: var(--_ink);
307
+ }
308
+ .tmk-quote--ph .tmk-quote-b { color: var(--_muted); }
309
+ .tmk-quote-b::before { content: '“'; color: var(--_brand); font-weight: 700; }
310
+ .tmk-quote-cite { font-style: normal; }
311
+ .tmk-quote-name {
312
+ display: block;
313
+ font-family: 'Oswald', sans-serif;
314
+ font-weight: 600;
315
+ font-size: 14.5px;
316
+ color: var(--_ink);
317
+ }
318
+ .tmk-quote-role { display: block; font-size: 12.5px; color: var(--_muted); }
319
+
320
+ .tmk-ph-note {
321
+ text-align: center;
322
+ color: var(--_muted);
323
+ font-size: 12.5px;
324
+ margin: 16px 0 0;
325
+ font-style: italic;
326
+ }
327
+
328
+ /* Sample deliverable -------------------------------------------------- */
329
+ .tmk-sample {
330
+ margin-top: 52px;
331
+ display: grid;
332
+ grid-template-columns: 0.92fr 1.08fr;
333
+ gap: 34px;
334
+ align-items: center;
335
+ padding: 30px;
336
+ border-radius: var(--_r-lg);
337
+ background: var(--_bg);
338
+ border: 1px solid var(--_hairline);
339
+ }
340
+ @media (max-width: 860px) {
341
+ .tmk-sample { grid-template-columns: 1fr; gap: 24px; padding: 24px; }
342
+ }
343
+ .tmk-sample-eyebrow {
344
+ font-family: 'Oswald', sans-serif;
345
+ font-size: 11px;
346
+ font-weight: 600;
347
+ letter-spacing: 0.2em;
348
+ text-transform: uppercase;
349
+ color: var(--_brand);
350
+ margin: 0 0 8px;
351
+ }
352
+ .tmk-sample-t {
353
+ font-family: 'Oswald', 'Inter', sans-serif;
354
+ font-size: clamp(20px, 2.4vw, 26px);
355
+ font-weight: 700;
356
+ line-height: 1.14;
357
+ margin: 0 0 10px;
358
+ color: var(--_ink);
359
+ }
360
+ .tmk-sample-cap { color: var(--_muted); margin: 0; font-size: 14.5px; }
361
+ .tmk-sample-media { min-width: 0; }
362
+ .tmk-sample-img {
363
+ display: block;
364
+ width: 100%;
365
+ height: auto;
366
+ border-radius: var(--_r-md);
367
+ border: 1px solid var(--_hairline);
368
+ }
369
+
370
+ /* Founding-partner panel ---------------------------------------------- */
371
+ .tmk-founding {
372
+ margin-top: 52px;
373
+ display: flex;
374
+ align-items: center;
375
+ justify-content: space-between;
376
+ gap: 30px;
377
+ flex-wrap: wrap;
378
+ padding: 30px 32px;
379
+ border-radius: var(--_r-lg);
380
+ background: var(--_ink);
381
+ color: var(--_paper);
382
+ border: 1px solid var(--_ink);
383
+ }
384
+ .tmk-founding-body { flex: 1 1 420px; }
385
+ .tmk-founding-eyebrow {
386
+ font-family: 'Oswald', sans-serif;
387
+ font-size: 11px;
388
+ font-weight: 600;
389
+ letter-spacing: 0.2em;
390
+ text-transform: uppercase;
391
+ color: var(--_accent);
392
+ margin: 0 0 8px;
393
+ }
394
+ .tmk-founding-t {
395
+ font-family: 'Oswald', 'Inter', sans-serif;
396
+ font-size: clamp(22px, 2.6vw, 28px);
397
+ font-weight: 700;
398
+ line-height: 1.12;
399
+ margin: 0 0 10px;
400
+ color: var(--_paper);
401
+ }
402
+ .tmk-founding-b {
403
+ color: rgba(255, 255, 255, 0.78);
404
+ margin: 0 0 16px;
405
+ font-size: 14.5px;
406
+ max-width: 60ch;
407
+ }
408
+ .tmk-founding-perks {
409
+ list-style: none;
410
+ padding: 0;
411
+ margin: 0;
412
+ display: grid;
413
+ grid-template-columns: repeat(2, minmax(0, 1fr));
414
+ gap: 8px 22px;
415
+ }
416
+ @media (max-width: 560px) { .tmk-founding-perks { grid-template-columns: 1fr; } }
417
+ .tmk-founding-perks li {
418
+ position: relative;
419
+ padding-left: 22px;
420
+ color: rgba(255, 255, 255, 0.9);
421
+ font-size: 13.8px;
422
+ }
423
+ .tmk-founding-perks li::before {
424
+ content: '';
425
+ position: absolute;
426
+ left: 0;
427
+ top: 7px;
428
+ width: 8px;
429
+ height: 8px;
430
+ border-radius: 50%;
431
+ background: var(--_accent);
432
+ }
433
+ .tmk-founding-cta {
434
+ box-sizing: border-box;
435
+ min-height: var(--tmk-min-target);
436
+ min-width: var(--tmk-min-target);
437
+ display: inline-flex;
438
+ align-items: center;
439
+ justify-content: center;
440
+ flex-shrink: 0;
441
+ padding: 14px 24px;
442
+ border-radius: 999px;
443
+ background: var(--_accent);
444
+ color: var(--_ink);
445
+ font-family: 'Inter', system-ui, sans-serif;
446
+ font-weight: 700;
447
+ font-size: 14.5px;
448
+ letter-spacing: 0.01em;
449
+ text-decoration: none;
450
+ border: 1px solid transparent;
451
+ transition: transform 0.12s ease, box-shadow 0.12s ease;
452
+ cursor: pointer;
453
+ }
454
+ .tmk-founding-cta:hover {
455
+ transform: translateY(-1px);
456
+ box-shadow: 0 12px 26px -12px rgba(0, 0, 0, 0.6);
457
+ }
458
+ .tmk-founding-cta:focus-visible {
459
+ outline: 2px solid var(--_accent);
460
+ outline-offset: 3px;
461
+ }
462
+
463
+ /* Founder line -------------------------------------------------------- */
464
+ .tmk-founder {
465
+ margin: 40px 0 0;
466
+ display: flex;
467
+ align-items: center;
468
+ gap: 16px;
469
+ max-width: 78ch;
470
+ }
471
+ .tmk-founder-av {
472
+ flex-shrink: 0;
473
+ width: 52px;
474
+ height: 52px;
475
+ border-radius: 50%;
476
+ object-fit: cover;
477
+ border: 1px solid var(--_hairline);
478
+ }
479
+ .tmk-founder-av--ph {
480
+ display: inline-grid;
481
+ place-items: center;
482
+ background: color-mix(in srgb, var(--_brand) 12%, transparent);
483
+ color: var(--_brand);
484
+ font-family: 'Oswald', sans-serif;
485
+ font-weight: 700;
486
+ font-size: 20px;
487
+ text-transform: uppercase;
488
+ }
489
+ .tmk-founder-cap { margin: 0; }
490
+ .tmk-founder-line {
491
+ margin: 0;
492
+ color: var(--_ink);
493
+ font-size: 15.5px;
494
+ line-height: 1.5;
495
+ }
496
+ .tmk-founder-cite { margin: 4px 0 0; }
497
+ .tmk-founder-name {
498
+ font-family: 'Oswald', sans-serif;
499
+ font-weight: 600;
500
+ font-size: 13.5px;
501
+ color: var(--_ink);
502
+ }
503
+ .tmk-founder-role {
504
+ font-size: 12.5px;
505
+ color: var(--_muted);
506
+ margin-left: 8px;
507
+ }
508
+
509
+ /* Built by ------------------------------------------------------------ */
510
+ .tmk-builtby {
511
+ margin: 48px 0 0;
512
+ text-align: center;
513
+ color: var(--_muted);
514
+ font-size: 13px;
515
+ }
516
+ /* 44px hit box (a11y.css --tmk-min-target) without moving the line: the
517
+ vertical padding is cancelled by an equal negative margin. */
518
+ .tmk-builtby a {
519
+ display: inline-block;
520
+ padding-block: 14px;
521
+ margin-block: -14px;
522
+ color: var(--_ink);
523
+ text-decoration: underline dotted var(--_muted);
524
+ text-underline-offset: 3px;
525
+ margin-left: 5px;
526
+ }
527
+ .tmk-builtby a:hover { color: var(--_brand); }
528
+
529
+ @media (max-width: 560px) { .tmk-trust { padding: 64px 0; } }
530
+ </style>