Design System · April 2026

Mullin360 Brand Identity.

This document is the source of truth for tokens, components, and patterns used on mullinv1.netlify.app. Every value shown is extracted directly from index.html and its sibling pages — so what you see here is what renders in production. Each section is structured to map cleanly onto Figma frames: one page per foundation, one frame per component, and one master file for patterns.

Maturity score
62/100
Consistent visual language, tokenization gaps.
Components
11
9 documented · 2 partial (tmember-placeholder, scroll hint)
Tokens
47
14 color · 2 type families · 17 spacing · 3 radius · 4 shadow · rest: motion/border
Top risks
3
WCAG contrast · missing focus rings · no spacing scale

Foundations · 01

Colors

Two intentional families: a deep green brand spectrum and a warm-leaning neutral. The palette is small by design, but opacity variants are overused — see the Gaps section.

Brand · Green

#0E6133
Green
--green
Primary brand, CTAs, links
#0A4A27
Green Deep
--green-deep
Hover, stats section bg
#2C7A4B
Green Soft
--green-soft
Secondary accent
#7EA08A
Green Muted
--green-muted
Subtle text, muted borders
#DCE9E1
Green Pale
--green-pale
Italics on dark, accents

Neutrals

#FFFFFF
White
--white
Primary surface
#F8FAF8
White Soft
--white-soft
Subtle section tint
#EEF3EF
Mist
--mist
Section backgrounds
#E1E9E3
Mist 2
--mist-2
Alt section bg
#D5DED8
Line
--line
Dividers, input borders
#86958D
Stone Light
--stone-light
Placeholder, tertiary text
#5F6F66
Stone
--stone
Body on light bg
#1A2E22
Charcoal Soft
--charcoal-soft
Headings alt
#102218
Charcoal
--charcoal
Primary text, footer bg
#f0c060
Warn / In-progress
undefined
Coming-soon, status not tokenized

Common overlays / tints used in the site

ValueWhereNote
rgba(255,255,255,.78)Nav links default
rgba(255,255,255,.62)Footer linksBelow 4.5:1 on charcoal
rgba(245,240,232,.55)Card meta textcream-leaning white; off-palette
rgba(14,97,51,.35)Button hover shadow
rgba(14,97,51,.08)Field focus ring
rgba(220,233,225,.25 / .4)Status-badge bordersTwo similar variants; consolidate
Heads-up · unused / alias tokens

--cream (#0c1a11), --terra (alias of --green), and --terra-light (alias of --green-soft) are declared but never referenced. Delete from :root or repurpose as canonical names — aliases fragment the token graph.

Foundations · 02

Typography

Two families: Cormorant Garamond for expressive display, DM Sans for the rest. The display voice leans 300-weight and uses italicized ems in green-pale for emphasis. Body sizing is fluid via clamp() — good in practice, but no named scale means every headline picks its own clamp range.

Font families

Cormorant Garamond
--font-d · 300 / 400 / 500 / 600 · italic 300,400
Display serif. Used for h1, h2, project names, team names, stat numerals, blockquotes.
DM Sans
--font-b · 300 / 400 / 500 · no italics imported
UI sans. Body, labels, buttons, eyebrows, metadata.

Display specimens (Cormorant)

Display · Hero XL
clamp(3.8rem, 8.5vw, 7.2rem)
weight 300 · line-height 1.02
Build boldly, where
others hesitate.
Display · Hero
clamp(3rem, 5.5vw, 4.5rem)
weight 300 · line-height 1.05
Let's talk.
Section Title
clamp(2rem, 3.5vw, 2.75rem)
weight 300 · line-height 1.2
Our vision for the corridor
Stat numeral
3.5rem · weight 300 · line-height 1
10
Project name
1.5rem · weight 400
Scottsdale Autoshow
Blockquote
italic 400 · line-height 1.5
"We build neighborhoods, not parcels."

UI specimens (DM Sans)

Lead
1.22rem · weight 300 · line-height 1.6
Commercial and mixed-use developments across the Sun Corridor.
Body
1rem · weight 400 · line-height 1.7
We develop and operate commercial real estate in partnership with communities, tenants, and investors.
Small / meta
.85rem · weight 400 · line-height 1.5
Scottsdale · Est. 2018
Eyebrow / label
.65rem · uppercase · letter-spacing .25em · weight 500
PROJECTS · SUN CORRIDOR
Nav link
.7rem · uppercase · letter-spacing .16em
PROJECTS
Button text
.72-.85rem · uppercase · letter-spacing .12-.14em · weight 500
GET IN TOUCH

Letter-spacing cheat sheet

Token candidateValueUsed in
--tracking-hero.32emHero eyebrow
--tracking-label.25emSection labels, eyebrows
--tracking-footer.2emFooter heads, status, info labels
--tracking-form.18emForm labels
--tracking-nav.16emNav links, filter buttons
--tracking-btn.14emPrimary buttons
--tracking-btn-sm.12emSmall buttons, CTA links
Consolidate Seven adjacent values is too many. Recommend collapsing to 3: .12em (buttons), .18em (labels), .28em (eyebrows).

Foundations · 03

Spacing

The site uses 17 distinct spacing values without a declared scale. Most values fall on or near a 4px grid, but there's meaningful drift — values like .45rem and .55rem exist for one-off nudges. Below is the observed spectrum and the recommended reduced scale.

Observed spacing (in rem, 16px base)

.25rem
4px
.5rem
8px
.75rem
12px
1rem
16px
1.25rem
20px
1.5rem
24px
2rem
32px
2.5rem
40px
3rem
48px
4rem
64px
5rem
80px
6rem
96px

Drift Non-conforming values seen in production: .2rem, .3rem, .4rem, .45rem, .55rem, .6rem, .8rem, .85rem, .9rem, 1.1rem, 1.2rem, 1.75rem, 3.5rem, 4.5rem. Recommend snapping to the 12-step scale above.

Foundations · 04

Border radius

Three effective values. Sharp corners are the default — radii are used sparingly for "click" affordance on primary buttons and 100% for dots/avatars.

0
--radius-none
0
Cards, form inputs, submit btn
6px
--radius-md
6px
Primary buttons (.btn-terra, .btn-sage)
--radius-round
50%
Dots, avatars, slide indicators
Inconsistency
Contact form submit button has 0 radius while hero buttons have 6px. Decide which is canonical and apply everywhere.

Foundations · 05

Shadows / elevation

Shadows are used as motion accents (on hover / lift) rather than for static elevation. No card shadow tokens exist — cards use borders instead.

--elev-nav0 6px 18px rgba(0,0,0,.18)
--elev-cta0 14px 34px rgba(14,97,51,.22)
--elev-cta-hover0 15px 35px rgba(14,97,51,.35)

Foundations · 06

Borders

WidthColorUsed for
1px solidvar(--line) #D5DED8Form fields, info blocks, cards, dividers
1px solidvar(--green)Field focus state
1px solidrgba(245,240,232,.08)Footer bottom
2px solidvar(--green)Blockquote left border
2px solidrgba(255,255,255,.75)Secondary button (.btn-sage on dark)
2px solidrgba(14,97,51,.18)Avatar placeholder

Foundations · 07

Motion

Fourteen distinct duration values is too many. Recommend collapsing to a five-step scale (100 / 200 / 350 / 600 / 1000ms) plus two easings.

Durations observed

DurationUsed inRecommended
.15sButton active state100ms
.2s / .3sHover colors, filter active200ms
.35s / .4sButton transforms, nav scroll350ms
.5s / .6s / .7sImage zoom on hover600ms
.8s–1.2sPage reveal / fade-up1000ms
1.8s / 2.2sScroll arrow bounce (ambient)1800ms (keep)

Easings

NameValueUsed for
--ease-out-sitecubic-bezier(.22, 1, .36, 1)Reveals, card image zooms
--ease-out-btncubic-bezier(.23, 1, .32, 1)Button transforms on hover
--ease-stdease / ease-in-outHover color swaps (consolidate)

Good prefers-reduced-motion: reduce is respected across all keyframe animations.

Foundations · 08

Breakpoints

NameQueryDrop-ins
desktop (default)3-col grids, 5rem section padding
tablet(max-width: 1024px)2-col grids, 2rem nav padding, split sections stack
mobile(max-width: 640px)1-col grids, nav links hidden, hero type shrinks

Gap No tablet-portrait (768px) breakpoint — layouts either commit desktop or mobile behavior in that range.

Components · 02

Buttons

Four variants in production. Inconsistent radius between .btn-terra (6px) and .btn-submit (0) is the top fix.

On light surface

On dark surface

VariantPaddingRadiusSizeHover
.btn-terra1.25rem 3rem6px.85rem · .14embg → green-deep · ty(-6px) · shadow
.btn-sage1.25rem 3rem6px.85rem · .14embg tint · border → green · ty(-4px)
.btn-submit1rem 2.5rem0.72rem · .12embg → green-deep · ty(-1px)
.btn-cream1rem 2.5rem0.72rem · .12embg → green-pale
DisabledNot defined
FocusNot defined
LoadingNot defined

Components · 03

Form fields

Label + input stacked vertically. Focus ring is good; error and success states don't exist yet.

States
Default1px solid #D5DED8 · .8rem 1rem padding
Focusborder → --green · shadow 0 0 0 3px rgba(14,97,51,.08)
ErrorNot defined — add: border → #a3262c · inline message .8rem
DisabledNot defined — add: bg → --mist · color → --stone-light
Placeholdercolor --stone-light · ~4.1:1 contrast, borderline

Components · 04

Filter chips

Components · 05

Status badges

Complete In progress Coming soon

Components · 06

Info blocks

Address7580 E Gray Rd
Scottsdale, AZ 85260
Phone+1 (480) 555-0199

Components · 07

Venture links

Components · 08

Project cards

Hover-only affordance The arrow icon and status badge only appear on hover. Consider making them visible on touch devices.

Components · 09

Team cards

Jim Mullin
Principal
Jacqueline Swanson
Director of Operations
Mark Simmons
Development

Patterns · 01

Hero

SCOTTSDALE · EST. 2018

Build boldly, where others hesitate.

Commercial and mixed-use developments across the Sun Corridor.

Patterns · 02

Split section

"Built on place, not hype."

OUR VISION

Long-horizon investment in the Sun Corridor.

We build neighborhoods, not parcels. Every project is shaped by climate, community, and what's already there.

Our portfolio spans automotive, hospitality, and mixed-use — always with a 20-year view.

Patterns · 03

Stats strip

10
Projects
20+
Years
1.2M
SqFt
3
Counties

Patterns · 04

Pillars

OUR APPROACH

How we build, summarized.

01

Climate-first design

Desert-tuned massing, shade, and thermal envelope decisions at land-entitlement stage.

02

Community alignment

City conversations start before the survey. Projects are shaped by what the place already tells us.

03

Long-hold economics

We develop to own, not to flip. That changes every material decision.

Audit · 01

Maturity score · 62/100

CategoryScoreNotes
Color tokens8 / 10Well-structured; three unused aliases to remove
Typography tokens7 / 10Good families, no named size scale
Spacing tokens5 / 1017 observed values, no declared scale
Radius tokens6 / 103 values, inconsistent between button variants
Shadow tokens6 / 103 in use, none named; no card elevation
Motion tokens5 / 1014 durations — consolidate
Component completeness6 / 10Missing: focus, error, disabled, loading states
Accessibility5 / 10Contrast fails in footer; focus rings absent
Documentation4 / 10This doc closes the gap
Code ↔ design parity7 / 10Good — tokens in CSS variables

Audit · 02

Gaps · hardcoded & inconsistent values

Hardcoded pixel values (should be tokens)

ValueWhereIssue
20pxGrid gaps across projects/team/galleryRecommend --space-5 (20px) token
34 / 30 / 26pxNav logo height at 3 breakpointsExtract to --nav-logo-h
420 / 380 / 280 / 300pxCard image heightsDefine --card-media-h tokens
60pxJS scroll thresholdExpose as data-attribute or token
.45rem / .55rem / .85remVarious off-scale spacingSnap to 4px scale

Near-duplicates

ItemsRecommendation
--charcoal #102218 vs --charcoal-soft #1A2E22Slight variation, rarely used deliberately. Consider dropping one.
rgba(255,255,255,.78) vs .62 vs .55 vs .5Define an opacity scale: --opacity-primary .88, --opacity-muted .66, --opacity-subtle .4
Easings cubic-bezier(.22,1,.36,1) vs (.23,1,.32,1)Nearly identical — collapse to one named easing
--terra, --terra-light, --creamUnused aliases — delete from :root

Missing component states

ComponentMissing
ButtonsFocus ring, disabled, loading
Nav linksFocus ring
Project cardsFocus ring, keyboard-visible status/arrow
Form fieldsError, success, disabled
Filter chipsFocus ring

Audit · 03

WCAG contrast spot-checks

AA pass ≥ 4.5:1 Borderline Fail
PairForegroundBackgroundRatioStatus
Body on white--stone #5F6F66#FFFFFF~5.5:1AA
Labels on white--stone-light #86958D#FFFFFF~4.1:1Borderline large-text only
Nav linksrgba(255,255,255,.78)#102218 (scrolled)~6.1:1AA
Footer linksrgba(255,255,255,.62)#102218~3.8:1Fail 4.5:1
Footer copyrightrgba(255,255,255,.5)#102218~2.9:1Fail
Card metargba(245,240,232,.55)pcard overlay dark~3.5:1Large text only
Green-pale on green#DCE9E1#0E6133~2.1:1Decorative only — don't use for text
#f0c060 on dark#f0c060rgba(0,40,32,.97)~7.2:1AA

Audit · 04

Priority actions

P0 · this sprint
  1. Lift footer link opacity from .62.78; copyright to .72.
  2. Add :focus-visible ring to buttons, nav links, cards, filter chips (2px --green-pale outline, 2px offset).
  3. Unify button radius — decide 0 or 6px and apply to all four variants.
P1 · next sprint
  1. Publish a 12-step spacing scale and codemod off-scale values.
  2. Collapse 14 motion durations → 5 (100/200/350/600/1000ms).
  3. Consolidate letter-spacing values from 7 → 3.
  4. Define error / disabled / success states for form fields and buttons.
P2 · nice to have
  1. Add a 768px tablet-portrait breakpoint.
  2. Extract image-height tokens for media cards.
  3. Remove unused aliases --cream, --terra, --terra-light.
  4. Add skip-to-content link on every page.
Metrics to track post-fix
  • Axe Core failures: should reach 0
  • Unique spacing values: < 14
  • Unique motion durations: < 6
  • CSS custom properties with 0 references: 0

Delivery · Figma

How to drop this into Figma

Three realistic paths, in order of effort:

A · html.to.design plugin

Install html.to.design in Figma (free tier covers single-file docs). Paste this document's URL (or drag the file) — it auto-generates a Figma page with real frames and text layers. Best one-click option.

B · Tokens Studio import

I can spin up a design-tokens.json matching W3C DTCG format from the values in this doc. Load it into Tokens Studio for Figma. You'll get colors + typography styles + spacing variables wired to Figma variables in about 5 minutes.

C · Screenshot + rebuild

Low-tech but reliable: take screenshots of each section, paste onto a Figma page for reference, and rebuild natively. Best if you want clean Figma components from day one.

Say the word ("generate tokens.json") and I'll produce the file. Likewise if you want a Figma