{"product_id":"men-s-comfort-fit-rashguard-ss-mode-water","title":"Men’s Comfort Fit Rashguard SS - THUNDER MASTER","description":"\u003cbody\u003e\n\n\n\u003cmeta charset=\"UTF-8\"\u003e\n\u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e\n\u003ctitle\u003eComfort Fit Rashguard ; Premium Italian Fabrics\u003c\/title\u003e\n\u003cmeta name=\"description\" content=\"Comfort Fit Rashguard — relaxed-fit 220 g\/m² Italian knit by SITIP with raglan sleeve. Acquazero water repellent, Eclipse UPF 50+, 4-way stretch. Custom team kits for surf, swim, watersports and beach lifestyle. Made in Italy.\"\u003e\n\u003cmeta name=\"keywords\" content=\"comfort fit rashguard, relaxed rashguard, custom rashguard, raglan rashguard, SITIP italian knit, Acquazero water repellent, Eclipse UPF 50+, 4-way stretch rashguard, surf rashguard, watersports rashguard, made in Italy\"\u003e\n\u003clink rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\"\u003e\n\u003clink rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin\u003e\n\u003clink href=\"https:\/\/fonts.googleapis.com\/css2?family=Archivo:wght@400;500;600;700;800;900\u0026amp;family=Archivo+Narrow:wght@400;500;600;700\u0026amp;family=JetBrains+Mono:wght@400;500;600\u0026amp;display=swap\" rel=\"stylesheet\"\u003e\n\u003cstyle\u003e\n  :root {\n    --ink: #0a1f2c;\n    --ink-soft: #143246;\n    --paper: #ffffff;\n    --paper-warm: #f4efe6;\n    --foam: #ffffff;\n    --ocean: #0066a2;\n    --ocean-deep: #00466e;\n    --aqua: #1fb6c1;\n    --sun: #f5b13d;\n    --coral: #ff5e3a;\n    --sand: #d9c8a5;\n    --line: rgba(10, 31, 44, 0.14);\n  }\n  * { box-sizing: border-box; }\n  html, body {\n    margin: 0;\n    padding: 0;\n    background: var(--paper);\n    color: var(--ink);\n    font-family: 'Archivo', sans-serif;\n    -webkit-font-smoothing: antialiased;\n  }\n  .product-desc {\n    max-width: 1100px;\n    margin: 0 auto;\n    padding: 24px 20px 80px;\n  }\n\n  \/* ============ PRODUCT TITLE BLOCK ============ *\/\n  .product-title {\n    position: relative;\n    padding: 28px 8px 56px;\n    margin-bottom: 8px;\n    border-bottom: 1px solid var(--line);\n    overflow: hidden;\n  }\n  .product-title .top-row {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    gap: 16px;\n    margin-bottom: 28px;\n    flex-wrap: wrap;\n  }\n  .product-title .pill {\n    display: inline-flex;\n    align-items: center;\n    gap: 10px;\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 11px;\n    letter-spacing: 0.22em;\n    text-transform: uppercase;\n    color: var(--ocean-deep);\n    background: rgba(0, 102, 162, 0.08);\n    border: 1px solid rgba(0, 102, 162, 0.25);\n    padding: 8px 14px;\n    border-radius: 100px;\n  }\n  .product-title .pill .pulse {\n    width: 7px; height: 7px;\n    border-radius: 50%;\n    background: var(--coral);\n    box-shadow: 0 0 0 4px rgba(255, 94, 58, 0.18);\n    animation: pulse 1.6s ease-in-out infinite;\n  }\n  @keyframes pulse {\n    0%, 100% { transform: scale(1); opacity: 1; }\n    50% { transform: scale(1.25); opacity: 0.7; }\n  }\n  .product-title .meta-row {\n    display: flex;\n    gap: 18px;\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 11px;\n    letter-spacing: 0.16em;\n    text-transform: uppercase;\n    color: var(--ink-soft);\n    flex-wrap: wrap;\n  }\n  .product-title .meta-row span {\n    display: inline-flex;\n    align-items: center;\n    gap: 8px;\n  }\n  .product-title .meta-row span + span::before { display: none; }\n  .product-title .kicker {\n    display: inline-flex;\n    align-items: center;\n    gap: 12px;\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 12px;\n    letter-spacing: 0.2em;\n    color: var(--ocean);\n    text-transform: uppercase;\n    margin-bottom: 14px;\n  }\n  .product-title .kicker::before {\n    content: \"\";\n    width: 36px;\n    height: 1.5px;\n    background: var(--ocean);\n  }\n  .product-title h1 {\n    font-family: 'Archivo Narrow', sans-serif;\n    font-weight: 700;\n    font-size: clamp(44px, 7vw, 92px);\n    line-height: 0.92;\n    letter-spacing: -0.025em;\n    text-transform: uppercase;\n    margin: 0 0 8px;\n    text-wrap: balance;\n    color: var(--ink);\n  }\n  .product-title h1 .accent {\n    font-family: 'Archivo', sans-serif;\n    font-weight: 900;\n    font-style: italic;\n    background: linear-gradient(110deg, var(--ocean-deep) 0%, var(--ocean) 45%, var(--aqua) 100%);\n    -webkit-background-clip: text;\n    background-clip: text;\n    color: transparent;\n    letter-spacing: -0.04em;\n    padding-right: 0.12em;\n    display: inline-block;\n  }\n  .product-title .product-full-title {\n    position: relative;\n    margin: 18px 0 0;\n    padding-inline-start: 24px;\n    font-family: 'Archivo', sans-serif;\n    font-size: clamp(14px, 1.4vw, 18px);\n    line-height: 1.45;\n    letter-spacing: -0.005em;\n    color: var(--ocean-deep);\n    font-weight: 500;\n    font-style: italic;\n    max-width: 640px;\n    text-wrap: balance;\n  }\n  .product-title .product-full-title::before {\n    content: \"\";\n    position: absolute;\n    inset-block-start: 0.65em;\n    inset-inline-start: 0;\n    width: 14px;\n    height: 2px;\n    background: linear-gradient(90deg, var(--ocean-deep), var(--aqua));\n    border-radius: 2px;\n  }\n  .product-title .subline {\n    font-size: 17px;\n    line-height: 1.55;\n    color: var(--ink-soft);\n    max-width: 640px;\n    margin: 22px 0 0;\n  }\n  .product-title .subline strong {\n    color: var(--ink);\n    font-weight: 700;\n  }\n  .product-title .feature-tabs {\n    display: flex;\n    gap: 8px;\n    margin-top: 28px;\n    flex-wrap: wrap;\n  }\n  .product-title .feature-tabs span {\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 11px;\n    letter-spacing: 0.14em;\n    text-transform: uppercase;\n    padding: 8px 14px;\n    border: 1px solid var(--line);\n    border-radius: 100px;\n    color: var(--ink-soft);\n    background: var(--paper-warm);\n  }\n\n  \/* ============ DESIGN CTAS ============ *\/\n  .liquid-tag { display: none; }\n  .design-ctas {\n    display: grid;\n    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n    gap: 12px;\n    margin-top: 32px;\n    position: relative;\n  }\n  .design-ctas::before {\n    content: \"\/\/ Customize this product\";\n    position: absolute;\n    top: -22px;\n    left: 0;\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 10px;\n    letter-spacing: 0.2em;\n    text-transform: uppercase;\n    color: var(--ocean);\n    opacity: 0.7;\n  }\n  .cta-btn {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    gap: 12px;\n    width: 100%;\n    padding: 18px 24px;\n    text-decoration: none;\n    font-family: 'Archivo', sans-serif;\n    font-weight: 700;\n    font-size: 14px;\n    letter-spacing: 0.08em;\n    text-transform: uppercase;\n    border-radius: 14px;\n    border: 1.5px solid transparent;\n    transition: transform 0.25s ease, box-shadow 0.25s ease, background 0.25s ease, color 0.25s ease, border-color 0.25s ease;\n    cursor: pointer;\n    position: relative;\n    overflow: hidden;\n  }\n  .cta-btn svg {\n    flex-shrink: 0;\n    transition: transform 0.25s ease, stroke 0.25s ease;\n  }\n  .cta-btn:hover {\n    transform: translateY(-2px);\n  }\n  .cta-btn:hover svg {\n    transform: rotate(-8deg) scale(1.05);\n  }\n\n  \/* Primary — Edit Design (ocean gradient + attention motion) *\/\n  .cta-btn--primary {\n    background: linear-gradient(135deg, var(--ocean-deep) 0%, var(--ocean) 50%, var(--aqua) 100%);\n    color: var(--foam);\n    box-shadow: 0 6px 20px rgba(0, 70, 110, 0.22);\n    position: relative;\n    animation: pdw-cta-pulse 2.6s ease-in-out infinite;\n  }\n  \/* Soft halo behind the button — pulses gently *\/\n  .cta-btn--primary::before {\n    content: \"\";\n    position: absolute;\n    inset: -2px;\n    border-radius: 16px;\n    background: linear-gradient(135deg, var(--ocean), var(--aqua));\n    z-index: -1;\n    opacity: 0.5;\n    filter: blur(8px);\n    animation: pdw-cta-glow 2.6s ease-in-out infinite;\n  }\n  \/* Repeating shine sweep — draws the eye without changing the color *\/\n  .cta-btn--primary::after {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    background: linear-gradient(120deg, transparent 35%, rgba(255,255,255,0.4) 50%, transparent 65%);\n    transform: translateX(-100%);\n    animation: pdw-cta-shine 3.2s ease-in-out infinite;\n    pointer-events: none;\n  }\n  \/* Animated arrow hint that nudges right *\/\n  .cta-btn--primary .nudge {\n    display: inline-block;\n    animation: pdw-cta-nudge 1.6s ease-in-out infinite;\n  }\n  .cta-btn--primary:hover {\n    transform: translateY(-3px);\n    box-shadow: 0 14px 32px rgba(0, 70, 110, 0.42);\n    animation-play-state: paused;\n  }\n  .cta-btn--primary:hover::before { animation-play-state: paused; opacity: 0.85; }\n  @keyframes pdw-cta-pulse {\n    0%, 100% { box-shadow: 0 6px 20px rgba(0, 70, 110, 0.22); }\n    50% { box-shadow: 0 8px 28px rgba(31, 182, 193, 0.55), 0 0 0 6px rgba(31, 182, 193, 0.12); }\n  }\n  @keyframes pdw-cta-glow {\n    0%, 100% { opacity: 0.35; }\n    50% { opacity: 0.7; }\n  }\n  @keyframes pdw-cta-shine {\n    0%, 55%, 100% { transform: translateX(-100%); }\n    80% { transform: translateX(100%); }\n  }\n  @keyframes pdw-cta-nudge {\n    0%, 100% { transform: translateX(0); }\n    50% { transform: translateX(4px); }\n  }\n\n  \/* Secondary — Create New Design (outlined → filled on hover) *\/\n  .cta-btn--secondary {\n    background: var(--foam);\n    border-color: var(--ocean-deep);\n    color: var(--ocean-deep);\n  }\n  .cta-btn--secondary svg { stroke: var(--ocean-deep); }\n  .cta-btn--secondary:hover {\n    background: linear-gradient(135deg, var(--ocean-deep) 0%, var(--ocean) 50%, var(--aqua) 100%);\n    border-color: transparent;\n    color: var(--foam);\n    box-shadow: 0 10px 28px rgba(0, 70, 110, 0.28);\n  }\n  .cta-btn--secondary:hover svg { stroke: var(--foam); }\n\n  @media (max-width: 640px) {\n    .design-ctas { grid-template-columns: 1fr; }\n  }\n\n  \/* ============ PRICING TABLE ============ *\/\n  .pricing {\n    margin-top: 36px;\n    background: linear-gradient(180deg, #fff 0%, var(--paper-warm) 100%);\n    border: 1px solid var(--line);\n    border-radius: 20px;\n    padding: 28px 28px 24px;\n    position: relative;\n    overflow: hidden;\n  }\n  .pricing::before {\n    content: \"\/\/ Volume pricing\";\n    position: absolute;\n    top: 16px;\n    right: 22px;\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 10px;\n    letter-spacing: 0.2em;\n    text-transform: uppercase;\n    color: var(--ocean);\n    opacity: 0.6;\n  }\n  .pricing-head {\n    display: flex;\n    align-items: end;\n    justify-content: space-between;\n    gap: 20px;\n    margin-bottom: 22px;\n    flex-wrap: wrap;\n  }\n  .pricing-title {\n    font-family: 'Archivo Narrow', sans-serif;\n    text-transform: uppercase;\n    font-size: 24px;\n    font-weight: 700;\n    letter-spacing: -0.01em;\n    margin: 0;\n    line-height: 1;\n  }\n  .pricing-title .em {\n    font-family: 'Archivo', sans-serif;\n    font-style: italic;\n    font-weight: 900;\n    background: linear-gradient(110deg, var(--ocean-deep), var(--aqua));\n    -webkit-background-clip: text;\n    background-clip: text;\n    color: transparent;\n  }\n  .pricing-sub {\n    font-size: 12px;\n    color: var(--ink-soft);\n    font-family: 'JetBrains Mono', monospace;\n    letter-spacing: 0.1em;\n    text-transform: uppercase;\n    margin: 6px 0 0;\n  }\n\n  \/* Live readout *\/\n  .pricing-readout {\n    background: var(--ink);\n    color: var(--foam);\n    border-radius: 16px;\n    padding: 22px 26px;\n    display: grid;\n    grid-template-columns: auto 1fr auto;\n    gap: 24px;\n    align-items: center;\n    margin-bottom: 22px;\n    position: relative;\n    overflow: hidden;\n  }\n  .pricing-readout::after {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    background: radial-gradient(ellipse 400px 120px at 0% 100%, rgba(31,182,193,0.25), transparent);\n    pointer-events: none;\n  }\n  .readout-qty {\n    display: flex;\n    flex-direction: column;\n    gap: 4px;\n    position: relative;\n    z-index: 1;\n  }\n  .readout-qty .label {\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 10px;\n    letter-spacing: 0.2em;\n    text-transform: uppercase;\n    color: var(--aqua);\n  }\n  .readout-qty .value {\n    font-family: 'Archivo', sans-serif;\n    font-weight: 900;\n    font-style: italic;\n    font-size: 48px;\n    line-height: 0.9;\n    letter-spacing: -0.04em;\n  }\n  .readout-qty .value small {\n    font-size: 14px;\n    font-style: normal;\n    font-weight: 600;\n    letter-spacing: 0.05em;\n    color: rgba(255,255,255,0.55);\n    margin-left: 6px;\n  }\n  .readout-discount {\n    text-align: center;\n    position: relative;\n    z-index: 1;\n  }\n  .readout-discount .badge {\n    display: inline-flex;\n    align-items: center;\n    gap: 6px;\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 11px;\n    letter-spacing: 0.18em;\n    text-transform: uppercase;\n    background: rgba(255, 94, 58, 0.18);\n    border: 1px solid rgba(255, 94, 58, 0.4);\n    color: #ffb89e;\n    padding: 6px 14px;\n    border-radius: 100px;\n    transition: all 0.3s ease;\n  }\n  .readout-discount .badge.zero {\n    background: rgba(255,255,255,0.08);\n    border-color: rgba(255,255,255,0.2);\n    color: rgba(255,255,255,0.55);\n  }\n  .readout-discount .save {\n    display: block;\n    font-size: 11px;\n    color: rgba(255,255,255,0.55);\n    margin-top: 8px;\n    font-family: 'JetBrains Mono', monospace;\n    letter-spacing: 0.08em;\n  }\n  .readout-discount .save b {\n    color: var(--sun);\n    font-weight: 600;\n  }\n  .readout-price {\n    text-align: right;\n    position: relative;\n    z-index: 1;\n  }\n  .readout-price .label {\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 10px;\n    letter-spacing: 0.2em;\n    text-transform: uppercase;\n    color: var(--aqua);\n    margin-bottom: 4px;\n  }\n  .readout-price .unit {\n    font-family: 'Archivo', sans-serif;\n    font-weight: 900;\n    font-size: 36px;\n    letter-spacing: -0.03em;\n    line-height: 1;\n  }\n  .readout-price .unit .strike {\n    font-size: 16px;\n    color: rgba(255,255,255,0.4);\n    text-decoration: line-through;\n    font-weight: 600;\n    margin-right: 8px;\n    vertical-align: middle;\n  }\n  .readout-price .total {\n    font-size: 12px;\n    color: rgba(255,255,255,0.7);\n    font-family: 'JetBrains Mono', monospace;\n    letter-spacing: 0.05em;\n    margin-top: 6px;\n  }\n  .readout-price .total b {\n    color: var(--foam);\n    font-weight: 700;\n  }\n\n  \/* Quantity slider *\/\n  .qty-slider-wrap {\n    margin: 0 0 24px;\n  }\n  .qty-slider {\n    -webkit-appearance: none;\n    appearance: none;\n    width: 100%;\n    height: 8px;\n    border-radius: 100px;\n    background: var(--paper-warm);\n    border: 1px solid var(--line);\n    outline: none;\n  }\n  .qty-slider::-webkit-slider-thumb {\n    -webkit-appearance: none;\n    appearance: none;\n    width: 32px;\n    height: 32px;\n    border-radius: 50%;\n    background: linear-gradient(135deg, var(--ocean-deep), var(--aqua));\n    border: 3px solid var(--foam);\n    box-shadow: 0 4px 12px rgba(0, 70, 110, 0.35);\n    cursor: pointer;\n    transition: transform 0.2s ease;\n  }\n  .qty-slider::-webkit-slider-thumb:hover {\n    transform: scale(1.15);\n  }\n  .qty-slider::-moz-range-thumb {\n    width: 32px;\n    height: 32px;\n    border-radius: 50%;\n    background: linear-gradient(135deg, var(--ocean-deep), var(--aqua));\n    border: 3px solid var(--foam);\n    box-shadow: 0 4px 12px rgba(0, 70, 110, 0.35);\n    cursor: pointer;\n  }\n  .qty-ticks {\n    position: relative;\n    height: 14px;\n    margin-top: 10px;\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 10px;\n    letter-spacing: 0.1em;\n    color: var(--ink-soft);\n  }\n  .qty-ticks span {\n    position: absolute;\n    top: 0;\n    transform: translateX(-50%);\n    white-space: nowrap;\n  }\n\n  \/* Tier table — auto-fit lets the grid reflow based on the actual\n     available width (no media\/container queries needed). In a 1100px\n     description it stays 7 columns; in a 400px sidebar it wraps to 3. *\/\n  .tier-grid {\n    display: grid;\n    grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));\n    gap: 6px;\n  }\n  .tier {\n    background: var(--foam);\n    border: 1.5px solid var(--line);\n    border-radius: 12px;\n    padding: 14px 10px;\n    text-align: center;\n    transition: all 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);\n    cursor: pointer;\n    position: relative;\n  }\n  .tier:hover {\n    border-color: var(--aqua);\n    transform: translateY(-2px);\n  }\n  .tier.active {\n    background: linear-gradient(160deg, var(--ocean-deep), var(--ocean));\n    border-color: var(--ocean-deep);\n    color: var(--foam);\n    transform: translateY(-3px);\n    box-shadow: 0 10px 24px rgba(0, 70, 110, 0.3);\n  }\n  .tier .qty {\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 10px;\n    letter-spacing: 0.12em;\n    text-transform: uppercase;\n    color: var(--ink-soft);\n    margin-bottom: 6px;\n  }\n  .tier.active .qty { color: rgba(255,255,255,0.7); }\n  .tier .disc {\n    font-family: 'Archivo', sans-serif;\n    font-weight: 900;\n    font-style: italic;\n    font-size: 24px;\n    letter-spacing: -0.03em;\n    line-height: 1;\n    color: var(--ocean-deep);\n  }\n  .tier.active .disc { color: var(--sun); }\n  .tier .disc.zero { color: var(--ink-soft); opacity: 0.5; }\n  .tier .price-each {\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 10px;\n    color: var(--ocean);\n    margin-top: 4px;\n    letter-spacing: 0.05em;\n  }\n  .tier.active .price-each { color: var(--aqua); }\n\n  \/* Bulk inquiry banner (qty 50+) *\/\n  .bulk-inquiry {\n    margin-top: 14px;\n    padding: 22px 24px;\n    border-radius: 14px;\n    background: linear-gradient(135deg, var(--ocean-deep), var(--ocean));\n    color: var(--foam);\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    gap: 18px;\n    flex-wrap: wrap;\n    box-shadow: 0 14px 32px rgba(0, 50, 77, 0.28);\n    overflow: hidden;\n    position: relative;\n    opacity: 0;\n    transform: translateY(8px);\n    pointer-events: none;\n    max-height: 0;\n    margin-top: 0;\n    padding-top: 0;\n    padding-bottom: 0;\n    transition: opacity 0.4s ease, transform 0.4s ease, max-height 0.45s ease, margin-top 0.45s ease, padding 0.45s ease;\n  }\n  .bulk-inquiry.show {\n    opacity: 1;\n    transform: translateY(0);\n    pointer-events: auto;\n    max-height: 240px;\n    margin-top: 14px;\n    padding-top: 22px;\n    padding-bottom: 22px;\n  }\n  .bulk-inquiry::before {\n    content: \"\";\n    position: absolute;\n    top: -40%;\n    right: -10%;\n    width: 280px;\n    height: 280px;\n    background: radial-gradient(circle, rgba(31,182,193,0.35), transparent 70%);\n    pointer-events: none;\n  }\n  .bulk-inquiry-text { position: relative; flex: 1 1 320px; }\n  .bulk-inquiry-eyebrow {\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 11px;\n    letter-spacing: 0.18em;\n    color: var(--sun);\n    text-transform: uppercase;\n    margin-bottom: 8px;\n  }\n  .bulk-inquiry h4 {\n    font-family: 'Archivo', sans-serif;\n    font-weight: 900;\n    font-size: 22px;\n    line-height: 1.15;\n    letter-spacing: -0.02em;\n    margin: 0 0 6px;\n  }\n  .bulk-inquiry h4 em {\n    font-style: italic;\n    color: var(--aqua);\n  }\n  .bulk-inquiry p {\n    font-size: 14px;\n    line-height: 1.5;\n    color: rgba(255,255,255,0.82);\n    margin: 0;\n  }\n  .bulk-inquiry-cta {\n    position: relative;\n    display: inline-flex;\n    align-items: center;\n    gap: 10px;\n    padding: 14px 22px;\n    background: var(--sun);\n    color: var(--ocean-deep);\n    text-decoration: none;\n    border-radius: 999px;\n    font-family: 'Archivo', sans-serif;\n    font-weight: 800;\n    font-size: 14px;\n    letter-spacing: 0.04em;\n    text-transform: uppercase;\n    transition: transform 0.2s ease, box-shadow 0.2s ease;\n    flex-shrink: 0;\n  }\n  .bulk-inquiry-cta:hover {\n    transform: translateY(-2px);\n    box-shadow: 0 10px 24px rgba(255, 200, 87, 0.4);\n  }\n  .bulk-inquiry-cta svg { width: 16px; height: 16px; }\n\n  \/* Quote request modal *\/\n  .quote-modal-overlay {\n    position: fixed;\n    inset: 0;\n    background: rgba(0, 30, 50, 0.6);\n    backdrop-filter: blur(6px);\n    -webkit-backdrop-filter: blur(6px);\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    z-index: 99999;\n    padding: 20px;\n    opacity: 0;\n    pointer-events: none;\n    transition: opacity 0.25s ease;\n  }\n  .quote-modal-overlay.show {\n    opacity: 1;\n    pointer-events: auto;\n  }\n  .quote-modal {\n    position: relative;\n    background: #ffffff;\n    border-radius: 18px;\n    width: 100%;\n    max-width: 520px;\n    \/* iOS Safari: 92dvh follows the dynamic viewport (excludes the URL bar\n       when it appears), preventing the modal from being clipped on phones.\n       Falls back to 92vh on browsers without dvh support. *\/\n    max-height: 92vh;\n    max-height: 92dvh;\n    overflow-y: auto;\n    \/* Prevent scroll chaining: when the modal reaches its top\/bottom edge,\n       the scroll DOES NOT propagate to the page below. Critical on iOS to\n       avoid the bouncing\/locked feeling. *\/\n    overscroll-behavior: contain;\n    \/* Smooth touch-scrolling on older iOS (deprecated but harmless on new). *\/\n    -webkit-overflow-scrolling: touch;\n    box-shadow: 0 30px 80px rgba(0, 30, 50, 0.4);\n    transform: translateY(20px) scale(0.96);\n    transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);\n  }\n  .quote-modal-overlay.show .quote-modal { transform: translateY(0) scale(1); }\n  .quote-modal-header {\n    padding: 28px 32px 18px;\n    background: linear-gradient(135deg, var(--ocean-deep), var(--ocean));\n    color: var(--foam);\n    border-radius: 18px 18px 0 0;\n    position: relative;\n    overflow: hidden;\n  }\n  .quote-modal-header::before {\n    content: \"\";\n    position: absolute;\n    top: -50%;\n    right: -20%;\n    width: 220px;\n    height: 220px;\n    background: radial-gradient(circle, rgba(31,182,193,0.4), transparent 70%);\n    pointer-events: none;\n  }\n  .quote-modal-eyebrow {\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 11px;\n    letter-spacing: 0.18em;\n    text-transform: uppercase;\n    color: var(--sun);\n    margin-bottom: 6px;\n    position: relative;\n  }\n  .quote-modal-header h3 {\n    font-family: 'Archivo', sans-serif;\n    font-weight: 900;\n    font-size: 24px;\n    line-height: 1.15;\n    letter-spacing: -0.02em;\n    margin: 0 0 6px;\n    position: relative;\n  }\n  .quote-modal-header h3 em { font-style: italic; color: var(--aqua); }\n  .quote-modal-header p {\n    font-size: 13px;\n    line-height: 1.5;\n    color: rgba(255,255,255,0.78);\n    margin: 0;\n    position: relative;\n  }\n  .quote-modal-close {\n    position: absolute;\n    top: 16px;\n    right: 16px;\n    \/* Visible button stays compact 32x32 so it doesn't get clipped by the\n       header's rounded top-right corner (border-radius 18px + overflow:hidden).\n       The ::before pseudo-element extends the clickable hit-area to 44x44\n       outside the visible button — invisible, but catches taps. *\/\n    width: 32px;\n    height: 32px;\n    border-radius: 50%;\n    background: rgba(255,255,255,0.15);\n    border: none;\n    color: #fff;\n    cursor: pointer;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    font-size: 20px;\n    line-height: 1;\n    transition: background 0.2s ease, transform 0.2s ease;\n    z-index: 2;\n  }\n  \/* Invisible hit-area extender: takes the clickable area from 32x32 visible\n     to ~44x44 effective, without affecting the visual size. *\/\n  .quote-modal-close::before {\n    content: \"\";\n    position: absolute;\n    inset: -6px;\n    border-radius: 50%;\n  }\n  .quote-modal-close:hover { background: rgba(255,255,255,0.28); transform: rotate(90deg); }\n  .quote-modal-body {\n    padding: 24px 32px 32px;\n  }\n  .quote-form-row {\n    display: grid;\n    gap: 16px;\n    margin-bottom: 14px;\n  }\n  .quote-form-row.two { grid-template-columns: 1fr 1fr; }\n  @media (max-width: 480px) {\n    .quote-form-row.two { grid-template-columns: 1fr; }\n    .quote-modal-header { padding: 22px 22px 16px; }\n    .quote-modal-body { padding: 20px 22px 26px; }\n  }\n  .quote-field { display: flex; flex-direction: column; gap: 6px; }\n  .quote-field label {\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 10px;\n    letter-spacing: 0.15em;\n    text-transform: uppercase;\n    color: var(--ink-soft);\n    font-weight: 600;\n  }\n  .quote-field label .req { color: var(--coral); }\n  .quote-field label .opt {\n    color: var(--ink-soft);\n    opacity: 0.6;\n    font-size: 9px;\n    margin-left: 4px;\n    text-transform: none;\n    letter-spacing: 0.05em;\n  }\n  .quote-field input,\n  .quote-field select,\n  .quote-field textarea {\n    font-family: 'Archivo', sans-serif;\n    font-size: 14px;\n    color: var(--ink);\n    background: var(--foam);\n    border: 1.5px solid var(--line);\n    border-radius: 10px;\n    padding: 11px 14px;\n    outline: none;\n    transition: border-color 0.2s ease, background 0.2s ease;\n    width: 100%;\n    box-sizing: border-box;\n  }\n  .quote-field input:focus,\n  .quote-field select:focus,\n  .quote-field textarea:focus {\n    border-color: var(--ocean);\n    background: #fff;\n  }\n  \/* iOS Safari triggers auto-zoom on text\/textarea inputs whose font-size\n     is below 16px. With body in position:fixed (our scroll lock), that\n     zoom gets stuck and the virtual keyboard fails to open — only\n     type=\"number\" and type=\"email\" remain functional. Force 16px on\n     mobile to disable the auto-zoom. *\/\n  @media (max-width: 640px) {\n    .quote-field input,\n    .quote-field select,\n    .quote-field textarea {\n      font-size: 16px;\n    }\n  }\n  .quote-field input.invalid,\n  .quote-field select.invalid {\n    border-color: var(--coral);\n    background: #fff5f3;\n  }\n  .quote-field-error {\n    color: var(--coral);\n    font-size: 11px;\n    font-family: 'JetBrains Mono', monospace;\n    margin-top: 2px;\n    display: none;\n  }\n  .quote-field-error.show { display: block; }\n\n  \/* Honeypot anti-spam: hidden off-screen for humans, but still in the DOM\n     and submitted by naive bots that auto-fill every visible input. We\n     avoid display:none \/ visibility:hidden because some bots skip those. *\/\n  .quote-honeypot {\n    position: absolute;\n    left: -10000px;\n    top: auto;\n    width: 1px;\n    height: 1px;\n    overflow: hidden;\n  }\n  .quote-modal-submit {\n    width: 100%;\n    margin-top: 8px;\n    padding: 16px 22px;\n    background: linear-gradient(135deg, var(--ocean-deep), var(--ocean));\n    color: var(--foam);\n    border: none;\n    border-radius: 12px;\n    font-family: 'Archivo', sans-serif;\n    font-weight: 800;\n    font-size: 15px;\n    letter-spacing: 0.04em;\n    text-transform: uppercase;\n    cursor: pointer;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    gap: 10px;\n    transition: transform 0.2s ease, box-shadow 0.2s ease;\n  }\n  .quote-modal-submit:hover {\n    transform: translateY(-1px);\n    box-shadow: 0 12px 28px rgba(0, 70, 110, 0.35);\n  }\n  .quote-modal-submit svg { width: 16px; height: 16px; }\n  .quote-modal-footnote {\n    text-align: center;\n    font-size: 11px;\n    color: var(--ink-soft);\n    margin-top: 14px;\n  }\n  .quote-success {\n    text-align: center;\n    padding: 40px 20px;\n  }\n  .quote-success .check {\n    width: 64px;\n    height: 64px;\n    border-radius: 50%;\n    background: linear-gradient(135deg, #22c55e, #16a34a);\n    color: #fff;\n    margin: 0 auto 18px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    font-size: 32px;\n    font-weight: 700;\n  }\n  .quote-success h4 {\n    font-family: 'Archivo', sans-serif;\n    font-weight: 900;\n    font-size: 22px;\n    margin: 0 0 8px;\n    color: var(--ink);\n  }\n  .quote-success p {\n    font-size: 14px;\n    color: var(--ink-soft);\n    margin: 0 auto;\n    max-width: 36ch;\n    line-height: 1.5;\n  }\n\n  @media (max-width: 720px) {\n    .pricing-readout { grid-template-columns: 1fr; gap: 16px; text-align: left; }\n    .readout-discount, .readout-price { text-align: left; }\n    .tier-grid { grid-template-columns: repeat(2, 1fr); }\n    .bulk-inquiry { padding: 18px 16px; }\n    .bulk-inquiry h4 { font-size: 18px; }\n    .pricing::before { display: none; }\n  }\n\n  \/* ============ HERO BANNER ============ *\/\n  .hero {\n    position: relative;\n    border-radius: 28px;\n    overflow: hidden;\n    background: linear-gradient(160deg, var(--ocean-deep) 0%, var(--ocean) 45%, var(--aqua) 100%);\n    color: var(--foam);\n    padding: 64px 48px 72px;\n    isolation: isolate;\n    display: grid;\n    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n    gap: 40px;\n    align-items: center;\n  }\n  .hero-text { position: relative; z-index: 2; }\n  .hero-visual {\n    position: relative;\n    z-index: 1;\n    aspect-ratio: 1 \/ 1;\n    width: 100%;\n    max-width: 460px;\n    justify-self: end;\n    border-radius: 24px;\n    overflow: hidden;\n    background:\n      radial-gradient(ellipse at 30% 20%, rgba(255,255,255,0.35), transparent 55%),\n      linear-gradient(150deg, rgba(255,255,255,0.18), rgba(255,255,255,0.04));\n    border: 1px solid rgba(255,255,255,0.22);\n    box-shadow: 0 30px 60px -20px rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.18);\n    backdrop-filter: blur(4px);\n  }\n  .hero-visual svg.honeycomb,\n  .hero-visual img.honeycomb {\n    position: absolute;\n    inset: 0;\n    width: 100%;\n    height: 100%;\n    display: block;\n    object-fit: cover;\n  }\n  .hero-visual .hc-label {\n    position: absolute;\n    left: 18px; bottom: 18px;\n    z-index: 3;\n    display: inline-flex; flex-direction: column; gap: 4px;\n    padding: 10px 14px;\n    background: rgba(255,255,255,0.92);\n    color: var(--ink);\n    border-radius: 12px;\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 10px;\n    letter-spacing: 0.18em;\n    text-transform: uppercase;\n    box-shadow: 0 8px 24px -8px rgba(0,0,0,0.3);\n  }\n  .hero-visual .hc-label strong {\n    font-family: 'Archivo Narrow', sans-serif;\n    font-size: 18px;\n    letter-spacing: -0.01em;\n    text-transform: none;\n    font-weight: 800;\n    color: var(--ocean-deep);\n  }\n  .hero-visual .hc-feather {\n    position: absolute;\n    right: 16px; top: 16px;\n    z-index: 3;\n    display: inline-flex; align-items: center; gap: 6px;\n    padding: 6px 12px;\n    background: rgba(255,255,255,0.18);\n    border: 1px solid rgba(255,255,255,0.4);\n    color: #fff;\n    border-radius: 100px;\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 10px;\n    letter-spacing: 0.2em;\n    text-transform: uppercase;\n    backdrop-filter: blur(6px);\n  }\n  .hero-visual .hc-feather::before { content: \"\"; width: 5px; height: 5px; background: var(--sun); border-radius: 50%; box-shadow: 0 0 0 3px rgba(245,177,61,0.4); }\n  @keyframes hc-breathe { 0%,100% { opacity: 0.7; } 50% { opacity: 1; } }\n  .hero-visual svg.honeycomb .cell-a { animation: hc-breathe 5s ease-in-out infinite; }\n  .hero-visual svg.honeycomb .cell-b { animation: hc-breathe 5s ease-in-out infinite; animation-delay: -1.6s; }\n  .hero-visual svg.honeycomb .cell-c { animation: hc-breathe 5s ease-in-out infinite; animation-delay: -3.2s; }\n  .hero::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    background:\n      radial-gradient(circle at 85% 20%, rgba(245, 177, 61, 0.35), transparent 45%),\n      radial-gradient(circle at 10% 90%, rgba(255, 255, 255, 0.18), transparent 50%);\n    z-index: -1;\n  }\n  .hero svg.waves {\n    position: absolute;\n    left: 0; right: 0; bottom: -2px;\n    width: 100%;\n    height: 110px;\n    z-index: 0;\n  }\n  .hero-eyebrow {\n    display: inline-flex;\n    align-items: center;\n    gap: 10px;\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 11px;\n    letter-spacing: 0.22em;\n    text-transform: uppercase;\n    background: rgba(255,255,255,0.14);\n    border: 1px solid rgba(255,255,255,0.3);\n    padding: 8px 14px;\n    border-radius: 100px;\n    backdrop-filter: blur(6px);\n  }\n  .hero-eyebrow .dot {\n    width: 6px; height: 6px;\n    background: var(--sun);\n    border-radius: 50%;\n    box-shadow: 0 0 0 4px rgba(245,177,61,0.3);\n  }\n  .hero h2 {\n    font-family: 'Archivo', sans-serif;\n    font-weight: 900;\n    font-size: clamp(40px, 6vw, 76px);\n    line-height: 0.95;\n    letter-spacing: -0.03em;\n    margin: 22px 0 18px;\n    text-wrap: balance;\n  }\n  .hero h2 .ital {\n    font-style: italic;\n    font-weight: 800;\n    color: var(--sun);\n  }\n  .hero p {\n    font-size: 17px;\n    line-height: 1.5;\n    max-width: 540px;\n    opacity: 0.92;\n    margin: 0;\n  }\n  .hero-meta {\n    display: flex;\n    gap: 24px;\n    margin-top: 36px;\n    flex-wrap: wrap;\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 12px;\n    letter-spacing: 0.08em;\n    text-transform: uppercase;\n  }\n  .hero-meta span {\n    display: flex; align-items: center; gap: 8px;\n  }\n  .hero-meta span::before {\n    content: \"\";\n    width: 8px; height: 8px;\n    border: 1.5px solid var(--sun);\n    transform: rotate(45deg);\n  }\n\n  \/* ============ SECTION HEAD ============ *\/\n  .section-head {\n    margin: 72px 0 28px;\n    display: flex;\n    align-items: end;\n    justify-content: space-between;\n    gap: 24px;\n    flex-wrap: wrap;\n  }\n  .section-head .num {\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 12px;\n    color: var(--ocean);\n    letter-spacing: 0.2em;\n  }\n  .section-head h2 {\n    font-family: 'Archivo Narrow', sans-serif;\n    font-weight: 700;\n    font-size: clamp(34px, 4.5vw, 54px);\n    line-height: 0.95;\n    letter-spacing: -0.02em;\n    margin: 6px 0 0;\n    text-transform: uppercase;\n  }\n  .section-head .lede {\n    max-width: 360px;\n    font-size: 14px;\n    line-height: 1.5;\n    color: var(--ink-soft);\n  }\n\n  \/* ============ TECHNOLOGY CARDS (Microsense \u0026 Native) ============ *\/\n  .tech-grid {\n    display: grid;\n    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));\n    gap: 20px;\n  }\n  .tech-card {\n    position: relative;\n    border-radius: 24px;\n    padding: 36px 32px 32px;\n    overflow: hidden;\n    color: var(--foam);\n    isolation: isolate;\n    min-height: 460px;\n    display: flex;\n    flex-direction: column;\n  }\n  .tech-card.acquazero {\n    background:\n      radial-gradient(ellipse 600px 400px at 80% 10%, rgba(31,182,193,0.7), transparent),\n      linear-gradient(160deg, var(--ocean-deep), var(--ocean));\n  }\n  .tech-card.eclipse {\n    background:\n      radial-gradient(ellipse 500px 400px at 90% 90%, rgba(245,177,61,0.55), transparent),\n      linear-gradient(160deg, var(--ink), var(--ink-soft));\n  }\n  .tech-card .badge {\n    display: inline-flex;\n    align-items: center;\n    gap: 8px;\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 10px;\n    letter-spacing: 0.2em;\n    text-transform: uppercase;\n    background: rgba(255,255,255,0.15);\n    border: 1px solid rgba(255,255,255,0.3);\n    padding: 6px 12px;\n    border-radius: 100px;\n    align-self: flex-start;\n  }\n  .tech-card h3 {\n    font-family: 'Archivo', sans-serif;\n    font-weight: 900;\n    font-style: italic;\n    font-size: 64px;\n    line-height: 0.9;\n    letter-spacing: -0.04em;\n    margin: 22px 0 6px;\n  }\n  .tech-card .tagline {\n    font-size: 15px;\n    opacity: 0.85;\n    margin: 0 0 28px;\n    max-width: 280px;\n    line-height: 1.4;\n  }\n  .tech-features {\n    list-style: none;\n    padding: 0;\n    margin: auto 0 0;\n    display: grid;\n    gap: 12px;\n  }\n  .tech-features li {\n    display: flex;\n    align-items: center;\n    gap: 14px;\n    padding: 12px 14px;\n    background: rgba(255,255,255,0.08);\n    border: 1px solid rgba(255,255,255,0.14);\n    border-radius: 14px;\n    backdrop-filter: blur(8px);\n    transition: transform 0.3s ease, background 0.3s ease;\n  }\n  .tech-features li:hover {\n    transform: translateX(4px);\n    background: rgba(255,255,255,0.14);\n  }\n  .tech-features .ico {\n    width: 38px; height: 38px;\n    flex-shrink: 0;\n    border-radius: 10px;\n    display: grid;\n    place-items: center;\n    font-size: 18px;\n    background: rgba(255,255,255,0.16);\n  }\n  .tech-card.eclipse .tech-features .ico {\n    background: rgba(245,177,61,0.25);\n  }\n  .tech-features .label {\n    font-size: 14px;\n    font-weight: 600;\n    letter-spacing: 0.01em;\n  }\n\n  \/* Decorative drop \/ sun *\/\n  .tech-card .deco {\n    position: absolute;\n    top: 28px; right: 28px;\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 10px;\n    letter-spacing: 0.18em;\n    opacity: 0.55;\n  }\n  .tech-card .ring {\n    position: absolute;\n    border-radius: 50%;\n    border: 1.5px dashed rgba(255,255,255,0.18);\n    pointer-events: none;\n  }\n  .acquazero .ring-1 { width: 320px; height: 320px; top: -120px; right: -100px; animation: spin 60s linear infinite; }\n  .acquazero .ring-2 { width: 180px; height: 180px; top: -40px; right: -20px; animation: spin 40s linear infinite reverse; }\n  .eclipse .ring-1 { width: 280px; height: 280px; bottom: -100px; right: -80px; animation: spin 70s linear infinite; }\n  .eclipse .feather {\n    position: absolute;\n    width: 86px; height: 150px;\n    top: 18px; right: 26px;\n    pointer-events: none;\n    opacity: 0.92;\n    filter: drop-shadow(0 6px 18px rgba(255,255,255,0.18));\n    transform-origin: 50% 8%;\n    animation: feather-float 7s ease-in-out infinite;\n  }\n  @keyframes spin {\n    to { transform: rotate(360deg); }\n  }\n  @keyframes feather-float {\n    0%, 100% { transform: translate(0, 0) rotate(18deg); }\n    50%      { transform: translate(-6px, -10px) rotate(24deg); }\n  }\n\n  \/* ============ PERFORMANCE STRIP ============ *\/\n  .perf-strip {\n    background: var(--ink);\n    color: var(--foam);\n    border-radius: 24px;\n    padding: 48px 40px;\n    margin-top: 28px;\n    position: relative;\n    overflow: hidden;\n  }\n  .perf-strip::after {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    background: radial-gradient(ellipse 800px 200px at 50% 100%, rgba(31,182,193,0.25), transparent);\n    pointer-events: none;\n  }\n  .perf-strip h3 {\n    font-family: 'Archivo Narrow', sans-serif;\n    text-transform: uppercase;\n    letter-spacing: -0.01em;\n    font-size: 32px;\n    font-weight: 700;\n    margin: 0 0 6px;\n  }\n  .perf-strip .sub {\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 11px;\n    letter-spacing: 0.2em;\n    color: var(--aqua);\n    text-transform: uppercase;\n    margin: 0 0 32px;\n  }\n  .perf-grid {\n    display: grid;\n    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n    gap: 16px;\n    position: relative;\n    z-index: 1;\n  }\n  .perf-card {\n    background: rgba(255,255,255,0.04);\n    border: 1px solid rgba(255,255,255,0.1);\n    border-radius: 16px;\n    padding: 22px 20px;\n    transition: all 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);\n    cursor: default;\n  }\n  .perf-card:hover {\n    background: rgba(31,182,193,0.12);\n    border-color: var(--aqua);\n    transform: translateY(-4px);\n  }\n  .perf-card .icon-box {\n    width: 48px; height: 48px;\n    border-radius: 12px;\n    background: linear-gradient(135deg, var(--aqua), var(--ocean));\n    display: grid;\n    place-items: center;\n    font-size: 22px;\n    margin-bottom: 18px;\n  }\n  .perf-card h4 {\n    font-family: 'Archivo', sans-serif;\n    font-size: 17px;\n    font-weight: 800;\n    margin: 0 0 6px;\n    letter-spacing: -0.01em;\n  }\n  .perf-card p {\n    font-size: 13px;\n    line-height: 1.45;\n    color: rgba(255,255,255,0.65);\n    margin: 0;\n  }\n\n  \/* ============ CUSTOM PRINT STRIP ============ *\/\n  .custom-strip {\n    background: linear-gradient(140deg, color-mix(in oklab, var(--ocean-deep) 70%, black) 0%, var(--ocean-deep) 50%, color-mix(in oklab, var(--ocean) 80%, var(--aqua)) 100%);\n    color: var(--foam);\n    border-radius: 28px;\n    padding: 56px 48px;\n    margin-top: 24px;\n    position: relative;\n    overflow: hidden;\n  }\n  .custom-strip::before {\n    content: \"\/\/ 01 → 50+ pieces\";\n    position: absolute;\n    top: 22px; right: 28px;\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 11px;\n    letter-spacing: 0.22em;\n    text-transform: uppercase;\n    color: rgba(255,255,255,0.55);\n  }\n  .custom-strip::after {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    background: radial-gradient(900px circle at 110% -10%, rgba(31,182,193,0.28), transparent 55%),\n                radial-gradient(700px circle at -10% 110%, rgba(255,255,255,0.06), transparent 60%);\n    pointer-events: none;\n  }\n  .custom-strip h3 {\n    font-family: 'Archivo Narrow', sans-serif;\n    text-transform: uppercase;\n    font-size: 36px;\n    font-weight: 700;\n    letter-spacing: -0.01em;\n    margin: 0 0 6px;\n    position: relative;\n    z-index: 1;\n  }\n  .custom-strip .sub {\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 11px;\n    letter-spacing: 0.22em;\n    text-transform: uppercase;\n    color: rgba(255,255,255,0.6);\n    margin: 0 0 32px;\n    position: relative;\n    z-index: 1;\n  }\n  .custom-grid {\n    display: grid;\n    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n    gap: 16px;\n    position: relative;\n    z-index: 1;\n  }\n  .custom-card {\n    background: rgba(255,255,255,0.05);\n    border: 1px solid rgba(255,255,255,0.12);\n    border-radius: 18px;\n    padding: 24px 22px;\n    position: relative;\n    overflow: hidden;\n    transition: transform .3s cubic-bezier(.2,.8,.2,1), background .3s, border-color .3s;\n  }\n  .custom-card:hover {\n    background: rgba(31,182,193,0.14);\n    border-color: var(--aqua);\n    transform: translateY(-4px);\n  }\n  .custom-num {\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 11px;\n    letter-spacing: 0.2em;\n    color: var(--aqua);\n    margin-bottom: 18px;\n  }\n  .custom-card h4 {\n    font-family: 'Archivo', sans-serif;\n    font-size: 17px;\n    font-weight: 700;\n    margin: 0 0 8px;\n    color: var(--foam);\n    letter-spacing: -0.01em;\n  }\n  .custom-card p {\n    font-size: 13px;\n    line-height: 1.5;\n    color: rgba(255,255,255,0.7);\n    margin: 0;\n  }\n\n  \/* ============ USE CASES ============ *\/\n  .usecase { margin-top: 28px; display: flex; flex-direction: column; gap: 20px; }\n  .compare { background: linear-gradient(160deg, var(--paper-warm), #fff); border: 1px solid var(--line); border-radius: 24px; padding: 32px 28px; position: relative; overflow: hidden; }\n  .compare::before { content: \"\/\/ vs · standard sports tee\"; position: absolute; top: 16px; right: 22px; font-family: 'JetBrains Mono', monospace; font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--ocean); opacity: 0.6; }\n  .compare h3 { font-family: 'Archivo Narrow', sans-serif; text-transform: uppercase; font-size: 26px; font-weight: 700; margin: 14px 0 6px; line-height: 1; letter-spacing: -0.01em; }\n  .compare h3 .em { font-family: 'Archivo', sans-serif; font-style: italic; font-weight: 900; background: linear-gradient(110deg, var(--ocean-deep), var(--aqua)); -webkit-background-clip: text; background-clip: text; color: transparent; }\n  .compare-lead { font-size: 13px; line-height: 1.55; color: var(--ink-soft); margin: 0 0 22px; }\n  .compare-rows { display: grid; gap: 8px; }\n  .compare-row { display: grid; grid-template-columns: 1fr 1fr; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; background: #fff; }\n  .compare-row .col { padding: 12px 14px; font-size: 12.5px; line-height: 1.35; display: flex; align-items: center; gap: 10px; }\n  .compare-row .col.lo { color: var(--ink-soft); background: rgba(10, 31, 44, 0.025); }\n  .compare-row .col.hi { color: var(--ink); font-weight: 600; background: linear-gradient(110deg, rgba(31, 182, 193, 0.12), rgba(0, 102, 162, 0.06)); border-left: 1px solid var(--line); }\n  .compare-row .col.hi::before { content: \"\"; width: 12px; height: 12px; border-radius: 50%; background: linear-gradient(135deg, var(--ocean-deep), var(--aqua)); flex-shrink: 0; box-shadow: 0 0 0 3px rgba(31,182,193,0.2); }\n  .compare-row .col.lo::before { content: \"\"; width: 12px; height: 12px; border-radius: 50%; border: 1.5px solid var(--line); flex-shrink: 0; background: #fff; }\n  .compare-row .lab { grid-column: 1 \/ -1; background: var(--ink); color: var(--foam); font-family: 'JetBrains Mono', monospace; font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; padding: 8px 14px; }\n  .compare-pill { display: inline-flex; align-items: center; gap: 8px; font-family: 'JetBrains Mono', monospace; font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; background: var(--ink); color: var(--foam); padding: 6px 12px; border-radius: 100px; }\n  .compare-pill .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--sun); }\n  .compare { display: grid; grid-template-columns: auto 1fr auto; column-gap: 28px; row-gap: 14px; align-items: center; }\n  .compare .compare-pill { grid-column: 1 \/ -1; justify-self: start; }\n  .fit-headline { text-align: left; }\n  .fit-headline h3 { margin: 0 0 8px; font-size: 30px; }\n  .fit-headline .compare-lead { margin: 0; max-width: 60ch; }\n  .fit-mark { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; margin: 0; padding: 0; border-top: none; align-self: center; max-width: 220px; }\n  .fit-mark span { font-family: 'JetBrains Mono', monospace; font-size: 9px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ocean-deep); background: rgba(31, 182, 193, 0.08); padding: 6px 10px; border-radius: 100px; }\n  @media (max-width: 720px) { .compare { grid-template-columns: 1fr; } .fit-headline { text-align: left; } .fit-mark { justify-content: flex-start; max-width: none; } }\n  .usecase-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; align-content: start; }\n  .uc-card { background: #fff; border: 1px solid var(--line); border-radius: 18px; padding: 22px 20px 20px; position: relative; overflow: hidden; transition: transform .3s cubic-bezier(.2,.8,.2,1), border-color .3s ease, box-shadow .3s ease; display: flex; flex-direction: column; gap: 14px; }\n  .uc-card::before { content: \"\"; position: absolute; top: 0; left: 0; width: 4px; height: 100%; background: linear-gradient(180deg, var(--ocean-deep), var(--aqua)); opacity: 0.85; }\n  .uc-card:hover { transform: translateY(-4px); border-color: var(--ocean); box-shadow: 0 14px 30px rgba(0, 70, 110, 0.1); }\n  .uc-card:hover .uc-icon { background: linear-gradient(135deg, var(--ocean-deep), var(--aqua)); color: var(--foam); border-color: transparent; }\n  .uc-icon { width: 56px; height: 56px; border-radius: 14px; border: 1.5px solid var(--line); background: var(--paper-warm); display: grid; place-items: center; color: var(--ocean-deep); transition: all .3s ease; flex-shrink: 0; }\n  .uc-icon svg { width: 28px; height: 28px; stroke: currentColor; stroke-width: 1.6; fill: none; stroke-linecap: round; stroke-linejoin: round; }\n  .uc-num { font-family: 'JetBrains Mono', monospace; font-size: 9px; letter-spacing: 0.22em; color: var(--ocean); display: flex; align-items: center; gap: 8px; text-transform: uppercase; }\n  .uc-num::after { content: \"\"; flex: 1; height: 1px; background: var(--line); }\n  .uc-card h4 { font-family: 'Archivo Narrow', sans-serif; font-weight: 700; text-transform: uppercase; font-size: 20px; line-height: 1; margin: 0; letter-spacing: -0.01em; color: var(--ink); }\n  .uc-card h4 .ital { font-family: 'Archivo', sans-serif; font-style: italic; font-weight: 900; color: var(--ocean); }\n  .uc-benefit { font-size: 12.5px; line-height: 1.4; color: var(--ink-soft); margin: 0; padding: 10px 12px; background: rgba(31, 182, 193, 0.06); border-left: 2px solid var(--aqua); border-radius: 4px; }\n  .uc-benefit b { color: var(--ink); font-weight: 700; }\n  .uc-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: auto; }\n  .uc-tags span { font-family: 'JetBrains Mono', monospace; font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ocean-deep); background: rgba(0, 102, 162, 0.06); border: 1px solid rgba(0, 102, 162, 0.18); padding: 4px 8px; border-radius: 100px; }\n  @media (max-width: 900px) { .usecase-list { grid-template-columns: repeat(3, 1fr); } }\n  @media (max-width: 720px) { .usecase-list { grid-template-columns: 1fr 1fr; } }\n  @media (max-width: 540px) { .usecase-list { grid-template-columns: 1fr; } .compare-row { grid-template-columns: 1fr; } .compare-row .col.hi { border-left: none; border-top: 1px solid var(--line); } }\n\n  \/* ============ CERTIFICATIONS ============ *\/\n  .certs {\n    margin-top: 28px;\n    background: var(--paper-warm);\n    border-radius: 24px;\n    padding: 40px;\n    position: relative;\n    overflow: hidden;\n  }\n  .certs-head {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    margin-bottom: 28px;\n    flex-wrap: wrap;\n    gap: 16px;\n  }\n  .certs h3 {\n    font-family: 'Archivo Narrow', sans-serif;\n    text-transform: uppercase;\n    font-size: 28px;\n    font-weight: 700;\n    margin: 0;\n    letter-spacing: -0.01em;\n  }\n  .certs .stamp {\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 11px;\n    letter-spacing: 0.2em;\n    color: var(--ocean-deep);\n    text-transform: uppercase;\n    border: 1.5px solid var(--ocean-deep);\n    padding: 6px 12px;\n    border-radius: 100px;\n  }\n  .cert-grid {\n    display: grid;\n    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n    gap: 12px;\n  }\n  .cert {\n    background: var(--foam);\n    border: 1px solid var(--line);\n    border-radius: 16px;\n    padding: 22px 20px;\n    display: flex;\n    align-items: center;\n    gap: 14px;\n    transition: all 0.3s ease;\n  }\n  .cert:hover {\n    border-color: var(--ocean);\n    transform: translateY(-2px);\n    box-shadow: 0 8px 24px rgba(0,70,110,0.08);\n  }\n  .cert .glyph {\n    width: 44px; height: 44px;\n    border-radius: 12px;\n    background: var(--paper);\n    display: grid;\n    place-items: center;\n    font-size: 20px;\n    flex-shrink: 0;\n  }\n  .cert .name {\n    font-weight: 700;\n    font-size: 14px;\n    line-height: 1.2;\n    letter-spacing: -0.01em;\n  }\n  .cert .meta {\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 9px;\n    letter-spacing: 0.15em;\n    color: var(--ocean);\n    text-transform: uppercase;\n    margin-top: 3px;\n  }\n\n  \/* ============ FAQ ============ *\/\n  .faq {\n    margin-top: 28px;\n    background: var(--paper-warm);\n    border: 1px solid var(--line);\n    border-radius: 24px;\n    padding: 40px 36px;\n    position: relative;\n    overflow: hidden;\n  }\n  .faq::before {\n    content: \"\/\/ frequently asked\";\n    position: absolute;\n    top: 18px; right: 24px;\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 10px;\n    letter-spacing: 0.22em;\n    text-transform: uppercase;\n    color: var(--ocean);\n    opacity: 0.55;\n  }\n  .faq-list {\n    display: flex;\n    flex-direction: column;\n    gap: 0;\n    margin-top: 8px;\n  }\n  .faq-item {\n    border-top: 1px solid var(--line);\n    padding: 0;\n  }\n  .faq-item:last-child { border-bottom: 1px solid var(--line); }\n  .faq-item summary {\n    list-style: none;\n    cursor: pointer;\n    padding: 22px 48px 22px 0;\n    font-family: 'Archivo', sans-serif;\n    font-size: 17px;\n    font-weight: 600;\n    color: var(--ink);\n    letter-spacing: -0.005em;\n    position: relative;\n    transition: color .2s;\n  }\n  .faq-item summary::-webkit-details-marker { display: none; }\n  .faq-item summary::after {\n    content: \"+\";\n    position: absolute;\n    right: 4px; top: 50%;\n    transform: translateY(-50%);\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 22px;\n    color: var(--ocean-deep);\n    font-weight: 400;\n    transition: transform .25s cubic-bezier(.2,.8,.2,1);\n  }\n  .faq-item[open] summary::after { content: \"\\2013\"; }\n  .faq-item summary:hover { color: var(--ocean-deep); }\n  .faq-item .answer {\n    padding: 0 24px 24px 0;\n    font-size: 14.5px;\n    line-height: 1.65;\n    color: #4b5663;\n    max-width: 780px;\n  }\n  .faq-item .answer strong { color: var(--ink); }\n  @media (max-width: 720px) {\n    .faq { padding: 32px 22px; }\n    .faq-item summary { font-size: 15.5px; padding: 20px 40px 20px 0; }\n  }\n\n  \/* ============ CLOSING TICKER ============ *\/\n  .ticker {\n    margin-top: 28px;\n    background: var(--ocean-deep);\n    color: var(--foam);\n    border-radius: 100px;\n    overflow: hidden;\n    position: relative;\n    height: 56px;\n    display: flex;\n    align-items: center;\n  }\n  .ticker-track {\n    display: flex;\n    gap: 48px;\n    white-space: nowrap;\n    animation: ticker-scroll 28s linear infinite;\n    padding-right: 48px;\n  }\n  .ticker-track span {\n    font-family: 'Archivo Narrow', sans-serif;\n    font-weight: 700;\n    font-size: 18px;\n    text-transform: uppercase;\n    letter-spacing: 0.05em;\n    display: flex;\n    align-items: center;\n    gap: 48px;\n  }\n  .ticker-track span::after {\n    content: \"✦\";\n    color: var(--sun);\n  }\n  @keyframes ticker-scroll {\n    to { transform: translateX(-50%); }\n  }\n\n  \/* ============ INTRO ANIMATION ============ *\/\n  @media (prefers-reduced-motion: no-preference) {\n    [data-anim] {\n      opacity: 0;\n      will-change: opacity, transform, filter, clip-path;\n    }\n    [data-anim=\"fade\"]    { transform: translateY(8px); }\n    [data-anim=\"rise\"]    { transform: translateY(28px); }\n    [data-anim=\"rise-lg\"] { transform: translateY(56px); }\n    [data-anim=\"drop\"]    { transform: translateY(-22px); }\n    [data-anim=\"left\"]    { transform: translateX(-32px); }\n    [data-anim=\"right\"]   { transform: translateX(32px); }\n    [data-anim=\"scale\"]   { transform: scale(0.92); }\n    [data-anim=\"zoom\"]    { transform: scale(0.6); filter: blur(8px); }\n    [data-anim=\"reveal\"]  { clip-path: inset(0 100% 0 0); }\n    [data-anim=\"blur\"]    { filter: blur(14px); transform: translateY(12px); }\n\n    [data-anim].in {\n      opacity: 1;\n      transform: none;\n      filter: none;\n      clip-path: inset(0 0 0 0);\n      transition:\n        opacity 0.9s cubic-bezier(0.2, 0.8, 0.2, 1),\n        transform 1s cubic-bezier(0.2, 0.8, 0.2, 1),\n        filter 0.9s ease,\n        clip-path 1.1s cubic-bezier(0.7, 0, 0.3, 1);\n    }\n  }\n\n  \/* ============ TWEAKS — DENSITY ============ *\/\n  \/* Active preset: \"compact\" (tighter, denser). Base vars are inherited by\n     all density-scoped rules below. *\/\n  html { --tw-pad-scale: 1; --tw-radius-scale: 1; --tw-weight-shift: 0; --tw-tracking-add: 0em; --tw-line-shift: 0; }\n  html[data-density=\"compact\"]   { --tw-pad-scale: 0.72; --tw-radius-scale: 0.45; --tw-weight-shift: 100; --tw-tracking-add: -0.005em; --tw-line-shift: -0.06; }\n\n  \/* Apply density to the major surfaces *\/\n  html[data-density] .product-desc { padding: calc(24px * var(--tw-pad-scale)) calc(20px * var(--tw-pad-scale)) calc(80px * var(--tw-pad-scale)); }\n  html[data-density] .hero,\n  html[data-density] .perf-strip,\n  html[data-density] .custom-strip,\n  html[data-density] .certs,\n  html[data-density] .faq,\n  html[data-density] .pricing,\n  html[data-density] .compare,\n  html[data-density] .tech-card,\n  html[data-density] .uc-card,\n  html[data-density] .perf-card,\n  html[data-density] .custom-card,\n  html[data-density] .cert,\n  html[data-density] .pricing-readout,\n  html[data-density] .tier,\n  html[data-density] .bulk-inquiry { border-radius: calc(var(--natural-radius, 20px) * var(--tw-radius-scale)); }\n  \/* assign each surface its natural base radius via custom prop *\/\n  html[data-density] .hero          { --natural-radius: 28px; padding: calc(64px * var(--tw-pad-scale)) calc(48px * var(--tw-pad-scale)) calc(72px * var(--tw-pad-scale)); }\n  html[data-density] .perf-strip    { --natural-radius: 24px; padding: calc(48px * var(--tw-pad-scale)) calc(40px * var(--tw-pad-scale)); }\n  html[data-density] .custom-strip  { --natural-radius: 28px; padding: calc(56px * var(--tw-pad-scale)) calc(48px * var(--tw-pad-scale)); }\n  html[data-density] .certs         { --natural-radius: 24px; padding: calc(40px * var(--tw-pad-scale)); }\n  html[data-density] .faq           { --natural-radius: 24px; padding: calc(40px * var(--tw-pad-scale)) calc(36px * var(--tw-pad-scale)); }\n  html[data-density] .pricing       { --natural-radius: 20px; padding: calc(28px * var(--tw-pad-scale)) calc(28px * var(--tw-pad-scale)) calc(24px * var(--tw-pad-scale)); }\n  html[data-density] .compare       { --natural-radius: 24px; padding: calc(32px * var(--tw-pad-scale)) calc(28px * var(--tw-pad-scale)); }\n  html[data-density] .tech-card     { --natural-radius: 24px; padding: calc(36px * var(--tw-pad-scale)) calc(32px * var(--tw-pad-scale)) calc(32px * var(--tw-pad-scale)); }\n  html[data-density] .uc-card       { --natural-radius: 18px; padding: calc(22px * var(--tw-pad-scale)) calc(20px * var(--tw-pad-scale)) calc(20px * var(--tw-pad-scale)); }\n  html[data-density] .perf-card     { --natural-radius: 16px; padding: calc(22px * var(--tw-pad-scale)) calc(20px * var(--tw-pad-scale)); }\n  html[data-density] .custom-card   { --natural-radius: 18px; padding: calc(24px * var(--tw-pad-scale)) calc(22px * var(--tw-pad-scale)); }\n  html[data-density] .cert          { --natural-radius: 16px; padding: calc(22px * var(--tw-pad-scale)) calc(20px * var(--tw-pad-scale)); }\n  html[data-density] .pricing-readout { --natural-radius: 16px; padding: calc(22px * var(--tw-pad-scale)) calc(26px * var(--tw-pad-scale)); }\n  html[data-density] .bulk-inquiry  { --natural-radius: 14px; }\n  html[data-density] .tier          { --natural-radius: 12px; padding: calc(14px * var(--tw-pad-scale)) calc(10px * var(--tw-pad-scale)); }\n\n  \/* Editorial: lighter weights, looser tracking; Compact: heavier, tighter *\/\n  html[data-density] h1,\n  html[data-density] h2,\n  html[data-density] h3,\n  html[data-density] h4,\n  html[data-density] .pricing-title,\n  html[data-density] .uc-card h4 {\n    font-weight: calc(700 + var(--tw-weight-shift));\n    letter-spacing: calc(-0.02em + var(--tw-tracking-add));\n  }\n  html[data-density=\"compact\"]   .product-title h1 { font-weight: 800; letter-spacing: -0.035em; }\n  html[data-density=\"compact\"]   .hero h2 { font-weight: 900; letter-spacing: -0.045em; }\n\n  \/* Compact thickens borders, sharpens contrast *\/\n  html[data-density=\"compact\"] .pricing,\n  html[data-density=\"compact\"] .compare,\n  html[data-density=\"compact\"] .faq,\n  html[data-density=\"compact\"] .uc-card,\n  html[data-density=\"compact\"] .cert,\n  html[data-density=\"compact\"] .perf-card,\n  html[data-density=\"compact\"] .tier,\n  html[data-density=\"compact\"] .compare-row { border-width: 2px; }\n  html[data-density=\"compact\"] .uc-card::before { width: 6px; }\n\n  \/* ============ TWEAKS — MOTION ============ *\/\n  \/* Active preset: \"riptide\" (everything pulsing). *\/\n  html[data-motion=\"riptide\"] {\n    --tw-spin-mult: 0.18;     \/* rings spin much faster *\/\n    --tw-ticker-mult: 0.35;   \/* ticker much faster *\/\n    --tw-pulse-mult: 0.45;\n  }\n  html[data-motion=\"riptide\"] .acquazero .ring-1 { animation-duration: calc(60s * var(--tw-spin-mult)); }\n  html[data-motion=\"riptide\"] .acquazero .ring-2 { animation-duration: calc(40s * var(--tw-spin-mult)); }\n  html[data-motion=\"riptide\"] .eclipse .ring-1   { animation-duration: calc(70s * var(--tw-spin-mult)); }\n  html[data-motion=\"riptide\"] .ticker-track       { animation-duration: calc(28s * var(--tw-ticker-mult)); }\n  html[data-motion=\"riptide\"] .cta-btn--primary   { animation-duration: calc(2.6s * var(--tw-pulse-mult)); }\n  html[data-motion=\"riptide\"] .cta-btn--primary::before { animation-duration: calc(2.6s * var(--tw-pulse-mult)); }\n  html[data-motion=\"riptide\"] .cta-btn--primary::after  { animation-duration: calc(3.2s * var(--tw-pulse-mult)); }\n  html[data-motion=\"riptide\"] .cta-btn--primary .nudge  { animation-duration: calc(1.6s * var(--tw-pulse-mult)); }\n  html[data-motion=\"riptide\"] .product-title .pill .pulse { animation-duration: 0.8s; }\n  \/* In riptide, add a livelier float to the eclipse feather. *\/\n  html[data-motion=\"riptide\"] .eclipse .feather { animation-duration: 4.5s; }\n  html[data-motion=\"riptide\"] .hero-eyebrow .dot,\n  html[data-motion=\"riptide\"] .pricing-readout::after { animation: tw-glow 2.4s ease-in-out infinite; }\n  @keyframes tw-glow {\n    0%, 100% { opacity: 0.6; }\n    50%      { opacity: 1; }\n  }\n\n  \/* ============ RESPONSIVE ============ *\/\n  @media (max-width: 800px) {\n    .hero { padding: 44px 28px 56px; grid-template-columns: 1fr; gap: 28px; }\n    .hero-visual { max-width: 100%; justify-self: stretch; aspect-ratio: 16 \/ 11; }\n    .tech-grid { grid-template-columns: 1fr; }\n    .perf-grid { grid-template-columns: repeat(2, 1fr); }\n    .cert-grid { grid-template-columns: repeat(2, 1fr); }\n    .custom-grid { grid-template-columns: repeat(2, 1fr); }\n    .custom-strip { padding: 44px 28px; }\n    .custom-strip h3 { font-size: 28px; }\n    .product-desc { padding: 16px 12px 60px; }\n  }\n  @media (max-width: 480px) {\n    .perf-grid, .cert-grid { grid-template-columns: 1fr; }\n    .custom-grid { grid-template-columns: 1fr; }\n    .tech-card h3 { font-size: 48px; }\n  }\n\n  \/* ============ A11Y: respect prefers-reduced-motion ============ *\/\n  \/* Disable all infinite\/looping decorative animations when the user has\n     selected \"reduce motion\" in their OS settings. The brief one-shot\n     intro animations on [data-anim] are already guarded by their own\n     @media (prefers-reduced-motion: no-preference) block above and so\n     do not run at all in this mode. *\/\n  @media (prefers-reduced-motion: reduce) {\n    .acquazero .ring-1,\n    .acquazero .ring-2,\n    .eclipse .ring-1,\n    .eclipse .feather,\n    .ticker-track,\n    .product-title .pill .pulse,\n    .hero-visual svg.honeycomb .cell-a,\n    .hero-visual svg.honeycomb .cell-b,\n    .hero-visual svg.honeycomb .cell-c,\n    .cta-btn--primary,\n    .cta-btn--primary::before,\n    .cta-btn--primary::after,\n    .cta-btn--primary .nudge,\n    .pricing-readout::after,\n    .hero-eyebrow .dot {\n      animation: none !important;\n    }\n  }\n\n  \/* ============ PERF: content-visibility ============ *\/\n  \/* Sections below the initial fold: the browser skips layout\/paint\/style\n     until they scroll near the viewport. contain-intrinsic-size reserves\n     approximate space so the scrollbar doesn't jump. Supported by\n     Chrome\/Edge\/Safari 16+; older browsers ignore both properties safely. *\/\n  .perf-strip,\n  .custom-strip,\n  .usecase,\n  .certs,\n  .faq,\n  .ticker {\n    content-visibility: auto;\n    contain-intrinsic-size: auto 800px;\n  }\n\u003c\/style\u003e\n\n\n\u003cdiv class=\"product-desc\"\u003e\n\n  \u003c!-- ============ PRODUCT TITLE ============ --\u003e\n  \u003cheader class=\"product-title\" style=\"padding: 28px 8px 40px\"\u003e\n    \u003cdiv class=\"top-row\"\u003e\n      \u003cdiv class=\"pill\" data-anim=\"drop\"\u003e\n\u003cspan class=\"pulse\"\u003e\u003c\/span\u003eFully Customizable\u003c\/div\u003e\n      \u003cdiv class=\"meta-row\" data-anim=\"right\"\u003e\n        \u003cspan\u003eSKU · COM-RG-01\u003c\/span\u003e\n        \u003cspan\u003eComfort Series\u003c\/span\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"kicker\" data-anim=\"left\"\u003eComfort Fit · Relaxed Series\u003c\/div\u003e\n    \u003ch1 data-anim=\"reveal\"\u003eComfort Fit\u003cbr\u003e\u003cspan class=\"accent\"\u003eRashguard\u003c\/span\u003e\n\u003c\/h1\u003e\n    \u003cp class=\"product-full-title\" data-anim=\"rise\"\u003eMen’s Comfort Fit Rashguard SS - THUNDER MASTER\u003c\/p\u003e\n    \u003cp class=\"subline\" data-anim=\"blur\"\u003e\u003cstrong\u003eCustom relaxed-fit rashguard.\u003c\/strong\u003e Same Italian 4-way stretch knit at \u003cstrong\u003e220 g\/m²\u003c\/strong\u003e, same SITIP performance ; but cut with a \u003cstrong\u003eraglan sleeve and a relaxed silhouette\u003c\/strong\u003e that drapes instead of compresses. Print your \u003cstrong\u003elogo, numbers and sponsors\u003c\/strong\u003e, from \u003cstrong\u003e1 piece to full team kits\u003c\/strong\u003e ; all-day comfort for every body, no athletic build required.\u003c\/p\u003e\n    \u003cdiv class=\"feature-tabs\" data-anim-stagger=\"60\"\u003e\n      \u003cspan data-anim=\"rise\"\u003e✎ Custom Print\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003e◐ Acquazero\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003e☀ Eclipse UPF 50+\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003e↔ 4-Way Stretch\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003e🇮🇹 Made in Italy\u003c\/span\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Design CTAs (Shopify Liquid) --\u003e\n    \u003cdiv class=\"design-ctas\" data-anim=\"rise\"\u003e\n      \u003cspan class=\"liquid-tag\"\u003e\u003c\/span\u003e\n      \u003ca href=\"https:\/\/dqavr9-dh.myshopify.com\/pages\/configurator?design=5000834c82f7977f42d0aee5298e456f\" class=\"cta-btn cta-btn--primary\" style=\"background-size: cover; line-height: 2.3; padding: 22px 24px\"\u003e\n        \u003csvg width=\"18\" height=\"18\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"\u003e\n          \u003cpath d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\"\u003e\u003c\/path\u003e\n        \u003c\/svg\u003e\n        Edit Design \u003cspan class=\"nudge\"\u003e→\u003c\/span\u003e\n      \u003c\/a\u003e\n      \u003cspan class=\"liquid-tag\"\u003e\u003c\/span\u003e\n      \u003ca href=\"https:\/\/infernobeachwear.com\/pages\/configurator\" class=\"cta-btn cta-btn--secondary\"\u003e\n        \u003csvg width=\"18\" height=\"18\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"\u003e\n          \u003cpath d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\"\u003e\u003c\/path\u003e\n        \u003c\/svg\u003e\n        Create a New Design\n      \u003c\/a\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- ============ PRICING TABLE ============ --\u003e\n    \u003cdiv class=\"pricing\" data-anim=\"rise-lg\"\u003e\n      \u003cdiv class=\"pricing-head\"\u003e\n        \u003cdiv\u003e\n          \u003ch3 class=\"pricing-title\"\u003eVolume \u003cspan class=\"em\" style=\"padding: 2px 50px 0px 0px\"\u003ediscounts\u003c\/span\u003e\n\u003c\/h3\u003e\n          \u003cp class=\"pricing-sub\"\u003eDrag the slider · the more you order, the more you save\u003c\/p\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Live readout --\u003e\n      \u003cdiv class=\"pricing-readout\" style=\"background-color: rgb(255, 255, 255)\"\u003e\n        \u003cdiv class=\"readout-qty\"\u003e\n          \u003cspan class=\"label\"\u003eQuantity\u003c\/span\u003e\n          \u003cspan class=\"value\"\u003e\u003cspan id=\"qty-num\" style=\"color: rgb(245, 177, 61); font-size: 60px\"\u003e2\u003c\/span\u003e\u003csmall style=\"color: rgb(0, 0, 0)\"\u003epcs\u003c\/small\u003e\u003c\/span\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"readout-discount\" style=\"color: rgb(0, 0, 0)\"\u003e\n          \u003cdiv class=\"badge zero\" id=\"disc-badge\" style=\"color: rgb(0, 0, 0); font-size: 17px\"\u003e0% OFF\u003c\/div\u003e\n          \u003cspan class=\"save\" id=\"save-line\" style=\"color: rgb(0, 0, 0)\"\u003ePick 2+ pcs to start saving\u003c\/span\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"readout-price\"\u003e\n          \u003cdiv class=\"label\"\u003eYour price\u003c\/div\u003e\n          \u003cdiv class=\"unit\"\u003e\n\u003cspan class=\"strike\" id=\"strike-price\" style=\"display: none; color: rgb(0, 0, 0)\"\u003e{{ product.price | money }}\u003c\/span\u003e\u003cspan id=\"unit-price\" style=\"color: rgb(53, 36, 36)\"\u003e{{ product.price | money }}\u003c\/span\u003e\n\u003c\/div\u003e\n          \u003cdiv class=\"total\" style=\"color: rgb(245, 177, 61)\"\u003eTotal: \u003cb style=\"color: rgb(245, 177, 61)\"\u003e\u003cspan id=\"total-price\" style=\"color: rgb(245, 177, 61)\"\u003e{{ product.price | money }}\u003c\/span\u003e\u003c\/b\u003e\n\u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Slider --\u003e\n      \u003cdiv class=\"qty-slider-wrap\"\u003e\n        \u003cinput type=\"range\" min=\"1\" max=\"60\" value=\"1\" class=\"qty-slider\" id=\"qty-slider\" aria-label=\"Quantity\"\u003e\n        \u003cdiv class=\"qty-ticks\"\u003e\n          \u003cspan style=\"left: 14px\"\u003e1\u003c\/span\u003e\n          \u003cspan style=\"left: calc(15.25% + 9.73px)\"\u003e10\u003c\/span\u003e\n          \u003cspan style=\"left: calc(32.20% + 4.98px)\"\u003e20\u003c\/span\u003e\n          \u003cspan style=\"left: calc(49.15% + 0.24px)\"\u003e30\u003c\/span\u003e\n          \u003cspan style=\"left: calc(66.10% - 4.51px)\"\u003e40\u003c\/span\u003e\n          \u003cspan style=\"left: calc(83.05% - 9.25px)\"\u003e50\u003c\/span\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Tiers --\u003e\n      \u003cdiv class=\"tier-grid\" id=\"tier-grid\"\u003e\n        \u003cdiv class=\"tier active\" data-min=\"1\" data-max=\"1\" data-disc=\"0\" style=\"border-color: rgb(138, 82, 82)\"\u003e\n          \u003cdiv class=\"qty\"\u003e1 pc\u003c\/div\u003e\n          \u003cdiv class=\"disc zero\"\u003e0%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | money }} ea\u003c\/div\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"tier\" data-min=\"2\" data-max=\"2\" data-disc=\"5\"\u003e\n          \u003cdiv class=\"qty\"\u003e2 pcs\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−5%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.95 | money }} ea\u003c\/div\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"tier\" data-min=\"3\" data-max=\"5\" data-disc=\"15\"\u003e\n          \u003cdiv class=\"qty\"\u003e3–5 pcs\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−15%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.85 | money }} ea\u003c\/div\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"tier\" data-min=\"6\" data-max=\"10\" data-disc=\"25\"\u003e\n          \u003cdiv class=\"qty\"\u003e6–10 pcs\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−25%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.75 | money }} ea\u003c\/div\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"tier\" data-min=\"11\" data-max=\"20\" data-disc=\"35\"\u003e\n          \u003cdiv class=\"qty\"\u003e11–20 pcs\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−35%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.65 | money }} ea\u003c\/div\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"tier\" data-min=\"21\" data-max=\"35\" data-disc=\"45\"\u003e\n          \u003cdiv class=\"qty\"\u003e21–35 pcs\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−45%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.55 | money }} ea\u003c\/div\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"tier\" data-min=\"36\" data-max=\"50\" data-disc=\"50\"\u003e\n          \u003cdiv class=\"qty\"\u003e36–50 pcs\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−50%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.50 | money }} ea\u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Bulk inquiry (50+) --\u003e\n      \u003cdiv class=\"bulk-inquiry\" id=\"bulk-inquiry\"\u003e\n        \u003cdiv class=\"bulk-inquiry-text\"\u003e\n          \u003cdiv class=\"bulk-inquiry-eyebrow\"\u003e⚓ 50+ pieces\u003c\/div\u003e\n          \u003ch4\u003eNeed a full team kit? \u003cem\u003eLet's talk.\u003c\/em\u003e\n\u003c\/h4\u003e\n          \u003cp\u003eCustom pricing for clubs, teams and events with 50+ pieces. We'll quote you within 24 hours.\u003c\/p\u003e\n        \u003c\/div\u003e\n        \u003cbutton type=\"button\" id=\"quote-open-btn\" class=\"bulk-inquiry-cta\"\u003e\n          \u003csvg viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"\u003e\n            \u003cpath d=\"M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z\"\u003e\u003c\/path\u003e\n            \u003cpolyline points=\"22,6 12,13 2,6\"\u003e\u003c\/polyline\u003e\n          \u003c\/svg\u003e\n          Request a quote\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Quote request modal --\u003e\n      \u003cdiv class=\"quote-modal-overlay\" id=\"quote-modal-overlay\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"quote-modal-title\" hidden\u003e\n        \u003cdiv class=\"quote-modal\"\u003e\n          \u003cdiv class=\"quote-modal-header\"\u003e\n            \u003cbutton type=\"button\" class=\"quote-modal-close\" id=\"quote-close-btn\" aria-label=\"Close\"\u003e×\u003c\/button\u003e\n            \u003cdiv class=\"quote-modal-eyebrow\"\u003e⚓ Bulk inquiry · 50+ pieces\u003c\/div\u003e\n            \u003ch3 id=\"quote-modal-title\"\u003eGet your \u003cem\u003ecustom quote.\u003c\/em\u003e\n\u003c\/h3\u003e\n            \u003cp\u003eTell us about your team and we'll get back within 24h with pricing and lead time.\u003c\/p\u003e\n          \u003c\/div\u003e\n          \u003cdiv class=\"quote-modal-body\" id=\"quote-modal-body\"\u003e\n            \u003cform id=\"quote-form\" action=\"\/contact\" method=\"post\" accept-charset=\"UTF-8\" novalidate\u003e\n              \u003cinput type=\"hidden\" name=\"form_type\" value=\"contact\"\u003e\n              \u003cinput type=\"hidden\" name=\"utf8\" value=\"✓\"\u003e\n              \u003cinput type=\"hidden\" name=\"authenticity_token\" id=\"qf-token\" value=\"\"\u003e\n              \u003cinput type=\"hidden\" name=\"return_to\" value=\"\"\u003e\n              \u003cinput type=\"hidden\" name=\"contact[Product]\" value=\"Men’s Comfort Fit Rashguard SS - THUNDER MASTER\"\u003e\n              \u003cinput type=\"hidden\" name=\"contact[Product URL]\" id=\"qf-product-url\" value=\"{{ shop.url | append: product.url }}\"\u003e\n              \u003cinput type=\"hidden\" name=\"contact[subject]\" id=\"qf-subject\" value=\"Bulk quote request from product page\"\u003e\n\n              \u003cdiv class=\"quote-form-row\"\u003e\n                \u003cdiv class=\"quote-field\"\u003e\n                  \u003clabel for=\"qf-club\"\u003eClub \/ Company name \u003cspan class=\"req\"\u003e*\u003c\/span\u003e\u003c\/label\u003e\n                  \u003cinput type=\"text\" id=\"qf-club\" name=\"contact[name]\" required autocomplete=\"organization\"\u003e\n                  \u003cdiv class=\"quote-field-error\" data-for=\"qf-club\"\u003ePlease enter your club or company name\u003c\/div\u003e\n                \u003c\/div\u003e\n              \u003c\/div\u003e\n\n              \u003cdiv class=\"quote-form-row two\"\u003e\n                \u003cdiv class=\"quote-field\"\u003e\n                  \u003clabel for=\"qf-country\"\u003eCountry \u003cspan class=\"req\"\u003e*\u003c\/span\u003e\u003c\/label\u003e\n                  \u003cinput type=\"text\" id=\"qf-country\" name=\"contact[Country]\" required autocomplete=\"country-name\" placeholder=\"e.g. Italy\"\u003e\n                  \u003cdiv class=\"quote-field-error\" data-for=\"qf-country\"\u003eRequired\u003c\/div\u003e\n                \u003c\/div\u003e\n                \u003cdiv class=\"quote-field\"\u003e\n                  \u003clabel for=\"qf-vat\"\u003eVAT number \u003cspan class=\"opt\"\u003e(if any)\u003c\/span\u003e\u003c\/label\u003e\n                  \u003cinput type=\"text\" id=\"qf-vat\" name=\"contact[VAT]\" autocomplete=\"off\" placeholder=\"IT12345678901\"\u003e\n                \u003c\/div\u003e\n              \u003c\/div\u003e\n\n              \u003cdiv class=\"quote-form-row two\"\u003e\n                \u003cdiv class=\"quote-field\"\u003e\n                  \u003clabel for=\"qf-qty\"\u003eQuantity \u003cspan class=\"req\"\u003e*\u003c\/span\u003e\u003c\/label\u003e\n                  \u003cinput type=\"number\" id=\"qf-qty\" name=\"contact[Quantity]\" min=\"50\" required placeholder=\"e.g. 80\" autocomplete=\"off\" inputmode=\"numeric\"\u003e\n                  \u003cdiv class=\"quote-field-error\" data-for=\"qf-qty\"\u003eMust be 50 or more\u003c\/div\u003e\n                \u003c\/div\u003e\n                \u003cdiv class=\"quote-field\"\u003e\n                  \u003clabel for=\"qf-email\"\u003eEmail \u003cspan class=\"req\"\u003e*\u003c\/span\u003e\u003c\/label\u003e\n                  \u003cinput type=\"email\" id=\"qf-email\" name=\"contact[email]\" required autocomplete=\"email\" inputmode=\"email\" placeholder=\"you@club.com\"\u003e\n                  \u003cdiv class=\"quote-field-error\" data-for=\"qf-email\"\u003eValid email required\u003c\/div\u003e\n                \u003c\/div\u003e\n              \u003c\/div\u003e\n\n              \u003cdiv class=\"quote-form-row\"\u003e\n                \u003cdiv class=\"quote-field\"\u003e\n                  \u003clabel for=\"qf-notes\"\u003eNotes \u003cspan class=\"opt\"\u003e(optional — tell us about your team, custom design, deadline, etc.)\u003c\/span\u003e\u003c\/label\u003e\n                  \u003ctextarea id=\"qf-notes\" name=\"contact[Notes]\" rows=\"4\" autocomplete=\"off\" placeholder=\"e.g. 80 rashguards for our surf club — same logo on all, 6 different sizes mixed, needed by July 15th.\"\u003e\u003c\/textarea\u003e\n                \u003c\/div\u003e\n              \u003c\/div\u003e\n\n              \u003cdiv class=\"quote-honeypot\" aria-hidden=\"true\"\u003e\n                \u003clabel for=\"qf-website\"\u003eWebsite (leave empty — anti-spam)\u003c\/label\u003e\n                \u003cinput type=\"text\" id=\"qf-website\" name=\"website\" tabindex=\"-1\" autocomplete=\"off\"\u003e\n              \u003c\/div\u003e\n\n              \u003cbutton type=\"submit\" class=\"quote-modal-submit\"\u003e\n                \u003csvg viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"\u003e\n                  \u003cline x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"\u003e\u003c\/line\u003e\n                  \u003cpolygon points=\"22 2 15 22 11 13 2 9 22 2\"\u003e\u003c\/polygon\u003e\n                \u003c\/svg\u003e\n                Send request\n              \u003c\/button\u003e\n              \u003cdiv class=\"quote-modal-footnote\"\u003eWe'll reply within 24h to the email you provide. Backup contact: \u003cstrong\u003ecustominferno@gmail.com\u003c\/strong\u003e.\u003c\/div\u003e\n            \u003c\/form\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003cscript\u003e\n      (function() {\n        \/\/ --- Dynamic base price + currency detection from Shopify ---\n        \/\/ The theme's visible price element is our single source of truth: it\n        \/\/ already reflects the current currency switcher state. We scrape both\n        \/\/ the numeric value AND the currency symbol from its rendered text,\n        \/\/ and re-scrape on every DOM mutation so the volume discount stays in\n        \/\/ sync when the user flips currency.\n        \/\/ Pin the selector to the CURRENT product's ID via Liquid. Horizon\n        \/\/ emits \u003cproduct-price data-product-id=\"\"\u003e,\n        \/\/ so this anchors us to the main product and ignores any unrelated\n        \/\/ \u003cproduct-price\u003e elements (related\/featured\/recommended products)\n        \/\/ that would otherwise be matched by a generic selector.\n        \/\/ If Liquid is not processed, PRODUCT_ID will literally be the\n        \/\/ string \"\", which won't match anything — and the\n        \/\/ unscoped fallbacks below will take over.\n        var PRODUCT_ID = \"\";\n        \/\/ If Liquid was not processed, PRODUCT_ID still contains \"{{\" —\n        \/\/ blank it so we don't generate broken [data-product-id=\"{{ ...\"]\n        \/\/ selectors that wouldn't match anything anyway.\n        if (PRODUCT_ID.indexOf('{') !== -1) PRODUCT_ID = '';\n        var PRICE_SELECTOR = [\n          '[data-product-id=\"' + PRODUCT_ID + '\"] [ref=\"priceContainer\"] .price:not(.compare-at-price)',\n          '[data-product-id=\"' + PRODUCT_ID + '\"] .price:not(.compare-at-price)',\n          '[data-product-id=\"' + PRODUCT_ID + '\"]',\n          \/\/ Unscoped fallbacks (only if data-product-id pinning failed)\n          '.product-details product-price .price:not(.compare-at-price)',\n          '.product-information product-price .price:not(.compare-at-price)',\n          '[data-product-price]',\n          '.price-item--regular',\n          '.product__price'\n        ].join(', ');\n        var themePriceEl = null;\n\n        function parsePriceText(raw) {\n          if (!raw) return null;\n          \/\/ Capture the currency symbol\/code: anything that's not digit\/space\/.,\/-\n          \/\/ Examples we should handle: \"€50.00\", \"$50.00\", \"£50.00\", \"50.00 €\",\n          \/\/ \"USD 50.00\", \"CHF 50,00\", \"kr 50,00\"\n          var symMatch = raw.match(\/[^\\d\\s.,\\-]+(?:\\s*[A-Z]{2,3})?|[A-Z]{2,3}\/);\n          var sym = symMatch ? symMatch[0].trim() : '';\n          \/\/ Normalize number: strip non-numeric except . and ,, drop thousand\n          \/\/ separators, convert decimal comma to dot.\n          var cleaned = raw.replace(\/[^\\d.,]\/g, '');\n          \/\/ If both . and , present, the LAST one is the decimal separator\n          var lastDot = cleaned.lastIndexOf('.');\n          var lastCom = cleaned.lastIndexOf(',');\n          if (lastDot \u003e -1 \u0026\u0026 lastCom \u003e -1) {\n            if (lastCom \u003e lastDot) cleaned = cleaned.replace(\/\\.\/g, '').replace(',', '.');\n            else                   cleaned = cleaned.replace(\/,\/g, '');\n          } else if (lastCom \u003e -1) {\n            \/\/ Only comma — treat as decimal if 1-2 digits after, else thousands\n            var afterCom = cleaned.length - 1 - lastCom;\n            cleaned = afterCom \u003c= 2 ? cleaned.replace(',', '.') : cleaned.replace(\/,\/g, '');\n          }\n          var n = parseFloat(cleaned);\n          if (isNaN(n) || n \u003c= 0) return null;\n          return { value: n, symbol: sym || '' };\n        }\n\n        \/\/ Map a currency CODE (USD, GBP, JPY...) to its localized symbol.\n        \/\/ Intl gives us the right glyph for free — much more reliable than\n        \/\/ scraping the theme's static markup, which often keeps \"€\" hardcoded\n        \/\/ in the Liquid template even after the number gets swapped.\n        var SYMBOL_CACHE = {};\n        function symbolFromCode(code) {\n          if (!code) return null;\n          if (SYMBOL_CACHE[code]) return SYMBOL_CACHE[code];\n          try {\n            var parts = new Intl.NumberFormat('en', { style: 'currency', currency: code }).formatToParts(0);\n            for (var i = 0; i \u003c parts.length; i++) {\n              if (parts[i].type === 'currency') {\n                SYMBOL_CACHE[code] = parts[i].value;\n                return parts[i].value;\n              }\n            }\n          } catch(e) {}\n          SYMBOL_CACHE[code] = code;\n          return code;\n        }\n\n        \/\/ Shopify exposes the currently active currency code globally —\n        \/\/ currency-switcher apps update this synchronously when the user\n        \/\/ picks a new currency, so it's the single source of truth.\n        function activeShopifyCurrency() {\n          try {\n            if (window.Shopify \u0026\u0026 window.Shopify.currency \u0026\u0026 window.Shopify.currency.active) {\n              return window.Shopify.currency.active;\n            }\n          } catch(e) {}\n          return null;\n        }\n\n        function detectFromDOM() {\n          themePriceEl = document.querySelector(PRICE_SELECTOR);\n          var parsed = null;\n          if (themePriceEl) {\n            var raw = themePriceEl.getAttribute('data-product-price')\n                   || themePriceEl.getAttribute('data-price')\n                   || themePriceEl.textContent;\n            parsed = parsePriceText(raw);\n          }\n          \/\/ Override the scraped symbol with Shopify.currency.active when\n          \/\/ it's available — that's the only string that actually tracks the\n          \/\/ currency switcher; theme markup can lag behind.\n          var code = activeShopifyCurrency();\n          if (code \u0026\u0026 parsed) {\n            parsed.symbol = symbolFromCode(code) || parsed.symbol;\n          }\n          \/\/ Do NOT fabricate a value here. If parsed is null, return null\n          \/\/ so the caller falls through to other detection paths.\n          return parsed;\n        }\n\n        function detectInitial() {\n          \/\/ Priority 1: trust the Liquid-rendered initial value in our own\n          \/\/ readout. If the store processes Liquid in product descriptions,\n          \/\/ {{ product.price | money }} has already been replaced with the\n          \/\/ CORRECT product price — that's our single source of truth, and\n          \/\/ it can't be confused with prices of unrelated products on the page.\n          \/\/ If Liquid was not processed, the textContent is \"{{ product.price | money }}\"\n          \/\/ (literal) and parsePriceText returns null, so we fall through.\n          var ownUnit = document.getElementById('unit-price');\n          if (ownUnit) {\n            var ownParsed = parsePriceText(ownUnit.textContent);\n            if (ownParsed \u0026\u0026 ownParsed.value \u003e 0) {\n              \/\/ Override symbol with active Shopify currency when available\n              var code = activeShopifyCurrency();\n              if (code) ownParsed.symbol = symbolFromCode(code) || ownParsed.symbol;\n              return ownParsed;\n            }\n          }\n          \/\/ Priority 2: theme DOM (for stores where Liquid is NOT processed\n          \/\/ in descriptions). detectFromDOM also drives currency switching.\n          var fromDom = detectFromDOM();\n          if (fromDom) return fromDom;\n          try {\n            var sa = window.ShopifyAnalytics;\n            if (sa \u0026\u0026 sa.meta \u0026\u0026 sa.meta.product \u0026\u0026 sa.meta.product.variants \u0026\u0026 sa.meta.product.variants.length) {\n              var v = sa.meta.product.variants[0];\n              if (v \u0026\u0026 typeof v.price === 'number') return { value: v.price \/ 100, symbol: (symbolFromCode(activeShopifyCurrency()) || '') };\n            }\n            if (window.meta \u0026\u0026 window.meta.product \u0026\u0026 window.meta.product.variants \u0026\u0026 window.meta.product.variants.length) {\n              var mv = window.meta.product.variants[0];\n              if (mv \u0026\u0026 typeof mv.price === 'number') return { value: mv.price \/ 100, symbol: (symbolFromCode(activeShopifyCurrency()) || '') };\n            }\n            var jsonEl = document.querySelector('script[type=\"application\/json\"][data-product-json], [id^=\"ProductJson\"]');\n            if (jsonEl) {\n              try {\n                var data = JSON.parse(jsonEl.textContent);\n                if (data) {\n                  if (typeof data.price === 'number') return { value: data.price \/ 100, symbol: (symbolFromCode(activeShopifyCurrency()) || '') };\n                  if (data.variants \u0026\u0026 data.variants[0] \u0026\u0026 data.variants[0].price != null) {\n                    var p = data.variants[0].price;\n                    return { value: (typeof p === 'number' ? p \/ 100 : parseFloat(p)), symbol: (symbolFromCode(activeShopifyCurrency()) || '') };\n                  }\n                }\n              } catch(e) {}\n            }\n          } catch(e) {}\n          \/\/ Last-resort fallback: no detection succeeded. Return 0 (not 50,\n          \/\/ which used to be a confusing \"fake real price\"). The widget\n          \/\/ will visibly read 0,00 so it's obvious detection failed.\n          return { value: 0, symbol: (symbolFromCode(activeShopifyCurrency()) || '') };\n        }\n\n        var initial = detectInitial();\n        var BASE = initial.value;\n        var CURRENCY = initial.symbol;\n\n        var TIERS = [\n          { min: 1, max: 1, disc: 0 },\n          { min: 2, max: 2, disc: 5 },\n          { min: 3, max: 5, disc: 15 },\n          { min: 6, max: 10, disc: 25 },\n          { min: 11, max: 20, disc: 35 },\n          { min: 21, max: 35, disc: 45 },\n          { min: 36, max: 50, disc: 50 }\n        ];\n        var BULK_THRESHOLD = 50;\n        var slider = document.getElementById('qty-slider');\n        var qtyNum = document.getElementById('qty-num');\n        var discBadge = document.getElementById('disc-badge');\n        var saveLine = document.getElementById('save-line');\n        var unitPrice = document.getElementById('unit-price');\n        var totalPrice = document.getElementById('total-price');\n        var strikePrice = document.getElementById('strike-price');\n        var tierEls = document.querySelectorAll('#tier-grid .tier');\n        var bulkBanner = document.getElementById('bulk-inquiry');\n\n        function fmt(n) { return n.toFixed(2); }\n        function money(n) { return CURRENCY + fmt(n); }\n\n        \/\/ The static readout HTML had hardcoded \"€\" prefix spans before\n        \/\/ #unit-price (and a \"€\" text-node before #total-price inside its \u003cb\u003e).\n        \/\/ We blank those out so the symbol now lives in textContent only,\n        \/\/ emitted by money() and refreshable when currency changes.\n        var unitPrefix = unitPrice \u0026\u0026 unitPrice.previousElementSibling;\n        if (unitPrefix \u0026\u0026 unitPrefix.textContent.trim().length \u003c= 3) unitPrefix.textContent = '';\n        if (totalPrice \u0026\u0026 totalPrice.parentNode) {\n          var tp = totalPrice.parentNode;\n          for (var i = 0; i \u003c tp.childNodes.length; i++) {\n            var n = tp.childNodes[i];\n            if (n.nodeType === 3 \u0026\u0026 n.textContent.trim().length \u0026\u0026 n.textContent.trim().length \u003c= 3) n.textContent = '';\n          }\n        }\n\n        function update(qty) {\n          var isBulk = qty \u003e BULK_THRESHOLD;\n          if (bulkBanner) bulkBanner.classList.toggle('show', isBulk);\n\n          if (isBulk) {\n            qtyNum.textContent = '50+';\n            unitPrice.textContent = '—';\n            totalPrice.textContent = 'Quote';\n            discBadge.textContent = '⚓ Custom quote';\n            discBadge.classList.remove('zero');\n            saveLine.innerHTML = 'Bulk pricing on request';\n            strikePrice.style.display = 'none';\n            tierEls.forEach(function(el){ el.classList.remove('active'); });\n            return;\n          }\n\n          var tier = TIERS.find(function(t){ return qty \u003e= t.min \u0026\u0026 qty \u003c= t.max; }) || TIERS[TIERS.length-1];\n          var unit = BASE * (1 - tier.disc\/100);\n          var total = unit * qty;\n          var saved = (BASE - unit) * qty;\n\n          qtyNum.textContent = qty;\n          unitPrice.textContent = money(unit);\n          totalPrice.textContent = money(total);\n\n          if (tier.disc === 0) {\n            discBadge.textContent = '0% off';\n            discBadge.classList.add('zero');\n            saveLine.innerHTML = 'Pick 2+ pcs to start saving';\n            strikePrice.style.display = 'none';\n          } else {\n            discBadge.textContent = '− ' + tier.disc + '% off';\n            discBadge.classList.remove('zero');\n            saveLine.innerHTML = 'You save \u003cb\u003e' + money(saved) + '\u003c\/b\u003e';\n            strikePrice.style.display = '';\n            strikePrice.textContent = money(BASE);\n          }\n\n          tierEls.forEach(function(el) {\n            var min = parseInt(el.getAttribute('data-min'),10);\n            var max = parseInt(el.getAttribute('data-max'),10);\n            el.classList.toggle('active', qty \u003e= min \u0026\u0026 qty \u003c= max);\n          });\n        }\n\n        function refreshTiers() {\n          tierEls.forEach(function(el){\n            var disc = parseInt(el.getAttribute('data-disc'),10) || 0;\n            var label = el.querySelector('.price-each');\n            if (label) label.textContent = money(BASE * (1 - disc\/100)) + ' ea';\n          });\n        }\n\n        slider.addEventListener('input', function(){ update(parseInt(slider.value,10)); });\n        tierEls.forEach(function(el){\n          el.addEventListener('click', function(){\n            var min = parseInt(el.getAttribute('data-min'),10);\n            slider.value = min;\n            update(min);\n          });\n        });\n        refreshTiers();\n        update(1);\n\n        \/\/ --- React to Shopify currency switcher ---\n        \/\/ The theme price element re-renders when the user changes currency.\n        \/\/ Re-scrape its value+symbol on every mutation, then re-run the math\n        \/\/ so tiers, readout and \"save\" line all stay coherent.\n        function onCurrencyMaybeChanged() {\n          var fresh = detectFromDOM();\n          if (!fresh) return;\n          if (fresh.value === BASE \u0026\u0026 fresh.symbol === CURRENCY) return;\n          \/\/ Outlier guard: if the symbol didn't change but the value is\n          \/\/ wildly different from the current BASE (more than 2x larger or\n          \/\/ smaller), that's almost certainly a different product picked\n          \/\/ up by an incorrect selector — reject the update.\n          if (fresh.symbol === CURRENCY \u0026\u0026 BASE \u003e 0) {\n            var ratio = fresh.value \/ BASE;\n            if (ratio \u003c 0.5 || ratio \u003e 2.0) return;\n          }\n          BASE = fresh.value;\n          CURRENCY = fresh.symbol;\n          refreshTiers();\n          update(parseInt(slider.value,10));\n        }\n        \/\/ If detectInitial picked the value from our own readout (Priority 1)\n        \/\/ themePriceEl was never set. Call detectFromDOM purely for the\n        \/\/ side-effect of populating it, so the MutationObserver can watch\n        \/\/ the theme's price element for currency-switch changes.\n        if (!themePriceEl) detectFromDOM();\n        if (themePriceEl \u0026\u0026 window.MutationObserver) {\n          var mo = new MutationObserver(onCurrencyMaybeChanged);\n          mo.observe(themePriceEl, { childList: true, characterData: true, subtree: true, attributes: true, attributeFilter: ['data-product-price','data-price'] });\n        }\n        \/\/ Some currency apps swap the price element wholesale or only fire\n        \/\/ Listen to standard currency-switcher events only. NO polling:\n        \/\/ a setInterval kept overwriting the correct Liquid-rendered price\n        \/\/ with whatever the (potentially wrong) PRICE_SELECTOR found.\n        ['shopify:section:load','currency:change','currency.changed','shopify:cart:update'].forEach(function(ev){\n          document.addEventListener(ev, onCurrencyMaybeChanged);\n        });\n\n        \/\/ ===== Quote request modal =====\n        var qOverlay = document.getElementById('quote-modal-overlay');\n        var qOpenBtn = document.getElementById('quote-open-btn');\n        var qCloseBtn = document.getElementById('quote-close-btn');\n        var qForm = document.getElementById('quote-form')\n          || document.querySelector('#quote-modal-body form');\n        var qBody = document.getElementById('quote-modal-body');\n\n        \/\/ Remember which element was focused before the modal opened, so we\n        \/\/ can restore focus there on close (a11y: keyboard users should not\n        \/\/ be stranded at the page \u003cbody\u003e after closing the modal).\n        var qFocusReturn = null;\n        \/\/ Saved scroll position for iOS-safe body scroll lock.\n        var qSavedScrollY = 0;\n\n        function openQuote() {\n          if (!qOverlay) return;\n          \/\/ Move overlay to \u003cbody\u003e on open to escape any ancestor with\n          \/\/ transform\/filter\/will-change that would trap position:fixed\n          \/\/ (Shopify theme wrappers commonly do this — symptom on mobile:\n          \/\/ the site header stays visible behind the \"fullscreen\" modal).\n          if (qOverlay.parentNode !== document.body) {\n            document.body.appendChild(qOverlay);\n          }\n          qFocusReturn = document.activeElement;\n          qOverlay.hidden = false;\n          \/\/ force reflow then add show class\n          requestAnimationFrame(function(){ qOverlay.classList.add('show'); });\n          \/\/ Pre-fill quantity with current slider value if 50+\n          var qInput = document.getElementById('qf-qty');\n          if (qInput) {\n            var cur = parseInt(slider.value, 10);\n            qInput.value = cur \u003e 50 ? cur : 50;\n          }\n          \/\/ iOS-safe body scroll lock: overflow:hidden alone DOES NOT prevent\n          \/\/ scrolling on iOS Safari. We freeze the body in place with\n          \/\/ position:fixed and remember the scroll position so we can restore\n          \/\/ it on close — the only reliable cross-browser approach.\n          qSavedScrollY = window.scrollY || window.pageYOffset || 0;\n          document.body.style.position = 'fixed';\n          document.body.style.top = (-qSavedScrollY) + 'px';\n          document.body.style.left = '0';\n          document.body.style.right = '0';\n          document.body.style.width = '100%';\n          \/\/ Move focus to the first input inside the modal after the open\n          \/\/ animation has had a moment to start (avoids fighting the visual\n          \/\/ transition or being stolen back by the page).\n          setTimeout(function(){\n            var firstInput = qOverlay.querySelector('input:not([type=\"hidden\"]):not([disabled]):not(.quote-honeypot input), textarea:not([disabled]), select:not([disabled])');\n            if (firstInput) firstInput.focus();\n          }, 60);\n        }\n        function closeQuote() {\n          if (!qOverlay) return;\n          qOverlay.classList.remove('show');\n          setTimeout(function(){\n            qOverlay.hidden = true;\n            \/\/ Undo iOS-safe body scroll lock and restore the user's scroll\n            \/\/ position (which was lost when we switched body to position:fixed).\n            document.body.style.position = '';\n            document.body.style.top = '';\n            document.body.style.left = '';\n            document.body.style.right = '';\n            document.body.style.width = '';\n            window.scrollTo(0, qSavedScrollY);\n            \/\/ Restore focus to whatever opened the modal.\n            if (qFocusReturn \u0026\u0026 typeof qFocusReturn.focus === 'function') {\n              try { qFocusReturn.focus(); } catch(err) {}\n            }\n            qFocusReturn = null;\n          }, 280);\n        }\n        if (qOpenBtn) qOpenBtn.addEventListener('click', openQuote);\n        if (qCloseBtn) qCloseBtn.addEventListener('click', closeQuote);\n        if (qOverlay) qOverlay.addEventListener('click', function(e){\n          if (e.target === qOverlay) closeQuote();\n        });\n        document.addEventListener('keydown', function(e){\n          if (e.key === 'Escape' \u0026\u0026 qOverlay \u0026\u0026 !qOverlay.hidden) closeQuote();\n        });\n\n        \/\/ Focus trap: while the modal is open, keep Tab\/Shift+Tab cycling\n        \/\/ among focusable elements inside the modal — never letting focus\n        \/\/ escape to the page underneath.\n        if (qOverlay) qOverlay.addEventListener('keydown', function(e){\n          if (e.key !== 'Tab' || qOverlay.hidden) return;\n          var focusables = qOverlay.querySelectorAll(\n            'a[href], button:not([disabled]), input:not([disabled]):not([type=\"hidden\"]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])'\n          );\n          var visible = Array.prototype.filter.call(focusables, function(el){\n            return el.offsetParent !== null;\n          });\n          if (!visible.length) return;\n          var first = visible[0];\n          var last = visible[visible.length - 1];\n          if (e.shiftKey \u0026\u0026 document.activeElement === first) {\n            e.preventDefault();\n            last.focus();\n          } else if (!e.shiftKey \u0026\u0026 document.activeElement === last) {\n            e.preventDefault();\n            first.focus();\n          }\n        });\n\n        function isValidEmail(s) {\n          return \/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\/.test(String(s).trim());\n        }\n\n        \/\/ Escape HTML special chars before interpolating user input into\n        \/\/ innerHTML. Prevents XSS via crafted email addresses (the email\n        \/\/ regex above doesn't block \u003c \u003e \" ' \u0026 by itself).\n        function escapeHtml(s) {\n          return String(s).replace(\/[\u0026\u003c\u003e\"']\/g, function(c){\n            return ({ '\u0026': '\u0026amp;', '\u003c': '\u0026lt;', '\u003e': '\u0026gt;', '\"': '\u0026quot;', \"'\": '\u0026#39;' })[c];\n          });\n        }\n\n        function showError(id, show) {\n          var input = document.getElementById(id);\n          var err = document.querySelector('.quote-field-error[data-for=\"' + id + '\"]');\n          if (input) input.classList.toggle('invalid', !!show);\n          if (err) err.classList.toggle('show', !!show);\n        }\n\n        \/\/ ===== Scrape Shopify's authenticity_token at page load =====\n        \/\/ The token is needed so the native form submit can POST to \/contact.\n        \/\/ We scrape it from any page on the store that DOES render a Liquid\n        \/\/ {% form %} tag (product description HTML doesn't). Best source is\n        \/\/ the current page (same session, same cookie). The token is written\n        \/\/ into the hidden #qf-token BEFORE the user submits.\n        function loadTokenIntoForm(){\n          var qfToken = document.getElementById('qf-token');\n          if (!qfToken) return;\n          \/\/ Scrape only the current page: same session\/cookie, token is\n          \/\/ guaranteed valid if found. Skip the \/pages\/contact and \/ fallbacks\n          \/\/ that previously chained — they downloaded ~400KB of HTML for no\n          \/\/ additional chance of success in practice.\n          fetch(window.location.pathname + window.location.search, {\n            credentials: 'same-origin',\n            headers: { 'Accept': 'text\/html' }\n          })\n            .then(function(r){ return r.ok ? r.text() : Promise.reject(new Error('GET ' + r.status)); })\n            .then(function(html){\n              var m = html.match(\/name=\"authenticity_token\"\\s+value=\"([^\"]+)\"\/);\n              if (m) qfToken.value = m[1];\n              \/* if no match, qfToken stays empty → submit handler falls back to mailto: *\/\n            })\n            .catch(function(){ \/* network error — submit handler falls back to mailto: *\/ });\n        }\n        loadTokenIntoForm();\n\n        \/\/ ===== URL hygiene: strip Shopify contact-form leftover params =====\n        \/\/ When return_to fails to resolve (Liquid not processed in a product\n        \/\/ description), Shopify can redirect back with all the contact[*]\n        \/\/ fields appended to the page URL. Those leftovers then pollute the\n        \/\/ NEXT submission's \"Product URL\" field (auto-perpetuating bug) and\n        \/\/ make the shared page URL ugly. Strip them on load, and use this\n        \/\/ helper any time we copy window.location into a hidden field.\n        function stripContactParams(url) {\n          var u;\n          try { u = new URL(url, window.location.origin); }\n          catch (e) { return url; }\n          var changed = false;\n          var keep = new URLSearchParams();\n          u.searchParams.forEach(function(v, k){\n            if (k.indexOf('contact[') === 0 || k === 'form_type' || k === 'contact_posted') {\n              changed = true;\n              return;\n            }\n            keep.append(k, v);\n          });\n          if (!changed) return url;\n          u.search = keep.toString();\n          return u.toString();\n        }\n        try {\n          var cleanUrl = stripContactParams(window.location.href);\n          if (cleanUrl !== window.location.href) {\n            history.replaceState(null, '', cleanUrl);\n          }\n        } catch (e) {}\n\n        \/\/ ===== Product URL: guarantee a correct value =====\n        \/\/ The Liquid `{{ shop.url | append: product.url }}` SHOULD resolve to\n        \/\/ the full product URL, but some Liquid-in-description apps strip or\n        \/\/ mis-parse complex tags. The browser's window.location.href is\n        \/\/ always the actual product URL the user is viewing (including the\n        \/\/ ?variant=... param), so we override the hidden field with it if\n        \/\/ the Liquid output looks incomplete (missing \"\/products\/\" path).\n        \/\/ Always run through stripContactParams so a polluted URL from a\n        \/\/ previous failed submit can't poison the next one.\n        (function ensureProductUrl(){\n          var el = document.getElementById('qf-product-url');\n          if (!el) return;\n          var liquidValue = (el.value || '').trim();\n          if (liquidValue.indexOf('\/products\/') === -1) {\n            el.value = stripContactParams(window.location.href);\n          } else {\n            el.value = stripContactParams(liquidValue);\n          }\n        })();\n\n        \/\/ ===== return_to: same defensive treatment =====\n        \/\/ If Liquid didn't resolve ``, fall back to the\n        \/\/ current pathname (no query string). Otherwise strip contact[*]\n        \/\/ params so the post-submit redirect lands on a clean URL.\n        (function ensureReturnTo(){\n          if (!qForm) return;\n          var el = qForm.querySelector('input[name=\"return_to\"]');\n          if (!el) return;\n          var v = (el.value || '').trim();\n          if (v.indexOf('\/products\/') === -1) {\n            el.value = window.location.pathname;\n          } else {\n            el.value = stripContactParams(v);\n          }\n        })();\n\n        if (qForm) {\n          qForm.addEventListener('submit', function(e){\n            \/\/ Honeypot check: real humans won't see\/fill the off-screen\n            \/\/ \"website\" field. If it's been filled, silently drop the\n            \/\/ submission and show a fake success — the bot moves on, no\n            \/\/ email is sent.\n            var honeypot = document.getElementById('qf-website');\n            if (honeypot \u0026\u0026 honeypot.value.trim() !== '') {\n              e.preventDefault();\n              if (qBody) {\n                qBody.innerHTML =\n                  '\u003cdiv class=\"quote-success\"\u003e'\n                  + '\u003cdiv class=\"check\"\u003e✓\u003c\/div\u003e'\n                  + '\u003ch4\u003eRequest sent!\u003c\/h4\u003e'\n                  + '\u003cp\u003eWe received your inquiry and will reply within 24 hours.\u003c\/p\u003e'\n                  + '\u003c\/div\u003e';\n              }\n              setTimeout(closeQuote, 4000);\n              return;\n            }\n\n            var club = document.getElementById('qf-club').value.trim();\n            var country = document.getElementById('qf-country').value.trim();\n            var vat = document.getElementById('qf-vat').value.trim();\n            var qty = parseInt(document.getElementById('qf-qty').value, 10);\n            var email = document.getElementById('qf-email').value.trim();\n            var notes = (document.getElementById('qf-notes')?.value || '').trim();\n\n            \/\/ Client-side validation — block native submit only on errors.\n            var ok = true;\n            showError('qf-club', !club); if (!club) ok = false;\n            showError('qf-country', !country); if (!country) ok = false;\n            showError('qf-qty', !(qty \u003e= 50)); if (!(qty \u003e= 50)) ok = false;\n            showError('qf-email', !isValidEmail(email)); if (!isValidEmail(email)) ok = false;\n            if (!ok) { e.preventDefault(); return; }\n\n            \/\/ Resolve product name and compose subject + body for the email.\n            var productName = document.title || 'Custom Inferno product';\n            try {\n              if (window.ShopifyAnalytics \u0026\u0026 window.ShopifyAnalytics.meta \u0026\u0026 window.ShopifyAnalytics.meta.product) {\n                productName = window.ShopifyAnalytics.meta.product.title || productName;\n              }\n            } catch(err) {}\n            var subject = 'Bulk quote request — ' + qty + ' pcs — ' + club;\n            var bodyLines = [\n              'New bulk quote request from the product page.', '',\n              'Product: ' + productName,\n              'Club \/ Company: ' + club,\n              'Country: ' + country,\n              'VAT number: ' + (vat || '—'),\n              'Quantity: ' + qty + ' pieces',\n              'Contact email: ' + email\n            ];\n            if (notes) {\n              bodyLines.push('', 'Notes:', notes);\n            }\n            \/\/ Body string is only used for the mailto: fallback; Shopify\n            \/\/ renders the individual fields (Name, Country, VAT, Quantity,\n            \/\/ Email, Notes, Product, Product URL) in the email itself, so\n            \/\/ we no longer push it into a contact[body] hidden field.\n            var body = bodyLines.join('\\n');\n            var qfSubject = document.getElementById('qf-subject');\n            if (qfSubject) qfSubject.value = subject;\n\n            \/\/ If token wasn't fetched (slow network or theme didn't expose\n            \/\/ it), show an in-modal error instead of falling back to mailto:.\n            \/\/ On iOS, `location.href = 'mailto:'` opens the Mail app — that's\n            \/\/ confusing UX, and the resulting message comes from the user's\n            \/\/ own email client (different from\/template, no Shopify routing).\n            var qfToken = document.getElementById('qf-token');\n            if (!qfToken || !qfToken.value) {\n              e.preventDefault();\n              if (qBody) {\n                qBody.innerHTML =\n                  '\u003cdiv class=\"quote-success\"\u003e'\n                  + '\u003cdiv class=\"check\" style=\"background: linear-gradient(135deg, #ff5e3a, #f5b13d)\"\u003e!\u003c\/div\u003e'\n                  + '\u003ch4\u003eService temporarily unavailable\u003c\/h4\u003e'\n                  + '\u003cp\u003ePlease try again in a few seconds, or email us directly at \u003cstrong\u003ecustominferno@gmail.com\u003c\/strong\u003e.\u003c\/p\u003e'\n                  + '\u003c\/div\u003e';\n              }\n              return;\n            }\n\n            \/\/ Set a localStorage flag with a timestamp BEFORE the native\n            \/\/ submit. localStorage (not sessionStorage) because some browsers\n            \/\/ do not commit sessionStorage in time during a synchronous form\n            \/\/ unload, leaving the flag null on the next page. localStorage\n            \/\/ is committed synchronously and survives the redirect reliably.\n            try {\n              localStorage.setItem('quoteSubmitted', JSON.stringify({\n                email: email,\n                timestamp: Date.now()\n              }));\n            } catch(err) {}\n\n            \/\/ Disable the submit button to prevent double-clicks while the\n            \/\/ native submit is in flight (the browser navigates away in ~1s,\n            \/\/ but a fast double-tap could otherwise trigger two POSTs).\n            var qSubmitBtn = qForm.querySelector('button[type=\"submit\"]');\n            if (qSubmitBtn) qSubmitBtn.disabled = true;\n\n            \/\/ Show pending state — the browser will reload shortly.\n            qBody.innerHTML =\n              '\u003cdiv class=\"quote-success\"\u003e'\n              + '\u003cdiv class=\"check\" style=\"background: linear-gradient(135deg, #1fb6c1, #0066a2)\"\u003e…\u003c\/div\u003e'\n              + '\u003ch4\u003eSending your request…\u003c\/h4\u003e'\n              + '\u003cp\u003eOne moment.\u003c\/p\u003e'\n              + '\u003c\/div\u003e';\n\n            \/\/ No e.preventDefault() — let the browser do the native POST.\n            \/\/ hCaptcha will solve invisibly; Shopify sends the email and\n            \/\/ redirects to the URL declared in `return_to` (the product page).\n            \/\/ When that landing page loads, the IIFE runs again and the\n            \/\/ detectQuoteSubmitted handler picks up the sessionStorage flag.\n          });\n        }\n\n        \/\/ ===== Post-redirect success banner =====\n        \/\/ Triggers on TWO independent signals (either one is enough):\n        \/\/   1. localStorage 'quoteSubmitted' flag set by the submit handler\n        \/\/   2. Shopify's own URL params (contact_posted=true, etc.) that\n        \/\/      Shopify sometimes appends after a successful contact submit\n        \/\/ We run the check on DOMContentLoaded to guarantee qBody\/openQuote\n        \/\/ are defined; if the script already runs late, we run immediately.\n        function detectQuoteSubmitted(){\n          var raw = null;\n          var data = null;\n          try { raw = localStorage.getItem('quoteSubmitted'); } catch(err) {}\n          if (raw) {\n            try { data = JSON.parse(raw); } catch(err) {}\n            \/\/ Always clear the flag (even if invalid) so it never fires twice.\n            try { localStorage.removeItem('quoteSubmitted'); } catch(err) {}\n          }\n          \/\/ Check URL params as a secondary signal (Shopify standard).\n          var params = new URLSearchParams(window.location.search);\n          var shopifyPosted = params.get('contact_posted') === 'true'\n            || params.get('contact[posted]') === 'true'\n            || params.has('contact_form_success');\n          if (shopifyPosted) {\n            \/\/ Strip these params so a refresh doesn't replay the banner.\n            ['contact_posted', 'contact[posted]', 'contact_form_success'].forEach(function(k){\n              params.delete(k);\n            });\n            var cleanUrl = window.location.pathname\n              + (params.toString() ? '?' + params.toString() : '')\n              + window.location.hash;\n            history.replaceState({}, '', cleanUrl);\n          }\n          \/\/ Trigger if EITHER the flag is recent (\u003c 60s) OR Shopify URL signal.\n          var flagFresh = data \u0026\u0026 data.timestamp \u0026\u0026 (Date.now() - data.timestamp \u003c= 60000);\n          if (!flagFresh \u0026\u0026 !shopifyPosted) return;\n          var email = (data \u0026\u0026 data.email) || '';\n          if (qBody) {\n            qBody.innerHTML =\n              '\u003cdiv class=\"quote-success\"\u003e'\n              + '\u003cdiv class=\"check\"\u003e✓\u003c\/div\u003e'\n              + '\u003ch4\u003eRequest sent!\u003c\/h4\u003e'\n              + '\u003cp\u003eWe received your inquiry'\n              + (email ? ' and will reply to \u003cstrong\u003e' + escapeHtml(email) + '\u003c\/strong\u003e' : '')\n              + ' within 24 hours.\u003c\/p\u003e'\n              + '\u003c\/div\u003e';\n          }\n          openQuote();\n          setTimeout(closeQuote, 5500);\n        }\n        if (document.readyState === 'loading') {\n          document.addEventListener('DOMContentLoaded', detectQuoteSubmitted);\n        } else {\n          detectQuoteSubmitted();\n        }\n      })();\n      \u003c\/script\u003e\n    \u003c\/div\u003e\n\n  \u003c\/header\u003e\n\n  \u003c!-- ============ HERO ============ --\u003e\n  \u003csection class=\"hero\" data-anim=\"rise-lg\"\u003e\n    \u003cdiv class=\"hero-text\"\u003e\n    \u003cdiv class=\"hero-eyebrow\" data-anim=\"drop\"\u003e\n      \u003cspan class=\"dot\"\u003e\u003c\/span\u003e\n      Premium Italian Fabrics\n    \u003c\/div\u003e\n    \u003ch2 data-anim=\"reveal\"\u003eEngineered for the\u003cbr\u003e\u003cspan class=\"ital\"\u003ewater.\u003c\/span\u003e Cut for the sun.\u003c\/h2\u003e\n    \u003cp data-anim=\"blur\"\u003eBuilt with SITIP Technical Textiles ; a Bergamo mill weaving performance threads since 1956. Every meter of fabric is finished to survive saltwater, sunlight and a thousand wash cycles.\u003c\/p\u003e\n    \u003cdiv class=\"hero-meta\" data-anim-stagger=\"80\"\u003e\n      \u003cspan data-anim=\"rise\"\u003ePowered by SITIP\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003eMade in Italy\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003eTested in the Mediterranean\u003c\/span\u003e\n    \u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"hero-visual\" data-anim=\"zoom\" aria-label=\"NEW MONICA fabric — UPF 50+ sun protection and water-resistant Italian knit by SITIP\"\u003e\n      \u003cspan class=\"hc-feather\"\u003eUPF 50+ · Water Resistant\u003c\/span\u003e\n      \u003cimg class=\"honeycomb\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0988\/4323\/0595\/files\/NEW_MONICA_FABRIC_UPF_50_WATER_RESISTANT_a7590067-5f99-481a-a1d3-e1247285a509.png?v=1779367352\" alt=\"NEW MONICA fabric by SITIP — UPF 50+ sun protection and water-resistant Italian performance knit\" decoding=\"async\" fetchpriority=\"high\" width=\"460\" height=\"460\"\u003e\n      \u003cspan class=\"hc-label\"\u003e\n        New Fabric\n        \u003cstrong\u003eSITIP · MONICA\u003c\/strong\u003e\n      \u003c\/span\u003e\n    \u003c\/div\u003e\n    \u003csvg class=\"waves\" viewbox=\"0 0 1200 110\" preserveaspectratio=\"none\" aria-hidden=\"true\"\u003e\n      \u003cpath d=\"M0,60 C200,100 400,20 600,60 C800,100 1000,20 1200,60 L1200,110 L0,110 Z\" fill=\"rgba(255,255,255,0.08)\"\u003e\u003c\/path\u003e\n      \u003cpath d=\"M0,80 C200,40 400,110 600,80 C800,50 1000,110 1200,80 L1200,110 L0,110 Z\" fill=\"rgba(255,255,255,0.14)\"\u003e\u003c\/path\u003e\n      \u003cpath d=\"M0,100 C300,80 600,120 900,100 C1050,90 1150,105 1200,100 L1200,110 L0,110 Z\" fill=\"#ffffff\"\u003e\u003c\/path\u003e\n    \u003c\/svg\u003e\n  \u003c\/section\u003e\n\n  \u003c!-- ============ TECHNOLOGIES ============ --\u003e\n  \u003cdiv class=\"section-head\"\u003e\n    \u003cdiv\u003e\n      \u003cdiv class=\"num\" data-anim=\"left\"\u003e01 ; TECHNOLOGY\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eTwo finishes.\u003cbr\u003eOne ocean.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eTwo proprietary SITIP treatments work together ; one repels what the water throws at you, the other shields you from what the sun sends down.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003cdiv class=\"tech-grid\" data-anim-stagger=\"180\"\u003e\n    \u003c!-- Acquazero --\u003e\n    \u003carticle class=\"tech-card acquazero\" data-anim=\"rise-lg\"\u003e\n      \u003cdiv class=\"ring ring-1\"\u003e\u003c\/div\u003e\n      \u003cdiv class=\"ring ring-2\"\u003e\u003c\/div\u003e\n      \u003cdiv class=\"deco\"\u003e\/\/ SITIP·H₂O\u003c\/div\u003e\n      \u003cdiv class=\"badge\"\u003e◐ Water Repellent System\u003c\/div\u003e\n      \u003ch3\u003eAcquazero\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eWater beads off. Salt slides off. Stains never settle.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💧\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eFluorine-free water repellent\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🌿\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003ePFOA-free \u0026amp; eco-friendly chemistry\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🧼\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eWash-resistant ; performance lasts\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💨\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eBreathable with a soft hand-feel\u003c\/div\u003e\n        \u003c\/li\u003e\n      \u003c\/ul\u003e\n    \u003c\/article\u003e\n\n    \u003c!-- NATIVE --\u003e\n    \u003carticle class=\"tech-card eclipse\" data-anim=\"rise-lg\"\u003e\n      \u003csvg class=\"feather\" viewbox=\"0 0 80 140\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\"\u003e\n        \u003cdefs\u003e\n          \u003clineargradient id=\"featherFill\" x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\"\u003e\n            \u003cstop offset=\"0%\" stop-color=\"#ffffff\" stop-opacity=\"0.95\"\u003e\u003c\/stop\u003e\n            \u003cstop offset=\"60%\" stop-color=\"#ffffff\" stop-opacity=\"0.75\"\u003e\u003c\/stop\u003e\n            \u003cstop offset=\"100%\" stop-color=\"#ffffff\" stop-opacity=\"0.35\"\u003e\u003c\/stop\u003e\n          \u003c\/lineargradient\u003e\n          \u003clineargradient id=\"featherShade\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\"\u003e\n            \u003cstop offset=\"0%\" stop-color=\"#ffffff\" stop-opacity=\"0\"\u003e\u003c\/stop\u003e\n            \u003cstop offset=\"50%\" stop-color=\"#ffffff\" stop-opacity=\"0.22\"\u003e\u003c\/stop\u003e\n            \u003cstop offset=\"100%\" stop-color=\"#ffffff\" stop-opacity=\"0\"\u003e\u003c\/stop\u003e\n          \u003c\/lineargradient\u003e\n        \u003c\/defs\u003e\n        \u003c!-- main plume --\u003e\n        \u003cpath d=\"M 40 6 C 22 22, 12 50, 14 82 C 16 108, 26 128, 38 138 L 42 138 C 54 128, 64 108, 66 82 C 68 50, 58 22, 40 6 Z\" fill=\"url(#featherFill)\"\u003e\u003c\/path\u003e\n        \u003c!-- inner shading --\u003e\n        \u003cpath d=\"M 40 18 C 28 32, 22 56, 24 80 C 26 100, 32 116, 40 124 C 48 116, 54 100, 56 80 C 58 56, 52 32, 40 18 Z\" fill=\"url(#featherShade)\"\u003e\u003c\/path\u003e\n        \u003c!-- rachis (central spine) --\u003e\n        \u003cpath d=\"M 40 8 Q 41 70 40 135\" stroke=\"rgba(255,255,255,0.55)\" stroke-width=\"0.9\" fill=\"none\" stroke-linecap=\"round\"\u003e\u003c\/path\u003e\n        \u003c!-- left barbs --\u003e\n        \u003cg stroke=\"rgba(255,255,255,0.32)\" stroke-width=\"0.6\" fill=\"none\" stroke-linecap=\"round\"\u003e\n          \u003cpath d=\"M 39 24 Q 32 27 22 32\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 39 36 Q 30 41 18 48\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 39 48 Q 28 54 16 62\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 39 60 Q 27 67 15 76\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 39 72 Q 27 78 16 88\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 39 84 Q 28 91 18 100\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 39 96 Q 30 104 22 112\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 39 108 Q 32 116 27 124\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 39 120 Q 35 126 32 132\"\u003e\u003c\/path\u003e\n        \u003c\/g\u003e\n        \u003c!-- right barbs --\u003e\n        \u003cg stroke=\"rgba(255,255,255,0.32)\" stroke-width=\"0.6\" fill=\"none\" stroke-linecap=\"round\"\u003e\n          \u003cpath d=\"M 41 24 Q 48 27 58 32\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 41 36 Q 50 41 62 48\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 41 48 Q 52 54 64 62\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 41 60 Q 53 67 65 76\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 41 72 Q 53 78 64 88\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 41 84 Q 52 91 62 100\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 41 96 Q 50 104 58 112\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 41 108 Q 48 116 53 124\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M 41 120 Q 45 126 48 132\"\u003e\u003c\/path\u003e\n        \u003c\/g\u003e\n      \u003c\/svg\u003e\n      \u003cdiv class=\"ring ring-1\"\u003e\u003c\/div\u003e\n      \u003cdiv class=\"deco\"\u003e\/\/ SITIP·UV\u003c\/div\u003e\n      \u003cdiv class=\"badge\"\u003e☀ Sun Protection System\u003c\/div\u003e\n      \u003ch3\u003eEclipse\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eA built-in shadow you wear. Cool to the touch, opaque under glare.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e☀️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eUPF 50+ certified UV protection\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e👁️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eNo see-through, even when wet\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e❄️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eCool-feeling yarn technology\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🎯\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eTailored fit, fully breathable\u003c\/div\u003e\n        \u003c\/li\u003e\n      \u003c\/ul\u003e\n    \u003c\/article\u003e\n  \u003c\/div\u003e\n\n  \u003c!-- ============ PERFORMANCE ============ --\u003e\n  \u003cdiv class=\"section-head\"\u003e\n    \u003cdiv\u003e\n      \u003cdiv class=\"num\" data-anim=\"left\"\u003e02 ; PERFORMANCE\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eHow it moves\u003cbr\u003ewith you.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eFrom the first paddle-out to the last sunset walk ; fabric behaviour you can feel from minute one.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"perf-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eBuilt for movement\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003eFour-direction performance · all-day wear\u003c\/p\u003e\n    \u003cdiv class=\"perf-grid\" data-anim-stagger=\"100\"\u003e\n      \u003cdiv class=\"perf-card\" data-anim=\"zoom\"\u003e\n        \u003cdiv class=\"icon-box\"\u003e💪\u003c\/div\u003e\n        \u003ch4\u003eComfort Fit · Raglan\u003c\/h4\u003e\n        \u003cp\u003eRelaxed silhouette with a raglan sleeve ; falls easy on every body, no compression, no second-skin squeeze.\u003c\/p\u003e\n      \u003c\/div\u003e\n      \u003cdiv class=\"perf-card\" data-anim=\"zoom\"\u003e\n        \u003cdiv class=\"icon-box\"\u003e🔄\u003c\/div\u003e\n        \u003ch4\u003e4-Way Stretch\u003c\/h4\u003e\n        \u003cp\u003eTotal freedom of movement ; every paddle, twist and pop-up unrestricted.\u003c\/p\u003e\n      \u003c\/div\u003e\n      \u003cdiv class=\"perf-card\" data-anim=\"zoom\"\u003e\n        \u003cdiv class=\"icon-box\"\u003e⚡\u003c\/div\u003e\n        \u003ch4\u003eQuick-Dry\u003c\/h4\u003e\n        \u003cp\u003eMoisture is pushed to the surface and gone ; comfortable from sea to sand.\u003c\/p\u003e\n      \u003c\/div\u003e\n      \u003cdiv class=\"perf-card\" data-anim=\"zoom\"\u003e\n        \u003cdiv class=\"icon-box\"\u003e✨\u003c\/div\u003e\n        \u003ch4\u003eAnti-Pilling\u003c\/h4\u003e\n        \u003cp\u003eStays smooth wash after wash. No fuzz, no pills, no premature aging.\u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n  \u003c\/section\u003e\n\n  \u003c!-- ============ CUSTOM PRINT (SEO: custom rashguard, team kits, customizable lycra) ============ --\u003e\n  \u003cdiv class=\"section-head\"\u003e\n    \u003cdiv\u003e\n      \u003cdiv class=\"num\" data-anim=\"left\"\u003e03 ; CUSTOMIZE\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eMake it\u003cbr\u003eyours.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eA custom rashguard built around your team. Print your logo, numbers and sponsors on a denser-than-standard 220 g\/m² Italian lycra ; team-ready from a single piece.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"custom-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eCustom rashguard, your way\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003eLogo · Numbers · Sponsors · Team colours\u003c\/p\u003e\n    \u003cdiv class=\"custom-grid\" data-anim-stagger=\"100\"\u003e\n      \u003cdiv class=\"custom-card\" data-anim=\"zoom\"\u003e\n        \u003cdiv class=\"custom-num\"\u003e01\u003c\/div\u003e\n        \u003ch4\u003ePrint your logo\u003c\/h4\u003e\n        \u003cp\u003eSublimation print across the chest, sleeves and back. Photo-grade detail on a custom lycra rashguard that won't crack, peel or fade.\u003c\/p\u003e\n      \u003c\/div\u003e\n      \u003cdiv class=\"custom-card\" data-anim=\"zoom\"\u003e\n        \u003cdiv class=\"custom-num\"\u003e02\u003c\/div\u003e\n        \u003ch4\u003eNumbers \u0026amp; names\u003c\/h4\u003e\n        \u003cp\u003eRoster ready. Add player numbers, names or sponsor blocks ; perfect for surf clubs, watersports teams and event squads.\u003c\/p\u003e\n      \u003c\/div\u003e\n      \u003cdiv class=\"custom-card\" data-anim=\"zoom\"\u003e\n        \u003cdiv class=\"custom-num\"\u003e03\u003c\/div\u003e\n        \u003ch4\u003eFrom 1 piece\u003c\/h4\u003e\n        \u003cp\u003eNo minimum order on a personalized rashguard. One-off custom prints all the way up to mixed-size team kits of 50+ ; bulk discounts apply automatically.\u003c\/p\u003e\n      \u003c\/div\u003e\n      \u003cdiv class=\"custom-card\" data-anim=\"zoom\"\u003e\n        \u003cdiv class=\"custom-num\"\u003e04\u003c\/div\u003e\n        \u003ch4\u003eMade in Italy\u003c\/h4\u003e\n        \u003cp\u003eCut, sewn and printed in Italy on a 220 gsm Italian knit. The same fabric your team trains and competes in ; no compromise on the custom build.\u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n  \u003c\/section\u003e\n\n  \u003c!-- ============ USE CASES ============ --\u003e\n  \u003cdiv class=\"section-head\"\u003e\n    \u003cdiv\u003e\n      \u003cdiv class=\"num\" data-anim=\"left\"\u003e04 ; USE CASES\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eWear it like\u003cbr\u003eyour favourite tee.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eA \u003cstrong\u003edenser, heavier knit\u003c\/strong\u003e than a standard rashguard, with the \u003cstrong\u003esame protection\u003c\/strong\u003e as the Pro Lycra ; cut with a raglan sleeve and a relaxed silhouette that moves with you instead of clamping down.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"usecase\"\u003e\n    \u003c!-- Fit ID card --\u003e\n    \u003cdiv class=\"compare\" data-anim=\"rise-lg\"\u003e\n      \u003cdiv class=\"compare-pill\"\u003e\n\u003cspan class=\"dot\"\u003e\u003c\/span\u003eRelaxed comfort fit\u003c\/div\u003e\n\n      \u003cdiv class=\"fit-headline\"\u003e\n        \u003ch3\u003eEasy \u003cspan class=\"em\"\u003ecomfort.\u003c\/span\u003e\n\u003c\/h3\u003e\n        \u003cp class=\"compare-lead\"\u003eA \u003cstrong\u003ethicker, denser\u003c\/strong\u003e Italian knit than a regular rashguard ; built to protect, not just to cover. \u003cstrong\u003eRaglan sleeve\u003c\/strong\u003e and \u003cstrong\u003erelaxed silhouette\u003c\/strong\u003e ; drapes easy on every body, no need to be in athletic shape to wear it.\u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"fit-mark\"\u003e\n        \u003cspan\u003eRaglan sleeve\u003c\/span\u003e\n        \u003cspan\u003eRelaxed silhouette\u003c\/span\u003e\n        \u003cspan\u003eEvery body\u003c\/span\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Use cases grid --\u003e\n    \u003cdiv class=\"usecase-list\" data-anim-stagger=\"100\"\u003e\n      \u003cdiv class=\"uc-card\" data-anim=\"rise\"\u003e\n        \u003cdiv class=\"uc-icon\"\u003e\u003csvg viewbox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003ccircle cx=\"12\" cy=\"8\" r=\"3\"\u003e\u003c\/circle\u003e\u003cpath d=\"M5 21c2-4 5-6 7-6s5 2 7 6\"\u003e\u003c\/path\u003e\u003cpath d=\"M3 14c2-2 4-3 6-3\"\u003e\u003c\/path\u003e\u003cpath d=\"M21 14c-2-2-4-3-6-3\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/div\u003e\n        \u003cdiv class=\"uc-num\"\u003e01 \/ Surf\u003c\/div\u003e\n        \u003ch4\u003eLong \u003cspan class=\"ital\"\u003epaddle-outs\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eRaglan sleeve\u003c\/b\u003e gives shoulders total freedom ; dense knit shields ribs from board rash.\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eSurfing\u003c\/span\u003e\u003cspan\u003eSUP\u003c\/span\u003e\u003cspan\u003eBodyboard\u003c\/span\u003e\u003cspan\u003eCoastal rowing\u003c\/span\u003e\n\u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"uc-card\" data-anim=\"rise\"\u003e\n        \u003cdiv class=\"uc-icon\"\u003e\u003csvg viewbox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003ccircle cx=\"12\" cy=\"12\" r=\"9\"\u003e\u003c\/circle\u003e\u003cpath d=\"M3 12h18\"\u003e\u003c\/path\u003e\u003cpath d=\"M12 3c3 3 3 15 0 18\"\u003e\u003c\/path\u003e\u003cpath d=\"M12 3c-3 3-3 15 0 18\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/div\u003e\n        \u003cdiv class=\"uc-num\"\u003e02 \/ Swim\u003c\/div\u003e\n        \u003ch4\u003eOpen \u003cspan class=\"ital\"\u003ewater\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eHydrodynamic\u003c\/b\u003e \u0026amp; opaque ; less drag, faster strokes.\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eOpen-water swim\u003c\/span\u003e\u003cspan\u003eTriathlon\u003c\/span\u003e\u003cspan\u003eCoastal rowing\u003c\/span\u003e\u003cspan\u003eLap swim\u003c\/span\u003e\n\u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"uc-card\" data-anim=\"rise\"\u003e\n        \u003cdiv class=\"uc-icon\"\u003e\u003csvg viewbox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003ccircle cx=\"12\" cy=\"12\" r=\"4\"\u003e\u003c\/circle\u003e\u003cpath d=\"M12 2v3M12 19v3M2 12h3M19 12h3M4.9 4.9l2.1 2.1M17 17l2.1 2.1M4.9 19.1L7 17M17 7l2.1-2.1\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/div\u003e\n        \u003cdiv class=\"uc-num\"\u003e03 \/ Layer\u003c\/div\u003e\n        \u003ch4\u003eUnder a \u003cspan class=\"ital\"\u003ewetsuit\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eSlips on smooth\u003c\/b\u003e ; prevents chafe, adds thermal layer.\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eWetsuit base\u003c\/span\u003e\u003cspan\u003eSpring suit\u003c\/span\u003e\u003cspan\u003eCold water\u003c\/span\u003e\u003cspan\u003eTechnical drysuit\u003c\/span\u003e\n\u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"uc-card\" data-anim=\"rise\"\u003e\n        \u003cdiv class=\"uc-icon\"\u003e\u003csvg viewbox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath d=\"M3 19c2 0 3-2 5-2s3 2 5 2 3-2 5-2 3 2 3 2\"\u003e\u003c\/path\u003e\u003cpath d=\"M3 15c2 0 3-2 5-2s3 2 5 2 3-2 5-2 3 2 3 2\"\u003e\u003c\/path\u003e\u003cpath d=\"M3 11c2 0 3-2 5-2s3 2 5 2 3-2 5-2 3 2 3 2\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/div\u003e\n        \u003cdiv class=\"uc-num\"\u003e04 \/ Sun\u003c\/div\u003e\n        \u003ch4\u003eAll-day \u003cspan class=\"ital\"\u003eUV\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eUPF 50+ Eclipse\u003c\/b\u003e ; blocks 98% UVA \/ UVB, even on reflected glare.\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eTropical\u003c\/span\u003e\u003cspan\u003eSailing\u003c\/span\u003e\u003cspan\u003eKayak\u003c\/span\u003e\u003cspan\u003eBoat days\u003c\/span\u003e\u003cspan\u003eFishing\u003c\/span\u003e\n\u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"uc-card\" data-anim=\"rise\"\u003e\n        \u003cdiv class=\"uc-icon\"\u003e\u003csvg viewbox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath d=\"M4 20l4-8 4 4 4-6 4 10\"\u003e\u003c\/path\u003e\u003ccircle cx=\"12\" cy=\"6\" r=\"2\"\u003e\u003c\/circle\u003e\u003c\/svg\u003e\u003c\/div\u003e\n        \u003cdiv class=\"uc-num\"\u003e05 \/ Watersports\u003c\/div\u003e\n        \u003ch4\u003eSpeed \u0026amp; \u003cspan class=\"ital\"\u003espray\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eHolds firm\u003c\/b\u003e under harness pressure, blocks wind chill at speed.\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eKitesurf\u003c\/span\u003e\u003cspan\u003eWindsurf\u003c\/span\u003e\u003cspan\u003eWing foil\u003c\/span\u003e\u003cspan\u003eWakeboard\u003c\/span\u003e\u003cspan\u003eWater-ski\u003c\/span\u003e\u003cspan\u003eJet ski\u003c\/span\u003e\u003cspan\u003eFlyboard\u003c\/span\u003e\n\u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"uc-card\" data-anim=\"rise\"\u003e\n        \u003cdiv class=\"uc-icon\"\u003e\u003csvg viewbox=\"0 0 24 24\" aria-hidden=\"true\"\u003e\u003cpath d=\"M6 22V10l6-6 6 6v12\"\u003e\u003c\/path\u003e\u003cpath d=\"M9 22V14h6v8\"\u003e\u003c\/path\u003e\u003cpath d=\"M2 12h2M20 12h2\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/div\u003e\n        \u003cdiv class=\"uc-num\"\u003e06 \/ Dive\u003c\/div\u003e\n        \u003ch4\u003eSnorkel \u0026amp; \u003cspan class=\"ital\"\u003efreedive\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eDense knit\u003c\/b\u003e ; warmth on long swims, barrier vs jellyfish \u0026amp; rocks.\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eSnorkeling\u003c\/span\u003e\u003cspan\u003eFreediving\u003c\/span\u003e\u003cspan\u003eSpearfishing\u003c\/span\u003e\u003cspan\u003eCoasteering\u003c\/span\u003e\u003cspan\u003eSeabob\u003c\/span\u003e\u003cspan\u003eScuba base layer\u003c\/span\u003e\n\u003c\/div\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n  \u003c\/section\u003e\n\n  \u003c!-- ============ CERTIFICATIONS ============ --\u003e\n  \u003cdiv class=\"section-head\"\u003e\n    \u003cdiv\u003e\n      \u003cdiv class=\"num\" data-anim=\"left\"\u003e05 ; STANDARDS\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eMade honestly.\u003cbr\u003eMade in Italy.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eIndependently audited from yarn to finished garment. Nothing claimed without proof.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"certs\" data-anim=\"rise-lg\"\u003e\n    \u003cdiv class=\"certs-head\"\u003e\n      \u003ch3 data-anim=\"reveal\"\u003eOrigin \u0026amp; certifications\u003c\/h3\u003e\n      \u003cdiv class=\"stamp\" data-anim=\"right\"\u003eVerified · Audited · Traceable\u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"cert-grid\" data-anim-stagger=\"110\"\u003e\n      \u003cdiv class=\"cert\" data-anim=\"rise\"\u003e\n        \u003cdiv class=\"glyph\"\u003e🇮🇹\u003c\/div\u003e\n        \u003cdiv\u003e\n          \u003cdiv class=\"name\"\u003eMade in Italy\u003c\/div\u003e\n          \u003cdiv class=\"meta\"\u003eBergamo · SITIP mill\u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n      \u003cdiv class=\"cert\" data-anim=\"rise\"\u003e\n        \u003cdiv class=\"glyph\"\u003e✅\u003c\/div\u003e\n        \u003cdiv\u003e\n          \u003cdiv class=\"name\"\u003eOeko-Tex\u003c\/div\u003e\n          \u003cdiv class=\"meta\"\u003eStandard 100 · Class I\u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n      \u003cdiv class=\"cert\" data-anim=\"rise\"\u003e\n        \u003cdiv class=\"glyph\"\u003e🔬\u003c\/div\u003e\n        \u003cdiv\u003e\n          \u003cdiv class=\"name\"\u003eBluesign®\u003c\/div\u003e\n          \u003cdiv class=\"meta\"\u003eApproved supply chain\u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n      \u003cdiv class=\"cert\" data-anim=\"rise\"\u003e\n        \u003cdiv class=\"glyph\"\u003e♻️\u003c\/div\u003e\n        \u003cdiv\u003e\n          \u003cdiv class=\"name\"\u003eEco-Friendly\u003c\/div\u003e\n          \u003cdiv class=\"meta\"\u003eLow-impact dyes \u0026amp; finishes\u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n  \u003c\/section\u003e\n\n  \u003c!-- ============ FAQ (SEO: FAQPage schema) ============ --\u003e\n  \u003cdiv class=\"section-head\"\u003e\n    \u003cdiv\u003e\n      \u003cdiv class=\"num\" data-anim=\"left\"\u003e06 ; FAQ\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eQuestions,\u003cbr\u003eanswered.\u003c\/h2\u003e\n    \u003c\/div\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"faq\" data-anim=\"rise-lg\"\u003e\n    \u003cdiv class=\"faq-list\" data-anim-stagger=\"60\"\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eCan I print my own logo on the rashguard?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eEven better; you can \u003cstrong\u003ebuild your rashguard from scratch\u003c\/strong\u003e with our advanced \u003cstrong\u003e3D configurator\u003c\/strong\u003e. Change colours, add your logo, write your name, place sponsors, mix patterns; everything is previewed live in 3D. Need ideas? Our \u003cstrong\u003eAI Designer\u003c\/strong\u003e generates custom artwork from a simple text prompt. Total creative freedom; no design skills required.\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eWhat's the minimum order for a custom team kit?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\n\u003cstrong\u003eOne piece.\u003c\/strong\u003e There is no minimum. Order a single personalized rashguard or a full team kit of 50+ ; bulk discounts apply automatically from 3 pieces upwards.\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eHow long does a custom order take?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eProduction usually takes \u003cstrong\u003e2 to 3 weeks\u003c\/strong\u003e from checkout, plus shipping. Check the cart page for the exact production time on your current order.\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eWhat size should I choose?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eNo need to worry; the \u003cstrong\u003esize chart will be suggested directly during the configuration step\u003c\/strong\u003e, with measurements tailored to the \u003cstrong\u003erelaxed comfort fit\u003c\/strong\u003e of this model. \u003cstrong\u003eYou don't need to be an athlete to wear it\u003c\/strong\u003e ; the silhouette is cut to fall easy on every body.\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eIs the fabric really UPF 50+?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eYes. The Eclipse finish is rated \u003cstrong\u003eUPF 50+\u003c\/strong\u003e, blocking 98% of UVA\/UVB radiation. Tested and certified to UV Standard 801. The protection is woven into the yarn ; it doesn't wash out.\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eCan I wear it for sports other than surfing?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eWe recommend this model for \u003cstrong\u003eall water-contact sports\u003c\/strong\u003e; surfing, SUP, kitesurfing, swimming, freediving, snorkeling, sailing, wakeboarding and watercraft riding. The denser 220 g\/m² knit makes it ideal whenever you're in or on the water.\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eWhere is it made?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\n\u003cstrong\u003eEntirely produced in Italy\u003c\/strong\u003e, in our technical apparel manufacturing facility in \u003cstrong\u003eParma\u003c\/strong\u003e. Fabric is woven by SITIP in Bergamo, then cut, sewn, printed and finished in-house by our team.\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eHow do I care for it?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eRinse in fresh water after each session. Machine wash cold (30°C) on a gentle cycle, no fabric softener, no tumble dry. Hang to dry; sun drying is fine. Treated right, it will outlast three standard rashguards.\u003c\/div\u003e\n      \u003c\/details\u003e\n    \u003c\/div\u003e\n  \u003c\/section\u003e\n\n  \u003cscript type=\"application\/ld+json\"\u003e\n  {\n    \"@context\": \"https:\/\/schema.org\",\n    \"@type\": \"Product\",\n    \"name\": \"Comfort Fit Rashguard\",\n    \"description\": \"Relaxed-fit 220 g\/m² Italian knit rashguard with raglan sleeve. SITIP Acquazero water repellent and Eclipse UPF 50+ finishes, 4-way stretch. Custom printable from 1 piece for surf, swim, watersports and beach lifestyle. Made in Italy.\",\n    \"category\": \"Sportswear \/ Watersports\",\n    \"brand\": { \"@type\": \"Brand\", \"name\": \"Inferno Beachwear\" },\n    \"material\": \"220 g\/m² Italian knit · SITIP Acquazero · SITIP Eclipse UPF 50+\",\n    \"weight\": { \"@type\": \"QuantitativeValue\", \"value\": 220, \"unitText\": \"g\/m²\" },\n    \"countryOfOrigin\": \"IT\"\n  }\n  \u003c\/script\u003e\n  \u003cscript type=\"application\/ld+json\"\u003e\n  {\n    \"@context\": \"https:\/\/schema.org\",\n    \"@type\": \"FAQPage\",\n    \"mainEntity\": [\n      {\n        \"@type\": \"Question\",\n        \"name\": \"Can I print my own logo on the rashguard?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Yes. You can build your rashguard from scratch with our advanced 3D configurator: change colours, add your logo, write your name, place sponsors and mix patterns, with a live 3D preview. Our AI Designer also generates custom artwork from a simple text prompt, so total creative freedom is possible with no design skills required.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"What's the minimum order for a custom team kit?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"One piece. There is no minimum order. You can order a single personalized rashguard or a full team kit of 50+ pieces. Bulk discounts apply automatically from 3 pieces upwards.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"How long does a custom order take?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Production usually takes 2 to 3 weeks from checkout, plus shipping. Check the cart page for the exact production time on your current order.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"What size should I choose?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"The size chart will be suggested directly during the configuration step, with measurements tailored to the relaxed comfort fit of this model. You don't need to be an athlete to wear it.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"Is the fabric really UPF 50+?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Yes. The Eclipse finish is rated UPF 50+, blocking 98% of UVA\/UVB radiation. Tested and certified to UV Standard 801. The protection is woven into the yarn and does not wash out.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"Can I wear it for sports other than surfing?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"We recommend this model for all water-contact sports: surfing, SUP, kitesurfing, swimming, freediving, snorkeling, sailing, wakeboarding and watercraft riding. The denser 220 g\/m² knit makes it ideal whenever you are in or on the water.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"Where is it made?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Entirely produced in Italy, in our technical apparel manufacturing facility in Parma. Fabric is woven by SITIP in Bergamo, then cut, sewn, printed and finished in-house by our team.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"How do I care for the rashguard?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Rinse in fresh water after each session. Machine wash cold (30°C) on a gentle cycle, no fabric softener, no tumble dry. Hang to dry; sun drying is fine.\"\n        }\n      }\n    ]\n  }\n  \u003c\/script\u003e\n\n  \u003c!-- ============ TICKER ============ --\u003e\n  \u003cdiv class=\"ticker\" data-anim=\"reveal\"\u003e\n    \u003cdiv class=\"ticker-track\"\u003e\n      \u003cspan\u003ePremium Italian Fabrics\u003c\/span\u003e\n      \u003cspan\u003ePowered by SITIP\u003c\/span\u003e\n      \u003cspan\u003eAcquazero Water Repellent\u003c\/span\u003e\n      \u003cspan\u003eEclipse UPF 50+\u003c\/span\u003e\n      \u003cspan\u003e4-Way Stretch\u003c\/span\u003e\n      \u003cspan\u003eMade in Italy\u003c\/span\u003e\n      \u003cspan\u003ePremium Italian Fabrics\u003c\/span\u003e\n      \u003cspan\u003ePowered by SITIP\u003c\/span\u003e\n      \u003cspan\u003eAcquazero Water Repellent\u003c\/span\u003e\n      \u003cspan\u003eEclipse UPF 50+\u003c\/span\u003e\n      \u003cspan\u003e4-Way Stretch\u003c\/span\u003e\n      \u003cspan\u003eMade in Italy\u003c\/span\u003e\n    \u003c\/div\u003e\n  \u003c\/div\u003e\n\n\u003c\/div\u003e\n\u003cscript\u003e\n(function(){\n  var els = Array.from(document.querySelectorAll('.product-desc [data-anim]'));\n  if (!els.length) return;\n  var BASE_STEP = 70;       \/\/ ms between unrelated elements\n  var GROUP_STEP = 60;      \/\/ ms between siblings inside a stagger group (default)\n  var SECTION_GAP = 220;    \/\/ bigger pause when crossing major sections\n  var sectionSelector = '.hero, .section-head, .perf-strip, .certs, .ticker, .product-title, .pricing';\n\n  function findGroup(el) {\n    var p = el.parentElement;\n    while (p \u0026\u0026 p !== document.body) {\n      if (p.hasAttribute('data-anim-stagger')) return p;\n      p = p.parentElement;\n    }\n    return null;\n  }\n  function findSection(el) {\n    return el.closest(sectionSelector);\n  }\n\n  var t = 80; \/\/ initial offset so paint settles\n  var lastSection = null;\n  var seenGroups = new Map();\n\n  els.forEach(function(el, i){\n    var section = findSection(el);\n    if (lastSection \u0026\u0026 section !== lastSection) {\n      t += SECTION_GAP;\n    }\n    lastSection = section;\n\n    var group = findGroup(el);\n    var delay;\n    if (group) {\n      var step = parseInt(group.getAttribute('data-anim-stagger'),10) || GROUP_STEP;\n      if (!seenGroups.has(group)) {\n        seenGroups.set(group, { start: t, step: step, idx: 0 });\n        delay = t;\n        t += step * 1.2; \/\/ group occupies its own band\n      } else {\n        var g = seenGroups.get(group);\n        g.idx++;\n        delay = g.start + g.step * g.idx;\n      }\n    } else {\n      delay = t;\n      t += BASE_STEP;\n    }\n    el.style.transitionDelay = (delay\/1000).toFixed(3) + 's';\n  });\n\n  function play(){\n    requestAnimationFrame(function(){\n      requestAnimationFrame(function(){\n        els.forEach(function(el){ el.classList.add('in'); });\n      });\n    });\n  }\n  if (document.readyState === 'complete' || document.readyState === 'interactive') {\n    play();\n  } else {\n    window.addEventListener('DOMContentLoaded', play);\n  }\n})();\n\u003c\/script\u003e\n\n\u003c!-- Apply density \u0026 motion presets to \u003chtml\u003e on first paint (no flash) --\u003e\n\u003cscript\u003e\n  (function(){\n    var html = document.documentElement;\n    html.setAttribute('data-density', 'compact');\n    html.setAttribute('data-motion', 'riptide');\n  })();\n\u003c\/script\u003e\n\n\u003c\/body\u003e","brand":"Custom Inferno","offers":[{"title":"XS","offer_id":58201476727171,"sku":"COM-SS-XS","price":64.0,"currency_code":"EUR","in_stock":true},{"title":"S","offer_id":58201476759939,"sku":"COM-SS-S","price":64.0,"currency_code":"EUR","in_stock":true},{"title":"M","offer_id":58201476792707,"sku":"COM-SS-M","price":64.0,"currency_code":"EUR","in_stock":true},{"title":"L","offer_id":58201476825475,"sku":"COM-SS-L","price":64.0,"currency_code":"EUR","in_stock":true},{"title":"XL","offer_id":58201476858243,"sku":"COM-SS-XL","price":64.0,"currency_code":"EUR","in_stock":true},{"title":"XXL","offer_id":58201476891011,"sku":"COM-SS-XXL","price":64.0,"currency_code":"EUR","in_stock":true},{"title":"3XL","offer_id":58201476923779,"sku":"COM-SS-3XL","price":64.0,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0988\/4323\/0595\/files\/62029572fcf66415268e9f0b1ffe51c6.jpg?v=1781694991","url":"https:\/\/infernobeachwear.com\/en-it\/products\/men-s-comfort-fit-rashguard-ss-mode-water","provider":"Inferno Beachwear","version":"1.0","type":"link"}