Skip to content

Commit 3670787

Browse files
committed
Styling updates to Newsletter CTAs, adding default, article, and home page variants
1 parent 5dba03e commit 3670787

7 files changed

Lines changed: 15 additions & 208 deletions

File tree

‎src/components/CallToAction/Newsletter/client/__tests__/selectors.spec.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const defaultNewsletterProps: NewsletterProps = {
2222
description: 'Ensures selector utilities receive accurate markup',
2323
placeholder: 'user@example.com',
2424
buttonText: 'Subscribe',
25+
variant: 'article',
2526
}
2627

2728
describe('Newsletter selector utilities', () => {

‎src/components/Consent/Checkbox/client/__tests__/testUtils.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const defaultProps: CheckboxFixtureProps = {
3737
id: 'gdpr-consent',
3838
formId: 'contact-form',
3939
purpose: 'Responding to your inquiry',
40+
variant: 'default',
4041
wrapInForm: true,
4142
}
4243

‎src/components/Consent/Checkbox/newsletter-cta-home.astro‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,14 @@ const {
3333
aria-labelledby={`${id}-label`}
3434
aria-describedby={`${id}-description`}
3535
aria-invalid="false"
36-
class="relative border-2 border-content-offset rounded h-4 w-4 shrink-0 bg-transparent hover:border-content-active hover:bg-content-active/10 focus:outline-none focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 after:pointer-events-none after:absolute after:content-[''] after:inset-0 after:rounded-none after:border-2 after:border-transparent focus-visible:after:-inset-1 focus-visible:after:border-spotlight"
36+
class="relative h-4 w-4 shrink-0 appearance-none rounded border-2 border-content-offset bg-transparent
37+
outline-none hover:border-content-active hover:bg-content-active/10 focus:outline-none
38+
focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0
39+
checked:border-content-active checked:bg-content-active/20 checked:after:content-['']
40+
checked:after:absolute checked:after:inset-[3px] checked:after:rounded-[2px]
41+
checked:after:bg-content-active after:pointer-events-none after:absolute after:inset-0
42+
after:rounded-none after:border-2 after:border-transparent focus-visible:after:-inset-1
43+
focus-visible:after:border-spotlight"
3744
/>
3845
<span id={`${id}-label`} class="sr-only">Consent to data processing</span>
3946
<span id={`${id}-description`} class="text-[10px] text-content-offset leading-tight">

‎src/components/Home/Skills/client/selectors.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { EmblaCarouselType } from 'embla-carousel'
22
import {
33
isButtonElement,
4-
isDivElement,
54
isType1Element,
65
} from '@components/scripts/assertions/elements'
76
import { ClientScriptError } from '@components/scripts/errors'

‎src/components/Testimonials/client/__tests__/index.spec.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ vi.mock('embla-carousel-autoplay', () => ({
9292

9393
const defaultProps: TestimonialsProps = {
9494
title: 'Client Praise',
95+
showControls: true,
9596
}
9697

9798
const renderTestimonials = async (

‎src/components/Testimonials/client/index.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export class TestimonialsCarouselElement extends EmblaCarouselBase {
2525

2626
// ────────────────────── Base class abstract implementations ──────────────────────
2727

28-
protected getConfig(): EmblaCarouselConfig {
28+
protected override getConfig(): EmblaCarouselConfig {
2929
return {
3030
emblaOptions: {
3131
loop: true,
@@ -45,7 +45,7 @@ export class TestimonialsCarouselElement extends EmblaCarouselBase {
4545
}
4646
}
4747

48-
protected queryElements(): EmblaElementHandles {
48+
protected override queryElements(): EmblaElementHandles {
4949
const { emblaRoot, viewport } = getTestimonialsEmblaSetupElements(this)
5050
return {
5151
emblaRoot: emblaRoot as EmblaElementHandles['emblaRoot'],
@@ -69,7 +69,7 @@ export class TestimonialsCarouselElement extends EmblaCarouselBase {
6969

7070
protected override onInitialized(): void {
7171
this.autoplayToggleBtn = queryTestimonialsAutoplayToggleBtn(this)
72-
this.ensureViewportId()
72+
this.ensureTestimonialsViewportId()
7373
this.setupAriaControls()
7474
this.setupAutoplayToggle()
7575
}
@@ -103,7 +103,7 @@ export class TestimonialsCarouselElement extends EmblaCarouselBase {
103103

104104
// ────────────────────── Private helpers ──────────────────────
105105

106-
private ensureViewportId(): void {
106+
private ensureTestimonialsViewportId(): void {
107107
const vp = this.viewport
108108
if (!vp || this.viewportId) return
109109

‎src/pages/hero.astro‎

Lines changed: 0 additions & 202 deletions
Original file line numberDiff line numberDiff line change
@@ -6,208 +6,6 @@ const path = '/hero/'
66
---
77

88
<BaseLayout description={pageDescription} noindex={true} pageTitle={pageTitle} path={path}>
9-
<!-- ============================================================
10-
NEWSLETTER CTA VARIANTS - For Visual Comparison
11-
============================================================ -->
12-
13-
<section class="py-16 space-y-16">
14-
<div class="container mx-auto px-4 sm:px-6 lg:px-8">
15-
<h2 class="text-2xl font-bold text-content mb-4">Newsletter CTA Variants</h2>
16-
17-
<div class="mb-16">
18-
<p class="text-xs font-bold text-content-offset uppercase tracking-widest mb-4">NEWSLETTER CTA VARIANTS - Variant 1: Enhanced Value Proposition</p>
19-
20-
<div class="relative overflow-hidden bg-page-offset border border-trim rounded-2xl shadow-lg group">
21-
<!-- Decoration: Subtle tech grid background -->
22-
<div class="absolute inset-0 opacity-5 pointer-events-none">
23-
<svg class="w-full h-full" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
24-
<defs>
25-
<pattern id="grid-pattern" width="40" height="40" patternUnits="userSpaceOnUse">
26-
<path d="M0 40L40 0H20L0 20M40 40V20L20 40" stroke="currentColor" stroke-width="2" fill="none" class="text-primary"/>
27-
</pattern>
28-
</defs>
29-
<rect width="100%" height="100%" fill="url(#grid-pattern)" />
30-
</svg>
31-
</div>
32-
33-
<!-- Decoration: Gradient glow top right -->
34-
<div class="absolute -top-24 -right-24 w-64 h-64 bg-primary/10 rounded-full blur-3xl pointer-events-none"></div>
35-
36-
<!-- Legibility: Gradient wash to fade pattern behind text -->
37-
<div class="absolute inset-0 bg-linear-to-r from-page-offset/95 via-page-offset/60 to-transparent pointer-events-none"></div>
38-
39-
<div class="relative p-8 md:p-10 flex flex-col lg:flex-row gap-10 items-center">
40-
41-
<!-- Left: Content with Icon -->
42-
<div class="lg:flex-1 flex gap-6 md:gap-8">
43-
<!-- Newsletter Cover Art / Graphic -->
44-
<div class="hidden sm:flex w-24 md:w-32 bg-linear-to-br from-primary to-spotlight rounded-xl items-center justify-center shrink-0 shadow-lg shadow-primary/20 transform group-hover:scale-105 transition-transform duration-500 self-stretch relative overflow-hidden">
45-
<!-- Inner Pattern -->
46-
<div class="absolute inset-0 opacity-20 bg-[radial-gradient(circle_at_center,var(--tw-gradient-stops))] from-white to-transparent"></div>
47-
48-
<!-- Abstract "Book/Magazine" spine effect -->
49-
<div class="absolute left-0 top-0 bottom-0 w-1 bg-white/20"></div>
50-
51-
<!-- Central Icon/Symbol -->
52-
<div class="text-page-base flex flex-col items-center gap-2">
53-
<svg class="w-10 h-10" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
54-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z"></path>
55-
</svg>
56-
<span class="text-[10px] font-bold uppercase tracking-widest rotate-180 writing-vertical-lr opacity-80 backdrop-blur-sm">Issue #42</span>
57-
</div>
58-
</div>
59-
60-
<div class="space-y-6 flex-1">
61-
<div class="relative">
62-
<div class="flex items-center gap-2 mb-2">
63-
<span class="px-2 py-0.5 rounded-full bg-primary/10 text-primary text-[10px] font-bold uppercase tracking-wider border border-primary/20 backdrop-blur-sm">Monthly Dispatch</span>
64-
</div>
65-
<h3 class="text-2xl md:text-3xl font-black text-content leading-tight drop-shadow-sm">
66-
Engineering at Scale
67-
</h3>
68-
<p class="text-base font-medium text-content-offset mt-2 max-w-lg">
69-
Join 2,000+ platform engineers. Get the operational patterns, post-mortems, and architectural decisions that don't make it into the docs.
70-
</p>
71-
</div>
72-
73-
<ul class="grid grid-cols-1 sm:grid-cols-2 gap-3 text-sm font-medium text-content-offset">
74-
<li class="flex items-start gap-2">
75-
<svg class="w-5 h-5 text-success shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
76-
<span>Incident analysis</span>
77-
</li>
78-
<li class="flex items-start gap-2">
79-
<svg class="w-5 h-5 text-success shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
80-
<span>Scaling strategies</span>
81-
</li>
82-
<li class="flex items-start gap-2">
83-
<svg class="w-5 h-5 text-success shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
84-
<span>Tool evaluations</span>
85-
</li>
86-
<li class="flex items-start gap-2">
87-
<svg class="w-5 h-5 text-success shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
88-
<span>Architecture reviews</span>
89-
</li>
90-
</ul>
91-
</div>
92-
</div>
93-
94-
<!-- Right: Action Card -->
95-
<div class="lg:w-80 w-full shrink-0">
96-
<div class="bg-page-base p-6 rounded-xl border border-trim shadow-sm hover:shadow-md transition-shadow duration-300 relative group/form">
97-
<div class="absolute -top-3 -right-3">
98-
<span class="relative flex h-6 w-6">
99-
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-spotlight opacity-75"></span>
100-
<span class="relative inline-flex rounded-full h-6 w-6 bg-spotlight items-center justify-center">
101-
<svg class="w-3 h-3 text-page-base" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path></svg>
102-
</span>
103-
</span>
104-
</div>
105-
106-
<div class="space-y-4">
107-
<div class="space-y-1">
108-
<label for="newsletter-work-email" class="text-xs font-bold text-content uppercase">Work Email</label>
109-
<input
110-
type="email"
111-
id="newsletter-work-email"
112-
placeholder="engineer@company.com"
113-
class="w-full px-4 py-3 border border-trim rounded-lg bg-page-offset text-sm focus:border-primary focus:ring-1 focus:ring-primary focus:outline-none transition-colors"
114-
disabled
115-
/>
116-
</div>
117-
118-
<button
119-
type="button"
120-
class="w-full px-6 py-3 bg-content text-page-base font-bold rounded-lg text-sm transition-all transform hover:-translate-y-0.5 hover:shadow-lg flex items-center justify-center gap-2 group-hover/form:bg-primary"
121-
disabled
122-
>
123-
Subscribe Free
124-
<svg class="w-4 h-4 transition-transform group-hover/form:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path></svg>
125-
</button>
126-
127-
<div class="pt-2 border-t border-trim/50">
128-
<label class="flex items-start gap-2 cursor-pointer">
129-
<input type="checkbox" class="mt-1 border-trim rounded text-primary focus:ring-primary" disabled />
130-
<span class="text-[10px] text-content-offset leading-tight">
131-
By subscribing, you agree to our <a href="/privacy" class="underline hover:text-primary">Privacy Policy</a>. No spam, just engineering.
132-
</span>
133-
</label>
134-
</div>
135-
</div>
136-
</div>
137-
</div>
138-
139-
</div>
140-
</div>
141-
</div>
142-
143-
<!-- ============================================================
144-
VARIANT 2: Terminal Aesthetic (Brand Differentiation)
145-
Monospace/terminal-inspired, signals "for engineers"
146-
============================================================ -->
147-
<div class="mb-16">
148-
<p class="text-xs font-bold text-content-offset uppercase tracking-widest mb-4">NEWSLETTER CTA VARIANTS - Variant 2: Terminal Aesthetic</p>
149-
150-
<div class="bg-content border border-trim rounded-xl p-6 md:p-8 font-mono">
151-
<!-- Terminal header bar -->
152-
<div class="flex items-center gap-2 mb-4 pb-4 border-b border-page-base/20">
153-
<div class="w-3 h-3 rounded-full bg-danger"></div>
154-
<div class="w-3 h-3 rounded-full bg-warning"></div>
155-
<div class="w-3 h-3 rounded-full bg-success"></div>
156-
<span class="text-xs text-page-base/50 ml-2">newsletter.subscribe</span>
157-
</div>
158-
159-
<div class="space-y-3">
160-
<p class="text-page-base">
161-
<span class="text-success">$</span> subscribe --platform-engineering
162-
</p>
163-
<p class="text-page-base/70 text-sm">
164-
<span class="text-page-base/50">&gt;</span> Monthly dispatches: infra migrations, observability stacks, and lessons from production incidents.
165-
</p>
166-
167-
<!-- Form inline with terminal style -->
168-
<div class="flex flex-col sm:flex-row gap-3 pt-4">
169-
<div class="flex items-center gap-2 flex-1">
170-
<span class="text-success">$</span>
171-
<input
172-
type="email"
173-
placeholder="email: user@domain.com"
174-
class="flex-1 px-3 py-2 bg-page-base/10 border border-page-base/20 rounded text-page-base text-sm placeholder:text-page-base/40 focus:border-primary focus:ring-0 focus:outline-none"
175-
disabled
176-
/>
177-
</div>
178-
<button
179-
type="button"
180-
class="px-6 py-2 bg-primary hover:bg-primary-offset text-page-base font-semibold rounded text-sm transition-colors whitespace-nowrap"
181-
disabled
182-
>
183-
→ Subscribe
184-
</button>
185-
</div>
186-
187-
<!-- Consent in terminal style -->
188-
<div class="pt-3 border-t border-page-base/20 mt-4">
189-
<label class="flex items-start gap-2 cursor-pointer">
190-
<span class="text-page-base/50 text-sm">[</span>
191-
<input
192-
type="checkbox"
193-
class="border-2 border-page-base/30 rounded h-4 w-4 shrink-0 bg-transparent"
194-
disabled
195-
/>
196-
<span class="text-page-base/50 text-sm">]</span>
197-
<span class="text-xs text-page-base/60 leading-relaxed">
198-
--consent "I agree to data processing"
199-
<a href="/privacy" class="text-primary underline">--privacy</a>
200-
<a href="/consent" class="text-primary underline">--cookies</a>
201-
</span>
202-
</label>
203-
</div>
204-
</div>
205-
</div>
206-
</div>
207-
</div>
208-
</section>
209-
210-
2119
<!-- ============================================================
21210
CONTACT CTA VARIANTS - For Visual Comparison
21311
============================================================ -->

0 commit comments

Comments
 (0)