STORES.COM APP · THEME REFERENCE · 2026-07-13

Official Theme Colors, as the platform stores them

Every color below is read from production source — no invented values. Three layers exist today: the per-site scheme registry in mediocre-sdk/lib/siteContext.js (light + dark, the newest system), the legacy CSS layer in each storefront's theme.scss, and dynamic catalog themes on offers/events authored in Salesforce.

Layer 1 · canonical registry
siteContext schemes

theme.schemes.{light,dark} per site: primary/onPrimary, secondary/onSecondary, surface/onSurface. Powers cross-store emails, the admin Theme Builder, and is being rolled onto live sites (MorningSave already serves it inline).

Layer 2 · legacy site CSS — deprecated
theme.scss :root vars

--accent-color, --background-color, --foreground-color hard-coded per storefront. Still what most site CSS consumes, via color-mix() and -rgb variants.

Layer 3 · dynamic catalog
Offer / Event / Store themes

Authored in Salesforce (Accent_Color__c…), synced to catalog-service, injected as inline :root overrides — Meh's daily face theme, MS/SD event skins, in-store displays.

1The scheme registry — light & dark, per site

Source: mediocre-sdk/lib/siteContext.js (pulled 2026-07-13). Contrast ratios are computed live on this page, same math as the admin Theme Builder (admin.stores.com/theme); AA = 4.5:1 for text. Retail sites shown first.

1bWho actually uses the registry today — audit 2026-07-13

Where theme.schemes values are consumed exactly, vs. surfaces still on legacy or invented colors. The injector is mediocre-sdk/lib/views/shared/themeStyles.ejs — it renders the light scheme into :root and the dark scheme under @media (prefers-color-scheme: dark).

SurfaceUses registry?Detail
Cross-store email systemYES — fullyall ~20 SDK email layouts (sdk/lib/views/email/*) + their skeleton SVGs render from schemes.light; stores.com transactional emails (order-shipped, support-credited) read schemes directly. The email admin preview is token-based on every site, including ones whose storefronts aren't
admin.stores.com Theme BuilderYESreads the registry, live-previews both schemes, computes WCAG AA/AAA
buendeal.com storefrontYES — deepestinjector on 85 views; 11 stylesheets (buttons, checkout, deal pages, market) styled from tokens. Built on the new system
morningsave.com storefrontPARTIALinjector on 95 views, so tokens (+ dark scheme) are live site-wide — but only newer components consume them (market lifestyle variant, fragments, email); the bulk of MS CSS still reads legacy --accent-color. Jost/DM Sans typeface tokens live but not yet in repo scss (migration in flight)
lewisconger.com storefrontPARTIALinjector on 68 views; 4 token stylesheets
sidedeal / meh / casemates / hammacher / univision storefrontsNOno injector include; pages are 100% legacy --accent-color (their only token usage is the email admin preview). Meh's registry entry (green/orange) appears nowhere on meh.com itself — the site is painted by daily offer.theme
Existing MorningSave app (React Native)NOhard-coded app.morningsave.com/src/styles/colors.js — including a wrong yellow: #ffee08 vs official #fff066, plus iOS-default blue accents
Luke's SideDeal iOS prototypeNOsidedeal-ios/SideDealApp.swift invents #E31837 vs official #d8002a, and uses iOS-blue for interactive elements
Our app mock-upPARTIALgraded per-mode in section 4 below

Pattern worth noting: every past app effort drifted from brand colors because nothing fed them theme data — the registry now exists precisely to prevent that, and email already proves it works cross-store. Also: the registry defines a dark scheme for every site, but only the three injector sites actually serve one; no legacy storefront except SideDeal has any dark-mode support.

2Legacy static layer — DEPRECATED as a color source (7/14)

Decision (Dave, 7/14): the scheme registry (section 1) is the only canonical color source for app + brand work. This legacy layer is documented for archaeology and migration tracking only — never pull brand colors from it.

Source: <site>/public/styles/shared/theme.scss. This is the layer the storefront SCSS actually consumes right now. SDK default (black on white) applies where a value isn't set.

Site--accent-color--background-color--foregroundVariants & quirks
meh.comnone — fully dynamic; every page painted by the day's offer.theme (Layer 3)hamburger menu pins #ff6a00; Cash page #118825
morningsave.com#00004d#fff066#ffflive site already injecting Layer-1 tokens + Jost/DM Sans (font migration in flight; repo scss still says futura-pt)
sidedeal.com#d8002a#222#fffonly legacy site with real scheme support: prefers-color-scheme: light → white bg / #000 fg; prefers-contrast: more#eb002f on #000
hammacher.com#000000#007f6a#fffdisplay-p3 wide-gamut override for the green; adds --text-on-background-color
casemates.com#000#fff#000plain black/white; brand lives in Layer 1 (wine #722f37)
buendeal.com#FFB347#1A4A98#fffdisplay-p3 override; built new enough to also use Layer-1 tokens in page CSS
shop.univision.com#0cbfae#000#fffcode comment: "accent does not provide enough contrast against white"; prefers-contrast: more → black accent
lewisconger.com#000000#1a3c5a#fffdisplay-p3 override
stores.com#00b1ff#1a1a2e#fffadds --text-on-background-color

3Dynamic catalog themes — the per-offer / per-event layer

Authored in Salesforce on Offer__c / Event__c (Accent_Color__c, Background_Color__c, Background_Image__c, Foreground__c), synced by catalog-service/handlers/offers.js:313 into a theme object on offers, events, and stores (physical). Templates inject them as inline :root overrides on top of Layer 2.

Where it paintsTriggerDetail
meh.com home — the daily face themeevery offer, alwaysfull retheme: accent, background, background image, --meh-face-url. A Salesforce health-check (RuleOfferMustHaveTheme.cls) errors on any offer missing a complete theme. Face asset gets Cloudinary e_negate only when foreground is light (sdk/catalog/votes.js:96)
MS / SD home + deal pagessuperhero event, if hasTheme()guard treats default black-on-white as "no theme" and skips the override (sdk/catalog/events.js:431)
In-store TV / tablet / projector displaysevent thememorningsave.com/views/stores/displays/
hammacher.comoffer accent onlytints section headers; no full retheme
Live example — today's Meh theme (2026-07-13):  accent #ff6000  background #232f39  foreground light (#fff) + background image + negated face. This exact record is what the app would consume — zero new infrastructure.

4The app mock-up, graded against official data

Shawn's ask: build the prototype "using only the theme data and not invented colors." Where each mode stands:

Mock-up modeCurrently usesOfficial?Closest official source
MorningSave#00004d / #fff066YESLayer 1 + Layer 2 agree exactly (primary/secondary)
SideDeal#d8002a #1e1e1e #ffd966 + color-mix neutralsREGISTRY-PUREdark scheme straight from the registry; gold secondary now serves as price + active indicator; legacy anchors (#222, #eb002f) dropped 7/14
Meh#ff6000 / #232f39 (scraped 7/10)YES — by luckit IS a real day's offer.theme; correct move is consuming the daily record live (today's happens to match)
Community (stores)#00b1ff #003554 #e6f7ff + color-mix neutralsYES — snapped 7/14pure registry: primary, onSecondary (replaced the invented #0A7FC0 everywhere), secondary as chip/tab pill; ink = onSurface #000
OutletStores#C8281C #A01F15 #E0322ENOsampled from Matt's logo — no outlet.stores.com site exists yet, so no official record. Decision needed: mint a siteContext entry for it (that becomes the official data) or derive from stores.com

Status for Shawn as of 7/14: 4 of 5 modes are registry-pure (SideDeal + Community from registry schemes with the registry's own token names; MorningSave likewise; Meh runs the dynamic catalog layer through the same names) — MorningSave and Meh were already, SideDeal and Community were snapped (anchors = official values, neutrals = color-mix() of anchors, production's own technique). The one remaining gap is OutletStores, which has no official theme data to match — its palette needs to become official via a siteContext entry.