Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable public Spark changes should be recorded here.

Spark follows human-readable release notes rather than a package-manager version contract. The release version is stored in `manifest.json` and mirrored in [README.md](README.md) and `CLAUDE.md`. When releasing, update all three version markers, add a dated changelog section, and publish a Git tag or GitHub release when the repo is ready for external consumers to pin versions.

## Unreleased

- Theme Settings > Style gained nine token-shaped settings: Layout holds `body_bg_color`, `border_color`, `radius_control`, `radius_card`, `section_padding`, `content_gap` and `container_max_width`; Type Scale holds `heading_scale` and `body_size`. `layouts/base.html` bridges them into `:root` with the same guarded pattern the font and colour settings use (noun-first properties such as `--control-radius` and `--section-padding-y`), and `css/input.css` registers namespace-first `@theme` keys that read them with today's values as fallbacks (`--radius-control: var(--control-radius, 4px)`); the names differ on purpose, because a key that reads a property of its own name is a self-reference and the bridge disconnects. The default option of `section_padding`, `content_gap`, `heading_scale` and `body_size` emits nothing. Component rules now read the bridge directly: body background and font-size, `.btn` radius, `.btn-secondary` and `.product-card-bordered` border colour, `.container` max-width, `.product-card` radius (with `overflow: hidden` so a rounded card clips its image), and the `.product-grid` / `.category-grid` gaps. In the six homepage sections the live branches swap design-decision literals for token utilities: `py-section-y md:py-section-y-md` on the four standard sections and `py-band-y md:py-band-y-md` on the promo band, `gap-content-md md:gap-content-lg` on the featured product columns, `text-display md:text-display-md` on the hero heading, `text-h1 md:text-h1-md` / `text-h2` / `text-h3` on the section headings, promo heading and featured product title, and `rounded-card` on the featured image and category tiles. Every `--text-*` key carries Tailwind's own line-height ratio, so the swap changes neither size nor leading. Placeholder and empty-state chrome stays literal because it signals missing configuration rather than the merchant-facing design language. A fixture render of the homepage before and after, at default settings, shows 0 computed-style differences and 0 differing pixels at 1280 and 375, for both a populated homepage and a fresh store rendering only `settings_data.json`. `tests/test_style_tokens.py` pins the fallbacks, the bridge conditions, the live-versus-placeholder split and the nine setting ids. `assets/main.css` grew from 48219 to 50298 bytes (#56).

## 1.3.0 - 2026-09-03

- `layouts/base.html` now renders the platform `{% pixels %}` tag in a new `pixels` block, immediately before the theme script stack. The platform injects every app's storefront event tracker (Google Analytics 4, Google Tag Manager, Klaviyo, Taboola) as hidden iframes through that tag, and Intro Bootstrap reaches it indirectly through `{% core_js %}`. Spark replaced `core_js` with `spark-platform.js` and never re-added `pixels`, so no tracker iframe was rendered, `window.customerEventManager` never existed, and no app received `page_viewed`, `product_viewed`, `product_added_to_cart`, or `checkout_*` events on any Spark store. The tag is a platform builtin, needs no `{% load %}`, does not depend on jQuery, and respects the platform's `disable_pixel` guard.
Expand Down
43 changes: 34 additions & 9 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ Spark is a storefront theme for Next Commerce. This document is the single sourc

Merchants can override body and heading fonts via dashboard settings (`font_body`, `font_header`). The system stack is the default.

### Heading scale

| Utility | Default size |
|---------|--------------|
| `text-h3` | 1.25rem |
| `text-h2` | 1.5rem |
| `text-h1` / `md:text-h1-md` | 1.875rem / 2.25rem |
| `text-display` / `md:text-display-md` | 1.875rem / 3rem |

Each heading token carries Tailwind's line-height ratio. The `heading_scale` setting in Theme Settings > Style > Type Scale multiplies these sizes through `--heading-scale`: small is 0.875, default is 1, and large is 1.125. Body copy stays on the utility scale. The `body_size` setting accepts 15px through 18px and sets the body font-size through `--body-size`; its 16px default is the browser default. The page background comes from `body_bg_color` through `--body-bg-color`.

| Role | Size | Weight | Line-height | Usage |
|------|------|--------|-------------|-------|
| Page heading | text-2xl / text-3xl | 600 (semibold) | 1.2 | h1 on category, PDP, blog post |
Expand Down Expand Up @@ -97,13 +108,17 @@ These are functional signals, not brand expression. Never let merchants change t
| 12 | 48px | Major section padding (py-12) |
| 16 | 64px | Footer top margin (mt-16) |

### Section rhythm and content gap (merchant-adjustable)

Standard sections use 3rem vertical padding and 4rem at 768px and above. The promo band uses 4rem and 5rem at the same breakpoint. The default content gap is 1.5rem; its `sm`, `md`, and `lg` steps use 2/3, 4/3, and 2x ratios.

Theme Settings > Style > Layout controls these values. `section_padding` sets `--section-padding-y` to compact (2rem), default (3rem), or roomy (5rem). `content_gap` sets `--content-gap` to tight (1rem), default (1.5rem), or loose (2rem).

### Container

```
max-width: 1280px
padding: 1rem (mobile) → 1.5rem (768px+)
margin: auto (centered)
```
**Max-width:** 1280px default; `container_max_width` offers 1120px / 1280px / 1440px via `--container-max`.

**Gutters:** 1rem (mobile) → 1.5rem (768px+). Margin remains auto (centered).

---

Expand All @@ -113,11 +128,12 @@ margin: auto (centered)

| Element | Radius | Rationale |
|---------|--------|-----------|
| Buttons | 4px (0.25rem) | Only rounded element — subtle, functional |
| Form inputs | 4px (0.25rem) | Matches buttons |
| Buttons (`.btn`) | 4px default, `radius_control` (0-16px) via `--control-radius` | Subtle, functional rounding |
| Form inputs | 4px (0.25rem), literal | Matches the button default; not yet on the token |
| Product cards, featured image, category tiles | 0 default, `radius_card` (0-16px) via `--card-radius` | Sharp by default |
| Everything else | 0 | Sharp, architectural feel |

**Border style:** 1px solid slate-200 (`#E2E8F0`) for all layout dividers — header bottom, footer sections, form fields, card boundaries.
**Border style:** 1px solid slate-200 (`#E2E8F0`) for all layout dividers — header bottom, footer sections, form fields, card boundaries. `border_color` via `--border-color` drives the secondary button and bordered product cards today; the other dividers stay literal until they move onto the token.

**Box shadow:** Almost never. Clean flat aesthetic. Exception: side cart legacy CSS (platform dependency).

Expand Down Expand Up @@ -341,7 +357,7 @@ These patterns are banned. If you see them in a PR, reject it.
2. **Centered-everything layout** — left-align text. Only center: empty states, footer copyright.
3. **Generic hero text** — "Welcome to our store." The hero IS a product image.
4. **Decorative gradients or blobs** — zero decorative elements.
5. **Rounded-everything** — sharp corners (0px). Only buttons get 4px.
5. **Rounded-everything** — the default is 0px for cards and 4px for controls. Merchant radius settings are the sanctioned way to add rounding.
6. **Drop shadows for depth** — flat aesthetic. Borders for separation.
7. **Ratings/badges/tags on product cards** — image + title + price. Nothing else.
8. **Hover zoom on product images** — let photos breathe. group-hover:text-slate-600 on title is enough.
Expand Down Expand Up @@ -387,6 +403,15 @@ Applied to support articles and cart page. Hide chrome, clean layout, readable t
| `body_text_color` | color | #1E293B | Body text |
| `body_header_color` | color | #1E293B | Headings |
| `body_link_color` | color | primary | Links |
| `body_bg_color` | color | #FFFFFF | Page background via `--body-bg-color` |
| `border_color` | color | #E2E8F0 | Secondary button and bordered product card borders via `--border-color` |
| `radius_control` | select | 4px | Button (`.btn`) radius via `--control-radius` |
| `radius_card` | select | 0 | Product card, featured image, and category tile radius via `--card-radius` |
| `section_padding` | select | default (3rem) | Homepage section and promo-band vertical rhythm via `--section-padding-y` |
| `content_gap` | select | default (1.5rem) | Product grids, category grids, and content-column gaps via `--content-gap` |
| `container_max_width` | select | 1280px | Container maximum width via `--container-max` |
| `heading_scale` | select | default (1) | Display and section heading tokens via `--heading-scale` |
| `body_size` | select | 16px | Body font-size via `--body-size` |
| `navbar_bg_color` | color | white | Header background |
| `navbar_link_color` | color | #475569 | Nav icon/link color |
| `footer_bg_color` | color | #F8FAFC | Footer background |
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ Tracked theme documentation starts at [docs/README.md](docs/README.md). Current
- **Membership price presentation** — optional client-side member price display driven by logged-in customer metadata, designed to pair with platform-side checkout discounts.
- **Critical-path load order** — metadata, LCP preloads, CSS, body content, ordered theme JS, footer app hooks, and tracking are explicitly separated in `layouts/base.html`.
- **Delight package** — skeleton loading, image optimization, cart badge animation, keyboard navigation, contrast auto-detection, print stylesheet.
- **Merchant-configurable** — brand colors, fonts, navigation, footer, social links, payment icons, and more via Theme Settings.
- **Merchant-configurable** — brand colors, fonts, navigation, footer, social links, payment icons, layout and type-scale tokens (radius, section rhythm, content gap, border and page colours, container width, heading scale, body size), and more via Theme Settings.

See [docs/theme-settings-partials.md](docs/theme-settings-partials.md) for the design-team catalog of Theme Settings partials and homepage section partials, [docs/figma-section-library-plan.md](docs/figma-section-library-plan.md) for the Spark Figma section library plan, [docs/performance-load-order.md](docs/performance-load-order.md) for the critical-path loading convention, [docs/pdp-customization.md](docs/pdp-customization.md) for the PDP redesign preservation checklist and QA runbook, [docs/pdp-variant-state.md](docs/pdp-variant-state.md) for the PDP variant state Interface, [docs/cart-events.md](docs/cart-events.md) for the cart event Interface, [docs/cart-rewards.md](docs/cart-rewards.md) for side-cart rewards and upsell rules, [docs/cart-drawer-architecture.md](docs/cart-drawer-architecture.md) for the drawer Module split, [docs/intro-bootstrap-comparison.md](docs/intro-bootstrap-comparison.md) for the Intro Bootstrap comparison, [docs/design-block-authoring.md](docs/design-block-authoring.md) for design-block authoring guidance, [docs/terminology.md](docs/terminology.md) for NEXT-native naming guardrails, and [docs/sections-architecture-proposal.md](docs/sections-architecture-proposal.md) for the future theme sections platform proposal.

Expand Down
2 changes: 1 addition & 1 deletion assets/main.css

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions configs/settings_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,15 @@
"body_text_color": "",
"body_header_color": "",
"body_link_color": "",
"body_bg_color": "",
"border_color": "",
"radius_control": "4px",
"radius_card": "0",
"section_padding": "default",
"content_gap": "default",
"container_max_width": "1280px",
"heading_scale": "default",
"body_size": "16px",
"sidecart_open_on_add": true,
"enable_progress_bar": false,
"usd_goal_1": 50,
Expand Down
183 changes: 183 additions & 0 deletions configs/settings_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1177,6 +1177,189 @@
"type": "color",
"help_text": "Default color for links."
}
],
"Layout": [
{
"name": "body_bg_color",
"label": "Page Background Color",
"type": "color",
"help_text": "Background color for the page. Default white."
},
{
"name": "border_color",
"label": "Border Color",
"type": "color",
"help_text": "Color for secondary button and bordered product card borders. Default slate-200 (#E2E8F0)."
},
{
"name": "radius_control",
"label": "Control Radius",
"type": "select",
"options": [
{
"name": "None",
"value": "0"
},
{
"name": "4px",
"value": "4px"
},
{
"name": "8px",
"value": "8px"
},
{
"name": "12px",
"value": "12px"
},
{
"name": "16px",
"value": "16px"
}
],
"default": "4px",
"help_text": "Corner radius for buttons. Default 4px."
},
{
"name": "radius_card",
"label": "Card Radius",
"type": "select",
"options": [
{
"name": "None",
"value": "0"
},
{
"name": "4px",
"value": "4px"
},
{
"name": "8px",
"value": "8px"
},
{
"name": "12px",
"value": "12px"
},
{
"name": "16px",
"value": "16px"
}
],
"default": "0",
"help_text": "Corner radius for product cards. Default none."
},
{
"name": "section_padding",
"label": "Section Padding",
"type": "select",
"options": [
{
"name": "Compact",
"value": "compact"
},
{
"name": "Default",
"value": "default"
},
{
"name": "Roomy",
"value": "roomy"
}
],
"default": "default",
"help_text": "Vertical padding for homepage sections. Default 3rem."
},
{
"name": "content_gap",
"label": "Content Gap",
"type": "select",
"options": [
{
"name": "Tight",
"value": "tight"
},
{
"name": "Default",
"value": "default"
},
{
"name": "Loose",
"value": "loose"
}
],
"default": "default",
"help_text": "Gap between products and content columns. Default 1.5rem."
},
{
"name": "container_max_width",
"label": "Container Max Width",
"type": "select",
"options": [
{
"name": "1120px",
"value": "1120px"
},
{
"name": "1280px",
"value": "1280px"
},
{
"name": "1440px",
"value": "1440px"
}
],
"default": "1280px",
"help_text": "Maximum width for page content. Default 1280px."
}
],
"Type Scale": [
{
"name": "heading_scale",
"label": "Heading Scale",
"type": "select",
"options": [
{
"name": "Small",
"value": "small"
},
{
"name": "Default",
"value": "default"
},
{
"name": "Large",
"value": "large"
}
],
"default": "default",
"help_text": "Scale applied to display and section headings. Default 1."
},
{
"name": "body_size",
"label": "Body Size",
"type": "select",
"options": [
{
"name": "15px",
"value": "15px"
},
{
"name": "16px",
"value": "16px"
},
{
"name": "17px",
"value": "17px"
},
{
"name": "18px",
"value": "18px"
}
],
"default": "16px",
"help_text": "Base font size for body text. Default 16px."
}
]
},
"Side Cart": {
Expand Down
Loading
Loading