Skip to content

Claude/hansmartens market positioning mlt89z - #686

Merged
hansmartensdev merged 4 commits into
mainfrom
claude/hansmartens-market-positioning-mlt89z
Sep 14, 2026
Merged

hansmartensdev merged 4 commits into
mainfrom
claude/hansmartens-market-positioning-mlt89z

Conversation

@hansmartensdev

Copy link
Copy Markdown
Owner

What does this PR do?

A clear description of the change and why it was made.

Fixes # (issue number, if applicable)

Type of change

  • Bug fix
  • New feature or component
  • Documentation update
  • Refactor or code quality improvement
  • Other: ___

Checklist

  • pnpm lint passes with 0 errors
  • pnpm check passes with 0 errors
  • pnpm build completes successfully
  • I have tested this change in the browser
  • No unnecessary files are included in this PR

Screenshots (if relevant)

Add before/after screenshots for visual changes.

Each of these surfaces carried two closing CTAs saying the same thing: a
flat block for anything below `glitch` — 1024px with a fine pointer —
and the LetterGlitch band above it, because a canvas cannot run on the
smaller screens. Visitors on a phone got the plainer of the two, and the
home page is where somebody decides whether to fork this theme.

The new band is a brand-500 to brand-900 gradient with a grid over it,
and it has no width or pointer gate, so one block now serves every
screen and the duplicate is gone. It closes the home, about and services
pages, the projects index and its paginated routes, every project page,
and every blog surface including single posts.

The light stop sits at -16%, outside the box, so the band opens an
eighth of the way down the ramp rather than at full brand-500. That is a
legibility fix for the narrow case: a phone renders the band short with
the content nearly filling it, which puts the description in the
brightest part of the gradient where a desktop's taller band puts it in
the middle.

The badge goes. It belonged to the flat block, and on a saturated field
a brand-tinted pill on brand ground is close to invisible.

Measured at the top line of each element — the lightest ground its text
touches — across all twelve colour themes, both colour modes, at 412px
and 1440px: the description holds 4.58:1 at worst against the 4.5 body
text needs, and the heading 4.14:1 against the 3:1 large text needs.

Dropping the canvas from the home page takes React with it: desktop
JavaScript there falls from 199.8 kB to 7.3 kB. Phones were already
paying nothing, since the island never hydrated below the breakpoint.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BwJB1u6U3vdEZ9LrHRebST
The canvas now runs in one place on the demo: the end of the post that
explains how it is built. A reader there is there for the effect, so it
is the one page where it is the subject rather than decoration, and the
post's opening line stays true of what the demo shows.

Below `glitch` the canvas cannot run, so those screens keep the gradient
band and the post still closes on something. The two are a pair on this
one page only, which is a demonstration rather than an inconsistency.

BlogCta's props follow the block it renders. It used to take a class for
the phone CTA and another for the desktop band's section, because there
were two; now there is one section and one band, so it takes
`sectionClass`, `maxWidth`, and the `glitch` switch this post sets.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BwJB1u6U3vdEZ9LrHRebST
The showcase catalogues what the theme offers, so it is where somebody
choosing between the two bands will look. It now carries each as its own
entry, next to the `CTA` variants that were already there.

The LetterGlitch entry needs a stand-in. The band renders nothing below
`glitch`, so dropped into a showcase slot as-is it is an empty box on
every phone, which reads as broken rather than as deliberate. A note
takes that space and says what the constraint is — which is the thing
worth knowing when picking between this band and the gradient one.

Neither is a registry component: both are patterns, so the count stays
at 44 and the README names them alongside `Callout`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BwJB1u6U3vdEZ9LrHRebST
@vercel

vercel Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astro-rocket Ready Ready Preview Sep 14, 2026 5:48pm UTC

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8bf9522b0e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +85 to +89
background: linear-gradient(
180deg,
var(--color-brand-500) -16%,
var(--color-brand-900) 100%
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore contrast for primary CTA buttons

When a CtaBand contains the primary action used by the migrated page closers, that action sits in the lower half of this brand-500→brand-900 ramp while hero-btn-brand fills it with brand-700 (src/styles/global.css:1299-1303). The resulting button/background contrast is only about 1.3–1.4:1 across the bundled themes, so the primary action has no discernible boundary against the band and fails the 3:1 UI-component contrast requirement. Give the in-band primary action a contrasting fill or border rather than the same brand step as its surrounding gradient.

Useful? React with 👍 / 👎.

The band's buttons were a brand fill and a transparent outline, and the
grid decided both. Lines read straight through anything transparent, so
the outline was cut across; and the brand fill sat close enough to the
ground's own value that it never became a surface of its own.

The primary is now the near-white pill the home hero already uses on its
own gradient, and the secondary is `.cta-btn-brand`, unchanged — an
opaque brand fill with an opaque brand hover. `.hero-btn-brand` would
look the same at rest but fades to `opacity: 0.85` on hover, which turns
the whole button translucent and shows the grid through it.

The primary's label is brand-700 rather than a near-black. brand-700 is
the step that clears 4.5:1 on a near-white fill across all twelve
palettes; brand-500 fails in ten and brand-600 still fails on emerald,
teal, cyan and sky.

Measured in all twelve palettes, both colour modes: the primary's label
holds 5.07:1 at worst and the secondary's 6.03:1, against the 4.5 body
text needs.

The secondary's fill sits at about 1.5:1 against the band behind it,
under the 3:1 a control's own edge would want. No brand step does
better — brand-800 measures 1.05 and brand-900 1.33, both worse than
brand-700 — so a border is the only thing that would carry that edge,
and the design keeps the borderless pair. The label, not the fill, is
what identifies the control here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BwJB1u6U3vdEZ9LrHRebST
@hansmartensdev
hansmartensdev merged commit 9038242 into main Sep 14, 2026
7 checks passed

This branch was successfully deployed

1 active deployment
Preview — acedd660 Deployed Sep 14, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants