APEXX Design System Audit

Current production design system (Gatsby + Statamic codebase, apexx.global) compared against the proposed APEXX Design system Figma file, and cross-checked against Design System Implementation Plan v1.0 (Indulge Digital, 21 July 2026). Where the two align, where they diverge, gaps in the proposed system — with specific attention to the flexipage background/foreground matrix and to how many flexipage row types actually received new designs.

Reviewed 27 Jul 2026 Branch statamic_cms_integration Figma file: 9 pages / 6 foundation + audit Implementation Plan v1.0 factored in (§11) 12 live flexipages inspected Contrast ratios computed, not estimated

1. Verdict & headline findings

The proposed system is a genuine improvement on colour discipline and accessibility, but it is a page-redesign deck, not a complete design system. It cannot be implemented against the existing flexipage content model without decisions it does not make.

What it gets right. Documented tokens with hex/RGB/HSL, WCAG AA reasoning per pair, a 4pt spacing scale, a full type scale across three breakpoints, and — critically — a rule that fixes the single worst accessibility defect in the live site: jade/teal is demoted to CTA-only and navy becomes the default text colour.

The three blocking gaps.

1. Backgrounds. Production has eight row background options driving ~38 CSS custom properties each (text, headings, alt headings, links, buttons ×2 sizes, list markers, blockquote, table head/body/borders, accordion summary/body, subtitle rings, hero-CTA panel). The Figma system defines foreground behaviour for exactly two surfaces — “light bg” and “navy bg” — plus two gradients with no foreground spec at all. Six of the eight current backgrounds have no documented token set.

2. Row coverage. Of 8 flexipage row types plus the hero, the audit page designs cover 4 (hero, alt/split content, accordion, feature-card style panels). Testimonials, call-to-action, two-column, widget rows, tables, blockquotes, video embeds and the small/large button variants have no new design.

3. Component states vs CMS reality. The system specifies states (default/hover/click/focus/disabled) for buttons and cards on white and navy only. Editors can currently place any component on any of the eight backgrounds, so the matrix is 8× larger than what has been designed.

Where the Implementation Plan v1.0 lands (full cross-check in §11). It closes most component-level gaps — gradients standardised to two tokens, buttons specified on light and navy with all five states, CTA pairing fixed, icon library scoped as its own workstream, mobile hero gap enforced, video moved to external hosting — and it honestly flags its own open decisions. It does not close the two structural findings: its token layer is primitives-only with no semantic or per-surface tier, and neither its component list nor its phase plan mentions the flexipage row model. It also mis-identifies the stack — it instructs the team to rebuild “Antlers/Blade partials”, but this is a Gatsby/React front end with headless Statamic over GraphQL.

Two internal contradictions to resolve before build. (a) Typography page makes Poppins the heading family and Nunito Sans the body family — the live site uses Ambit for headings and Poppins for body, so this is a three-font swap, not a refinement, and the Ambit licence/webfonts already shipped become dead weight. (b) Colour page keeps two navy→blue gradient surfaces while the Components page instructs “use solid colours only… no gradients” for cards and the Split-content page removes accent colours; gradient rows are the site's main visual device, so the intended end-state for gradients is ambiguous.

2. Scope, sources & method

Everything below is derived from the code, the live HTML, and the Figma file itself — no assumptions about intent.

Sources

Deliberately out of scope

3. Current system as built

The flexipage layer is already a token-driven system. That is the thing the new design system has to replace or extend — and it is more permissive than the new system assumes.

3.1 Colour ramps in code

FlexipageColors defines 10 blues, 7 teals, 8 greys, 4 named button colours and 5 gradients:

blue1200 #052231
blue1000 #144056
blue900 #124997
blue800 #385DA7
blue700 #0F6CB6
blue600 #1E7FC2
blue500 #428AC9
blue400 #4CB9EF
blue200 #8FC5EA
blue100 #F4F9FD
teal1200 #15725A
teal1000 #46AC92
teal800 #55BAA3
teal600 #55B9A3
teal400 #39B8BD
teal300 #6BE2E5
teal200 #6ECDD6

Note teal800 #55BAA3 and teal600 #55B9A3 differ by one hex digit — a duplicate token in the current build, and evidence the ramp grew organically. The legacy src/utils/styles.js palette (primaryBlue2 #72b4b4, secondaryBlue3 #3b5Ca7, …) plus 13 hard-coded ApButton variants (green, greenTwo, greenTwoLarge, lightGreen, greenSecondaryLarge, …) exist in parallel for the non-flexipage pages.

3.2 The eight row backgrounds and their token overrides

Editors pick one of eight values in Statamic (backgroundColourFormatter()); each sets a class that re-points a subset of ~38 CSS custom properties:

Statamic optionCSS classSurfaceForeground props overriddenLive usage across 12 flexipages
(default / none)bg-white#FFFFFFbaseline (38 defaults)29 rows
Greybg-light-grey#f7f7f731 (re-declares defaults + 3)0 rows
Dark Bluebg-dark-blue#1440561314 rows
Gradient Darkbg-gradient-dark#144056 → #428AC9121 row (card-payments)
Gradient Midbg-gradient-mid#3B5CA7 → #428AC990 rows (hero only)
Gradient Lightbg-gradient-light#d5e0fa → #cceaff65 rows (all accordions)
Gradient Neutralbg-gradient-neutral#ddeef9 → #d4fdf460 rows (hard-coded in CTA row)
Gradient Extra Lightbg-gradient-extra-light#ddf1ed → #e9f4fb50 rows

Useful fact for scoping. Only four of the eight background options carry any production content today — white (29 rows), dark blue (14), gradient light (5), gradient dark (1). The other four — including Grey — are unused across all 12 flexipages. Counts are markup-level (styled-component class attributes on section.flexipage-row), so CSS rule text is excluded. Full decision table in §12.

3.3 Type scale in code

StyleFamily / weightDesktop≤992px≤767px
h1Ambit Bold64 / 1.24840
h1.titleAmbit Bold48 / 1.24040
h2Ambit Bold48 / 1.24032
h3Ambit Bold40 / 1.23224
h4Ambit Bold32 / 1.22424
h5Ambit Bold20 / 1.52020
h6Ambit Bold18 / 1.51818
p / generalPoppins 40016 / 1.51616
p.smallPoppins 40013 / 1.51313

Nunito Sans (600/800) is loaded too, and used by older non-flexipage components. Panel titles override to Ambit 20/30 uppercase.

3.4 Row types available in the CMS

From the flexipage GraphQL query — the authoritative contract: HeroSection (title, copy, video, lead image, icon, hero panels), CopyRow, AltRow, PanelsRow, AccordionRow, TestimonialsRow, TwoColumnsRow, CallToActionRow, WidgetRow (3 widgets: Payment Orchestration Platform Diagram, BNPL Logos Slider, Logos Map). Rich-text content additionally supports tables (incl. a responsive card mode), blockquotes, ordered/unordered lists with custom markers, inline video embeds, and three button classes (button, .large, .small).

4. Proposed system as documented

Transcribed from the Figma file. Values are as shown on the swatch/spec cards.

4.1 Palette

Navy default
#144056
Cyan accent
#39B8BD
Jade primary CTA
#3F9B83
Jade dark CTA
#317866
Jade light
#ECF7F4
Link default
#0F6CB6
Link hover
#0C5692
Link click
#09416D
Footer label bg
#88D4D7
Error
#DC3545
Error light
#F8D7DA
Warning
#FFC107
Warning light
#FFF3CD
Border
#728C9A
Surface bg
#DCE2E6
Surface bg 2
#F3F5F7
Background
#FFFFFF
Gradient surface 1
Gradient surface 2

Stated rules: primary green (jade) for buttons only; navy for all text on white; white text on navy or gradient; cyan sparingly for headlines/text on navy. “Don't” list includes: jade as text on white or navy (fails AA), jade on green-toned backgrounds, jade light as a background surface, jade and cyan in the same section, semantic colours used decoratively, any colour outside the palette. Neutrals were re-derived from navy (cool blue-greys replacing the site's warm greys).

4.2 Typography

StyleFamily / weightDesktopTabletMobile
Heading XXL (Display)Poppins 70056 / 64 / −146 / 5436 / 44
Heading XLPoppins 70048 / 56 / −140 / 4832 / 40
Heading LGPoppins 70040 / 48 / −134 / 4028 / 34
Heading MPoppins 60032 / 3628 / 3424 / 28
Heading SPoppins 60024 / 3222 / 2820 / 26
Heading XSPoppins 60020 / 2620 / 2618 / 24
Heading XXSPoppins 60016 / 2016 / 2016 / 20
Stat numbersPoppins 60020 / 2620 / 2618 / 24
Text linkPoppins 60016 / 2016 / 2016 / 20
Footer linkPoppins 40014 / 1814 / 1814 / 18
CaptionPoppins 50012 / 16 / +0.512 / 1612 / 16
PullquoteNunito Sans 70024 / 3222 / 2820 / 26
Article leadNunito Sans 40024 / 3222 / 2820 / 26
Body largeNunito Sans 40020 / 2820 / 2818 / 26
Body article/cardNunito Sans 40018 / 26 — fixed all breakpoints
Body medium (primary body)Nunito Sans 40016 / 24 — fixed
Stat textNunito Sans 40016 / 2416 / 2416 / 22
Button labelNunito Sans 70019 / 28 — fixed
Image buttonNunito Sans 50016 / 24 — fixed

4.3 Spacing & grid

4pt scale (“never use odd values like 5, 7 or 15px”; section/page gaps use 32/48/64). Layout grid documented as 12-column, Bootstrap 5-breakpoint:

BreakpointWidthColumnsGutterMargin
XS0–575px41616
SM575–767px41624
MD768–991px82432
LG992–1199px122448
XL1200px+123264

4.4 Components documented

The Icons page states plainly: “SVG access was not available for this project, so a full icon library has not been defined at this stage… It is recommended that APEXX review and update all remaining icons.” The icon layer is therefore explicitly unfinished.

5. Match / partial / divergence

Foundation-by-foundation. “Partial” means the concept survives but values or coverage change.

AreaStatusCurrent buildProposedImplication
Primary navyMatch #144056 as --color--primary#144056 navy default No change. Brand anchor is stable.
Link bluesMatch blue700 #0F6CB6 already in rampLink default/hover/click #0F6CB6 / #0C5692 / #09416D Adds the two missing interaction states; same base hue.
Type scale stepsMatch 48 / 40 / 32 / 20 / 18 heading steps48 / 40 / 32 / 24 / 20 / 16 + 56 display Mostly the same rhythm; h1 drops 64 → 56, an XXS 16 step is added, and h5/h6 line-heights tighten.
Spacing rhythmMatch Row padding 96 / 64 / 48px (6/4/3rem)4pt scale, big gaps 32/48/64 Existing paddings are already 4pt multiples — cheap alignment.
Accordion patternPartial Navy summary on light, white summary on dark; grey bodySame inversion rule; open header becomes jade-light Small token change (--color--accordion--summary--*, new open-state background).
Split content / alt rowPartial AltRow, image/text alternating, gradient allowed48px gap, 570px image, no accents, tint box Layout spec exists but only for 2 of the current row's configurations.
Button colourDiverges Primary #144056; large/small variants use teal #46AC92 / #6ECDD6 Single jade #3F9B83 primary + jade-dark ghost, min 19px bold label Live teal buttons with white labels measure 2.77:1 and 1.85:1 — the new spec is a fix, not a preference. But .large/.small rich-text button classes have no counterpart.
Heading colourDiverges --color--headings defaults to teal #46AC92 on white (2.77:1) Navy for all text on white; jade never as text Fixes a real AA failure sitewide; also removes the *asterisk*.alt teal-highlight convention used in titles.
Heading fontDiverges Ambit (self-hosted, 6 weights + italics, CoType EULA)Poppins 600/700 Full heading-family swap; Ambit files/licence become redundant. Confirm this is intentional brand direction.
Body fontDiverges Poppins 400 @16/1.5Nunito Sans 400 @16/24 Body-family swap with knock-on effects on line lengths and vertical rhythm across every row.
NeutralsDiverges Warm greys #f7f7f7 … #262626Cool blue-greys #F3F5F7 / #DCE2E6 / #728C9A Grey row background, table cells, borders, blockquote tints all shift; #728C9A on white is 3.54:1 so it is a border/UI colour only, never text.
GradientsDiverges 5 gradients (dark, mid, light, neutral, extra-light)2 gradient surfaces, both navy→blue Three light/teal gradients disappear with no replacement mapping. Accordion rows in production all sit on bg-gradient-light.
Semantic coloursNew None (no form feedback tokens)Error/warning + light variants, with usage notes Purely additive; needed if forms move in-house (contact-us currently HubSpot-embedded).
Interaction statesNew :hover + :focus-visible only; no disabled/pressed 5 states on every button/card/tab/link Additive and valuable; requires new CSS in every row component.
BreakpointsDiverges Custom max-width: 992px / 767px; Bootstrap 4 in depsBootstrap 5 five-tier (576/768/992/1200) 767 vs 768 boundary conflict, and no rules today for ≥1200 or ≤575. Container is 1170px (BS4) vs XL margin 64px implied by the grid.
MotionMissing Scroll fade-ins on every row (data-animation-*)Not documented No guidance on whether to keep, restyle, or drop the animation layer.

6. The background × foreground matrix problem

This is the question that decides whether the new system is implementable. Answer: as documented, no — it covers 2 surfaces where the CMS exposes 8.

Every flexipage row re-points a token set. Below is what a background variant actually has to define in code today (from FlexipageStyles.js), and whether the proposed system gives an answer for it.

Foreground token groupTokens involvedDocumented for white / light?Documented for navy?Documented for the 5 gradients + grey?
Body text--color--paragraphYes navyYes whiteGradient: “white text” rule only; grey surface unstated
Headings + alt headings--color--headings, --color--headings--altYes navyYes white / cyan sparinglyNo
Inline links--color--linkYes #0F6CB6 + hover/clickNo — #0F6CB6 on navy is 2.02:1No
Primary button--color--button--background/-text/-hover/-focusYesYesNo — jade on light-teal gradients is explicitly a “don't”
Large / small button variants--color--button--large--*, --color--button--small--*NoNoNo
List markers--color--list-item--markerImplied navyImpliedNo
Blockquotebackground, border, text (3)NoNoNo
Tables--color--th--background/-text, --color--td--background/-text, --color--tr--borderNoNoNo
Accordionsummary bg/text, body bg/text/link, toggle (6)YesYesNo — yet every live accordion sits on gradient-light
Two-column subtitle ring/line--color--subtitle--circle, --color--subtitle--lineNoNoNo
Hero CTA panel--color--hero-cta--panel--background/-textFeature-card treatment implies itPartialNo
Tabbed interface--color--tabbed--container--background/-textFilter tab covers light onlyNoNo

6.1 Why gradients are the hard case

A gradient has no single contrast value. bg-gradient-dark runs #144056 → #428AC9; the current build puts teal #55BAA3 headings and white body text on it:

So a row's compliance depends on how tall the row is and where the text lands in the ramp. The proposed system keeps two gradient surfaces and says “use white text on navy or gradient background”, which is still not sufficient: gradient surface 2 ends in #FFFFFF, where white text is invisible. No stop-position or minimum-contrast constraint is specified.

Recommendation. Either (a) restrict gradients to hero/full-bleed decoration and forbid body content over them, or (b) define each gradient with a guaranteed-contrast band (e.g. content only over the first 60% of the ramp) plus per-gradient token sets. Option (a) is what the redesigned Card Payments and APM pages actually do — the gradient is confined to the hero, and content rows are white/navy/grey. That intent should be written down as a rule, because right now the CMS still allows gradient content rows.

7. Flexipage row coverage — what was designed, what was missed

The Website-audit page shows full redesigns for two flexipage-driven URLs (Card Payments, Alternative Payment Methods). Mapping those designs back onto the row inventory shows what is unaddressed.

7.1 Row-by-row

Row type (CMS set)Live usage (12 flexipages)New design provided?What is missing
HeroSection (+ hero panels, video, icon)12 / 12 Partial Desktop hero redesigned on both pages (diagonal navy→blue, cards overlapping the fold). No spec for: hero video variant, hero icon, hero panel link row as a component, or the tablet/mobile hero — even though the audit summary itself flags mobile hero spacing as a sitewide defect.
AltRow (image/text, alternating, video items)39 instances — the workhorse Yes Covered by “Split content section” + page examples. But only image-left and text-left on white and navy; the multi-item alternating stack, video-in-column items, and gradient variants aren't shown.
CopyRow (bard rich text, centre/left, inline CTA, video)4 instances Partial Body/heading styles exist, but no design for the row itself: centred text measure, inline CTA button placement, embedded video block, and no styling shown for tables, blockquotes, or ordered lists that this row can contain.
AccordionRow5 pages (all on bg-gradient-light) Yes Component designed for light and dark surfaces; the gradient-light surface it currently uses isn't in the new palette, so a mapping decision is needed. Intro-copy area above the accordion isn't shown.
PanelsRow (2/3-col, 3 row styles: grid, gradient panels, white panels)0 in production (styled and available) Partial Feature card large/small replace the panel visually, but only as white cards on navy. The three row_style options, the 3-column layout, the uppercase Ambit panel title, and the highlighter-pen title treatment have no equivalent — so the CMS options would have to change with it.
TestimonialsRow (slick carousel, avatar, name, position)0 in production No Nothing. Pullquote type style exists, and case cards exist, but no testimonial panel, no carousel dots/arrow spec for this row, no avatar sizing.
CallToActionRow (label, tagline, button; hard-coded gradient-neutral)0 in production No The redesigned pages end with a bespoke closing CTA (heading + two buttons + three benefit cards) which is not this row. Its hard-coded bg-gradient-neutral is also a gradient that the new palette deletes.
TwoColumnsRow (subtitle ring/line, 2 rich-text columns, centre option)0 in production No Nothing — including the distinctive SubTitle circle+line ornament, which has dedicated tokens per background.
WidgetRow — Logos MapUsed on APM (+ most pages via footer variants) No The interactive world-map-with-logos widget is not redesigned. The APM redesign replaces it with a static acquirer logo grid — if that is the intent, say so, because it is a functional removal, not a restyle.
WidgetRow — Payment Orchestration Platform diagramUsed on payment-orchestration-platform No No design. This is the most complex interactive component on the site.
WidgetRow — BNPL Logos Slider0 in production (available) No No design; carousel arrows exist as buttons but no slider-row layout.
Rich-text sub-elements: tables (+responsive card mode), blockquote, ol/ul markers, inline video, .large/.small buttons, .alt heading spans Tables/blockquotes styled; buttons used (36 .large instances) No None of these appear anywhere in the new system, yet they are all editor-reachable through Bard fields. Tables in particular carry six tokens per background.

Score. 4 of 11 row/widget variants have a usable new design; 2 are partial; 5 have none. Counting the rich-text sub-elements as one bucket, roughly 60% of what an editor can build today has no designed counterpart — but four of the undesigned rows have never been used in production, so most of that gap can be closed by retirement rather than by design work. §12.2 turns this into a sign-off table with a per-row recommendation.

7.2 What the two designed pages actually contain

Both redesigned pages are built from the same small kit: hero (diagonal gradient) → 3 small feature cards → split content (light) → split content (navy, image left) → logo grid or FAQ accordion → closing CTA with 3 benefit cards → footer. That is a page pattern, and a good one — but it is narrower than the flexipage model, which is by design open-ended. Two possible readings, and they lead to very different builds:

8. Page/template coverage

The Figma audit page covers 10 page designs. The site has considerably more templates.

Template / pageImplementationDesigned in audit?
Landing / homesrc/pages/index.jsx + HomePage componentsYes (“Landing page”)
Card PaymentsflexipageYes
Alternative Payment MethodsflexipageYes
Blog articletemplates/blog-article.jsxYes (desktop + mobile)
Press & media / news listingsrc/pages/press-and-media.jsxYes (“News and media”, with filter tabs)
Our storysrc/pages/our-story.jsxYes
Partnershipssrc/pages/partnerships.jsxYes
Case studiessrc/pages/case-studies.jsxYes
Country report (focus)templates/country-report-focus.jsxYes (“Country report Argentina”)
“Global payments”No such live URLDesigned, unmapped — new page or a rename of an existing one?
Remaining 9 flexipages (revenue-protect, smart-split, cascading, dynamic-routing, insights-and-dashboards, payment-orchestration-platform, tokenisation, consolidated-reporting, bin-lookup)flexipageNo — assumed to inherit the two designed patterns; the POP diagram page in particular cannot
Careers (/careers-page-test/) — newest flexipage, still changingflexipageNo — and it introduces four patterns that exist nowhere else: hero panel links, emoji-as-icons, long-form editorial columns, flat mint illustration. Detail in §12.3
Blog listing + category listing + paginationtemplates/blog-listing*.jsxNo (news listing is a different template)
Contact us (+ embedded form)src/pages/contact-us.jsxNo — and semantic error/warning colours exist precisely for forms
Cost saving calculator / surcharge inspectorsrc/pages/cost-saving-calculator.jsx, surcharge-inspector.jsx, ApexxCalculator, apexchartsNo — no input, slider, chart or data-viz tokens anywhere in the system
Country reports indexsrc/pages/country-reports.jsxNo
Landing pages (campaign template)templates/landing-page.jsxNo
Privacy / T&Cs / 404src/pages/*No — long-form legal text has no documented layout
Global chrome: header/mega-nav, cookie banner, “How APEXX can help” footer CTA, footercomponents/Global/Layout/*Nav menu + footer appear inside page mocks; cookie banner and help-CTA section not specified

The audit summary explicitly recommends the nav background always match the hero section beneath it — a global behaviour change that touches Layout.jsx's headerTransparent / whiteToggler / logoDark props on every template, not just the designed pages.

9. Accessibility & contrast numbers

Computed with the WCAG 2.1 relative-luminance formula from the hex values in each system. AA needs 4.5:1 for normal text, 3:1 for large (≥18.66px bold / ≥24px) and for UI/graphics.

PairSystemRatioVerdict
Default heading teal #46AC92 on whiteCurrent2.77Fails AA (all sizes)
Panel/heading teal #55B9A3 on whiteCurrent2.37Fails
White label on primary teal button #46AC92Current2.77Fails
White label on .small/secondary teal #6ECDD6Current1.85Fails badly
White label on secondary blue #8FC5EACurrent1.85Fails badly
teal #55BAA3 heading on gradient-dark, navy endCurrent4.71Passes
…same heading, blue end #428AC9Current1.57Fails — position-dependent
White body text on #428AC9 (gradient-dark bottom)Current3.68Large text only
Navy #144056 on whiteBoth11.07Passes AAA
teal300 #6BE2E5 alt heading on navyCurrent7.19Passes AAA
Jade #3F9B83 as text on whiteProposed (forbidden)3.37Correctly banned for text
White label on jade #3F9B83 buttonProposed3.37Only valid because label is 19px bold — brittle
Jade dark #317866 on white (ghost button label)Proposed5.24Passes
Cyan #39B8BD on navyProposed4.62Passes (thin margin)
Cyan #39B8BD on whiteProposed2.40Must never be text on white
Border #728C9A on whiteProposed3.54OK for borders/UI, not text
Link #0F6CB6 on whiteBoth5.47Passes
Link #0F6CB6 on navyProposed (undefined case)2.02Fails — links on navy rows need a second token
Black #000000 on white (plan's --color-black body text)Plan v1.021.00Passes, but contradicts “navy for all text on white”
Jade-dark #317866 on jade-light #ECF7F4 (ghost hover)Plan v1.04.78Passes
Jade-light #ECF7F4 fill against a white page (edge perceivability)Plan v1.01.10Needs a border — fill boundary is invisible
White text on Gradient 2's white endPlan v1.01.00Rule “white text on gradient” breaks here
Cyan #39B8BD on Gradient 1/2 mid-stop #0F6CB6Plan v1.02.28Cyan is only safe on navy, not on the gradient body
Navy on surface tint 1 #DCE2E6 / tint 2 #F3F5F7Plan v1.08.47 / 10.13Both pass comfortably
Grey #728C9A as disabled text on whitePlan v1.03.54Compliant only via the disabled-control exemption

The proposed system's own contrast card is accurate (white on navy 11.06, white on jade 3.37 “19px bold only”, cyan on navy 4.61, green on navy 3.28 fail) — my independent calculations agree within rounding. That is a good sign for the rest of its reasoning.

Fragile by construction: the primary CTA only passes because the label is 19px bold. Any future small button, dense card CTA, or 16px label reintroduces a failure. A jade with ≥4.5:1 against white (e.g. the documented jade-dark #317866) would remove that dependency entirely — worth raising with the designer.

10. Issues in the proposed design system

Ordered by build risk. Each is a decision someone must make before implementation, or it will be made implicitly in CSS.

High · blocking

10.1 Foreground token sets exist for 2 surfaces, CMS exposes 8

Documented: light background, navy background. Undocumented: grey surface, and the five gradients — including bg-gradient-light, which carries every accordion row in production, and bg-gradient-neutral, which is hard-coded into CallToActionRow. Missing per-surface answers for blockquote (3 tokens), tables (5), subtitle ornament (2), hero-CTA panel (2), tabbed container (2), large/small buttons (4).

Fix: publish a surface × token matrix (even if the answer is “these four surfaces only, the rest are retired”), or explicitly reduce the CMS background options to match the palette.

High · blocking

10.2 Gradient rules are incomplete and internally inconsistent

Colour page keeps 2 gradient surfaces; Components page says cards must use “solid colours only — no gradients”; Split-content page removes accents “as the cyan accent did not perform reliably against white or jade green backgrounds”. Gradient surface 2 fades to #FFFFFF, so the “white text on gradient” rule breaks on it. No stop positions, angle, height limits, or minimum-contrast band are given, and contrast over a gradient varies by row height (1.57–4.71 measured today).

Fix: restrict gradients to hero/decorative full-bleed use (which is what the two page redesigns do), or specify a content-safe band per gradient.

High · blocking

10.3 Row coverage is incomplete relative to the content model

No design for Testimonials, CallToAction, TwoColumns (incl. the SubTitle ornament), any of the three widget rows, tables, blockquotes, inline video, or the .large/.small button classes (36 .large instances live today). Panels are only reinterpreted as white cards on navy, dropping the three existing row_style options and the 3-column layout.

Fix: decide per row — redesign, retire, or “inherit split-content/feature-card”. Retiring is defensible for the four rows with zero production usage, but it must be an explicit decision because the Statamic blueprint still offers them to editors.

Medium

10.4 Two font families change at once, and both differ from the current build

Headings Ambit → Poppins; body Poppins → Nunito Sans. Ambit is a licensed self-hosted family (CoType EULA in-repo) that becomes unused. Nunito Sans is currently loaded at 600/800 only — the new spec needs 400/500/700, i.e. new webfont subsets and a re-check of the font-loading budget (three families' worth of files are already shipped). Line-height changes (1.2em → fixed px, 1.5em → 24px) will reflow every row and every hard-coded height in older components.

Fix: confirm the family swap is intended brand direction, then plan subsetting/preload and delete Ambit.

Medium

10.5 Grid spec contradicts the codebase

The system documents Bootstrap 5 breakpoints (576 / 768 / 992 / 1200). The repo runs Bootstrap 4.5 and the flexipage CSS uses max-width: 992px and max-width: 767px — the 767/768 boundary leaves a 1px dead zone, and there are no rules for ≥1200 or ≤575 today. Container width is 1170px (BS4) while the XL row implies a 64px margin at 1440px (≈1312px content). The hero container is 1340px, a third value.

Fix: pick one container/breakpoint set and state it as tokens; upgrading Bootstrap is a separate, larger decision.

Medium

10.6 Primary CTA passes contrast only via a 19px-bold label

White on jade #3F9B83 = 3.37:1, which qualifies only as large text. Every future compact button, card CTA, or 16px label silently breaks AA. Also note the 19px button label is not a 4pt-scale value, contradicting the spacing/typography discipline elsewhere in the file.

Fix: use jade-dark #317866 (5.24:1) for solid CTAs, or accept jade only with the bold-19 rule enforced in code (single button component, no ad-hoc rich-text buttons).

Medium

10.7 Icon library explicitly unfinished

The system states no icon library was defined (no SVG access); only a handful of extracted icons were recoloured as before/after. The live site uses FontAwesome, Phosphor (src/icons/phosphor), and bespoke SVGs. Rule given — “jade never on pictograms inside a CTA component; use navy, cyan, or a tonal variant” — cannot be applied consistently without the library.

Fix: scope an icon pass as separate work; until then, expect inconsistency between designed pages and everything else.

Medium

10.8 No tokens for forms, charts, or the calculators

Semantic error/warning colours are defined but, per the file's own note, “not currently applied to any component”. There are no input, select, checkbox, slider, validation-message, tooltip, chart-series, or table-sort specs — yet cost-saving-calculator and surcharge-inspector ship apexcharts and custom inputs, and contact-us has a form.

Fix: add a forms/data-viz section, or declare those pages out of scope in writing.

Low

10.9 No motion, focus-ring, or dark-mode tokens

The site animates every row on scroll (data-animation, fade-in, durations/delays) — undocumented in the new system. Focus states are drawn as a black/white outline in mocks but no focus-ring token, width, offset, or the existing --color--button--outline--focus equivalent is specified. Prefers-reduced-motion isn't mentioned.

Low

10.10 Naming won't map cleanly to the existing token layer

Figma names are role-based prose (“Navy – default (surface/text)”, “Blue – link text hover”, “Surface background 2”); code uses numeric ramps (blue1000, teal800) plus semantic CSS custom properties (--color--headings--alt). There is no published mapping, and no Figma variables/styles to export, so the translation will be hand-made and drift-prone. Existing duplicates (teal800 #55BAA3 vs teal600 #55B9A3) should be resolved during the mapping.

Low

10.11 Unmapped page and an unresolved global nav behaviour

A “Global payments” page design exists with no corresponding URL. The nav-background-matches-hero recommendation is global but is only demonstrated on designed pages; it changes Layout props sitewide, including on templates that were never designed.

11. Cross-check: Design System Implementation Plan v1.0

Indulge Digital, 21 July 2026, 16pp. It adds a token-naming convention, button sizing/state tables, six component specs, a gap analysis against the audit findings, a risk list and a 5-phase / 8-week rollout. Read against this audit it closes several of my findings outright, leaves the two structural ones open, and introduces one factual error about the stack that will cost real time if it isn't corrected before Phase 0.

Correct this first — the plan targets the wrong rendering layer. §1 states the site “is being rebuilt on Statamic CMS and is nearly live”, and §5.3 instructs the team to “rebuild shared Antlers/Blade partials for each component”. This repository is a Gatsby / React front end using styled-components, consuming Statamic headlessly over GraphQL (gatsby-source-graphql; see src/templates/flexipage.jsx and gatsby-node.js). There are no Antlers or Blade templates to rebuild — components are *.styles.js styled-components under src/components/. Likewise §2's “outgoing live site … running on Gatsby with Contentful” is half right: the migration in flight is Contentful → Statamic as a data source on the same Gatsby build, not a move to Statamic-rendered templates.

Consequence: Phase 0/2 effort estimates assume a partial-per-component rebuild in a Blade-style templating layer. The real work is (a) a token module consumed by styled-components — the existing FlexipageStyles.js already does exactly this via CSS custom properties, so it is a rewrite of one file, not a new architecture — and (b) 8 row components plus the legacy non-flexipage component tree, which the plan never enumerates.

11.1 What the plan resolves

Audit finding (this document)Plan's positionStatus
§10.2 Gradients proliferate / ad-hoc“Standardise on Gradient 1 / Gradient 2 tokens; no other gradient combinationsResolved — implies retiring gradient mid / light / neutral / extra-light, exactly the reduction §12 recommends
§10.1 Buttons undefined on navyFull variants × states tables for light and navy; on navy both primary and ghost use Jade primary; focus ring black on light, white on darkResolved for buttons
§10.6 CTA pairing / hierarchyReplace “primary + text link” with “primary + ghost” so paired CTAs read as equalsResolved
§10.7 Icon library unfinishedNamed as an open dependency, scoped as its own workstream ahead of Phase 1Acknowledged & scheduled
§10.8 Semantic colours unused“Reserved tokens only — do not invent a component until a form/alert component is scoped”Deliberate deferral
§10.9 No focus-ring specFocus outline defined per surface (black on light, white on dark); disabled states described per variantMostly resolved — still no ring width/offset token
§10.10 Naming won't map to codeExplicit CSS variable names: --color-navy-500, --color-green-550, --color-neutral-100, --font-primary/secondary, --space-*Half resolved — see 11.3, these are primitives with no semantic layer
Video-in-hero performance red flagImagery rule: “embed video via external host (YouTube/Vimeo), never upload directly”Resolved
Mobile hero spacing defectEnforce 24–32px minimum nav→hero gap at all breakpointsResolved
§10.5 Container width unknown“No max container width is specified — confirm with design before build”, and listed as an open decision in §6Flagged, not answered
§10.11 Nav-matches-hero is globalListed as an undefined design decision needing sign-off before buildFlagged, not answered
Audit was captured on the outgoing site§2 and §6 both require re-validation of each finding against the new build before scheduling fixesCorrect call — and this audit supplies that re-validation for the flexipage layer (§7, §14.5)

11.2 What the plan does not close

The two structural findings survive intact, and the plan's phase list shows why: Phase 2 rebuilds six components (Case Card, Article Card, Feature Cards, Accordion, Split Content, Nav/dropdown) and Phase 3 is “apply components across all templates”. Nothing in either phase names the flexipage content model.

Open itemWhy the plan doesn't close itCost if left
Per-surface foreground token sets (§6 of this audit) §5.1 implements “all Section 3 tokens as CSS custom properties” — but Section 3 is a primitive palette (--color-navy-500 …). There is no semantic tier (--color--headings, --color--link, --color--th--background …) and no surface blocks. The existing build already has that tier with ~38 properties across 8 surfaces; primitives alone can't replace it. Each component author re-decides which primitive applies on which background. That is precisely the “per-page overrides” failure mode the plan's own §5.3 warns against.
Flexipage rows with no design (§7) Testimonials, CallToAction, TwoColumns (incl. the SubTitle ornament), the three widget rows, tables, blockquotes, inline video and the .large/.small rich-text buttons are absent from the plan as well as from Figma. “Case Card” covers testimonial cards, not the TestimonialsRow carousel. Phase 3 stalls, or a developer invents the styling — an undocumented system by Phase 4.
Statamic blueprint pruning Gradient reduction and any row retirement are styling decisions in the plan; nothing schedules the corresponding change to the background_colour option list or the row sets in the blueprint. Editors keep selecting “Gradient Neutral” etc. after the CSS for it is deleted — silent visual breakage in the CMS.
Contrast over a gradient (§6.1) Gradient 1 and 2 are standardised but still have no stop positions, height limits or content-safe band. Gradient 2 ends in #FFFFFF, where white text is 1.00:1; cyan on the #0F6CB6 mid-stop is 2.28:1. The plan's own Phase 4 “WCAG AA contrast check” cannot produce a pass/fail for gradient rows.
Forms, charts, calculators (§10.8) Deferring the semantic component is reasonable, but cost-saving-calculator and surcharge-inspector ship apexcharts and custom inputs today and appear in no phase. Two live pages drift out of the system.
Legacy component tree Not mentioned: src/utils/styles.js's parallel palette and 13 hard-coded ApButton variants (green, greenTwoLarge, lightGreen, …) used by home, our-story, partnerships, calculators, country reports. Phase 1 “buttons (all variants/states)” looks small and is not.
Motion (§10.9) Every flexipage row fades in on scroll via data-animation-*; no phase mentions it and no motion token exists. Animation survives by accident, undocumented, with no reduced-motion story.

11.3 New issues introduced by the plan

High

11.3.1 Token layer is primitives-only

Naming (--color-navy-500, --color-green-550, --color-neutral-25) is a numeric ramp with no role mapping. The current build's strength — that a row's background class re-points semantic properties and every child component inherits correctly — is lost if primitives are consumed directly.

Fix: keep three tiers — primitives (plan's names) → semantic roles (existing --color--paragraph, --color--headings, --color--link, --color--button--*, table/accordion/blockquote sets) → four surface blocks that re-point the semantic tier. Retaining the existing property names means the 8 row components need no edits at all.

Medium

11.3.2 Body-text colour contradicts itself: black or navy?

The neutral table defines --color-black as “default body text on light surfaces” — with no hex value — while the Do/Don't list one page later says “use navy for all text on white”, which is also what the Figma file says. Black on white is 21:1, navy 11.07:1; both pass, but they are visibly different and every row is affected.

Fix: pick one. Navy matches the Figma system and the page mocks; if black is intended, it needs a hex and the Do/Don't rule must change.

Medium

11.3.3 Jade-light is simultaneously banned and required as a background

§3.1: Jade light “Accent tint only — never as a background surface”. §3.5 colour logic: “Jade light = alternate CTA background where primary Jade can't be used”, and the ghost-button hover state is a “Jade-light tint fill”. The accordion spec also uses a light-jade background on the open header row.

Fix: restate as “never a section/page surface; permitted as a component fill”. Note the pair does work: jade-dark text on jade-light is 4.78:1, but jade-light against a white page is a 1.10:1 boundary, so those fills need a border to be perceivable.

Medium

11.3.4 The 4pt rule is broken by its own scale and by the button label

§3.3 says “every value must be a multiple of 4”, then lists 0, 1, 2, 4, 8 … — 1 and 2 are not multiples of 4. Button sizing then uses 8px nav-dropdown padding (fine) alongside a 19px button label and 15%-opacity shadow / +10px hover scale for article cards. The 19px is load-bearing for accessibility, so it should be called out as a deliberate exception rather than silently contradicting the scale.

Medium

11.3.5 Gap analysis is scoped to the marketing pages, not the content model

All 22 gap-analysis rows map to page-specific findings (nav, hero spacing, article hierarchy, case cards, press/blog merge, partner logo grid, stats-in-images, headshots, boilerplate). Useful — but the 12 flexipage URLs that make up half the site's page count are absent, and they are the pages whose styling is fully token-driven and therefore cheapest to fix. §14.5 of this document gives the row-by-row inventory to slot in.

Low

11.3.6 Breakpoint table overlaps at 575px, and still conflicts with the code

XS is 0–575 and SM is 575–767 — 575 belongs to both. The codebase meanwhile branches at max-width: 992px and max-width: 767px with a 1170px container (Bootstrap 4), and the hero uses 1340px. Since the plan defers container width to design anyway, resolve both in the same decision.

Low

11.3.7 Disabled text uses a 3.54:1 grey

--color-grey-300 #728C9A is specified as border colour “also disabled text”. On white that is 3.54:1. WCAG exempts disabled controls, so this is compliant — but it should be labelled as an intentional exemption so a future audit doesn't “fix” it, and it must never be reused for placeholder or helper text, which is not exempt.

11.4 Phase plan, adjusted for this codebase

The five phases are sensibly ordered. Three amendments make them executable here:

Plan phaseAmendment for the Gatsby/Statamic build
Phase 0 — Foundations (wks 1–2) Deliverable is a rewritten src/components/Flexipage/Global/FlexipageStyles.js (or a new src/styles/tokens.js) with the three-tier structure from 11.3.1 — not Antlers/Blade partials. Add the four surface blocks here, and delete the duplicate teal600/teal800 pair. Fonts: subset/preload Poppins 600/700 + Nunito Sans 400/500/700, remove Ambit.
Phase 1 — Core primitives (wks 2–3) Scope must include the legacy ApButton (13 variants) and the three rich-text button classes, or those pages keep the failing teal buttons (2.77:1 / 1.85:1). Decide jade #3F9B83 + enforced 19px bold vs jade-dark #317866 (5.24:1) before writing the component.
Phase 2 — Component library (wks 3–5) Add the flexipage rows to the list: AltRow, CopyRow, AccordionRow (+ the surviving Panels/Testimonials/CTA/TwoColumns rows if they aren't retired), plus tables, blockquote, lists, video embed. Get whatever is derived signed back into the Figma file.
Phase 3 — Page rollout (wks 5–7) Insert a blueprint task: prune background_colour options and retired row sets in the same release as the CSS. Add the 10 undesigned flexipages and the two calculator pages to the rollout list explicitly.
Phase 4 — QA & launch (wks 7–8) Contrast QA needs a defined answer for gradient rows before it can pass/fail them (§6.1). Add screenshot-diff over the 12 flexipages + blog/contact/calculator templates, since no design covers the latter.

Net read. The plan is a solid delivery document that closes most of the component-level gaps I raised and correctly flags its own open dependencies (icons, container width, nav rule, re-validation). It does not yet close the two that determine whether the system holds together: the semantic/per-surface token tier and the flexipage row inventory. Both are cheap to add now and expensive to retrofit after Phase 2.

12. Decision tables — backgrounds & rows

One row per CMS option, with where it is used today, whether a new design exists, and a single recommended action. Built for sign-off: agreeing these two tables settles most of §7 and §10. Usage figures are markup-level counts across all 12 live flexipage URLs (method in §14.5).

12.1 Table A — the eight row background options

Background optionUsed?WhereNew design covers it?Recommendation
(default) White
bg-white · #FFFFFF
29 rows Every flexipage; the default surface Yes — “Background primary” + full light-surface foregrounds, buttons, cards, accordion Keep as-is
Only change: heading colour teal → navy, body font swap.
Dark Blue
bg-dark-blue · #144056
14 rows Every flexipage — the alternating dark band Yes — navy surface with its own button, card, accordion and focus-ring rules Keep as-is
Outstanding: a link colour for navy (#0F6CB6 is 2.02:1 there).
Gradient Light
bg-gradient-light · #d5e0fa → #cceaff
5 rows The FAQ accordion row on bin-lookup, cascading, revenue-protect, smart-split, tokenisation Component yes, surface no — light gradients are deleted from the palette, but the navy-on-light accordion variant is designed Remap surface
Point these five rows at Surface tint 1 #DCE2E6 (navy text 8.47:1) or tint 2 #F3F5F7 (10.13:1), then retire the option. No new design needed.
Gradient Dark
bg-gradient-dark · #144056 → #428AC9
1 row Card Payments, final row (“Flexible Integration Options”) Token yes, rules no — Gradient 1 survives, but with no content-safe contrast band Remap to navy — reserve Gradient 1 for heroes/full-bleed.
Evidence for the decision is in the screenshot below: the teal heading is 4.71:1 at the top of the row and 1.57:1 at the bottom.
Grey
bg-light-grey · #f7f7f7
0 rows Nowhere in flexipage content (the class appears only in CSS; grey is used by non-flexipage sections such as the footer help band) Palette has cool tints instead Remove
If a light-tint band is wanted later, it comes back as “Surface tint”, not warm grey.
Gradient Mid
bg-gradient-mid · #3B5CA7 → #428AC9
0 rows Nowhere as a row. The same gradient is hard-coded as the hero background in HeroSection.styles.js No Remove
Keep it only as the hero token, replaced by Gradient 1.
Gradient Neutral
bg-gradient-neutral · #ddeef9 → #d4fdf4
0 rows Nowhere as an editor choice — but hard-coded into CallToActionRow and used by the Panels row's “Row Gradient White Panels” style No Remove
Depends on retiring the CTA and Panels rows (Table B); remove all three together.
Gradient Extra Light
bg-gradient-extra-light · #ddf1ed → #e9f4fb
0 rows Nowhere. Also the default hero-CTA panel background token No Remove
Repoint the hero-CTA panel to white or Surface tint 2.

Proposed end state — four surfaces: White · Surface tint (replaces Grey and Gradient Light) · Navy · Gradient 1 (hero and full-bleed decoration only, not a content-row option). That removes four of eight CMS options, needs no new component designs, and cuts the token matrix from 8 surfaces to 3 content surfaces — which the proposed system can already fill once the semantic tier exists (§11.3.1).

Where the four live backgrounds appear

White background row on Card Payments
White — 29 rows. Card Payments, AltRow. Note the teal CTA button (white label on #46AC92 = 2.77:1, fails AA) and the grey blockquote box, neither of which the new system specifies for this surface.
Dark blue background row on Card Payments
Dark Blue — 14 rows. Card Payments, AltRow. White heading + white body + tinted quote box; closest match to the designed navy surface.
Gradient light accordion row on Cascading
Gradient Light — 5 rows, always the FAQ accordion. Cascading. The accordion itself is designed; only the surface underneath needs remapping.
Gradient dark row on Card Payments
Gradient Dark — 1 row. Card Payments. The teal heading sits at 4.71:1 against the navy top and 1.57:1 against the blue bottom — the position-dependent contrast problem in one screenshot.

12.2 Table B — the eight row types (plus hero and rich-text elements)

Answer to “are all 8 rows used?” — no. Four are used, four have never been used in production.

Row typeUsed?WhereNew design?Recommendation
HeroSection12 / 12 pages Every flexipage Desktop only Needs design — tablet + mobile hero (the audit's own spacing defect), plus the hero-video, hero-icon and hero-panel-links variants that the CMS exposes.
AltRow (image/text split)39 instances All 12 pages — the workhorse row Yes — Split Content Section (48px gap, 570px image, tint box, no accent colours) Has its design — build as specified. Confirm the multi-item alternating stack inherits the same spec.
AccordionRow5 instances bin-lookup, cascading, revenue-protect, smart-split, tokenisation (FAQs) Yes — light and navy variants, jade-light open header Has its design — plus the surface remap from Table A. Intro-copy block above the accordion needs no more than body styles.
CopyRow (rich text, centred or left)5 instances cascading, revenue-protect, smart-split (centred on navy); payment-orchestration-platform ×2 (centred on white) No Needs design: centred text measure, inline CTA placement, and the rich-text elements it can contain (see bottom rows).
WidgetRow → Logos Map1 instance Alternative Payment Methods (“Truly Global Processing Locally”, interactive acquirer/APM map + filter) No — the APM redesign replaces it with a static logo grid Decide + design: keep the interactive widget (needs a design incl. the select and ACQ/APM toggle) or accept the static grid as a deliberate feature removal.
WidgetRow → POP Diagram1 instance payment-orchestration-platform No Needs design — the most complex interactive component on the site and the only thing on that page; it cannot inherit the two designed page patterns.
WidgetRow → BNPL Logos Slider0 Never usedNo Remove
PanelsRow (2/3-col panels, 3 row styles)0 Never used Feature cards are the visual successor Remove — if a panel grid is wanted later, rebuild it as Feature Cards, which are designed. Removing this also removes the “Row Gradient White Panels” style that depends on Gradient Neutral.
TestimonialsRow (carousel)0 Never used Case Card covers testimonial content, not the carousel row Remove — drops the react-slick dependency from the flexipage bundle.
TwoColumnsRow (+ SubTitle ring ornament)0 Never usedNo Remove — and with it the SubTitle ornament's per-surface tokens.
CallToActionRow (label + tagline + button)0 Never used The page designs end with a different closing-CTA pattern Remove — then design the closing CTA (heading + primary/ghost pair + 3 benefit cards) as a new row if editors need it, since that is what both redesigned pages actually show.
Rich text — blockquote34 instances Every page (the tinted “problem statement” boxes inside AltRows) Partial — Split Content's “10% black / 10% white tint box” is effectively this Confirm mapping, then it needs only per-surface tokens — no new design.
Rich text — bulleted lists191 instances Every page (custom round teal markers) No Needs a rule: marker colour per surface. Teal markers conflict with “jade for buttons only”, so specify navy or cyan.
Rich text — .large / .small buttons36 .large, 0 .small CTA links inside AltRow/CopyRow copy No Map to Primary/Ghost and remove the extra classes from the Bard toolbar, so editors can't create undocumented button variants (this is also what enforces the 19px-bold AA rule).
Rich text — tables (+ responsive card mode)0 Never used, but fully styled with 5 tokens per surface No Remove — or keep the code and accept it is undesigned. Removing deletes 5 tokens × every surface from the matrix.
Rich text — embedded video0 Never used in flexipage content (hero video is separate) Imagery rule only: external host, never uploaded Remove — no design needed either way.

Score after these decisions: 2 rows build as designed (AltRow, AccordionRow) · 4 rows/widgets need design (hero mobile + variants, CopyRow, Logos Map, POP Diagram) · 5 rows retire (Panels, Testimonials, TwoColumns, CallToAction, BNPL slider) · 4 rich-text elements need a rule or a toolbar removal, not a design. That takes the “60% undesigned” figure in §7 down to four genuine design tasks.

The two used rows with no design

CopyRow centred on navy, Cascading
CopyRow — 5 instances. Cascading, centred on navy. No design exists for the centred rich-text block or its inline CTA.
Logos Map widget row on APM
WidgetRow → Logos Map — the interactive region select + ACQ/APM toggle + logo tiles. The APM redesign silently replaces this with a static grid.

12.3 Late addition — /careers-page-test/

In scope and already counted in the tables above (it is one of the 12 flexipages), but it moved while this audit was being written — 3 rows at 15:26, 4 rows by 16:05 on 27 Jul — and it introduces four editorial patterns that appear nowhere else on the site and nowhere in the design system. Worth its own read before sign-off.

What it is structurally: hero (Gradient Mid + diagonal) with 3 hero panel links, then 4 × AltRow, all on white — no accordion, no table, no blockquote, no CTA button anywhere in the page body, and no job-listing component (the repo's src/components/JobOpening is unused here). Page height 5,945px; the last two rows are 1,140px and 1,426px tall.

Pattern introducedDetailDesign system positionRecommendation
Hero panel links (first live use) 3 cards over the hero: gradient-filled circular icon, navy label, trailing arrow, on a pale mint card Not designed as a component — but Feature card small (rectangle icon + bold title + trailing arrow) is nearly the same object; the two designed pages use exactly that treatment in the same position Map to Feature card small — closes the hero-panel gap in §12.2 with no new design. Two conflicts to fix in doing so: the icons are gradient-filled (system says solid only) and the card surface is a pale jade tint (system says jade light is never a background surface).
Emoji as icons in headings 10 of 15 headings are emoji-prefixed h3s — 🎉 🍿 🌍 💰 🏖️ ❤️ 🛡️ 👶 📈 No — the Icons page states no library exists yet and that pictograms should be navy, cyan or a tonal variant Remove — emoji render differently per OS, can't be brand-coloured, and are announced verbatim by screen readers (“party popper We Make Time for Fun”). Replace with the icon set once the icon workstream lands; interim, drop them and keep the text heading.
Long-form editorial column Rows 3–4 stack 7–8 sub-headings plus paragraphs in one text column beside a single image; rows are 1,140–1,426px tall No — Split Content is specified as one title + short copy + bullets against a fixed 570px image Needs a rule, not a new component: either cap Split Content at one heading and split long content across rows, or add a documented “editorial column” variant. Also fix heading levels — the page has 14 h3s under a single h2, so the outline is flat.
Illustration style + assets Flat navy-on-mint SVG illustrations (3), files named Untitled_design__1_.svg …; one raster Retirement_Plan.png at 600×450 displayed 676px wide (upscaled) Imagery rules exist (crop, focal point, responsive sizes, no embedded text) but no illustration style and no mint in the palette Needs a design call: is flat mint illustration part of the brand, or should these become photography/iconography? Also serve the raster at ≥2× or convert to SVG, and rename the assets.
No CTA in the page body A careers page with no “apply”, “see roles” or contact action — only the global header button Closing-CTA pattern exists in both redesigned pages Content fix — add the designed closing CTA (heading + primary/ghost pair). This is the strongest argument for designing that closing block as a reusable row (see the CallToActionRow line in §12.2).
-test slug is live and indexable Present in sitemap-pages.xml, real page title “Careers at APEXX Global | Join Our Team of Payments Experts” Out of design scope Flag to content/dev — rename to /careers/ with a redirect before launch, or noindex it. Not a styling issue, but it will ship as-is otherwise.
Careers hero panels over gradient hero
Hero panel links — gradient-filled icons on pale jade cards. Both details conflict with the new colour rules; the component itself maps cleanly onto Feature card small.
Emoji-prefixed headings on careers page
Emoji-as-icon headings inside an AltRow, beside a flat mint illustration — neither pattern exists in the design system.
Careers page full length
Full page: hero + 4 AltRows on white, 5,945px tall, no in-body CTA.

Process point. This page changed twice during a single day's audit, and it is the only flexipage inventing new patterns. Whatever is agreed from Tables A and B should be applied to the Statamic blueprint before more editorial pages are built this way — otherwise every new page adds undocumented patterns faster than the design system can absorb them. The row and background counts in this document are a snapshot dated 27 Jul 2026; re-run the parse (§14.5) at sign-off.

13. Recommended actions

Sequenced to slot into the Implementation Plan's phases rather than replace them. Items 1–5 below are the plan's “Next Steps” list extended with the three decisions it doesn't currently ask for (rows, widgets, blueprint).

Decisions needed from APEXX / the designer (blocking)

  1. Correct the stack assumption in the plan (no Antlers/Blade; Gatsby + styled-components + headless Statamic) and re-baseline the Phase 0/2 estimates on that basis — plus the plan's own three open items: nav-background rule, executive-headshot treatment, container max-width.
  2. Background reduction — sign off Table A (§12.1). Retire Grey, Gradient Mid, Gradient Neutral and Gradient Extra Light (zero production usage), remap the five Gradient Light accordion rows and the single Gradient Dark row, and reserve Gradient 1 for heroes. End state: White · Surface tint · Navy · Gradient 1 (decorative).
  3. Row reduction — sign off Table B (§12.2). Retire PanelsRow, TestimonialsRow, TwoColumnsRow, CallToActionRow and the BNPL Logos Slider widget (zero production usage); commission designs only for the hero's mobile/variant cases, CopyRow, and the two live widgets.
  4. Widgets. Decide whether the Logos Map and POP diagram survive; if they do, they need designs, and if they don't, the APM/POP pages need replacement content.
  5. Fonts. Confirm Poppins-headings / Nunito-body, and that Ambit is being dropped.
  6. CTA colour. Jade #3F9B83 + mandatory 19px-bold, or jade-dark #317866 for robustness.

Then, in build order

  1. Token layer first. Rewrite FlexipageStyles.js as: primitives (new palette) → semantic tokens (--color--paragraph, --color--headings, …) → 4 surface blocks. Keep the existing custom-property names so row components need no changes. Delete the teal600/teal800 duplicate.
  2. Typography. Replace the headingSizes map with the new scale, add the tablet tier at the documented breakpoints, subset and preload Poppins 600/700 + Nunito Sans 400/500/700, remove Ambit.
  3. Buttons. One component with the 5 states; map .large/.small rich-text classes onto primary/ghost or remove them from the Bard toolbar so editors can't produce undocumented variants.
  4. Statamic blueprint. Prune the background_colour option list and any retired sets in the same release as the CSS, otherwise editors can still select combinations that no longer have styles.
  5. Undesigned-but-surviving elements. Derive tables, blockquote, lists, subtitle ornament and hero-panel styles from the new tokens and get them signed off as additions to the Figma file, so the system stays the source of truth.
  6. Global chrome + mobile hero. Implement nav-matches-hero and fix the mobile hero spacing defect the audit flags; re-check every template, not only the designed ones.
  7. Regression pass. Contrast-audit the four surfaces (automated), then screenshot-diff the 12 flexipages plus the calculator/blog/contact templates, which no design covers.

The efficient sequencing insight: because only 4 of 8 backgrounds and 4 of 8 row types are used in production, the cheapest credible path is constrain first, then implement. Constraining converts most of the “missing design” findings in §7 from build blockers into deletions. Done before the plan's Phase 0, it also shrinks Phase 2 and Phase 3.

Three additions that would make the plan complete, in priority order: (1) a semantic + per-surface token tier on top of its primitive palette (§11.3.1); (2) the flexipage rows added to the Phase 2 component list, or an explicit retirement decision for the four unused ones (§11.2); (3) a Statamic blueprint task in Phase 3 so CMS options and CSS ship together. Everything else in it can proceed as written.

14. Appendix: evidence & screenshots

Figma captures were taken at 100% zoom (anonymous view). Live captures at 1440×900 (full-page) and 390×844 (mobile).

14.1 Proposed system — foundations

Figma colour page: primary and secondary palette
Colour — primary (navy, cyan) and secondary (jade primary/dark/light).
Figma colour page: tertiary, semantic, gradients, neutrals
Tertiary links, semantic error/warning, the two gradient surfaces, and the new cool neutrals.
Figma accessibility usage and rules
Do/Don't rules and the WCAG contrast card (jade on navy fails at 3.28:1).
Alert and warning colours usage notes
Semantic colours are documented as not yet applied to any component.
Typography headings scale
Headings — Poppins across desktop/tablet/mobile (the current build uses Ambit).
Typography stat numbers, links, caption
Stat numbers, text link, footer link, caption.
Body typography scale
Body — Nunito Sans (the current build uses Poppins for body).
Button label and image button typography
Button label: Nunito Sans Bold 19px, fixed at all breakpoints.
Spacing system and layout grid
4pt scale and the Bootstrap-5-style 12-column grid table.
Icons and pictograms design note
Icon library explicitly not defined; recolour shown as before/after only.

14.2 Proposed system — components

Buttons on light background with states
Buttons on light: primary, ghost, text — default/hover/click/focus/disabled.
Nav, carousel, filter tab, image buttons
Nav button, dropdown, carousel arrow, prev/next, filter tab, image button.
Buttons on navy background
Buttons on navy — the only other surface specified. Note the 3.28:1 caveat.
Button design revision notes
Revision notes: 19px bold labels, jade 10% darker, 12/20px padding, 2–4 word CTAs.
Components page overview
Components page: case card, article card, feature cards, accordion, split content.
Feature cards with revision notes
Feature cards — “solid colours only… no gradients”, shown on navy only.
Accordion design revisions
Accordion: white on dark, navy on light, jade-light open state.
Split content section revisions
Split content: 48px gap, 570px image, accents removed, 10% tint box.

14.3 Website audit page

Website audit page overview
Audit page: 10 page redesigns. Only Card Payments and APM are flexipage-driven URLs.
Audit summary and red flag
Summary: nav should match hero background; mobile hero spacing defect; video-in-hero performance red flag.
Card payments redesign top
Card Payments redesign — hero, 3 small feature cards, split content.
Card payments redesign bottom
…FAQ accordion and closing CTA with three benefit cards.
APM redesign top
APM redesign — same kit; the interactive Logos Map is replaced by a static logo grid.
APM redesign bottom
…navy split content and closing CTA.

14.4 Live site today

Live card payments page
apexx.global/card-payments — 4 AltRows (white, dark blue, white, gradient dark) + logos map widget.
Live APM page
apexx.global/alternative-payment-methods — AltRow + Logos Map widget row.
Live cascading page
apexx.global/cascading — includes a CopyRow (centred, navy) and an AccordionRow on gradient-light.
Live payment orchestration platform page
apexx.global/payment-orchestration-platform — the POP diagram widget, undesigned in the new system.
Live insights and dashboards page
apexx.global/insights-and-dashboards — the standard 3-AltRow pattern used by most flexipages.
Live home hero
Home hero — gradient with video; the audit's performance red flag.
Live mobile hero at 390px
Mobile hero at 390px — the spacing issue called out in the audit summary.

14.5 Production row/background inventory (parsed from live HTML)

PageRow sequence (type · background)
alternative-payment-methodsAltRow · white → WidgetRow · logos-map → AltRow · white → AltRow · dark-blue
bin-lookupAltRow · white → AltRow · dark-blue → AltRow · white → AccordionRow · gradient-light
card-paymentsAltRow · white → AltRow · dark-blue → AltRow · white → AltRow · gradient-dark
careers-page-test (newest page — see §12.3)AltRow · white ×4
cascadingAltRow · white → AltRow · dark-blue → AltRow · white → CopyRow · dark-blue centred → AccordionRow · gradient-light
consolidated-reportingAltRow · white → AltRow · dark-blue → AltRow · white
dynamic-routingAltRow · white → AltRow · dark-blue → AltRow · white
insights-and-dashboardsAltRow · white → AltRow · dark-blue → AltRow · white
payment-orchestration-platformCopyRow · white centred → WidgetRow · POP diagram → AltRow · white → CopyRow · white centred → AltRow · dark-blue
revenue-protectAltRow · white → AltRow · dark-blue → AltRow · white → CopyRow · dark-blue centred → AccordionRow · gradient-light
smart-splitAltRow · white → AltRow · dark-blue → AltRow · white → CopyRow · dark-blue centred → AccordionRow · gradient-light
tokenisationAltRow · white → AltRow · dark-blue → AltRow · white → AccordionRow · gradient-light

Totals: AltRow 40 · CopyRow 5 · AccordionRow 5 · WidgetRow 2 · PanelsRow 0 · TestimonialsRow 0 · TwoColumnsRow 0 · CallToActionRow 0. Backgrounds in use: white 29 · dark-blue 14 · gradient-light 5 · gradient-dark 1 · grey 0 · gradient-mid 0 · gradient-neutral 0 · gradient-extra-light 0. Rich-text elements in use: blockquote 34 · unordered lists 191 · tables 0 · embedded video 0.