Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/components/blog/BlogCta.astro
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const repoUrl =
>
<Icon name="github" size="sm" />
{t('blog.cta.button', locale)}
<Icon name="arrow-right" size="sm" />
</Button>
</div>
</CtaBand>
Expand All @@ -94,6 +95,7 @@ const repoUrl =
>
<Icon name="github" size="sm" />
{t('blog.cta.button', locale)}
<Icon name="arrow-right" size="sm" />
</Button>
</div>
</LetterGlitchBand>
Expand Down
54 changes: 41 additions & 13 deletions src/styles/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -1309,18 +1309,21 @@
}

/* CTA primary button on mobile / coarse-pointer CTA sections.
brand-700 fill / brand-800 hover in both modes: the lightest brand step
that holds white label text at WCAG AA (>=4.5:1) across every theme. */
brand-700 fill in both modes: the lightest brand step that holds white
label text at WCAG AA (>=4.5:1) across every theme.

No hover colour. On the CTA band this button sits on a gradient running
brand-500 down to brand-900, and the buttons land low in that travel where
the ground is already near brand-700. A darker hover put the fill within
1.1:1 of the ground behind it, so the button dissolved rather than
responded. Hover is carried by the arrow instead — it shifts 4px — and a
press by `active:scale-[0.98]` on Button itself. */
.cta-btn-brand {
background-color: var(--color-brand-700) !important;
background-image: none !important;
color: white !important;
border-color: transparent !important;
}
.cta-btn-brand:hover {
background-color: var(--color-brand-800) !important;
background-image: none !important;
}

/* Primary button inside an inverted section.
The primary variant is `bg-foreground text-background`, but the Button's own
Expand Down Expand Up @@ -1379,10 +1382,18 @@
fails on emerald, teal, cyan and sky — the same four the tag pill had to
move past.

Secondary: `.cta-btn-brand`, unchanged — an opaque brand fill with an
opaque brand hover and no border. `.hero-btn-brand` would look the same at
rest but fades to `opacity: 0.85` on hover, which makes the whole button
translucent and shows the grid through it. */
Neither button takes a hover colour. This one is already near-white on a
dark field, so it has nowhere brighter to go: its hover mixed the
foreground with white and moved the fill by under 2%, which read as no
response at all. The pair also needed opposite directions to be legible
here — lighter for the dark secondary, darker for this one — which one
hover convention cannot give. Hover is carried by the arrow instead, 4px on
both buttons, and a press by `active:scale-[0.98]` on Button itself.

Secondary: `.cta-btn-brand`, an opaque brand fill with no border.
`.hero-btn-brand` would look the same at rest but fades to `opacity: 0.85`
on hover, which makes the whole button translucent and shows the grid
through it. */
.cta-band.invert-section .btn-primary {
background-color: var(--color-foreground) !important;
background-image: linear-gradient(
Expand All @@ -1393,9 +1404,26 @@
border: 1px solid var(--color-foreground-secondary) !important;
color: var(--color-brand-700) !important;
}
.cta-band.invert-section .btn-primary:hover {
background-image: none !important;
background-color: color-mix(in oklch, var(--color-foreground) 90%, white) !important;

/* The secondary's edge, on the band only.

Its brand-700 fill sits on a field travelling brand-500 to brand-900, and
the buttons land where the ground is already near brand-700 — so the fill
is 1.5:1 against what is behind it and the button's shape barely reads.
WCAG 1.4.11 asks 3:1 to identify a control, which the fill cannot give
without breaking something else: brand-500 would clear the boundary in only
five of the eight palettes and would drop the white label to 2.8:1, and
brand-600 clears neither.

A 1px white line at 35% composites over the fill, so no colour changes —
the button only gains an edge. Worst of the eight is 3.21:1 (teal), which
clears the bar with little to spare; 45% is the same line at 3.91 if a
future palette needs the room.

Scoped to the band because `.cta-btn-brand` is used on light sections too,
including the contact form's submit, where a white edge would be wrong. */
.cta-band.invert-section .cta-btn-brand {
border-color: rgb(255 255 255 / 0.35) !important;
}

.hero-btn-learn {
Expand Down
Loading