Toshi dev style guide
Internal reference — enter the password to view.
Toshi dev style guide
Internal reference for anyone who touches how the site looks — developers, designers, marketers, or apps. Not linked from navigation, not indexed. New here? Read the next section first; it assumes no coding background.
Where these values come from
The one-minute version (no code needed). Every colour and font on toshi.com.au comes from one control panel — Theme settings — like a thermostat for the whole house. A button isn't painted gold; it points at the central "button colour" dial. Turn the dial once and every button everywhere changes.
"Drift" is painting instead of pointing. A colour code (say #CFB091) typed into one section looks identical today — that's the trap. The copy is disconnected: when the dial turns, everything connected updates and the painted copy silently stays behind. No error — the site just stops matching itself.
See it on this page: the button gold changed centrally on 2026-07-05 and every connected button followed — but the hand-painted copies (option-tile hover, sale chips, popup accents) stayed on the old colours until each file was hunted down and repointed that evening. The Custom-setting snapshots below preserve exactly what the mismatch looked like; the hunt they required is the lesson. The final tally of that hunt (2026-07-05/06): roughly 65–70 hardcoded items harmonised to theme tokens across ~18 files — every one a value someone once typed by hand instead of pointing at the dial.
The rule: change colours and fonts in Theme settings — never by typing values into a section, stylesheet, or app dashboard. No dial for what you need? That's a conversation, not a workaround.
For the detail-inclined: values on this page carry one of three tags, and only one of them is live. This page exists to drive everything toward the first one:
Theme setting — rendered live via var(--...), never hand-typed, so these panels can't drift. The source of truth, and the destination everything below is harmonised toward.
Custom setting — a value hand-typed into one section or snippet, quoted verbatim from where the 2026-07-05 audit found it. Deliberate snapshots: they stay as written after the source is cleaned up, so the lesson outlives the fix.
Proposed — a hand-typed candidate that doesn't exist in the theme yet, mostly fixing contrast fails. A pending decision: once approved it's applied as a theme setting and the tag flips to Updated.
Updated — a Proposed that was approved and applied centrally, with the date. The Theme setting panel beside it renders the new value live; the before/after working lives in Key decisions.
Repointed — a Custom setting whose source files now read the token instead of a typed value, with the date. The Custom panel stays as a hardcoded snapshot of what the drift looked like.
Where: Shopify Admin → Online Store → Themes → Customize → Theme settings → Colors / Typography (…/admin/themes/<theme-id>/editor; current IDs in .claude/project-details.md).
Respect it: if a value looks wrong here, fix it in Theme settings (or add a real token in snippets/doc-head-styles.liquid) — never hardcode a workaround. A hardcoded value is a second source of truth the next person won't know to update.
App widgets (Fera reviews): styled inside the app. Colours and fonts go in Fera → Customization → Widget Customization → Advanced → Custom CSS, written against the same var(--...) tokens (they resolve on the storefront). The Basic Customization pickers store disconnected hex/px — sizes, star shape and layout only. Git mirror: agents/reference/fera-reviews-custom.css; keep both in sync.
Key decisions
Deliberate Theme settings changes — what moved, when, why. Before = hardcoded snapshot (keeps the history); after = live token.
toshi_logo_b6c72085…png
The old footer source was only 141×61 px — a hard ceiling. Shopify's CDN can't serve more pixels than the file has, so on a 2× (retina) screen it upscaled to fill a 160px box and went fuzzy. Shown here magnified to ~200px so the softness is obvious.
toshi_Logo_taupe.png (2000×863)
Repointed the footer to the existing hi-res wordmark (same mark, already 2000px in the store — no new asset). sections/footer.liquid now emits an explicit 2× src + 1x/2x srcset, capped at the source width so it never upscales. Crisp on retina.
A logo (or any image) that looks fine on a normal monitor can be soft on retina / high-DPR screens, because those pack ~2× the physical pixels into the same CSS space. An image needs roughly double its on-screen width in real pixels to stay sharp. The footer logo was a 141px file shown in a 160px box — it needed ~320px of data and only had 141.
No CSS, srcset, or theme setting can fix a low-res source — the file is the ceiling. Requesting a bigger ?width= from the CDN just returns the same few pixels. The only remedy is re-uploading a higher-res image (ideally an SVG for a wordmark).
Before uploading a logo: make its longest side at least ~2× the largest box it will ever display in (e.g. a 160px footer slot → 320px+ file; 400px+ is safer). Gotcha: the shared snippets/image.liquid only builds a srcset when Theme setting image_quality ≠ "1" — this store has it at "1", so that snippet emits a bare 1× src. Logos that need retina crispness must hand-roll the 2× <img> (as the header and now the footer do).
Why: the footer wordmark read fuzzy against the crisp header. Root cause confirmed by probing the CDN (read the PNG's real dimensions): header source is 2000px and already sharp; the footer source was genuinely 141px. Changed: sections/footer-group.json image repointed to toshi_Logo_taupe.png; sections/footer.liquid text-block image now renders a direct 2× <img> instead of render 'image' (commit e334160). Dev theme only — LIVE untouched.
#916E4C gold → #736860 logo taupe (links stay gold)#916E4C bg / #FFFFFF text
Pass · 4.6:1
The approved gold (2026-07-05) — passed contrast, but a warm tan that didn't match the logo.
--btn-bg-color (#736860) / --btn-text-color
Pass · 5.4:1
The logo PNG (toshi_Logo_taupe.png) samples to #999089 — a light taupe that fails white text at 3.13:1. #736860 keeps the logo's hue but darkens it just enough to pass, so the button reads as the logo family without overpowering it.
Why: match the logo. The exact logo taupe #999089 can't carry white button text (3.13:1); #5F5956 body-ink charcoal passes (6.9:1) but overpowered the wordmark. #736860 is the middle ground — same hue, legible (5.4:1). Links & nav hover deliberately stay #916E4C gold so inline links keep a distinct accent — this reverses the 2026-07-05 "one accent for buttons + links + nav-hover" premise. Changed: btn_color, btn_color_hover, btn_alt_text → #736860; font_col_link, font_col_nav_hov unchanged. Also updated: the image-with-text-overlay hero-button schema default and the bundle-landing token fallback. Dev theme only — LIVE untouched.
#CFB091 → #916E4C, button text cream → pure white#CFB091 bg / #F8F5EE text
Fail · 1.9:1
The original brand gold — warm, but illegible under its own button text.
--btn-bg-color / --btn-text-color
Pass · 5.4:1
Renders live from Theme settings — if this swatch isn't #736860 on this theme, the change has been reverted or drifted. (Was #916E4C gold 2026-07-05 to 2026-07-07; see the newer decision below.)
Why: WCAG needs 4.5:1 and contrast caps lightness — white text (vs cream) buys the headroom. Superseded 2026-07-07: buttons moved off the gold to #736860 to match the logo taupe (see the newer decision below). Changed: btn_color, btn_color_hover, btn_alt_text (+ border) → #916E4C (now #736860); btn_color_text, btn_alt_bg → #FFFFFF. Also fixes the footer Subscribe button. Dev theme only — LIVE untouched until published. Full working: Colour tokens below.
#B7A6A1 / #CFB091 → #916E4C#B7A6A1 links / #CFB091 nav hover
Fail · 2.3:1 / 2.0:1
Two separate failing accents — a pinkish taupe for links, the old gold for nav hover.
--link-color / --main-nav-link-hover-col
Pass · 4.6:1
Renders live from Theme settings — links and nav hover now share the approved button gold.
Why: on 2026-07-05, links, nav hover and buttons were unified on the approved #916E4C — a single passing gold instead of two extra failing near-golds. Changed: font_col_link #B7A6A1 → #916E4C, font_col_nav_hov #CFB091 → #916E4C. Superseded 2026-07-07 (see newest decision above): buttons moved to the logo taupe #736860; links and nav hover keep this gold, so the accent is now shared by links + nav-hover only. Dev theme only — LIVE untouched.
Borders & radius
rgb(var(--text-color) / var(--divider-opacity))
--btn-border-radius
--sf-card-radius
Minted for the PDP v3 measuring-tip card (16px, assets/toshi-custom.css). Reuse it for any new card surface rather than typing a radius.
Colour tokens
What the Pass / Fail pills mean (no code needed). Each pill scores how strongly text stands out from its background, from 1:1 (invisible) to 21:1 (black on white). The accessibility standard WCAG sets 4.5:1 as the bar for normal text — readable for ordinary ageing eyesight, not just perfect vision.
Who it's for: one in twelve men can't distinguish certain colours, contrast sensitivity declines from about age 40, and every customer is "low vision" on a phone in direct sunlight — exactly where someone buying a baby sun hat is standing. The old gold scored 1.9:1: real shoppers couldn't read "Add to cart" on the button that takes their money. Contrast is a conversion issue before it's a compliance issue.
And it's the law: Australian websites fall under the Disability Discrimination Act, measured against WCAG. 4.5:1 is the minimum, not gold-plating.
Rows read Theme setting → Proposed fix; where the 2026-07-05 audit found a hand-typed copy in the code, a Custom card leads. Pills are WCAG 2.1 ratios (AA: 4.5:1 text, 3:1 large text/UI), snapshotted — re-check after any colour edit.
"Exempt" = fails the ratio without violating WCAG: the rating star (snippets/rating.liquid) is aria-hidden decoration; the visible "4.8 / 5" text carries the rating. Holds only while that number stays visible.
Changing a colour is fine — what matters is where. A hex typed into one section changes only that section. A theme setting changes once, in Theme settings → Colors, and flows into every var(--...) everywhere.
--body-bg-color
The page background every other colour here is checked against.
--text-color
Pass · 6.9:1
Body text.
--heading-color
Pass · 6.9:1
Headings.
rgb(var(--text-color) / 0.7)
Fail · 3.4:1
Soft/muted text — opacity applied on top of --text-color, not a separate hex.
rgb(var(--text-color) / 0.85)
Pass · 4.75:1
Raise opacity 70% → 85%. Still visibly "softer" than full body text, but legible.
--link-color
Pass · 4.6:1
Link text. Was #B7A6A1 (2.3:1 fail) until 2026-07-05 — now #916E4C gold, shared with nav hover. (Buttons moved off this gold to #736860 on 2026-07-07 — links keep the gold.) See Key decisions above.
#916E4C
Applied in Theme settings → Colors; the panel to the left renders it live. Working in Key decisions above.
--main-nav-link-hover-col
Pass · 4.6:1
Nav hover. Was the old gold #CFB091 (2.0:1 fail) until 2026-07-05 — now the approved button gold. See Key decisions above.
#916E4C
Applied in Theme settings → Colors; the panel to the left renders it live. Working in Key decisions above.
--rating-star-color
Exempt · 2.0:1
Rendered aria-hidden="true"; the numeric rating text carries the real info. See note above.
--btn-bg-color / --btn-text-color
Pass · 4.6:1
Primary button bg/text. Was #CFB091/#F8F5EE (1.9:1 fail) until 2026-07-05 — see Key decisions above.
#916E4C bg / #FFFFFF text
Applied in Theme settings → Colors; the panel to the left renders it live. Working in Key decisions above.
--btn-alt-bg-color / --btn-alt-text-color / --btn-alt-border-color
Pass · 4.6:1
Secondary button bg/text/border. Was #CFB091 on cream (1.9:1 fail) until 2026-07-05; the bg moved cream → white with the gold, since on cream the new gold only reaches 4.25:1.
#916E4C text/border, bg → white
Applied in Theme settings → Colors; the panel to the left renders it live. Working in Key decisions above.
Superseded 2026-07-07 — the button colour is now #736860 (logo taupe), white text, 5.4:1. See the newest Key decision above. The gold reasoning below is kept as history and still applies to links/nav-hover, which stayed #916E4C.
Decision — approved 2026-07-05: #916E4C with pure white text. White text (vs cream) buys the contrast headroom; #916E4C is the warmest tan that then clears 4.5:1. Passed over: #806D5A (grey-brown lean), #8A6948 (keeps cream text), dark-text-on-#CFB091 (7.7:1 but flips the button style). The secondary button bg moved cream → white with it — on cream the gold only reaches 4.25:1.
Applied 2026-07-05 — settings list in Key decisions above. The link/nav-hover reuse of this gold landed the same day (also in Key decisions). Buttons later split off to #736860 on 2026-07-07; links/nav-hover kept the gold.
--logo-col
Pass · 6.9:1
Store name.
--product-label-sale-text
Fail · 2.3:1
Product card — sale label.
#807471
Pass · 4.5:1
Same hue, 30% darker.
--product-label-sold-text
Pass · 6.9:1
Product card — sold out label.
--product-label-preorder-text
Resolves via currentColor — contrast depends on context, not a fixed pair.
--footer-bg-col / --footer-text-col
Pass · 6.3:1
Footer bg/text (foot_bg_col/foot_text_col). Related: --footer-heading-col (6.1:1, passes) and --footer-divider-col. Since the button text moved to white, this is where the brand cream #F8F5EE lives as a real token.
--success-text-color
Pass · 4.5:1
Success green for the PDP v3 size finder + delivery ladder. Minted 2026-07-07 as the net-new --sf-go; consolidated 2026-07-11 onto the theme's own --success-text-color (Shopify green 16 128 67 in stock Symmetry), overridden to the brand sage 82 119 74 in toshi-custom.css. One success token for vendor components (pickup icons, signup alerts) and ours; composes as rgb(var(--success-text-color) / 0.08).
#9E7967
Fail · 3.9:1
Found in bundle-landing.liquid, tiny-toes-bundles.liquid — a hand-typed guess at the brand accent.
--btn-bg-color (#736860)
Pass · 4.6:1
Same token as the primary button above — tracks whatever the button colour is (now #736860, 5.4:1). The fix for this row is repointing the two files at the token.
#CBAD87
Fail · 2.1:1
Found in promo-popup.liquid, promo-badge.liquid — noticeably more golden than the real link colour.
--link-color (#916e4c)
Pass · 4.6:1
Same token as the link item above — passes since the 2026-07-05 gold change. The fix for this row is repointing the two files at rgb(var(--link-color)).
#c8856a / 200 133 106
Fail · 3.0:1
Bundle CTAs, active filter chips and card prices in bundle-landing.liquid, tiny-toes-bundles.liquid — a terracotta accent that predates the gold decision. The two token-fallback occurrences already rendered gold; the hardcoded ones rendered this.
--btn-bg-color (#736860)
Pass · 4.6:1
Same token as the primary button — tracks the button colour (now #736860, 5.4:1).
rgb(var(--btn-bg-color)); the stale 200 133 106 Liquid fallbacks were corrected to the gold's 145 110 76. Visible shift from terracotta to gold.
#7a5c4a
Pass · 6.1:1
Found in bundle-landing.liquid, tiny-toes-bundles.liquid — warmer/browner than the theme's real text colour.
--text-color (#5f5956)
Pass · 6.9:1
Passes contrast as-is.
rgb(var(--text-color)) — a subtle visible shift from the warmer brown to the real brand ink.
background-color: #f8f5ee;
Pass · 6.3:1
PDP breadcrumb bar — main-product-toshi.liquid:6 (.breadcrumb-wrapper). A hand-typed copy of the footer cream.
rgb(var(--footer-bg-col))
Pass · 6.3:1
Same cream, but tracks Theme settings. Semantically it's a footer token on a breadcrumb bar — works, but see right.
--cream). One decision instead of three copies.
color:#854F0B; background:#FAEEDA; font-size:13px
Pass · 5.6:1
The sizing-tip callout, copy-pasted in 4 places across 3 files: main-product.liquid:411, main-product-toshi.liquid:554, cart-drawer.liquid:200 and :216. Contrast is fine — the drift here is the duplication, and it had already begun: the copies weren't quite verbatim (one had Gumbooties-specific wording, tags and margins differed).
snippets/sizing-tip.liquid — one source for copy and styling, with optional text/margin params covering the variants. Colours stay hardcoded in the snippet pending an info-callout token; if the pattern spreads, that becomes a Theme settings conversation.
Triaged 2026-07-05: cart-drawer.liquid's 21 hardcoded hexes broke down as: 8 schema defaults (not drift — the original count of 6 missed that one #e5e5e5 and one #1a1a1a live in the schema), 4 sizing-tip callout (now a shared snippet), and 4 × #e5e5e5 borders repointed at the divider recipe rgb(var(--text-color) / var(--divider-opacity)) — though one of those (the shipping-bar track's Liquid default:) is inert in practice, since the schema default always supplies the value; that instance really belongs with the schema-default decision below. Resolved 2026-07-06: #1a1a1a ×2 + its schema default (shipping progress-bar fill and success text) repointed to rgb(var(--text-color)) / #5f5956 — decision was to harmonise rather than keep near-black; #fff marker tick → rgb(var(--body-bg-color)); #666 marker label → the muted-text recipe rgb(var(--text-color) / 0.6); the #f9f9f9 comment deleted.
Typography
Real examples from this theme's code (2026-07-05 audit). Rows stay after the source is fixed — the distinction is the point. Custom samples render the literal typed value, so the comparison is genuine.
font-family: 'Merriweather', Georgia, serif;
Found in promo-popup.liquid, category-grid.liquid + 4 more — matches today's heading font by coincidence, won't follow a future font change.
--heading-font-family (Merriweather italic)
Set in Theme settings → Typography → Headings.
font-family: 'Nunito', sans-serif;
Found in category-grid.liquid, promo-badge.liquid, upf-badge.liquid.
--base-font-family (Nunito)
Set in Theme settings → Typography → Text & buttons.
font-size: 18px;
Found in bundle-builder.liquid, clearance-popup.liquid, bundle-landing.liquid — each section invented its own number in the gap between 16px and 32px.
.h6 (18.6px mobile / 19.8px desktop) or --base-text-size (16px)
Raw tokens jump 16→32px, but the heading ladder (strip below) fills the range and recalculates from Theme settings — .h6 lands within half a pixel of the hand-typed 18px on mobile. Pick a step; don't invent one.
.h6 step; its stepper glyph and clearance-popup's two lines took --base-text-size.
--smaller-text-size-4
12px · sans · also the PDP v3 age-chip caption (its alias --sf-caption-size was removed 2026-07-11 as a duplicate)
--smaller-text-size-3
13px · sans
--smaller-text-size-1
13px · sans
--smaller-text-size-2
14px · sans
--base-text-size
16px · sans
--logo-text-size
24px · logo (--logo-font-family)
--larger-mobile-text-size
32px · serif (h1 on mobile)
--larger-text-size
40px · serif
h1–h6/.h1–.h6 (main.css) derive from the size tokens, recalculate with Theme settings, and fill the 16→32px range. .hN sets size only (works on sans text; add .heading-font for serif). Desktop px, mobile in brackets.
.h6
20px (19px)
.h5
24px (21px)
.h4
28px (24px)
.h3
31px (26px)
.h2
35px (29px)
.h1
40px (32px)
Before typing a colour, font-family, or size, check it against this page. If it's not here, that's a conversation, not a guess.
Buttons & option tiles
Reused as-is from toshi-custom.css / main.css — this is the pattern the age-band size chips and colour tiles should match, not a new bespoke tile system.
Custom setting (2026-07-05 audit): the tile's hover/checked borders are hardcoded twice — toshi-custom.css:16-23 and main-product-toshi.liquid:45-63. When the gold changed on 2026-07-05 both copies were silently missed and still show #CFB091 — compare the tiles below. The hover border also fails contrast.
border-color: #cfb091 !important;
Fail · 2.0:1
Hover-state border. Found in toshi-custom.css:22-23 and duplicated in main-product-toshi.liquid:62-63 — same hardcoded hex in both.
border-color: rgb(var(--btn-bg-color));
Pass · 4.6:1
Same token as the primary button — tracks the button colour (now #736860, 5.4:1). The hardcoded #cfb091 copies (toshi-custom.css + main-product-toshi.liquid) were repointed at it on 2026-07-05.
border: 1px solid #5f5956 !important;
Pass · 6.9:1
Checked-state border. Found in toshi-custom.css:16-18 and duplicated in main-product-toshi.liquid:45-63 — happens to equal today's text colour by coincidence, so it won't follow a future change.
border-color: rgb(var(--text-color));
Pass · 6.9:1
Identical colour today — but tracks Theme settings when the brand ink changes.
rgb(var(--text-color)) — visually identical today, but they'll follow the brand ink when it changes.
Price & rating
Rendered via the real snippets/price.liquid and rating partial, against the product picked in the section settings below — real components, real data, not a mockup.
Sample product: Organic Beanie Mystical Jasmine Oak
