Milinda Uitgevers — Herontwerp Mobiele Webshop
Pitch voor het herontwerp van de webshop van Milinda Uitgevers
📖 Over dit project
Dit project is een pitch voor het herontwerp van de webshop van Milinda Uitgevers. De huidige website is ruim vijftien jaar oud en voldoet niet meer aan de eisen van vandaag op het gebied van responsive design en toegankelijkheid.
Doelstelling
Het doel van dit herontwerp is om:
- Gebruiksgemak op alle platforms — Een volledig responsieve mobiele ervaring die naadloos werkt op smartphones, tablets en desktops
- Toegankelijkheid — Volledige ondersteuning voor gebruikers met een beperking (WCAG-richtlijnen)
- Behoud van de "feel" — De oorspronkelijke sfeer en identiteit van de website behouden terwijl de visuele presentatie wordt gemoderniseerd
Waarom deze aanpak?
We hebben gekozen voor een Web Components-architectuur om de volgende redenen:
- Geen externe frameworks — Werkt met vanilla JavaScript, geen React/Vue/Angular nodig
- Eenvoudige integratie — De componenten kunnen gemakkelijk worden geïntegreerd met de bestaande back-end
- Toekomstbestendig — Web Components zijn een webstandaard en werken in alle moderne browsers
- Modulair — Elk component is zelfstandig en herbruikbaar
- Geen server-side libraries — Volledig client-side, zoals gevraagd in de opdracht
🚀 Project starten
Vereisten
Installatie
De applicatie is vervolgens beschikbaar op http://localhost:3000.
Beschikbare pagina's
| Pagina |
URL |
Beschrijving |
| Homepage |
/index.html |
Overzicht met uitgelichte boeken, categorieën en nieuwsbrief |
| Boekdetail |
/book.html |
Detailpagina voor "Zen is opendoen" |
📁 Projectstructuur
🧩 Componenten
Layout Componenten
| Component |
Bestand |
Beschrijving |
<site-header> |
site-header.js |
Sticky header met scroll-gedrag: klapt in bij scrollen naar beneden, verschijnt bij omhoog scrollen |
<top-bar> |
top-bar.js |
Bovenste balk met logo, menu-knop en acties (profiel, winkelwagen) |
<horizontal-scroll-nav> |
horizontal-scroll-nav.js |
Horizontaal scrollbare categorie-navigatie met pill-vormige knoppen |
<search-bar> |
search-bar.js |
Zoekbalk met spraakherkenning (Nederlands) en zoek-icoon |
<site-content> |
site-content.js |
Wrapper voor de hoofdinhoud van de pagina |
<site-footer> |
site-footer.js |
Footer met accordion-secties en linkkolommen |
<mobile-drawer> |
mobile-drawer.js |
Slide-in navigatiemenu vanaf de linkerzijde met backdrop |
Content Componenten
| Component |
Bestand |
Beschrijving |
<book-card> |
book-card.js |
Boekkaart met cover, titel, beschrijving, auteur en prijs. Ondersteunt licht/donker thema |
<book-details> |
book-details.js |
Uitgebreide boekdetails met metadata, categorieën en koopknoppen |
<book-description> |
book-description.js |
Gestileerde boekbeschrijving met citaten |
<book-reviews> |
book-reviews.js |
Container voor boekrecensies |
<book-review-item> |
book-review-item.js |
Individuele recensie met sterren, auteur en datum |
<category-card> |
category-card.js |
Categoriekaart met icoon en titel |
<image-gallery> |
image-gallery.js |
Afbeeldingsgalerij met thumbnails |
<content-tabs> |
content-tabs.js |
Tabblad-interface voor verschillende secties (Beschrijving, Inzage, Recensies) met volledige keyboard navigatie |
Interactieve Componenten
| Component |
Bestand |
Beschrijving |
<push-box> |
push-box.js |
Promotionele container met logo, titel en CTA. Ondersteunt variant="purple" |
<newsletter-signup> |
newsletter-signup.js |
Nieuwsbrief aanmeldformulier met e-mail input |
<footer-accordion-item> |
footer-accordion-item.js |
Inklapbare sectie voor de footer met ARIA-ondersteuning |
<add-to-cart-button> |
add-to-cart-button.js |
Plus-knop voor toevoegen aan winkelwagen |
Button Componenten
| Component |
Bestand |
Beschrijving |
<arrow-button> |
arrow-button.js |
Link met ronde pijl-icoon |
<cta-button> |
cta-button.js |
Full-width call-to-action knop |
<icon-cta-button> |
icon-cta-button.js |
CTA knop met icoon (winkelwagen, e-book) |
<icon-link-button> |
icon-link-button.js |
Link met icoon (verlanglijstje, recensie) |
<action-links-list> |
action-links-list.js |
Gegroepeerde actie-links |
Utility Componenten
| Component |
Bestand |
Beschrijving |
<section-title> |
section-title.js |
Consistente sectietitel |
🎨 Iconen
Alle iconen zijn geïmplementeerd als Web Components en/of exporteerbare functies. Ze ondersteunen size, color en stroke-width attributen.
| Icon Component |
Bestand |
Beschrijving |
<menu-icon> |
menu-icon.js |
Hamburger menu icoon (3 lijnen) |
<user-icon> |
user-icon.js |
Gebruikersprofiel icoon |
<shopping-bag-icon> |
shopping-bag-icon.js |
Boodschappentas icoon |
<arrow-circle-right-icon> |
arrow-circle-right-icon.js |
Pijl in cirkel (rechts) |
<book-open-icon> |
book-open-icon.js |
Open boek icoon (placeholder) |
<clipboard-icon> |
clipboard-icon.js |
Klembord icoon |
<chevron-down-icon> |
chevron-down-icon.js |
Pijl naar beneden (accordion) |
<close-icon> |
close-icon.js |
Sluiten/kruis icoon |
Icon Functies
| Functie |
Bestand |
Beschrijving |
micIcon() |
mic.js |
Microfoon icoon (spraakherkenning) |
searchIcon() |
search.js |
Vergrootglas icoon |
sendIcon() |
send-icon.js |
Verstuur/pijl icoon (nieuwsbrief) |
🎨 Design System
Lettertypen
| Font |
Gewichten |
Gebruik |
| Outfit |
400 (Regular), 700 (Bold) |
Primair lettertype voor alle tekst, titels en UI elementen |
| System fonts |
- |
Fallback: system-ui, -apple-system, etc. |
Het Outfit lettertype wordt geladen via Google Fonts CDN.
Kleuren
Primaire Kleuren
| Naam |
Waarde |
CSS Variable |
Gebruik |
| Purple (primair) |
#951D51 |
--color-button-primary, --color-purple |
Knoppen, links, accenten |
| Purple Dark |
#7A1842 |
--color-purple-dark |
Hover states |
Tekst Kleuren
| Naam |
Waarde |
CSS Variable |
Gebruik |
| Text |
#1E293B |
--color-text |
Primaire tekst |
| Text Light |
#64748B |
--color-text-light |
Secundaire tekst |
| Text Inverse |
#FFFFFF |
--color-text-inverse |
Tekst op donkere achtergrond |
| Black |
#000000 |
--color-black |
Titels en koppen |
Achtergrond Kleuren
| Naam |
Waarde |
CSS Variable |
Gebruik |
| Background |
#FFFFFF |
--color-background |
Primaire achtergrond |
| Background Secondary |
#F8FAFC |
--color-background-secondary |
Pagina achtergrond |
| Background Tertiary |
#F1F5F9 |
--color-background-tertiary |
Cards, secties |
| Push Box BG |
#EBEEF4 |
--color-push-box-bg |
Promotie blokken |
| Card Dark BG |
#EBEEF4 |
--color-card-dark-bg |
Donkere kaarten |
| Category Card |
#F5F4FC |
- |
Categorie kaarten |
Overige Kleuren
| Naam |
Waarde |
CSS Variable |
Gebruik |
| Border |
#E2E8F0 |
--color-border |
Borders en scheidingslijnen |
| Accent |
#F59E0B |
--color-accent |
Sterren, favoriet icoon |
| Success |
#22C55E |
--color-success |
Bevestigingen |
| Error |
#EF4444 |
--color-error |
Foutmeldingen |
Spacing
| Naam |
Waarde |
CSS Variable |
| XS |
4px (0.25rem) |
--spacing-xs |
| SM |
8px (0.5rem) |
--spacing-sm |
| MD |
16px (1rem) |
--spacing-md |
| LG |
24px (1.5rem) |
--spacing-lg |
| XL |
32px (2rem) |
--spacing-xl |
| 2XL |
48px (3rem) |
--spacing-2xl |
Typografie Schaal
| Naam |
Waarde |
CSS Variable |
| XS |
12px (0.75rem) |
--font-size-xs |
| SM |
14px (0.875rem) |
--font-size-sm |
| Base |
16px (1rem) |
--font-size-base |
| LG |
18px (1.125rem) |
--font-size-lg |
| XL |
20px (1.25rem) |
--font-size-xl |
| 2XL |
24px (1.5rem) |
--font-size-2xl |
| 3XL |
30px (1.875rem) |
--font-size-3xl |
Border Radius
| Naam |
Waarde |
CSS Variable |
| SM |
4px (0.25rem) |
--radius-sm |
| MD |
8px (0.5rem) |
--radius-md |
| LG |
12px (0.75rem) |
--radius-lg |
| XL |
16px (1rem) |
--radius-xl |
| Full |
9999px |
--radius-full |
Transities
| Naam |
Waarde |
CSS Variable |
| Fast |
150ms ease |
--transition-fast |
| Normal |
250ms ease |
--transition-normal |
| Slow |
350ms ease |
--transition-slow |
♿ Toegankelijkheid (WCAG)
Dit project is gebouwd met toegankelijkheid als prioriteit en volgt de WCAG 2.1 richtlijnen.
Geïmplementeerde functies
Skip-to-content link
- Verborgen link die verschijnt bij keyboard focus
- Stelt gebruikers in staat direct naar de hoofdinhoud te navigeren
- Slaat herhalende navigatie-elementen over
Semantische HTML
- Correcte gebruik van
<header>, <nav>, <main>, <footer>, <section>, <article>
- Logische heading hiërarchie (h1, h2, h3)
<main> element met id="main-content" voor skip-link target
ARIA Labels en Rollen
aria-label op alle icon buttons (menu, profiel, winkelwagen, zoeken, etc.)
aria-expanded en aria-controls op accordion componenten
role="tablist", role="tab", en role="tabpanel" voor tabbed interfaces
aria-selected voor actieve tabs
aria-current voor actieve navigatie-items
aria-pressed voor toggle buttons
Keyboard Navigatie
- Alle interactieve elementen zijn bereikbaar met Tab
- Tab componenten ondersteunen pijltjestoetsen (←/→), Home, en End
- Escape sluit de mobile drawer
- Zichtbare focus indicators op alle focusable elementen
- Logische focus volgorde
Formulieren
aria-label op input velden
- Associatie tussen labels en inputs
- Duidelijke foutmeldingen
Spraakherkenning
- Zoekfunctie met Nederlandse spraakherkenning (
lang="nl-NL")
- Visuele feedback tijdens luisteren (pulse animatie)
- Graceful degradation in browsers zonder ondersteuning
Taal
lang="nl" attribuut op HTML element
- Correcte taalinstelling voor screenreaders
Focus Stijlen
Alle interactieve elementen hebben duidelijke focus indicators:
📱 Responsive Design
Het ontwerp is mobile-first gebouwd met een maximale breedte van 430px voor de mobiele container. Op grotere schermen wordt de mobiele weergave gecentreerd weergegeven met een schaduw.
Breakpoints
| Breakpoint |
Gedrag |
| < 431px |
Volledige breedte, mobiele ervaring |
| ≥ 431px |
Gecentreerde container met afgeronde hoeken en schaduw |
🔧 Technische details
Browser ondersteuning
- Chrome 90+
- Firefox 90+
- Safari 14+
- Edge 90+
Geen build stap nodig
Het project maakt gebruik van native ES modules en heeft geen build tooling nodig. Alle JavaScript wordt direct door de browser geladen.
State management
Een eenvoudige winkelwagen store (js/store/cart.js) beheert de winkelwagen state met:
addItem() — Voeg item toe
removeItem() — Verwijder item
getItems() — Haal alle items op
getTotal() — Bereken totaal
getItemCount() — Tel items
Events worden gedispatched voor reactieve updates.
📞 Contact
Tim Rijkse
Front-end Developer
📄 Licentie
Dit project is gemaakt als onderdeel van een pitch voor Milinda Uitgevers en mag uitsluitend worden gebruikt indien de opdracht wordt gegund.
Gemaakt met ❤️ voor boeken en boeddhisme