Lab21 — Gordijn · Werking

Deze pagina laat zien welke invoervelden welke andere velden of berekeningen sturen. Gebruik dit om snel te begrijpen waarom een waarde verandert na een keuze, en waarom een artikel als «niet mogelijk» wordt gemarkeerd. Voor de exacte formules: zie Berekeningsregels.

Inhoudsopgave

  1. Legenda
  2. Hoofd-flow van de configurator
  3. Flow: kan dit artikel deze maten aan?
  4. Flow: snijhoogte (lengte per baan)
  5. Flow: benodigde stofbreedte
  6. Flow: aantal banen & totaal metrage
  7. Flow: verkoopprijs & eindprijs
  8. Flow: verzwaringskoord-keuze & onderzoom
  9. Flow: plooi-geschiktheid & vouwgordijn-flag
  10. Effect-matrix: welk veld stuurt wat?
  11. Flow: Style Engine (interieur-configurator)
  12. Flow: Vrije Keuze (product-selector)

1. Legenda

De flowcharts gebruiken vier soorten blokken:

Invoer Beslissing Berekening Resultaat Fout / blokkade

Pijlen lopen van boven naar beneden. Bij een beslissing splitst de flow zich, en de tak heeft een label (Ja, Nee, of de gekozen optie).

2. Hoofd-flow van de configurator

De stappen van de configurator volgen elkaar in vaste volgorde. Elke stap filtert of stuurt de volgende.

Configuratie-volgorde
Groep (sessie-context)groepnummer + omschrijving (bv. Slaapkamer links) — meegenomen in elke orderregel
Stap 1 — Type gordijnOvergordijn / Inbetween
Stap 2 — KlaarmatenKlaarBreedte + KlaarHoogte (cm)
Filter artikellijstop type + hoogte-feasibility
Stap 3 — Artikel kiezenuit gefilterde lijst
Stap 4 — Kleur
Stap 5 — BevestigingPlafond / Wand / In de dag
Stap 6 — Plooi & verdelingplooi, aantal delen, vliesband, hoofdje (0 / 2,5 mm)
Stap 7 — Voeringtype, kleur, prijs
Stap 8 — Afwerking & bedieningverzwaringskoord (Bestaande / Toevoegen / Nee) · Rail bediening (Handbediend / Elektrisch → Lab21 wizard) · Rail familie (DS / DS XL / KS, gefilterd op plooi) · Rail kleur · Trekstang (alleen handbediend) · Elektrisch → 6-vragen wizard (slim systeem · merk · stroom · bediening · terugkoppeling)
compute() → orderregels1 gordijn · 2 rail · 3 steun · 4 eind stk · 5 glider · 6 vertragingsglider · 7 voorloper (Wave) · 8 trekstang (handbediend) · totaal (excl. TBD)

3. Flow: kan dit artikel deze maten aan?

Bij het renderen van de artikellijst (stap 3) wordt per artikel een feasibility-check uitgevoerd. De uitkomst bepaalt of het artikel geschikt, kantel-fallback of niet mogelijk krijgt.

Per artikel — past het bij de klaarmaten?
Artikel met
kamerhoog, hoogte_stof,
kantelbaar, patroon
Bereken snijhoogte
= klaarhoogte + vliesband + onderzoom
kamerhoog = Ja?
Ja — Kamerhoog
snijhoogte
≤ hoogte_stof?
Ja
Geschikt
scenario: rechtop
Nee
kantelbaar = Ja
& patroon = Uni?
Ja
Geschikt
scenario: gekanteld
Nee
Niet mogelijk
hoogte stof te klein
Nee — Banenstof
Geschikt
geen hoogtegrens, lengte onbeperkt

4. Flow: snijhoogte (lengte per baan)

De snijhoogte is de lengte stof die per baan wordt afgesneden. KlaarHoogte, vliesband en onderzoom bepalen samen de snijhoogte. Patroonhoogte (rapport) telt niet mee — het atelier beoordeelt rapport-uitlijning bij verwerking.

Snijhoogte = klaarhoogte + vliesband + onderzoom
KlaarHoogte
uit stap 2
Vliesband
8 / 10 / 12 / 15 cm
Verzwaringskoord
Bestaande / Toevoegen / Nee
Koord aanwezig?
Bestaande of Toevoegen
Ja — koord
onderzoom = 2 cm
koord ingewerkt
Nee
onderzoom = 15 cm
gestoomde onderzoom
snijhoogte = klaarhoogte + vliesband + onderzoom (cm)

5. Flow: benodigde stofbreedte

De effectieve breedte hangt af van de plooi (retour vraagt extra slack) en aantal delen (zijzomen alleen kamerhoog).

benodigdeStofbreedte = effectieveBreedte × plooifactor  (+ zijzomen)
KlaarBreedte
uit stap 2
Plooi
Wave / Dubbel R / Enkel R / Dubbel / Enkel
Aantal delen
Stel / Links / Rechts
Plooi = Enkel retour
of Dubbel retour?
Ja
klaarbreedte
≥ 300 cm?
Ja
retourMarge = 10 % × klaarbreedte
Nee
retourMarge = 30 cm
Nee
retourMarge = 0
effectieveBreedte = klaarbreedte + retourMarge
Artikel kamerhoog = Ja?
Ja — Kamerhoog
+ aantalDelen × 24 cm zijzomen
Stel = 48, 1 deel = 24
Nee — Banenstof
geen zijzomen-toeslag
benodigdeStofbreedte (cm)
effectieveBreedte > 600 cm?
Ja
Waarschuwing
verdeel in 1 deel L + 1 deel R
Nee
OK

6. Flow: aantal banen & totaal metrage

De manier waarop banen worden geteld hangt af van of het artikel kamerhoog is, en bij kamerhoog of de stof gekanteld moet worden.

aantalBanen + lengte per baan → totaalMetrage
benodigdeStofbreedte
snijhoogte
artikel.hoogte_stof
artikel.breedte_stof
artikel.kantelbaar / patroon
kamerhoog = Ja?
Ja — Kamerhoog
snijhoogte
≤ hoogte_stof?
Ja — rechtop
aantalBanen = 1
totaalMetrage = stofbreedte / 100
Nee — kantelen
kantelbaar = Ja
& patroon = Uni?
Ja
koordverlies = bestaande koord? 2 : 0
alleen Bestaande kost stof; Toevoegen plaatst het koord pas na verwerking
baanBreedte = hoogte_stof − koordverlies
aantalBanen = ⌈stofbreedte / baanBreedte⌉
totaalMetrage = banen × snijhoogte / 100
Nee
Berekening stopt
artikel niet geschikt
Nee — Banenstof
aantalBanen = ⌈stofbreedte / breedte_stof⌉
totaalCm = banen × snijhoogte
totaalMetrage = totaalCm / 100

7. Flow: verkoopprijs & eindprijs

De stofprijs gebruikt het handmatige verkoopprijs_per_m1 als die is ingevuld; anders een 60−%-fallback gebaseerd op de inkoopprijs.

verkoopPrijs/m¹ → stofPrijs → totaalPrijs
artikel.verkoopprijs_per_m1
handmatig veld
artikel.prijs_per_m1
inkoop
verkoopprijs_per_m1
ingevuld & > 0?
Ja — handmatig
verkoopPrijs/m¹ = handmatige waarde
bron: handmatig
Nee — auto
verkoopPrijs/m¹ = inkoop × 3
afgerond op eerstvolgende xx,95
bron: auto
stofPrijs = totaalMetrage × verkoopPrijs/m¹
Voering ≠ Geen?
Ja
voeringPrijs/m¹ = voering_prijs_per_m1
óf inkoop × 0,60 (fallback)
voeringKosten = totaalMetrage × prijs
Nee
voeringKosten = 0
totaalPrijs = stofPrijs + voeringKosten

8. Flow: verzwaringskoord-keuze & onderzoom

De verzwaringskoord-keuze is een 3-state dropdown: Bestaande verzwaringskoord, Toevoegen verzwaringskoord of Nee. De artikel-flag geschikt_voor_verzwaringskoord bepaalt of de optie Toevoegen beschikbaar is.

Verzwaringskoord-keuze → onderzoom
Artikel.geschikt_voor_verzwaringskoord
Ja / Nee
geschikt = Ja?
Ja
3 opties beschikbaar:
Bestaande / Toevoegen / Nee
Nee
2 opties: Bestaande / Nee
Toevoegen verborgen

Configurator-keuze: Bestaande of Toevoegen
onderzoom = 2 cm
koord ingewerkt
bij gekanteld scenario:
baanBreedte − 2 cm
alleen bij Bestaande
Toevoegen geeft geen verlies

Configurator-keuze: Nee
onderzoom = 15 cm
gestoomde onderzoom

Patroon = Patroon (artikel)
Kantelbaar geforceerd op Nee
patroon mag niet 90° draaien
Patroonhoogte (rapport) telt niet mee in snijhoogte
atelier beoordeelt rapport bij verwerking

8b. Flow: hoofdje (afwerkings-keuze)

Het hoofdje is het smalle strookje stof bovenop de plooiband. Het is een configurator-keuze in Stap 6 — Plooi & verdeling die de atelier-afwerking documenteert — het beïnvloedt de snijhoogte niet. Mogelijke waarden: 0 of 2,5 mm. Bij Wave, Enkel retour en Dubbel retour is het hoofdje technisch altijd 0 — de configurator zet de keuze automatisch vast op 0 en deactiveert het veld.

Hoofdje-keuze (lock-rule)
Plooi-keuze
uit Stap 6 dropdown
Plooi = Wave / Enkel retour / Dubbel retour?
Ja
hoofdje = 0
veld vastgezet en gedeactiveerd
Nee — Enkel of Dubbel
hoofdje = gebruikerskeuze
0 of 2,5 mm

Hoofdje wordt opgeslagen als atelier-instructie. Geen invloed op snijhoogte of metrage.

9. Flow: plooi-geschiktheid & vouwgordijn-flag

Het artikel-veld geschikte_plooi (Multi-Select Picklist) bepaalt welke plooitypes voor deze stof zijn toegestaan. Daarnaast geldt een aparte regel: Wave plooi is alleen geschikt voor kamerhoog stoffen — bij banenstof valt Wave automatisch af, ook als het in geschikte_plooi staat. Bij keuze van een niet-geschikte plooi geeft de configurator een waarschuwing — de berekening blijft draaien, maar de gebruiker ziet duidelijk dat het advies is af te wijken.

Plooi-geschiktheid — per artikel
Artikel.geschikte_plooi
Wave / Dubbel R / Enkel R / Dubbel / Enkel
Plooi-keuze
uit Stap 6 dropdown
geschikte_plooi leeg?
Ja — geen restrictie
Alle plooien toegestaan
geen waarschuwing
Nee — restrictie aanwezig
plooi-keuze in lijst?
Ja
Geschikt
geen melding
Nee
Waarschuwing
"niet geschikt voor plooi X — geschikt: …"

Artikel.geschikt_vouwgordijn
Ja / Nee / Ja (ongevoerd)
Informatief — niet in berekening
Toont alleen welke stoffen óók als (Romeinse) vouwgordijn verwerkt mogen worden

Waar zichtbaar?

10. Effect-matrix: welk veld stuurt wat?

Snel naslagwerk: zoek een invoerveld in de eerste kolom, en zie welke andere velden of berekeningen daardoor veranderen.

Bron-veld (invoer) Stap Stuurt → doel-veld of berekening
Type gordijn 1 Filtert artikellijst (alleen artikelen met dat gordijn_type).
KlaarBreedte 2 retourMarge (drempel 300 cm)
effectieveBreedte
benodigdeStofbreedte
aantalBanen (banenstof of gekanteld)
→ waarschuwing > 600 cm
KlaarHoogte 2 rawSnijhoogtesnijhoogte
→ feasibility-check kamerhoog
totaalMetrage bij banenstof / gekanteld
Artikel.kamerhoog 3 Kiest scenario A (kamerhoog) of B (banenstof). Kamerhoog krijgt zijzomen-toeslag.
Artikel.hoogte_stof 3 Bovengrens voor kamerhoog rechtop. Bij gekanteld is dit de baan-breedte.
Artikel.breedte_stof 3 Bij banenstof: rolbreedte voor aantalBanen = ⌈stofbreedte/breedte_stof⌉.
Artikel.kantelbaar 3 Schakelt gekanteld scenario aan/uit. Wordt geforceerd Nee bij patroon.
Artikel.patroon (+ patroonhoogte) 3 Bij Patroon: forceert kantelbaar = Nee. Patroonhoogte (rapport) is informatief en telt niet mee in de snijhoogte — het atelier beoordeelt rapport-uitlijning bij verwerking.
Artikel.verkoopprijs_per_m1 3 Bron handmatig → stofPrijs. Leeg/0 → auto via inkoop×3 / xx,95.
Plooi 6 plooifactor (1.80–2.50)
retourMarge (alleen bij Enkel/Dubbel retour)
benodigdeStofbreedte
→ vergeleken met artikel.geschikte_plooi → waarschuwing als niet in lijst
Artikel.geschikte_plooi 3 Multi-Select lijst van toegestane plooien (Wave / Dubbel retour / Enkel retour / Dubbel / Enkel). Leeg = geen restrictie. Stuurt waarschuwing in stap 6 + badge-rendering in artikellijst en aside.
Artikel.geschikt_vouwgordijn 3 Picklist Ja / Nee / Ja (ongevoerd). Informatief — niet in metrage of prijs.
Aantal delen 6 → zijzomen-toeslag (Stel +48 / 1 deel +24, alleen kamerhoog).
Vliesband (8/10/12/15) 6 rawSnijhoogte.
Voering 7 Voering ≠ Geen toont kleur + prijsveld; vermenigvuldigt met totaalMetrage.
Verzwaringskoord (configurator) 8 3 opties: Bestaande, Toevoegen, Nee.
→ Bestaande/Toevoegen → onderzoom = 2 cm
→ Nee → onderzoom = 15 cm
→ bij gekanteld kamerhoog: alleen Bestaande kost 2 cm baan-breedte (koord wordt weggesneden). Toevoegen geeft geen verlies.
Artikel.geschikt_voor_verzwaringskoord 3 Veldlabel "Geschikt met verzwaringskoord" (Ja/Nee). Stuurt of de optie Toevoegen verzwaringskoord in de configurator beschikbaar is. Nee → optie verborgen.
Artikel.eenheid 3 Prijs-eenheid. Voor gordijnenstoffen ; voor accessoires evt. stuk. Wordt naast Inkoop- en Verkoopprijs getoond in de aside en in de prijsregel van de breakdown.
Trekstang (12 SKU's) 8 Alleen zichtbaar bij Handbediend. Materiaal (Fiber transparant / Wit aluminium / Zilver aluminium / Zwart aluminium) × lengte (92 / 122 / 152 cm). Klant kiest altijd zelf de lengte; per optie toont de configurator live de onderkant (onderkant = KlaarHoogte − lengte) met ✓ binnen 140–160 cm of ⚠ daarbuiten. Aanbeveling onder het veld: lengte dichtst bij 150 cm onderkant. Prijzen: 92 cm €19,95 / 122 cm €22,95 / 152 cm €24,95 incl. btw. Aantal stuks = aantal gordijn-delen.
Rail (8 SKU's, handbediend) 8 Familie × kleur. DS (wit/zwart) en DS XL (wit/antraciet/zilver) voor Wave + Retour; KS (wit/zwart/zilver) voor Enkel/Dubbel. Familie-dropdown wordt gefilterd op de gekozen plooi. Hoofdje wordt automatisch gezet: KS → 2,5 mm, DS / DS XL → 0 mm. Staaf à 600 cm; aantal staaven = ⌈KlaarBreedte÷600⌉, minimum 1. Prijzen lopen van €40 (KS wit) tot €150 (DS XL antraciet/zilver). Bij Elektrisch: TBD-orderregel.
Rail-toebehoren (TBD) 8 Per gordijn-orderregel automatisch toegevoegd, artikelnummers to be filled: steun (platformsteun bij plafond/in-de-dag, wandsteun bij wand) — 1 stk per 50 cm; eind stuk — 2 stk; glider — 10 per meter klaarbreedte; vertragingsglider — 1 stk; voorloper — 2 stk alleen bij Wave plooi.
Elektrische bediening — Lab21 wizard 8 Bij keuze Elektrisch verschijnt een 6-vragen wizard (afgeleid van Forest Group stappenplan, met Forest → Lab21). Vragen: 1) slim systeem aanwezig, 2) via slim systeem bedienen, 3) type systeem (Domotica / Smart Home), 3a) merk (Somfy / HUE / IKEA / Apple HomeKit / Homey / Fibaro / KAKU / SmartThings / Apple Siri / Luxaflex / Google·Amazon / Coulisse), 3b) type domotica (RS232/485 / spanningsvrij / schakeldraden), 4) stroompunt bij motor, 5) bediening (multi: AB / wandschakelaar / app / spraak / domotica), 6) terugkoppeling. Live advies onder de wizard met Dé oplossing (Lab21 Shuttle motor + WiFi dongel / Wireless Connector / Diamond Sense AB / Wandschakelaar / Externe RF Multi ontvanger / RJ-45 / AC Control Set) en extras. Third-party stekkers (HomeKit / KAKU / Z-Wave / Somfy / HUE / IKEA / Powerview) markeert de wizard expliciet als extern, niet via Lab21. Alle componenten verschijnen als aparte orderregels met prijs to be filled.
Wave plooi-regel 6 Wave plooi is alleen geschikt voor kamerhoog stoffen. Bij banenstof valt Wave automatisch af in de plooi-keuze (waarschuwing + uitsluiting in dropdown).

11. Flow: Style Engine (interieur-configurator)

De pagina style-configurator.html is een aparte tool die de woonstijl en kleurvoorkeur van een klant vertaalt naar een gestructureerd JSON-profiel. Dit profiel wordt door de externe AI-visualizer-API van Kevin gebruikt om meubels in een foto van de klant te plaatsen.

6-staps trechter — van inspiratie tot Style Profile JSON
Stap 1 — WoonstijlIndustrieel / Scandinavisch / Modern / Landelijk
Filter kleur-paletten3 van 4 paletten passend bij de gekozen stijl
Stap 2 — Kleur-paletWarm & Geborgen / Koel & Fris / Krachtig Contrast / Natuurlijk
Stap 3 — Meubel-inventarisatiefoto + L×B×H per behouden meubel (optioneel)
Stap 4 — Project-scope (multi-select)Vloer / Raamdecoratie / Muur / Meubelen — minstens één
Stap 5 — Raamdecoratie per raammaten + kozijn + doel-klant → Top-4 uit oplossingen-matrix
'window_decor' niet in scope?
→ sla stap 5 over
Stap 6 — Foto-uploadJPG / PNG / WEBP — drag-drop of klik
buildStyleProfile()stijl + palet + scope + meubels + ramen + tags
Style Profile JSON+ kapstalen-IDs per raam → showroom-koppeling
Adviseur-CTA"Vraag fysieke stalen van dit ontwerp"

Filtering — stijl stuurt het palet

Stap 2 toont alle vier de paletten, maar zwakt er telkens één af die stilistisch botst. Niet-passende paletten blijven klikbaar in beeld zodat de gebruiker ziet waarom de keuze inkrimpt — een blokkade in plaats van verbergen voorkomt verwarring.

StijlToegelaten paletten (volgorde)Afgezwakt
IndustrieelKrachtig Contrast · Warm & Geborgen · NatuurlijkKoel & Fris
ScandinavischKoel & Fris · Warm & Geborgen · NatuurlijkKrachtig Contrast
Modern / MinimalistischKoel & Fris · Krachtig Contrast · Warm & GeborgenNatuurlijk
Landelijk / KlassiekWarm & Geborgen · Natuurlijk · Krachtig ContrastKoel & Fris

Oplossingen-matrix — doel-klant filtert raamdecoratie (stap 5)

Per raam selecteert de klant één of meer doelen (privacy, verduistering, akoestiek, hitte/UV, …). De functie filterRaamOplossingen(goals) filtert de matrix uit de bron-spreadsheet en toont de Top 4 combinaties die alle doelen afdekken, gesorteerd op veelzijdigheid.

// TypeScript-equivalent voor AI-pipeline
function filterRaamOplossingen(goals: string[]): RaamOplossing[] {
  if (!goals.length) return [...RAAM_OPLOSSINGEN].sort(byCoverage);
  return RAAM_OPLOSSINGEN
    .filter(o => goals.every(g => o.goals.includes(g)))
    .sort((a, b) => b.goals.length - a.goals.length);
}

De 15 combinaties uit de matrix dekken alle producten van het bronbestand: Inbetween, Overgordijn, Jaloezie, Duette (incl. transparante variant) en Rolgordijn — solo of in combinaties van 2-3 producten.

Auto-waarschuwingen per raam (stap 5)

Kapstalen-ID — showroom-koppeling

Per gekozen raamdecoratie-combinatie wordt automatisch een kapstalen_id gegenereerd in de vorm KAP-{stijl}-{palet}-{producten}-{nr}. De verkoper in de showroom weet daarmee direct welke fysieke stalen uit het rek te halen.

generateKapstalenId('Industrial', 'Warm_Earth', 'inb_over_jal', 1)
// → "KAP-IND-WE-INB-OG-JAL-001"

Uitgebreide JSON-output (input voor Kevin's visualizer-API)

De primaire sleutels zijn nog steeds style_id en color_palette_id; daarnaast gaan nu project_scope, existing_furniture en per-raam window_specs mee — inclusief technische advanced-velden en de Kapstalen-ID die de verkoper aan de showroom koppelt.

{
  "style_id": "Industrial",
  "color_palette_id": "Warm_Earth",
  "project_scope": ["flooring", "window_decor", "wall", "furniture"],
  "existing_furniture": [
    { "type": "Bank", "dimensions": { "l": 220, "w": 90, "h": 80 }, "image_url": "data:…" }
  ],
  "window_specs": [
    {
      "name": "Raam 1",
      "dimensions": { "width": 1800, "height": 2400 },
      "frame_material": "kunststof",
      "operable_type": "bewegend",
      "mounting": "in_de_dag",
      "function_goals": ["privacy", "verduistering", "akoestiek"],
      "suggested_products": ["inbetween", "overgordijn", "duette"],
      "kapstalen_id": "KAP-IND-WE-INB-OG-DUE-001",
      "advanced": { "vol_muur": false, "draaikiep": true, "…": "…" }
    }
  ],
  "customer_photo_url": "data:image/jpeg;base64,…",
  "ai_prompt_tags": ["exposed brick walls", "warm earth tones", "…"],
  "meta": { "ai_suggested": false, "furniture_count": 1, "window_count": 1, "…": "…" }
}

Bijzonderheden

12. Flow: Vrije Keuze (product-selector)

De pagina product-selector.html is een parallel pad voor klanten die geen stijl- of kleuradvies willen, maar direct uit een catalogus kiezen. De Style Engine en de Product Selector zijn cross-linked — de gebruiker kan op elk moment switchen.

4-staps shopping-flow — van scope tot render-input
Stap 1 — Scope (multi-select)Vloer / Raamdecoratie / Muur* / Meubels* (* = roadmap)
Stap 2 — Eigen meubelsfoto + L×B×H per object dat blijft staan
Stap 3 — Productentabs (Vloer / Raamdecor) + filters + grid + winkelmandje
Validatie
kozijn-conflict?
combinatie-assistent?
Stap 4 — Foto-uploadJPG / PNG / WEBP — ruimte van de klant
Free-Selection JSONmode: "free_selection" + Product_IDs + Texture_Maps

Validatie-regels in de winkelmand

Het winkelmandje (sticky zijpaneel) draait validateCart() live na elke productwijziging en toont waarschuwingen + alternatieven:

Elke notice heeft een klikbaar alternatief; één klik voegt het voorgestelde product direct aan de mand toe.

Free-Selection JSON-output

Het schema volgt de briefing exact, met arrays waar combinaties mogelijk zijn (Inbetween + Duette). texture_map wijst naar een statische CDN-URL die Kevin's diffusion-pipeline inlaadt.

{
  "mode": "free_selection",
  "project_scope": ["flooring", "window_decor"],
  "selected_products": {
    "floor": {
      "id": "PVC_OAK_HERR_001", "pattern": "visgraat", "material": "PVC",
      "texture_map": "/textures/floor/PVC_OAK_HERR_001.jpg"
    },
    "window": [
      { "id": "DUE_BLK_003", "product_type": "duette",
        "mount": "clamp_on_frame",
        "texture_map": "/textures/window/DUE_BLK_003.jpg" },
      { "id": "INB_LIN_NAT_001", "product_type": "inbetween",
        "mount": "wall_mount",
        "texture_map": "/textures/window/INB_LIN_NAT_001.jpg" }
    ]
  },
  "window_context": { "frame_material": "kunststof", "draaikiep": true, "mounting": "in_de_dag" },
  "custom_furniture": [
    { "id": "user_sofa_1", "type": "Bank", "dimensions": [220, 90, 80], "image_url": "data:…" }
  ],
  "floor_plan": {
    "filename": "plattegrond_woonkamer.pdf",
    "mime_type": "application/pdf",
    "size_bytes": 234567,
    "data_url": "data:application/pdf;base64,…"
  },
  "room_photo": "data:image/jpeg;base64,…",
  "validation_notices": [
    { "icon": "ℹ", "message": "Draai-/kiepraam: gekozen producten blokkeren kantelen …" }
  ],
  "meta": { "floor_count": 1, "window_count": 2, "furniture_count": 1, "…": "…" }
}

Verschillen Style Engine vs. Vrije Keuze

AspectStyle EngineVrije Keuze
InstapStijl + kleur als ankerDirect in de catalogus
JSON-mode(impliciet)"mode": "free_selection"
ProductkeuzeAI suggereert (Top 4 uit matrix)Klant kiest zelf uit grid
Output naar AIstyle_id + color_palette_id + tagsProduct_ID + texture_map per item
Cross-link"🛍️ Vrije keuze" in luck-bar"Help me kiezen op basis van mijn stijl" in switch-bar
Visueel designIdentiek — gedeelde stylesheet style-engine.css

Gedeelde stylesheet (DRY)

Beide pagina's linken style-engine.css voor alle visuele basis: header, voortgangsbalk, knoppen, .tile, .upload-zone, .toast, .final-note, .plan-upload, gradient-achtergronden en mobile-tweaks. De scope-tegels in stap 1 (Vrije Keuze) en stap 4 (Style Engine) gebruiken nu dezelfde .tile + bg-* + SVG-icoon combinatie zodat de twee paden 1-op-1 dezelfde look-and-feel hebben.

Page-specifieke componenten (Style Engine: raam-cards, top4-grid, profile-summary, advanced-details; Vrije Keuze: tabs, filter-bar, product-grid, cart-panel, ctx-card) blijven inline op de pagina zelf — dat is bewust, ze hoeven niet gedeeld te worden en houden het CSS-bestand klein.

↑ Terug naar boven