/* Veton Charger Configurator — frontend stylesheet
 * Pre-compiled from assets/scss/configure.scss. Re-run `npm run build`
 * after editing the SCSS sources. Layout uses the theme's Bootstrap grid;
 * this file only styles the configurator's own components. */

/* Title bar */
/* NOTE: background must stay fully opaque. When .is-stuck (position:fixed)
   scrolls over the composer / step stack, a translucent bar let that content
   bleed through (visible "Type./Plug" ghosting mid-scroll). Solid white +
   a soft shadow keeps the sticky header legible over any content beneath. */
.vcc-title-bar {
  background: #ffffff;
  border-bottom: 1px solid rgba(220, 220, 222, 0.85);
  padding: 20px 0;
  transition: padding 250ms ease-out;
  position: absolute;
  top: 50px;
  left: 0;
  right: 0;
  z-index: 49;
}
@media (min-width: 768px) {
  .vcc-title-bar { top: 60px; }
}
.vcc-title-bar.is-stuck {
  position: fixed;
  top: 50px;
  padding: 8px 0;
  background: #ffffff;
  border-bottom: 0;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  animation: vcc-title-bar-slide-down 300ms ease-out;
}
@media (min-width: 768px) {
  .vcc-title-bar.is-stuck { top: 60px; padding: 15px 0; }
}
.vcc-title-bar.is-stuck .vcc-title { font-size: 18px; }
@media (min-width: 768px) {
  .vcc-title-bar.is-stuck .vcc-title { font-size: 21px; }
}
@keyframes vcc-title-bar-slide-down {
  from { transform: translateY(-100%); }
  to   { transform: translateY(0); }
}
.vcc-title-bar .vcc-title {
  margin: 0;
  font-size: 28px;
  line-height: 32px;
  font-weight: 700;
  color: #2A2A2A;
  transition: font-size 250ms ease-out;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.vcc-title-bar .nav {
  list-style: none;
  margin: 0;
  padding: 0;
}
.vcc-title-bar .nav li { margin-left: 20px; }
.vcc-title-bar .nav li:first-child { margin-left: 0; }
.vcc-title-bar .nav a {
  color: #C49E60;
  text-decoration: none;
  padding: 0;
}
.vcc-title-bar .nav a:hover { color: #9D783A; }
@media (max-width: 575px) {
  .vcc-title-bar .vcc-title { font-size: 21px; }
}

/* Product wrapper — clears the absolute-positioned title bar at scroll=0.
   On lg+ (>= 992px) we add 35px extra breathing room. */
#vcc-product {
  position: relative;
  margin-top: 75px;
  padding-bottom: 100px;
}
@media (min-width: 992px) {
  #vcc-product { margin-top: 135px; }
}

/* Image grid */
.vcc-image-wrapper {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 5px;
}
@media (min-width: 992px) {
  .vcc-image-wrapper {
    position: sticky;
    top: 165px;
    align-self: start;
  }
}
.vcc-image-wrapper .vcc-image-main {
  grid-column: 1 / -1;
  display: block;
  position: relative;
}
.vcc-image-wrapper .vcc-image-thumb {
  display: block;
  position: relative;
}
/* First image flows naturally and sets the anchor's height. Any additional
   stacked image (the crossfade overlay) is absolutely positioned on top so
   the two opacities can transition simultaneously. */
.vcc-image-wrapper .vcc-image-main img,
.vcc-image-wrapper .vcc-image-thumb img {
  width: 100%;
  height: auto;
  cursor: pointer;
  transition: opacity 750ms ease-out;
}
.vcc-image-wrapper .vcc-image-main img:nth-child(n+2),
.vcc-image-wrapper .vcc-image-thumb img:nth-child(n+2) {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
}
.vcc-image-wrapper .vcc-image-loader {
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.85);
  opacity: 0;
  z-index: 3;
  pointer-events: none;
  transition: opacity 250ms ease-out;
}
.vcc-image-wrapper .vcc-image-loader.is-visible {
  opacity: 1;
  pointer-events: auto;
}

/* Flex header: model title on left, VAT toggle on right */
.vcc-summary-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 5px;
}

/* Summary header title */
.vcc-product-title {
  margin: 0;
  flex: 0 0 auto;
  font-size: 32px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #2A2A2A;
}

/* VAT toggle — iOS-style pill switch */
.vcc-vat-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 1rem;
  flex-shrink: 0;
}
.vcc-vat-toggle .vcc-vat-label {
  color: #737373;
  font-size: 1rem;
  font-weight: 300;
  transition: color 200ms ease-out;
  user-select: none;
}
.vcc-vat-toggle[data-mode="excl"] .vcc-vat-label[data-side="excl"],
.vcc-vat-toggle[data-mode="incl"] .vcc-vat-label[data-side="incl"] {
  color: #C49E60;
}
.vcc-vat-toggle .vcc-vat-switch {
  width: 48px;
  height: 26px;
  border-radius: 14px;
  background: #f5f5f5;
  border: 0;
  padding: 0;
  position: relative;
  flex-shrink: 0;
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.25);
}
.vcc-vat-toggle[data-mode="incl"] .vcc-vat-switch { background: #f9f5ee; }
.vcc-vat-toggle .vcc-vat-knob {
  position: absolute;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #C49E60;
  top: 3px;
  left: 3px;
  transition: left 200ms ease-out;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
}
.vcc-vat-toggle[data-mode="incl"] .vcc-vat-knob { left: calc(100% - 23px); }

/* Inline option price */
.vcc-option-price {
  color: #656565;
  margin-left: 4px;
}
.vcc-product-title .vcc-product-logo {
  max-width: 75px;
  width: auto;
  height: 40px; /* explicit — SVGs without viewBox would otherwise collapse to 0 */
  vertical-align: middle;
}
.vcc-slogan {
  display: block;
  font-size: 21px;
  font-weight: 300;
  color: #2A2A2A;
  margin: 0 0 28px;
}
.vcc-price-from {
  color: #737373;
  font-size: 1.1rem;
  margin: 0 0 28px;
}
.vcc-slogan + .vcc-price-from { margin-top: -20px; }
.vcc-intro {
  color: #656565;
  line-height: 1.55;
  margin: 0 0 28px;
}

/* Card */
.vcc-card {
  border: 1px solid #dbdadb;
  padding: 20px;
  background: #ffffff;
  margin: 0;
}
.vcc-card .vcc-card-label {
  display: block;
  margin-bottom: 20px;
  font-weight: 700;
  color: #2A2A2A;
  padding: 0;
  width: auto;
  font-size: inherit;
}
.vcc-card .vcc-card-info {
  color: #656565;
  font-size: 1.1rem;
  margin: 0 0 30px;
  line-height: 1.5;
}

/* Shared option-row layout */
.vcc-radio,
.vcc-check {
  display: flex;
  align-items: center;
  position: relative;
  cursor: pointer;
  line-height: 20px;
  margin: 7px 0;
  user-select: none;
}
.vcc-radio input,
.vcc-check input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.vcc-radio .vcc-radio-text,
.vcc-check .vcc-check-text {
  color: #2A2A2A;
  font-size: 1.1rem;
  font-weight: 300;
}

/* Radio (single) */
.vcc-radio .vcc-radio-box {
  position: relative;
  display: inline-block;
  margin-right: 10px;
  width: 20px;
  height: 20px;
  border: 2px solid #dbdadb;
  border-radius: 50%;
  background: transparent;
  flex-shrink: 0;
  transition: all 0.4s cubic-bezier(0.35, 0.9, 0.4, 0.9);
}
.vcc-radio .vcc-radio-box::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #C49E60;
  transform: scale(0);
  opacity: 0.08;
  pointer-events: none;
  transition: all 0.2s ease-out;
}
.vcc-radio:hover .vcc-radio-box::after,
.vcc-radio input:focus-visible + .vcc-radio-box::after,
.vcc-radio:active .vcc-radio-box::after { transform: scale(3.6); }
.vcc-radio input:focus-visible + .vcc-radio-box { border-color: #C49E60; }
.vcc-radio input:checked + .vcc-radio-box { border-color: #C49E60; }
.vcc-radio input:checked + .vcc-radio-box::after {
  transform: scale(1);
  opacity: 1;
  transition: all 0.4s cubic-bezier(0.35, 0.9, 0.4, 0.9);
}
.vcc-radio input:disabled + .vcc-radio-box {
  border-color: #f1f1f1;
  background: #f1f1f1;
}

/* Checkbox (multi) */
.vcc-check .vcc-check-box {
  position: relative;
  display: inline-block;
  margin-right: 10px;
  width: 20px;
  height: 20px;
  border: 2px solid #dbdadb;
  border-radius: 3px;
  background: transparent;
  flex-shrink: 0;
  transition: all 0.2s ease-out;
}
.vcc-check .vcc-check-box::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #C49E60;
  transform: scale(0);
  opacity: 0.08;
  pointer-events: none;
  transition: transform 0.2s ease-out, opacity 0.2s ease-out;
}
.vcc-check .vcc-check-box::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 5px;
  width: 6px;
  height: 11px;
  border-right: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(45deg) scale(0);
  transform-origin: center;
  transition: transform 0.18s cubic-bezier(0.35, 0.9, 0.4, 0.9);
}
.vcc-check:hover .vcc-check-box::before,
.vcc-check input:focus-visible + .vcc-check-box::before,
.vcc-check:active .vcc-check-box::before { transform: scale(3.2); }
.vcc-check input:focus-visible + .vcc-check-box { border-color: #C49E60; }
.vcc-check input:checked + .vcc-check-box {
  background: #C49E60;
  border-color: #C49E60;
}
.vcc-check input:checked + .vcc-check-box::before { opacity: 0; }
.vcc-check input:checked + .vcc-check-box::after { transform: rotate(45deg) scale(1); }
.vcc-check input:disabled + .vcc-check-box {
  border-color: #f1f1f1;
  background: #f1f1f1;
}

/* Quantity */
.vcc-quantity {
  position: relative;
  width: 100%;
  display: flex;
  align-items: stretch;
}
.vcc-quantity .vcc-quantity-input {
  flex: 1;
  height: 42px;
  line-height: 1.65;
  padding: 0 0 0 20px;
  margin: 0;
  border: 1px solid #dbdadb;
  background: #ffffff;
  font-size: 16px;
  -moz-appearance: textfield;
}
.vcc-quantity .vcc-quantity-input:focus {
  outline: 0;
  border-color: #C49E60;
}
.vcc-quantity .vcc-quantity-input::-webkit-inner-spin-button,
.vcc-quantity .vcc-quantity-input::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.vcc-quantity .vcc-quantity-nav {
  position: relative;
  width: 28px;
  border-left: 1px solid #dbdadb;
  flex-shrink: 0;
}
.vcc-quantity .vcc-quantity-button {
  position: absolute;
  left: 0;
  right: 0;
  height: 50%;
  cursor: pointer;
  color: #333;
  font-size: 13px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  user-select: none;
}
/* Free-form RAL code field. Wrapper opens in two beats:
 *   1. The cream background slides open (grid-template-rows 0fr → 1fr)
 *   2. Once the wrap is (almost) fully open, the input + confirm fade in.
 * Closing reverses: input fades out first, then the wrapper collapses. */
.vcc-ral-wrap {
  display: grid;
  grid-template-rows: 0fr;
  background: #FBF7F0;
  transition: grid-template-rows 0.32s cubic-bezier(0.35, 0.9, 0.4, 0.9);
}
.vcc-ral-wrap.is-visible { grid-template-rows: 1fr; }
.vcc-ral-inner { overflow: hidden; min-height: 0; }
.vcc-ral-field {
  position: relative;
  margin: 0 14px 14px 14px;
}
.vcc-ral-field .vcc-ral-prefix {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: #656565;
  font-size: 1rem;
  font-weight: 700;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  pointer-events: none;
}
.vcc-ral-field .vcc-ral-input {
  width: 100%;
  /* right padding leaves room for the 38px confirm button (6px gap + 38px
   * pill + 6px breathing). */
  padding: 16px 52px 16px 42px;
  border: 1px solid #dbdadb;
  border-radius: 0;
  background: #fff;
  font-size: 1rem;
  font-weight: 300;
  color: #2A2A2A;
  transition: border-color 200ms ease-out;
}
.vcc-ral-field .vcc-ral-input::placeholder { color: #bbbbbb; opacity: 1; }
.vcc-ral-field .vcc-ral-input:focus { outline: none; border-color: #C49E60; }
/* Border colour mirrors the validation marker: red when the typed value
 * doesn't match the 4-digit format, green when it does. :has() lets the
 * parent field react to the state on its child confirm button. */
.vcc-ral-field:has(.vcc-ral-confirm[data-validation="invalid"]) .vcc-ral-input { border-color: #D9534F; }
.vcc-ral-field:has(.vcc-ral-confirm[data-validation="valid"])   .vcc-ral-input { border-color: #2BB673; }
/* Confirm "mark" inside the RAL field — renders a green check or red X
 * depending on the typed value's validity. configure.js sets
 * data-validation on the button (empty / valid / invalid) on each input
 * event. Both SVGs are stacked; the active one animates its strokes from
 * dashoffset 100 → 0 ("draws itself" from nothing). */
.vcc-ral-field .vcc-ral-confirm {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  width: 38px;
  height: 38px;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 0;
  border-radius: 3px;
  transition: background-color 200ms ease-out;
  outline: none;
}
/* Hide both mouse and keyboard focus rings — the data-validation state
 * (cream pill, gold check, red X) already gives clear visual feedback. */
.vcc-ral-field .vcc-ral-confirm:focus,
.vcc-ral-field .vcc-ral-confirm:focus-visible,
.vcc-variant-field .vcc-variant-confirm:focus,
.vcc-variant-field .vcc-variant-confirm:focus-visible,
.vcc-step-confirm:focus,
.vcc-step-confirm:focus-visible {
  outline: none;
  box-shadow: none;
}

/* Per-option step-confirm arrow — appears after the user picks a plain
 * choice (no RAL/variant child wrap). Same morph animation as the RAL
 * confirm: 3 SVG paths interpolate from a single centre point (empty) to
 * an arrow (valid). marginLeft:auto pushes it to the right edge of the
 * option pill. */
.vcc-step-confirm {
  margin-left: auto;
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 0;
  border-radius: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 280ms ease-out, background-color 200ms ease-out;
}
.vcc-step-confirm[data-validation="valid"] {
  opacity: 1;
  pointer-events: auto;
}
/* Hover paints a cream pill behind the arrow (matches the RAL/variant
 * confirm hover state). Active darkens the pill ~10% so the click reads. */
.vcc-step-confirm[data-validation="valid"]:hover  { background: #E6DECF; }
.vcc-step-confirm[data-validation="valid"]:active { background: #D6CDBA; }
.vcc-step-mark {
  width: auto;
  height: 20px;
  aspect-ratio: 26 / 24;
  display: block;
}
.vcc-step-stroke {
  fill: none;
  stroke: #C49E60;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: d 380ms cubic-bezier(0.4, 0, 0.2, 1);
}
.vcc-step-confirm[data-validation="valid"] .vcc-step-stroke-1 { d: path("M2 12 L24 12"); }
.vcc-step-confirm[data-validation="valid"] .vcc-step-stroke-2 { d: path("M24 12 L17 5"); }
.vcc-step-confirm[data-validation="valid"] .vcc-step-stroke-3 { d: path("M24 12 L17 19"); }
/* Hover only affects the button look in its valid (button) state — the X
 * has no button styling so it stays transparent on hover too. Override
 * the 350ms entry delay used for the initial cream fade-in so hover
 * reacts immediately instead of after a beat. */
.vcc-ral-field .vcc-ral-confirm[data-validation="valid"]:hover {
  background: #E6DECF;
}
.vcc-ral-field .vcc-ral-confirm[data-validation="valid"]:active {
  background: #D6CDBA;
}
/* When the typed value is valid, the confirm turns into a proper-looking
 * button: cream tile + gold check. The background fades in after a short
 * delay so the user first sees the green-on-white check confirm validity,
 * then the affordance materialises. Leaving the valid state clears it
 * immediately (no delay on the reverse transition). */
.vcc-ral-field .vcc-ral-confirm[data-validation="valid"] {
  background: #F9F5EE;
}
.vcc-ral-field .vcc-ral-mark {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: auto;
  height: 20px;
  aspect-ratio: 26 / 24;
  pointer-events: none;
  fill: none;
}
/* Three paths morph directly between three shapes via CSS `d`
 * interpolation:
 *   - empty:   all three at a point in the centre (invisible)
 *   - invalid: stroke-1 / stroke-2 are the X's diagonals, stroke-3 stays
 *              hidden at the centre point so it doesn't read in the X
 *   - valid:   stroke-1 is the arrow's horizontal shaft, stroke-2 / -3
 *              are the upper and lower chevrons — the hidden 3rd path
 *              grows into the lower chevron as the X morphs into the arrow
 * After the morph settles, the green arrow promotes to gold + a cream
 * "button" background fades in behind it. Reversing (valid → invalid or
 * valid → empty) clears the bg immediately. */
.vcc-ral-field .vcc-ral-stroke {
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke: transparent;
  transition: d 320ms ease, stroke 220ms ease;
}
.vcc-ral-field .vcc-ral-confirm[data-validation="invalid"] .vcc-ral-stroke   { stroke: #D9534F; }
.vcc-ral-field .vcc-ral-confirm[data-validation="invalid"] .vcc-ral-stroke-1 { d: path("M7 6 L19 18"); }
.vcc-ral-field .vcc-ral-confirm[data-validation="invalid"] .vcc-ral-stroke-2 { d: path("M19 6 L7 18"); }
.vcc-ral-field .vcc-ral-confirm[data-validation="invalid"] .vcc-ral-stroke-3 { d: path("M13 12 L13 12"); }
.vcc-ral-field .vcc-ral-confirm[data-validation="valid"]   .vcc-ral-stroke   { stroke: #2BB673; }
.vcc-ral-field .vcc-ral-confirm[data-validation="valid"]   .vcc-ral-stroke-1 { d: path("M2 12 L24 12"); }
.vcc-ral-field .vcc-ral-confirm[data-validation="valid"]   .vcc-ral-stroke-2 { d: path("M24 12 L17 5"); }
.vcc-ral-field .vcc-ral-confirm[data-validation="valid"]   .vcc-ral-stroke-3 { d: path("M24 12 L17 19"); }
/* Promote the arrow to primary-gold after the morph has visibly settled. */
.vcc-ral-field .vcc-ral-confirm[data-validation="valid"] .vcc-ral-stroke {
  animation: vcc-ral-arrow-promote 220ms ease 380ms forwards;
}
@keyframes vcc-ral-arrow-promote {
  from { stroke: #2BB673; }
  to   { stroke: #C49E60; }
}

/* Variant swatch grid (Optional Extras with variations).
 * Same slide-down wrap as the RAL field. Inside, a white "pill" mirrors the
 * RAL field — swatches on the left, confirm button on the right. The
 * confirm button reuses the RAL X→arrow morph (vcc-variant-stroke d-paths)
 * but only ever transitions between empty and valid for variants. */
.vcc-variant-wrap {
  display: grid;
  grid-template-rows: 0fr;
  background: #FBF7F0;
  transition: grid-template-rows 0.32s cubic-bezier(0.35, 0.9, 0.4, 0.9);
}
.vcc-variant-wrap.is-visible { grid-template-rows: 1fr; }
.vcc-variant-inner { overflow: hidden; min-height: 0; }
.vcc-variant-field {
  margin: 0 14px 14px 14px;
  background: #fff;
  border: 1px solid #dbdadb;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 6px 8px 8px;
}
.vcc-variant-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  flex: 1;
  min-width: 0;
}
.vcc-variant-swatch {
  appearance: none;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  overflow: hidden;
  transition: border-color 200ms ease, transform 200ms ease;
}
.vcc-variant-swatch img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.vcc-variant-swatch .vcc-variant-swatch-text {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: 0.7rem;
  color: #2A2A2A;
  background: #ECE0CB;
}
.vcc-variant-swatch:hover { border-color: #C49E60; }
.vcc-variant-swatch.is-active {
  border-color: #C49E60;
  box-shadow: 0 0 0 1px #C49E60;
}

/* Confirm button mirrors .vcc-ral-confirm: 30×30 tile that holds the
 * stroke-morph SVG. Empty state shows nothing (strokes transparent at
 * the centre point); valid state morphs the strokes into the arrow shape
 * and promotes them from green to gold. */
.vcc-variant-confirm {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 0;
  border-radius: 3px;
  position: relative;
  transition: background-color 200ms ease-out;
}
.vcc-variant-confirm[data-validation="valid"]:hover {
  background: #E6DECF;
}
.vcc-variant-confirm[data-validation="valid"]:active {
  background: #D6CDBA;
}
.vcc-variant-confirm[data-validation="valid"] {
  background: #F9F5EE;
}
.vcc-variant-mark {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: auto;
  height: 20px;
  aspect-ratio: 26 / 24;
  pointer-events: none;
  fill: none;
}
.vcc-variant-stroke {
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke: transparent;
  transition: d 320ms ease, stroke 220ms ease;
}
.vcc-variant-confirm[data-validation="valid"] .vcc-variant-stroke   { stroke: #2BB673; }
.vcc-variant-confirm[data-validation="valid"] .vcc-variant-stroke-1 { d: path("M2 12 L24 12"); }
.vcc-variant-confirm[data-validation="valid"] .vcc-variant-stroke-2 { d: path("M24 12 L17 5"); }
.vcc-variant-confirm[data-validation="valid"] .vcc-variant-stroke-3 { d: path("M24 12 L17 19"); }
.vcc-variant-confirm[data-validation="valid"] .vcc-variant-stroke {
  animation: vcc-ral-arrow-promote 220ms ease 380ms forwards;
}

/* "Need help along the way?" footer line below the last attribute card. */
.vcc-help-line {
  margin-top: 30px;
  margin-bottom: 0;
  color: #656565;
  font-size: 1rem;
  font-weight: 300;
  line-height: 1.5;
}
.vcc-help-line .vcc-help-link {
  color: #C49E60;
  font-size: 1rem;
  font-weight: 300;
  text-decoration: none;
  transition: color 0.18s ease-out;
}
.vcc-help-line .vcc-help-link:hover,
.vcc-help-line .vcc-help-link:focus {
  color: #9D783A;
  text-decoration: none;
  outline: none;
}

.vcc-quantity .vcc-quantity-button.vcc-quantity-up   { top: 0; border-bottom: 1px solid #dbdadb; }
.vcc-quantity .vcc-quantity-button.vcc-quantity-down { bottom: 0; }
.vcc-quantity .vcc-quantity-button:hover { background: #f1f1f1; }

/* Option row wraps a label + (optional) info trigger as siblings so the
   info click never bubbles through the label to toggle the input. */
.vcc-option-row {
  display: flex;
  align-items: center;
}
.vcc-option-row > .vcc-radio,
.vcc-option-row > .vcc-check { margin: 7px 0; }

/* Info trigger — small "(i)" next to a choice label. */
.vcc-info-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: 6px;
  padding: 0;
  width: 20px;
  height: 20px;
  border: 0;
  background: transparent;
  color: #C49E60;
  cursor: pointer;
  vertical-align: middle;
  font-size: 1rem;
  line-height: 1;
  transition: color 0.18s ease-out, transform 0.18s ease-out;
}
.vcc-info-trigger:hover,
.vcc-info-trigger:focus {
  color: #a5875b;
  transform: scale(1.08);
  outline: none;
}
.vcc-info-trigger i { display: block; line-height: 1; }

/* Info modal — overrides Bootstrap styling only where needed. */
.vcc-info-modal .modal-header .close {
  margin: 0 0 0 auto;
  padding: 0;
  background: transparent;
  border: 0;
  box-shadow: none;
  cursor: pointer;
  color: #2A2A2A;
  font-size: 1.2rem;
  line-height: 1;
}
.vcc-info-modal .modal-header .close:hover,
.vcc-info-modal .modal-header .close:focus {
  color: #C49E60;
  outline: none;
}
.vcc-info-modal .modal-header .close i { display: block; line-height: 1; }

.vcc-info-modal .vcc-info-image {
  background: #f1f1f1;
  border-radius: 0;
  overflow: hidden;
}
.vcc-info-modal .vcc-info-image img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 360px;
  object-fit: contain;
}
.vcc-info-modal .vcc-info-text {
  color: #656565;
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.vcc-info-modal .vcc-info-text p { margin: 0 0 .8em; }
.vcc-info-modal .vcc-info-text p:last-child { margin-bottom: 0; }

.vcc-info-modal .modal-body { padding-bottom: 35px; }
.vcc-info-modal .modal-footer {
  border-top: 0;
  padding-top: 0;
}

/* Region modal — shown to international visitors. Same chrome as the
   info/added modals; just tighter type sizes per spec. */
.vcc-region-modal .modal-title {
  font-size: 1.25rem;
  font-weight: 700;
  color: #2A2A2A;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.vcc-region-modal .modal-body,
.vcc-region-modal .modal-body p {
  font-size: 1.1rem;
  font-weight: 300;
  color: #656565;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.vcc-region-modal .modal-body p { margin: 0 0 .6em; }
.vcc-region-modal .modal-body p:last-child { margin-bottom: 0; }

/* "Added to order" confirmation modal */
.vcc-added-modal .modal-content { padding: 8px 14px 18px; }
.vcc-added-modal .modal-header {
  border-bottom: 0;
  padding: 8px 4px 0;
}
.vcc-added-modal .modal-header .close {
  margin: 0 0 0 auto;
  padding: 0;
  background: transparent;
  border: 0;
  box-shadow: none;
  cursor: pointer;
  color: #2A2A2A;
  font-size: 1.2rem;
  line-height: 1;
}
.vcc-added-modal .modal-header .close:hover,
.vcc-added-modal .modal-header .close:focus {
  color: #C49E60;
  outline: none;
}
.vcc-added-modal .modal-header .close i { display: block; line-height: 1; }
.vcc-added-modal .modal-title {
  margin: 0;
  padding-right: 12px;
  color: #2A2A2A;
  font-size: 1.55rem;
  font-weight: 500;
  line-height: 1.3;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.vcc-added-modal .modal-body { padding: 28px 4px 4px; }
.vcc-added-modal .vcc-added-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin: 0;
  padding: 18px 24px;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: uppercase;
  text-decoration: none;
  line-height: 1;
  cursor: pointer;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transition: background 0.18s ease-out, color 0.18s ease-out;
}
.vcc-added-modal .vcc-added-cta .icon-arrow-right { margin-left: 10px; }
.vcc-added-modal .vcc-added-cta--primary { border: 0; }
.vcc-added-modal .vcc-added-cta--outline {
  background: transparent;
  border: 1px solid #C49E60;
  color: #C49E60;
  box-shadow: none;
}
.vcc-added-modal .vcc-added-cta--outline:hover,
.vcc-added-modal .vcc-added-cta--outline:focus {
  background: #C49E60;
  color: #fff;
  outline: none;
}

/* Fixed bottom — releases (JS) when footer content top reaches viewport bottom,
   then switches to absolute at #vcc-product bottom + 30 (= footer content top). */
.vcc-current-state {
  background: rgba(249, 245, 238, 0.98);
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 50;
  overflow: hidden;
  opacity: 1;
  transition: opacity 320ms ease;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.vcc-current-state.is-released {
  position: absolute;
  bottom: 0;
}
.vcc-current-state .vcc-selection {
  color: #2A2A2A;
  line-height: 1.4;
  font-weight: 500;
  font-size: 1.3rem;
}
.vcc-current-state .vcc-cta {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-top: 20px;
}
@media (min-width: 768px) {
  .vcc-current-state .vcc-cta { margin-top: 0; justify-content: flex-end; }
}
.vcc-current-state .vcc-cumulative {
  color: #656565;
  font-weight: 500;
  font-size: 1.3rem;
  white-space: nowrap;
}
/* Price roll: the entire "from € 3.614,88 (excl. VAT)" line is the
 * animated unit. On change, old slides up + fades out while new slides
 * up from below + fades in. Clipping happens on .vcc-current-state (the
 * full sticky bar) instead of on .vcc-cumulative so the slide travels
 * the bar's height — the text is visually pulled all the way off the
 * top of the bar (and the new line comes from beyond the bottom).
 * .vcc-cumulative stays position:relative as the positioning context
 * for the absolute .is-leaving layer. */
.vcc-cumulative {
  position: relative;
  display: inline-block;
  vertical-align: bottom;
  text-align: right;
}
.vcc-price-text {
  display: inline-block;
}
.vcc-price-text.is-leaving {
  position: absolute;
  top: 0;
  right: 0;
  animation: vcc-price-leave 900ms ease-out forwards;
}
.vcc-price-text.is-entering {
  animation: vcc-price-enter 900ms ease-out backwards;
}
/* translateY values are percentages of the price-text's own height (~1.3rem).
 * 300% ≈ 4× the line height ≈ the typical .vcc-current-state height, so the
 * leaving line clears the top of the bar and the entering one starts well
 * below the bottom before sliding in.
 *
 * Opacity timing is offset from translate so the fade happens while the
 * element is INSIDE the visible bar area:
 *   - Leaving:  opaque while travelling through the bar, faded out by the
 *               time it reaches the top edge.
 *   - Entering: invisible while still below the bar (first 15% of duration),
 *               then fades up to fully opaque just inside the visible zone. */
@keyframes vcc-price-leave {
  0%   { transform: translateY(0);     opacity: 1; }
  45%  {                               opacity: 0; }
  100% { transform: translateY(-300%); opacity: 0; }
}
@keyframes vcc-price-enter {
  0%   { transform: translateY(300%);  opacity: 0; }
  15%  {                               opacity: 0; }
  55%  {                               opacity: 1; }
  100% { transform: translateY(0);     opacity: 1; }
}

.vcc-current-state .vcc-cumulative,
.vcc-cumulative * {
  color: #a89c8a;
  font-weight: 500;
  font-size: 1.3rem;
}
/* old #vcc-cumulative-suffix rule dropped — the full line is one .vcc-price-text now. */
/* Button uses theme's .btn.btn-secondary.btn-submit styling — no custom rules. */

/* =========================================================================
 * Progressive /configure/ — vertical step stack on the right, single-image
 * gallery slider on the left. The old .vcc-image-wrapper + .vcc-card flow
 * is no longer rendered by page-configure.php; legacy rules above are kept
 * for now to avoid touching the inquiry/details/overview templates which
 * still reuse some of those component classes.
 * ========================================================================= */

/* Centre the configure UI inside a viewport-tall (capped at 1000px) #content
 * so the gallery + step stack sit in the visual middle of the page on tall
 * screens. #vcc-product flex-grows to fill the full height of #content;
 * its in-flow .container is then vertically centred inside vcc-product.
 * This keeps .vcc-current-state.is-released (bottom:-30px on vcc-product)
 * flush with the footer instead of leaving a gap above it. */
body.vcc-configure #content {
  /* min-height (not height): on short windows — laptop with dock/toolbars,
     popped-out DevTools, split-screen — a hard height clamps the flex column
     and pushes the composer up under the fixed title bar / past the sticky
     bottom bar. min-height keeps the "centred at rest" look on tall screens
     while letting content grow the container when it doesn't fit. */
  min-height: min(100vh, 1000px);
  display: flex;
  flex-direction: column;
}
body.vcc-configure #vcc-product {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* margin-top reserves the fixed masthead height (50 mobile / 60 desktop)
   * because #content sits at viewport top:0 (no theme compensation). Padding
   * then reserves the title-bar (immediately below the masthead) and the
   * sticky current-state bar at the bottom, so the .container lands
   * geometrically between those two bars:
   *   - masthead:        50 (mobile) / 60 (lg+)
   *   - title-bar:       20 + 32 line-height + 20 + 1 border = 73px
   *   - current-state:   ~90px (py-20 + button row)
   * Overrides the legacy 75/135 margin-top + 100 padding-bottom used by the
   * old top-aligned layout. */
  margin-top: 50px;
  padding-top: 73px;
  padding-bottom: 90px;
}
@media (min-width: 768px) {
  body.vcc-configure #vcc-product { margin-top: 60px; }
}

/* Title bar — title + "from €" left, VAT toggle right. */
.vcc-title-bar .vcc-title-block { display: flex; flex-direction: column; gap: 6px; }
.vcc-title-bar .vcc-title-block .vcc-price-from {
  font-size: 1.1rem;
  color: #8C8C8C;
  font-weight: 400;
  margin: 0;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ----- Gallery slider (left) -----
 * 4 anchors stacked absolutely; only .is-active is at opacity 1. Nav buttons
 * step the active index; gallery-key changes silently swap each slide's src
 * via configure.js (preload-then-set on the inactive layer pattern). */
/* --- Composer ---------------------------------------------------------------
 * Stacked image rig (shadow / body / trim / cable) that replaces the static
 * gallery. Each .vcc-composer-layer is an <img> absolutely positioned over the
 * frame; configure.js sets src per layer based on the current state.
 */
.vcc-composer {
  position: relative;
  background: #eaeaea;
  aspect-ratio: 4 / 3;
  overflow: hidden;
}
/* Native scroll-snap carousel: 3 slides (one per pose) sit side-by-side in
 * a horizontally scrolling container. The browser handles touch-follow,
 * momentum, and snap-back so the swipe reads like Apple's product
 * carousels rather than a JS-driven transform. Each slide carries its
 * own grey background + own 4-layer img stack, so the background scrolls
 * along with the image. Scrollbars hidden because the dots already
 * indicate position. */
.vcc-composer-scroll {
  position: absolute;
  inset: 0;
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
  /* Earlier steps: block horizontal swipe so the gallery doesn't react
   * before the user reaches the "Your Veton® …" overview step. Vertical
   * page scroll still passes through. Programmatic scrollTo (used for
   * step-driven pose changes) is unaffected by touch-action. */
  touch-action: pan-y;
}
.vcc-composer[data-gallery-mode="1"] .vcc-composer-scroll { touch-action: auto; }
.vcc-composer-scroll::-webkit-scrollbar { display: none; }
.vcc-composer-slide {
  flex: 0 0 100%;
  position: relative;
  scroll-snap-align: center;
  scroll-snap-stop: always;
  background: #eaeaea;
}
/* Mobile-only: when JS relocates the composer into the overview card
 * (last step reached, see relocateComposerForOverview() in configure.js),
 * leave room below the gallery for the dots (top:100% + margin-top:12px
 * + 8px height ≈ 20px overhang) plus a ~30px gap before the "Your Veton® …"
 * title. */
@media (max-width: 991.98px) {
  .vcc-step-overview > .vcc-composer { margin-bottom: 50px; }
}
.vcc-composer-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  /* Default per-layer fade — used by the per-slide crossfade when a
   * single layer's source changes (RAL colour, trim variant, etc.).
   * Shared house bezier matches attribute-card / RAL-wrap / confirm-
   * button transitions for visual consistency. */
  transition: opacity 220ms cubic-bezier(0.35, 0.9, 0.4, 0.9);
  pointer-events: none;
  /* Hint the compositor that opacity is the only thing animating, so
   * the layer is promoted to its own GPU surface and stays there for
   * the whole crossfade — avoids the brief tail-end repaint flicker
   * we'd see when the previous img got demoted at fade end. */
  will-change: opacity;
}
.vcc-composer-layer.is-visible { opacity: 1; }
.vcc-composer-layer[data-layer="shadow"] { z-index: 1; }
.vcc-composer-layer[data-layer="body"]   { z-index: 2; }
.vcc-composer-layer[data-layer="trim"]   { z-index: 3; }
.vcc-composer-layer[data-layer="cable"]  { z-index: 4; }

/* Body-ready gate: shadow / trim / cable stay at opacity 0 until the
 * body layer has actually decoded (configure.js sets .is-body-ready on
 * the slide / composer the first time the body img's onload fires).
 * Prevents the visual glitch where a small cable / shadow asset finishes
 * loading before the larger body image and briefly paints "floating" on
 * the grey background. */
.vcc-composer-slide:not(.is-body-ready) .vcc-composer-layer:not([data-layer="body"]),
.vcc-composer:not(.is-body-ready) > .vcc-composer-layer:not([data-layer="body"]) {
  opacity: 0;
}

/* Pose-change fade: while data-state="hidden" every layer drops to opacity 0
 * during ~250ms so configure.js can swap srcs at the trough, then data-state
 * flips back to "visible" and the new pose fades up. Sync'd with the step
 * stack's 750ms cubic-bezier transition. */
.vcc-composer[data-state="hidden"] .vcc-composer-layer.is-visible {
  opacity: 0;
  transition: opacity 250ms ease-in;
}
.vcc-composer[data-state="visible"] .vcc-composer-layer.is-visible {
  opacity: 1;
  transition: opacity 300ms ease-out;
}

/* Gallery navigation — hidden until the user moves past the material step.
 * data-gallery-mode="1" reveals the prev/next arrows and the 3 pose dots. */
.vcc-composer-nav,
.vcc-composer-dots { display: none; }
.vcc-composer[data-gallery-mode="1"] .vcc-composer-nav,
.vcc-composer[data-gallery-mode="1"] .vcc-composer-dots { display: flex; }

.vcc-composer-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  border-radius: 0;
  background: rgba(0, 0, 0, 0.5);
  border: 0;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: #fff;
  font-size: 20px;
  padding: 0;
  transition: background-color 0.2s ease;
  z-index: 3;
}
.vcc-composer-nav:hover { background: rgba(0, 0, 0, 0.75); }
.vcc-composer-prev { left: 16px; }
.vcc-composer-next { right: 16px; }

.vcc-composer-dots {
  position: absolute;
  left: 50%;
  bottom: 16px;
  transform: translateX(-50%);
  gap: 8px;
  z-index: 3;
}
.vcc-composer-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.3);
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: background 200ms ease;
}
.vcc-composer-dot:hover { background: rgba(0, 0, 0, 0.5); }
.vcc-composer-dot.is-active { background: #c8a85d; }

/* Mobile gallery layout: drop the nav arrows, push the dots out from
 * inside the composer to just below it, shrink them to 8px, and skip
 * the scale-up on the active dot (colour-only delta reads cleaner on
 * the smaller hit target). overflow:visible on both composer + slider
 * lets the dots peek below AND the outgoing slide travel off-screen
 * (Apple carousel feel). On desktop the slider stays clipped so the
 * slide doesn't bleed into the right-column step cards. */
@media (max-width: 991.98px) {
  .vcc-composer        { overflow: visible; }
  .vcc-composer[data-gallery-mode="1"] .vcc-composer-nav { display: none; }
  .vcc-composer-dots {
    top: 100%;
    bottom: auto;
    margin-top: 12px;
  }
}

/* ----- Step stack (right) ----- */
.vcc-steps {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.vcc-step-card {
  display: flex;
  flex-direction: column;
}
.vcc-step-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0;
  padding: 0;
  background: transparent;
  border: 0;
  cursor: default;
  outline: none;
  user-select: none;
}
.vcc-step-card.is-past .vcc-step-head { cursor: pointer; }
.vcc-step-card.is-past .vcc-step-head:hover .vcc-step-title,
.vcc-step-card.is-past .vcc-step-head:focus-visible .vcc-step-title { color: #C49E60; }
.vcc-step-title {
  font-size: 1.75rem;
  font-weight: 700;
  margin: 0 0 5px;
  letter-spacing: 0;
  transition: color 0.25s ease;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.vcc-step-value {
  font-size: 1.75rem;
  font-weight: 700;
  color: #d4d4d4;
  letter-spacing: 0;
  transition: color 0.25s ease, opacity 0.25s ease;
  opacity: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.vcc-step-card.is-past   .vcc-step-value { color: #d4d4d4; opacity: 1; }
.vcc-step-card.is-future .vcc-step-title { color: #b9b9b9; }
/* Title is black on every step that has been opened (= active or past),
 * whether or not the user picked a radio. Only is-future (never opened)
 * stays in the muted grey above. */
.vcc-step-card.is-active .vcc-step-title,
.vcc-step-card.is-past   .vcc-step-title {
  color: #2A2A2A;
}

/* One-shot pulse on the heading when the step is freshly activated (added
 * by configure.js via .is-just-activated, removed after the animation).
 * Combines a brief scale-up (visible even when the title is already gold
 * from past-state hover) with a long gold hold + fade-to-black at the end.
 * animation-fill-mode: both keeps the 0% keyframe applied at the moment
 * the class is added, sidestepping the existing transition: color. */
@keyframes vcc-step-pulse {
  0%   { transform: scale(1);    color: #C49E60; }
  20%  { transform: scale(1.04); color: #C49E60; }
  70%  { transform: scale(1);    color: #C49E60; }
  100% { transform: scale(1);    color: #2A2A2A; }
}
.vcc-step-card.is-just-activated .vcc-step-title {
  animation: vcc-step-pulse 1000ms ease-out both;
  transform-origin: left center;
}

/* Pane animates open via grid-template-rows 0fr -> 1fr. Inner box is the
 * actual content box; min-height:0 lets it collapse fully. */
.vcc-step-pane {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  margin-top: 0;
  transition: grid-template-rows 0.4s ease, opacity 0.3s ease, margin-top 0.35s ease;
  pointer-events: none;
}
.vcc-step-card.is-active .vcc-step-pane {
  grid-template-rows: 1fr;
  opacity: 1;
  pointer-events: auto;
}
.vcc-step-pane-inner {
  min-height: 0;
  overflow: hidden;
}
.vcc-step-intro {
  font-size: 1.25rem;
  font-weight: 500;
  color: #8C8C8C;
  margin: 0 0 30px;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.vcc-step-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 10px;
}
/* Each choice (label + optional RAL field) lives in a cell so the gap from
 * .vcc-step-options is between CELLS, not between the label and its inline
 * RAL field — keeps them visually flush as one box when expanded. */
.vcc-step-option-cell {
  display: flex;
  flex-direction: column;
}
.vcc-step-option {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  background: #f5f5f5;
  cursor: pointer;
  transition: background-color 0.2s ease;
  position: relative;
}
.vcc-step-option:hover { background: #ececec; }
.vcc-step-option input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
/* Puffy "pearl" radio. Unchecked state has no solid fill — a soft radial
 * gradient + opposing inset shadows give the 3D-ball look. On check the
 * background swaps to a gold gradient, the cream border appears, and the
 * inner cream dot (::after) springs in from scale 0 to scale 1 with a
 * cubic-bezier overshoot (easeOutBack). */
/* Radio "pearl". Unchecked = transparent fill with a single top-down inset
 * shadow for the carved-in look. Checked = solid gold + cream ring border,
 * background fades in over 320ms (matching the previous spring duration). */
.vcc-step-option-box {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1px solid transparent;
  background: transparent;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.25);
  margin-top: 1px;
  position: relative;
  transition:
    background-color 320ms ease,
    border-color     320ms ease;
}
.vcc-step-option input:checked + .vcc-step-option-box {
  border-color: #ECE0CB;
  background-color: #C49E60;
}
.vcc-step-option-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  min-width: 0;
}
.vcc-step-option-label {
  font-size: 1.1rem;
  font-weight: 600;
  color: #2A2A2A;
  line-height: 1.3;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.vcc-step-option-label .vcc-option-price {
  font-weight: 400;
  color: #8C8C8C;
  margin-left: 4px;
}
.vcc-step-option-info {
  font-size: 0.9rem;
  font-weight: 400;
  color: #8C8C8C;
  line-height: 1.4;
}
/* Selected option uses cream tint (matches questionnaire is-active card). */
.vcc-step-option:has(input:checked) {
  background: #F9F5EE;
}

/* Conditional-availability hide: configure.js toggles this when the option's
 * "Requires" rule isn't met by the current selection. We keep it as
 * display:none to also collapse the layout — the option simply doesn't
 * exist for the user until they pick the prerequisite. */
.vcc-step-option.is-hidden-by-requires { display: none; }

/* Overview step uses the same .vcc-step-title rules (font-size, colours,
 * hover, pulse) as the other steps — its h2 carries both classes. */
.vcc-step-overview {
  position: relative;
  padding-top: 0;
  margin-top: 0;
  transition: padding-top 600ms ease, margin-top 600ms ease;
}
.vcc-step-overview.is-active {
  padding-top: 31px;
  margin-top: 11px;
}
/* Border-top drawn as a pseudo-element with an animatable width so it
 * "draws in" from the left when the step becomes active, and retracts the
 * same way when it leaves the active state. Width was chosen over scaleX
 * because pseudo-elements can lose their transform on subpixel rounding
 * and the visible transition becomes flaky on some browsers/zoom levels. */
.vcc-step-overview::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 1px;
  background: #dbdadb;
  transition: width 600ms ease;
}
.vcc-step-overview.is-active::before {
  width: 100%;
}
.vcc-step-overview .vcc-step-head {
  margin-bottom: 15px;
}
/* Stack overview pane content vertically (price → CTA) so each sits on
 * its own row, left-aligned. */
.vcc-step-overview .vcc-step-pane-inner {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 30px;
}
/* Overview-pane price — same value as the sticky bar but in a darker grey
 * (#656565) to read as primary content rather than the muted bar-cream
 * tone. Selectors include the inner .vcc-price-text so the shared
 * `.vcc-cumulative *` rule doesn't override the colour. */
.vcc-step-overview-price,
.vcc-step-overview-price * {
  color: #656565;
  font-weight: 500;
  white-space: nowrap;
  text-align: left;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
/* Theme ships .btn.btn-secondary with width: 100% !important. To win the
 * cascade we (a) keep the !important and (b) chain extra classes from the
 * same element so our specificity (0,0,3,0) beats the theme's (0,0,2,0). */
.vcc-step-overview-cta.btn.btn-secondary {
  display: inline-block !important;
  width: auto !important;
}
/* Disabled when not all preceding steps have a pick. pointer-events:none
 * blocks the Bootstrap modal trigger + our stash click handler in one go. */
.vcc-step-overview-cta.is-disabled {
  opacity: 0.45;
  pointer-events: none;
  cursor: not-allowed;
}

/* Sticky-bar "Add to order" — fully removed from layout until every step
 * has a pick, so the "from €" price hugs the right edge of the bar. When
 * the gate opens the button takes its place in the flex row (pushing the
 * price leftward) and slides in from off-screen right. Clipping is on the
 * dedicated .vcc-cta-button-slot (NOT on .vcc-cta) so the price-roll on
 * .vcc-cumulative is free to animate vertically past the cta's bounds. */
.vcc-current-state .vcc-cta-button-slot {
  display: inline-flex;
  overflow: hidden;
  /* Reserve the button's height even while the button is display:none, so
   * the bar doesn't grow ~10px taller the moment the CTA reveals. */
  min-height: 40px;
  align-items: center;
}
.vcc-current-state #vcc-request-offer {
  display: none !important;
}
.vcc-current-state #vcc-request-offer.is-revealed {
  display: inline-block !important;
  width: auto !important;
  animation: vcc-cta-bar-in 500ms ease-out both;
}
@keyframes vcc-cta-bar-in {
  from { transform: translateX(100%); opacity: 0; }
  to   { transform: none;             opacity: 1; }
}

/* Inline asterisk hugging the step title (no extra spacing — sits between
 * the title text and the final period). Inherits colour via the parent
 * (state-cascade), and re-declares the typography props that don't always
 * inherit cleanly across vendor smoothing rules. Hidden on non-active
 * steps so past/future headings read as plain "Title. value." lines. */
.vcc-step-title-asterisk {
  margin: 0 1px;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  letter-spacing: inherit;
  color: inherit;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.vcc-step-card:not(.is-active) .vcc-step-title-asterisk { display: none; }

/* Footnote shown below the options list when the admin filled in
 * vcc_configuration.categories[<id>].footnote. Muted, italic-free, with
 * a hanging * for visual link to the title's asterisk. */
.vcc-step-footnote {
  margin: 15px 0;
  font-size: 0.9rem;
  font-weight: 400;
  color: #8C8C8C;
  line-height: 1.25;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.vcc-step-footnote-mark {
  display: inline-block;
  margin-right: 2px;
}

/* ============ Mobile / tablet (< lg, 991.98px and below) =============
 * Desktop layout (≥ lg / 992px) stays exactly as defined above. Everything
 * inside this query is a mobile-only override; never put desktop-affecting
 * declarations here. */
@media (max-width: 991.98px) {
  .vcc-current-state .vcc-cta { margin-top: 0; }
  /* Disable the vertical roll on the price line — keep just the opacity
   * fade. !important overrides the transform applied by the keyframe so
   * the leaving + entering layers fade in place without moving. */
  .vcc-price-text { transform: none !important; }
  /* Cookiebot "renew consent" floating widget — sits bottom-left by default
   * which collides with the sticky vcc-current-state on small screens.
   * Flip it to bottom-right on mobile. (The widget itself is up for a
   * full replacement later — this is just a stop-gap.) */
  #CookiebotWidget,
  .CookiebotWidget {
    left: auto !important;
    right: 16px !important;
  }
  /* Mirror the desktop overlap into the footer's padding-top, scaled to
   * the mobile padding (pt-15 ≈ 15px) so the bar's bottom edge sits at
   * the .main-footer border-top — same visual relationship as desktop
   * where -30px matches pt-lg-30. Pair with the IO rootMargin override
   * in configure.js. */
  .vcc-current-state.is-released { bottom: -15px; }
  /* Desktop centres the configurator inside a 100vh-capped #content (see
   * line ~849). On mobile the content stacks and is usually taller than
   * the viewport, so the cap traps everything in a 100vh box, the
   * footer is permanently "intersecting" the IO root, and the bar gets
   * stuck mid-page in is-released state. Drop back to natural document
   * flow on mobile — #content grows with its content, #vcc-product
   * stops flex-centring. The fixed → absolute toggle then behaves as
   * intended: fixed at viewport-bottom while scrolling, releasing to
   * #vcc-product's bottom (= footer-top) when the footer enters view. */
  body.vcc-configure #content {
    height: auto;
    display: block;
  }
  body.vcc-configure #vcc-product {
    flex: none;
    display: block;
  }
  .vcc-steps {
    padding-top: 20px;
    padding-bottom: 20px;
  }
  /* Sticky bar on mobile: hide the "Add to order" CTA (overview step has
   * its own and the user is meant to scroll through the steps), and
   * tighten the from-price typography so it sits comfortably on a
   * narrow row. Targets both the wrapper and its children because the
   * base rule sets font-size on `.vcc-cumulative *` too. */
  .vcc-current-state .vcc-cta-button-slot { display: none; }
  .vcc-current-state .vcc-cumulative,
  .vcc-current-state .vcc-cumulative * {
    font-size: 1.1rem;
  }
  /* Fade the sticky bar out while the overview step is active — its CTA
   * + price already live in the step card on mobile, so the bar would
   * just duplicate the same action in cramped vertical space. Desktop
   * has plenty of room and keeps the bar visible (no rule outside this
   * media block). pointer-events off so the hidden bar can't be
   * accidentally tapped during the fade. */
  .vcc-current-state.is-overview-active {
    opacity: 0;
    pointer-events: none;
  }
}
