{
  "version": 3,
  "sources": ["/cdn/shop/t/35/assets/lux-sheer-design-studio-v5.js?lux_v=20260729_sheer_single_track_v535"],
  "sourcesContent": ["/**\n * LUXWORLD Design Studio\u2122 \u2014 Sheer Curtain Builder V5\n * Production journey and pricing engine for sections/lux-sheer-design-studio-v5.liquid.\n * @version 5.3.5\n */\n(() => {\n  /* =====================================================================\n     01. FILE HEADER AND STRICT MODE\n     ===================================================================== */\n\n  \"use strict\";\n\n  /* =====================================================================\n     02. CONSTANTS AND ENUMS\n     ===================================================================== */\n\n  const VERSION = \"5.3.5-sheer\";\n  const ROOT_ID = \"luxDoubleDesignStudioV5\";\n  const DATA_ID = \"LuxSheerDesignStudioV5Data\";\n  const STORAGE_KEY = \"luxworld_sheer_studio_v5_project\";\n  const PRICING_ERROR =\n    \"Pricing is temporarily unavailable for this selection. Please choose another option or contact LUXWORLD.\";\n\n  const STAGES = Object.freeze({\n    ENTRY: \"entry\",\n    WHOLE_HOME_PLANNER: \"whole-home-planner\",\n    FABRIC_SELECTION: \"fabric-selection\",\n    MEASUREMENTS: \"measurements\",\n    WINDOW_CONFIGURATION: \"window-configuration\",\n    WINDOW_REVIEW: \"window-review\",\n    PROJECT_REVIEW: \"project-review\"\n  });\n\n  const MODES = Object.freeze({ SINGLE: \"single\", WHOLE_HOME: \"whole-home\" });\n  const STATUS = Object.freeze({\n    PLANNED: \"planned\",\n    ACTIVE: \"active\",\n    COMPLETE: \"complete\",\n    ERROR: \"error\"\n  });\n\n  const OPTION_LABELS = Object.freeze({\n    heading: {\n      \"s-wave\": \"S-Wave Fold\",\n      \"double-pinch\": \"Double Pinch Pleat\",\n      \"triple-pinch\": \"Triple Pinch Pleat\"\n    },\n    supply: {\n      \n      \"curtain-only\": \"Curtains Only\",\n    \"manual-double-track\": \"Single Curtain Tracks\",\n      \"motorised-double-track\": \"Motorized Tracks\",\n      \"led-motorised-double-track\": \"Motorized Tracks with LED\"\n    },\n    trackColour: { white: \"White\", black: \"Black\", platinum: \"Platinum\" },\n    opening: {\n      centre: \"Centre Opening\",\n      left: \"Left Stack\",\n      right: \"Right Stack\",\n      free: \"Free Hanging\"\n    },\n    fixing: { ceiling: \"Ceiling Mounted\", wall: \"Wall Mounted\" },\n    finish: {\n      \"off-floor\": \"Slightly Off Floor\",\n      puddle: \"Puddle\"\n    },\n\n});\n\n  const HOUSE_PRESETS = Object.freeze([\n    { name: \"Studio / Apartment\", rooms: { \"Living Room\": 1, \"Master Bedroom\": 1 } },\n    {\n      name: \"2 Bedroom Home\",\n      rooms: { \"Living Room\": 1, \"Dining Room\": 1, \"Master Bedroom\": 1, \"Bedroom 1\": 1 }\n    },\n    {\n      name: \"3 Bedroom Home\",\n      rooms: {\n        \"Living Room\": 1,\n        \"Dining Room\": 1,\n        \"Master Bedroom\": 1,\n        \"Bedroom 1\": 1,\n        \"Bedroom 2\": 1\n      }\n    },\n    {\n      name: \"4 Bedroom Home\",\n      rooms: {\n        \"Living Room\": 1,\n        \"Dining Room\": 1,\n        \"Master Bedroom\": 1,\n        \"Bedroom 1\": 1,\n        \"Bedroom 2\": 1,\n        \"Bedroom 3\": 1\n      }\n    }\n  ]);\n\n  const REQUIRED_DOM = Object.freeze([\n    \"luxV5Loading\",\n    \"luxV5FatalError\",\n    \"luxV5FatalErrorMessage\",\n    \"luxV5Application\",\n    \"luxV5Entry\",\n    \"luxV5Planner\",\n    \"luxV5JourneyHeader\",\n    \"luxV5Progress\",\n    \"luxV5Workspace\",\n    \"luxV5FabricLookStage\",\n    \"luxV5MeasurementStage\",\n    \"luxV5ConfigurationStage\",\n    \"luxV5WindowReviewStage\",\n    \"luxV5ProjectReviewStage\",\n    \"luxV5SheerCollections\",\n    \"luxV5SheerProduct\",\n    \"luxV5SheerVariants\",\n    \"luxV5BlackoutCollections\",\n    \"luxV5BlackoutProduct\",\n    \"luxV5BlackoutVariants\",\n    \"luxV5Width\",\n    \"luxV5Drop\",\n    \"luxV5Sidebar\",\n    \"luxV5CheckoutButton\"\n  ]);\n\n  /* =====================================================================\n     03. CONFIGURATION\n     ===================================================================== */\n\n  let config = null;\n  let catalog = null;\n  let dom = null;\n  let state = null;\n  let pricingProvider = null;\n  let initialised = false;\n  let lastFocusedElement = null;\n  let inputFrame = 0;\n\n  /* =====================================================================\n     04. UTILITIES\n     ===================================================================== */\n\n  const toNumber = (value, fallback = 0) => {\n    const parsed = Number(value);\n    return Number.isFinite(parsed) ? parsed : fallback;\n  };\n\n  const clamp = (value, minimum, maximum) =>\n    Math.min(maximum, Math.max(minimum, toNumber(value)));\n\n  const roundMoney = value => Math.round((toNumber(value) + Number.EPSILON) * 100) / 100;\n  const roundUpDollar = value => Math.ceil(Math.max(0, toNumber(value)));\n  const positive = value => Number.isFinite(Number(value)) && Number(value) > 0;\n  const deepCopy = value => JSON.parse(JSON.stringify(value));\n  const idString = value => (value === null || value === undefined ? \"\" : String(value));\n  const uid = prefix =>\n    `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 9)}`;\n\n  const cleanText = (value, limit = 1000) =>\n    String(value ?? \"\")\n      .replace(/[\\u0000-\\u001f\\u007f]/g, \" \")\n      .replace(/\\s+/g, \" \")\n      .trim()\n      .slice(0, limit);\n\n  const money = value => {\n    if (!Number.isFinite(Number(value)) || Number(value) < 0) return \"Unavailable\";\n    try {\n      return new Intl.NumberFormat(config?.locale || \"en-AU\", {\n        style: \"currency\",\n        currency: config?.currencyCode || \"AUD\",\n        minimumFractionDigits: 0,\n        maximumFractionDigits: 0\n      }).format(roundUpDollar(value));\n    } catch (_) {\n      return `$${roundUpDollar(value)}`;\n    }\n  };\n\n  const savedTimeLabel = value => {\n    const date = value ? new Date(value) : new Date();\n    if (Number.isNaN(date.getTime())) return \"Saved\";\n    return `Saved ${date.toLocaleTimeString([], { hour: \"numeric\", minute: \"2-digit\" })}`;\n  };\n\n  const element = (tag, className, text) => {\n    const node = document.createElement(tag);\n    if (className) node.className = className;\n    if (text !== undefined) node.textContent = text;\n    return node;\n  };\n\n  const clear = node => {\n    if (node) node.replaceChildren();\n    return node;\n  };\n\n  const setHidden = (node, hidden) => {\n    if (!node) return;\n    node.hidden = Boolean(hidden);\n    node.setAttribute(\"aria-hidden\", hidden ? \"true\" : \"false\");\n  };\n\n  const setAction = (node, action, value) => {\n    node.dataset.v5Action = action;\n    if (value !== undefined) node.dataset.v5Value = String(value);\n    return node;\n  };\n\n  const debounceInputPricing = () => {\n    cancelAnimationFrame(inputFrame);\n    inputFrame = requestAnimationFrame(() => {\n      recalculate();\n      if (state.journey.stage === STAGES.MEASUREMENTS) {\n        updateMeasurementValidation();\n        renderMeasurementPricePanel();\n      }\n      renderSidebar();\n      updatePrimaryAction();\n    });\n  };\n\n  const announce = (message, kind = \"status\") => {\n    if (!dom?.announcement) return;\n    dom.announcement.textContent = message;\n    dom.announcement.classList.toggle(\"has-error\", kind === \"error\");\n  };\n\n  const themeHeaderOffset = () => {\n    const themeHeaderGroup = document.querySelector(\n      \".shopify-section-group-header-group, [data-header-group]\"\n    );\n    let headerOffset = 0;\n    if (themeHeaderGroup && !dom.root.contains(themeHeaderGroup)) {\n      const style = window.getComputedStyle(themeHeaderGroup);\n      const rect = themeHeaderGroup.getBoundingClientRect();\n      if (style.display !== \"none\" && style.visibility !== \"hidden\") {\n        headerOffset = Math.min(rect.height, 360);\n      }\n    }\n    if (headerOffset) return headerOffset;\n    return [\n      ...document.querySelectorAll(\n        \"header, [role='banner'], #shopify-section-header, .header-wrapper, .announcement-bar\"\n      )\n    ].reduce((maximum, node) => {\n      if (dom.root.contains(node)) return maximum;\n      const style = window.getComputedStyle(node);\n      const rect = node.getBoundingClientRect();\n      const visibleAtTop =\n        style.display !== \"none\" &&\n        style.visibility !== \"hidden\" &&\n        rect.top <= 4 &&\n        rect.bottom > 0 &&\n        rect.bottom <= 360;\n      return visibleAtTop ? Math.max(maximum, rect.bottom) : maximum;\n    }, 0);\n  };\n\n  const scrollStageIntoView = () => {\n    const active = dom.root.querySelector(\".lux-v5-stage:not([hidden]), .lux-v5-planner:not([hidden])\");\n    if (!active) return;\n    const reducedMotion = window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n    const alignBuilderTop = behavior => {\n      const rootTop = dom.root.getBoundingClientRect().top + window.scrollY;\n      window.scrollTo({\n        top: Math.max(0, rootTop - themeHeaderOffset()),\n        behavior\n      });\n    };\n    alignBuilderTop(reducedMotion ? \"auto\" : \"smooth\");\n    // Recheck once the theme has completed any hide/show header animation.\n    window.setTimeout(() => alignBuilderTop(\"auto\"), reducedMotion ? 50 : 320);\n  };\n\n  /* =====================================================================\n     05. DOM REGISTRY\n     ===================================================================== */\n\n  const createDomRegistry = root => {\n    const get = id => root.querySelector(`#${id}`);\n    const registry = {\n      root,\n      data: root.querySelector(`#${DATA_ID}`),\n      loading: get(\"luxV5Loading\"),\n      fatal: get(\"luxV5FatalError\"),\n      fatalMessage: get(\"luxV5FatalErrorMessage\"),\n      application: get(\"luxV5Application\"),\n      announcement: get(\"luxV5Announcement\"),\n      entry: get(\"luxV5Entry\"),\n      planner: get(\"luxV5Planner\"),\n      journeyHeader: get(\"luxV5JourneyHeader\"),\n      journeyLabel: get(\"luxV5JourneyLabel\"),\n      journeySummary: get(\"luxV5JourneySummary\"),\n      progress: get(\"luxV5Progress\"),\n      windowNavigator: get(\"luxV5WindowNavigator\"),\n      workspace: get(\"luxV5Workspace\"),\n      stages: {\n        fabric: get(\"luxV5FabricLookStage\"),\n        measurements: get(\"luxV5MeasurementStage\"),\n        configuration: get(\"luxV5ConfigurationStage\"),\n        windowReview: get(\"luxV5WindowReviewStage\"),\n        projectReview: get(\"luxV5ProjectReviewStage\")\n      },\n      presets: get(\"luxV5HousePresets\"),\n      roomSelector: get(\"luxV5RoomSelector\"),\n      plannedWindows: get(\"luxV5PlannedWindows\"),\n      beginWholeHome: get(\"luxV5BeginWholeHome\"),\n      collections: {\n        sheer: get(\"luxV5SheerCollections\"),\n        blackout: get(\"luxV5BlackoutCollections\")\n      },\n      products: {\n        sheer: get(\"luxV5SheerProduct\"),\n        blackout: get(\"luxV5BlackoutProduct\")\n      },\n      variants: {\n        sheer: get(\"luxV5SheerVariants\"),\n        blackout: get(\"luxV5BlackoutVariants\")\n      },\n      roomPills: get(\"luxV5RoomPills\"),\n      customRoomField: get(\"luxV5CustomRoomField\"),\n      customRoom: get(\"luxV5CustomRoom\"),\n      width: get(\"luxV5Width\"),\n      drop: get(\"luxV5Drop\"),\n      measurementValidation: get(\"luxV5MeasurementValidation\"),\n      activeWindowTitle: get(\"luxV5ActiveWindowTitle\"),\n      configSections: {\n        heading: get(\"luxV5HeadingSection\"),\n        supply: get(\"luxV5SupplySection\"),\n        opening: get(\"luxV5OpeningSection\"),\n        fixing: get(\"luxV5FixingSection\"),\n        finish: get(\"luxV5FinishSection\"),\n        pelmet: get(\"luxV5PelmetSection\"),\n        notes: get(\"luxV5NotesSection\")\n      },\n      configurationTitle: get(\"luxV5ConfigurationTitle\"),\n      windowReview: get(\"luxV5WindowReview\"),\n      projectReview: get(\"luxV5ProjectReview\"),\n      sidebar: get(\"luxV5Sidebar\"),\n      activePreview: get(\"luxV5ActiveWindowPreview\"),\n      sheerPreview: get(\"luxV5SheerPreview\"),\n      blackoutPreview: get(\"luxV5BlackoutPreview\"),\n      activeWindowPrice: get(\"luxV5ActiveWindowPrice\"),\n      currentSummary: get(\"luxV5CurrentSummary\"),\n      savedWindows: get(\"luxV5SavedWindows\"),\n      windowCount: get(\"luxV5ProjectWindowCount\"),\n      projectTotal: get(\"luxV5ProjectTotal\"),\n      projectTotals: get(\"luxV5ProjectTotals\"),\n      desktopSavings: get(\"luxV5DesktopSavings\"),\n      promotionProgress: get(\"luxV5PromotionProgress\"),\n      projectStatus: get(\"luxV5ProjectStatus\"),\n      addWindow: get(\"luxV5AddWindow\"),\n      checkoutConfirmation: get(\"luxV5CheckoutConfirmation\"),\n      checkoutButton: get(\"luxV5CheckoutButton\"),\n      clearProject: get(\"luxV5ClearProject\"),\n      saveStatus: get(\"luxV5SaveStatus\"),\n      mobileBar: get(\"luxV5MobileBar\"),\n      mobilePrimary: get(\"luxV5MobilePrimary\"),\n      mobileTotal: get(\"luxV5MobileTotal\"),\n      mobileProject: get(\"luxV5MobileProject\"),\n      drawer: get(\"luxV5ProjectDrawer\"),\n      drawerContent: get(\"luxV5DrawerContent\"),\n      modals: {\n        fabric: get(\"luxV5FabricModal\"),\n        confirm: get(\"luxV5ConfirmModal\")\n      },\n      modalContents: {\n        fabric: get(\"luxV5FabricModalContent\"),\n        confirm: get(\"luxV5ConfirmModalContent\")\n      }\n    };\n    const missing = REQUIRED_DOM.filter(id => !get(id));\n    if (missing.length) throw new Error(`Missing required Design Studio elements: ${missing.join(\", \")}`);\n    return registry;\n  };\n\n  /* =====================================================================\n     06. EVENT BUS\n     ===================================================================== */\n\n  const eventBus = (() => {\n    const listeners = new Map();\n    return Object.freeze({\n      on(name, listener) {\n        if (!listeners.has(name)) listeners.set(name, new Set());\n        listeners.get(name).add(listener);\n        return () => listeners.get(name)?.delete(listener);\n      },\n      emit(name, detail) {\n        listeners.get(name)?.forEach(listener => listener(detail));\n      }\n    });\n  })();\n\n  /* =====================================================================\n     07. STATE FACTORY\n     ===================================================================== */\n\n  const blankFabric = layer => ({\n    layer,\n    collectionId: \"\",\n    collectionHandle: \"\",\n    collectionTitle: \"\",\n    collectionImage: \"\",\n    collectionDiscountPercent: 0,\n    productId: \"\",\n    productHandle: \"\",\n    productTitle: \"\",\n    productImage: \"\",\n    variantId: \"\",\n    variantTitle: \"\",\n    variantSku: \"\",\n    variantImage: \"\",\n    pricingReference: null,\n    promotionPercent: 0,\n    maximumDropMm: 0,\n    fabricWidth: \"\",\n    fabricComposition: \"\",\n    description: \"\",\n    confirmed: false\n  });\n\n\nconst blankWindow = (overrides = {}) => ({\n    id: uid(\"window\"),\n    plannedWindowId: null,\n    roomPreset: \"\",\n    customRoomName: \"\",\n    displayName: \"\",\n    roomName: \"\",\n    windowName: \"\",\n    widthMm: 0,\n    dropMm: 0,\n    sheer: blankFabric(\"sheer\"),\n    blackout: blankFabric(\"blackout\"),\n    heading: \"s-wave\",\n    // Tracks are optional. Start every fresh window as curtains-only so a\n    // track charge is added only after the customer explicitly selects one.\n    supply: \"curtain-only\",\n    supplyChoice: null,\n    trackColour: \"white\",\n    opening: \"centre\",\n    fixing: \"ceiling\",\n    finish: \"off-floor\",\n    pelmet: false,\n    pelmetChoice: null,\n    remote: false,\n    notes: \"\",\n    confirmation: false,\n    status: STATUS.PLANNED,\n    quote: null,\n    updatedAt: new Date().toISOString(),\n    ...deepCopy(Object.fromEntries(Object.entries(overrides || {}).filter(([key]) => ![\"trackBending\", \"bendMeasurements\"].includes(key))))\n  });\n\n  const createState = () => ({\n    version: VERSION,\n    runtime: { initialised: false, loading: true, fatalError: null },\n    journey: { mode: null, stage: STAGES.ENTRY, history: [] },\n    catalog: {\n      sheerCollections: [],\n      blackoutCollections: [],\n      collectionsById: {},\n      collectionsByHandle: {},\n      productsById: {},\n      productsByHandle: {},\n      variantsById: {}\n    },\n    planner: { selectedPreset: \"\", plannedWindows: [], activePlannedWindowId: null },\n    project: {\n      id: uid(\"project\"),\n      windows: [],\n      activeWindowId: null,\n      editingWindowId: null,\n      baseDesign: null,\n      confirmed: false\n    },\n    draft: { window: blankWindow() },\n    pricing: { draftQuote: null, projectQuote: null },\n    ui: {\n      mobileDrawerOpen: false,\n      activeModal: null,\n      busy: false,\n      configuringBase: false,\n      fabricReturnStage: null,\n      windowFlowStep: \"measurements\",\n      optionalRoomsExpanded: false,\n      completedWindowSteps: []\n    },\n    timestamps: { createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }\n  });\n\n  /* =====================================================================\n     08. STATE MANAGER\n     ===================================================================== */\n\n  /** Records a mutation, invalidates project confirmation and persists safely. */\n  const touchState = (persist = true) => {\n    state.timestamps.updatedAt = new Date().toISOString();\n    state.project.confirmed = false;\n    if (dom?.checkoutConfirmation) dom.checkoutConfirmation.checked = false;\n    if (persist) storage.save();\n    eventBus.emit(\"state:changed\", state);\n    if (dom?.mobilePrimary) updatePrimaryAction();\n  };\n\n  const replaceDraft = draft => {\n    const next = blankWindow(draft);\n    ensureSyntheticSheer(next);\n    next.roomPreset = next.roomPreset || next.roomName;\n    next.displayName = next.displayName || next.windowName;\n    next.roomName = next.roomName || next.roomPreset;\n    next.windowName = next.windowName || next.displayName;\n    if (next.roomPreset === \"Custom Room\") {\n      next.customRoomName = next.customRoomName || next.windowName;\n    }\n    state.draft.window = next;\n    state.project.activeWindowId = state.draft.window.id;\n    state.ui.windowFlowStep = \"measurements\";\n    state.ui.completedWindowSteps = [];\n    syncInputs();\n    recalculate();\n  };\n\n  const invalidateDraftConfirmation = () => {\n    if (state?.draft?.window) state.draft.window.confirmation = false;\n  };\n\n  /* =====================================================================\n     09. SHOPIFY DATA ADAPTER\n     ===================================================================== */\n\n  const readShopifyData = () => {\n    const dataNode = document.getElementById(DATA_ID);\n    if (!dataNode) throw new Error(`Missing Shopify JSON block #${DATA_ID}.`);\n    let parsed;\n    try {\n      parsed = JSON.parse(dataNode.textContent);\n    } catch (error) {\n      throw new Error(`Invalid Shopify JSON configuration: ${error.message}`);\n    }\n    if (!parsed?.catalog || !parsed?.settings || !parsed?.routes) {\n      throw new Error(\"The Design Studio configuration is incomplete.\");\n    }\n    if (!parsed.currencyCode || !parsed.locale) {\n      throw new Error(\"Currency or locale is missing from the Design Studio configuration.\");\n    }\n    return parsed;\n  };\n\n  /* =====================================================================\n     10. CATALOG NORMALISER\n     ===================================================================== */\n\n  /**\n   * Filters and indexes the Shopify catalog without mutating the parsed\n   * Liquid payload.\n   */\n  const normaliseCatalog = data => {\n    const collectionsById = new Map();\n    const collectionsByHandle = new Map();\n    const productsById = new Map();\n    const productsByHandle = new Map();\n    const variantsById = new Map();\n\n    const normaliseLayer = (source, layer) =>\n      (Array.isArray(source) ? source : [])\n        .map(collection => {\n          const products = (Array.isArray(collection.products) ? collection.products : [])\n            .map(product => {\n              const variants = (Array.isArray(product.variants) ? product.variants : []).filter(\n                variant => variant.available && variant.id\n              );\n              if (!product.available || !variants.length) return null;\n              const canPrice = [\n                product.pricing?.baseSetPrice,\n                product.pricing?.shopifyPrice,\n                ...variants.map(variant => variant.price)\n              ].some(positive);\n              if (!canPrice) return null;\n              const copy = { ...product, variants, layer };\n              productsById.set(idString(copy.id), copy);\n              if (copy.handle) productsByHandle.set(String(copy.handle), copy);\n              variants.forEach(variant =>\n                variantsById.set(idString(variant.id), { ...variant, productId: copy.id, layer })\n              );\n              return copy;\n            })\n            .filter(Boolean);\n          if (!products.length) return null;\n          const copy = { ...collection, type: layer, products };\n          collectionsById.set(idString(copy.id), copy);\n          if (copy.handle) collectionsByHandle.set(String(copy.handle), copy);\n          return copy;\n        })\n        .filter(Boolean)\n        .sort(\n          (a, b) =>\n            toNumber(a.sortOrder, 999) - toNumber(b.sortOrder, 999) ||\n            String(a.title).localeCompare(String(b.title))\n        );\n\n    const sheer = normaliseLayer(data.catalog.sheerCollections, \"sheer\");\n    const blackout = normaliseLayer(data.catalog.blackoutCollections, \"blackout\");\n    if (!sheer.length) throw new Error(\"No available sheer collections were supplied by Shopify.\");\n    if (!blackout.length) throw new Error(\"No available sheer collections were supplied by Shopify.\");\n    return {\n      collections: { sheer, blackout },\n      collectionsById,\n      collectionsByHandle,\n      productsById,\n      productsByHandle,\n      variantsById\n    };\n  };\n\n  const attachCatalogState = target => {\n    target.catalog = {\n      sheerCollections: catalog.collections.sheer,\n      blackoutCollections: catalog.collections.blackout,\n      collectionsById: Object.fromEntries(catalog.collectionsById),\n      collectionsByHandle: Object.fromEntries(catalog.collectionsByHandle),\n      productsById: Object.fromEntries(catalog.productsById),\n      productsByHandle: Object.fromEntries(catalog.productsByHandle),\n      variantsById: Object.fromEntries(catalog.variantsById)\n    };\n  };\n\n  const collectionFor = (layer, id) =>\n    catalog.collections[layer].find(item => idString(item.id) === idString(id));\n\n  const productFor = id => catalog.productsById.get(idString(id));\n  const variantFor = id => catalog.variantsById.get(idString(id));\n\n  /* =====================================================================\n     11. STORAGE ADAPTER\n     ===================================================================== */\n\n  const storage = Object.freeze({\n    /**\n     * The current project intentionally remains page-session only. A browser\n     * refresh must always reopen a clean builder.\n     */\n    save() {\n      if (dom?.saveStatus) dom.saveStatus.textContent = \"In progress\";\n    },\n    /**\n     * Removes records created by earlier versions and starts clean.\n     */\n    load() {\n      try {\n        localStorage.removeItem(STORAGE_KEY);\n      } catch (_) {\n        /* Storage can be unavailable in private browsing. */\n      }\n      return null;\n    },\n    clear() {\n      try {\n        localStorage.removeItem(STORAGE_KEY);\n      } catch (_) {\n        /* Storage can be unavailable in private browsing. */\n      }\n    }\n  });\n\n  /* =====================================================================\n     12. JOURNEY ROUTER\n     ===================================================================== */\n\n  const stagesForMode = mode =>\n    mode === MODES.WHOLE_HOME\n      ? [\n          STAGES.WHOLE_HOME_PLANNER,\n          STAGES.FABRIC_SELECTION,\n          STAGES.MEASUREMENTS,\n          STAGES.WINDOW_CONFIGURATION,\n          STAGES.WINDOW_REVIEW,\n          STAGES.PROJECT_REVIEW\n        ]\n      : [\n          STAGES.FABRIC_SELECTION,\n          STAGES.MEASUREMENTS,\n          STAGES.WINDOW_CONFIGURATION,\n          STAGES.WINDOW_REVIEW,\n          STAGES.PROJECT_REVIEW\n        ];\n\n  /**\n   * Routes the single Liquid-owned application shell to one named V5 stage.\n   * @param {string} stage\n   * @param {{scroll?: boolean}} options\n   */\n  const routeTo = (stage, options = {}) => {\n    if (!Object.values(STAGES).includes(stage)) return;\n    if (state.journey.stage !== stage) state.journey.history.push(state.journey.stage);\n    state.journey.stage = stage;\n\n    setHidden(dom.entry, stage !== STAGES.ENTRY);\n    setHidden(dom.planner, stage !== STAGES.WHOLE_HOME_PLANNER);\n    const workspaceVisible = ![STAGES.ENTRY, STAGES.WHOLE_HOME_PLANNER].includes(stage);\n    setHidden(dom.workspace, !workspaceVisible);\n    setHidden(dom.journeyHeader, !workspaceVisible);\n    setHidden(dom.mobileBar, !workspaceVisible);\n    setHidden(dom.stages.fabric, stage !== STAGES.FABRIC_SELECTION);\n    setHidden(dom.stages.measurements, stage !== STAGES.MEASUREMENTS);\n    setHidden(dom.stages.configuration, stage !== STAGES.WINDOW_CONFIGURATION);\n    setHidden(dom.stages.windowReview, stage !== STAGES.WINDOW_REVIEW);\n    setHidden(dom.stages.projectReview, stage !== STAGES.PROJECT_REVIEW);\n\n    renderProgress();\n    renderStage();\n    updatePrimaryAction();\n    touchState();\n    if (options.scroll !== false) scrollStageIntoView();\n  };\n\n  const renderProgress = () => {\n    clear(dom.progress);\n    const stages =\n      state.journey.mode === MODES.WHOLE_HOME && state.ui.configuringBase\n        ? [\n            STAGES.WHOLE_HOME_PLANNER,\n            STAGES.FABRIC_SELECTION,\n            STAGES.WINDOW_CONFIGURATION,\n            STAGES.MEASUREMENTS,\n            STAGES.WINDOW_REVIEW,\n            STAGES.PROJECT_REVIEW\n          ]\n        : stagesForMode(state.journey.mode);\n    const currentIndex = stages.indexOf(state.journey.stage);\n    stages.forEach((stage, index) => {\n      const item = element(\"span\", \"lux-v5-progress__item\");\n      item.textContent = {\n        [STAGES.WHOLE_HOME_PLANNER]: \"Plan\",\n        [STAGES.FABRIC_SELECTION]: \"Fabrics\",\n        [STAGES.MEASUREMENTS]: \"Measure\",\n        [STAGES.WINDOW_CONFIGURATION]: state.ui.configuringBase ? \"Create Base Look\" : \"Configure\",\n        [STAGES.WINDOW_REVIEW]: \"Window Review\",\n        [STAGES.PROJECT_REVIEW]: \"Project Review\"\n      }[stage];\n      item.classList.toggle(\"is-active\", index === currentIndex);\n      item.classList.toggle(\"is-complete\", index < currentIndex);\n      if (index === currentIndex) item.setAttribute(\"aria-current\", \"step\");\n      dom.progress.append(item);\n    });\n  };\n\n  /* =====================================================================\n     13. ENTRY JOURNEY\n     ===================================================================== */\n\n  const selectJourney = mode => {\n    state = createState();\n    attachCatalogState(state);\n    state.runtime.initialised = true;\n    state.runtime.loading = false;\n    state.journey.mode = mode;\n    if (mode === MODES.SINGLE) {\n      const draft = blankWindow({ roomName: \"Living Room\", windowName: \"Living Room Window 1\" });\n      replaceDraft(draft);\n      routeTo(STAGES.FABRIC_SELECTION);\n    } else {\n      state.planner.plannedWindows = [];\n      routeTo(STAGES.WHOLE_HOME_PLANNER);\n      renderPlanner();\n    }\n    renderJourneyHeader();\n  };\n\n  const renderJourneyHeader = () => {\n    const whole = state.journey.mode === MODES.WHOLE_HOME;\n    if (dom.journeyLabel) dom.journeyLabel.textContent = whole ? \"WHOLE-HOME PROJECT\" : \"ONE WINDOW PROJECT\";\n    if (dom.journeySummary) {\n      const completed = state.planner.plannedWindows.filter(\n        item => item.status === STATUS.COMPLETE\n      ).length;\n      dom.journeySummary.textContent = whole\n        ? `${completed} of ${state.planner.plannedWindows.length} windows completed`\n        : \"Design your custom sheer curtains\";\n    }\n    renderWindowNavigator();\n  };\n\n  const renderWindowNavigator = () => {\n    if (!dom?.windowNavigator) return;\n    clear(dom.windowNavigator);\n    setHidden(dom.windowNavigator, true);\n    return;\n    const plans = state.planner.plannedWindows || [];\n    const visible =\n      state.journey.mode === MODES.WHOLE_HOME &&\n      plans.length > 0 &&\n      !state.ui.configuringBase &&\n      ![STAGES.ENTRY, STAGES.WHOLE_HOME_PLANNER, STAGES.FABRIC_SELECTION].includes(\n        state.journey.stage\n      );\n    setHidden(dom.windowNavigator, !visible);\n    if (!visible) return;\n    plans.forEach((plan, index) => {\n      const button = setAction(\n        element(\"button\", `lux-v5-window-nav__item is-${plan.status}`),\n        \"jump-window\",\n        plan.id\n      );\n      button.type = \"button\";\n      button.classList.toggle(\"is-current\", plan.id === state.draft.window.plannedWindowId);\n      button.setAttribute(\n        \"aria-current\",\n        plan.id === state.draft.window.plannedWindowId ? \"step\" : \"false\"\n      );\n      const status =\n        plan.status === STATUS.COMPLETE\n          ? \"Complete\"\n          : plan.id === state.draft.window.plannedWindowId\n            ? \"In progress\"\n            : \"Not started\";\n      button.append(\n        element(\"span\", \"\", String(index + 1).padStart(2, \"0\")),\n        element(\"strong\", \"\", plan.windowName),\n        element(\"small\", \"\", status)\n      );\n      dom.windowNavigator.append(button);\n    });\n  };\n\n  /* =====================================================================\n     14. WHOLE-HOME PLANNER\n     ===================================================================== */\n\n  const roomNames = () =>\n    Array.isArray(config?.labels?.rooms) && config.labels.rooms.length\n      ? config.labels.rooms\n      : [\"Living Room\", \"Dining Room\", \"Kitchen\", \"Master Bedroom\", \"Custom Room\"];\n\n  const roomWindows = room => state.planner.plannedWindows.filter(item => item.roomName === room);\n\n  const addPlannedWindow = (room, count = 1) => {\n    for (let index = 0; index < count; index += 1) {\n      const sequence = roomWindows(room).length + 1;\n      state.planner.plannedWindows.push({\n        id: uid(\"planned\"),\n        roomName: room,\n        customRoomName: room === \"Custom Room\" ? \"\" : null,\n        windowName: `${room} Window ${sequence}`,\n        sequence,\n        status: STATUS.PLANNED,\n        savedWindowId: null,\n        widthMm: 0,\n        dropMm: 0\n      });\n    }\n    normalisePlan();\n  };\n\n  const normalisePlan = () => {\n    const counts = new Map();\n    state.planner.plannedWindows.forEach(item => {\n      const next = (counts.get(item.roomName) || 0) + 1;\n      counts.set(item.roomName, next);\n      item.sequence = next;\n      if (!cleanText(item.windowName)) item.windowName = `${item.roomName} Window ${next}`;\n    });\n  };\n\n  const applyPreset = presetName => {\n    const preset = HOUSE_PRESETS.find(item => item.name === presetName);\n    if (!preset) return;\n    state.planner.selectedPreset = presetName;\n    state.ui.optionalRoomsExpanded = false;\n    state.planner.plannedWindows = [];\n    Object.entries(preset.rooms).forEach(([room, count]) => addPlannedWindow(room, count));\n    renderPlanner();\n    touchState();\n  };\n\n  const renderPlanner = () => {\n    clear(dom.presets);\n    HOUSE_PRESETS.forEach(preset => {\n      const button = setAction(element(\"button\", \"lux-v5-preset-card\"), \"preset\", preset.name);\n      button.type = \"button\";\n      button.textContent = preset.name;\n      button.classList.toggle(\"is-selected\", state.planner.selectedPreset === preset.name);\n      button.setAttribute(\"aria-pressed\", String(state.planner.selectedPreset === preset.name));\n      dom.presets.append(button);\n    });\n\n    const createRoomCard = room => {\n      const card = element(\"div\", \"lux-v5-room-card\");\n      const windowCount = roomWindows(room).length;\n      card.classList.toggle(\"is-active\", windowCount > 0);\n      const title = element(\"strong\", \"\", room);\n      const controls = element(\"div\", \"lux-v5-room-card__controls\");\n      const minus = setAction(element(\"button\", \"\", \"\u2212\"), \"room-minus\", room);\n      minus.type = \"button\";\n      minus.disabled = windowCount === 0;\n      minus.setAttribute(\"aria-label\", `Remove one ${room} window`);\n      const count = element(\"span\", \"\", String(windowCount));\n      count.setAttribute(\"aria-live\", \"polite\");\n      const plus = setAction(element(\"button\", \"\", \"+\"), \"room-plus\", room);\n      plus.type = \"button\";\n      plus.setAttribute(\"aria-label\", `Add one ${room} window`);\n      controls.append(minus, count, plus);\n      card.append(title, controls);\n      return card;\n    };\n\n    clear(dom.roomSelector);\n    const selectedPreset = HOUSE_PRESETS.find(item => item.name === state.planner.selectedPreset);\n    const presetRooms = selectedPreset ? Object.keys(selectedPreset.rooms) : roomNames();\n    const primaryRooms = roomNames().filter(room => presetRooms.includes(room));\n    const optionalRooms = roomNames().filter(room => !presetRooms.includes(room));\n    const primaryGroup = element(\"div\", \"lux-v5-room-grid__group\");\n    primaryRooms.forEach(room => primaryGroup.append(createRoomCard(room)));\n    dom.roomSelector.append(primaryGroup);\n\n    if (optionalRooms.length) {\n      const toggle = setAction(\n        element(\"button\", \"lux-v5-room-grid__toggle\"),\n        \"toggle-optional-rooms\"\n      );\n      toggle.type = \"button\";\n      toggle.classList.toggle(\"is-open\", state.ui.optionalRoomsExpanded);\n      toggle.setAttribute(\"aria-expanded\", String(state.ui.optionalRoomsExpanded));\n      toggle.setAttribute(\"aria-controls\", \"luxV5OptionalRooms\");\n      toggle.append(\n        element(\"span\", \"\", state.ui.optionalRoomsExpanded ? \"Hide additional rooms\" : \"Add more rooms\"),\n        element(\"span\", \"lux-v5-room-grid__toggle-icon\")\n      );\n      toggle.lastElementChild.setAttribute(\"aria-hidden\", \"true\");\n      dom.roomSelector.append(toggle);\n\n      const optionalGroup = element(\"div\", \"lux-v5-room-grid__group lux-v5-room-grid__group--optional\");\n      optionalGroup.id = \"luxV5OptionalRooms\";\n      optionalGroup.hidden = !state.ui.optionalRoomsExpanded;\n      optionalRooms.forEach(room => optionalGroup.append(createRoomCard(room)));\n      dom.roomSelector.append(optionalGroup);\n    }\n\n    clear(dom.plannedWindows);\n    if (!state.planner.plannedWindows.length) {\n      dom.plannedWindows.append(\n        element(\"p\", \"lux-v5-empty-state\", \"Add at least one room window to continue.\")\n      );\n    }\n    state.planner.plannedWindows.forEach(item => {\n      const row = element(\"div\", \"lux-v5-planned-window\");\n      row.dataset.plannedId = item.id;\n      if (item.roomName === \"Custom Room\") {\n        const roomLabel = element(\"label\", \"lux-v5-field\");\n        roomLabel.append(element(\"span\", \"\", \"Custom room name\"));\n        const roomInput = element(\"input\");\n        roomInput.type = \"text\";\n        roomInput.value = item.customRoomName || \"\";\n        roomInput.placeholder = \"Nursery, Alfresco, Guest Suite\u2026\";\n        roomInput.maxLength = 60;\n        roomInput.dataset.v5PlanRoom = item.id;\n        roomLabel.append(roomInput);\n        row.append(roomLabel);\n      }\n      const label = element(\"label\", \"lux-v5-field\");\n      label.append(element(\"span\", \"\", `${item.roomName} \u00B7 Window ${item.sequence}`));\n      const input = element(\"input\");\n      input.type = \"text\";\n      input.value = item.windowName;\n      input.dataset.v5PlanName = item.id;\n      input.maxLength = 80;\n      label.append(input);\n      const remove = setAction(element(\"button\", \"lux-v5-text-button\", \"Delete\"), \"plan-delete\", item.id);\n      remove.type = \"button\";\n      remove.setAttribute(\"aria-label\", `Delete ${item.windowName}`);\n      row.append(label, remove);\n      dom.plannedWindows.append(row);\n    });\n    dom.beginWholeHome.disabled = !state.planner.plannedWindows.length;\n    renderJourneyHeader();\n  };\n\n  const beginWholeHome = () => {\n    if (!state.planner.plannedWindows.length) return announce(\"Add at least one window.\", \"error\");\n    const unnamedCustom = state.planner.plannedWindows.find(\n      item => item.roomName === \"Custom Room\" && !cleanText(item.customRoomName)\n    );\n    if (unnamedCustom) {\n      dom.plannedWindows.querySelector(`[data-v5-plan-room=\"${unnamedCustom.id}\"]`)?.focus();\n      return announce(\"Enter a name for each custom room.\", \"error\");\n    }\n    state.planner.plannedWindows.forEach(item => {\n      if (item.roomName !== \"Custom Room\") return;\n      const originalName = item.windowName;\n      item.roomName = cleanText(item.customRoomName, 60);\n      if (originalName.startsWith(\"Custom Room Window\")) {\n        item.windowName = `${item.roomName} Window 1`;\n      }\n    });\n    state.planner.plannedWindows.forEach(item => {\n      item.status = STATUS.PLANNED;\n      item.savedWindowId = null;\n    });\n    state.planner.activePlannedWindowId = null;\n    state.project.baseDesign = null;\n    state.ui.configuringBase = false;\n    replaceDraft(blankWindow({ roomName: \"\", windowName: \"Whole-Home Base Look\" }));\n    routeTo(STAGES.FABRIC_SELECTION);\n  };\n\n  /* =====================================================================\n     15. ROOM ENGINE\n     ===================================================================== */\n\n  const renderRooms = () => {\n    clear(dom.roomPills);\n    const names =\n      state.journey.mode === MODES.WHOLE_HOME\n        ? [...new Set(state.planner.plannedWindows.map(item => item.roomName))]\n        : roomNames();\n    const roomField = element(\"label\", \"lux-v5-field lux-v5-room-select-field\");\n    const roomLabel = element(\"span\", \"\", \"Room name\");\n    roomField.append(roomLabel);\n    const roomIsLocked =\n      Boolean(cleanText(state.draft.window.roomName)) && state.planner.plannedWindows.length > 0; // Whole-home rooms are inherited from plan.\n    if (roomIsLocked) {\n      const lockedRoom = element(\"input\", \"lux-v5-room-locked\");\n      lockedRoom.type = \"text\";\n      lockedRoom.value = state.draft.window.roomName;\n      lockedRoom.readOnly = true;\n      lockedRoom.setAttribute(\"aria-readonly\", \"true\");\n      roomField.classList.add(\"is-locked\");\n      roomLabel.textContent = \"Room name \u00B7 Locked from plan\";\n      roomField.append(lockedRoom);\n    } else {\n      const select = element(\"select\");\n      select.dataset.v5RoomSelect = \"\";\n      names.forEach(room => {\n        const option = element(\"option\", \"\", room);\n        option.value = room;\n        option.selected = state.draft.window.roomName === room;\n        select.append(option);\n      });\n      roomField.append(select);\n    }\n    dom.roomPills.append(roomField);\n\n    setHidden(dom.customRoomField, false);\n    const windowNameLabel = dom.customRoomField.querySelector(\":scope > span\");\n    if (windowNameLabel) windowNameLabel.textContent = \"Window name\";\n    dom.customRoom.placeholder = \"Example: Living Room Window 1\";\n    dom.customRoom.value = state.draft.window.windowName;\n  };\n\n  /* =====================================================================\n     16. WINDOW ENGINE\n     ===================================================================== */\n\n  const plannedForDraft = () =>\n    state.planner.plannedWindows.find(item => item.id === state.draft.window.plannedWindowId);\n\n  const persistActiveDraft = () => {\n    const planned = plannedForDraft();\n    if (!planned || planned.savedWindowId) return;\n    planned.draftWindow = deepCopy(state.draft.window);\n    planned.widthMm = state.draft.window.widthMm;\n    planned.dropMm = state.draft.window.dropMm;\n  };\n\n  const adjacentPlannedWindow = direction => {\n    const currentId = state.draft.window.plannedWindowId;\n    const currentIndex = state.planner.plannedWindows.findIndex(item => item.id === currentId);\n    if (currentIndex < 0) return null;\n    return state.planner.plannedWindows[currentIndex + direction] || null;\n  };\n\n  const openPlannedWindow = (item, { startFresh = false } = {}) => {\n    persistActiveDraft();\n    const saved = state.project.windows.find(windowData => windowData.id === item.savedWindowId);\n    state.planner.plannedWindows.forEach(plan => {\n      if (plan.status === STATUS.ACTIVE) plan.status = plan.savedWindowId ? STATUS.COMPLETE : STATUS.PLANNED;\n    });\n    item.status = STATUS.ACTIVE;\n    state.planner.activePlannedWindowId = item.id;\n    state.project.editingWindowId = saved?.id || null;\n    if (startFresh) {\n      item.draftWindow = null;\n      item.widthMm = 0;\n      item.dropMm = 0;\n    }\n    const baseFabrics = state.project.baseDesign\n      ? {\n          sheer: deepCopy(state.project.baseDesign.sheer),\n          blackout: deepCopy(state.project.baseDesign.blackout)\n        }\n      : {};\n    const seed =\n      saved ||\n      (!startFresh && item.draftWindow) ||\n      blankWindow({\n        plannedWindowId: item.id,\n        roomName: item.roomName,\n        windowName: item.windowName,\n        ...baseFabrics\n      });\n    replaceDraft(seed);\n    state.draft.window.plannedWindowId = item.id;\n    if (saved) state.draft.window.confirmation = false;\n    if (saved) {\n      state.ui.completedWindowSteps = [\n        \"measurements\",\n        \"heading\",\n        \"supply\",\n        \"opening\",\n        \"fixing\",\n        \"finish\",\n\n        \"pelmet\",\n        \"notes\"\n      ];\n    }\n    routeTo(STAGES.MEASUREMENTS);\n  };\n\n  const startAdditionalWindow = () => {\n    if (state.journey.mode === MODES.WHOLE_HOME) {\n      addPlannedWindow(\"Custom Room\");\n      const item = state.planner.plannedWindows[state.planner.plannedWindows.length - 1];\n      openPlannedWindow(item);\n      return;\n    }\n    replaceDraft(\n      blankWindow({\n        roomName: \"Living Room\",\n        windowName: `Window ${state.project.windows.length + 1}`,\n        sheer: deepCopy(state.draft.window.sheer),\n        blackout: deepCopy(state.draft.window.blackout)\n      })\n    );\n    state.project.editingWindowId = null;\n    routeTo(STAGES.MEASUREMENTS);\n  };\n\n  /* =====================================================================\n     17. FABRIC ENGINE\n     ===================================================================== */\n\n  const fabricSelection = (layer, collection, product, variant) => ({\n    layer,\n    collectionId: idString(collection.id),\n    collectionHandle: collection.handle || \"\",\n    collectionTitle: collection.title || \"\",\n    collectionImage: collection.icon || collection.featuredImage || \"\",\n    collectionDiscountPercent: clamp(collection.discountPercent, 0, 95),\n    productId: idString(product.id),\n    productHandle: product.handle || \"\",\n    productTitle: product.title || \"\",\n    productImage: product.featuredImage || \"\",\n    variantId: idString(variant.id),\n    variantTitle: variant.title || \"Default\",\n    variantSku: variant.sku || \"\",\n    variantImage: variant.image || product.featuredImage || collection.featuredImage || \"\",\n    pricingReference: {\n      baseSetPrice: toNumber(product.pricing?.baseSetPrice),\n      shopifyPrice: toNumber(product.pricing?.shopifyPrice || variant.price),\n      variantPrice: toNumber(variant.price)\n    },\n    promotionPercent: clamp(product.pricing?.promotionPercent, 0, 95),\n    maximumDropMm: toNumber(\n      product.specifications?.maximumDropMm,\n      config.settings.defaultMaximumDropMm\n    ),\n    fabricWidth: product.specifications?.fabricWidth || \"\",\n    fabricComposition: product.specifications?.fabricComposition || \"\",\n    description: product.specifications?.description || \"\",\n    confirmed: false\n  });\n\n  const ensureSyntheticSheer = windowData => {\n    if (!windowData || windowData.sheer?.confirmed) return;\n    const collection = catalog?.collections?.sheer?.[0];\n    const product = collection?.products?.[0];\n    const variant = product?.variants?.[0];\n    if (!collection || !product || !variant) return;\n    windowData.sheer = fabricSelection(\"sheer\", collection, product, variant);\n    windowData.sheer.confirmed = true;\n  };\n\n  const selectedCollection = layer =>\n    collectionFor(layer, state.draft.window[layer].collectionId);\n\n  const renderFabrics = () => {\n    [\"blackout\"].forEach(layer => {\n      const selection = state.draft.window[layer];\n      clear(dom.collections[layer]);\n      catalog.collections[layer].forEach(collection => {\n        const button = setAction(\n          element(\"button\", \"lux-v5-collection-card\"),\n          \"fabric-collection\",\n          `${layer}:${collection.id}`\n        );\n        button.type = \"button\";\n        button.classList.toggle(\"is-selected\", idString(collection.id) === selection.collectionId);\n        button.setAttribute(\n          \"aria-pressed\",\n          String(idString(collection.id) === selection.collectionId)\n        );\n        const imageUrl = collection.icon || collection.featuredImage;\n        if (imageUrl) {\n          const image = element(\"img\");\n          image.src = imageUrl;\n          image.alt = \"\";\n          image.loading = \"lazy\";\n          button.append(image);\n        }\n        button.append(element(\"strong\", \"\", collection.title));\n        if (collection.badge) button.append(element(\"small\", \"lux-v5-badge\", collection.badge));\n        dom.collections[layer].append(button);\n      });\n      renderFabricProducts(layer);\n    });\n  };\n\n  const renderConfirmedFabricSummary = layer => {\n    const selection = state.draft.window[layer];\n    const summary = element(\"article\", \"lux-v5-confirmed-fabric\");\n    if (selection.variantImage) {\n      const image = element(\"img\");\n      image.src = selection.variantImage;\n      image.alt = `${selection.variantTitle} from ${selection.collectionTitle}`;\n      image.loading = \"lazy\";\n      summary.append(image);\n    }\n    const details = element(\"div\", \"lux-v5-confirmed-fabric__details\");\n    details.append(\n      element(\"small\", \"\", `${layer === \"sheer\" ? \"Sheer\" : \"Sheer\"} confirmed`),\n      element(\"strong\", \"\", selection.variantTitle),\n      element(\"span\", \"\", `${selection.collectionTitle} \u00B7 ${selection.productTitle}`)\n    );\n    if (selection.promotionPercent) {\n      details.append(\n        element(\"em\", \"lux-v5-badge\", `${selection.promotionPercent}% promotion`)\n      );\n    }\n    const change = setAction(\n      element(\n        \"button\",\n        \"lux-v5-button lux-v5-button--secondary\",\n        `Change ${layer === \"sheer\" ? \"Sheer\" : \"Sheer\"} Fabric`\n      ),\n      \"change-fabric\",\n      layer\n    );\n    change.type = \"button\";\n    summary.append(details, change);\n    return summary;\n  };\n\n  const renderFabricProducts = layer => {\n    clear(dom.products[layer]);\n    clear(dom.variants[layer]);\n    const selection = state.draft.window[layer];\n    const section = dom.collections[layer].closest(\".lux-v5-config-card\");\n    section?.classList.toggle(\"is-fabric-confirmed\", selection.confirmed);\n    setHidden(dom.collections[layer], selection.confirmed);\n    setHidden(dom.variants[layer], selection.confirmed);\n    if (selection.confirmed) {\n      dom.products[layer].append(renderConfirmedFabricSummary(layer));\n      return;\n    }\n    const collection = selectedCollection(layer);\n    if (!collection) return;\n\n    if (collection.description) {\n      const details = setAction(\n        element(\"button\", \"lux-v5-text-button\", \"View collection details\"),\n        \"fabric-details\",\n        `${layer}:collection`\n      );\n      details.type = \"button\";\n      dom.products[layer].append(details);\n    }\n\n    const productWrap = element(\"div\", \"lux-v5-product-grid\");\n    collection.products.forEach(product => {\n      const button = setAction(\n        element(\"button\", \"lux-v5-product-card\"),\n        \"fabric-product\",\n        `${layer}:${product.id}`\n      );\n      button.type = \"button\";\n      button.classList.toggle(\"is-selected\", idString(product.id) === selection.productId);\n      button.setAttribute(\"aria-pressed\", String(idString(product.id) === selection.productId));\n      button.append(element(\"strong\", \"\", product.title));\n      const discount = clamp(product.pricing?.promotionPercent, 0, 95);\n      if (discount) button.append(element(\"small\", \"lux-v5-badge\", `${discount}% promotion`));\n      productWrap.append(button);\n    });\n    dom.products[layer].append(productWrap);\n\n    const product = productFor(selection.productId);\n    if (!product || idString(product.collectionId) !== idString(collection.id)) return;\n    if (product.specifications?.description) {\n      const details = setAction(\n        element(\"button\", \"lux-v5-text-button\", \"View fabric details\"),\n        \"fabric-details\",\n        `${layer}:product`\n      );\n      details.type = \"button\";\n      dom.products[layer].append(details);\n    }\n    product.variants.forEach(variant => {\n      const button = setAction(\n        element(\"button\", \"lux-v5-swatch\"),\n        \"fabric-variant\",\n        `${layer}:${variant.id}`\n      );\n      button.type = \"button\";\n      button.classList.toggle(\"is-selected\", idString(variant.id) === selection.variantId);\n      button.setAttribute(\"aria-pressed\", String(idString(variant.id) === selection.variantId));\n      if (variant.image) {\n        const image = element(\"img\");\n        image.src = variant.image;\n        image.alt = \"\";\n        image.loading = \"lazy\";\n        button.append(image);\n      }\n      button.append(element(\"span\", \"\", variant.title || \"Default\"));\n      dom.variants[layer].append(button);\n    });\n\n    if (selection.variantId) {\n      const confirm = setAction(\n        element(\n          \"button\",\n          `lux-v5-button lux-v5-fabric-review-button ${selection.confirmed ? \"lux-v5-button--secondary\" : \"lux-v5-button--primary\"}`,\n          selection.confirmed\n            ? `Change ${layer === \"blackout\" ? \"sheer\" : layer} fabric`\n            : \"Confirm Fabric Selection\"\n        ),\n        selection.confirmed ? \"change-fabric\" : \"review-fabric\",\n        layer\n      );\n      confirm.type = \"button\";\n      dom.variants[layer].append(confirm);\n    }\n  };\n\n  const chooseCollection = (layer, collectionId) => {\n    const collection = collectionFor(layer, collectionId);\n    if (!collection) return;\n    invalidateDraftConfirmation();\n    state.draft.window[layer] = blankFabric(layer);\n    state.draft.window[layer].collectionId = idString(collection.id);\n    state.draft.window[layer].collectionHandle = collection.handle || \"\";\n    state.draft.window[layer].collectionTitle = collection.title || \"\";\n    state.draft.window[layer].collectionImage =\n      collection.icon || collection.featuredImage || \"\";\n    state.draft.window[layer].collectionDiscountPercent = clamp(\n      collection.discountPercent,\n      0,\n      95\n    );\n    const product = collection.products[0];\n    if (product) chooseProduct(layer, product.id, false);\n    renderFabricProducts(layer);\n    touchState();\n  };\n\n  const chooseProduct = (layer, productId, shouldRender = true) => {\n    const collection = selectedCollection(layer);\n    const product = collection?.products.find(item => idString(item.id) === idString(productId));\n    if (!product) return;\n    invalidateDraftConfirmation();\n    const previous = state.draft.window[layer];\n    state.draft.window[layer] = {\n      ...blankFabric(layer),\n      collectionId: previous.collectionId,\n      collectionHandle: previous.collectionHandle,\n      collectionTitle: previous.collectionTitle,\n      collectionImage: previous.collectionImage,\n      collectionDiscountPercent: previous.collectionDiscountPercent,\n      productId: idString(product.id),\n      productHandle: product.handle || \"\",\n      productTitle: product.title || \"\",\n      productImage: product.featuredImage || \"\"\n    };\n    if (product.variants.length) chooseVariant(layer, product.variants[0].id, false);\n    if (shouldRender) renderFabricProducts(layer);\n    touchState();\n  };\n\n  const chooseVariant = (layer, variantId, shouldRender = true) => {\n    const collection = selectedCollection(layer);\n    const product = productFor(state.draft.window[layer].productId);\n    const variant = product?.variants.find(item => idString(item.id) === idString(variantId));\n    if (!collection || !product || !variant) return;\n    invalidateDraftConfirmation();\n    state.draft.window[layer] = fabricSelection(layer, collection, product, variant);\n    if (shouldRender) renderFabricProducts(layer);\n    recalculate();\n    renderSidebar();\n    touchState();\n    if (shouldRender) openFabricDetails(layer, \"product\", true);\n  };\n\n  /* =====================================================================\n     18. MEASUREMENT ENGINE\n     ===================================================================== */\n\n  const combinedMaximumDrop = windowData => {\n    const configured = toNumber(config.settings.defaultMaximumDropMm);\n    const values = [windowData.sheer.maximumDropMm, windowData.blackout.maximumDropMm]\n      .map(value => toNumber(value))\n      .filter(positive);\n    return values.length ? Math.min(...values) : configured;\n  };\n\n  const validateMeasurements = windowData => {\n    const errors = [];\n    const minimumWidth = toNumber(config.settings.minimumWidthMm);\n    const minimumDrop = toNumber(config.settings.minimumDropMm);\n    const maximumDrop = combinedMaximumDrop(windowData);\n    if (!positive(windowData.widthMm) || windowData.widthMm < minimumWidth) {\n      errors.push(`Track width must be at least ${minimumWidth} mm.`);\n    }\n    if (!positive(windowData.dropMm) || windowData.dropMm < minimumDrop) {\n      errors.push(`Finished drop must be at least ${minimumDrop} mm.`);\n    } else if (positive(maximumDrop) && windowData.dropMm > maximumDrop) {\n      errors.push(\n        `Drops above ${maximumDrop} mm require a custom quotation and cannot use standard checkout.`\n      );\n    }\n    return errors;\n  };\n\n  const syncInputs = () => {\n    if (!dom) return;\n    dom.width.value = state.draft.window.widthMm || \"\";\n    dom.drop.value = state.draft.window.dropMm || \"\";\n    renderRooms();\n  };\n\n  const updateMeasurementValidation = () => {\n    const errors = validateMeasurements(state.draft.window);\n    const untouched = !positive(state.draft.window.widthMm) && !positive(state.draft.window.dropMm);\n    if (untouched) {\n      dom.measurementValidation.textContent = \"\";\n      dom.measurementValidation.classList.remove(\"has-error\");\n      setHidden(dom.measurementValidation, true);\n      return errors;\n    }\n    setHidden(dom.measurementValidation, !errors.length);\n    dom.measurementValidation.textContent = errors.length ? errors[0] : \"\";\n    dom.measurementValidation.classList.toggle(\"has-error\", Boolean(errors.length));\n    return errors;\n  };\n\n  const renderMeasurementPricePanel = () => {\n    if (!dom?.measurementValidation || !state) return;\n    let panel = dom.root.querySelector(\"#luxV5MeasurementPricePanel\");\n    if (!panel) {\n      panel = element(\"div\", \"lux-v5-measurement-price\");\n      panel.id = \"luxV5MeasurementPricePanel\";\n      dom.measurementValidation.insertAdjacentElement(\"beforebegin\", panel);\n    }\n    clear(panel);\n    const draft = state.draft.window;\n    const quote = PricingProvider.quoteWindow(draft);\n    if (!positive(draft.widthMm) || !positive(draft.dropMm)) {\n      panel.append(\n        element(\"strong\", \"\", \"Live window estimate\"),\n        element(\"span\", \"\", \"Enter the finished width and drop to see pricing.\")\n      );\n      return;\n    }\n    const trackAmount = toNumber(quote.breakdown?.tracks?.base);\n    const trackDescription =\n      !draft.supplyChoice\n        ? \"No track option selected \u00B7 no track charge\"\n        : draft.supply === \"curtain-only\"\n        ? \"Curtains only \u00B7 no track charge\"\n        : trackAmount\n          ? `${OPTION_LABELS.supply[draft.supply]} \u00B7 ${money(trackAmount)} track component`\n          : OPTION_LABELS.supply[draft.supply];\n    panel.append(\n      (() => {\n        const copy = element(\"div\");\n        copy.append(\n          element(\"small\", \"\", \"Current configuration\"),\n          element(\"strong\", \"\", trackDescription)\n        );\n        return copy;\n      })(),\n      (() => {\n        const total = element(\"div\", \"lux-v5-measurement-price__total\");\n        total.append(\n          element(\"small\", \"\", \"Live window estimate\"),\n          element(\"strong\", \"\", quote.valid ? money(quote.finalTotal) : \"Complete selections\")\n        );\n        return total;\n      })()\n    );\n  };\n\n  const renderMeasurements = () => {\n    renderRooms();\n    syncInputs();\n    const planned = plannedForDraft();\n    if (dom.activeWindowTitle) {\n      dom.activeWindowTitle.textContent = `Measure ${planned?.windowName || state.draft.window.windowName || \"your window\"}`;\n    }\n    updateMeasurementValidation();\n    renderMeasurementPricePanel();\n  };\n\n  /* =====================================================================\n     19. CONFIGURATION ENGINE\n     ===================================================================== */\n\n  const CONFIG_SECTION_NUMBERS = {\n    supply: \"01\",\n    heading: \"02\",\n    opening: \"03\",\n    fixing: \"04\",\n    finish: \"05\",\n    pelmetChoice: \"06\"\n  };\n\n  const sectionHeading = (title, description, number = \"\") => {\n    const header = element(\"div\", \"lux-v5-section-heading\");\n    const text = element(\"div\");\n    text.append(element(\"h3\", \"\", title), element(\"p\", \"\", description));\n    if (number) header.append(element(\"span\", \"\", number));\n    header.append(text);\n    return header;\n  };\n\n  const optionPriceDelta = (group, value) => {\n    if (!PricingProvider || state.draft.window[group] === value) return \"\";\n    const current = PricingProvider.quoteWindow(state.draft.window);\n    const candidateWindow = deepCopy(state.draft.window);\n    candidateWindow[group] = value;\n    if (group === \"supply\" && value === \"curtain-only\") {\n      candidateWindow.remote = false;\n    }\n    const candidate = PricingProvider.quoteWindow(candidateWindow);\n    if (!current.valid || !candidate.valid) return \"\";\n    const difference = roundMoney(candidate.finalTotal - current.finalTotal);\n    if (!difference) return \"No price change\";\n    return `${difference > 0 ? \"+\" : \"\u2212\"}${money(Math.abs(difference))}`;\n  };\n\n  const optionCard = (group, value, label, selected, imageUrl, description) => {\n    const button = setAction(element(\"button\", \"lux-v5-option-card\"), \"option\", `${group}:${value}`);\n    button.type = \"button\";\n    button.classList.toggle(\"is-selected\", selected);\n    button.setAttribute(\"aria-pressed\", String(selected));\n    if (imageUrl) {\n      const image = element(\"img\");\n      image.src = imageUrl;\n      image.alt = \"\";\n      image.loading = \"lazy\";\n      button.append(image);\n    }\n    if (group === \"trackColour\") {\n      const swatch = element(\"span\", `lux-v5-track-swatch lux-v5-track-swatch--${value}`);\n      swatch.setAttribute(\"aria-hidden\", \"true\");\n      button.append(swatch);\n    }\n    button.append(element(\"strong\", \"\", label));\n    const supportingText =\n      group === \"pelmetChoice\" ? \"\" : description || optionPriceDelta(group, value);\n    if (supportingText) button.append(element(\"small\", \"\", supportingText));\n    return button;\n  };\n\nconst renderOptionSection = (node, title, description, group, options) => {\n\n    clear(node);\n    node.append(sectionHeading(title, description, CONFIG_SECTION_NUMBERS[group]));\n    const grid = element(\"div\", \"lux-v5-option-grid\");\n    options.forEach(option =>\n      grid.append(\n        optionCard(\n          group,\n          option.value,\n          option.label,\n          (group === \"supply\"\n            ? state.draft.window.supplyChoice\n            : state.draft.window[group]) === option.value,\n          option.image,\n          option.description\n        )\n      )\n    );\n    node.append(grid);\n  };\n\n  const renderCurrentWindowFabrics = () => {\n    dom.root.querySelector(\"#luxV5CurrentWindowFabrics\")?.remove();\n    if (state.ui.configuringBase) return;\n    const section = element(\"section\", \"lux-v5-current-fabrics\");\n    section.id = \"luxV5CurrentWindowFabrics\";\n    section.append(\n      sectionHeading(\n        \"Current Sheer Fabric\",\n        \"This sheer fabric applies only to this window. Change it without affecting saved windows.\"\n      )\n    );\n    const grid = element(\"div\", \"lux-v5-current-fabrics__grid\");\n    [\"blackout\"].forEach(layer => {\n      const selection = state.draft.window[layer];\n      const card = element(\"article\", \"lux-v5-current-fabric\");\n      if (selection.variantImage) {\n        const image = element(\"img\");\n        image.src = selection.variantImage;\n        image.alt = `${selection.productTitle} ${selection.variantTitle}`;\n        image.loading = \"lazy\";\n        card.append(image);\n      }\n      const details = element(\"div\", \"lux-v5-current-fabric__details\");\n      details.append(\n        element(\"small\", \"\", layer === \"sheer\" ? \"Sheer\" : \"Sheer\"),\n        element(\"strong\", \"\", selection.productTitle || \"Not selected\"),\n        element(\"span\", \"\", selection.variantTitle || \"Choose a colour\")\n      );\n      const change = setAction(\n        element(\"button\", \"lux-v5-button lux-v5-button--secondary\", \"Change\"),\n        \"change-window-fabric\",\n        layer\n      );\n      change.type = \"button\";\n      card.append(details, change);\n      grid.append(card);\n    });\n    section.append(grid);\n    const targetStage = dom.windowAccordion ? dom.stages.measurements : dom.stages.configuration;\n    const header = targetStage.querySelector(\".lux-v5-stage-header\");\n    if (header) header.insertAdjacentElement(\"afterend\", section);\n    else targetStage.prepend(section);\n  };\n\n  const renderConfiguration = () => {\n    const visuals = config.visuals || {};\n    if (dom.configurationTitle) {\n      dom.configurationTitle.textContent = \"Design your sheer curtains\";\n    }\n    renderCurrentWindowFabrics();\n    renderOptionSection(\n      dom.configSections.heading,\n      \"Heading Style\",\n      \"Choose the fullness and finished appearance.\",\n      \"heading\",\n      [\n        { value: \"s-wave\", label: OPTION_LABELS.heading[\"s-wave\"], image: visuals.headingSWave },\n        {\n          value: \"double-pinch\",\n          label: OPTION_LABELS.heading[\"double-pinch\"],\n          image: visuals.headingDoublePinch\n        },\n        {\n          value: \"triple-pinch\",\n          label: OPTION_LABELS.heading[\"triple-pinch\"],\n          image: visuals.headingTriplePinch\n        }\n      ]\n    );\n    renderOptionSection(\n      dom.configSections.supply,\n      \"Curtain & Track Option\",\n      \"Choose your Luxworld curtain track.\",\n      \"supply\",\n      [\n        {\n          value: \"curtain-only\",\n          label: OPTION_LABELS.supply[\"curtain-only\"],\n          image:\n            state.draft.window.sheer.variantImage ||\n            state.draft.window.blackout.variantImage ||\n            visuals.fabricEffectsImage\n        },\n        {\n          value: \"manual-double-track\",\n          label: OPTION_LABELS.supply[\"manual-double-track\"],\n          image: visuals.manualTracks\n        },\n        {\n          value: \"motorised-double-track\",\n          label: OPTION_LABELS.supply[\"motorised-double-track\"],\n          image: visuals.motorisedTracks\n        },\n        {\n          value: \"led-motorised-double-track\",\n          label: OPTION_LABELS.supply[\"led-motorised-double-track\"],\n          image: visuals.ledMotorisedTracks\n        }\n      ]\n    );\n\n    const trackSupplied = state.draft.window.supply !== \"curtain-only\";\n    const motorised = [\"motorised-double-track\", \"led-motorised-double-track\"].includes(\n      state.draft.window.supply\n    );\n    let trackOptions = null;\n    if (trackSupplied) {\n      trackOptions = element(\"div\", \"lux-v5-suboptions\");\n      trackOptions.append(element(\"strong\", \"\", \"Track Colour\"));\n      const colourGrid = element(\"div\", \"lux-v5-option-grid\");\n      Object.entries(OPTION_LABELS.trackColour).forEach(([value, label]) => {\n        const button = optionCard(\n          \"trackColour\",\n          value,\n          label,\n          state.draft.window.trackColour === value,\n          \"\",\n          motorised && value !== \"white\" ? \"Unavailable for motorised tracks\" : \"\"\n        );\n        if (motorised && value !== \"white\") button.disabled = true;\n        colourGrid.append(button);\n      });\n      trackOptions.append(colourGrid);\n      if (motorised) {\n        const remoteLabel = element(\"label\", \"lux-v5-toggle\");\n        const remote = element(\"input\");\n        remote.type = \"checkbox\";\n        remote.checked = state.draft.window.remote;\n        remote.dataset.v5Field = \"remote\";\n        remoteLabel.append(remote, element(\"span\", \"\", \"Add Remote Control\"));\n        trackOptions.append(remoteLabel);\n      }\n    }\n\n    renderOptionSection(\n      dom.configSections.opening,\n      \"Curtain Opening\",\n      \"Choose how the curtain panels stack.\",\n      \"opening\",\n      [\n        { value: \"centre\", label: OPTION_LABELS.opening.centre, image: visuals.openingCentre },\n        { value: \"left\", label: OPTION_LABELS.opening.left, image: visuals.openingLeft },\n        { value: \"right\", label: OPTION_LABELS.opening.right, image: visuals.openingRight },\n        { value: \"free\", label: OPTION_LABELS.opening.free, image: visuals.openingFree }\n      ]\n    );\n    renderOptionSection(\n      dom.configSections.fixing,\n      \"Track Fixing\",\n      \"Choose how supplied tracks will be mounted.\",\n      \"fixing\",\n      [\n        { value: \"ceiling\", label: OPTION_LABELS.fixing.ceiling, image: visuals.fixingCeiling },\n        { value: \"wall\", label: OPTION_LABELS.fixing.wall, image: visuals.fixingWall }\n      ]\n    );\n    if (trackOptions) dom.configSections.fixing.append(trackOptions);\n    renderOptionSection(\n      dom.configSections.finish,\n      \"Bottom Finish\",\n      \"Choose how the curtains finish at floor level.\",\n      \"finish\",\n      [\n        { value: \"off-floor\", label: OPTION_LABELS.finish[\"off-floor\"], image: visuals.finishOffFloor },\n        { value: \"puddle\", label: OPTION_LABELS.finish.puddle, image: visuals.finishPuddle }\n      ]\n    );\n    renderOptionSection(\n      dom.configSections.pelmet,\n      \"Designer Pelmet\",\n      \"Please choose Yes or No before continuing.\",\n      \"pelmetChoice\",\n      [\n        {\n          value: \"no\",\n          label: \"No Pelmet\"\n        },\n        {\n          value: \"yes\",\n          label: \"Yes, Add Designer Pelmet\"\n        }\n      ]\n    );\n\n    clear(dom.configSections.notes);\n    dom.configSections.notes.append(\n      sectionHeading(\n        \"Project Notes\",\n        \"Add installation, access or manufacturing notes for this window.\",\n        \"08\"\n      )\n    );\n    const notes = element(\"textarea\", \"lux-v5-textarea\");\n    notes.rows = 4;\n    notes.maxLength = 500;\n    notes.value = state.draft.window.notes;\n    notes.dataset.v5Field = \"notes\";\n    dom.configSections.notes.append(notes);\n    if (dom.windowAccordion) renderWindowAccordion();\n  };\n\n  /* =====================================================================\n     19A. ONE-PAGE WINDOW ACCORDION\n     ===================================================================== */\n\n  const WINDOW_FLOW_STEPS = Object.freeze([\n    {\n      key: \"measurements\",\n      title: \"Room & Measurements\",\n      description: \"Name this window and enter the finished width and drop.\"\n    },\n    {\n      key: \"supply\",\n      title: \"Curtain & Track Option\",\n      description: \"Choose from our single-curtain track options.\"\n    },\n    {\n      key: \"heading\",\n      title: \"Heading Style\",\n      description: \"Choose the curtain heading and fullness.\"\n    },\n    {\n      key: \"opening\",\n      title: \"Curtain Opening\",\n      description: \"Choose how the curtain panels stack.\"\n    },\n    {\n      key: \"fixing\",\n      title: \"Fixing & Track Colour\",\n      description: \"Choose the fixing method and track finish.\"\n    },\n    {\n      key: \"finish\",\n      title: \"Bottom Finish\",\n      description: \"Choose the finished curtain position.\"\n    },\n{\n      key: \"pelmet\",\n      title: \"Designer Pelmet\",\n      description: \"Add a made-to-measure designer pelmet.\"\n    },\n    {\n      key: \"notes\",\n      title: \"Customer Notes\",\n      description: \"Add any access, installation or manufacturing notes.\"\n    }\n  ]);\n\n  const accordionStepVisible = key => true;\n\n  const initialiseWindowAccordion = () => {\n    if (dom.windowAccordion) return;\n    const measurementStage = dom.stages.measurements;\n    const measurementCards = [\n      ...measurementStage.querySelectorAll(\":scope > .lux-v5-config-card\")\n    ];\n    const stageHeader = measurementStage.querySelector(\":scope > .lux-v5-stage-header\");\n    if (stageHeader) {\n      stageHeader.classList.add(\"lux-v5-window-flow__intro\");\n      const eyebrow = stageHeader.querySelector(\".lux-v5-eyebrow\");\n      const description = stageHeader.querySelector(\"p:last-child\");\n      if (eyebrow) eyebrow.textContent = \"Design This Window\";\n      if (description) {\n        description.textContent =\n          \"Complete each section in order. You can reopen any section to make changes.\";\n      }\n    }\n\n    const flow = element(\"div\", \"lux-v5-window-accordion\");\n    flow.setAttribute(\"aria-label\", \"Window design steps\");\n    const nodeMap = {\n      measurements: measurementCards,\n      heading: [dom.configSections.heading],\n      supply: [dom.configSections.supply],\n      opening: [dom.configSections.opening],\n      fixing: [dom.configSections.fixing],\n      finish: [dom.configSections.finish],\n      pelmet: [dom.configSections.pelmet],\n      notes: [dom.configSections.notes]\n    };\n\n    WINDOW_FLOW_STEPS.forEach((step, index) => {\n      const item = element(\"section\", \"lux-v5-accordion-step\");\n      item.dataset.v5AccordionStep = step.key;\n      const trigger = setAction(\n        element(\"button\", \"lux-v5-accordion-step__trigger\"),\n        \"accordion-open\",\n        step.key\n      );\n      trigger.type = \"button\";\n      trigger.setAttribute(\"aria-expanded\", \"false\");\n      const marker = element(\"span\", \"lux-v5-accordion-step__marker\", \"\u25C7\");\n      marker.setAttribute(\"aria-hidden\", \"true\");\n      const copy = element(\"span\", \"lux-v5-accordion-step__copy\");\n      copy.append(\n        element(\"strong\", \"\", step.title),\n        element(\"small\", \"\", step.description)\n      );\n      trigger.append(\n        marker,\n        copy,\n        element(\"span\", \"lux-v5-accordion-step__status\", index === 0 ? \"Open\" : \"Select\")\n      );\n\n      const body = element(\"div\", \"lux-v5-accordion-step__body\");\n      body.hidden = true;\n      (nodeMap[step.key] || []).filter(Boolean).forEach(node => body.append(node));\n      if (step.key === \"notes\") {\n        const confirmationLabel = element(\n          \"label\",\n          \"lux-v5-confirmation lux-v5-window-save-confirmation\"\n        );\n        const confirmationInput = element(\"input\");\n        confirmationInput.type = \"checkbox\";\n        confirmationInput.checked = state.draft.window.confirmation === true;\n        confirmationInput.dataset.v5Field = \"window-confirmation\";\n        confirmationLabel.append(\n          confirmationInput,\n          element(\"span\", \"\", \"I confirm my measurements and selections are correct.\")\n        );\n        body.append(confirmationLabel);\n      }\n      const footer = element(\"footer\", \"lux-v5-accordion-step__footer\");\n      const isFinalStep = step.key === \"notes\";\n      const save = setAction(\n        element(\n          \"button\",\n          \"lux-v5-button lux-v5-button--step\",\n          isFinalStep\n            ? state.project.editingWindowId\n              ? \"Save Window Changes\"\n              : \"Confirm & Save Window\"\n            : \"Save & Continue\"\n        ),\n        isFinalStep ? \"save-window-direct\" : \"accordion-next\",\n        step.key\n      );\n      save.type = \"button\";\n      if (isFinalStep) save.disabled = true;\n      footer.append(save);\n      body.append(footer);\n      item.append(trigger, body);\n      flow.append(item);\n    });\n\n    measurementStage.append(flow);\n    dom.windowAccordion = flow;\n    dom.stages.configuration.hidden = true;\n    dom.stages.windowReview.hidden = true;\n  };\n\n  const windowStepSummary = key => {\n    const draft = state.draft.window;\n    if (key === \"measurements\") {\n      return draft.widthMm && draft.dropMm\n        ? `${draft.windowName || draft.roomName} \u00B7 ${draft.widthMm} \u00D7 ${draft.dropMm} mm`\n        : \"Name this window and enter its finished size\";\n    }\n    if (key === \"heading\") return OPTION_LABELS.heading[draft.heading];\n    if (key === \"supply\") {\n      return draft.supplyChoice\n        ? OPTION_LABELS.supply[draft.supply]\n        : \"Choose curtains only or add tracks\";\n    }\n    if (key === \"opening\") return OPTION_LABELS.opening[draft.opening];\n    if (key === \"fixing\") {\n      const colour =\n        draft.supply === \"curtain-only\" ? \"\" : ` \u00B7 ${OPTION_LABELS.trackColour[draft.trackColour]}`;\n      return `${OPTION_LABELS.fixing[draft.fixing]}${colour}`;\n    }\n    if (key === \"finish\") return OPTION_LABELS.finish[draft.finish];\n    if (key === \"pelmet\") {\n      if (draft.pelmetChoice === \"yes\") return \"Designer pelmet included\";\n      if (draft.pelmetChoice === \"no\") return \"No pelmet\";\n      return \"Choose Yes or No\";\n    }\n    if (key === \"notes\") return draft.notes ? \"Notes added\" : \"No notes added\";\n    return \"\";\n  };\n\n  const renderWindowAccordion = () => {\n    if (!dom.windowAccordion || !state) return;\n    const activeKey = state.ui.windowFlowStep || \"measurements\";\n    dom.windowAccordion.querySelectorAll(\"[data-v5-accordion-step]\").forEach(item => {\n      const key = item.dataset.v5AccordionStep;\n      const visible = accordionStepVisible(key);\n      const active = visible && key === activeKey;\n      const complete = state.ui.completedWindowSteps.includes(key);\n      setHidden(item, !visible);\n      item.classList.toggle(\"is-open\", active);\n      item.classList.toggle(\"is-complete\", complete);\n      const trigger = item.querySelector(\".lux-v5-accordion-step__trigger\");\n      const body = item.querySelector(\".lux-v5-accordion-step__body\");\n      const marker = item.querySelector(\".lux-v5-accordion-step__marker\");\n      const status = item.querySelector(\".lux-v5-accordion-step__status\");\n      const description = item.querySelector(\".lux-v5-accordion-step__copy small\");\n      trigger?.setAttribute(\"aria-expanded\", String(active));\n      if (body) body.hidden = !active;\n      if (marker) marker.textContent = complete ? \"\u2713\" : active ? \"\u25BE\" : \"\u25C7\";\n      if (status) status.textContent = complete ? \"Complete\" : active ? \"Open\" : \"Select\";\n      if (description) {\n        const stepDefinition = WINDOW_FLOW_STEPS.find(step => step.key === key);\n        description.textContent = complete\n          ? windowStepSummary(key)\n          : stepDefinition?.description || \"\";\n      }\n    });\n    const finalConfirmation = dom.windowAccordion.querySelector(\n      '[data-v5-field=\"window-confirmation\"]'\n    );\n    if (finalConfirmation) {\n      finalConfirmation.checked = state.draft.window.confirmation === true;\n    }\n    const finalSave = dom.windowAccordion.querySelector(\n      '[data-v5-action=\"save-window-direct\"]'\n    );\n    if (finalSave) {\n      finalSave.textContent = state.project.editingWindowId\n        ? \"Save Window Changes\"\n        : \"Confirm & Save Window\";\n      finalSave.disabled =\n        validateWindow(state.draft.window).length > 0 ||\n        state.draft.window.confirmation !== true;\n    }\n  };\n\n  const openWindowAccordionStep = (key, shouldScroll = true) => {\n    if (!WINDOW_FLOW_STEPS.some(step => step.key === key) || !accordionStepVisible(key)) return;\n    state.ui.windowFlowStep = key;\n    renderWindowAccordion();\n    if (shouldScroll) {\n      const item = dom.windowAccordion?.querySelector(`[data-v5-accordion-step=\"${key}\"]`);\n      window.setTimeout(() => {\n        if (!item) return;\n        const reducedMotion = window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n        const isMobile = window.matchMedia(\"(max-width: 980px)\").matches;\n        if (!isMobile) {\n          item.scrollIntoView({ behavior: reducedMotion ? \"auto\" : \"smooth\", block: \"start\" });\n          return;\n        }\n        const alignHeading = behavior => {\n          const trigger = item.querySelector(\".lux-v5-accordion-step__trigger\") || item;\n          const top = trigger.getBoundingClientRect().top + window.scrollY;\n          window.scrollTo({\n            top: Math.max(0, top - themeHeaderOffset() - 12),\n            behavior\n          });\n        };\n        alignHeading(reducedMotion ? \"auto\" : \"smooth\");\n        window.setTimeout(() => alignHeading(\"auto\"), reducedMotion ? 50 : 280);\n      }, 30);\n    }\n  };\n\n  const completeWindowAccordionStep = key => {\n    if (key === \"measurements\") {\n      const errors = validateMeasurements(state.draft.window);\n      if (errors.length) {\n        announce(errors[0], \"error\");\n        setHidden(dom.measurementValidation, false);\n        dom.measurementValidation.textContent = errors[0];\n        dom.measurementValidation.classList.add(\"has-error\");\n        (errors[0].startsWith(\"Track\") ? dom.width : dom.drop).focus();\n        return;\n      }\n    }\n    if (key === \"supply\" && !state.draft.window.supplyChoice) {\n      announce(\"Choose Curtains Only or select a double-track option.\", \"error\");\n      return;\n    }\n    if (key === \"pelmet\" && ![\"yes\", \"no\"].includes(state.draft.window.pelmetChoice)) {\n      announce(\"Please choose Yes or No for the Designer Pelmet.\", \"error\");\n      return;\n    }\n    if (!state.ui.completedWindowSteps.includes(key)) {\n      state.ui.completedWindowSteps.push(key);\n    }\n    const currentIndex = WINDOW_FLOW_STEPS.findIndex(step => step.key === key);\n    const next = WINDOW_FLOW_STEPS.slice(currentIndex + 1).find(step =>\n      accordionStepVisible(step.key)\n    );\n    touchState();\n    if (next) openWindowAccordionStep(next.key);\n  };\n\n  /* =====================================================================\n     20. TRACK ENGINE\n     ===================================================================== */\n\n  const trackTierPrice = widthMm => {\n    const table = (Array.isArray(config.settings.trackPricing)\n      ? config.settings.trackPricing\n      : []\n    )\n      .map(item => ({\n        maximumWidthMm: toNumber(item.maximumWidthMm),\n        price: toNumber(item.price)\n      }))\n      .filter(item => positive(item.maximumWidthMm) && positive(item.price))\n      .sort((a, b) => a.maximumWidthMm - b.maximumWidthMm);\n    if (!table.length || !positive(widthMm)) return { valid: false, total: 0, pieces: [] };\n    const preferredSplitWidthMm = toNumber(config.settings.preferredSplitWidthMm, 3000);\n    if (!positive(preferredSplitWidthMm)) return { valid: false, total: 0, pieces: [] };\n    const pieceCount = Math.max(1, Math.ceil(widthMm / preferredSplitWidthMm));\n    const pieceWidth = Math.ceil(widthMm / pieceCount);\n    const maximumSellingWidthMm = table[table.length - 1].maximumWidthMm;\n    const sellingTier =\n      widthMm <= maximumSellingWidthMm\n        ? table.find(item => widthMm <= item.maximumWidthMm)\n        : table.find(item => pieceWidth <= item.maximumWidthMm);\n    if (!sellingTier) return { valid: false, total: 0, pieces: [] };\n    const sellingPrice =\n      widthMm <= maximumSellingWidthMm\n        ? sellingTier.price\n        : sellingTier.price * pieceCount;\n    return {\n      valid: true,\n      total: roundMoney(sellingPrice),\n      sellingWidthMm: widthMm,\n      sellingTierMaximumMm: sellingTier.maximumWidthMm,\n      pieces: Array(pieceCount).fill({\n        widthMm: pieceWidth,\n        tierMaximumMm: sellingTier.maximumWidthMm\n      })\n    };\n  };\n\n  const calculateTracks = windowData => {\n    if (windowData.supply === \"curtain-only\") {\n      return {\n        valid: true,\n        basePerTrack: 0,\n        trackBase: 0,\n        motorisation: 0,\n        ledUpgrade: 0,\n        remote: 0,\n        pieces: [],\n        total: 0\n      };\n    }\n    const tier = trackTierPrice(windowData.widthMm);\n    const multiplier = toNumber(config.settings.doubleTrackMultiplier);\n    if (!tier.valid || !positive(multiplier)) return { valid: false, total: 0 };\n    const trackBase = tier.total * multiplier;\n    const motorised = [\"motorised-double-track\", \"led-motorised-double-track\"].includes(\n      windowData.supply\n    );\n    const motorisation = motorised\n      ? toNumber(config.settings.motorisedTrackAdditionPerTrack) * multiplier\n      : 0;\n    const ledSystem = windowData.supply === \"led-motorised-double-track\";\n    const ledTarget = ledSystem\n      ? toNumber(config.settings.ledMotorisedTrackAdditionPerTrack) * multiplier\n      : 0;\n    const ledUpgrade = Math.max(0, ledTarget - motorisation);\n    const remote = motorised && windowData.remote ? toNumber(config.settings.remoteAddition) : 0;\n    return {\n      valid: true,\n      basePerTrack: tier.total,\n      trackBase,\n      motorisation,\n      ledUpgrade,\n      remote,\n      pieces: tier.pieces,\n      total: roundMoney(trackBase + motorisation + ledUpgrade + remote)\n    };\n  };\n\n  /* =====================================================================\n     21. BENDING ENGINE\n     ===================================================================== */\n\n  /* =====================================================================\n     22. PRICING PROVIDER\n     ===================================================================== */\n\n  const PricingProvider = Object.freeze({\n    quoteWindow(windowData) {\n      return pricingProvider.quoteWindow(windowData);\n    },\n    quoteProject(projectData) {\n      return pricingProvider.quoteProject(projectData);\n    }\n  });\n\n  /* =====================================================================\n     23. LOCAL SHOPIFY PRICING\n     ===================================================================== */\n\n  const fabricPrice = (selection, widthMm, heading) => {\n    const snapshot = selection?.pricingReference || {};\n    const base =\n      [snapshot.baseSetPrice, snapshot.shopifyPrice, snapshot.variantPrice]\n        .map(value => toNumber(value))\n        .find(positive) || 0;\n    const minimumWidth = toNumber(config.settings.minimumChargedWidthMm);\n    const fullness = config.settings.fullness || {};\n    const factors = {\n      \"s-wave\": toNumber(fullness.sWave),\n      \"double-pinch\": toNumber(fullness.doublePinch),\n      \"triple-pinch\": toNumber(fullness.triplePinch)\n    };\n    if (!positive(base) || !positive(minimumWidth) || !positive(factors[\"s-wave\"]) || !positive(factors[heading])) {\n      return { valid: false, errors: [PRICING_ERROR] };\n    }\n    const chargedWidthMm = Math.max(widthMm, minimumWidth);\n    // Pricing multipliers differ from manufacturing fullness specifications.\n    const headingFactor = heading === \"double-pinch\" ? 1 : factors[heading] / factors[\"s-wave\"];\n    const original = base * (chargedWidthMm / minimumWidth) * headingFactor;\n    const promotionPercentage = clamp(selection.promotionPercent, 0, 95);\n    const savings = original * (promotionPercentage / 100);\n    return {\n      valid: true,\n      chargedWidthMm,\n      baseSetPrice: base,\n      headingFactor,\n      promotionPercentage,\n      original: roundMoney(original),\n      savings: roundMoney(savings),\n      final: roundMoney(original - savings),\n      errors: []\n    };\n  };\n\n  const LocalShopifyPricingProvider = Object.freeze({\n    /**\n     * Calculates one window from the immutable Shopify pricing snapshot.\n     * @param {object} windowData\n     * @returns {object} Normalised quote result.\n     */\n    quoteWindow(windowData) {\n      const errors = [];\n      if (!windowData?.sheer?.confirmed || !windowData?.blackout?.confirmed) {\n        errors.push(\"Confirm the sheer fabric selection.\");\n      }\n      errors.push(...validateMeasurements(windowData));\n      const sheer = {\n        valid: true,\n        chargedWidthMm: 0,\n        baseSetPrice: 0,\n        headingFactor: 1,\n        promotionPercentage: 0,\n        original: 0,\n        savings: 0,\n        final: 0,\n        errors: []\n      };\n      const blackout = fabricPrice(windowData.blackout, windowData.widthMm, windowData.heading);\n      if (!blackout.valid) errors.push(PRICING_ERROR);\n      const tracks = calculateTracks(windowData);\n      if (!tracks.valid) errors.push(PRICING_ERROR);\n      const pelmetWidthMm = windowData.pelmet\n        ? windowData.widthMm + toNumber(config.settings.pelmetReturnsMm)\n        : 0;\n      const pelmet = {\n        chargedWidthMm: pelmetWidthMm,\n        total: windowData.pelmet\n          ? roundMoney((pelmetWidthMm / 1000) * toNumber(config.settings.pelmetPricePerMetre))\n          : 0\n      };\n      if (windowData.pelmet && (!positive(pelmetWidthMm) || !positive(config.settings.pelmetPricePerMetre))) {\n        errors.push(PRICING_ERROR);\n      }\n      const rawOriginalTotal = roundMoney(\n        toNumber(sheer.original) +\n          toNumber(blackout.original) +\n          toNumber(tracks.total) +\n          pelmet.total +\n          0\n      );\n      const rawSavings = roundMoney(toNumber(sheer.savings) + toNumber(blackout.savings));\n      const originalTotal = roundUpDollar(rawOriginalTotal);\n      const finalTotal = roundUpDollar(rawOriginalTotal - rawSavings);\n      const savings = Math.max(0, originalTotal - finalTotal);\n      const uniqueErrors = [...new Set(errors)];\n      return {\n        valid: uniqueErrors.length === 0 && positive(finalTotal),\n        source: \"shopify-local\",\n        currency: config.currencyCode,\n        originalTotal,\n        savings,\n        finalTotal,\n        breakdown: {\n          sheer,\n          blackout,\n          tracks: { base: tracks.trackBase || 0, pieces: tracks.pieces || [] },\n          motorisation: { total: tracks.motorisation || 0, ledUpgrade: tracks.ledUpgrade || 0 },\n          remote: { total: tracks.remote || 0 },\n          pelmet,\n          promotions: { sheer: sheer.savings || 0, blackout: blackout.savings || 0 },\n          orderDiscount: { total: 0 }\n        },\n        errors: uniqueErrors,\n        warnings: []\n      };\n    },\n\n    /**\n     * Requotes all saved windows and applies the highest matching order discount.\n     * @param {object} projectData\n     * @returns {object} Normalised project quote.\n     */\n    quoteProject(projectData) {\n      const windows = (projectData?.windows || []).map(windowData => ({\n        id: windowData.id,\n        quote: LocalShopifyPricingProvider.quoteWindow(windowData)\n      }));\n      const errors = windows.flatMap(item => item.quote.errors);\n      const originalTotal = roundUpDollar(\n        windows.reduce((sum, item) => sum + item.quote.originalTotal, 0)\n      );\n      const beforeOrderDiscount = roundUpDollar(\n        windows.reduce((sum, item) => sum + item.quote.finalTotal, 0)\n      );\n      const fabricPromotions = roundUpDollar(\n        windows.reduce((sum, item) => sum + item.quote.savings, 0)\n      );\n      const rules = (Array.isArray(config.settings.orderDiscounts)\n        ? config.settings.orderDiscounts\n        : []\n      )\n        .map(rule => ({ minimum: toNumber(rule.minimum), discount: toNumber(rule.discount) }))\n        .filter(rule => positive(rule.minimum) && positive(rule.discount))\n        .sort((a, b) => b.minimum - a.minimum);\n      const match = rules.find(rule => beforeOrderDiscount >= rule.minimum);\n      const orderDiscount = Math.min(beforeOrderDiscount, roundUpDollar(match?.discount || 0));\n      const finalTotal = roundUpDollar(beforeOrderDiscount - orderDiscount);\n      return {\n        valid:\n          windows.length > 0 &&\n          windows.every(item => item.quote.valid) &&\n          positive(finalTotal) &&\n          errors.length === 0,\n        source: \"shopify-local\",\n        currency: config.currencyCode,\n        originalTotal,\n        fabricPromotions,\n        orderDiscount,\n        savings: fabricPromotions + orderDiscount,\n        finalTotal,\n        windows,\n        errors: [...new Set(errors)],\n        warnings: []\n      };\n    }\n  });\n\n  const SecureApiPricingProvider = Object.freeze({\n    quoteWindow() {\n      return {\n        valid: false,\n        source: \"secure-api-not-configured\",\n        currency: config.currencyCode,\n        originalTotal: 0,\n        savings: 0,\n        finalTotal: 0,\n        breakdown: {},\n        errors: [\n          \"Secure pricing is enabled, but no verified quote contract is configured for this storefront.\"\n        ],\n        warnings: []\n      };\n    },\n    quoteProject() {\n      return {\n        valid: false,\n        source: \"secure-api-not-configured\",\n        currency: config.currencyCode,\n        originalTotal: 0,\n        fabricPromotions: 0,\n        orderDiscount: 0,\n        savings: 0,\n        finalTotal: 0,\n        windows: [],\n        errors: [\n          \"Secure pricing is enabled, but no verified quote contract is configured for this storefront.\"\n        ],\n        warnings: []\n      };\n    }\n  });\n\n  /* =====================================================================\n     24. PROJECT TOTAL ENGINE\n     ===================================================================== */\n\n  const recalculate = () => {\n    state.pricing.draftQuote = PricingProvider.quoteWindow(state.draft.window);\n    state.pricing.projectQuote = PricingProvider.quoteProject(state.project);\n    return state.pricing;\n  };\n\n  const allPlannedComplete = () =>\n    state.journey.mode !== MODES.WHOLE_HOME ||\n    (state.planner.plannedWindows.length > 0 &&\n      state.planner.plannedWindows.every(item => item.status === STATUS.COMPLETE));\n\n  /* =====================================================================\n     25. SIDEBAR ENGINE\n     ===================================================================== */\n\n  const summaryRow = (label, value) => {\n    const row = element(\"div\", \"lux-v5-summary-row\");\n    row.append(element(\"span\", \"\", label), element(\"strong\", \"\", value));\n    return row;\n  };\n\n  const renderFabricPreview = (node, label, selection) => {\n    clear(node);\n    if (selection.variantImage) {\n      const image = element(\"img\");\n      image.src = selection.variantImage;\n      image.alt = `${selection.productTitle} ${selection.variantTitle}`;\n      node.append(image);\n    }\n    node.append(element(\"span\", \"\", label), element(\"strong\", \"\", selection.variantTitle || \"Not selected\"));\n  };\n\n  const renderSavedWindowCards = target => {\n    clear(target);\n    if (!state.project.windows.length) {\n      target.append(element(\"p\", \"lux-v5-empty-state\", \"No saved windows yet.\"));\n      return;\n    }\n    state.project.windows.forEach(windowData => {\n      const quote = PricingProvider.quoteWindow(windowData);\n      const card = element(\"article\", \"lux-v5-saved-window\");\n      card.setAttribute(\"aria-expanded\", \"false\");\n      const text = element(\"div\", \"lux-v5-saved-window__heading\");\n      text.append(\n        element(\"strong\", \"\", windowData.windowName || windowData.roomName),\n        element(\"small\", \"\", quote.valid ? money(quote.finalTotal) : \"Pricing unavailable\")\n      );\n      const meta = element(\"div\", \"lux-v5-saved-window__meta\");\n      meta.append(\n        element(\"span\", \"\", `Sheer: ${windowData.blackout.variantTitle || \"Not selected\"}`),\n        element(\"span\", \"\", `System: ${OPTION_LABELS.supply[windowData.supply]}`),\n        element(\"span\", \"\", `Heading: ${OPTION_LABELS.heading[windowData.heading]}`)\n      );\n      const edit = setAction(element(\"button\", \"lux-v5-text-button\", \"Edit\"), \"edit-window\", windowData.id);\n      edit.type = \"button\";\n      const duplicate = setAction(\n        element(\"button\", \"lux-v5-text-button\", \"Duplicate\"),\n        \"duplicate-window\",\n        windowData.id\n      );\n      duplicate.type = \"button\";\n      const remove = setAction(\n        element(\"button\", \"lux-v5-text-button\", \"Remove\"),\n        \"remove-window\",\n        windowData.id\n      );\n      remove.type = \"button\";\n      const actions = element(\"div\", \"lux-v5-saved-window__actions\");\n      actions.append(edit, duplicate, remove);\n      card.append(text, meta, actions);\n      target.append(card);\n    });\n  };\n\n  const renderTotals = target => {\n    clear(target);\n    const quote = state.pricing.projectQuote;\n    const original = toNumber(quote.originalTotal);\n    const fabricPromotion = toNumber(quote.fabricPromotions);\n    const orderPromotion = toNumber(quote.orderDiscount);\n    const subtotal = Math.max(0, original - fabricPromotion);\n    target.append(\n      summaryRow(\"Original Value\", quote.valid || original ? money(original) : \"\u2014\"),\n      summaryRow(\"Fabric Promotion\", fabricPromotion ? `\u2212${money(fabricPromotion)}` : \"\u2014\"),\n      summaryRow(\"Subtotal\", quote.valid || subtotal ? money(subtotal) : \"\u2014\")\n    );\n    if (orderPromotion) {\n      target.append(summaryRow(\"Order Promotion\", `\u2212${money(orderPromotion)}`));\n    }\n    target.append(summaryRow(\"Project Total\", quote.valid ? money(quote.finalTotal) : \"\u2014\"));\n  };\n\n  const renderPromotionProgress = target => {\n    if (!target) return;\n    clear(target);\n    const quote = state.pricing.projectQuote;\n    const spend = Math.max(0, toNumber(quote.originalTotal) - toNumber(quote.fabricPromotions));\n    const rules = (Array.isArray(config.settings.orderDiscounts)\n      ? config.settings.orderDiscounts\n      : []\n    )\n      .map(rule => ({ minimum: toNumber(rule.minimum), discount: toNumber(rule.discount) }))\n      .filter(rule => positive(rule.minimum) && positive(rule.discount))\n      .sort((a, b) => a.minimum - b.minimum);\n    const next = rules.find(rule => spend < rule.minimum);\n    const current = [...rules].reverse().find(rule => spend >= rule.minimum);\n    const message = next\n      ? `Add ${money(next.minimum - spend)} more to unlock ${money(next.discount)} off your project`\n      : current\n        ? `${money(current.discount)} project promotion unlocked`\n        : \"Your project promotions will appear here\";\n    const progress = next ? clamp((spend / next.minimum) * 100, 0, 100) : current ? 100 : 0;\n    target.append(\n      element(\"strong\", \"\", message),\n      (() => {\n        const track = element(\"span\", \"lux-v5-promotion-progress__track\");\n        const fill = element(\"span\", \"lux-v5-promotion-progress__fill\");\n        fill.style.width = `${progress}%`;\n        track.append(fill);\n        return track;\n      })()\n    );\n  };\n\n  const renderProjectStatus = target => {\n    if (!target) return;\n    clear(target);\n    const planned = state.planner.plannedWindows.length;\n    const completed =\n      state.journey.mode === MODES.WHOLE_HOME\n        ? state.planner.plannedWindows.filter(item => item.status === STATUS.COMPLETE).length\n        : state.project.windows.length;\n    target.append(\n      summaryRow(\"Windows completed\", planned ? `${completed} of ${planned}` : String(completed)),\n      summaryRow(\"Manufacturing\", \"4\u20136 Weeks\")\n    );\n  };\n\n  const renderSidebar = () => {\n    if (!dom || !state) return;\n    recalculate();\n    const draft = state.draft.window;\n    const draftQuote = state.pricing.draftQuote;\n    const projectQuote = state.pricing.projectQuote;\n    setHidden(dom.sheerPreview, true);\n    renderFabricPreview(dom.blackoutPreview, \"Sheer\", draft.blackout);\n    dom.activeWindowPrice.textContent = draftQuote.valid ? money(draftQuote.finalTotal) : \"\u2014\";\n    clear(dom.currentSummary);\n    dom.currentSummary.append(\n      summaryRow(\"Window\", draft.windowName || \"Draft window\"),\n      summaryRow(\"Sheer\", draft.blackout.variantTitle || \"Not selected\"),\n      summaryRow(\n        \"System\",\n        draft.supplyChoice ? OPTION_LABELS.supply[draft.supply] : \"Not selected\"\n      )\n    );\n    renderSavedWindowCards(dom.savedWindows);\n    renderTotals(dom.projectTotals);\n    if (dom.desktopSavings) {\n      const savings = toNumber(projectQuote.savings);\n      dom.desktopSavings.textContent = savings\n        ? `\uD83C\uDF89 You saved ${money(savings)} today`\n        : \"\";\n      setHidden(dom.desktopSavings, !savings);\n    }\n    renderPromotionProgress(dom.promotionProgress);\n    renderProjectStatus(dom.projectStatus);\n    dom.windowCount.textContent = `${state.project.windows.length} Window${\n      state.project.windows.length === 1 ? \"\" : \"s\"\n    }`;\n    dom.projectTotal.textContent = projectQuote.valid ? money(projectQuote.finalTotal) : \"\u2014\";\n    const showDraftPrice = [\n      STAGES.MEASUREMENTS,\n      STAGES.WINDOW_CONFIGURATION,\n      STAGES.WINDOW_REVIEW\n    ].includes(state.journey.stage);\n    dom.mobileTotal.textContent = projectQuote.valid\n      ? money(projectQuote.finalTotal)\n      : showDraftPrice && draftQuote.valid\n        ? money(draftQuote.finalTotal)\n        : \"\u2014\";\n    renderDrawer();\n    refreshCheckoutState();\n  };\n\n  /* =====================================================================\n     26. MOBILE BAR\n     ===================================================================== */\n\n  const primaryStageReady = () => {\n    if (state.journey.stage === STAGES.FABRIC_SELECTION) {\n      return state.draft.window.blackout.confirmed;\n    }\n    if (state.journey.stage === STAGES.MEASUREMENTS) {\n      return validateMeasurements(state.draft.window).length === 0;\n    }\n    if (state.journey.stage === STAGES.WINDOW_CONFIGURATION) {\n      return state.ui.configuringBase\n        ? state.draft.window.sheer.confirmed && state.draft.window.blackout.confirmed\n        : validateWindow(state.draft.window).length === 0;\n    }\n    if (state.journey.stage === STAGES.WINDOW_REVIEW) {\n      return (\n        validateWindow(state.draft.window).length === 0 &&\n        state.draft.window.confirmation === true\n      );\n    }\n    if (state.journey.stage === STAGES.PROJECT_REVIEW) {\n      return (\n        state.project.windows.length > 0 &&\n        allPlannedComplete() &&\n        state.pricing.projectQuote?.valid === true\n      );\n    }\n    return true;\n  };\n\n  const updatePrimaryAction = () => {\n    if (!dom?.mobilePrimary) return;\n    if (state.journey.stage === STAGES.FABRIC_SELECTION) {\n      dom.mobilePrimary.hidden = true;\n      return;\n    }\n    dom.mobilePrimary.hidden = false;\n    const labels = {\n      [STAGES.FABRIC_SELECTION]:\n        state.journey.mode === MODES.WHOLE_HOME && !state.project.baseDesign\n          ? \"Continue to Design Curtains\"\n          : \"Continue to Measurements\",\n      [STAGES.MEASUREMENTS]: \"Continue Window Design\",\n      [STAGES.WINDOW_CONFIGURATION]: state.ui.configuringBase\n        ? \"Start Measuring Windows\"\n        : \"Review This Window\",\n      [STAGES.WINDOW_REVIEW]: \"Save This Window\",\n      [STAGES.PROJECT_REVIEW]: \"Confirm Project\"\n    };\n    dom.mobilePrimary.textContent = labels[state.journey.stage] || \"Continue\";\n    const disabled = state.ui.busy || !primaryStageReady();\n    dom.mobilePrimary.disabled = disabled;\n    dom.root\n      .querySelectorAll(\".lux-v5-generated-actions [data-v5-action='primary-next']\")\n      .forEach(button => {\n        button.disabled = disabled;\n      });\n  };\n\n  /* =====================================================================\n     27. PROJECT DRAWER\n     ===================================================================== */\n\n  const projectCheckoutReady = () =>\n    !state.ui.busy &&\n    positive(config.checkout?.priceUnitVariantId) &&\n    state.project.confirmed === true &&\n    state.project.windows.length > 0 &&\n    allPlannedComplete() &&\n    state.pricing.projectQuote?.valid === true;\n\n  const projectCheckoutMessage = () => {\n    if (!state.project.windows.length) return \"Save at least one window before checkout.\";\n    if (!allPlannedComplete()) return \"Complete every planned window before checkout.\";\n    if (!state.pricing.projectQuote?.valid) return PRICING_ERROR;\n    if (!positive(config.checkout?.priceUnitVariantId)) {\n      return \"Checkout is unavailable until the Shopify price-unit variant is configured.\";\n    }\n    return state.project.confirmed\n      ? \"Your complete project is ready for secure checkout.\"\n      : \"Confirm your complete project to enable checkout.\";\n  };\n\n  const renderDrawer = () => {\n    clear(dom.drawerContent);\n    const overview = element(\"section\", \"lux-v5-drawer-overview\");\n    const overviewHeading = element(\"div\", \"lux-v5-drawer-overview__heading\");\n    const overviewCopy = element(\"div\");\n    overviewCopy.append(\n      element(\"small\", \"\", \"Your Project\"),\n      element(\n        \"strong\",\n        \"\",\n        `${state.project.windows.length} Window${state.project.windows.length === 1 ? \"\" : \"s\"}`\n      )\n    );\n    const overviewTotal = state.pricing.projectQuote?.valid\n      ? money(state.pricing.projectQuote.finalTotal)\n      : state.pricing.draftQuote?.valid\n        ? money(state.pricing.draftQuote.finalTotal)\n        : \"\u2014\";\n    overviewHeading.append(overviewCopy, element(\"b\", \"\", overviewTotal));\n    const overviewFabrics = element(\"div\", \"lux-v5-drawer-overview__fabrics\");\n    const overviewBlackout = element(\"div\", \"lux-v5-fabric-preview\");\n    renderFabricPreview(overviewBlackout, \"Sheer\", state.draft.window.blackout);\n    overviewFabrics.append(overviewBlackout);\n    overview.append(overviewHeading, overviewFabrics);\n    const draft = element(\"section\", \"lux-v5-drawer-card\");\n    draft.append(\n      element(\"h3\", \"\", state.draft.window.windowName || \"Active Window\"),\n      summaryRow(\n        \"Live estimate\",\n        state.pricing.draftQuote?.valid ? money(state.pricing.draftQuote.finalTotal) : \"\u2014\"\n      )\n    );\n    const windows = element(\"section\", \"lux-v5-drawer-card\");\n    windows.append(element(\"h3\", \"\", \"Saved Windows\"));\n    const list = element(\"div\", \"lux-v5-saved-windows\");\n    renderSavedWindowCards(list);\n    windows.append(list);\n    const promotion = element(\"section\", \"lux-v5-promotion-progress\");\n    renderPromotionProgress(promotion);\n    const status = element(\"section\", \"lux-v5-project-status\");\n    renderProjectStatus(status);\n    const totals = element(\"section\", \"lux-v5-project-totals\");\n    renderTotals(totals);\n    const savings = element(\n      \"strong\",\n      \"lux-v5-savings-banner\",\n      state.pricing.projectQuote?.savings\n        ? `\uD83C\uDF89 You saved ${money(state.pricing.projectQuote.savings)} today`\n        : \"Your savings will appear here\"\n    );\n    const confidence = element(\"div\", \"lux-v5-checkout-confidence\");\n    confidence.append(\n      element(\"strong\", \"\", \"Secure Shopify Checkout\"),\n      element(\"span\", \"\", \"Custom-made in approximately 4\u20136 weeks\"),\n      element(\"span\", \"\", \"Refreshing this page starts a new project\")\n    );\n    const confirmation = element(\"label\", \"lux-v5-confirmation\");\n    const confirmationInput = element(\"input\");\n    confirmationInput.type = \"checkbox\";\n    confirmationInput.checked = state.project.confirmed === true;\n    confirmationInput.dataset.v5ProjectConfirmation = \"\";\n    confirmation.append(\n      confirmationInput,\n      element(\n        \"span\",\n        \"\",\n        \"I confirm all measurements, fabric colours and selected options are correct.\"\n      )\n    );\n    const warning = element(\"p\", \"lux-v5-inline-message\");\n    warning.dataset.v5CheckoutWarning = \"\";\n    warning.textContent = projectCheckoutMessage();\n    warning.classList.toggle(\"has-error\", !projectCheckoutReady());\n    const checkoutButton = setAction(\n      element(\"button\", \"lux-v5-button lux-v5-button--checkout\", \"Proceed to Secure Checkout\"),\n      \"drawer-checkout\"\n    );\n    checkoutButton.type = \"button\";\n    checkoutButton.disabled = !projectCheckoutReady();\n    const startOver = setAction(element(\"button\", \"lux-v5-clear-project\", \"Start Over\"), \"request-reset\");\n    startOver.type = \"button\";\n    dom.drawerContent.append(\n      overview,\n      ...(![STAGES.PROJECT_REVIEW, STAGES.ENTRY].includes(state.journey.stage) ? [draft] : []),\n      status,\n      windows,\n      totals,\n      savings,\n      promotion,\n      confidence,\n      warning,\n      confirmation,\n      checkoutButton,\n      startOver\n    );\n  };\n\n  const openDrawer = () => {\n    lastFocusedElement = document.activeElement;\n    state.ui.mobileDrawerOpen = true;\n    dom.drawer.classList.add(\"is-open\");\n    dom.drawer.setAttribute(\"aria-hidden\", \"false\");\n    document.body.classList.add(\"lux-v5-scroll-locked\");\n    dom.drawerContent.scrollTop = 0;\n    window.requestAnimationFrame(() => {\n      dom.drawerContent.scrollTop = 0;\n    });\n    dom.drawer.querySelector(\"[data-v5-close-drawer]\")?.focus();\n  };\n\n  const closeDrawer = () => {\n    state.ui.mobileDrawerOpen = false;\n    dom.drawer.classList.remove(\"is-open\");\n    dom.drawer.setAttribute(\"aria-hidden\", \"true\");\n    if (!state.ui.activeModal) document.body.classList.remove(\"lux-v5-scroll-locked\");\n    lastFocusedElement?.focus?.();\n  };\n\n  /* =====================================================================\n     28. WINDOW REVIEW\n     ===================================================================== */\n\n  /**\n   * Validates all customer, measurement, bending and pricing requirements.\n   * @param {object} windowData\n   * @returns {string[]}\n   */\n  const validateWindow = windowData => {\n    const errors = [];\n    // Room selection is inherited from the whole-home project plan.\n    if (!cleanText(windowData.windowName)) errors.push(\"Enter a window name.\");\n        if (!windowData.blackout.confirmed) errors.push(\"Confirm the sheer fabric.\");\n    if (!windowData.supplyChoice) {\n      errors.push(\"Choose Curtains Only or select a double-track option.\");\n    }\n    if (![\"yes\", \"no\"].includes(windowData.pelmetChoice)) {\n      errors.push(\"Choose Yes or No for the Designer Pelmet.\");\n    }\n    errors.push(...validateMeasurements(windowData));\n    const quote = PricingProvider.quoteWindow(windowData);\n    if (!quote.valid && !errors.includes(PRICING_ERROR)) errors.push(...quote.errors);\n    return [...new Set(errors)];\n  };\n\n  const renderWindowReview = () => {\n    clear(dom.windowReview);\n    const windowData = state.draft.window;\n    const quote = PricingProvider.quoteWindow(windowData);\n    const errors = validateWindow(windowData);\n    const card = element(\"article\", \"lux-v5-review-card\");\n    card.append(element(\"h3\", \"\", windowData.windowName || \"Window Review\"));\n    [\n      [\"Room\", windowData.roomName],\n      [\"Size\", `${windowData.widthMm} \u00D7 ${windowData.dropMm} mm`],\n      [\n        \"Sheer\",\n        `${windowData.blackout.collectionTitle} \u00B7 ${windowData.blackout.productTitle} \u00B7 ${windowData.blackout.variantTitle}`\n      ],\n      [\"Heading\", OPTION_LABELS.heading[windowData.heading]],\n      [\"System\", OPTION_LABELS.supply[windowData.supply]],\n      [\"Track colour\", windowData.supply === \"curtain-only\" ? \"Not applicable\" : OPTION_LABELS.trackColour[windowData.trackColour]],\n      [\"Opening\", OPTION_LABELS.opening[windowData.opening]],\n      [\"Fixing\", OPTION_LABELS.fixing[windowData.fixing]],\n      [\"Finish\", OPTION_LABELS.finish[windowData.finish]],\n      [\"Pelmet\", windowData.pelmet ? \"Included\" : \"Not included\"],\n      [\"Remote\", windowData.remote ? \"Included\" : \"Not included\"],\n      [\"Notes\", windowData.notes || \"None\"]\n    ].forEach(([label, value]) => card.append(summaryRow(label, value)));\n    const pricing = element(\"div\", \"lux-v5-review-pricing\");\n    pricing.append(\n      summaryRow(\"Original value\", quote.valid ? money(quote.originalTotal) : \"\u2014\"),\n      summaryRow(\"Savings\", quote.valid ? money(quote.savings) : \"\u2014\"),\n      summaryRow(\"Final window price\", quote.valid ? money(quote.finalTotal) : \"\u2014\")\n    );\n    const actions = element(\"div\", \"lux-v5-screen-actions\");\n    const confirmationLabel = element(\"label\", \"lux-v5-confirmation\");\n    const confirmationInput = element(\"input\");\n    confirmationInput.type = \"checkbox\";\n    confirmationInput.checked = state.draft.window.confirmation === true;\n    confirmationInput.dataset.v5Field = \"window-confirmation\";\n    confirmationLabel.append(\n      confirmationInput,\n      element(\n        \"span\",\n        \"\",\n        \"I confirm that this window\u2019s measurements, fabric colours and selected options are correct.\"\n      )\n    );\n    const back = setAction(\n      element(\"button\", \"lux-v5-button lux-v5-button--secondary\", \"Back to Configuration\"),\n      \"review-back\"\n    );\n    back.type = \"button\";\n    const save = setAction(\n      element(\n        \"button\",\n        \"lux-v5-button lux-v5-button--primary\",\n        state.project.editingWindowId ? \"Save Window Changes\" : \"Confirm and Save Window\"\n      ),\n      \"save-window\"\n    );\n    save.type = \"button\";\n    save.disabled = Boolean(errors.length) || state.draft.window.confirmation !== true;\n    if (errors.length) {\n      const message = element(\"div\", \"lux-v5-inline-message has-error\");\n      message.setAttribute(\"role\", \"alert\");\n      message.textContent = errors[0];\n      card.append(message);\n    }\n    actions.append(back, save);\n    dom.windowReview.append(card, pricing, confirmationLabel, actions);\n  };\n\n  const showWindowCompletion = saved => {\n    const content = clear(dom.modalContents.confirm);\n    content.className = \"lux-v5-completion\";\n    const plans = state.planner.plannedWindows;\n    const completed =\n      state.journey.mode === MODES.WHOLE_HOME\n        ? plans.filter(item => item.status === STATUS.COMPLETE).length\n        : state.project.windows.length;\n    const total = state.journey.mode === MODES.WHOLE_HOME ? plans.length : state.project.windows.length;\n    const next =\n      state.journey.mode === MODES.WHOLE_HOME\n        ? plans.find(item => item.status !== STATUS.COMPLETE)\n        : null;\n    const icon = element(\"span\", \"lux-v5-completion__icon\", \"\u2713\");\n    icon.setAttribute(\"aria-hidden\", \"true\");\n    const heading = element(\"h2\", \"\", `${saved.windowName} completed`);\n    heading.id = \"luxV5ConfirmModalTitle\";\n    const progress = element(\n      \"p\",\n      \"lux-v5-completion__progress\",\n      `${completed} of ${Math.max(total, completed)} windows completed`\n    );\n    const summary = element(\"div\", \"lux-v5-completion__summary\");\n    summary.append(\n      summaryRow(\"Sheer\", saved.blackout.variantTitle),\n      summaryRow(\"System\", OPTION_LABELS.supply[saved.supply]),\n      summaryRow(\"Window price\", saved.quote?.valid ? money(saved.quote.finalTotal) : \"\u2014\")\n    );\n    const actions = element(\"div\", \"lux-v5-completion__actions\");\n    const edit = setAction(\n      element(\"button\", \"lux-v5-button lux-v5-button--secondary\", \"Review Completed Window\"),\n      \"completion-edit\",\n      saved.id\n    );\n    edit.type = \"button\";\n    if (next) {\n      const nextButton = setAction(\n        element(\"button\", \"lux-v5-button lux-v5-button--primary\", `Start ${next.windowName} Fresh`),\n        \"completion-next\",\n        next.id\n      );\n      nextButton.type = \"button\";\n      actions.append(edit, nextButton);\n    } else {\n      const review = setAction(\n        element(\"button\", \"lux-v5-button lux-v5-button--primary\", \"Review Your Project\"),\n        \"completion-review\"\n      );\n      review.type = \"button\";\n      actions.append(edit, review);\n    }\n    content.append(\n      icon,\n      heading,\n      progress,\n      element(\n        \"p\",\n        \"\",\n        next\n          ? `Saved successfully. Your next window is ${next.windowName}.`\n          : \"Every planned window is complete and ready for project review.\"\n      ),\n      summary,\n      actions\n    );\n    openModal(\"confirm\");\n  };\n\n  const commitWindow = () => {\n    const errors = validateWindow(state.draft.window);\n    if (errors.length) return announce(errors[0], \"error\");\n    if (state.draft.window.confirmation !== true) {\n      return announce(\"Confirm this window before saving it.\", \"error\");\n    }\n    const saved = deepCopy(state.draft.window);\n    saved.quote = PricingProvider.quoteWindow(saved);\n    saved.status = STATUS.COMPLETE;\n    saved.updatedAt = new Date().toISOString();\n    const existingIndex = state.project.windows.findIndex(\n      item => item.id === (state.project.editingWindowId || saved.id)\n    );\n    if (existingIndex >= 0) {\n      saved.id = state.project.windows[existingIndex].id;\n      state.project.windows.splice(existingIndex, 1, saved);\n    } else {\n      state.project.windows.push(saved);\n    }\n    const planned = plannedForDraft();\n    if (planned) {\n      planned.savedWindowId = saved.id;\n      planned.widthMm = saved.widthMm;\n      planned.dropMm = saved.dropMm;\n      planned.status = STATUS.COMPLETE;\n      planned.draftWindow = null;\n    }\n    if (state.journey.mode === MODES.WHOLE_HOME && !state.project.baseDesign) {\n      state.project.baseDesign = {\n        sheer: deepCopy(saved.sheer),\n        blackout: deepCopy(saved.blackout),\n        heading: saved.heading,\n        supply: saved.supply,\n        supplyChoice: saved.supplyChoice,\n        trackColour: saved.trackColour,\n        opening: saved.opening,\n        fixing: saved.fixing,\n        finish: saved.finish,\n        pelmet: saved.pelmet,\n        pelmetChoice: saved.pelmetChoice,\n        remote: saved.remote\n      };\n    }\n    state.project.editingWindowId = null;\n    recalculate();\n    touchState();\n    announce(`${saved.windowName} was saved.`);\n    showWindowCompletion(saved);\n  };\n\n  /* =====================================================================\n     29. PROJECT REVIEW\n     ===================================================================== */\n\n  const renderProjectReview = () => {\n    clear(dom.projectReview);\n    const heading = element(\"section\", \"lux-v5-review-card\");\n    const rooms = new Set(state.project.windows.map(item => item.roomName));\n    heading.append(\n      summaryRow(\"Project type\", state.journey.mode === MODES.WHOLE_HOME ? \"Whole-Home Project\" : \"Single Window\"),\n      summaryRow(\"Rooms\", String(rooms.size)),\n      summaryRow(\"Saved windows\", String(state.project.windows.length))\n    );\n    const windowList = element(\"div\", \"lux-v5-project-review__windows\");\n    renderSavedWindowCards(windowList);\n    const totals = element(\"section\", \"lux-v5-project-totals\");\n    renderTotals(totals);\n    const notice = element(\n      \"p\",\n      \"lux-v5-inline-message\",\n      \"Custom-made products will be manufactured from the measurements and selections you confirm.\"\n    );\n    const actions = element(\"div\", \"lux-v5-screen-actions lux-v5-project-review__actions\");\n    const add = setAction(\n      element(\"button\", \"lux-v5-button lux-v5-button--secondary\", \"Add Another Window\"),\n      \"add-window\"\n    );\n    add.type = \"button\";\n    const checkoutButton = setAction(\n      element(\"button\", \"lux-v5-button lux-v5-button--primary\", \"Proceed to Checkout\"),\n      \"review-checkout\"\n    );\n    checkoutButton.type = \"button\";\n    actions.append(add, checkoutButton);\n    dom.projectReview.append(heading, windowList, totals, notice, actions);\n    renderSidebar();\n  };\n\n  /* =====================================================================\n     30. CHECKOUT ENGINE\n     ===================================================================== */\n\n  const refreshCheckoutState = () => {\n    const enabled = projectCheckoutReady();\n    dom.checkoutConfirmation.checked = state.project.confirmed === true;\n    dom.root.querySelectorAll(\"[data-v5-project-confirmation]\").forEach(input => {\n      input.checked = state.project.confirmed === true;\n    });\n    dom.checkoutButton.disabled = !enabled;\n    dom.checkoutButton.textContent = state.ui.busy\n      ? \"Preparing Your Custom Order\u2026\"\n      : enabled\n        ? \"Proceed to Secure Checkout\"\n        : \"Confirm Project to Checkout\";\n    dom.root.querySelectorAll(\"[data-v5-action='drawer-checkout']\").forEach(button => {\n      button.disabled = !enabled;\n      button.textContent = state.ui.busy\n        ? \"Preparing Your Custom Order\u2026\"\n        : \"Proceed to Secure Checkout\";\n    });\n    dom.root.querySelectorAll(\"[data-v5-checkout-warning]\").forEach(warning => {\n      warning.textContent = projectCheckoutMessage();\n      warning.classList.toggle(\"has-error\", !enabled);\n    });\n  };\n\n  const productionCode = (windowData, index) =>\n    cleanText(\n      `V5-W${String(index + 1).padStart(2, \"0\")}-${cleanText(\n        windowData.roomName || windowData.windowName,\n        60\n      )\n        .toUpperCase()\n        .replace(/[^A-Z0-9]+/g, \"-\")\n        .replace(/^-|-$/g, \"\")}`,\n      180\n    );\n\n  const compactWindowSummary = (windowData, index) => {\n    const quote = PricingProvider.quoteWindow(windowData);\n    return cleanText(\n      [\n        `${index + 1}. ${windowData.roomName} / ${windowData.windowName}`,\n        `${windowData.widthMm}x${windowData.dropMm}mm`,\n        `Sheer: ${windowData.blackout.productTitle} / ${windowData.blackout.variantTitle} (${windowData.blackout.variantSku || \"Code unavailable\"})`,\n        `${OPTION_LABELS.heading[windowData.heading]}; ${OPTION_LABELS.supply[windowData.supply]}`,\n        `${OPTION_LABELS.opening[windowData.opening]}; ${OPTION_LABELS.fixing[windowData.fixing]}; ${OPTION_LABELS.finish[windowData.finish]}`,\n        `Pelmet: ${windowData.pelmet ? \"Yes\" : \"No\"}; Remote: ${windowData.remote ? \"Yes\" : \"No\"}`,\n        `Final: ${money(quote.finalTotal)}; Code: ${productionCode(windowData, index)}`,\n        windowData.notes ? `Notes: ${windowData.notes}` : \"\"\n      ]\n        .filter(Boolean)\n        .join(\" | \"),\n      1000\n    );\n  };\n\n  const appendManufacturingProperties = (properties, windowData, index) => {\n    const prefix = `W${String(index + 1).padStart(2, \"0\")}`;\n    const room = cleanText(windowData.roomName || \"Room not specified\", 100);\n    const windowName = cleanText(windowData.windowName || `Window ${index + 1}`, 120);\n    // Both single-layer V5 builders store the selected curtain fabric in\n    // windowData.blackout internally; this does not indicate a second layer.\n    const fabric = windowData.blackout;\n    const colour = cleanText(fabric.variantTitle || \"Not specified\", 140);\n    const sku = cleanText(fabric.variantSku || \"\", 80);\n    properties[`${prefix} Window`] = cleanText(`${room} \u00B7 ${windowName}`, 220);\n    properties[`${prefix} Reference`] = productionCode(windowData, index);\n    properties[`${prefix} Measurements`] = `Width ${windowData.widthMm} mm \u00B7 Height entered ${windowData.dropMm} mm`;\n    properties[`${prefix} Fabric`] = cleanText(fabric.productTitle, 220);\n    properties[`${prefix} Colour / Code`] = sku && !colour.includes(sku) ? `${colour} \u00B7 ${sku}` : colour;\n    properties[`${prefix} Heading`] = OPTION_LABELS.heading[windowData.heading];\n    properties[`${prefix} Opening`] = OPTION_LABELS.opening[windowData.opening];\n    properties[`${prefix} Fixing`] = OPTION_LABELS.fixing[windowData.fixing];\n    properties[`${prefix} Curtain Finish`] = OPTION_LABELS.finish[windowData.finish];\n    properties[`${prefix} Track`] = windowData.supply === \"curtain-only\"\n      ? \"Curtains only / No track supplied\"\n      : OPTION_LABELS.supply[windowData.supply];\n    if (windowData.supply !== \"curtain-only\") {\n      properties[`${prefix} Track Colour`] = OPTION_LABELS.trackColour[windowData.trackColour];\n    }\n    properties[`${prefix} Pelmet`] = windowData.pelmet ? \"Included\" : \"Not included\";\n    properties[`${prefix} Remote`] = windowData.remote ? \"Included\" : \"Not included\";\n    if (cleanText(windowData.notes)) properties[`${prefix} Notes`] = cleanText(windowData.notes, 240);\n  };\n\n  const existingV5Lines = (cart, variantId) =>\n    (cart?.items || []).filter(\n      item =>\n        idString(item.variant_id) === idString(variantId) &&\n        item.properties?.[\"_Luxworld Design Studio\"] === \"Sheer Curtain Builder\"\n    );\n\n  /**\n   * Requotes the project, replaces only the prior marked V5 cart line and\n   * redirects to Shopify checkout.\n   */\n  const checkout = async () => {\n    recalculate();\n    const quote = state.pricing.projectQuote;\n    const variantId = toNumber(config.checkout?.priceUnitVariantId);\n    if (!state.project.windows.length) return announce(\"Save at least one window before checkout.\", \"error\");\n    if (!allPlannedComplete()) return announce(\"Complete every planned window before checkout.\", \"error\");\n    if (!state.project.confirmed) {\n      return announce(\"Confirm the complete project before checkout.\", \"error\");\n    }\n    if (!quote.valid || !positive(quote.finalTotal)) return announce(PRICING_ERROR, \"error\");\n    if (!positive(variantId)) return announce(\"The Shopify checkout product is not configured.\", \"error\");\n\n    state.ui.busy = true;\n    refreshCheckoutState();\n    storage.save();\n    const rooms = new Set(state.project.windows.map(item => item.roomName));\n    const properties = {\n      \"_Luxworld Design Studio\": \"Sheer Curtain Builder\",\n      \"Order Type\": \"Custom-Made Sheer Curtains\",\n      \"Number of Windows\": String(state.project.windows.length),\n      \"Number of Rooms\": String(rooms.size),\n      \"Manufacturing Lead Time\": cleanText(config.settings.leadTime || \"Approximately 4\u20136 weeks\", 120),\n      \"Project ID\": cleanText(state.project.id, 100),\n      \"Builder Version\": VERSION,\n      \"Journey Type\": state.journey.mode === MODES.WHOLE_HOME ? \"Whole-Home Project\" : \"One Window\"\n    };\n    state.project.windows.forEach((windowData, index) => {\n      appendManufacturingProperties(properties, windowData, index);\n    });\n    properties[\"Original Project Value\"] = money(quote.originalTotal);\n    properties[\"Fabric Promotions\"] = quote.fabricPromotions ? money(quote.fabricPromotions) : \"None\";\n    properties[\"Order Promotion\"] = quote.orderDiscount ? money(quote.orderDiscount) : \"None\";\n    properties[\"Total Savings\"] = quote.savings ? money(quote.savings) : \"None\";\n    properties[\"Final Project Value\"] = money(quote.finalTotal);\n\n    try {\n      const cartResponse = await fetch(config.routes.cartJson || \"/cart.js\", {\n        headers: { Accept: \"application/json\" }\n      });\n      if (!cartResponse.ok) throw new Error(`Cart fetch failed (${cartResponse.status}).`);\n      const cart = await cartResponse.json();\n      for (const line of existingV5Lines(cart, variantId)) {\n        const removeResponse = await fetch(config.routes.cartChange || \"/cart/change.js\", {\n          method: \"POST\",\n          headers: { \"Content-Type\": \"application/json\", Accept: \"application/json\" },\n          body: JSON.stringify({ id: line.key, quantity: 0 })\n        });\n        if (!removeResponse.ok) throw new Error(\"Could not replace the previous V5 cart line.\");\n      }\n      const addResponse = await fetch(config.routes.cartAdd || \"/cart/add.js\", {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\", Accept: \"application/json\" },\n        body: JSON.stringify({\n          items: [\n            {\n              id: variantId,\n              quantity: Math.max(1, Math.ceil(quote.finalTotal)),\n              properties\n            }\n          ]\n        })\n      });\n      if (!addResponse.ok) throw new Error(`Cart add failed (${addResponse.status}).`);\n      window.location.assign(config.routes.checkout || \"/cart\");\n    } catch (error) {\n      console.error(\"[LUXWORLD DESIGN STUDIO] Checkout failed:\", error);\n      state.ui.busy = false;\n      refreshCheckoutState();\n      announce(\"Unable to prepare the secure checkout. Please try again or contact LUXWORLD.\", \"error\");\n    }\n  };\n\n  /* =====================================================================\n     31. VALIDATION\n     ===================================================================== */\n\n  const nextStage = () => {\n    const current = state.journey.stage;\n    if (current === STAGES.FABRIC_SELECTION) {\n      if (!state.draft.window.blackout.confirmed) {\n        return announce(\"Confirm your sheer fabric before continuing.\", \"error\");\n      }\n      if (state.ui.fabricReturnStage) {\n        const returnStage = state.ui.fabricReturnStage;\n        state.ui.fabricReturnStage = null;\n        routeTo(returnStage);\n        return;\n      }\n      if (state.journey.mode === MODES.WHOLE_HOME) {\n        state.project.baseDesign = {\n          sheer: deepCopy(state.draft.window.sheer),\n          blackout: deepCopy(state.draft.window.blackout)\n        };\n        state.ui.configuringBase = false;\n        const first = state.planner.plannedWindows.find(item => item.status !== STATUS.COMPLETE);\n        if (!first) return announce(\"No incomplete planned window is available.\", \"error\");\n        openPlannedWindow(first);\n      } else {\n        routeTo(STAGES.MEASUREMENTS);\n      }\n      return;\n    }\n    if (current === STAGES.MEASUREMENTS) {\n      const errors = validateMeasurements(state.draft.window);\n      if (errors.length) {\n        announce(errors[0], \"error\");\n        dom.measurementValidation.textContent = errors[0];\n        dom.measurementValidation.classList.add(\"has-error\");\n        (errors[0].startsWith(\"Track\") ? dom.width : dom.drop).focus();\n        return;\n      }\n      completeWindowAccordionStep(\"measurements\");\n      return;\n    }\n    if (current === STAGES.WINDOW_CONFIGURATION) {\n      if (state.ui.configuringBase) {\n        const draft = state.draft.window;\n        state.project.baseDesign = {\n          sheer: deepCopy(draft.sheer),\n          blackout: deepCopy(draft.blackout),\n          heading: draft.heading,\n          supply: draft.supply,\n          supplyChoice: draft.supplyChoice,\n          trackColour: draft.trackColour,\n          opening: draft.opening,\n          fixing: draft.fixing,\n          finish: draft.finish,\n          pelmet: draft.pelmet,\n          pelmetChoice: draft.pelmetChoice,\n          remote: draft.remote\n        };\n        state.ui.configuringBase = false;\n        const first = state.planner.plannedWindows.find(item => item.status !== STATUS.COMPLETE);\n        if (!first) return announce(\"No incomplete planned window is available.\", \"error\");\n        touchState();\n        openPlannedWindow(first);\n        return;\n      }\n      routeTo(STAGES.WINDOW_REVIEW);\n      return;\n    }\n    if (current === STAGES.WINDOW_REVIEW) commitWindow();\n    if (current === STAGES.PROJECT_REVIEW) {\n      if (window.matchMedia(\"(max-width: 980px)\").matches) {\n        openDrawer();\n        requestAnimationFrame(() => {\n          dom.drawerContent\n            .querySelector(\"[data-v5-project-confirmation]\")\n            ?.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n        });\n      } else {\n        dom.sidebar?.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n        dom.checkoutConfirmation?.focus();\n      }\n    }\n  };\n\n  const renderDesktopPrimaryAction = () => {\n    dom.root.querySelectorAll(\".lux-v5-generated-actions\").forEach(node => node.remove());\n    const stageNode = {\n      [STAGES.FABRIC_SELECTION]: dom.stages.fabric,\n      [STAGES.WINDOW_CONFIGURATION]: dom.stages.configuration\n    }[state.journey.stage];\n    if (!stageNode) return;\n    if (state.journey.stage === STAGES.FABRIC_SELECTION) {\n      return;\n    }\n    const labels = {\n      [STAGES.FABRIC_SELECTION]:\n        state.journey.mode === MODES.WHOLE_HOME && !state.project.baseDesign\n          ? \"Continue to Design Curtains\"\n          : \"Continue to Measurements\",\n      [STAGES.WINDOW_CONFIGURATION]: state.ui.configuringBase\n        ? \"Start Measuring Windows\"\n        : \"Review This Window\"\n    };\n    const footer = element(\"footer\", \"lux-v5-screen-actions lux-v5-generated-actions\");\n    const backLabels = {\n      [STAGES.FABRIC_SELECTION]:\n        state.journey.mode === MODES.WHOLE_HOME ? \"Back to Project Plan\" : \"Back to Journey\",\n      [STAGES.WINDOW_CONFIGURATION]: state.ui.configuringBase\n        ? \"Back to Fabrics\"\n        : \"Back to Measurements\"\n    };\n    const back = setAction(\n      element(\n        \"button\",\n        \"lux-v5-button lux-v5-button--secondary lux-v5-stage-back\",\n        backLabels[state.journey.stage]\n      ),\n      \"stage-back\"\n    );\n    back.type = \"button\";\n    const button = setAction(\n      element(\"button\", \"lux-v5-button lux-v5-button--primary\", labels[state.journey.stage]),\n      \"primary-next\"\n    );\n    button.type = \"button\";\n    button.disabled = state.ui.busy || !primaryStageReady();\n    footer.append(back, button);\n    stageNode.append(footer);\n  };\n\n  /* =====================================================================\n     32. ACCESSIBILITY\n     ===================================================================== */\n\n  const focusableSelector =\n    'a[href], button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\n  const openModal = name => {\n    const modal = dom.modals[name];\n    if (!modal) return;\n    lastFocusedElement = document.activeElement;\n    state.ui.activeModal = name;\n    modal.classList.add(\"is-open\");\n    modal.setAttribute(\"aria-hidden\", \"false\");\n    document.body.classList.add(\"lux-v5-scroll-locked\");\n    const isCompletion = name === \"confirm\" && modal.querySelector(\".lux-v5-completion\");\n    document.body.classList.toggle(\"lux-v5-completion-open\", Boolean(isCompletion));\n    if (isCompletion) {\n      document.querySelectorAll(\"a\").forEach(link => {\n        const identity = `${link.textContent || \"\"} ${link.getAttribute(\"href\") || \"\"}`.toLowerCase();\n        if (identity.includes(\"orders@luxworld.net.au\") || identity.includes(\"orders%40luxworld.net.au\")) {\n          link.classList.add(\"lux-v5-hidden-completion-email\");\n        }\n      });\n    }\n    modal.querySelector(focusableSelector)?.focus();\n  };\n\n  const closeModal = name => {\n    const modal = dom.modals[name];\n    if (!modal) return;\n    modal.classList.remove(\"is-open\");\n    modal.setAttribute(\"aria-hidden\", \"true\");\n    state.ui.activeModal = null;\n    document.body.classList.remove(\"lux-v5-completion-open\");\n    document.querySelectorAll(\".lux-v5-hidden-completion-email\").forEach(link => {\n      link.classList.remove(\"lux-v5-hidden-completion-email\");\n    });\n    if (!state.ui.mobileDrawerOpen) document.body.classList.remove(\"lux-v5-scroll-locked\");\n    lastFocusedElement?.focus?.();\n  };\n\n  const trapModalFocus = event => {\n    if (event.key !== \"Tab\") return;\n    const trapRoot = state.ui.activeModal\n      ? dom.modals[state.ui.activeModal]\n      : state.ui.mobileDrawerOpen\n        ? dom.drawer.querySelector(\".lux-v5-drawer__panel\")\n        : null;\n    if (!trapRoot) return;\n    const items = [...trapRoot.querySelectorAll(focusableSelector)];\n    if (!items.length) return;\n    const first = items[0];\n    const last = items[items.length - 1];\n    if (event.shiftKey && document.activeElement === first) {\n      event.preventDefault();\n      last.focus();\n    } else if (!event.shiftKey && document.activeElement === last) {\n      event.preventDefault();\n      first.focus();\n    }\n  };\n\n  /* =====================================================================\n     33. ERROR HANDLING\n     ===================================================================== */\n\n  const fatal = error => {\n    console.error(\"[LUXWORLD DESIGN STUDIO] Initialisation failed:\", error);\n    if (!dom || !state?.runtime) {\n      const root = document.getElementById(ROOT_ID);\n      const message = root?.querySelector(\"#luxV5FatalErrorMessage\");\n      const fatalNode = root?.querySelector(\"#luxV5FatalError\");\n      const loading = root?.querySelector(\"#luxV5Loading\");\n      if (message) message.textContent = cleanText(error.message);\n      if (fatalNode) fatalNode.hidden = false;\n      if (loading) loading.hidden = true;\n      return;\n    }\n    state.runtime.fatalError = error.message;\n    dom.fatalMessage.textContent = cleanText(error.message);\n    setHidden(dom.loading, true);\n    setHidden(dom.application, true);\n    setHidden(dom.fatal, false);\n  };\n\n  /* =====================================================================\n     34. APPLICATION INITIALISATION\n     ===================================================================== */\n\n  const renderStage = () => {\n    if (!state || !dom) return;\n    renderJourneyHeader();\n    if (state.journey.stage === STAGES.WHOLE_HOME_PLANNER) renderPlanner();\n    if (state.journey.stage === STAGES.FABRIC_SELECTION) renderFabrics();\n    if (state.journey.stage === STAGES.MEASUREMENTS) {\n      renderMeasurements();\n      renderConfiguration();\n      renderWindowReview();\n      renderWindowAccordion();\n    }\n    if (state.journey.stage === STAGES.WINDOW_CONFIGURATION) renderConfiguration();\n    if (state.journey.stage === STAGES.WINDOW_REVIEW) renderWindowReview();\n    if (state.journey.stage === STAGES.PROJECT_REVIEW) renderProjectReview();\n    renderDesktopPrimaryAction();\n    renderSidebar();\n  };\n\n  const confirmAction = (title, message, action, value) => {\n    const content = clear(dom.modalContents.confirm);\n    const heading = element(\"h2\", \"\", title);\n    heading.id = \"luxV5ConfirmModalTitle\";\n    const actions = element(\"div\", \"lux-v5-screen-actions\");\n    const cancel = setAction(\n      element(\"button\", \"lux-v5-button lux-v5-button--secondary\", \"Cancel\"),\n      \"close-confirm\"\n    );\n    cancel.type = \"button\";\n    const confirm = setAction(\n      element(\"button\", \"lux-v5-button lux-v5-button--primary\", \"Confirm\"),\n      action,\n      value\n    );\n    confirm.type = \"button\";\n    actions.append(cancel, confirm);\n    content.append(heading, element(\"p\", \"\", message), actions);\n    openModal(\"confirm\");\n  };\n\n  const openFabricDetails = (layer, kind, allowConfirmation = false) => {\n    const selection = state.draft.window[layer];\n    const collection = selectedCollection(layer);\n    const product = productFor(selection.productId);\n    const content = clear(dom.modalContents.fabric);\n    const source = kind === \"collection\" ? collection : product;\n    content.className = allowConfirmation ? \"lux-v5-fabric-confirmation\" : \"lux-v5-fabric-details\";\n    const title = element(\n      \"h2\",\n      \"\",\n      allowConfirmation\n        ? selection.variantTitle || source?.title || `${layer} fabric`\n        : source?.title || `${layer} fabric`\n    );\n    title.id = \"luxV5FabricModalTitle\";\n    const imageUrl =\n      kind === \"product\" && selection.variantImage\n        ? selection.variantImage\n        : source?.featuredImage || selection.collectionImage;\n    if (imageUrl) {\n      const image = element(\"img\");\n      image.src = imageUrl;\n      image.alt = allowConfirmation\n        ? `${selection.variantTitle} from ${selection.collectionTitle}`\n        : source?.title || \"\";\n      image.className = allowConfirmation\n        ? \"lux-v5-fabric-confirmation__image\"\n        : \"lux-v5-fabric-details__image\";\n      content.append(image);\n    }\n    content.append(title);\n    if (allowConfirmation) {\n      content.append(\n        element(\n          \"p\",\n          \"lux-v5-fabric-confirmation__subtitle\",\n          `${selection.collectionTitle}${selection.variantSku ? ` \u00B7 ${selection.variantSku}` : \"\"}`\n        )\n      );\n    } else {\n      content.append(\n        element(\n          \"p\",\n          \"\",\n          kind === \"collection\"\n            ? collection?.description || \"Collection details are not available.\"\n            : product?.specifications?.description || \"Fabric details are not available.\"\n        )\n      );\n    }\n    if (kind === \"product\" && product && !allowConfirmation) {\n      const selectionDetails = element(\"dl\", \"lux-v5-specifications\");\n      [\n        [\"Collection\", selection.collectionTitle],\n        [\"Fabric\", selection.productTitle],\n        [\"Colour\", selection.variantTitle],\n        [\"SKU\", selection.variantSku || \"Not supplied\"],\n        [\n          \"Promotion\",\n          selection.promotionPercent ? `${selection.promotionPercent}%` : \"No current promotion\"\n        ],\n        [\"Maximum drop\", `${selection.maximumDropMm || \"\u2014\"} mm`]\n      ].forEach(([term, description]) => {\n        selectionDetails.append(element(\"dt\", \"\", term), element(\"dd\", \"\", description));\n      });\n      content.append(selectionDetails);\n      const specs = element(\"dl\", \"lux-v5-specifications\");\n      [\n        [\"Composition\", product.specifications?.fabricComposition],\n        [\"Fabric width\", product.specifications?.fabricWidth],\n        [\"Maximum drop\", `${product.specifications?.maximumDropMm || \"\u2014\"} mm`]\n      ].forEach(([term, description]) => {\n        specs.append(element(\"dt\", \"\", term), element(\"dd\", \"\", description || \"\u2014\"));\n      });\n      content.append(specs);\n    }\n    if (allowConfirmation && selection.variantId) {\n      const confirmation = setAction(\n        element(\n          \"button\",\n          \"lux-v5-button lux-v5-button--primary\",\n          `Confirm ${layer === \"sheer\" ? \"Sheer\" : \"Sheer\"} \u2014 ${selection.variantTitle}`\n        ),\n        \"confirm-fabric\",\n        layer\n      );\n      confirmation.type = \"button\";\n      confirmation.textContent = \"Confirm Colour\";\n      const chooseDifferent = setAction(\n        element(\"button\", \"lux-v5-button lux-v5-button--secondary\", \"Choose Different Colour\"),\n        \"close-fabric\"\n      );\n      chooseDifferent.type = \"button\";\n      const actions = element(\"div\", \"lux-v5-fabric-confirmation__actions\");\n      actions.append(confirmation, chooseDifferent);\n      content.append(actions);\n    }\n    openModal(\"fabric\");\n  };\n\n  const handleAction = target => {\n    const action = target.dataset.v5Action;\n    const value = target.dataset.v5Value;\n    if (!action) return;\n    const [first, second] = String(value || \"\").split(\":\");\n\n    if (action === \"preset\") applyPreset(value);\n    if (action === \"toggle-optional-rooms\") {\n      state.ui.optionalRoomsExpanded = !state.ui.optionalRoomsExpanded;\n      renderPlanner();\n    }\n    if (action === \"close-fabric\") closeModal(\"fabric\");\n    if (action === \"stage-back\") {\n      if (state.journey.stage === STAGES.FABRIC_SELECTION) {\n        if (state.ui.fabricReturnStage) {\n          const returnStage = state.ui.fabricReturnStage;\n          state.ui.fabricReturnStage = null;\n          routeTo(returnStage);\n        } else {\n          routeTo(\n            state.journey.mode === MODES.WHOLE_HOME ? STAGES.WHOLE_HOME_PLANNER : STAGES.ENTRY\n          );\n        }\n      } else if (state.journey.stage === STAGES.MEASUREMENTS) {\n        const previous = adjacentPlannedWindow(-1);\n        if (state.journey.mode === MODES.WHOLE_HOME && previous) {\n          openPlannedWindow(previous);\n        } else {\n          routeTo(STAGES.FABRIC_SELECTION);\n        }\n      } else if (state.journey.stage === STAGES.WINDOW_CONFIGURATION) {\n        routeTo(state.ui.configuringBase ? STAGES.FABRIC_SELECTION : STAGES.MEASUREMENTS);\n      }\n    }\n    if (action === \"jump-window\") {\n      const planned = state.planner.plannedWindows.find(item => item.id === value);\n      if (planned && planned.id !== state.draft.window.plannedWindowId) openPlannedWindow(planned);\n    }\n    if (action === \"completion-next\") {\n      const planned = state.planner.plannedWindows.find(item => item.id === value);\n      closeModal(\"confirm\");\n      if (planned) openPlannedWindow(planned, { startFresh: true });\n    }\n    if (action === \"completion-edit\") {\n      const saved = state.project.windows.find(item => item.id === value);\n      closeModal(\"confirm\");\n      if (saved) {\n        const planned = state.planner.plannedWindows.find(item => item.savedWindowId === saved.id);\n        state.project.editingWindowId = saved.id;\n        if (planned) openPlannedWindow(planned);\n        else {\n          replaceDraft(saved);\n          routeTo(STAGES.MEASUREMENTS);\n        }\n      }\n    }\n    if (action === \"completion-review\") {\n      closeModal(\"confirm\");\n      routeTo(STAGES.PROJECT_REVIEW);\n    }\n    if (action === \"request-reset\") {\n      closeDrawer();\n      confirmAction(\n        \"Start over?\",\n        \"This will clear all your current selections and start a new design.\",\n        \"confirm-reset\"\n      );\n    }\n    if (action === \"room-plus\") {\n      addPlannedWindow(value);\n      renderPlanner();\n      touchState();\n    }\n    if (action === \"room-minus\") {\n      const candidates = roomWindows(value);\n      const item = candidates[candidates.length - 1];\n      if (item && !item.savedWindowId) {\n        state.planner.plannedWindows = state.planner.plannedWindows.filter(plan => plan.id !== item.id);\n        normalisePlan();\n        renderPlanner();\n        touchState();\n      } else if (item) {\n        announce(\"Remove the saved window from the project before reducing this room.\", \"error\");\n      }\n    }\n    if (action === \"plan-delete\") {\n      state.planner.plannedWindows = state.planner.plannedWindows.filter(item => item.id !== value);\n      normalisePlan();\n      renderPlanner();\n      touchState();\n    }\n    if (action === \"fabric-collection\") chooseCollection(first, second);\n    if (action === \"fabric-product\") chooseProduct(first, second);\n    if (action === \"fabric-variant\") chooseVariant(first, second);\n    if (action === \"review-fabric\") openFabricDetails(value, \"product\", true);\n    if (action === \"change-fabric\") {\n      invalidateDraftConfirmation();\n      state.draft.window[value].confirmed = false;\n      renderFabricProducts(value);\n      recalculate();\n      renderSidebar();\n      touchState();\n      announce(`${value === \"sheer\" ? \"Sheer\" : \"Sheer\"} fabric unlocked for changes.`);\n    }\n    if (action === \"confirm-fabric\") {\n      invalidateDraftConfirmation();\n      state.draft.window[value].confirmed = true;\n      closeModal(\"fabric\");\n      renderFabricProducts(value);\n      recalculate();\n      renderSidebar();\n      touchState();\n\n      // Continue directly to Room & Measurements after confirming the colour.\n      state.ui.fabricReturnStage = null;\n      routeTo(STAGES.MEASUREMENTS);\n      return;\n    }\n    if (action === \"fabric-details\") openFabricDetails(first, second);\n    if (action === \"change-window-fabric\") {\n      invalidateDraftConfirmation();\n      state.draft.window[value].confirmed = false;\n      state.ui.fabricReturnStage = STAGES.MEASUREMENTS;\n      routeTo(STAGES.FABRIC_SELECTION);\n      announce(\n        `Choose and confirm a new sheer fabric for this window.`\n      );\n    }\n    if (action === \"primary-next\") nextStage();\n    if (action === \"accordion-open\") openWindowAccordionStep(value);\n    if (action === \"accordion-next\") completeWindowAccordionStep(value);\n    if (action === \"select-room\") {\n      invalidateDraftConfirmation();\n      state.draft.window.roomName = value;\n      state.draft.window.roomPreset = value;\n      if (value !== \"Custom Room\") {\n        state.draft.window.windowName =\n          state.journey.mode === MODES.SINGLE\n            ? `${value} Window ${state.project.windows.filter(item => item.roomName === value).length + 1}`\n            : state.draft.window.windowName;\n        state.draft.window.displayName = state.draft.window.windowName;\n        state.draft.window.customRoomName = \"\";\n      }\n      renderRooms();\n      touchState();\n    }\n    if (action === \"option\") {\n      invalidateDraftConfirmation();\n      const group = first;\n      state.draft.window[group] = second;\n      if (group === \"supply\") {\n        state.draft.window.supplyChoice = second;\n        if (second === \"curtain-only\") {\n          state.draft.window.remote = false;\n        }\n        if (second === \"manual-double-track\") state.draft.window.remote = false;\n        if ([\"motorised-double-track\", \"led-motorised-double-track\"].includes(second)) {\n          state.draft.window.trackColour = \"white\";\n        }\n      }\n      if (group === \"pelmetChoice\") {\n        state.draft.window.pelmet = second === \"yes\";\n      }\n      renderConfiguration();\n      recalculate();\n      renderSidebar();\n      touchState();\n    }\n    if (action === \"review-back\") openWindowAccordionStep(\"notes\");\n    if (action === \"save-window\") commitWindow();\n    if (action === \"save-window-direct\") commitWindow();\n    if (action === \"edit-window\") {\n      const saved = state.project.windows.find(item => item.id === value);\n      if (!saved) return;\n      state.project.editingWindowId = saved.id;\n      const planned = state.planner.plannedWindows.find(item => item.savedWindowId === saved.id);\n      if (planned) {\n        openPlannedWindow(planned);\n      } else {\n        replaceDraft(saved);\n        state.draft.window.confirmation = false;\n        routeTo(STAGES.MEASUREMENTS);\n      }\n      closeDrawer();\n    }\n    if (action === \"duplicate-window\") {\n      const source = state.project.windows.find(item => item.id === value);\n      if (source) {\n        const duplicate = deepCopy(source);\n        duplicate.id = uid(\"window\");\n        duplicate.windowName = `${source.windowName} Copy`;\n        duplicate.displayName = duplicate.windowName;\n        duplicate.confirmation = true;\n        duplicate.updatedAt = new Date().toISOString();\n        state.project.windows.push(duplicate);\n        if (state.journey.mode === MODES.WHOLE_HOME) {\n          state.planner.plannedWindows.push({\n            id: uid(\"planned\"),\n            roomName: duplicate.roomName,\n            customRoomName: null,\n            windowName: duplicate.windowName,\n            sequence: roomWindows(duplicate.roomName).length + 1,\n            status: STATUS.COMPLETE,\n            savedWindowId: duplicate.id,\n            widthMm: duplicate.widthMm,\n            dropMm: duplicate.dropMm,\n            draftWindow: null\n          });\n          normalisePlan();\n        }\n        recalculate();\n        renderStage();\n        touchState();\n        announce(`${duplicate.windowName} added to your project.`);\n      }\n    }\n    if (action === \"remove-window\") {\n      closeDrawer();\n      confirmAction(\n        \"Remove this window?\",\n        \"This removes the saved window and its price from your project.\",\n        \"confirm-remove-window\",\n        value\n      );\n    }\n    if (action === \"confirm-remove-window\") {\n      state.project.windows = state.project.windows.filter(item => item.id !== value);\n      state.project.confirmed = false;\n      if (state.project.editingWindowId === value) state.project.editingWindowId = null;\n      const planned = state.planner.plannedWindows.find(item => item.savedWindowId === value);\n      if (planned) {\n        planned.savedWindowId = null;\n        planned.status = STATUS.PLANNED;\n        planned.widthMm = 0;\n        planned.dropMm = 0;\n      }\n      closeModal(\"confirm\");\n      recalculate();\n      renderStage();\n      touchState();\n      announce(\"Window removed.\");\n    }\n    if (action === \"add-window\") startAdditionalWindow();\n    if (action === \"review-checkout\") nextStage();\n    if (action === \"drawer-checkout\") checkout();\n    if (action === \"close-confirm\") closeModal(\"confirm\");\n    if (action === \"confirm-reset\") {\n      closeModal(\"confirm\");\n      resetProject();\n    }\n  };\n\n  const bindEvents = () => {\n    dom.root.addEventListener(\"click\", event => {\n      const journey = event.target.closest(\"[data-v5-select-journey]\");\n      if (journey) return selectJourney(journey.dataset.v5SelectJourney);\n      if (event.target.closest(\"[data-v5-back-entry], [data-v5-change-journey]\")) {\n        return confirmAction(\n          \"Change your design journey?\",\n          \"This will clear all your current selections and start a new design journey.\",\n          \"confirm-reset\"\n        );\n      }\n      if (event.target.closest(\"[data-v5-close-drawer]\")) return closeDrawer();\n      const close = event.target.closest(\"[data-v5-close-modal]\");\n      if (close) return closeModal(close.dataset.v5CloseModal);\n      const actionTarget = event.target.closest(\"[data-v5-action]\");\n      if (actionTarget) {\n        event.preventDefault();\n        handleAction(actionTarget);\n      }\n    });\n\n    dom.root.addEventListener(\"input\", event => {\n      if (event.target.matches(\"[data-v5-plan-name]\")) {\n        const item = state.planner.plannedWindows.find(\n          plan => plan.id === event.target.dataset.v5PlanName\n        );\n        if (item) item.windowName = cleanText(event.target.value, 80);\n        touchState();\n      }\n      if (event.target.matches(\"[data-v5-plan-room]\")) {\n        const item = state.planner.plannedWindows.find(\n          plan => plan.id === event.target.dataset.v5PlanRoom\n        );\n        if (item) item.customRoomName = cleanText(event.target.value, 60);\n        touchState();\n      }\n      if (event.target === dom.width || event.target === dom.drop) {\n        invalidateDraftConfirmation();\n        const field = event.target === dom.width ? \"widthMm\" : \"dropMm\";\n        state.draft.window[field] = Math.max(0, toNumber(event.target.value));\n        debounceInputPricing();\n        touchState();\n      }\n      if (event.target === dom.customRoom) {\n        invalidateDraftConfirmation();\n        state.draft.window.windowName = cleanText(event.target.value, 80);\n        state.draft.window.displayName = state.draft.window.windowName;\n        state.draft.window.customRoomName = state.draft.window.windowName;\n        touchState();\n      }\n      if (event.target.dataset.v5Field === \"notes\") {\n        invalidateDraftConfirmation();\n        state.draft.window.notes = cleanText(event.target.value, 500);\n        touchState();\n      }\n    });\n\n    dom.root.addEventListener(\"change\", event => {\n      if (event.target.hasAttribute(\"data-v5-room-select\")) {\n        const room = cleanText(event.target.value, 60);\n        invalidateDraftConfirmation();\n        state.draft.window.roomName = room;\n        state.draft.window.roomPreset = room;\n        if (room !== \"Custom Room\" && state.journey.mode === MODES.SINGLE) {\n          state.draft.window.windowName = `${room} Window ${\n            state.project.windows.filter(item => item.roomName === room).length + 1\n          }`;\n          state.draft.window.displayName = state.draft.window.windowName;\n          dom.customRoom.value = state.draft.window.windowName;\n        }\n        renderWindowAccordion();\n        renderSidebar();\n        touchState();\n      }\n      if (event.target.dataset.v5Field === \"window-confirmation\") {\n        state.draft.window.confirmation = event.target.checked;\n        dom.root\n          .querySelectorAll(\n            \"[data-v5-action='save-window'], [data-v5-action='save-window-direct']\"\n          )\n          .forEach(save => {\n            save.disabled =\n            validateWindow(state.draft.window).length > 0 ||\n            state.draft.window.confirmation !== true;\n          });\n        touchState();\n      }\n      if (event.target.dataset.v5Field === \"remote\") {\n        invalidateDraftConfirmation();\n        state.draft.window.remote = event.target.checked;\n        recalculate();\n        renderSidebar();\n        touchState();\n      }\n      if (event.target.dataset.v5Field === \"pelmet\") {\n        invalidateDraftConfirmation();\n        state.draft.window.pelmet = event.target.checked;\n        recalculate();\n        renderSidebar();\n        touchState();\n      }\n      if (\n        event.target === dom.checkoutConfirmation ||\n        event.target.hasAttribute(\"data-v5-project-confirmation\")\n      ) {\n        state.project.confirmed = event.target.checked;\n        refreshCheckoutState();\n        state.timestamps.updatedAt = new Date().toISOString();\n        storage.save();\n      }\n    });\n\n    dom.beginWholeHome.addEventListener(\"click\", beginWholeHome);\n    dom.mobilePrimary.addEventListener(\"click\", nextStage);\n    dom.mobileProject.addEventListener(\"click\", openDrawer);\n    dom.root.querySelector(\"#luxV5OpenProject\")?.addEventListener(\"click\", openDrawer);\n    dom.addWindow?.addEventListener(\"click\", startAdditionalWindow);\n    dom.checkoutButton.addEventListener(\"click\", checkout);\n    dom.clearProject.addEventListener(\"click\", () =>\n      confirmAction(\n        \"Start over?\",\n        \"This will clear all your current selections and start a new design.\",\n        \"confirm-reset\"\n      )\n    );\n\n    document.addEventListener(\"keydown\", event => {\n      if (event.key === \"Escape\") {\n        if (state.ui.activeModal) closeModal(state.ui.activeModal);\n        else if (state.ui.mobileDrawerOpen) closeDrawer();\n      }\n      trapModalFocus(event);\n    });\n  };\n\n  /**\n   * Starts the V5 application when its Liquid root and Shopify data are present.\n   * Repeated calls are safe.\n   */\n  const initialise = () => {\n    if (initialised) return;\n    const root = document.getElementById(ROOT_ID);\n    if (\n      !root ||\n      !(\n        root.hasAttribute(\"data-lux-sheer-v5\") ||\n        root.hasAttribute(\"data-lux-double-v5\")\n      )\n    ) return;\n    initialised = true;\n    try {\n      dom = createDomRegistry(root);\n      config = readShopifyData();\n      const requestedMode = new URLSearchParams(window.location.search)\n        .get(\"mode\")\n        ?.toLowerCase();\n      if (requestedMode === \"sheer\") {\n        config.selectedSystem = \"sheer\";\n        config.settings = { ...(config.settings || {}), selectedSystem: \"sheer\" };\n        root.dataset.selectedSystem = \"sheer\";\n      }\n      catalog = normaliseCatalog(config);\n      if (config.settings.legacyFallbackActive === true) {\n        console.warn(\"[LUXWORLD DESIGN STUDIO] Shopify catalog is using the temporary legacy fallback.\");\n      }\n      pricingProvider =\n        config.checkout?.securePricingMode === true\n          ? SecureApiPricingProvider\n          : LocalShopifyPricingProvider;\n      state = createState();\n      attachCatalogState(state);\n      const restored = storage.load();\n      if (restored) {\n        state = restored;\n        state.runtime = { initialised: true, loading: false, fatalError: null };\n      }\n      initialiseWindowAccordion();\n      bindEvents();\n      recalculate();\n      setHidden(dom.loading, true);\n      setHidden(dom.fatal, true);\n      setHidden(dom.application, false);\n      state.runtime.initialised = true;\n      state.runtime.loading = false;\n      routeTo(state.journey.stage || STAGES.ENTRY, { scroll: false });\n      if (state.journey.stage === STAGES.ENTRY) {\n        setHidden(dom.journeyHeader, true);\n        setHidden(dom.workspace, true);\n        setHidden(dom.mobileBar, true);\n      }\n      renderStage();\n      if (!positive(config.checkout?.priceUnitVariantId)) {\n        announce(\n          \"Design Studio is ready, but checkout is unavailable until the Shopify price-unit variant is configured.\",\n          \"error\"\n        );\n      } else if (config.checkout?.securePricingMode === true) {\n        announce(\n          \"Secure pricing is enabled but its verified quote integration is not configured.\",\n          \"error\"\n        );\n      }\n    } catch (error) {\n      fatal(error);\n    }\n  };\n\n  const resetProject = () => {\n    storage.clear();\n    state = createState();\n    attachCatalogState(state);\n    state.runtime = { initialised: true, loading: false, fatalError: null };\n    recalculate();\n    setHidden(dom.entry, false);\n    setHidden(dom.planner, true);\n    setHidden(dom.workspace, true);\n    setHidden(dom.journeyHeader, true);\n    setHidden(dom.mobileBar, true);\n    closeDrawer();\n    Object.keys(dom.modals).forEach(name => closeModal(name));\n    document.body.classList.remove(\"lux-v5-scroll-locked\");\n\n  };\n\n  /* =====================================================================\n     35. PUBLIC API\n     ===================================================================== */\n\n  window.LuxDoubleStudioV5 = Object.freeze({\n    version: VERSION,\n    initialise,\n    getState: () => deepCopy(state),\n    calculateDraft: () =>\n      state && pricingProvider ? deepCopy(PricingProvider.quoteWindow(state.draft.window)) : null,\n    calculateProject: () =>\n      state && pricingProvider ? deepCopy(PricingProvider.quoteProject(state.project)) : null,\n    resetProject\n  });\n\n  if (document.readyState === \"loading\") {\n    document.addEventListener(\"DOMContentLoaded\", initialise, { once: true });\n  } else {\n    initialise();\n  }\n})();\n;(() => {\n  const syncSheerWindowConfirmation = () => {\n    const confirmations = Array.from(document.querySelectorAll('[data-v5-field=\"window-confirmation\"]'));\n    const visibleConfirmation = confirmations.find((input) => input.offsetParent !== null) || confirmations[confirmations.length - 1];\n    const saveButton = document.querySelector('[data-v5-action=\"save-window-direct\"]');\n    if (saveButton && visibleConfirmation) {\n      saveButton.disabled = !visibleConfirmation.checked;\n    }\n  };\n\n  document.addEventListener('change', (event) => {\n    if (event.target.matches('[data-v5-field=\"window-confirmation\"]')) {\n      syncSheerWindowConfirmation();\n    }\n  });\n  document.addEventListener('click', () => setTimeout(syncSheerWindowConfirmation, 0));\n})();\n"],
  "mappings": "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",
  "names": ["copy", "product"]
}
