{
  "version": 3,
  "sources": ["/cdn/shop/t/8/assets/trh-cushion-calculator.js?cb=20260501b"],
  "sourcesContent": ["/**\n * TRH Cushion Calculator - Browser Module\n * =========================================================================\n * Manages the cushion calculator form, price calculation, yardage,\n * and add-to-cart flow via /cart/add.js ($1 variant x dollar amount,\n * same pattern as drapery).\n *\n * Dependencies:\n *   - window.TRHFabricBrowser (shared fabric/trim selection module)\n *\n * Exposes:\n *   - window.TRHCushionCalculator.init(config)\n *   - window.TRHCushionCalculator.setBrowseTarget(target)\n *\n * @module TRHCushionCalculator\n * @version 2.0.0\n */\n(function () {\n  'use strict';\n\n  // -------------------------------------------------------------------------\n  // Constants \u2014 must mirror api/lib/cushion-calculator.js EXACTLY\n  // -------------------------------------------------------------------------\n\n  var LOG_PREFIX = '[TRHCushionCalc]';\n\n  /** Fill pricing per square inch, keyed by thickness (1-8). */\n  var FILL_RATES = {\n    1: { foam: 0.08, foamFeather: 0.15, feather: 0.19, outdoor: 0.15 },\n    2: { foam: 0.10, foamFeather: 0.18, feather: 0.22, outdoor: 0.17 },\n    3: { foam: 0.12, foamFeather: 0.20, feather: 0.25, outdoor: 0.20 },\n    4: { foam: 0.14, foamFeather: 0.22, feather: 0.28, outdoor: 0.22 },\n    5: { foam: 0.17, foamFeather: 0.26, feather: 0.31, outdoor: 0.26 },\n    6: { foam: 0.19, foamFeather: 0.27, feather: 0.34, outdoor: 0.29 },\n    7: { foam: 0.21, foamFeather: 0.31, feather: 0.37, outdoor: 0.31 },\n    8: { foam: 0.23, foamFeather: 0.33, feather: 0.40, outdoor: 0.33 }\n  };\n\n  var FILL_TYPE_MAP = {\n    'Foam - Soft':              'foam',\n    'Foam - Medium':            'foam',\n    'Foam - Firm':              'foam',\n    'Feather & Foam - Soft':    'foamFeather',\n    'Feather & Foam - Medium':  'foamFeather',\n    'Feather & Foam - Firm':    'foamFeather',\n    'Feather Only':             'feather',\n    'Outdoor':                  'outdoor'\n  };\n\n  /**\n   * Cover-only option: the customer buys just the sewn cover with no\n   * foam/fill insert, so the fill component of the price is $0.\n   * Must match api/lib/cushion-calculator.js NO_FILL_OPTION exactly.\n   */\n  var NO_FILL_OPTION = 'No Fill (Cover Only)';\n\n  var SEW_MULTIPLIERS = {\n    'No Band, No Welt':   1,\n    'No Band with Welt':  1.5,\n    'Band, No Welt':      2,\n    'Band with Welt':     2.5\n  };\n\n  var TUFTING_PRICE_PER_BUTTON = 10;\n  var DEFAULT_FABRIC_WIDTH = 54;\n  var SEAM_ALLOWANCE = 1;\n  var MIN_FABRIC_YARDS = 3; /* default only; per-fabric minimum comes from _FM() */\n  var MIN_TRIM_YARDS = 5;\n  var MIN_CONTRAST_YARDS = 3;\n\n  var REPEAT_CHART = [\n    [0,  0],\n    [14, 0.10],\n    [19, 0.15],\n    [27, 0.20],\n    [36, 0.25],\n    [45, 0.30],\n    [54, 0.35]\n  ];\n\n  var YARDAGE_NOTE = 'Yardage is based on standard 54\\u201d wide fabric and is sold in whole yards. Some fabrics and trims have their own minimum order, shown when you select them. If you have questions about a specific fabric\\u2019s width or repeat, please reach out.';\n\n  /* TRH yardage note 2026-10-26 (Rachel t360u): short, accurate note; names the selected fabric's / trim's own minimum (TRHFabricMin + trimMinYards) */\n  function yardageNote(noStoreFabric) {\n    var storeFabric = !noStoreFabric && !_ownFabric && _selectedFabric;\n    var unitWord = (storeFabric && _FM().info(_selectedFabric).unit === 'meter') ? 'meters' : 'yards';\n    var parts = [_ownFabric ? 'Yardage is based on standard 54\\u201d wide fabric.' : 'Yardage is based on standard 54\\u201d wide fabric and is sold in whole ' + unitWord + '.'];\n    var named = false;\n    if (storeFabric) {\n      var fMin = _FM().info(_selectedFabric).min;\n      if (fMin > 1) { parts.push('This fabric has a minimum order of ' + _FM().label(fMin, _selectedFabric) + '.'); named = true; }\n    }\n    if (_selectedTrim && !_ownTrim && trimMinYards(_selectedTrim) > 1) {\n      parts.push('This trim has a minimum order of ' + trimMinYards(_selectedTrim) + ' yards.'); named = true;\n    }\n    if (!named && !storeFabric) parts.push('Some fabrics and trims have their own minimum order, shown when you select them.');\n    parts.push('If you have questions about a specific fabric\\u2019s width or repeat, please reach out.');\n    return parts.join(' ');\n  }\n\n  /* TRH fabric min fix 2026-10-26: per-fabric minimum + unit (see TRHFabricMin in trh-fabric-browser.js) */\n  function _FM() {\n    return window.TRHFabricMin || {\n      qty: function (y) { return Math.max(Math.ceil(y), 1); },\n      info: function () { return { min: 1, unit: 'yard' }; },\n      label: function (n) { return n + ' yards'; },\n      abbr: function () { return 'yd'; },\n      per: function () { return '/yd'; }\n    };\n  }\n\n  // -------------------------------------------------------------------------\n  // Module state\n  // -------------------------------------------------------------------------\n\n  var _config = null;\n  var _selectedFabric = null;\n  var _selectedTrim = null;\n  var _selectedContrast = null;\n  var _ownFabric = false;\n  var _ownTrim = false;\n  var _ownContrast = false;\n  var _isSubmitting = false;\n  var _boundListeners = [];\n  /** Tracks which target a catalog browse is for: 'fabric' or 'contrast'. */\n  var _browseTarget = 'fabric';\n  /** Selected photo files for reference upload. */\n  var _photoFiles = [];\n\n  // -------------------------------------------------------------------------\n  // DOM helper\n  // -------------------------------------------------------------------------\n\n  function $(id) { return document.getElementById(id); }\n\n  function roundTo(value, decimals) {\n    var factor = Math.pow(10, decimals);\n    return Math.round(value * factor) / factor;\n  }\n\n  // -------------------------------------------------------------------------\n  // Pricing calculations (mirror server-side EXACTLY)\n  // -------------------------------------------------------------------------\n\n  function calculateFillPrice(length, width, thickness, fillType) {\n    /* Cover-only: no foam/fill insert, so no fill charge. */\n    if (fillType === NO_FILL_OPTION) return 0;\n    var t = Math.min(Math.max(Math.round(thickness), 1), 8);\n    var rateKey = FILL_TYPE_MAP[fillType];\n    if (!rateKey) return 0;\n    var rates = FILL_RATES[t];\n    if (!rates) return 0;\n    var rate = rates[rateKey];\n    if (rate == null) return 0;\n    return Math.ceil(length * width * rate);\n  }\n\n  function calculateSewPrice(length, width, edgeFinish) {\n    var m = SEW_MULTIPLIERS[edgeFinish];\n    if (m == null) return 0;\n    return Math.ceil((length + width) * m);\n  }\n\n  function calculateButtonCount(tuftingType, spacing, length, width) {\n    if (!tuftingType || tuftingType === 'No Tufting' || !spacing || spacing <= 0) return 0;\n    var bL = Math.ceil((length - spacing) / spacing) + 1;\n    var bW = Math.ceil((width - spacing) / spacing) + 1;\n    var straight = bL * bW;\n    if (tuftingType.indexOf('Diamond') !== -1) {\n      return straight + (bL - 1) * (bW - 1);\n    }\n    return straight;\n  }\n\n  function calculateBoxCushionYardage(length, width, thickness, fabricWidth) {\n    var sa = SEAM_ALLOWANCE;\n    var L = Math.max(length, width);\n    var W = Math.min(length, width);\n    var plateL = L + sa;\n    var plateW = W + sa;\n    var boxingW = thickness + sa;\n    var boxingPerimeter = 2 * (L + W) + 4;\n\n    var plateFabricInches;\n    if (2 * plateW <= fabricWidth) {\n      plateFabricInches = plateL;\n    } else {\n      plateFabricInches = 2 * plateL;\n    }\n\n    var platesAcross = (2 * plateW <= fabricWidth) ? 2 : 1;\n    var remainingW = fabricWidth - (platesAcross * plateW);\n    var boxingFabricInches;\n\n    if (remainingW >= boxingW) {\n      var stripsNextToPlates = Math.floor(remainingW / boxingW);\n      var boxingLengthFromPlates = stripsNextToPlates * plateFabricInches;\n      if (boxingLengthFromPlates >= boxingPerimeter) {\n        boxingFabricInches = 0;\n      } else {\n        var remainingBoxing = boxingPerimeter - boxingLengthFromPlates;\n        var additionalStrips = Math.ceil(remainingBoxing / fabricWidth);\n        boxingFabricInches = additionalStrips * boxingW;\n      }\n    } else {\n      var strips = Math.ceil(boxingPerimeter / fabricWidth);\n      boxingFabricInches = strips * boxingW;\n    }\n\n    return (plateFabricInches + boxingFabricInches) / 36;\n  }\n\n  function calculateTrimYardage(edgeFinish, length, width) {\n    var totalInches;\n    if (edgeFinish === 'No Band with Welt') {\n      totalInches = (length * 2) + (width * 2);\n    } else if (edgeFinish === 'Band with Welt') {\n      totalInches = (length * 4) + (width * 4);\n    } else {\n      return 0;\n    }\n    return Math.ceil(totalInches / 36);\n  }\n\n  function calculateContrastYardage(edgeFinish, length, width) {\n    var totalInches;\n    if (edgeFinish === 'No Band with Welt') {\n      totalInches = (length * 2) + (width * 2);\n    } else if (edgeFinish === 'Band with Welt') {\n      totalInches = (length * 4) + (width * 4);\n    } else {\n      return 0;\n    }\n    var yards = totalInches / 700;\n    return Math.round(yards * 4) / 4;\n  }\n\n  function getRepeatAdjustment(combinedRepeat) {\n    if (!combinedRepeat || combinedRepeat <= 0) return 0;\n    for (var i = REPEAT_CHART.length - 1; i >= 0; i--) {\n      if (combinedRepeat > (i === 0 ? 0 : REPEAT_CHART[i - 1][0])) {\n        return REPEAT_CHART[i][1];\n      }\n    }\n    return 0;\n  }\n\n  /* TRH trim min 2026-10-26 (Rachel): only The ReBorn House (TRH) trims have the 5 yd minimum; other\n     brands' trims have none (sold by the yard, 1+; a min-N tag on a trim still applies) */\n  function trimMinYards(t) {\n    if (!t) return 1;\n    var n = 0;\n    (t.tags || []).forEach(function (x) { x = String(x).toLowerCase(); if (x.slice(0, 4) === 'min-') { var v = parseInt(x.slice(4), 10); if (v > n) n = v; } });\n    if (t.vendor === 'The ReBorn House' || /^TRH\\d/i.test(String(t.title || ''))) return Math.max(5, n);\n    return n > 1 ? n : 1;\n  }\n  function applyMinimum(yards, type) {\n    var ceiled = Math.ceil(yards);\n    if (type === 'trim') return Math.max(ceiled, trimMinYards(_selectedTrim));\n    if (type === 'contrast') return Math.max(ceiled, MIN_CONTRAST_YARDS);\n    return Math.max(ceiled, MIN_FABRIC_YARDS);\n  }\n\n  // -------------------------------------------------------------------------\n  // Full calculation (mirrors server calculateCushionPrice)\n  // -------------------------------------------------------------------------\n\n  function calculateAll() {\n    var length = parseFloat(($('cushion-length') || {}).value) || 0;\n    var width = parseFloat(($('cushion-width') || {}).value) || 0;\n    var thickness = parseFloat(($('cushion-thickness') || {}).value) || 0;\n    var edgeFinish = ($('cushion-edge') || {}).value || '';\n    var fillType = ($('cushion-fill') || {}).value || '';\n    var tuftingType = ($('cushion-tufting') || {}).value || 'No Tufting';\n    var tuftingSpacing = parseFloat(($('cushion-tufting-spacing') || {}).value) || 0;\n    var quantity = parseInt(($('cushion-quantity') || {}).value, 10) || 1;\n    var fabricWidth = parseFloat(($('cushion-fabric-width') || {}).value) || DEFAULT_FABRIC_WIDTH;\n\n    if (length <= 0 || width <= 0 || thickness <= 0 || !edgeFinish || !fillType) {\n      return null;\n    }\n\n    thickness = Math.min(thickness, 8);\n\n    var verticalRepeat = 0;\n    var horizontalRepeat = 0;\n    if (_selectedFabric) {\n      verticalRepeat = _selectedFabric.verticalRepeat || 0;\n      horizontalRepeat = _selectedFabric.horizontalRepeat || 0;\n    }\n\n    // Determine welt type\n    var weltType = '';\n    var weltSelect = $('cushion-welt');\n    var weltSection = $('cushion-welt-section');\n    if (weltSection && weltSection.style.display !== 'none' && weltSelect) {\n      weltType = weltSelect.value || '';\n    }\n\n    // Pricing\n    var fillPrice = calculateFillPrice(length, width, thickness, fillType);\n    var sewPrice = calculateSewPrice(length, width, edgeFinish);\n    var buttonCount = calculateButtonCount(tuftingType, tuftingSpacing, length, width);\n    var tuftingPrice = buttonCount * TUFTING_PRICE_PER_BUTTON;\n    var perCushionPrice = sewPrice + fillPrice + tuftingPrice;\n\n    // Yardage\n    var baseYardage = calculateBoxCushionYardage(length, width, thickness, fabricWidth);\n    var tuftingYardageAdj = (tuftingType !== 'No Tufting' && tuftingSpacing > 0)\n      ? Math.ceil(length / 36)\n      : 0;\n    var combinedRepeat = verticalRepeat + horizontalRepeat;\n    var repeatPct = getRepeatAdjustment(combinedRepeat);\n    var adjustedYardage = baseYardage * (1 + repeatPct) + tuftingYardageAdj;\n    var totalFabricYardage = Math.ceil(adjustedYardage * quantity);\n    var fabricYardsFinal = _ownFabric ? totalFabricYardage : _FM().qty(adjustedYardage * quantity, _selectedFabric);\n\n    // Trim yardage\n    var trimYards = 0;\n    if (weltType === 'Trim') {\n      trimYards = Math.ceil(calculateTrimYardage(edgeFinish, length, width) * quantity);\n      if (!_ownTrim) trimYards = Math.max(trimYards, trimMinYards(_selectedTrim));\n    }\n\n    // Contrast yardage\n    var contrastYards = 0;\n    if (weltType === 'Contrast Fabric Welt') {\n      contrastYards = calculateContrastYardage(edgeFinish, length, width) * quantity;\n      contrastYards = Math.round(contrastYards * 4) / 4;\n      contrastYards = _ownContrast ? Math.ceil(contrastYards) : _FM().qty(contrastYards, _selectedContrast);\n    }\n\n    // Material costs\n    var fabricPrice = (_selectedFabric && !_ownFabric) ? _selectedFabric.price : 0;\n    var fabricCost = (fabricPrice > 0) ? Math.ceil(fabricYardsFinal * fabricPrice) : 0;\n\n    var trimPrice = (_selectedTrim && !_ownTrim) ? _selectedTrim.price : 0;\n    var trimCost = (trimPrice > 0 && trimYards > 0) ? Math.ceil(trimYards * trimPrice) : 0;\n\n    var contrastPrice = (_selectedContrast && !_ownContrast) ? _selectedContrast.price : 0;\n    var contrastCost = (contrastPrice > 0 && contrastYards > 0) ? Math.ceil(contrastYards * contrastPrice) : 0;\n\n    var cushionTotal = perCushionPrice * quantity;\n    var total = cushionTotal + fabricCost + trimCost + contrastCost;\n\n    return {\n      total: total,\n      breakdown: {\n        sewPrice: sewPrice,\n        fillPrice: fillPrice,\n        tuftingPrice: tuftingPrice,\n        buttonCount: buttonCount,\n        perCushionPrice: perCushionPrice,\n        cushionTotal: cushionTotal,\n        fabricCost: fabricCost,\n        trimCost: trimCost,\n        contrastCost: contrastCost\n      },\n      yardage: {\n        baseYardage: roundTo(baseYardage, 2),\n        tuftingYardageAdj: tuftingYardageAdj,\n        repeatPct: repeatPct,\n        fabricYardsFinal: fabricYardsFinal,\n        trimYards: trimYards,\n        contrastYards: contrastYards\n      },\n      inputs: {\n        length: length,\n        width: width,\n        thickness: thickness,\n        edgeFinish: edgeFinish,\n        fillType: fillType,\n        tuftingType: tuftingType,\n        tuftingSpacing: tuftingSpacing,\n        quantity: quantity,\n        fabricWidth: fabricWidth,\n        weltType: weltType\n      }\n    };\n  }\n\n  // -------------------------------------------------------------------------\n  // UI update functions\n  // -------------------------------------------------------------------------\n\n  function updateConditionalUI() {\n    var edgeSelect = $('cushion-edge');\n    var weltSection = $('cushion-welt-section');\n    var weltSelect = $('cushion-welt');\n    var trimSection = $('cushion-trim-section');\n    var contrastSection = $('cushion-contrast-section');\n\n    if (!edgeSelect) return;\n\n    var showWelt = (edgeSelect.value === 'No Band with Welt' || edgeSelect.value === 'Band with Welt');\n    if (weltSection) weltSection.style.display = showWelt ? '' : 'none';\n\n    var needsTrim = false;\n    var needsContrast = false;\n    if (showWelt && weltSelect && weltSelect.value) {\n      needsTrim = (weltSelect.value === 'Trim');\n      needsContrast = (weltSelect.value === 'Contrast Fabric Welt');\n    }\n\n    if (trimSection) trimSection.style.display = needsTrim ? '' : 'none';\n    if (contrastSection) contrastSection.style.display = needsContrast ? '' : 'none';\n\n    // Tufting spacing\n    var tuftingSelect = $('cushion-tufting');\n    var spacingSection = $('cushion-tufting-spacing-section');\n    if (tuftingSelect && spacingSection) {\n      var showSpacing = (tuftingSelect.value && tuftingSelect.value !== 'No Tufting');\n      spacingSection.style.display = showSpacing ? '' : 'none';\n    }\n\n    updateCalculation();\n  }\n\n  function updateCalculation() {\n    var result = calculateAll();\n    updateYardageDisplay(result);\n    updatePricingDisplay(result);\n  }\n\n  function updateYardageDisplay(result) {\n    var el = $('cushion-yardage-display');\n    if (!el) return;\n\n    if (!result) {\n      el.innerHTML = '';\n      el.style.display = 'none';\n      return;\n    }\n\n    var lines = [];\n    var y = result.yardage;\n\n    // Main fabric\n    if (_ownFabric) {\n      lines.push('<p><strong>Fabric Required:</strong> ' + y.fabricYardsFinal + ' yards</p>');\n    } else {\n      var fabricMin = _FM().info(_selectedFabric).min;\n      var fabricNote = fabricMin > 1 && y.fabricYardsFinal <= fabricMin\n        ? ' <span style=\"color:#888;font-size:12px;\">(min ' + fabricMin + ' ' + _FM().abbr(_selectedFabric) + ' order)</span>'\n        : '';\n      lines.push('<p><strong>Fabric Required:</strong> ' + _FM().label(y.fabricYardsFinal, _selectedFabric) + fabricNote + '</p>');\n    }\n\n    // Seam note\n    var fabricWidth = parseFloat(($('cushion-fabric-width') || {}).value) || DEFAULT_FABRIC_WIDTH;\n    var length = result.inputs.length;\n    if (length > fabricWidth) {\n      lines.push('<p style=\"color:#b35900;font-size:12px;font-style:italic;\">If your cushion length exceeds the width of your selected fabric, your cushion will require a seam. Please allow a few extra inches of fabric for seam allowance.</p>');\n    }\n\n    // Trim\n    if (y.trimYards > 0) {\n      var trimNote = '';\n      if (!_ownTrim && trimMinYards(_selectedTrim) > 1 && y.trimYards <= trimMinYards(_selectedTrim)) {\n        trimNote = ' <span style=\"color:#888;font-size:12px;\">(min ' + trimMinYards(_selectedTrim) + ' yd order)</span>';\n      }\n      lines.push('<p><strong>Trim Required:</strong> ' + y.trimYards + ' yards' + trimNote + '</p>');\n    }\n\n    // Contrast\n    if (y.contrastYards > 0) {\n      var contrastNote = '';\n      var contrastMin = _FM().info(_selectedContrast).min;\n      if (!_ownContrast && contrastMin > 1 && y.contrastYards <= contrastMin) {\n        contrastNote = ' <span style=\"color:#888;font-size:12px;\">(min ' + contrastMin + ' ' + _FM().abbr(_selectedContrast) + ' order)</span>';\n      }\n      lines.push('<p><strong>Contrast Fabric Required:</strong> ' + (_ownContrast ? y.contrastYards + ' yards' : _FM().label(y.contrastYards, _selectedContrast)) + contrastNote + '</p>');\n    }\n\n    // Tufting info\n    if (result.breakdown.buttonCount > 0) {\n      lines.push('<p><strong>Tufting Buttons:</strong> ' + result.breakdown.buttonCount + ' buttons</p>');\n    }\n\n    lines.push('<p style=\"margin-top:6px;font-size:11px;color:#888;font-style:italic;\">' + yardageNote() + '</p>');\n\n    el.innerHTML = lines.join('');\n    el.style.display = 'block';\n  }\n\n  function updatePricingDisplay(result) {\n    var el = $('cushion-pricing-display');\n    if (!el) return;\n\n    if (!result) {\n      el.style.display = 'none';\n      return;\n    }\n\n    var b = result.breakdown;\n    var rows = [];\n\n    // Cushion base\n    if (result.inputs.quantity > 1) {\n      rows.push(pricingRow('Cushion (sew + fill' + (b.tuftingPrice > 0 ? ' + tufting' : '') + ') \\u00d7 ' + result.inputs.quantity, b.cushionTotal));\n    } else {\n      rows.push(pricingRow('Cushion (sew + fill' + (b.tuftingPrice > 0 ? ' + tufting' : '') + ')', b.cushionTotal));\n    }\n\n    // Fabric\n    if (_ownFabric) {\n      rows.push('<div class=\"cushion-pricing-row\"><span>Fabric (COM / Off-Site)</span><span>excluded</span></div>');\n    } else if (_selectedFabric && b.fabricCost > 0) {\n      rows.push(pricingRow(\n        escapeHTML(_selectedFabric.title) + ' (' + result.yardage.fabricYardsFinal + ' ' + _FM().abbr(_selectedFabric) + ' @ $' + _selectedFabric.price.toFixed(2) + _FM().per(_selectedFabric) + ')',\n        b.fabricCost\n      ));\n    }\n\n    // Trim\n    if (result.inputs.weltType === 'Trim') {\n      if (_ownTrim) {\n        rows.push('<div class=\"cushion-pricing-row\"><span>Trim (COM / Off-Site)</span><span>excluded</span></div>');\n      } else if (_selectedTrim && b.trimCost > 0) {\n        rows.push(pricingRow(\n          escapeHTML(_selectedTrim.title) + ' (' + result.yardage.trimYards + ' yd @ $' + _selectedTrim.price.toFixed(2) + '/yd)',\n          b.trimCost\n        ));\n      }\n    }\n\n    // Contrast\n    if (result.inputs.weltType === 'Contrast Fabric Welt') {\n      if (_ownContrast) {\n        rows.push('<div class=\"cushion-pricing-row\"><span>Contrast Fabric (COM / Off-Site)</span><span>excluded</span></div>');\n      } else if (_selectedContrast && b.contrastCost > 0) {\n        rows.push(pricingRow(\n          escapeHTML(_selectedContrast.title) + ' (' + result.yardage.contrastYards + ' ' + _FM().abbr(_selectedContrast) + ' @ $' + _selectedContrast.price.toFixed(2) + _FM().per(_selectedContrast) + ')',\n          b.contrastCost\n        ));\n      }\n    }\n\n    // Total\n    rows.push('<div class=\"cushion-pricing-total\"><span>Estimated Total</span><span>$' + Math.ceil(result.total) + '</span></div>');\n\n    el.innerHTML = rows.join('');\n    el.style.display = 'block';\n  }\n\n  function pricingRow(label, amount) {\n    return '<div class=\"cushion-pricing-row\"><span>' + label + '</span><span>$' + Math.ceil(amount) + '</span></div>';\n  }\n\n  function escapeHTML(str) {\n    if (!str) return '';\n    var d = document.createElement('div');\n    d.appendChild(document.createTextNode(str));\n    return d.innerHTML;\n  }\n\n  // -------------------------------------------------------------------------\n  // Swatch preview management (matches drapery pattern)\n  // -------------------------------------------------------------------------\n\n  function showFabricSwatch(fabric) {\n    var preview = $('cushionFabricSwatchPreview');\n    var img = $('cushionFabricSwatchImage');\n    var price = $('cushionFabricSwatchPrice');\n    var clearBtn = $('cushionFabricClearBtn');\n    if (!preview) return;\n\n    if (img && fabric.imageUrl) { img.src = fabric.imageUrl; img.alt = fabric.title || ''; }\n    if (price) price.textContent = '$' + fabric.price.toFixed(2) + _FM().per(fabric);\n    if (clearBtn) clearBtn.classList.add('visible');\n    preview.style.display = 'flex';\n  }\n\n  function hideFabricSwatch() {\n    var preview = $('cushionFabricSwatchPreview');\n    var clearBtn = $('cushionFabricClearBtn');\n    if (preview) preview.style.display = 'none';\n    if (clearBtn) clearBtn.classList.remove('visible');\n  }\n\n  function showTrimSwatch(trim) {\n    var preview = $('cushionTrimSwatchPreview');\n    var img = $('cushionTrimSwatchImage');\n    var price = $('cushionTrimSwatchPrice');\n    var clearBtn = $('cushionTrimClearBtn');\n    if (!preview) return;\n\n    if (img && trim.imageUrl) { img.src = trim.imageUrl; img.alt = trim.title || ''; }\n    if (price) price.textContent = '$' + trim.price.toFixed(2) + '/yd';\n    if (clearBtn) clearBtn.classList.add('visible');\n    preview.style.display = 'flex';\n  }\n\n  function hideTrimSwatch() {\n    var preview = $('cushionTrimSwatchPreview');\n    var clearBtn = $('cushionTrimClearBtn');\n    if (preview) preview.style.display = 'none';\n    if (clearBtn) clearBtn.classList.remove('visible');\n  }\n\n  function showContrastSwatch(contrast) {\n    var preview = $('cushionContrastSwatchPreview');\n    var img = $('cushionContrastSwatchImage');\n    var price = $('cushionContrastSwatchPrice');\n    var clearBtn = $('cushionContrastClearBtn');\n    if (!preview) return;\n\n    if (img && contrast.imageUrl) { img.src = contrast.imageUrl; img.alt = contrast.title || ''; }\n    if (price) price.textContent = '$' + contrast.price.toFixed(2) + _FM().per(contrast);\n    if (clearBtn) clearBtn.classList.add('visible');\n    preview.style.display = 'flex';\n  }\n\n  function hideContrastSwatch() {\n    var preview = $('cushionContrastSwatchPreview');\n    var clearBtn = $('cushionContrastClearBtn');\n    if (preview) preview.style.display = 'none';\n    if (clearBtn) clearBtn.classList.remove('visible');\n  }\n\n  // -------------------------------------------------------------------------\n  // Thickness validation (max 8\")\n  // -------------------------------------------------------------------------\n\n  function enforceThicknessMax() {\n    var el = $('cushion-thickness');\n    if (!el) return;\n    var val = parseFloat(el.value);\n    if (val > 8) {\n      el.value = 8;\n      showThicknessTooltip();\n    }\n  }\n\n  function showThicknessTooltip() {\n    var tip = $('cushion-thickness-tooltip');\n    if (tip) {\n      tip.style.display = 'block';\n      setTimeout(function () { tip.style.display = 'none'; }, 3000);\n    }\n  }\n\n  // -------------------------------------------------------------------------\n  // COM toggles (matches drapery handleOwnFabricChange / handleOwnTrimChange)\n  // -------------------------------------------------------------------------\n\n  function handleOwnFabricToggle() {\n    var cb = $('cushionOwnFabric');\n    _ownFabric = cb ? cb.checked : false;\n\n    var fabricField = $('cushionFabricField');\n    var browseBtn = $('cushionBrowseFabricsBtn');\n    var customFabricNameLabel = $('cushionCustomFabricName') ? $('cushionCustomFabricName').parentElement : null;\n    var customFabricColorLabel = $('cushionCustomFabricColor') ? $('cushionCustomFabricColor').parentElement : null;\n    var swatchPreview = $('cushionFabricSwatchPreview');\n    var widthField = $('cushion-fabric-width');\n\n    // Show/hide COM fields (parentElement = <label>)\n    if (customFabricNameLabel) customFabricNameLabel.style.display = _ownFabric ? 'block' : 'none';\n    if (customFabricColorLabel) customFabricColorLabel.style.display = _ownFabric ? 'block' : 'none';\n\n    // Disable (not hide) search field and browse button\n    if (fabricField) {\n      fabricField.disabled = _ownFabric;\n      fabricField.value = _ownFabric\n        ? ''\n        : (_selectedFabric ? _selectedFabric.title + ' ($' + _selectedFabric.price.toFixed(2) + _FM().per(_selectedFabric) + ')' : '');\n      if (_ownFabric) {\n        fabricField.classList.remove('selected');\n      } else {\n        fabricField.classList.toggle('selected', !!_selectedFabric);\n      }\n    }\n    if (browseBtn) browseBtn.disabled = _ownFabric;\n    if (swatchPreview) swatchPreview.style.display = _ownFabric ? 'none' : (_selectedFabric ? 'flex' : 'none');\n\n    // Fabric width: editable for own, readonly for store fabric\n    if (widthField) {\n      if (_ownFabric) {\n        _selectedFabric = null;\n        widthField.removeAttribute('readonly');\n        widthField.style.background = '#fff';\n      } else {\n        widthField.setAttribute('readonly', 'readonly');\n        widthField.style.background = '#f0f0f0';\n        if (!_selectedFabric) {\n          widthField.value = DEFAULT_FABRIC_WIDTH;\n        }\n      }\n    }\n\n    updateCalculation();\n  }\n\n  function handleOwnTrimToggle() {\n    var cb = $('cushionOwnTrim');\n    _ownTrim = cb ? cb.checked : false;\n\n    var trimField = $('cushionTrimField');\n    var browseBtn = $('cushionBrowseTrimsBtn');\n    var customTrimNameLabel = $('cushionCustomTrimName') ? $('cushionCustomTrimName').parentElement : null;\n    var customTrimColorLabel = $('cushionCustomTrimColor') ? $('cushionCustomTrimColor').parentElement : null;\n    var swatchPreview = $('cushionTrimSwatchPreview');\n\n    // Show/hide COM fields\n    if (customTrimNameLabel) customTrimNameLabel.style.display = _ownTrim ? 'block' : 'none';\n    if (customTrimColorLabel) customTrimColorLabel.style.display = _ownTrim ? 'block' : 'none';\n\n    // Disable (not hide) search field and browse button\n    if (trimField) {\n      trimField.disabled = _ownTrim;\n      trimField.value = _ownTrim\n        ? ''\n        : (_selectedTrim ? _selectedTrim.title + ' ($' + _selectedTrim.price.toFixed(2) + '/yd)' : '');\n      if (_ownTrim) {\n        trimField.classList.remove('selected');\n      } else {\n        trimField.classList.toggle('selected', !!_selectedTrim);\n      }\n    }\n    if (browseBtn) browseBtn.disabled = _ownTrim;\n    if (swatchPreview) swatchPreview.style.display = _ownTrim ? 'none' : (_selectedTrim ? 'flex' : 'none');\n\n    if (_ownTrim) {\n      _selectedTrim = null;\n    }\n\n    updateCalculation();\n  }\n\n  function handleOwnContrastToggle() {\n    var cb = $('cushionOwnContrast');\n    _ownContrast = cb ? cb.checked : false;\n\n    var contrastField = $('cushionContrastField');\n    var browseBtn = $('cushionBrowseContrastBtn');\n    var customContrastNameLabel = $('cushionCustomContrastName') ? $('cushionCustomContrastName').parentElement : null;\n    var customContrastColorLabel = $('cushionCustomContrastColor') ? $('cushionCustomContrastColor').parentElement : null;\n    var swatchPreview = $('cushionContrastSwatchPreview');\n\n    // Show/hide COM fields\n    if (customContrastNameLabel) customContrastNameLabel.style.display = _ownContrast ? 'block' : 'none';\n    if (customContrastColorLabel) customContrastColorLabel.style.display = _ownContrast ? 'block' : 'none';\n\n    // Disable (not hide) search field and browse button\n    if (contrastField) {\n      contrastField.disabled = _ownContrast;\n      contrastField.value = _ownContrast\n        ? ''\n        : (_selectedContrast ? _selectedContrast.title + ' ($' + _selectedContrast.price.toFixed(2) + _FM().per(_selectedContrast) + ')' : '');\n      if (_ownContrast) {\n        contrastField.classList.remove('selected');\n      } else {\n        contrastField.classList.toggle('selected', !!_selectedContrast);\n      }\n    }\n    if (browseBtn) browseBtn.disabled = _ownContrast;\n    if (swatchPreview) swatchPreview.style.display = _ownContrast ? 'none' : (_selectedContrast ? 'flex' : 'none');\n\n    if (_ownContrast) {\n      _selectedContrast = null;\n    }\n\n    updateCalculation();\n  }\n\n  // -------------------------------------------------------------------------\n  // Photo upload handlers\n  // -------------------------------------------------------------------------\n\n  function handlePhotoFiles(files) {\n    for (var i = 0; i < files.length; i++) {\n      if (files[i].type.indexOf('image/') !== 0) continue;\n      if (_photoFiles.length >= 10) break;\n      _photoFiles.push(files[i]);\n    }\n    renderPhotoThumbs();\n  }\n\n  function removePhoto(index) {\n    _photoFiles.splice(index, 1);\n    renderPhotoThumbs();\n  }\n\n  function renderPhotoThumbs() {\n    var container = $('cushion-photo-thumbs');\n    if (!container) return;\n    container.innerHTML = '';\n\n    _photoFiles.forEach(function (file, idx) {\n      var thumb = document.createElement('div');\n      thumb.className = 'cushion-photo-thumb';\n\n      var img = document.createElement('img');\n      img.alt = file.name;\n      var reader = new FileReader();\n      reader.onload = function (e) { img.src = e.target.result; };\n      reader.readAsDataURL(file);\n\n      var removeBtn = document.createElement('button');\n      removeBtn.type = 'button';\n      removeBtn.className = 'cushion-photo-remove';\n      removeBtn.textContent = '\\u00d7';\n      removeBtn.addEventListener('click', function () { removePhoto(idx); });\n\n      thumb.appendChild(img);\n      thumb.appendChild(removeBtn);\n      container.appendChild(thumb);\n    });\n  }\n\n  function bindPhotoUpload() {\n    var fileInput = $('cushion-photo-input');\n    var uploadArea = $('cushion-upload-area');\n    if (!fileInput || !uploadArea) return;\n\n    addTrackedListener(uploadArea, 'click', function () { fileInput.click(); });\n\n    addTrackedListener(fileInput, 'change', function () {\n      if (fileInput.files && fileInput.files.length > 0) {\n        handlePhotoFiles(fileInput.files);\n        fileInput.value = '';\n      }\n    });\n\n    addTrackedListener(uploadArea, 'dragover', function (e) {\n      e.preventDefault();\n      uploadArea.style.borderColor = '#007cba';\n      uploadArea.style.background = '#f0f8ff';\n    });\n\n    addTrackedListener(uploadArea, 'dragleave', function () {\n      uploadArea.style.borderColor = '';\n      uploadArea.style.background = '';\n    });\n\n    addTrackedListener(uploadArea, 'drop', function (e) {\n      e.preventDefault();\n      uploadArea.style.borderColor = '';\n      uploadArea.style.background = '';\n      if (e.dataTransfer && e.dataTransfer.files) {\n        handlePhotoFiles(e.dataTransfer.files);\n      }\n    });\n  }\n\n  // -------------------------------------------------------------------------\n  // Clear button handlers\n  // -------------------------------------------------------------------------\n\n  function clearFabricSelection() {\n    _selectedFabric = null;\n    hideFabricSwatch();\n    var field = $('cushionFabricField');\n    if (field) { field.value = ''; field.classList.remove('selected'); }\n    var widthField = $('cushion-fabric-width');\n    if (widthField && !_ownFabric) {\n      widthField.value = DEFAULT_FABRIC_WIDTH;\n      widthField.readOnly = true;\n      widthField.style.background = '#f0f0f0';\n    }\n    // Dispatch trh:fabric-cleared so fabric browser syncs\n    document.dispatchEvent(new CustomEvent('trh:fabric-cleared'));\n    updateCalculation();\n  }\n\n  function clearTrimSelection() {\n    _selectedTrim = null;\n    hideTrimSwatch();\n    var field = $('cushionTrimField');\n    if (field) { field.value = ''; field.classList.remove('selected'); }\n    document.dispatchEvent(new CustomEvent('trh:trim-cleared'));\n    updateCalculation();\n  }\n\n  function clearContrastSelection() {\n    _selectedContrast = null;\n    hideContrastSwatch();\n    var field = $('cushionContrastField');\n    if (field) { field.value = ''; field.classList.remove('selected'); }\n    updateCalculation();\n  }\n\n  // -------------------------------------------------------------------------\n  // Contrast fabric search autocomplete\n  // -------------------------------------------------------------------------\n\n  /** @type {number} Sequence counter guarding against stale async search renders */\n  var _contrastSearchSeq = 0;\n\n  async function showContrastSuggestions(query) {\n    var suggestionsEl = $('cushionContrastSuggestions');\n    var field = $('cushionContrastField');\n    if (!suggestionsEl) return;\n\n    var normalized = (query || '').normalize('NFD').replace(/[\\u0300-\\u036f]/g, '').toLowerCase();\n    if (!normalized || normalized.length < 1) {\n      suggestionsEl.style.display = 'none';\n      suggestionsEl.innerHTML = '';\n      return;\n    }\n\n    var seq = ++_contrastSearchSeq;\n    suggestionsEl.innerHTML = '<div class=\"search-no-results\">Searching\\u2026</div>';\n    suggestionsEl.style.display = 'block';\n\n    /* Search the FULL fabric inventory server-side (the store has 5,000+\n     * fabrics \\u2014 TRHFabricBrowser.getAllFabrics() is a bounded cache and\n     * must not be used for search). */\n    var matches = [];\n    if (typeof window.TRHFabricBrowser !== 'undefined' &&\n        typeof window.TRHFabricBrowser.searchFabrics === 'function') {\n      try {\n        matches = await window.TRHFabricBrowser.searchFabrics(query, 10);\n      } catch (err) {\n        console.error('[TRHCushionCalculator] Contrast fabric search failed:', err);\n        if (seq !== _contrastSearchSeq) return;\n        suggestionsEl.innerHTML = '<div class=\"search-no-results\">Search is temporarily unavailable. Please try again.</div>';\n        return;\n      }\n    }\n\n    if (seq !== _contrastSearchSeq) return; /* superseded by a newer keystroke */\n\n    suggestionsEl.innerHTML = '';\n    if (matches.length === 0) {\n      suggestionsEl.innerHTML = '<div class=\"search-no-results\">No fabrics found</div>';\n    } else {\n      matches.forEach(function (item) {\n        var row = document.createElement('div');\n        row.className = 'search-suggestion';\n\n        var img = document.createElement('img');\n        img.src = item.imageUrl;\n        img.alt = item.title;\n        img.className = 'fabric-image';\n\n        var details = document.createElement('div');\n        details.className = 'fabric-details';\n        details.innerHTML = '<p class=\"fabric-name\">' + escapeHTML(item.title) + '</p>' +\n          '<p class=\"fabric-price\">$' + item.price.toFixed(2) + '/yd</p>';\n\n        row.appendChild(img);\n        row.appendChild(details);\n\n        row.addEventListener('click', function () {\n          _selectedContrast = { id: item.id, title: item.title, price: item.price, imageUrl: item.imageUrl || '' };\n          if (field) { field.value = item.title; field.classList.add('selected'); }\n          showContrastSwatch(_selectedContrast);\n          suggestionsEl.style.display = 'none';\n          suggestionsEl.innerHTML = '';\n          updateCalculation();\n        });\n\n        suggestionsEl.appendChild(row);\n      });\n    }\n    suggestionsEl.style.display = 'block';\n  }\n\n  // -------------------------------------------------------------------------\n  // Validation\n  // -------------------------------------------------------------------------\n\n  function validateForCart() {\n    var length = parseFloat(($('cushion-length') || {}).value);\n    var width = parseFloat(($('cushion-width') || {}).value);\n    var thickness = parseFloat(($('cushion-thickness') || {}).value);\n\n    if (!length || length <= 0) return 'Please enter a valid length.';\n    if (!width || width <= 0) return 'Please enter a valid width/depth.';\n    if (!thickness || thickness <= 0) return 'Please enter a valid thickness.';\n    if (thickness > 8) return 'Maximum thickness is 8 inches.';\n\n    var edge = ($('cushion-edge') || {}).value;\n    if (!edge) return 'Please select an edge finish.';\n\n    var fill = ($('cushion-fill') || {}).value;\n    if (!fill) return 'Please select a fill type.';\n\n    var tufting = ($('cushion-tufting') || {}).value;\n    if (tufting && tufting !== 'No Tufting') {\n      var spacing = ($('cushion-tufting-spacing') || {}).value;\n      if (!spacing) return 'Please select a tufting spacing.';\n    }\n\n    // Fabric required unless COM\n    if (!_ownFabric && !_selectedFabric) {\n      return 'Please select a fabric or check \"Use My Own Fabric\".';\n    }\n    if (_ownFabric) {\n      var comFabricName = ($('cushionCustomFabricName') || {}).value || '';\n      if (!comFabricName.trim()) {\n        return 'Please enter your fabric pattern name.';\n      }\n    }\n\n    // Trim required if welt = Trim\n    var weltSection = $('cushion-welt-section');\n    var weltSelect = $('cushion-welt');\n    if (weltSection && weltSection.style.display !== 'none' && weltSelect) {\n      if (weltSelect.value === 'Trim' && !_ownTrim && !_selectedTrim) {\n        return 'Please select a trim or check \"Use My Own Trim\".';\n      }\n      if (weltSelect.value === 'Trim' && _ownTrim) {\n        var comTrimName = ($('cushionCustomTrimName') || {}).value || '';\n        if (!comTrimName.trim()) {\n          return 'Please enter your trim pattern name.';\n        }\n      }\n      if (weltSelect.value === 'Contrast Fabric Welt' && !_ownContrast && !_selectedContrast) {\n        return 'Please select a contrast fabric or check \"Use My Own Fabric\".';\n      }\n      if (weltSelect.value === 'Contrast Fabric Welt' && _ownContrast) {\n        var comContrastName = ($('cushionCustomContrastName') || {}).value || '';\n        if (!comContrastName.trim()) {\n          return 'Please enter your contrast fabric pattern name.';\n        }\n      }\n    }\n\n    return null;\n  }\n\n  // -------------------------------------------------------------------------\n  // Add to Cart (/cart/add.js \u2014 $1 variant x dollar amount, same as drapery)\n  // -------------------------------------------------------------------------\n\n  function buildCartItems(result) {\n    var items = [];\n    var groupId = 'cush-' + Date.now() + '-' + Math.random().toString(36).substr(2, 5);\n    var b = result.breakdown;\n    var y = result.yardage;\n    var inp = result.inputs;\n\n    var cushionCost = Math.max(Math.round(b.cushionTotal), 1);\n\n    var properties = {\n      '_group_id': groupId,\n      '_cushion_order': 'true',\n      'Length': inp.length + '\"',\n      'Width/Depth': inp.width + '\"',\n      'Thickness': inp.thickness + '\"',\n      'Edge Finish': inp.edgeFinish,\n      'Fill': inp.fillType,\n      'Quantity': String(inp.quantity)\n    };\n\n    if (inp.tuftingType !== 'No Tufting') {\n      properties['Tufting'] = inp.tuftingType;\n      properties['Tufting Spacing'] = inp.tuftingSpacing + '\"';\n      properties['Button Count'] = String(b.buttonCount);\n    }\n\n    if (inp.weltType) {\n      properties['Welt'] = inp.weltType;\n    } else if (/No Welt/.test(inp.edgeFinish || '')) {\n      properties['Welt'] = 'No Welt';\n    }\n\n\n    // Fabric info (matches drapery property format)\n    if (_ownFabric) {\n      var comFabricName = ($('cushionCustomFabricName') || {}).value || '';\n      var comFabricColor = ($('cushionCustomFabricColor') || {}).value || '';\n      properties['Fabric'] = comFabricName + (comFabricColor ? ' - ' + comFabricColor : '') + ' (Customer Fabric)';\n    } else if (_selectedFabric) {\n      properties['Fabric'] = _selectedFabric.title + ' (' + _FM().label(y.fabricYardsFinal, _selectedFabric) + ' @ $' + _selectedFabric.price.toFixed(2) + _FM().per(_selectedFabric) + ' = $' + Math.ceil(b.fabricCost) + ')';\n    }\n\n    // Trim info (matches drapery property format)\n    if (inp.weltType === 'Trim') {\n      if (_ownTrim) {\n        var comTrimName = ($('cushionCustomTrimName') || {}).value || '';\n        var comTrimColor = ($('cushionCustomTrimColor') || {}).value || '';\n        properties['Trim'] = comTrimName + (comTrimColor ? ' - ' + comTrimColor : '') + ' (Customer Trim)';\n      } else if (_selectedTrim) {\n        properties['Trim'] = _selectedTrim.title + ' (' + y.trimYards + ' yards @ $' + _selectedTrim.price.toFixed(2) + '/yd = $' + Math.ceil(b.trimCost) + ')';\n      }\n    }\n\n    // Contrast info (matches drapery property format)\n    if (inp.weltType === 'Contrast Fabric Welt') {\n      if (_ownContrast) {\n        var comContrastName = ($('cushionCustomContrastName') || {}).value || '';\n        var comContrastColor = ($('cushionCustomContrastColor') || {}).value || '';\n        properties['Contrast Fabric'] = comContrastName + (comContrastColor ? ' - ' + comContrastColor : '') + ' (Customer Fabric)';\n      } else if (_selectedContrast) {\n        properties['Contrast Fabric'] = _selectedContrast.title + ' (' + _FM().label(y.contrastYards, _selectedContrast) + ' @ $' + _selectedContrast.price.toFixed(2) + _FM().per(_selectedContrast) + ' = $' + Math.ceil(b.contrastCost) + ')';\n      }\n    }\n\n    // Notes\n    var notes = ($('cushion-notes') || {}).value || '';\n    if (notes) properties['Customer Notes'] = notes;\n\n    // Photos\n    if (_photoFiles.length > 0) {\n      properties['Reference Photos'] = _photoFiles.length + ' photo(s) \u2014 will be sent via email';\n    }\n\n    // Yardage\n    properties['Fabric Yardage'] = _ownFabric ? y.fabricYardsFinal + ' yards' : _FM().label(y.fabricYardsFinal, _selectedFabric);\n    if (y.trimYards > 0) properties['Trim Yardage'] = y.trimYards + ' yards';\n    if (y.contrastYards > 0) properties['Contrast Yardage'] = _ownContrast ? y.contrastYards + ' yards' : _FM().label(y.contrastYards, _selectedContrast);\n\n    // 1. Cushion product\n    items.push({\n      id: _config.variantId,\n      quantity: cushionCost,\n      properties: properties\n    });\n\n    // 2. Fabric (separate line item)\n    if (!_ownFabric && _selectedFabric && _selectedFabric.id) {\n      items.push({\n        id: parseInt(_selectedFabric.id, 10),\n        quantity: y.fabricYardsFinal,\n        properties: {\n          '_group_id': groupId,\n          '_is_sub_item': 'true',\n          'For': 'Custom Cushion',\n          'Yardage': _FM().label(y.fabricYardsFinal, _selectedFabric)\n        }\n      });\n    }\n\n    // 3. Trim (separate line item)\n    if (inp.weltType === 'Trim' && !_ownTrim && _selectedTrim && _selectedTrim.id && y.trimYards > 0) {\n      items.push({\n        id: parseInt(_selectedTrim.id, 10),\n        quantity: y.trimYards,\n        properties: {\n          '_group_id': groupId,\n          '_is_sub_item': 'true',\n          'For': 'Custom Cushion (Trim)',\n          'Yardage': y.trimYards + ' yards'\n        }\n      });\n    }\n\n    // 4. Contrast fabric (separate line item)\n    if (inp.weltType === 'Contrast Fabric Welt' && !_ownContrast && _selectedContrast && _selectedContrast.id && y.contrastYards > 0) {\n      items.push({\n        id: parseInt(_selectedContrast.id, 10),\n        quantity: y.contrastYards,\n        properties: {\n          '_group_id': groupId,\n          '_is_sub_item': 'true',\n          'For': 'Custom Cushion (Contrast Welt)',\n          'Yardage': _FM().label(y.contrastYards, _selectedContrast)\n        }\n      });\n    }\n\n    return items;\n  }\n\n  function handleAddToCart() {\n    if (_isSubmitting) return;\n\n    var error = validateForCart();\n    if (error) {\n      showMessage(error, true);\n      return;\n    }\n\n    var result = calculateAll();\n    if (!result || result.breakdown.cushionTotal <= 0) {\n      showMessage('Unable to calculate price. Please verify your selections.', true);\n      return;\n    }\n\n    _isSubmitting = true;\n    var btn = $('cushion-add-to-cart');\n    if (btn) { btn.disabled = true; btn.textContent = 'Processing...'; }\n\n    // Show loading bar\n    var msgEl = $('cushion-cart-message');\n    var loadingBar = $('cushionLoadingBar');\n    var cartMsg = $('cushionCartMessage');\n    var successIcon = $('cushionSuccessIcon');\n    var viewCartBtn = $('cushionViewCartButton');\n\n    if (msgEl) {\n      msgEl.classList.remove('error');\n      msgEl.style.display = 'flex';\n    }\n    if (successIcon) successIcon.style.display = 'none';\n    if (viewCartBtn) viewCartBtn.style.display = 'none';\n    if (cartMsg) cartMsg.textContent = 'Adding to cart...';\n    if (loadingBar) {\n      loadingBar.style.display = 'block';\n      var bar = loadingBar.querySelector('.loading-bar');\n      if (bar) { bar.classList.remove('animate'); void bar.offsetWidth; bar.classList.add('animate'); }\n    }\n\n    var items = buildCartItems(result);\n    console.log(LOG_PREFIX, 'Adding to cart:', items);\n\n    fetch('/cart/add.js', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ items: items })\n    })\n      .then(function (response) {\n        if (!response.ok) {\n          return response.json().then(function (data) {\n            throw new Error(data.description || data.message || 'Failed to add to cart');\n          });\n        }\n        return response.json();\n      })\n      .then(function () {\n        console.log(LOG_PREFIX, 'Successfully added to cart.');\n        _isSubmitting = false;\n        if (btn) { btn.disabled = false; btn.textContent = 'Add to Cart'; }\n\n        // Show success state\n        if (loadingBar) loadingBar.style.display = 'none';\n        if (successIcon) successIcon.style.display = '';\n        var successText = 'Added to cart!';\n        if (_photoFiles.length > 0) {\n          successText = 'Added to cart! Please email your reference photos to info@therebornhouse.com';\n        }\n        if (cartMsg) cartMsg.textContent = successText;\n        if (viewCartBtn) viewCartBtn.style.display = '';\n        if (msgEl) { msgEl.classList.remove('error'); msgEl.style.display = 'flex'; }\n      })\n      .catch(function (err) {\n        console.error(LOG_PREFIX, 'Add to cart error:', err);\n        _isSubmitting = false;\n        if (btn) { btn.disabled = false; btn.textContent = 'Add to Cart'; }\n        if (loadingBar) loadingBar.style.display = 'none';\n        showMessage(err.message || 'An error occurred. Please try again.', true);\n      });\n  }\n\n  function showMessage(text, isError) {\n    var msgEl = $('cushion-cart-message');\n    var cartMsg = $('cushionCartMessage');\n    var successIcon = $('cushionSuccessIcon');\n    var loadingBar = $('cushionLoadingBar');\n    var viewCartBtn = $('cushionViewCartButton');\n\n    if (cartMsg) cartMsg.textContent = text;\n    if (successIcon) successIcon.style.display = 'none';\n    if (loadingBar) loadingBar.style.display = 'none';\n    if (viewCartBtn) viewCartBtn.style.display = 'none';\n    if (msgEl) {\n      if (isError) {\n        msgEl.classList.add('error');\n      } else {\n        msgEl.classList.remove('error');\n      }\n      msgEl.style.display = 'flex';\n    }\n  }\n\n  // -------------------------------------------------------------------------\n  // Event binding\n  // -------------------------------------------------------------------------\n\n  function addTrackedListener(target, eventName, handler) {\n    target.addEventListener(eventName, handler);\n    _boundListeners.push({ target: target, event: eventName, handler: handler });\n  }\n\n  function removeAllListeners() {\n    _boundListeners.forEach(function (e) {\n      e.target.removeEventListener(e.event, e.handler);\n    });\n    _boundListeners = [];\n  }\n\n  function bindEvents() {\n    // Dimension inputs\n    ['cushion-length', 'cushion-width', 'cushion-thickness', 'cushion-quantity', 'cushion-fabric-width'].forEach(function (id) {\n      var el = $(id);\n      if (el) {\n        addTrackedListener(el, 'input', function () {\n          if (id === 'cushion-thickness') enforceThicknessMax();\n          updateCalculation();\n        });\n      }\n    });\n\n    // Select dropdowns\n    ['cushion-edge', 'cushion-welt', 'cushion-tufting', 'cushion-tufting-spacing', 'cushion-fill'].forEach(function (id) {\n      var el = $(id);\n      if (el) {\n        addTrackedListener(el, 'change', updateConditionalUI);\n      }\n    });\n\n    // COM toggles\n    var ownFabricCb = $('cushionOwnFabric');\n    if (ownFabricCb) addTrackedListener(ownFabricCb, 'change', handleOwnFabricToggle);\n    var ownTrimCb = $('cushionOwnTrim');\n    if (ownTrimCb) addTrackedListener(ownTrimCb, 'change', handleOwnTrimToggle);\n    var ownContrastCb = $('cushionOwnContrast');\n    if (ownContrastCb) addTrackedListener(ownContrastCb, 'change', handleOwnContrastToggle);\n\n    // Clear buttons\n    var fabricClearBtn = $('cushionFabricClearBtn');\n    if (fabricClearBtn) addTrackedListener(fabricClearBtn, 'click', clearFabricSelection);\n    var trimClearBtn = $('cushionTrimClearBtn');\n    if (trimClearBtn) addTrackedListener(trimClearBtn, 'click', clearTrimSelection);\n    var contrastClearBtn = $('cushionContrastClearBtn');\n    if (contrastClearBtn) addTrackedListener(contrastClearBtn, 'click', clearContrastSelection);\n\n    // Fabric selected/cleared events (from TRHFabricBrowser)\n    addTrackedListener(document, 'trh:fabric-selected', function (e) {\n      var fabric = e.detail ? (e.detail.fabric || e.detail) : null;\n      if (!fabric) return;\n\n      var fabricData = {\n        id: fabric.id,\n        title: fabric.title,\n        price: fabric.price,\n        imageUrl: fabric.imageUrl || '',\n        fabricWidth: fabric.fabricWidth || DEFAULT_FABRIC_WIDTH,\n        verticalRepeat: fabric.verticalRepeat || 0,\n        horizontalRepeat: fabric.horizontalRepeat || 0,\n        minQty: fabric.minQty || null,\n        unit: fabric.unit || null,\n        tags: fabric.tags || null,\n        vendor: fabric.vendor || ''\n      };\n\n      // Route based on browse target\n      if (_browseTarget === 'contrast') {\n        /* TRH welt 2026-10-26: contrast welt must be a sellable Fabric/Vinyl;\n         * put the main fabric back in the shared browser either way */\n        _browseTarget = 'fabric';\n        var fbx = window.TRHFabricBrowser;\n        if (fbx && _selectedFabric) setTimeout(function () { fbx.selectFabric(_selectedFabric); }, 0);\n        else if (fbx) setTimeout(function () { fbx.clearSelection('fabric'); }, 0);\n        if (fbx && fbx.isWeltFabric && !fbx.isWeltFabric(fabric)) { fbx.weltBlocked(fabric); return; }\n        _browseTarget = 'contrast';\n        _selectedContrast = fabricData;\n        var contrastField = $('cushionContrastField');\n        if (contrastField) { contrastField.value = fabric.title; contrastField.classList.add('selected'); }\n        showContrastSwatch(_selectedContrast);\n        _browseTarget = 'fabric'; // reset\n      } else {\n        _selectedFabric = fabricData;\n        var fabricField = $('cushionFabricField');\n        if (fabricField) fabricField.classList.add('selected');\n        showFabricSwatch(_selectedFabric);\n        // Auto-fill fabric width\n        var widthField = $('cushion-fabric-width');\n        if (widthField && fabric.fabricWidth) {\n          widthField.value = fabric.fabricWidth;\n          widthField.readOnly = true;\n          widthField.style.background = '#f0f0f0';\n        }\n      }\n\n      hideMessage();\n      updateCalculation();\n    });\n\n    addTrackedListener(document, 'trh:fabric-cleared', function () {\n      // Only clear main fabric (not contrast)\n      if (_browseTarget !== 'contrast') {\n        _selectedFabric = null;\n        hideFabricSwatch();\n        var widthField = $('cushion-fabric-width');\n        if (widthField && !_ownFabric) {\n          widthField.value = DEFAULT_FABRIC_WIDTH;\n          widthField.readOnly = true;\n          widthField.style.background = '#f0f0f0';\n        }\n        updateCalculation();\n      }\n    });\n\n    // Trim selected/cleared events\n    addTrackedListener(document, 'trh:trim-selected', function (e) {\n      var trim = e.detail ? (e.detail.trim || e.detail) : null;\n      if (!trim) return;\n      _selectedTrim = { id: trim.id, title: trim.title, price: trim.price, imageUrl: trim.imageUrl || '', vendor: trim.vendor || '', tags: trim.tags || [] };\n      var trimField = $('cushionTrimField');\n      if (trimField) trimField.classList.add('selected');\n      showTrimSwatch(_selectedTrim);\n      hideMessage();\n      updateCalculation();\n    });\n\n    addTrackedListener(document, 'trh:trim-cleared', function () {\n      _selectedTrim = null;\n      hideTrimSwatch();\n      updateCalculation();\n    });\n\n    // Contrast fabric search autocomplete\n    var contrastField = $('cushionContrastField');\n    var contrastSuggestions = $('cushionContrastSuggestions');\n    if (contrastField && contrastSuggestions) {\n      var debounce = null;\n      addTrackedListener(contrastField, 'input', function () {\n        clearTimeout(debounce);\n        debounce = setTimeout(function () { showContrastSuggestions(contrastField.value); }, 200);\n      });\n      addTrackedListener(contrastField, 'focus', function () {\n        if (contrastField.value.length > 0) showContrastSuggestions(contrastField.value);\n      });\n      addTrackedListener(document, 'click', function (e) {\n        if (!contrastField.contains(e.target) && !contrastSuggestions.contains(e.target)) {\n          contrastSuggestions.style.display = 'none';\n        }\n      });\n    }\n\n    // Photo upload\n    bindPhotoUpload();\n\n    // Add to Cart button\n    var addBtn = $('cushion-add-to-cart');\n    if (addBtn) {\n      addTrackedListener(addBtn, 'click', function (e) {\n        e.preventDefault();\n        handleAddToCart();\n      });\n    }\n  }\n\n  function hideMessage() {\n    var msgEl = $('cushion-cart-message');\n    if (msgEl) msgEl.style.display = 'none';\n  }\n\n  // -------------------------------------------------------------------------\n  // Public API\n  // -------------------------------------------------------------------------\n\n  window.TRHCushionCalculator = {\n\n    /**\n     * Set the browse target before opening the catalog.\n     * 'fabric' (default) routes trh:fabric-selected to _selectedFabric.\n     * 'contrast' routes it to _selectedContrast.\n     */\n    setBrowseTarget: function (target) {\n      _browseTarget = (target === 'contrast') ? 'contrast' : 'fabric';\n    },\n\n    init: function (config) {\n      if (_config) {\n        removeAllListeners();\n        _config = null;\n        _selectedFabric = null;\n        _selectedTrim = null;\n        _selectedContrast = null;\n        _ownFabric = false;\n        _ownTrim = false;\n        _ownContrast = false;\n        _isSubmitting = false;\n        _browseTarget = 'fabric';\n        _photoFiles = [];\n      }\n\n      _config = config || {};\n\n      if (document.readyState === 'loading') {\n        document.addEventListener('DOMContentLoaded', function () {\n          bindEvents();\n          updateConditionalUI();\n          console.log(LOG_PREFIX, 'Initialized (v2).');\n        });\n      } else {\n        bindEvents();\n        updateConditionalUI();\n        console.log(LOG_PREFIX, 'Initialized (v2).');\n      }\n    },\n\n    getState: function () {\n      return {\n        selectedFabric: _selectedFabric,\n        selectedTrim: _selectedTrim,\n        selectedContrast: _selectedContrast,\n        ownFabric: _ownFabric,\n        ownTrim: _ownTrim,\n        ownContrast: _ownContrast,\n        calculation: calculateAll()\n      };\n    },\n\n    destroy: function () {\n      removeAllListeners();\n      _config = null;\n      _selectedFabric = null;\n      _selectedTrim = null;\n      _selectedContrast = null;\n      _isSubmitting = false;\n      _browseTarget = 'fabric';\n      console.log(LOG_PREFIX, 'Destroyed.');\n    }\n  };\n})();\n"],
  "mappings": "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",
  "names": ["contrastField"]
}
