/* ============================================================================
 * WoodSucces offerte calculator
 * Kleuren en font komen uit de bestaande Elementor globals van de site:
 *   #283618 donkergroen, #151515 bijna zwart, #FEFAE0 crème, Montserrat
 * ========================================================================== */

.ws-wrap {
  --ws-green: #283618;
  --ws-green-dark: #1c2611;
  --ws-ink: #151515;
  --ws-cream: #FEFAE0;
  --ws-paper: #ffffff;
  --ws-line: #e2e0cf;
  --ws-muted: #6b6b60;
  --ws-accent: #8a9a5b;
  --ws-warn-bg: #fff4d6;
  --ws-warn-line: #e6c65c;
  --ws-warn-ink: #6b5310;
  --ws-radius: 14px;
  --ws-shadow: 0 2px 4px rgba(21, 21, 21, .06), 0 12px 28px rgba(21, 21, 21, .07);

  font-family: "Montserrat", system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--ws-ink);
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 20px 140px;
  box-sizing: border-box;
}

.ws-wrap *, .ws-wrap *::before, .ws-wrap *::after { box-sizing: inherit; }

/* --- Banner voorlopige prijzen ----------------------------------------- */
.ws-banner {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: var(--ws-warn-bg);
  border: 1px solid var(--ws-warn-line);
  border-left-width: 5px;
  border-radius: 10px;
  padding: 14px 18px;
  margin: 0 0 28px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ws-warn-ink);
}
.ws-banner strong { display: block; margin-bottom: 2px; }
.ws-banner-icon { font-size: 18px; line-height: 1.3; }

/* --- Voortgang --------------------------------------------------------- */
.ws-progress { margin: 0 0 30px; }
.ws-progress-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 13px;
  font-weight: 600;
  color: var(--ws-muted);
  margin-bottom: 8px;
}
.ws-progress-pct { color: var(--ws-green); font-size: 15px; }
.ws-progress-track {
  height: 8px;
  background: var(--ws-line);
  border-radius: 99px;
  overflow: hidden;
}
.ws-progress-fill {
  height: 100%;
  width: 0;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--ws-accent), var(--ws-green));
  transition: width .45s cubic-bezier(.4, 0, .2, 1);
}

/* --- Layout ------------------------------------------------------------ */
.ws-layout { display: grid; grid-template-columns: 1fr; gap: 28px; align-items: start; }
@media (min-width: 1000px) {
  .ws-layout { grid-template-columns: minmax(0, 1fr) 340px; gap: 34px; }
  .ws-aside { position: sticky; top: 24px; }
}

/* --- Stap --------------------------------------------------------------- */
.ws-step {
  background: var(--ws-paper);
  border: 1px solid var(--ws-line);
  border-radius: var(--ws-radius);
  padding: 22px 22px 24px;
  margin: 0 0 18px;
  box-shadow: 0 1px 2px rgba(21, 21, 21, .04);
}
.ws-step[hidden] { display: none; }
.ws-step-n {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ws-accent);
  margin-bottom: 6px;
}
.ws-step h3 {
  margin: 0 0 4px;
  font-size: 21px;
  font-weight: 700;
  line-height: 1.25;
  color: var(--ws-ink);
}
.ws-step p.ws-hint {
  margin: 0 0 18px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ws-muted);
}

/* --- Tegels ------------------------------------------------------------- */
.ws-tiles { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.ws-tiles.is-wide { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }

.ws-tile { position: relative; display: block; cursor: pointer; }
.ws-tile input {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
  margin: 0;
}
/* spans, so they need their display set: left inline the card collapses and
   only its rounded corners paint */
.ws-tile-inner {
  display: flex;
  flex-direction: column;
  height: 100%;
  border: 2px solid var(--ws-line);
  border-radius: 12px;
  overflow: hidden;
  background: var(--ws-paper);
  transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}
.ws-tile:hover .ws-tile-inner { border-color: var(--ws-accent); transform: translateY(-2px); }
.ws-tile input:checked + .ws-tile-inner {
  border-color: var(--ws-green);
  box-shadow: 0 0 0 3px rgba(40, 54, 24, .12);
}
.ws-tile input:focus-visible + .ws-tile-inner { outline: 3px solid var(--ws-accent); outline-offset: 2px; }

.ws-tile-img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: var(--ws-line);
}
.ws-tile-swatch { display: block; width: 100%; height: 54px; }
.ws-tile-body { display: block; flex: 1; padding: 10px 12px 12px; }
.ws-tile-label { display: block; font-size: 14px; font-weight: 600; line-height: 1.3; }
.ws-tile-sub { display: block; font-size: 12px; color: var(--ws-muted); margin-top: 2px; line-height: 1.35; }
.ws-tile-price {
  display: block;
  margin-top: 7px;
  font-size: 13px;
  font-weight: 700;
  color: var(--ws-green);
}
.ws-tile input:checked + .ws-tile-inner .ws-tile-price { color: var(--ws-green-dark); }

.ws-tile-check {
  position: absolute;
  top: 8px; right: 8px;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--ws-green);
  color: #fff;
  display: none;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  line-height: 1;
}
.ws-tile input:checked ~ .ws-tile-check { display: flex; }

/* --- Schuifregelaars en getallen ---------------------------------------- */
.ws-field { margin-bottom: 18px; }
.ws-field:last-child { margin-bottom: 0; }
.ws-field > label { display: block; font-size: 14px; font-weight: 600; margin-bottom: 7px; }
.ws-field-row { display: flex; align-items: center; gap: 14px; }
.ws-field-row input[type="range"] { flex: 1; min-width: 0; accent-color: var(--ws-green); }
.ws-out {
  min-width: 78px;
  text-align: center;
  font-weight: 700;
  font-size: 15px;
  padding: 7px 10px;
  border-radius: 9px;
  background: var(--ws-cream);
  border: 1px solid var(--ws-line);
}

/* Het element staat er bewust voor. Het gekloonde thema heeft
 *   input[type=text],input[type=email],...{border:1px solid #666;
 *   border-radius:3px;padding:.5rem 1rem;width:100%}
 * en dat is (0,1,1), dus een kale .ws-input van (0,1,0) verliest en het veld
 * kreeg stilletjes de grijze themarand. input.ws-input is (0,2,1) en wint.
 * Kort je dit in tot .ws-input, dan komt de themastijl terug. */
.ws-wrap input.ws-input,
.ws-wrap select.ws-select,
.ws-wrap textarea.ws-textarea {
  width: 100%;
  font: inherit;
  font-size: 15px;
  padding: 11px 13px;
  border: 1px solid var(--ws-line);
  border-radius: 9px;
  background: var(--ws-paper);
  color: var(--ws-ink);
}
.ws-textarea { min-height: 96px; resize: vertical; }
.ws-input:focus, .ws-select:focus, .ws-textarea:focus {
  outline: none;
  border-color: var(--ws-green);
  box-shadow: 0 0 0 3px rgba(40, 54, 24, .12);
}

.ws-check { display: flex; align-items: flex-start; gap: 10px; font-size: 14px; line-height: 1.45; cursor: pointer; }
.ws-check input { margin-top: 2px; width: 17px; height: 17px; accent-color: var(--ws-green); flex: none; }

.ws-grid-2 { display: grid; gap: 14px; grid-template-columns: 1fr; }
@media (min-width: 620px) { .ws-grid-2 { grid-template-columns: 1fr 1fr; } }

/* --- Validatie ---------------------------------------------------------- */
.ws-error { display: block; font-size: 12.5px; color: #a4262c; margin-top: 5px; min-height: 0; }
.ws-field.is-invalid .ws-input,
.ws-field.is-invalid .ws-select,
.ws-field.is-invalid .ws-textarea { border-color: #a4262c; }
/* eigen regel, anders overschrijft de focusstijl de foutkleur terwijl
   iemand hem juist aan het herstellen is */
.ws-field.is-invalid .ws-input:focus,
.ws-field.is-invalid .ws-select:focus,
.ws-field.is-invalid .ws-textarea:focus {
  border-color: #a4262c;
  box-shadow: 0 0 0 3px rgba(164, 38, 44, .14);
}

/* --- Samenvatting ------------------------------------------------------- */
.ws-summary {
  background: var(--ws-green);
  color: var(--ws-cream);
  border-radius: var(--ws-radius);
  padding: 22px;
  box-shadow: var(--ws-shadow);
}
.ws-summary h3 {
  margin: 0 0 14px;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ws-cream);
}
.ws-rate-parts, .ws-lines { list-style: none; margin: 0; padding: 0; }

.ws-rate-parts {
  font-size: 13px;
  border-bottom: 1px solid rgba(254, 250, 224, .22);
  padding-bottom: 10px;
  margin-bottom: 12px;
}
.ws-rate-parts li { display: flex; justify-content: space-between; gap: 10px; padding: 3px 0; opacity: .82; }
.ws-rate-parts .ws-rate-total { opacity: 1; font-weight: 700; padding-top: 7px; }

.ws-line { padding: 9px 0; border-bottom: 1px solid rgba(254, 250, 224, .16); }
.ws-line:last-child { border-bottom: 0; }
.ws-line-main { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; }
.ws-line-label { font-size: 14px; font-weight: 600; }
.ws-line-amount { font-size: 14px; font-weight: 700; white-space: nowrap; }
.ws-line-detail { font-size: 12px; opacity: .72; margin-top: 2px; }
.ws-line-empty { font-size: 13px; opacity: .75; line-height: 1.5; }

.ws-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 2px solid rgba(254, 250, 224, .3);
}
.ws-total-label { font-size: 14px; font-weight: 600; }
.ws-total-amount {
  font-size: 27px;
  font-weight: 800;
  letter-spacing: -.02em;
  text-decoration: underline;
  text-decoration-thickness: 3px;
  text-underline-offset: 5px;
  text-decoration-color: rgba(254, 250, 224, .45);
  white-space: nowrap;
}
.ws-total-note { margin: 12px 0 0; font-size: 11.5px; line-height: 1.5; opacity: .78; }

.ws-prov {
  display: inline-block;
  margin-left: 5px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--ws-warn-line);
  color: var(--ws-warn-ink);
  text-decoration: none;
  vertical-align: middle;
}

/* --- Voorwaarden -------------------------------------------------------- */
.ws-disclaimer {
  margin: 18px 0 0;
  padding: 16px 18px;
  background: var(--ws-cream);
  border: 1px solid var(--ws-line);
  border-radius: 10px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--ws-muted);
}
.ws-disclaimer strong { color: var(--ws-ink); }
.ws-disclaimer ul { margin: 8px 0 0; padding-left: 18px; }
.ws-disclaimer li { margin-bottom: 3px; }

/* --- Verzenden ---------------------------------------------------------- */
.ws-submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  width: 100%;
  font: inherit;
  font-size: 16px;
  font-weight: 700;
  padding: 15px 26px;
  border: 0;
  border-radius: 99px;
  background: var(--ws-cream);
  color: var(--ws-green);
  cursor: pointer;
  transition: transform .18s ease, box-shadow .18s ease, background .18s ease;
}
.ws-step .ws-submit { background: var(--ws-green); color: var(--ws-cream); }
.ws-submit:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(40, 54, 24, .24); }
.ws-submit:disabled { opacity: .6; cursor: progress; transform: none; }

.ws-status { margin: 12px 0 0; font-size: 14px; line-height: 1.5; min-height: 1px; }
.ws-status.is-error { color: #a4262c; font-weight: 600; }
.ws-status.is-ok { color: var(--ws-green); font-weight: 600; }
.ws-status.is-busy { color: var(--ws-muted); }

.ws-gotcha {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

.ws-spec {
  margin: 14px 0 0;
  padding: 13px 15px;
  background: #f7f6ee;
  border: 1px dashed var(--ws-line);
  border-radius: 9px;
  font-size: 12px;
  line-height: 1.55;
  white-space: pre-wrap;
  color: var(--ws-muted);
  max-height: 190px;
  overflow: auto;
}

/* --- Zwevende prijsbalk ------------------------------------------------- */
.ws-pricebar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 900;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 20px calc(12px + env(safe-area-inset-bottom, 0px));
  background: var(--ws-green);
  color: var(--ws-cream);
  box-shadow: 0 -6px 22px rgba(21, 21, 21, .2);
  transform: translateY(105%);
  transition: transform .3s cubic-bezier(.4, 0, .2, 1);
}
.ws-pricebar.is-visible { transform: translateY(0); }
.ws-pricebar-label { font-size: 12px; font-weight: 600; opacity: .82; display: block; }
.ws-pricebar-amount {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -.02em;
  text-decoration: underline;
  text-decoration-thickness: 3px;
  text-underline-offset: 4px;
  text-decoration-color: rgba(254, 250, 224, .45);
}
.ws-pricebar-cta {
  flex: none;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  padding: 11px 20px;
  border: 0;
  border-radius: 99px;
  background: var(--ws-cream);
  color: var(--ws-green);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
}
@media (min-width: 1000px) { .ws-pricebar { display: none; } }

@media (prefers-reduced-motion: reduce) {
  .ws-wrap *, .ws-pricebar { transition: none !important; }
  .ws-tile:hover .ws-tile-inner, .ws-submit:hover { transform: none; }
}

/* ============================================================================
 * Toevoegingen bij de prijslijst van 1 september 2026
 * ========================================================================== */

/* --- Tekening in plaats van een foto ------------------------------------ *
 * Een foto kan 19 van 21 planken niet laten zien, en een schutting zonder
 * poort leest als een schutting. Daar staat een tekening. currentColor, zodat
 * de tekening de tekstkleur van de tegel volgt. */
.ws-tile-svg {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  background: var(--ws-cream);
  color: var(--ws-green);
  padding: 14px 18px;
}

/* --- Aanvinkbare optie met miniatuur ------------------------------------ */
.ws-checks { display: grid; gap: 10px; }
.ws-check-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 2px solid var(--ws-line);
  border-radius: 12px;
  background: var(--ws-paper);
  cursor: pointer;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.ws-check-card:hover { border-color: var(--ws-accent); }
.ws-check-card input {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
  margin: 0;
}
.ws-check-card:has(input:checked) {
  border-color: var(--ws-green);
  box-shadow: 0 0 0 3px rgba(40, 54, 24, .12);
}
.ws-check-card:has(input:focus-visible) { outline: 3px solid var(--ws-accent); outline-offset: 2px; }
.ws-check-img {
  flex: none;
  width: 68px;
  height: 51px;
  border-radius: 8px;
  object-fit: cover;
  background: var(--ws-line);
}
.ws-check-body { flex: 1; min-width: 0; }
.ws-check-label { display: block; font-size: 14px; font-weight: 600; line-height: 1.3; }
.ws-check-sub { display: block; font-size: 12px; color: var(--ws-muted); margin-top: 2px; line-height: 1.35; }
.ws-check-price { flex: none; font-size: 13px; font-weight: 700; white-space: nowrap; }
/* Het vinkje zit rechts en verschijnt pas als de optie aanstaat, zodat een
   rij niet-aangevinkte opties rustig blijft. */
.ws-check-mark {
  flex: none;
  width: 22px; height: 22px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 2px solid var(--ws-line);
  font-size: 12px;
  color: transparent;
}
.ws-check-card:has(input:checked) .ws-check-mark {
  background: var(--ws-green);
  border-color: var(--ws-green);
  color: var(--ws-cream);
}

/* --- Kop van de samenvatting, met de btw-schakelaar ---------------------- */
.ws-summary-head {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
.ws-summary-head h3 { margin: 0; }
.ws-btw {
  display: inline-flex;
  padding: 2px;
  border-radius: 99px;
  background: rgba(254, 250, 224, .14);
}
.ws-btw-btn {
  font: inherit;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .01em;
  padding: 5px 11px;
  border: 0;
  border-radius: 99px;
  background: transparent;
  color: var(--ws-cream);
  opacity: .7;
  cursor: pointer;
  transition: background .18s ease, opacity .18s ease;
}
.ws-btw-btn.is-active { background: var(--ws-cream); color: var(--ws-green); opacity: 1; }
.ws-btw-btn:focus-visible { outline: 2px solid var(--ws-cream); outline-offset: 2px; }

/* --- Posten zonder bedrag ------------------------------------------------ *
 * Staan er wel, tellen niet mee. Bewust geen bedrag en geen streepje dat op
 * nul lijkt. */
.ws-line-request {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 5px;
  border: 1px solid rgba(254, 250, 224, .35);
  white-space: nowrap;
}
.ws-line.is-request .ws-line-label { opacity: .9; }
.ws-total-request {
  margin: 12px 0 0;
  font-size: 11.5px;
  line-height: 1.5;
  padding: 8px 10px;
  border-radius: 8px;
  background: rgba(254, 250, 224, .12);
}
.ws-total-btw { font-weight: 400; opacity: .72; }

/* --- Losse opmerkingen zonder bedrag, zoals palen en hoeken -------------- */
.ws-notes {
  list-style: none;
  margin: 10px 0 0;
  padding: 10px 0 0;
  border-top: 1px solid rgba(254, 250, 224, .16);
  font-size: 12px;
  line-height: 1.5;
  opacity: .78;
}
.ws-notes li { padding: 2px 0; }
.ws-notes li::before { content: "\2022"; margin-right: 7px; opacity: .6; }

@media (prefers-reduced-motion: reduce) {
  .ws-check-card, .ws-btw-btn { transition: none !important; }
}

/* --- hidden moet ook echt verbergen --------------------------------------- *
 * Een eigen display-regel wint van de browserstandaard voor [hidden]. Dat gold
 * hier voor .ws-banner (flex) en .ws-checks (grid): die bleven staan terwijl
 * het element hidden was. Zichtbaar geworden toen de banner voor het eerst uit
 * moest. Een regel voor alles, zodat een volgende display-regel dit niet
 * opnieuw stukmaakt. */
.ws-wrap [hidden] { display: none !important; }

/* --- Blok per onderdeel in de maatstap ----------------------------------- *
 * Sinds stap 1 meerkeuze is, kan iemand hout, gaas en schanskorf tegelijk
 * aanvragen. Elk onderdeel krijgt dan zijn eigen maten, en die moeten visueel
 * bij elkaar horen, anders is niet te zien welke lengte bij welk ding hoort. */
.ws-sub {
  border: 1px solid var(--ws-line);
  border-radius: 12px;
  padding: 16px;
  margin-bottom: 18px;
  background: rgba(254, 250, 224, .35);
}
.ws-sub:last-child { margin-bottom: 0; }
.ws-sub-head {
  margin: 0 0 12px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ws-green);
}

/* --- Melding als er nog niets is aangevinkt ------------------------------- */
.ws-warn {
  margin: 14px 0 0;
  padding: 10px 14px;
  border-radius: 10px;
  background: var(--ws-warn-bg);
  border: 1px solid var(--ws-warn-line);
  color: var(--ws-warn-ink);
  font-size: 13px;
  line-height: 1.5;
}

/* --- Lengteveld: schuifregelaar plus invulvak ----------------------------- *
 * De regelaar dekt het gewone bereik en is daardoor fijn genoeg om 14 van 15
 * meter te onderscheiden. Wie een lange schutting heeft tikt het getal in. */
/* De breedte zit op het omhulsel, niet op het veld zelf. Het thema zet
 * input[type=number]{width:100%;padding:.5rem 1rem} op (0,1,1); daardoor werd
 * het vak zo breed als de rij en schoof het getal onder de "m". Het veld vult
 * nu 100 procent van een omhulsel met een vaste breedte, dus ook als die
 * themaregel wint klopt de maat nog. input.ws-num is (0,2,1) en wint van het
 * thema, zodat de padding blijft staan die het getal van de "m" weghoudt. */
.ws-num-wrap {
  position: relative;
  flex: 0 0 auto;
  width: 104px;
  display: inline-flex;
  align-items: center;
}
.ws-wrap input.ws-num {
  width: 100%;
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  text-align: right;
  padding: 10px 30px 10px 12px;
  border: 1px solid var(--ws-line);
  border-radius: 10px;
  background: var(--ws-cream);
  color: var(--ws-ink);
  -moz-appearance: textfield;
}
.ws-num::-webkit-outer-spin-button,
.ws-num::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.ws-wrap input.ws-num:focus {
  outline: 0;
  border-color: var(--ws-green);
  box-shadow: 0 0 0 3px rgba(40, 54, 24, .14);
}
.ws-num-unit {
  position: absolute;
  right: 11px;
  font-size: 13px;
  font-weight: 600;
  opacity: .6;
  pointer-events: none;
}
.ws-wrap .ws-field.is-invalid input.ws-num { border-color: #b3261e; }

/* --- Uitklapbare prijsbalk ------------------------------------------------ *
 * Op een smal scherm staat de opbouw van het bedrag helemaal onderaan de
 * pagina, dus daar is een bedrag zonder uitleg. De balk klapt daarom open. */
.ws-pricebar { flex-direction: column; align-items: stretch; gap: 0; padding-top: 0; }
.ws-pricebar-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: 12px;
}
.ws-pricebar-toggle {
  flex: 1;
  min-width: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 4px 10px;
  font: inherit;
  text-align: left;
  background: none;
  border: 0;
  padding: 0;
  color: inherit;
  cursor: pointer;
}
/* Bedrag onder het label, niet ernaast. Naast elkaar plus de knop ernaast is
   op 390 px te breed, waardoor het bedrag onder "Offerte aanvragen" schoof. */
.ws-pricebar-text { min-width: 0; }
.ws-pricebar-hint {
  grid-column: 1 / -1;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  opacity: .6;
}
.ws-pricebar-toggle:focus-visible { outline: 2px solid var(--ws-cream); outline-offset: 3px; border-radius: 6px; }
.ws-pricebar-chevron {
  flex: none;
  width: 9px; height: 9px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-135deg);
  opacity: .8;
  transition: transform .25s ease;
}
.ws-pricebar.is-open .ws-pricebar-chevron { transform: rotate(45deg); }

.ws-pricebar-panel {
  max-height: min(62vh, 460px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 16px 0 4px;
  border-bottom: 1px solid rgba(254, 250, 224, .22);
}
.ws-pricebar-panel-head {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
  opacity: .8;
  margin-bottom: 10px;
}
/* De balk is groen, dus de knoppen erin lenen het contrast van de zijbalk */
.ws-pricebar-panel .ws-btw { background: rgba(254, 250, 224, .16); }

@media (min-width: 1000px) { .ws-pricebar { display: none; } }

/* De prijsbalk is krap op een telefoon. Het bedrag krimpt mee in plaats van
   buiten zijn vak te lopen, en de knop houdt een vaste minimumbreedte. */
.ws-pricebar-row { min-width: 0; }
.ws-pricebar .ws-pricebar-amount {
  display: block;
  font-size: clamp(17px, 5.2vw, 22px);
  overflow: hidden;
  text-overflow: ellipsis;
}
.ws-pricebar .ws-pricebar-label { font-size: 11px; }
.ws-pricebar-cta { flex: none; padding: 11px 16px; font-size: 13px; }
@media (max-width: 359px) {
  .ws-pricebar-cta { padding: 10px 12px; font-size: 12px; }
}

/* ============================================================================
 * Reactie van de klant op de proefversie, 1 september 2026
 * ========================================================================== */

/* --- Regel met een eigen aantal ------------------------------------------- *
 * Schanskorven, gaasmaten en poorten worden per stuk of per meter besteld, en
 * twee maten in een aanvraag moet kunnen. Een tegel met een keuzerondje kan
 * dat niet, want die dwingt alles in een maat. Dit is dus geen keuze maar een
 * regel met een getal: beeld, wat het is, wat het kost, en hoeveel.
 *
 * Het is een label om het invoerveld heen, dus overal klikken zet de cursor in
 * het getal. Geen input:checked hier, want er valt niets aan of uit te zetten:
 * nul is gewoon een geldig antwoord. */
.ws-qty-list { display: grid; gap: 10px; }
.ws-qty-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 2px solid var(--ws-line);
  border-radius: 12px;
  background: var(--ws-paper);
  cursor: text;
}
.ws-qty-card:hover { border-color: var(--ws-accent); }
.ws-qty-card:focus-within {
  border-color: var(--ws-green);
  box-shadow: 0 0 0 3px rgba(40, 54, 24, .12);
}
/* Zowel een foto als een tekening komen hier terecht, dus de maat zit op het
   omhulsel en niet op het soort beeld. */
.ws-qty-media {
  flex: none;
  width: 68px;
  height: 51px;
  border-radius: 8px;
  overflow: hidden;
  object-fit: cover;
  background: var(--ws-line);
  display: block;
}
.ws-qty-media .ws-tile-svg { height: 100%; aspect-ratio: auto; padding: 6px 8px; }
.ws-qty-body { flex: 1; min-width: 0; }
.ws-qty-label { display: block; font-size: 14px; font-weight: 600; line-height: 1.3; }
.ws-qty-sub { display: block; font-size: 12px; color: var(--ws-muted); margin-top: 2px; line-height: 1.35; }
.ws-qty-price {
  display: block;
  margin-top: 3px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ws-green);
}

/* Het aantal is smaller dan het lengteveld: daar staat "12,5", hier "3". */
.ws-qty-card .ws-num-wrap { width: 88px; }

/* --- btw achter het bedrag in de dichtgeklapte prijsbalk ------------------- *
 * De schakelaar zit in het paneel erboven, dus zonder dit staat er een bedrag
 * zonder te zeggen welke van de twee het is. */
.ws-pricebar-btw {
  display: block;
  font-size: 11px;
  font-weight: 600;
  opacity: .72;
  margin-top: 1px;
}

/* --- Optiekaart op een smal scherm ---------------------------------------- *
 * Het bedrag staat op een eigen regel zodra het scherm smal is. Sinds er
 * "incl. btw" achter elk bedrag staat is die tekst te lang om naast de naam te
 * passen: hij heeft white-space nowrap, dus hij gaf niet mee en kneep de naam
 * in een kolom van drie woorden hoog. Het bedrag zakt daarom onder de kaart in
 * plaats van ernaast, en het vinkje blijft rechts van de naam staan. */
@media (max-width: 600px) {
  .ws-check-card { flex-wrap: wrap; }
  .ws-check-body { flex: 1 1 55%; }
  .ws-check-mark { order: 3; }
  .ws-check-price { order: 4; flex: 1 1 100%; white-space: normal; }
}

/* Het bedrag hoort bij de regel, niet in de tekstkolom. Op een breed scherm
   staat het links van het getal, op een smal scherm zakt het naar een eigen
   regel eronder: "EUR 157,30 p/m incl. btw" past niet naast een naam en een
   invoervak in 390 pixels, en knijpt anders de naam plat. */
.ws-qty-card { flex-wrap: wrap; }
.ws-qty-price { flex: 0 0 auto; order: 2; margin-top: 0; }
.ws-qty-card .ws-num-wrap { order: 3; }
@media (max-width: 600px) {
  .ws-qty-card { column-gap: 10px; }
  .ws-qty-media { width: 54px; height: 41px; }
  .ws-qty-price { flex: 1 1 100%; order: 4; margin-top: 6px; }
}

/* ==========================================================================
 * De wizard, 2026-09-04
 * ==========================================================================
 * De offertepagina was negen kaarten onder elkaar. De klant wees een
 * voorbeeld aan en vroeg om die vorm: een blok dat zichzelf vervangt, met
 * links een foto en rechts de vraag, op de telefoon precies hetzelfde maar
 * boven elkaar.
 *
 * Deze regels staan onderaan het bestand en niet tussen de bestaande, zodat
 * ze op gelijke specificiteit winnen van de layout die er al stond. Wat
 * hierboven staat is nog steeds de opmaak van een stap zelf; alleen de doos
 * eromheen is veranderd.
 * ========================================================================== */

/* Eén kolom, altijd. De zijbalk was de tweede kolom en is nu het overzicht
 * aan het eind, dus er valt niets meer naast te zetten. */
/* Deze regel staat later in het bestand dan de mediaquery hierboven die er
 * 340px naast zette. Bij gelijke specificiteit wint de laatste, ook van een
 * regel die in een mediaquery staat, dus die tweede kolom is hiermee weg. */
.ws-layout { grid-template-columns: minmax(0, 1fr); }

/* Het overzicht hoort bij de laatste stap. Onderweg staat het bedrag in de
 * balk onderin, met de opbouw erachter. */
.ws-aside { display: none; }
.ws-layout.is-last .ws-aside { display: block; position: static; }

.ws-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  background: var(--ws-paper);
  border: 1px solid var(--ws-line);
  border-radius: var(--ws-radius);
  overflow: hidden;
  box-shadow: 0 2px 10px rgba(21, 21, 21, .06);
}

@media (min-width: 900px) {
  .ws-card {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.12fr);
    /* Een ondergrens, geen vaste hoogte. Zonder ondergrens klapt de kaart bij
     * een korte stap in elkaar en springt hij bij de volgende weer open, en
     * dat leest als een pagina die op en neer stuitert. Een vaste hoogte zou
     * de lange stappen juist afkappen. */
    min-height: 580px;
  }
}

/* --- Het beeldpaneel --------------------------------------------------- */
.ws-preview {
  position: relative;
  display: flex;
  flex-direction: column;
  background: #1b1c18;
}

.ws-preview-frame {
  position: relative;
  flex: 1;
  min-height: 220px;
  aspect-ratio: 16 / 10;
  overflow: hidden;
}

/* Twee lagen over elkaar. De onderste is de vorige foto en blijft staan tot
 * de nieuwe geladen is, zodat er geen leeg frame tussen zit. */
/* De selector is met opzet lang. Kort je hem in tot `.ws-preview-img`, dan
 * verliest `height: 100%` van het gekloonde thema en pakt de foto de hoogte
 * die uit het height-attribuut volgt: 394px in een frame van 759px, met een
 * zwarte balk eronder. Gemeten, niet vermoed. Dezelfde valkuil als bij
 * `.ws-input`, zie PROBLEMS.md en de opmerking bij de invulvelden hierboven.
 * Het height-attribuut blijft er staan, want dat houdt de plek vrij tijdens
 * het laden. */
.ws-wrap .ws-preview-frame img.ws-preview-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity .45s ease;
}

.ws-wrap .ws-preview-frame img.ws-preview-img.is-on { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .ws-wrap .ws-preview-frame img.ws-preview-img { transition: none; }
}

/* Het bijschrift lag eerst als eigen strook onder de foto, en de knoppen
 * van de reeks stonden daar precies overheen. Nu ligt het in de foto zelf,
 * linksonder, met een verloop eronder zodat het leesbaar blijft op een lichte
 * lucht. Dat scheelt ook 40px hoogte, en die is in deze kaart schaars. */
.ws-preview-cap {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 1;
  margin: 0;
  padding: 34px 150px 14px 16px;
  font-size: 12.5px;
  line-height: 1.4;
  color: rgba(254, 250, 224, .92);
  background: linear-gradient(to top, rgba(15, 16, 13, .82) 0%,
                              rgba(15, 16, 13, .45) 55%, rgba(15, 16, 13, 0) 100%);
  pointer-events: none;
}

/* Rechtsonder, naast het bijschrift en niet eroverheen. Het bijschrift houdt
 * daar met padding-right ruimte voor vrij. */
.ws-preview-bar {
  position: absolute;
  right: 12px;
  bottom: 10px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  z-index: 2;
}

.ws-preview-nav {
  width: 34px;
  height: 34px;
  flex: none;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  background: rgba(21, 21, 21, .55);
  position: relative;
}

.ws-preview-nav:hover { background: rgba(21, 21, 21, .78); }
.ws-preview-nav:focus-visible { outline: 3px solid var(--ws-accent); outline-offset: 2px; }

/* Een pijl van twee lijnen, zodat er geen icoonbestand bij hoeft. */
.ws-preview-nav::before {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 8px; height: 8px;
  border-left: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: translate(-40%, -50%) rotate(45deg);
}

.ws-preview-nav.is-next::before {
  transform: translate(-60%, -50%) rotate(-135deg);
}

.ws-preview-dots { display: flex; align-items: center; gap: 6px; }

.ws-preview-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(254, 250, 224, .45);
  transition: background .25s ease, transform .25s ease;
}

.ws-preview-dot.is-on { background: var(--ws-cream); transform: scale(1.25); }

/* --- Het vragenpaneel -------------------------------------------------- */
.ws-panel { display: flex; flex-direction: column; min-width: 0; }
.ws-panel .ws-main { flex: 1; min-width: 0; }

/* Eén stap tegelijk.
 *
 * LET OP de volgorde tussen deze twee regels en `hidden`. `hidden` betekent
 * "deze vraag is niet van toepassing" en moet altijd winnen van "dit is de
 * huidige stap", anders komt een uitgeschakelde tak in beeld met velden die
 * op disabled staan. Vandaar `:not([hidden])` en niet alleen `.is-current`.
 * Zie ook PROBLEMS.md over display naast hidden. */
.ws-panel .ws-step { display: none; }
.ws-panel .ws-step.is-current:not([hidden]) { display: block; }

/* De doos zit nu om het geheel, dus de stap zelf is geen kaartje meer. */
.ws-panel .ws-step {
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  margin: 0;
  padding: 22px 20px 8px;
}

@media (min-width: 900px) {
  .ws-panel .ws-step { padding: 28px 30px 10px; }
}

/* --- Terug en volgende ------------------------------------------------- */
/* De lijn erboven is geen versiering: het vragenpaneel schuift eronder door
 * en zonder scheiding loopt een halve tegel visueel in de knoppenbalk. */
.ws-nav {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 20px 18px;
  margin-top: auto;
  border-top: 1px solid var(--ws-line);
  background: var(--ws-paper);
}

@media (min-width: 900px) { .ws-nav { padding: 16px 30px 24px; } }

.ws-nav-spacer { flex: 1; }

.ws-nav-btn {
  font: inherit;
  font-weight: 700;
  font-size: 15px;
  border-radius: 999px;
  padding: 12px 26px;
  cursor: pointer;
  border: 1px solid transparent;
}

.ws-nav-btn:focus-visible { outline: 3px solid var(--ws-accent); outline-offset: 2px; }

.ws-nav-next { background: var(--ws-green); color: var(--ws-cream); }
.ws-nav-next:hover { background: var(--ws-green-dark); }

.ws-nav-back {
  background: transparent;
  border-color: var(--ws-line);
  color: var(--ws-ink);
  padding-left: 20px;
  padding-right: 20px;
}

.ws-nav-back:hover { border-color: var(--ws-ink); }

/* De vaste prijsbalk ligt over de onderkant van de pagina heen. Zonder deze
 * ruimte valt de laatste knop erachter. */
.ws-wrap { padding-bottom: 96px; }

/* --- De kaart moet in beeld passen ------------------------------------- *
 * Dit is de kern van wat de klant vroeg: een blok dat zichzelf vervangt, niet
 * een pagina waar je doorheen scrolt. Dat lukt alleen als de kaart een hoogte
 * heeft. Anders groeit hij mee met de langste stap, en stap 1 met vier tegels
 * plus twee aantalblokken is bijna 850px hoog.
 *
 * Dus: de kaart krijgt de hoogte van het scherm min wat eromheen staat, en
 * het vragenpaneel schuift binnenin als een stap langer is. De foto en de
 * knoppen blijven staan. `clamp` houdt het leefbaar op een klein laptopscherm
 * en op een heel hoge monitor.
 *
 * `min-height: 0` op de gridkinderen is geen sierregel: een gridkind staat
 * standaard op `min-height: auto` en weigert dan te krimpen, waardoor
 * overflow-y nooit iets doet en de kaart alsnog uitdijt.
 * ---------------------------------------------------------------------- */
.ws-panel, .ws-preview { min-height: 0; }
/* `overscroll-behavior: contain` stond hier en dat brak het vegen op een
 * telefoon. De klant: "I cant scroll when I am clicking on the actual question
 * box, only to the side of it and above and below it."
 *
 * Dat klopte precies. `contain` verbiedt scroll chaining: een veeg die in deze
 * doos begint mag niet doorgegeven worden aan de pagina. Past de stap
 * helemaal in de doos, dan valt er hier niets te scrollen EN mag de pagina het
 * ook niet overnemen, dus gebeurt er niets. Alleen op de gegevensstap, die wel
 * overloopt, werkte vegen; dat is de stap waarvan hij zei dat die het als
 * enige deed.
 *
 * Nu chaint hij gewoon door naar de pagina. Er zit hier geen los overlappend
 * paneel dat achterlangs zou wegscrollen, dus daar is `contain` niet voor
 * nodig. De prijsbalk hierboven houdt hem wel, dat IS zo'n paneel. */
.ws-panel .ws-main { overflow-y: auto; overscroll-behavior: auto; }

/* De aftrek is geen rond getal maar de optelsom van wat er boven en onder de
 * kaart staat: de vaste koptekst, de paginabanner, de voortgangsbalk en de
 * prijsbalk onderin. Gemeten op 1440 breed. De ondergrens houdt de kaart
 * bruikbaar op een laag laptopscherm, waar dan alsnog een klein stukje
 * gescrold moet worden, en de bovengrens voorkomt dat de foto op een hoge
 * monitor een portret van twee meter wordt. */
@media (min-width: 900px) {
  .ws-card {
    height: clamp(440px, calc(100vh - 470px), 640px);
    min-height: 0;
  }
}

/* Op de telefoon dezelfde vorm, alleen boven elkaar. De foto krijgt een vast
 * deel van de hoogte, anders duwt hij de vraag van het scherm af. svh en niet
 * vh: op mobiel telt vh de adresbalk mee en dan valt de knoppenbalk onder de
 * onderrand. */
@media (max-width: 899px) {
  .ws-card {
    height: calc(100svh - 320px);
    min-height: 380px;
  }
  /* Twee rijen met een vaste verdeling, geen max-height.
   *
   * max-height: 34% deed op de telefoon niets: de rijen van het raster staan
   * op auto, de foto ontleent zijn hoogte aan niets (aspect-ratio is hier
   * los, min-height is 0) en de rij werd dus 0px hoog. De foto was op mobiel
   * daardoor volledig verdwenen. Gemeten, niet vermoed. Met expliciete rijen
   * krijgt de foto zijn deel van een hoogte die wel vaststaat. */
  .ws-card { grid-template-rows: 36% minmax(0, 1fr); }
  .ws-preview { max-height: none; }
  .ws-preview-frame { aspect-ratio: auto; min-height: 0; }
}

@supports not (height: 100svh) {
  @media (max-width: 899px) { .ws-card { height: calc(100vh - 320px); } }
}

/* De banner van de pagina zelf stond op 400px. Samen met de vaste koptekst
 * begon de kaart daardoor pas op 629px, en dan is "een blok dat in beeld
 * past" al verloren voordat het formulier begint. De foto blijft, hij is
 * alleen niet langer een halve schermhoogte. */
.elementor-element-13e659b { min-height: 210px !important; }

@media (max-width: 767px) {
  .elementor-element-13e659b { min-height: 110px !important; }
  /* Op 390 breed valt het bijschrift over de knoppen van de reeks heen, en
   * korter maken zou de zin onzin maken. De foto zelf zegt genoeg op een
   * scherm waar elke pixel hoogte telt. */
  .ws-preview-cap { display: none; }
}

/* --- Tegels in het paneel ---------------------------------------------- *
 * De tegels stonden op minmax(210px) met een foto op 4:3. In een kolom van
 * ruim 500px levert dat twee kolommen op, en zes houtsoorten worden dan drie
 * rijen van 230px: 700px in een paneel van 500. Dan moet je binnen de stap
 * scrollen om te zien welke houtsoorten er zijn, en juist die vergelijking is
 * waar deze stap voor bestaat.
 *
 * Smaller raster en een lagere foto brengen zes tegels terug naar twee rijen.
 * De foto blijft groot genoeg om de houtnerf te zien, en dat is wat hier
 * beoordeeld wordt. Buiten het paneel verandert er niets.
 * ---------------------------------------------------------------------- */
@media (min-width: 900px) {
  .ws-panel .ws-tiles { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
  .ws-panel .ws-tiles.is-wide { grid-template-columns: repeat(auto-fit, minmax(165px, 1fr)); }
  .ws-panel .ws-tile-img { aspect-ratio: 16 / 10; }
  .ws-panel .ws-tile-body { padding: 8px 10px 10px; }
  .ws-panel .ws-tile-price { margin-top: 5px; }
}

/* Een zweem onderaan het paneel, zodat zichtbaar is dat er nog iets onder de
 * rand doorloopt. Zonder dat lijkt een afgesneden tegelrij een fout.
 *
 * Alleen als er ECHT iets doorloopt. De zweem stond altijd aan, en sinds de
 * kaart om de inhoud heen krimpt valt de onderrand van het paneel samen met de
 * laatste keuze: die vervaagde dan aan zijn onderkant terwijl er niets meer
 * kwam. `is-scrollable` wordt door de wizard gezet, zie deel 13 van
 * calculator.js. */
.ws-panel .ws-main.is-scrollable {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 26px), transparent 100%);
          mask-image: linear-gradient(to bottom, #000 calc(100% - 26px), transparent 100%);
}

/* De wizard zet de aandacht op de kop van de nieuwe stap, zodat een
 * schermlezer voorleest waar je terecht bent gekomen. Een kop is geen
 * bedieningselement, dus de rand eromheen zegt niets en leest als een fout.
 * De aandacht zelf blijft, alleen de rand gaat weg. */
.ws-panel .ws-step h3:focus { outline: none; }

/* --- Nog wat ruimte winnen op de telefoon ------------------------------ *
 * Op 390 breed bleef er van het vragenpaneel te weinig over: de kop en de
 * uitleg vulden het, en de tegels waarop gekozen moet worden stonden onder
 * de rand. Een keuzestap waarin je de keuzes niet ziet is geen keuzestap.
 * ---------------------------------------------------------------------- */
@media (max-width: 899px) {
  .ws-card { grid-template-rows: 26% minmax(0, 1fr); height: calc(100svh - 340px); }
  .ws-panel .ws-step { padding: 16px 16px 6px; }
  .ws-panel .ws-step h3 { font-size: 19px; }
  .ws-panel .ws-step p.ws-hint { font-size: 13px; line-height: 1.45; margin-bottom: 12px; }
  .ws-nav { padding: 10px 16px 12px; }
  .ws-nav-btn { padding: 11px 22px; }
}

@supports not (height: 100svh) {
  @media (max-width: 899px) { .ws-card { height: calc(100vh - 340px); } }
}

/* De zwevende WhatsApp-knop stond precies op de plek van Volgende, en op de
 * plek van de prijsbalk zodra die omhoog komt. Hij hoort erboven te zweven,
 * niet erop. Alleen op deze pagina, want alleen hier staat die balk. */
/* `a.ws-wa` en niet `.ws-wa`: site.css wordt na dit bestand geladen en zou
 * bij gelijke specificiteit winnen. Dezelfde valkuil als bij de invulvelden
 * en bij de paneelfoto. */
@media (max-width: 899px) {
  body a.ws-wa { bottom: calc(150px + env(safe-area-inset-bottom, 0px)); }
}

/* ==========================================================================
 * Keuzeregels, de dunne kaartjes
 * ==========================================================================
 * Dit vervangt de fototegels. Een tegel was ongeveer 180px hoog omdat er een
 * foto van 4:3 boven de tekst stond; zes houtsoorten kostten daarmee 560px en
 * pasten nooit op een telefoon. Deze regel is er ongeveer 62px, dus zes opties
 * passen in 372px en er hoeft binnen de vraag niets meer gescrold te worden.
 *
 * Het blijft een kaartje en geen kale lijst met vinkjes: een rand, een eigen
 * achtergrond en een duidelijk aangevinkte staat. Alleen dun.
 * ========================================================================== */
.ws-keuzes { display: flex; flex-direction: column; gap: 8px; }

.ws-keuze {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  border: 1.5px solid var(--ws-line);
  border-radius: 11px;
  background: var(--ws-paper);
  cursor: pointer;
  transition: border-color .16s ease, background .16s ease;
}

.ws-keuze:hover { border-color: var(--ws-accent); }

/* Het echte veld ligt onzichtbaar over de regel heen in plaats van
 * display:none. Zo blijft hij bereikbaar met het toetsenbord en blijft
 * :focus-visible werken. */
.ws-keuze input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.ws-keuze input:checked ~ .ws-keuze-body,
.ws-keuze input:checked ~ .ws-keuze-price { color: var(--ws-green-dark); }

.ws-keuze:has(input:checked) {
  border-color: var(--ws-green);
  background: #f6f7f0;
}

/* Terugval voor browsers zonder :has. Dan geen getinte achtergrond, maar het
 * bolletje hieronder laat de keuze nog steeds zien. */
@supports not selector(:has(*)) {
  .ws-keuze input:checked ~ .ws-keuze-mark { border-color: var(--ws-green); }
}

/* Het bolletje of vierkantje. Getekend, niet het systeemelement: dat is op
 * Android en iOS elke keer een ander formaat en een andere kleur. */
.ws-keuze-mark {
  flex: none;
  width: 20px;
  height: 20px;
  border: 2px solid #c9c7b4;
  border-radius: 50%;
  position: relative;
  transition: border-color .16s ease;
}

.ws-keuze input[type="checkbox"] ~ .ws-keuze-mark { border-radius: 6px; }

.ws-keuze input:checked ~ .ws-keuze-mark {
  border-color: var(--ws-green);
  background: var(--ws-green);
}

.ws-keuze input:checked ~ .ws-keuze-mark::after {
  content: "";
  position: absolute;
  left: 5px;
  top: 2px;
  width: 5px;
  height: 10px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(42deg);
}

.ws-keuze input:focus-visible ~ .ws-keuze-mark {
  outline: 3px solid var(--ws-accent);
  outline-offset: 3px;
}

.ws-keuze-body { flex: 1; min-width: 0; }

.ws-keuze-label {
  display: block;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.25;
}

.ws-keuze-sub {
  display: block;
  font-size: 12.5px;
  color: var(--ws-muted);
  line-height: 1.35;
  margin-top: 1px;
}

.ws-keuze-price {
  flex: none;
  text-align: right;
  font-size: 13px;
  font-weight: 700;
  color: var(--ws-green);
  line-height: 1.3;
  max-width: 40%;
}

/* De ja/nee-kaarten en de aantalregels krijgen dezelfde dunne vorm, anders
 * staan er twee soorten kaartjes door elkaar in dezelfde wizard. */
.ws-check-card, .ws-qty-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  border: 1.5px solid var(--ws-line);
  border-radius: 11px;
  background: var(--ws-paper);
}

.ws-checks { display: flex; flex-direction: column; gap: 8px; }
.ws-qty-list { display: flex; flex-direction: column; gap: 8px; }

.ws-check-body, .ws-qty-body { flex: 1; min-width: 0; }
.ws-check-label, .ws-qty-label { display: block; font-size: 15px; font-weight: 600; line-height: 1.25; }
.ws-check-sub, .ws-qty-sub { display: block; font-size: 12.5px; color: var(--ws-muted); line-height: 1.35; }
.ws-check-price, .ws-qty-price {
  flex: none; text-align: right; font-size: 13px; font-weight: 700;
  color: var(--ws-green); line-height: 1.3; max-width: 38%;
}

/* ==========================================================================
 * Het fotopaneel, derde versie: de foto VULT het kader
 * ==========================================================================
 * De tweede versie zette de foto op `contain` in een kader met lucht eromheen,
 * zodat een telefoonfoto heel bleef. Dat werkte averechts en dit is gemeten,
 * niet vermoed. Vijftien van de zesentwintig paneelfoto's waren staand, 3:4,
 * en het kader is liggend. `contain` past een staande foto dan op de HOOGTE:
 * op 390px bleef er 99px foto over in een kader van 348px, driekwart zwart.
 * Dat is wat de klant bedoelde met "pictures are too small and cut off".
 *
 * De oplossing zit niet hier maar in `_tools/make-calc-images.js`: de foto's
 * worden daar liggend bijgesneden op 16:10, vanuit het midden, en elke snede
 * is op een contactafdruk nagekeken. Bron en kader hebben dus dezelfde
 * verhouding, en daarmee kan de foto het kader vullen ZONDER dat de browser
 * er nog iets afsnijdt. `cover` snijdt hier in de praktijk niets: 16:10 in
 * 16:10 is een exacte pasvorm.
 *
 * Vandaar geen padding meer, geen `contain`, geen zwarte rand. De donkere
 * ondergrond blijft staan, maar is achter een foto nooit meer te zien. Hij
 * doet nog wel werk onder de TEKENINGEN, die staan er in crème op.
 * ========================================================================== */
.ws-preview-frame {
  padding: 0;
  background: #1b1c18;
}

.ws-wrap .ws-preview-frame img.ws-preview-img {
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  object-fit: cover;
  border-radius: 0;
}

/* De tekeningen liggen in hetzelfde kader als de foto's en wisselen elkaar af:
 * nooit allebei tegelijk zichtbaar. Ze VULLEN het kader net zo goed als een
 * foto, alleen met een crème vlak in plaats van een afbeelding.
 *
 * Dat vlak staat hier en niet op de svg zelf. Deze tekeningen komen van de
 * oude keuzetegels en dragen nog `.ws-tile-svg`, met een eigen crème
 * achtergrond, een eigen 4:3 en eigen padding. In een tegel klopte dat; in dit
 * kader leverde het een crème kaartje op met een zwarte rand eromheen, terwijl
 * de foto's ernaast van rand tot rand lopen. Die drie eigenschappen worden
 * hieronder dus teruggezet, en het vlak wordt het kader zelf. */
.ws-preview-tekeningen {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ws-cream);
  color: var(--ws-green);
}

/* De tekening SCHAALT met het kader in plaats van een eigen hoogte te pakken.
 *
 * Met `height: auto` volgde de hoogte uit de breedte: op 390px werd een svg
 * van 132x96 dus 328 breed en 238 hoog, in een kader van 152. Hij stak er 47px
 * bovenuit en werd boven en onder afgesneden. Dat was de tweede helft van
 * "too small and cut off".
 *
 * Met width en height allebei op 100% doet de viewBox het werk: elke svg hier
 * heeft er een, en de standaard preserveAspectRatio schaalt hem passend en
 * gecentreerd binnen het vak. Er kan dus niets meer uitsteken, bij welke
 * kaderverhouding dan ook. */
/* Het bijschrift is gemaakt voor een foto: witte tekst op een donker verloop.
 * Over een tekening ligt dat verloop op een crème vlak en wordt de onderkant
 * van de tekening modderig. Staat er een tekening in beeld, dan valt het
 * verloop weg en wordt de tekst gewoon donker.
 *
 * `~` en niet `+`: tussen de tekeningenlaag en het bijschrift staat nog de
 * balk met de bladerknoppen. */
.ws-preview-tekeningen:not([hidden]) ~ .ws-preview-cap {
  color: var(--ws-green);
  background: none;
  padding-bottom: 10px;
}

.ws-preview-teken { width: 100%; height: 100%; padding: 22px 26px; }
.ws-preview-teken svg {
  width: 100%;
  height: 100%;
  display: block;
  /* De drie eigenschappen die `.ws-tile-svg` uit de tegeltijd meebrengt en
   * die hier tegenwerken: het crème vlak staat nu op de laag eronder, de
   * verhouding komt van het kader, en de lucht komt van de padding hierboven. */
  background: none;
  aspect-ratio: auto;
  padding: 0;
}

/* --------------------------------------------------------------------------
 * Mobiel: de kaart krijgt het scherm
 * --------------------------------------------------------------------------
 * De paginabanner nam 110px, de voortgangsbalk nog eens 55, en daarna begon de
 * kaart pas. Met de banner weg en de voortgang als dun lijntje boven de kaart
 * blijft er genoeg over om vraag, antwoorden en knop tegelijk te tonen. Dat is
 * het hele punt van deze pagina: kiezen zonder te zoeken.
 *
 * De banner blijft op desktop gewoon staan, daar is de ruimte er wel.
 * ------------------------------------------------------------------------ */
@media (max-width: 767px) {
  .elementor-element-13e659b { display: none !important; }

  /* De contactstrook boven de navigatie kost 41px en die zijn hier hard nodig:
   * ze gaan een op een naar de foto. Er gaat geen contactroute verloren, want
   * op deze breedte staat "Bel ons" al in de vaste balk onderin en zweeft de
   * WhatsApp-knop ernaast. Alleen op de offertepagina, alleen op een telefoon:
   * dit is de enige pagina die het hele scherm nodig heeft, en calculator.css
   * wordt alleen hier geladen. `[data-ws-topbar]` is de haak die site.js zelf
   * op de balk zet als hij hem voor de header tilt, dus dit hangt niet aan een
   * Elementor-id dat bij de volgende export anders heet.
   *
   * `body` ervoor is nodig, niet decoratief: site.css laadt NA calculator.css
   * en heeft zelf `[data-ws-topbar] { display: block }`. Gelijke specificiteit,
   * dus de laatste won en de balk bleef staan. Dezelfde valkuil als bij
   * `body a.ws-wa` hieronder. */
  body [data-ws-topbar] { display: none; }

  .ws-progress { margin: 0 0 10px; }
  .ws-progress-head { font-size: 12px; margin-bottom: 5px; }
  .ws-progress-track { height: 5px; }

  .ws-wrap { padding-left: 14px; padding-right: 14px; }
}

@media (max-width: 899px) {
  /* DE KAART IS ZO HOOG ALS DE VRAAG, niet zo hoog als het scherm.
   *
   * Hij stond op een vaste hoogte, en daardoor bleef er onder de laatste
   * keuze een leeg vlak staan tot aan de knoppenbalk. Bij de betonkleur, met
   * drie keuzes, was dat een gat van bijna 200px. De klant omcirkelde het.
   *
   * Nu: `height: auto` met een bovengrens. Weinig keuzes en de onderrand komt
   * omhoog, veel keuzes en hij zakt tot de grens en dan pas gaat `.ws-main`
   * scrollen. Zijn eigen woorden: "if there's multiple answers, it extends
   * down. If there's less answers to be clicked there, it extends up."
   *
   * De BOVENkant blijft staan, want die hangt onder de voortgangsbalk. Het
   * beeld verspringt dus niet tussen stappen, alleen de onderrand beweegt.
   *
   * Geen `min-height` meer: die zou het lege vlak op de korte stappen
   * terugzetten, en dat is precies wat hier weg moest. */
  /* FLEX en geen grid, en dat is niet willekeurig.
   *
   * Met `grid-template-rows: auto minmax(0, auto)` deed de kaart bijna wat er
   * moest gebeuren, maar zakte hij niet in als de bovengrens bereikt was: bij
   * zes houtsoorten liep `.ws-panel` 103px buiten de kaart door en knipte de
   * `overflow: hidden` van de kaart de laatste twee houtsoorten EN de hele
   * knoppenbalk weg. Onbereikbaar, en `.ws-main` scrollde niet, want die was
   * precies zo hoog als zijn inhoud. Gemeten, niet vermoed.
   *
   * `1fr` in plaats van `auto` lost dat op maar rekt de rij altijd op tot de
   * bovengrens, en dan is het lege vlak terug waar het hier om begonnen was.
   *
   * Flex kan wel allebei: `flex: 0 1 auto` groeit nooit (dus geen gat) en
   * krimpt wel onder zijn inhoud (dus geen overloop), en met `min-height: 0`
   * mag `.ws-main` daadwerkelijk inzakken en gaat hij scrollen. */
  .ws-card {
    display: flex;
    flex-direction: column;
    height: auto;
    max-height: calc(100svh - var(--ws-chrome, 156px));
  }
  /* Het beeld houdt zijn verhouding, de vraag levert de ruimte. */
  .ws-preview { flex: none; }
  .ws-panel { flex: 0 1 auto; min-height: 0; }
  .ws-panel .ws-main { min-height: 0; }

  /* Volgende mag de kaart niet ONDER de plakkende koptekst parkeren.
   *
   * `scrollIntoView({ block: 'start' })` zet de bovenkant van de kaart op de
   * bovenkant van het scherm, en daar staat de koptekst overheen. De foto
   * verdween daar dus achter en je moest zelf terugscrollen om hem te zien.
   * De klant: "every time I click volgende, I have to scroll back up."
   *
   * `scroll-margin-top` is precies waarvoor dit bedoeld is: de browser houdt
   * die marge vrij bij het scrollen. De waarde is gemeten, niet geschat, zie
   * meetChrome() in calculator.js. */
  .ws-card { scroll-margin-top: calc(var(--ws-header-h, 99px) + 10px); }

  /* Is er weinig schermhoogte, dan levert het beeld in. Bij een gesprek op de
   * achtergrond of een lage telefoon at het kader anders 42% van de kaart op
   * en bleef er te weinig over voor de vraag. Op een gewone telefoon van 844
   * doet deze regel niets: 26svh is daar 219px en dat is de 16:10 die het
   * kader toch al had. De foto staat op `cover`, dus hij vult ook bij een
   * plattere uitsnede. */

  /* `flex: none` hoort hier bij de verhouding. Met de `flex: 1` uit de
   * basisregel staat flex-basis op 0 en bepaalt flex de hoogte, en dan doet
   * aspect-ratio niets: die telt alleen mee als de hoogte nog vrij is. */
  .ws-preview-frame { flex: none; width: 100%; aspect-ratio: 16 / 10; max-height: 26svh; }
  .ws-preview-teken { padding: 16px 18px; }
}

/* --------------------------------------------------------------------------
 * Krappe schermen: alles een maat compacter
 * --------------------------------------------------------------------------
 * De klant keek op zijn eigen toestel en zag minder dan in de ontwikkelweergave:
 * "it doesn't show enough space". Zijn scherm is 402 breed maar de bruikbare
 * hoogte was ongeveer 700 in plaats van 844, onder meer door de balk van een
 * lopend gesprek bovenin.
 *
 * Onder de 760px hoogte gaat daarom alles wat lucht is een maat terug. Niets
 * wordt weggelaten: de ondertitel en het bedrag blijven bij elke keuze staan,
 * want dat is de informatie waarop iemand vergelijkt. Alleen de ruimte
 * eromheen krimpt.
 * ------------------------------------------------------------------------ */
@media (max-width: 899px) and (max-height: 760px) {
  .ws-panel .ws-step { padding: 6px 14px 0; }
  .ws-step-n { font-size: 10.5px; margin-bottom: 2px; }
  .ws-panel .ws-step h3 { font-size: 16.5px; margin-bottom: 2px; }
  .ws-panel .ws-step p.ws-hint { font-size: 12px; line-height: 1.35; margin-bottom: 6px; }

  .ws-keuzes, .ws-checks, .ws-qty-list { gap: 5px; }
  .ws-keuze, .ws-check-card, .ws-qty-card { padding: 7px 11px; }
  .ws-keuze-sub { line-height: 1.25; }
  .ws-keuze-price { line-height: 1.2; }

  .ws-nav { padding: 6px 14px 8px; }
  .ws-nav-btn { padding: 8px 18px; font-size: 14px; }
  .ws-preview-teken { padding: 10px 12px; }
}

@supports not (height: 100svh) {
  @media (max-width: 899px) { .ws-card { max-height: calc(100vh - var(--ws-chrome, 156px)); } }
}

/* --------------------------------------------------------------------------
 * De regel als raster in plaats van een rij
 * --------------------------------------------------------------------------
 * Met flex kregen de naam en het bedrag elk hun deel van de breedte, en op 390
 * brak "Houten schutting" daardoor over drie regels: de kaart werd 90px hoog
 * in plaats van 62 en er pasten er weer maar twee op het scherm.
 *
 * Als raster staat het bedrag naast de NAAM en loopt de ondertitel eronder
 * over de volle breedte door. Twee regels tekst, vaste hoogte, en het bedrag
 * breekt nooit meer af.
 * ------------------------------------------------------------------------ */
.ws-keuze {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr) auto;
  grid-template-areas:
    "mark label price"
    "mark sub   sub";
  column-gap: 12px;
  row-gap: 1px;
  align-items: center;
}

.ws-keuze-mark  { grid-area: mark; align-self: center; }
.ws-keuze-body  { display: contents; }
.ws-keuze-label { grid-area: label; }
.ws-keuze-sub   { grid-area: sub; }

.ws-keuze-price {
  grid-area: price;
  align-self: center;
  max-width: none;
  white-space: nowrap;
  font-size: 12.5px;
}

/* Op een smal scherm is "vanaf € 121,00 p/m incl. btw" op een regel te lang
 * naast een naam. Daar mag hij over twee regels, rechts uitgelijnd. */
@media (max-width: 460px) {
  .ws-keuze-price { white-space: normal; text-align: right; max-width: 8.5em; }
}

/* Dezelfde vorm voor de ja/nee-kaarten en de aantalregels. */
.ws-check-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  column-gap: 12px;
  align-items: center;
}
.ws-check-body { display: block; min-width: 0; }
.ws-check-price { white-space: nowrap; font-size: 12.5px; max-width: none; }

.ws-qty-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "body num" "price num";
  column-gap: 12px;
  align-items: center;
}
.ws-qty-body  { grid-area: body; }
.ws-qty-price { grid-area: price; text-align: left; white-space: nowrap; font-size: 12.5px; max-width: none; }
.ws-qty-card .ws-num-wrap { grid-area: num; }

/* De zwevende WhatsApp-knop lag op deze pagina over de keuzeregels heen. Hij
 * gaat naar de linkerkant: rechts staan de bedragen en de knop Volgende, en
 * links is op deze pagina niets. Alleen hier, want alleen hier staat een
 * formulier dat het hele scherm vult. */
@media (max-width: 899px) {
  /* De zwevende WhatsApp-knop staat op DEZE pagina niet op een telefoon.
   *
   * Hij heeft hier drie plekken gehad en alle drie waren fout. Rechtsonder lag
   * hij over Volgende. Linksonder lag hij over Terug, en zodra er gescrold werd
   * ook over het lopende totaal: "the WhatsApp to the bottom left is in the way
   * of the price indication."
   *
   * Dat is geen kwestie van de juiste hoek zoeken. De wizard vult op een
   * telefoon het hele scherm en heeft onderin aan BEIDE kanten een knop staan,
   * dus elke hoek is bezet.
   *
   * Er gaat niets verloren: de balk onderin draagt "Bel ons", de prijsbalk
   * draagt de offerteknop, en in de voettekst staan het telefoonnummer en
   * WhatsApp gewoon. Op desktop blijft de knop staan, daar is de ruimte er
   * wel. Alleen deze pagina, want alleen hier wordt calculator.css geladen. */
  body a.ws-wa { display: none; }
}

/* Het bedrag zakt naar de tweede regel, naast de ondertitel.
 *
 * Naast de NAAM zetten kostte te veel breedte: "vanaf € 121,00 p/m incl. btw"
 * is lang, en op 390 hield de naam daardoor zo weinig over dat "Houten
 * schutting" alsnog over twee regels brak. De naam krijgt nu de volle breedte
 * en het bedrag deelt de onderste regel met de ondertitel. Twee korte regels
 * per kaart, en vier kaarten passen op een telefoonscherm.
 *
 * Het achtervoegsel incl. of excl. btw blijft staan: de klant vroeg er
 * uitdrukkelijk om dat overal bij te zetten. */
.ws-keuze {
  grid-template-areas:
    "mark label label"
    "mark sub   price";
  align-items: start;
}

.ws-keuze-mark { align-self: center; }
.ws-keuze-label { align-self: center; }
.ws-keuze-sub { align-self: center; }

.ws-keuze-price {
  align-self: center;
  text-align: right;
  white-space: nowrap;
  max-width: none;
  font-size: 12.5px;
}

@media (max-width: 460px) {
  .ws-keuze-price { white-space: nowrap; max-width: none; font-size: 12px; }
  .ws-keuze-sub { font-size: 12px; }
}

/* Derde en laatste vorm van de regel, gemeten in plaats van geschat.
 *
 * Naast de naam paste het bedrag niet: "vanaf € 121,00 p/m incl. btw" is 27
 * tekens en dan houdt de naam op 390 te weinig over. Naast de ondertitel paste
 * het ook niet: dan brak die ondertitel over vier regels.
 *
 * Dus onder elkaar: naam, ondertitel, bedrag. Drie korte regels van samen
 * ongeveer 70px, en vier kaarten passen daarmee in het paneel. Het bedrag
 * staat rechts, zodat de bedragen onder elkaar uitlijnen en te vergelijken
 * zijn; dat is waar deze stap voor bestaat.
 *
 * Op desktop is er wel breedte, daar blijft het bedrag naast de naam staan. */
@media (max-width: 620px) {
  .ws-keuze {
    grid-template-columns: 20px minmax(0, 1fr);
    grid-template-areas:
      "mark label"
      "mark sub"
      "mark price";
    row-gap: 2px;
  }
  .ws-keuze-mark { align-self: start; margin-top: 2px; }
  .ws-keuze-label { font-size: 14.5px; }
  .ws-keuze-sub { font-size: 12px; }
  .ws-keuze-price { text-align: left; font-size: 12.5px; white-space: nowrap; }

  /* Kop en uitleg van de vraag mogen op een telefoon compacter. */
  .ws-panel .ws-step h3 { font-size: 17.5px; margin-bottom: 3px; }
  .ws-panel .ws-step p.ws-hint { font-size: 12.5px; margin-bottom: 8px; }
  .ws-panel .ws-step { padding: 9px 14px 6px; }
  .ws-step-n { font-size: 11px; margin-bottom: 3px; }
}

@media (min-width: 621px) {
  .ws-keuze {
    grid-template-areas:
      "mark label price"
      "mark sub   price";
  }
  .ws-keuze-price { align-self: center; text-align: right; }
}

/* Laatste maatvoering voor de telefoon, uitgerekend en daarna gemeten.
 *
 * Vier kaarten van 80px plus de kop vroegen 460px terwijl er 360 was. Er moest
 * dus 100px af. Die komt uit twee plekken: de foto van 32 naar 24 procent van
 * de kaart, en de kaart zelf van 80 naar ongeveer 65px door strakkere
 * regelhoogtes. Niets is weggelaten, alles is dichter op elkaar gezet.
 *
 * De regel over die 24% is hier weg. Hij deed precies wat er daarna misging:
 * 24% van 675 is 162px bij 348 breed, en dat is een kader van 2,15:1 waar
 * liggend materiaal van 16:10 niet in past. De hoogte volgt nu uit de
 * verhouding van het kader, in het blok bij `max-width: 899px` hierboven. */
@media (max-width: 620px) {
  .ws-keuzes, .ws-checks, .ws-qty-list { gap: 6px; }

  .ws-keuze, .ws-check-card, .ws-qty-card { padding: 8px 12px; }

  .ws-keuze-label { font-size: 14.5px; line-height: 1.2; }
  .ws-keuze-sub   { font-size: 11.5px; line-height: 1.3; }
  .ws-keuze-price { font-size: 12px; line-height: 1.25; }

  .ws-check-label, .ws-qty-label { font-size: 14.5px; line-height: 1.2; }
  .ws-check-sub, .ws-qty-sub { font-size: 11.5px; line-height: 1.3; }

  .ws-nav { padding: 7px 14px 9px; }
  .ws-nav-btn { padding: 9px 20px; font-size: 14.5px; }
}

/* De laatste negen pixels. Zonder dit staat de onderste kaart net onder de
 * rand en lijkt er meer te zijn dan er is. */
@media (max-width: 620px) {
  .ws-panel .ws-step { padding-bottom: 0; }
}

/* Desktop: dezelfde rekensom als op de telefoon.
 *
 * De kaart stond op minimaal 440px en de vier kaartjes van stap 1 vroegen er
 * met kop en al zo'n 480. Op een laptop van 900px hoog viel de onderste
 * daardoor onder de knoppenbalk. De banner mag kleiner, de kaart mag hoger, en
 * de binnenmarges mogen strakker. */
@media (min-width: 900px) {
  .elementor-element-13e659b { min-height: 150px !important; }
  .ws-card { height: clamp(500px, calc(100vh - 400px), 680px); }
  .ws-panel .ws-step { padding: 22px 26px 4px; }
  .ws-panel .ws-step h3 { font-size: 20px; }
  .ws-panel .ws-step p.ws-hint { margin-bottom: 14px; }
  .ws-nav { padding: 12px 26px 18px; }
}

/* Zes houtsoorten is de langste stap, en die is de maat waar de kaart op
 * ontworpen moet zijn. Met een banner van 150px en een kaart van 500 vroeg die
 * stap 450px in een paneel van 419: de onderste twee houtsoorten vielen weg,
 * precies de stap waar vergelijken het hele punt is.
 *
 * De banner gaat naar 110 en de kaart mag 540. Alles wat nu nog scrolt is de
 * gegevensstap, en dat is een gewoon formulier waar scrollen normaal is. */
@media (min-width: 900px) {
  .elementor-element-13e659b { min-height: 110px !important; }
  .ws-progress { margin-bottom: 16px; }
  .ws-card { height: clamp(540px, calc(100vh - 340px), 700px); }
}

/* ==========================================================================
 * Desktop: het beeld als blok in de kolom, niet als vulling ervan
 * ==========================================================================
 * Op desktop vulde het kader de hele linkerkolom, en die kolom is hoger dan
 * breed: ongeveer 519 bij 560, dus staand. Met liggende foto's van 16:10 zou
 * `cover` daar de helft van de breedte afsnijden, precies de lengte van de
 * schutting waar de foto om draait.
 *
 * Dus krijgt het kader ook hier zijn eigen 16:10 en gaat het als blok in het
 * midden van de kolom staan. Dat is ook wat de configurator doet die de klant
 * aanwees: daar staat het beeld als een liggend blok met rust eromheen, niet
 * als een vlak van rand tot rand. Zie screenshots/work/ref-config-step2.png.
 *
 * De ondergrond van de kolom wordt daarmee zichtbaar en gaat van bijna zwart
 * naar papier. Zwart om een foto heen las als een balk die er niet hoort; het
 * kader zelf blijft wel donker, want de TEKENINGEN staan er in crème op.
 * ========================================================================== */
@media (min-width: 900px) {
  .ws-preview {
    justify-content: center;
    padding: 18px;
    background: var(--ws-paper);
    border-right: 1px solid var(--ws-line);
  }

  .ws-preview-frame {
    flex: none;
    width: 100%;
    min-height: 0;
    border-radius: 12px;
    box-shadow: 0 4px 18px rgba(21, 21, 21, .14);
  }
}
