Design System Audit
edgehill.ac.uk · Audited 5 November 2026

Strong brand, loose system.

This audit covers the live design system behind edgehill.ac.uk: the ehu-neon-theme WordPress theme and the ehu-blocks component plugins. It looks at tokens, typography, colour, layout, components, accessibility and CSS health.

Jump to priority actions →
Screenshot of the edgehill.ac.uk homepage hero: a deep purple header, a large white headline, a lime-green Open Day button and a heliotrope course-search band.
Scope: 5 page templates (home, courses, study, news, departments) · 34 stylesheets (≈416 KB) · 6,299 CSS declarations · computed styles from live Chrome
01 · Executive summary

Summary

49/100
System maturity

The brand is clear and distinctive. The way it is coded is not consistent.

The newer “neon” palette is recognisable and confident: deep purple, heliotrope, grass green, square corners and offset block shadows. Underneath it, though, the token layer has two competing colour namespaces, a semantic layer that collapses into a few hex values, conflicting redefinitions, and widespread hardcoding of type, spacing and motion values. Components are well chosen for a university site. Their states, variants and documentation are uneven.

Brand expression
8.5
Component coverage
6.5
Accessibility foundations
6
Typography system
5
Colour tokens
4.5
Spacing & layout
4
Elevation, radius & motion
4
CSS health & performance
3.5
Breakpoints
3
Governance (public evidence)
4
164custom properties defined
7tokens defined twice with conflicting values
76distinct font-size values (12-step scale defined)
317!important declarations
236distinct padding / margin / gap values
77distinct media queries
82%of colour declarations use a token (good)
0uses of the defined motion tokens
02 · Token architecture

Three token layers that overlap

The site's CSS loads three overlapping vocabularies, and different components draw on different ones.

--ehu-color-* · brand primitives

20 well-named primitives (purple, heliotrope, grass-green, maple-red…). Defined in ehu-wordpress-colors.css. This is the right foundation.

--ehu-colors-* · legacy semantic

~80 aliases (primary-darkest, notice-warning-lighter, heritage-*) left over from an earlier palette and remapped to the neon values. Many resolve to the same hex value.

--wp--preset--* · WordPress core

The editor palette still exposes WordPress defaults (vivid-cyan-blue, pale-pink, luminous-vivid-amber), plus primary:#fff and secondary:#2D2926, a legacy charcoal.

Naming consistency

IssueEvidenceRecommendationSeverity
Singular and plural namespaces side by side--ehu-color-primary vs --ehu-colors-primary, both #3a0c51Keep --ehu-color-* for primitives. Add --ehu-role-* (or --ehu-sys-*) for semantics. Deprecate -colors-.High
“Heritage” names pointing to neon valuesheritage-purple → #3a0c51, heritage-yellow → marigoldRename by role, not by history. Map old names through a deprecation alias file.Med
Names that don't match the value--ehu-colors-sand = #ffba1b (marigold). --ehu-font-family-serif = a sans-serif stack. secondary-red-light = heliotrope (purple).Audit every alias against its value. Rename or remove the misleading ones.Med
Component tokens without a prefix--border-color, --padding, --font-size:18px, --text-color:#111 (TablePress / theme)Scope component tokens: --ehu-table-border etc.Low
Two size vocabulariesT-shirt sizes (xs…xxxxl, hero-plus) alongside WP numeric presets (spacing--20…80)Pick one. Numeric steps scale better than xxxxl.Low

Broken references

These tokens are referenced with var() but never defined in any stylesheet the site loads, so they silently fall back to their initial value:

--ehu-color-suffragette   --ehu-font-size-md   --ehu-cover-title-width (may be set inline per block)

66 --ehu-* tokens are defined but never referenced. Most are the duplicated -dark/-darker/-darkest steps.

03 · Colour

Colour

These are the 20 brand primitives in --ehu-color-*. Each tile shows the colour's contrast against white and black.

Aa 15.5
Purple / primary#3a0c51 · white ✓ AAA
Aa 5.8
Violet#8c40c4 · white ✓ AA
Aa 6.4
Heliotrope#d883ff · on white ✗ 2.4
Aa 13.7
Maroon#53133e · white ✓ AAA
Aa 11.5
Grass green#baf02d · on white ✗ 1.4
Aa 4.7
Fern green#1e8443 · white ✓ AA
Aa 13.0
Forest green#12372e · white ✓ AAA
Aa 18.7
Marine blue#00044c · white ✓ AAA
Aa 4.0
Iris blue#4d75ff · white ⚠ large only
Aa
Sky blue#81d5ff · on white ✗ 1.6
Aa 12.3
Marigold#ffba1b · white ✗ 1.7
Aa 4.2
Maple red#e04528 · white ⚠ large only
Aa 21
Black#000
Aa 5.7
Black 60#666 · on white ✓ AA
Aa
Black 30#b3b3b3 · on white ✗ 2.1
Aa
Black 10#e6e6e6 · surfaces only
Key finding: the semantic ramps don't vary. For example, primary, primary-dark, -darker, -darkest and -accent all equal #3a0c51, and all seven notice-warning-* steps equal #ffba1b. Hover and active states built on these tokens therefore show no visible change, and a designer choosing “darker” in the editor gets the same colour.

Collapsed ramps

Semantic groupSteps definedDistinct valuesResolves to
--ehu-colors-primary*83#3a0c51 ×5, #8c40c4 ×3, #d883ff ×1
--ehu-colors-notice-warning*71#ffba1b
--ehu-colors-secondary-yellow*71#ffba1b
--ehu-colors-notice-error*73#e04528 ×5, #53133e (maroon), #d883ff (a purple used as “lightest error”)
--ehu-colors-secondary-green*72#1e8443, #12372e
--ehu-colors-neutral*94dark = darker = darkest = #b3b3b3. lighter = lightest = tabs = #fff
--ehu-colors-link*41#3a0c51: no visited, hover or active difference

Conflicting definitions

ehu-cover.css redefines seven global tokens with values from the previous palette. Which value wins depends on stylesheet load order and specificity, so pages that load the cover block may render differently from pages that don't.

Tokenehu-wordpress-colors.cssehu-cover.css
--ehu-colors-heritage-purple■ #3a0c51■ #5f295f
--ehu-colors-primary-light■ #8c40c4■ #875f87
--ehu-colors-deep-purple■ #3a0c51■ #21191c
--ehu-colors-sand■ #ffba1b■ #f0d283
--ehu-colors-outline-yellow■ #ffba1b■ #fedd00
--ehu-colors-notice-warning■ #ffba1b■ #dba617
--ehu-colors-text-black#000#1d1d1d

The legacy translucent overlays --ehu-trans-primary (rgba 95,41,95), --ehu-trans-blue and --ehu-trans-green are also still built from the old heritage hues.

Hardcoded colour

82% of the 1,083 colour declarations use var(), which is a solid result. The other 73 contain raw hex values (50 distinct). Notable ones: #ffe63c, #ed1f34 and #f9effb, which are not in the palette. There are also 11 different light greys (#ddd, #eee, #f0f0f0, #f8f8f8, #fafafa, #e0e0e0…) and un-themed vendor blues in TablePress (#d9edf7, #049cdb).

Contrast: pairings used on the site

White on Purple15.5:1 AAA
Heliotrope on Purple6.4:1 AA
Purple on Grass11.5:1 AAA
Forest on Grass9.7:1 AAA
White on Violet5.8:1 AA
White on Fern4.7:1 AA
White on Maple4.2:1 Large only
White on Iris4.0:1 Large only
White on Marigold1.7:1 Fail
Heliotrope on White2.4:1 Fail
Black 30 on White2.1:1 Fail
Sky on White1.6:1 Fail

Recommendation: publish an approved-pairings matrix and limit text-on-colour combinations to it in the block editor. Heliotrope, grass, sky and marigold should be documented as surface colours, never text on white. Maple red as an error colour is only safe at ≥24px (or ≥18.66px bold), so add a darker error-text token such as #b8321a.

04 · Typography

Typography

The typeface is Caslon Doric, served from Adobe Fonts in weights 300–700, with Public Sans as the fallback. The geometric grotesque suits the neon brand well.

The tokenised scale is a clean 1.2 minor third on an 18px root. The CSS also contains a second 1.25 major third scale (1.563, 1.953, 2.441, 3.052rem) and dozens of one-off sizes.

Font-family declarations

StackUses
'Open Sans' (not loaded)20
var(--ehu-font-family-primary)14
'Public Sans' on its own12
Caslon Doric, Public Sans (+ serif / Montserrat / Inter variants)16

Body text falls back to serif even though both named faces are sans-serif. If Adobe Fonts fails, users may see Times. Two icon fonts load as well (Font Awesome 6 Pro and Google Material Icons).

Defined scale (--ehu-font-size-*)

hero-plus6rem · 108pxAa
hero3.31rem · 60pxOpen Day
xxxxl2.488rem · 45pxHighlights
xxxl2.074rem · 37pxJoin us in January
xxl1.728rem · 31pxResearch at Edge Hill
xl1.44rem · 26pxAwards and recognition
lg1.2rem · 22pxCard heading sample
base1rem · 18pxBody copy at light 300 weight
sm.833rem · 15pxMeta and captions
xs.694rem · 12.5pxLegal / tags

Usage against the scale

PropertyToken definedUses via tokenHardcodedNotes
font-size12 steps~104 (40%)~157 · 64 distinct values.875rem ×20, 1.25rem ×12, 1.5rem ×11, plus px values (16, 20, 28, 35, 150px)
font-weight5 steps93 (55%)75Raw 700 appears 47 times
line-height6 steps8 (13%)~52 · 17 distinct1.15, 1.2, 1.25, 1.55, 1.9, 2.2, 20px, 6rem…
letter-spacing3 stepsrare——

Rendered headings on the homepage

ElementSize / weight / line-heightFinding
body18px / 300 / 1.55Med Light 300 weight for long-form body text reduces legibility, especially on low-DPI Windows screens. Consider 400.
h1 (hero)59.6px / 700 / 1.25Matches hero. Good.
h2 · section43.9px / 500 / 1.2High Three H2 treatments on one page (sizes 44, 37 and 26px, weights 500, 600 and 400). Heading level is being used for styling rather than structure.
h2 · promo37.3px / 600 / 1.2
h2 · news25.9px / 400 / 1.2
h3 · cards18px / 500 / 1.2Low Same size as body copy, so the hierarchy depends on weight alone.
05 · Spacing, layout & breakpoints

Spacing & layout

Two spacing scales

EHU tokensWP presets
xs 0.25rem20 · 0.44rem
sm 0.75rem30 · 0.67rem
md 1.5rem40 · 1rem
lg 3rem50 · 1.5rem
xl 4rem60 · 2.25rem · 70 · 3.38rem · 80 · 5.06rem

The EHU scale is used 87 times across 1,292 spacing declarations (under 10% of non-zero values). In practice the de facto rhythm is .75rem / 1.5rem / 3rem, which matches the tokens but is typed by hand. There are 236 distinct padding, margin and gap values in total, including 12px, 24px, .375rem, 1.2rem and 2.5rem.

Content width is 1200px (--wp--style--global--content-size), which is sensible.

Breakpoints: 77 distinct media queries

Breakpoints cluster in groups of values one pixel apart, a sign that each component was written independently:

IntendedValues actually used
Small320/321, 389/390/391, 499, 600, 680
Tablet766, 767, 768, 769
Laptop1000, 1023, 1024, 1025, 1026
Desktop1142, 1143, 1144, 1441, 1500, 1501, 1520, 1601, 1919

Overlapping min/max pairs (e.g. max-width:767px vs max-width:766px) leave 1px gaps where neither rule applies. Standardise on 4–5 breakpoints (e.g. 390, 768, 1144, 1500) as Sass/PostCSS custom media.

06 · Radius, elevation, motion, layering

Shape & motion

Signature: the offset block shadow

The coloured hard shadow (var(--ehu-color-*) -18px 18px) used on images and promo panels is the most distinctive element of the neon look. It is used with five colours but is not tokenised. Promote it to --ehu-shadow-offset-{sm,lg} with a colour variable.

Radius: square by intent, not by rule

Most elements have 0 radius, which is the brand intent. But 7 other values exist (3px, 4px, 5px, .3125rem, .625rem, 50px, 50px 50px 50px 0). Define --ehu-radius-none and --ehu-radius-pill only.

Shadows: 17 bespoke values

WordPress shadow presets (natural, deep, sharp, crisp, outlined) are defined but used 0 times. Soft drop shadows such as 0 4px 8px rgba(0,0,0,.2), 0 6px 20px… clash with the flat brand.

Motion tokens unused

--ehu-transition-fast and -normal are defined but never used. There are 24 distinct transition values (.2s–1s), and most use transition: all. Only 1 of 34 stylesheets respects prefers-reduced-motion.

z-index

There are 16 distinct values: 1, 2, 3, 4, 5, 9, 10, 70, 75, 100, 999, 10000, 100000, 999999 and others. Replace them with a named layer scale (base · dropdown · sticky · overlay · modal · toast).

07 · Components

Component inventory

Screenshot of the homepage: a forest-green promo panel with a lime offset frame and lime button, then a Highlights grid of purple event cards with date badges and photo news cards.
Promo panel, buttons and highlight cards on the homepage. The brand reads clearly here.

Components are built as bespoke ehu-blocks (Lazy Blocks) on top of WordPress core blocks. Each ships its own stylesheet. Scores are based on states, variants and token use visible in the CSS.

ComponentStatesVariantsToken useNotesScore
Buttons ehu-buttons✅ hover · ⚠ focus✅ colour ×6, size ×12⚠Hover differs by variant: some use filter:brightness(.85), some underline, some change background with !important. The weight is 600 on “Book” but 400 on “All news”.6/10
Cover / hero ehu-cover✅✅ many❌39 KB of CSS. Redefines global colour tokens (see §03). Two --stage-height values.5/10
Card ehu-card✅ hover✅ event / news✅Good brand use. Card H3s match body size.7/10
Promo panel✅✅ colourways✅Best showcase of the offset shadow. 17 !important.7/10
CTA ehu-cta✅⚠⚠Overlaps with Buttons. Consider merging.5/10
Course search (Algolia)✅—⚠25 KB of separate search CSS with its own greys.6/10
News list · Course list · Subject list · Department list · Research-unit list✅⚠⚠Five list blocks with similar anatomy. A candidate for one ehu-list pattern with modifiers.5/10
Icon panel · Tab heading · Sticky in-page menu⚠⚠⚠Small and focused.6/10
Modal (iziModal)✅—❌93 KB vendor CSS for a 244-byte theme wrapper.4/10
Toast (Notyf)✅✅❌Vendor defaults. Not themed to brand success/error.4/10
Carousel (Slick 1.8.1, CDN)⚠—❌Unmaintained library. Default theme loaded from jsDelivr.3/10
Tables (TablePress)⚠—❌Vendor blue header #d9edf7 / #049cdb, which is off-brand.3/10
Timetable (MP Timetable)⚠—❌Unthemed vendor styling.3/10

Buttons as rendered

Book your Open Day View our courses → All news Search

These are four buttons from one page, with two text colours on the same lime fill, two weights and two paddings. Define primary, secondary and tertiary variants with fixed text colour, weight and padding. Leave background choice to the colourway modifier.

08 · Accessibility foundations

Accessibility

CheckResultStatus
Skip linkSkip Navigation → #content presentPass
Document languageSetPass
Image alt attributes15/15 homepage images have alt textPass
Heading outline10 <h2>s in the header/mega-menu come before the page <h1>Fix
Focus styles172 :focus rules and 30 :focus-visible rules, but 10 outline:none/0. Focus ring colour varies (marigold, primary, default).Review
Reduced motionRespected in 1 of 34 stylesheetsFix
Colour contrastCore pairings pass. Heliotrope, grass, sky, marigold and Black 30 fail as text on white. Maple and iris are AA-large only.Govern
Body weight300 at 18pxReview

This is an automated, foundations-level review. A full WCAG 2.2 AA audit would need keyboard, screen-reader and zoom testing across templates.

09 · CSS health & delivery

CSS health

317 !important

Concentrated in styles.css (87), inline WP styles (87), block-margin.css (40) and customiser.css (30). The theme and the blocks are overriding each other.

34 stylesheets · ~416 KB

Each block loads its own file. Vendor CSS (iziModal 93 KB, Algolia 25 KB) makes up a large share. Slick loads from a third-party CDN.

Admin CSS on the front end

ehu-wordpress-admin.css loads for all public visitors. Scope it to is_admin() / the editor.

10 · Priority actions

Roadmap

The actions are ordered by impact relative to effort. Steps 1–3 fix the foundations, and the rest build on them.

Consolidate colour into two tiers

Keep --ehu-color-* primitives. Create a small semantic tier (text, surface, accent, link, focus, success/warning/error) with real hover/active values. Move all --ehu-colors-* into a deprecated alias file, and remove the conflicting redefinitions in ehu-cover.css.

High
~1 sprint

Replace the WordPress editor palette

Override theme.json so editors see only the neon palette and approved gradients. Remove the core defaults (vivid-cyan, pale-pink…) and the legacy #2D2926.

High
Days

Lock typography to one scale

Use the 1.2 scale only. Remove the 1.25 values and 'Open Sans'. Fix the fallback to sans-serif. Define heading roles (display, h1–h4) with fixed size and weight, and test body text at 400.

High
~1 sprint

Standardise breakpoints & spacing

Use 4–5 named breakpoints as custom media. Replace hand-typed .75/1.5/3rem with spacing tokens using a codemod, and choose one scale (EHU or WP), not both.

Med
1–2 sprints

Tokenise the signature elements

Add offset shadow, underline rule, tag/eyebrow, focus ring (marigold, 3–4px), radius-none/pill, motion durations and z-index layers. Add a global prefers-reduced-motion rule.

Med
Days

Rationalise components

Merge CTA into Buttons with three variants. Unify the five list blocks. Theme or replace the vendor modal, toast, carousel and table styles. Drop Slick.

Med
Quarter

Reduce !important with cascade layers

Introduce @layer reset, wp, tokens, base, blocks, utilities so blocks beat theme defaults by order rather than by force. Bundle the block CSS and stop loading admin CSS on the front end.

Low
Ongoing

Document & govern

Publish a living reference (Storybook or a WP pattern library page) covering tokens, approved colour pairings, component do's and don'ts, and a deprecation log. Add Stylelint rules: no raw hex, no unlisted font sizes, no new !important.

Low
Ongoing
Appendix

Methodology

  • Pages sampled: /, /courses/, /study/, /news/, /departments/
  • All linked stylesheets and inline <style> blocks were downloaded and parsed. Font Awesome and Slick were excluded from the counts.
  • Tokens extracted with regex. Usage counts are approximate and exclude vendor files (iziModal, Notyf, TablePress, MP Timetable, admin) unless noted.
  • Computed styles and screenshots taken from the live homepage in Chrome at 1432px viewport.
  • Contrast calculated with the WCAG 2.x relative-luminance formula.
  • Scores reflect public front-end evidence only. Internal docs and Figma libraries were not available.