Design system & developer handoff
Everything a custom-code team needs to implement the Papylon storefront: tokens, components and states, responsive rules, routes, legacy URL mapping, content schema, asset manifest, SEO, analytics events and backend dependencies. No backend framework is prescribed.
Papylon.dc.htmlStorefront prototype. Hash router, all page families, local state (cart, wishlist, consent) in localStorage.
papylon-data.jsAll content: products, categories, legacy map, stores, shipping, collections, articles, legal, FAQ, owner register. Layout never hardcodes prices or names.
ProductCard.dc.htmlThe only shared child component; receives a view-model p.
1. Tokens
Colour (contrast computed against white and canvas)
Adjustments from the brief: input/control borders use #8C94A0 (≈3.1:1 on white) because #D9DDE3 fails the 3:1 non-text contrast requirement; #D9DDE3 stays for dividers. Success text #17563A and error-on-tint text #8A1B12 were added. Warm accent never carries white text.
Typography — Manrope (fallback: "Segoe UI", system-ui, sans-serif; Latin Extended-A covers č ć š ž đ)
{{ t.token }}{{ t.spec }}{{ t.sample }}Display sizes use clamp(): H1 hero clamp(34px, 5.2vw, 64px), page H1 clamp(28px, 3.6vw, 44px), section H2 clamp(26px, 3vw, 36px). Mobile hero lands at 34–36 px. Product names are never uppercase; source titles are normalised in name and preserved in sourceTitle.
Spacing (4/8 base)
{{ s.t }}{{ s.px }}Radii, shadows, layers
{{ m.t }}{{ m.v }}Grid
Max content width 1280 px (1344 incl. gutters). 12-column desktop grid, 24–32 px outer gutters; 16 px on mobile.
Product grids: repeat(auto-fill, minmax(clamp(150px, 42vw, 220px), 1fr)) → 4 columns beside the filter rail at 1440, 2 columns at 360–390.
2. Components and states
Specimens use the same inline values as the storefront. One primary CTA treatment across every department.
Button · primary
Button · secondary, text, chip
Form field
Labels always visible above fields; errors linked via aria-describedby, aria-invalid; icon + text, never colour alone. Form-level error summary links to fields.
Price block, badges, stock
One badge per card (sale beats verified age). Previous price only when previous_price_eur_cents exists. Exact stock quantity is never shown.
Product card (live component)
Direct purchase from a card only for simple products; otherwise “Pogledaj proizvod” (second card = unavailable variant). Title clamped to two lines, full name in title and link text.
Feedback: toast, alerts, empty
Review component — DEMONSTRATION STATE ONLY
Not used on any PDP. Enable only with verified customer reviews from a real review service.
[Tekst recenzije iz verifikovanog izvora] · [ime] · [datum]
Component inventory
3. Responsive rules
Header/menu breakpoint: 980 px. Everything else reflows intrinsically (flex-wrap, auto-fill grids, clamp type). No horizontal page scroll; rails scroll horizontally inside their own container with snap.
4. Interaction specifications
{{ i.t }}
{{ i.d }}
5. Routes and templates
Prototype uses #/route; production should use real paths. Product slugs are preserved from the current site.
{{ r.r }}6. Legacy URL mapping ({{ legacyCount }})
All 301 redirects. route = own canonical page · facet = parent listing with pre-applied filter · merge = duplicate concept consolidated, products kept · redirect = renamed · exclude = no public route. Product URLs /proizvod/{slug}/ are unchanged.
7. Content schema
{{ s.title }}
{{ f.k }}{{ f.d }}8. Product data & asset manifest ({{ productCount }})
Observed 25 Sep 2026. Lead image = first image. All images currently hotlinked from papylon.me — localise and obtain owner approval of publishing rights before launch. All images loaded successfully in review; visual match of gallery images should be confirmed by the owner.
9. SEO & structured data
- One H1 per page (implemented in the prototype; PDP renders the H1 once for mobile or desktop).
- Breadcrumb markup follows the canonical category path →
BreadcrumbList. - PDP:
Productwith name, image, sku, brand;Offerwith price, priceCurrency EUR, availability — generated from the same price/stock source as the UI. Book-specific fields (author, ISBN) only when verified. - Stores:
Store/LocalBusinessonly after addresses and hours are confirmed. - No
AggregateRatinguntil real reviews exist. - Filtered listings: canonical to the unfiltered category; do not index arbitrary facet combinations.
10. Suggested analytics events
Not installed in the prototype. Fire only after consent for analytics.
{{ e.n }}11. Backend dependencies
{{ d.n }}
{{ d.req }}{{ d.d }}
12. Image guidance
- Image wells reserve space with
aspect-ratio(1:1 cards and PDP, 4:3 department tiles); images useobject-fit: contain— covers are never cropped. - Card wells use a warm tint with
mix-blend-mode: multiplyso white-background product photos sit on the surface; PDP galleries stay on pure white for colour accuracy. - Serve responsive sources (
srcset: 240, 480, 960, 1440 w) as WebP/AVIF with JPEG fallback; lazy-load below the fold, eager-load the PDP lead image and hero. - Alt text: product name + what is shown (cover, contents, packaging). Decorative shapes and duplicate thumbnails use empty alt.
- Excluded: Zu-Zu secondary image (filename references Jojo), 100 zadataka 5 godina fourth image (filename references 4 godine), CGB bedž (WooCommerce placeholder only).