Ember E-Bike Store
Build a premium electric-bike store with an orange photographic hero, bold condensed headings, dark photographic category cards and a dark component explorer that swaps close-up photos. Stone product cards come from one coherent studio set, and the whole store works: variants that change the price,…
Similar Skills
What you’ll get
- A 35-route example for the fictional Askel Cycles: six bikes, four categories, equipment, compare, journal, test rides, about, contact, FAQ, delivery, legal, b…
- A working store flow: battery and frame-size variants, a mini-cart drawer, a bag with promo code, demo checkout with validation and an order confirmation that …
- Home tools (hero carousel, component explorer, range calculator, shop finder) plus a style guide, image plan, photo-matching script and built-in checks.
Great for
- E-bike, scooter, cargo-trike or moped brands that want a premium store front with real product detail.
- Brands with partner shops or showrooms that offer test rides and want booking and a shop finder.
- Teams that want working variant, bag, compare and checkout screens to review before wiring payments.
Skip it if
- Taking real orders: checkout says clearly that payment is off, and nothing is charged until you connect your own commerce backend.
- Large catalogues that need inventory sync or a content management system.
- Soft pastel or minimal brands; the look relies on saturated orange, condensed capitals and dark panels.
About this Skill
- 1### 1. Establish the content and output location
- 2Read the target repository (if any) and its instructions first. Identify the
- 3brand, market, audience, product range and page requirements, then map them
- 4onto the template with **Adapting to a real brief** below. Ask only for
- 5information that blocks progress. For a real business, facts come from the
- 6brief; anything missing is drafted as specific, plausible placeholder copy
- 7(model names, prices, specs, shop names, dates) and listed in your final
- 8reply. Never use lorem ipsum, "Your Company" or generic names. Keep unrelated
- 9files intact and put a standalone site in its own directory. Do not silently
- 10migrate an existing app to another framework.
---
name: bs-ember-ebike-store
description: Build a complete multi-page website with an orange photographic hero, bold condensed headings, dark cycling category cards and tactile component details. Includes connected content pages and interactive controls, with a reusable visual system for new brands and content.
---
# Ember E-Bike Store
Build a premium electric-bike store: an orange photographic hero with a
condensed headline and a feathered bike photograph, dark photographic
category cards, a dark "built down to the bolt" component explorer, stone
product cards from one coherent studio set, and a full commerce and content
route family. The worked example is a fictional brand, Askel Cycles, with
20 page templates and 35 routes (plus a deep link per partner shop). `references/template.html` is the
visual and behavioural blueprint, not a substitute for a framework build.
The bar: a demanding designer would call the result premium, every image has
a job, motion is calm and purposeful, and the site works as a real store
front end that someone could adopt as-is.
## Workflow
### 1. Establish the content and output location
Read the target repository (if any) and its instructions first. Identify the
brand, market, audience, product range and page requirements, then map them
onto the template with **Adapting to a real brief** below. Ask only for
information that blocks progress. For a real business, facts come from the
brief; anything missing is drafted as specific, plausible placeholder copy
(model names, prices, specs, shop names, dates) and listed in your final
reply. Never use lorem ipsum, "Your Company" or generic names. Keep unrelated
files intact and put a standalone site in its own directory. Do not silently
migrate an existing app to another framework.
### 2. Choose the deliverable
- **No existing project and no named stack (the default):** build one
self-contained HTML file from the template, like the store demo. It is the
fastest reviewable result; do not ask a stack question first. Offer a
framework port as the next step in your final reply.
- **The buyer has a framework project or asks for one:** inspect it first and
port per `references/framework-adaptation.md` (Next.js App Router with
TypeScript when a framework is wanted but not named): real components,
typed content collections and framework routes. Never iframe the template
or inject it as raw HTML; the hash router belongs to the single file.
### 3. Read the visual system before writing UI
Read `references/style-guide.md` and `references/visual-contract.md`, then
open `references/template.html` (it renders on its own; images ship in
`references/images/` and fonts load from the fontsource CDN). Preserve these
signatures:
- `bike-hero` with `data-carousel`, kept small and calm: the paper header
sits above an inset orange panel (700 px tall on desktop, full-bleed and
620 px on phones). The bike is centred in a feathered studio-photo box;
under it, centred, come an ink category eyebrow, a two-line white Anton
headline at 46 px (34 px on phones): the model name, then the brand's short
tagline (four words or fewer; the example is "Scree. / Go your own way."),
and one light button with one short verb phrase ("Find your ride"). `bike-controls` sits bottom-left: round ink
prev/next arrows around a mono "01 / 03" counter. Nothing else goes in the
hero (no model block, second CTA, tab rail, stat strip or chips), and the
headline is never enlarged or moved to the left.
- `bike-categories`: dark photographic cards (ink ground, bottom gradient,
Anton category name, model count, orange arrow disc). A swipe rail on phones.
- Details band: dark section with an orange macro photo and four tactile
component tabs that swap the photo.
- Stone product cards: the photo ground equals the `--stone` token so studio
shots sit seamlessly; Anton name, "From" price, mono spec chips.
Fonts: Anton (display, uppercase), Archivo (variable; text/UI) and Geist
Mono (variable; labels, specs, numbers). The template loads them from the
fontsource CDN. In a framework project install `@fontsource/anton`,
`@fontsource-variable/archivo` and `@fontsource-variable/geist-mono` or use
`next/font/google` (`Anton`, `Archivo`, `Geist_Mono`); for the single-file
store `scripts/inline-assets.mjs` embeds the woff2 files as data URIs. Keep the token names and values from the style guide.
### 4. Plan the complete page family
Read `references/page-library.md`, `references/route-inventory.md` and
`references/interior-pages.md`. Inventory every nav item, card, CTA, footer
link and form destination before building. Each entity (bike, category,
accessory, story, shop) gets an id, specific copy and its own imagery. Detail
pages need galleries, variants, specs, reviews and related items; inner pages
are designed pages, never a heading and two sentences. Remove links when you
remove a page. Ship a designed 404.
### 5. Plan and produce the imagery as a set
Read `references/image-plan.md`. Write the art direction once, then plan
slots by role: hero (orange studio, one per hero slide), catalog (one studio
shot per product), category/lifestyle (dusk, warm rim light), detail macros
(orange backdrop), editorial (journal), people/workshop (about). Generate the
catalog as one batch from one prompt template so backdrop, light, angle and
scale match. On a small budget follow the image plan's **Minimum viable
set** (one orange studio shot per model, catalog shots derived from it).
Review every image; regenerate anything off-brief or with text, logos or
broken mechanics. Normalize with `scripts/normalize-images.py` (numpy and
Pillow): `stage` turns the hero photos into centred 2:1 stage crops at one
scale and wheel line on a flattened panel colour and prints that colour for
`data-bg`; `catalog` puts each product on the `--stone` ground with equal
margins (from a stone shot, or by swapping the orange sweep); `split` cuts an
accessory sheet into single shots. Look at the results: texture as well as
colour must match where a photo meets a panel. Never reuse one image for unrelated
entities; the same entity's photo on its card and detail page is correct.
### 6. Build the structure
Use shared components (header, mega menu, cards, buttons, fields, drawer,
footer). Keep content in typed collections separate from components. One
`h1` per page, semantic landmarks, skip link, labelled inputs, `aria-*` on
custom widgets. Tokens at the top of the CSS; no inline grid templates that
media queries cannot override; `minmax(0, 1fr)` tracks wherever content can
be wider than its column.
### 7. Wire every interaction (store contract)
Set `SITE` (name, journal name, URL, storage key, order prefix) and `CONFIG`
(locale, currency, tax added or included, tax rate and name, postcode
pattern, delivery fees and free-delivery threshold, energy price, promo code)
at the top of the template script for the buyer's market before writing
copy; prices, totals, the summary rows, postcode checks, dates and the range
calculator read from them.
- Variants change price and state: battery tiles (+price, range), frame-size
tiles with a sold-out state, a height-based fit helper.
- Add to bag shows loading then success, bumps the badge and opens the
mini-cart drawer (quantities, remove with undo, running subtotal, delivery
note, View bag / Checkout). The header bag is a 44 px icon with a count
badge hidden at zero.
- Bag page: line items, save for later, promo code with inline error, summary.
- Checkout: inline validation with focus on the first error, delivery method
radio cards that change totals and fields, a payment panel that clearly
says payment is off in the demo, then an order confirmation route.
- Collections: filter chips with counts, search, sort, and a designed empty
state with a reset. Compare page with a "differences only" toggle.
- Test rides: shop search + model filter with empty state, map card, booking
form (day chips, time slots with booked states) and a success state.
- Home tools: hero carousel (arrows with an "01 / 03" counter, swipe, arrow
keys, autoplay that pauses on hover/focus/off-screen and stops after
interaction), component explorer,
range calculator, shop finder.
- Global: mega menu, focus-trapped mobile sheet and drawer (Esc, scrim,
focus restore), search dialog with grouped results and empty state, toasts,
newsletter and contact forms with validation and honest demo confirmations.
Demo actions never claim a real payment, booking or message was sent.
### 8. Apply the motion system
Read `references/motion-system.md`. Content is visible without script; reveal
styles live under `.js` with an IntersectionObserver plus fallbacks; the hero
eyebrow, headline and button fade up on load, finished within 0.9 s; route changes fade in and scroll to
top; micro-interactions are 120-280 ms on transform/opacity only;
`prefers-reduced-motion` makes everything instant and stops autoplay.
### 9. Apply the icon grammar
Read `references/icon-library.md`. Lucide-grammar inline SVG only (24 grid,
1.75 stroke, round caps), one sprite, `currentColor`. No emoji, dingbats or
icon fonts. Icon-only buttons need accessible names.
### 10. Build and validate
Keep your source page next to an `images/` folder (a copy of the template
with the images you use), then build the single file and validate it:
```bash
node scripts/inline-assets.mjs site/index.src.html site/index.html
node scripts/validate-design.mjs site/index.html
```
`inline-assets.mjs` embeds every `images/` file (including the paths in the
`IMG` map) and downloads the three fontsource woff2 files once, as data URIs;
it stops with a clear message if a file is missing or a font download fails.
The validator's default mode is for your store: offline and self-contained,
sandbox-safe, labelled controls, alt text, reduced motion, focus styles,
`@font-face` fonts, the style's signature structures, route integrity
(home, not-found, at least 12 page templates or `--min-pages N`, every
`#/` link resolves, one static h1 per page), the 8 MB cap, and it fails when
any of the worked example's brand, products, people, shops, address or
story slugs are left. `--files` validates a deployed site that keeps
`images/` and `fonts/` beside the page; `--template` checks the template
itself. Fix every error. For a framework output, also run the project's own
type check and build.
### 11. Review in a real browser
Work through `references/quality-checklist.md`. Screenshot home and at least
six inner routes at 1440, 1024, 768 and 390 px (also 360 for overflow). Click
through the store flow end to end (variant, add, drawer, bag, checkout
errors, order), the filters and empty states, the booking form and the menus.
Confirm no horizontal overflow, no console errors, no hidden text and no
broken images. Fix what you see and review again.
### 12. Deliver clearly
Report the output path, stack, routes, image count and what was validated,
separating programmatic checks from browser review. Do not claim deployment,
publication or rights clearance that did not happen.
## Adapting to a real brief
- **Counts flex; the grammar does not.** Products, categories, accessories,
stories, shops and FAQs are the `BIKES`, `CATS`, `EQUIP`, `POSTS`,
`DEALERS` and `FAQS` arrays; cards, filters, counts, compare and search
render from them. Two or three categories switch the home grid to
`cats-2` / `cats-3` by themselves; fewer than five products leave a gap in
the 3.25-column line-up rail, so fill it with key accessories or use a
`cards-3` grid; one to three hero slides (the counter follows). See
"Small catalogs" in `references/visual-contract.md`. Headings that state a
number ("Six bikes. One standard.") change with it.
- **Map the sections to the business.** Scooters, cargo trikes or mopeds:
keep the `bike-hero`, `bike-categories` and `bike-controls` class names
(the validator looks for them) but rename the routes (`#/bikes` to
`#/scooters`); map frame-size tiles to what fits the product (seat height,
deck length) and keep the sold-out state and the height-based fit helper;
the details band shows that vehicle's parts. A store without test rides
turns the Test rides page into store locations or service bookings; a
brand without partner shops drops `DEALERS` and the shop finder.
- **Set the market.** `CONFIG` handles currency, VAT included or tax added,
postcodes and fees. Also rewrite the static market copy listed in the
Replace checklist (ZIP labels, the delivery table, legal text).
- **Real facts only.** For a real business, testimonials, ratings, review
counts, customer and shop names, figures, team, addresses, dates, prices,
specs and warranty terms come from the brief. Anything missing is drafted
as plausible placeholder copy and listed in your final reply for the buyer
to confirm or replace. No invented certifications, awards, safety ratings,
test standards (such as the EN 17860 line), regulatory or security claims.
- **People photos.** If the site shows a real founder, team or mechanic, ask
for their photos. Generated people (riders, `about-workshop`) are
stand-ins: say so in the final reply.
- **Shipped images** (`references/images/`). Reusable as neutral stand-ins
for any e-bike or two-wheeler store: `eq-lock`, `eq-helmet`, `eq-light`,
`eq-bag`, `eq-bottle`, `detail-brake`, `detail-cockpit`, `detail-battery`,
`cat-commute`. E-bike-specific, regenerate for other vehicles: the six
`bike-*` and three `hero-*` photos and their `-stage` crops (the worked
example's own models), `detail-drive` (a chainring), `eq-rack`,
`cat-trail`, `cat-step`, `cat-cargo`, `journal-coast`, `journal-cargo` and
`about-workshop` (pedals and chains in frame). Never present a shipped bike
photo as the buyer's product.
- **Deliverable.** No project: the single HTML file built with
`scripts/inline-assets.mjs` (fonts and images as data URIs, safe in a
sandboxed preview). A normal deployed site may keep `images/` and the font
files beside the page (validate it with `--files`). A framework project:
port per `references/framework-adaptation.md` with local image and font
files.
- **The hero copy changes, its anatomy does not.** New model names and
eyebrows, the brand's own tagline of four words or fewer, one short button
label; same sizes, same panel, same controls.
## Replace checklist
Static strings outside the data arrays and `SITE` / `CONFIG` (the validator
fails while any sample name is left, so search for "Askel", the model names
and "Portland" after editing):
- `<title>`, meta description, `og:*` tags, the CSS header comment.
- Header: brand mark, `.brand-word`, its `aria-label`; footer copyright line,
social `aria-label`s and the cropped `.foot-word` (resize it to the name's
length, see the style guide).
- Every section's `data-title` (the router sets `document.title` from it).
- Hero: slide `aria-label`s, `data-img`, `data-bg` (from `normalize-images.py
stage`), the eyebrow and headline `data-meta` spans, the tagline.
- Home: service strip ("Test rides at 38 shops"), line-up heading, details
band captions and tab copy ("Askel Drive"), reviews summary, test-ride
block, journal feature.
- About (story, facts, values, timeline), Contact (phone, address, hours),
Delivery table and service schedule (prices and currency), Legal text
(sales tax wording), FAQ answers (financing, warranty, return terms).
- Market inputs: the checkout "ZIP code" label, error text and
`inputmode="numeric"` (postcodes with letters need `inputmode="text"`), the
home ride finder's "City or ZIP code" label and error, the range
calculator's initial cost text.
- Script defaults that name sample models: `BIKE_FACTOR`, the compare
columns, the empty-search "Popular" list and the range calculator's default
bike (each falls back to the first products when the named ones are gone).
- Routes: when renaming, change `data-page`, every `href="#/..."`,
`data-nav`, the `resolve()` branch, `NAV_OF` and the `RENDER` key together.
## Single-file constraints
The single-file store is one self-contained HTML file (target 5 MB, hard cap
8 MB) with inline CSS, JS, fonts and images, built with
`scripts/inline-assets.mjs`. Sandbox restrictions apply when the page is
previewed inside a sandboxed iframe (`<iframe sandbox="allow-scripts">`
without same-origin): no network requests, no `alert/confirm/prompt`, no
`window.open`, no top navigation, storage only inside try/catch with an
in-memory fallback, no native form submission (`type="button"` plus Enter
handlers), and a router that keeps route state in JS and only tries
`history.pushState` inside try/catch. The template already follows these
rules. A deployed site or framework project does not need them.
## Files
- references/template.html: the working blueprint (images in references/images/, fonts from the fontsource CDN; `SITE` and `CONFIG` at the top of its script).
- references/style-guide.md: tokens, type scale, layout, surfaces, components, do and don't.
- references/visual-contract.md: non-negotiable signatures and fidelity checks.
- references/image-plan.md: art direction, every slot, prompts, normalization.
- references/motion-system.md: durations, easings, reveal pattern, reduced motion.
- references/quality-checklist.md: pre-delivery checklist.
- references/page-library.md: page roles and content requirements.
- references/route-inventory.md: complete route inventory of the worked example.
- references/interior-pages.md: interior page depth rules.
- references/framework-adaptation.md: stack choice and component mapping.
- references/reui-components.md: ReUI mapping for React outputs.
- references/icon-library.md: icon set and accessibility conventions.
- scripts/validate-design.mjs: static validation for your store (default), a deployed site (`--files`), the template (`--template`) and the store demo (`--demo`).
- scripts/inline-assets.mjs: builds the single-file store (images and fontsource fonts as data URIs).
- scripts/normalize-images.py: hero stage crops, catalog shots on stone and accessory-sheet splits.
### Shopping bag entrance
Use a compact 44 px icon-only bag button in the header. Do not render "Bag
(0)", "Cart (0)" or a text label. Hide the quantity badge for an empty cart;
show and update it for positive quantities, and keep the accessible label in
sync ("Open your bag, 2 items").
## Interior page depth
Read references/interior-pages.md. Preserve the complete page-specific
content, image roles, selection states and contextual actions of the
template. Do not reduce inner pages to a heading and a few sentences.
<!-- reui:stack -->
#### Interface components come from ReUI
In a React or Next.js output, every generic control in this template
(buttons, text fields, selects, radio groups, toggle groups, tabs,
accordions, filter chips, the mobile menu sheet, the bag drawer, dialogs) is
a [ReUI](https://reui.io) component, not a hand-written control. The catalog
template implements the same behaviour in plain HTML so it can run as one
file; `references/reui-components.md` maps each template control to its
ReUI component.
- Install from the official registry and use the real component source.
ReUI is a React component system built on Radix primitives; in a
Next.js/React project add components with the shadcn CLI
(`npx shadcn@latest add @reui/button`, and so on) and import them from
your `components/ui` directory. The component source also lives at
https://github.com/keenthemes/reui.
- Do not substitute a native `<select>`, a hand-rolled popover, or a `div`
with matching class names. If a control needs behaviour ReUI does not
provide (the quantity stepper, the range slider styling), build it
explicitly and say so.
- Style through tokens, not forks. Point ReUI's custom properties
(`--primary`, `--background`, `--border`, `--radius`, ...) at this
template's palette and keep its own control classes on the rendered
elements.
- In a non-React stack, check ReUI's real support before promising it.
Astro can mount React islands; a Vue or Svelte project cannot use ReUI
components directly; raise the conflict rather than switching stacks or
silently swapping in another library.
<!-- /reui:stack -->
User reviews
0 reviews
No reviews yet.
Ratings show up here once real people have tried it. We don’t display scores without the reviews behind them.
FAQ
What does the Skill deliver by default?
One self-contained file like the store demo, with fonts and images embedded, so it opens offline in any browser and works in a sandboxed preview. If you have a framework project or ask for one, your agent ports the design into real components and routes instead (Next.js App Router with TypeScript when you want a framework but do not name one).
Where do the bike photos come from?
Your agent generates the hero and catalogue shots with its own image tool from one prompt template, so backdrop, light and angle match; that may incur the tool's usage charges. On a small budget the image plan's minimum set uses one orange studio shot per model. Equipment and close-up images can be reused as neutral stand-ins, but the shipped bikes are never shown as your products.
Can I set my own currency, tax and delivery rules?
Yes. One settings block sets locale, currency, tax added or included, postcode format, delivery fees, the free-delivery threshold and the energy price, and prices, totals, postcode checks and the range calculator all read from it.







