{"title":"THUNDER MASTER","description":"","products":[{"product_id":"men-s-compression-rashguard-ls-iron-fist","title":"Compression Rashguard Uomo Manica Lunga - 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\u003eDescrizione prodotto ; Tessuti italiani premium\u003c\/title\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\u003eCompletamente personalizzabile\u003c\/div\u003e\n      \u003cdiv class=\"meta-row\" data-anim=\"right\"\u003e\n        \u003cspan\u003eSKU · PRO-RG-01\u003c\/span\u003e\n        \u003cspan\u003ePro Series\u003c\/span\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"kicker\" data-anim=\"left\"\u003ePro Lycra · Compression Series\u003c\/div\u003e\n    \u003ch1 data-anim=\"reveal\"\u003ePro Lycra Compression\u003cbr\u003e\u003cspan class=\"accent\"\u003eRashguard\u003c\/span\u003e\n\u003c\/h1\u003e\n    \u003cp class=\"product-full-title\" data-anim=\"rise\"\u003eCompression Rashguard Uomo Manica Lunga - THUNDER MASTER\u003c\/p\u003e\n    \u003cp class=\"subline\" data-anim=\"blur\"\u003e\u003cstrong\u003eRashguard armor-grade personalizzata. Maglia italiana 4-way stretch da 220 g\/m²: stampa il tuo logo, i numeri e gli sponsor su un tessuto più denso dello standard e ad alta resistenza all’abrasione. Dalla singola maglia ai kit completi per la squadra, con una compressione second-skin pensata per surfisti, nuotatori e amanti del mare che non scendono a compromessi.\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n    \u003cdiv class=\"feature-tabs\" data-anim-stagger=\"60\"\u003e\n      \u003cspan data-anim=\"rise\"\u003e✎ Stampa personalizzata\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=b15d36087ff3ba6f3d99173be3294312\" 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        Modifica 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        Crea un nuovo 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\"\u003eSconti \u003cspan class=\"em\" style=\"padding: 2px 50px 0px 0px\"\u003equantità\u003c\/span\u003e\n\u003c\/h3\u003e\n          \u003cp class=\"pricing-sub\"\u003eTrascina il cursore · più ordini, più risparmi\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\"\u003eQuantità\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)\"\u003epz\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% di sconto\u003c\/div\u003e\n          \u003cspan class=\"save\" id=\"save-line\" style=\"color: rgb(0, 0, 0)\"\u003eScegli 2+ pz per iniziare a risparmiare\u003c\/span\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"readout-price\"\u003e\n          \u003cdiv class=\"label\"\u003eIl tuo prezzo\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)\"\u003eTotale: \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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc zero\"\u003e0%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−5%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.95 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−15%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.85 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−25%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.75 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−35%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.65 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−45%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.55 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−50%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.50 | money }} cad.\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+ pezzi\u003c\/div\u003e\n          \u003ch4\u003eTi serve un kit completo per la squadra? Parliamone.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h4\u003e\n          \u003cp\u003ePrezzi dedicati per club, squadre ed eventi da 50+ pezzi: ti inviamo un preventivo entro 24 ore.\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          Richiedi un preventivo\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⚓ Richiesta quantità · 50+ pezzi\u003c\/div\u003e\n            \u003ch3 id=\"quote-modal-title\"\u003eRicevi il tuo preventivo personalizzato.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h3\u003e\n            \u003cp\u003eRaccontaci della tua squadra e ti rispondiamo entro 24h con prezzi e tempi di consegna.\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 Compression Rashguard LS - 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\"\u003eNome club \/ azienda \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\"\u003eInserisci il nome del club o dell’azienda\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\"\u003ePaese \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\"\u003eObbligatorio\u003c\/div\u003e\n                \u003c\/div\u003e\n                \u003cdiv class=\"quote-field\"\u003e\n                  \u003clabel for=\"qf-vat\"\u003ePartita IVA \u003cspan class=\"opt\"\u003e(se presente)\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\"\u003eQuantità \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\"\u003eDeve essere almeno 50\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\"\u003eÈ richiesta un’email valida\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\"\u003eNote \u003cspan class=\"opt\"\u003e(facoltativo — raccontaci della squadra, del design, delle scadenze, ecc.)\u003c\/span\u003e\u003c\/label\u003e\n                  \u003ctextarea id=\"qf-notes\" name=\"contact[Notes]\" rows=\"4\" autocomplete=\"off\" placeholder=\"e.g. 80 compression tops for our triathlon 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\"\u003eSito web (lascia vuoto — 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                Invia richiesta\n              \u003c\/button\u003e\n              \u003cdiv class=\"quote-modal-footnote\"\u003eTi risponderemo entro 24h all’email che ci indichi. Contatto alternativo: custominferno@gmail.com.\u003cstrong\u003e\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      Tessuti italiani premium\n    \u003c\/div\u003e\n    \u003ch2 data-anim=\"reveal\"\u003eProgettata per l’\u003cbr\u003e\u003cspan class=\"ital\"\u003eacqua.\u003c\/span\u003e Tagliata per il sole.\u003c\/h2\u003e\n    \u003cp data-anim=\"blur\"\u003eRealizzata con i tessuti tecnici SITIP, l’azienda di Bergamo che tesse filati ad alte prestazioni dal 1956. Ogni metro di tessuto è rifinito per resistere a salsedine, sole e mille lavaggi.\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\"\u003eTestata nel Mediterraneo\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+ · Idrorepellente\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        Nuovo tessuto SITIP · MONICA\n      \u003cstrong\u003e\u003c\/strong\u003e\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 ; TECNOLOGIA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eDue finiture.\u003cbr\u003eUn solo oceano.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDue trattamenti SITIP brevettati lavorano in coppia: uno respinge ciò che ti lancia l’acqua, l’altro ti scherma da ciò che ti manda il sole.\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◐ Sistema idrorepellente\u003c\/div\u003e\n      \u003ch3\u003eAcquazero\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eL’acqua scivola via, il sale scivola via e le macchie non attecchiscono.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💧\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eIdrorepellente senza fluoro\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🌿\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eChimica senza PFOA ed eco-friendly\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🧼\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eResistente ai lavaggi: le prestazioni durano nel tempo\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💨\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eTraspirante e morbida al tatto\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☀ Sistema di protezione solare\u003c\/div\u003e\n      \u003ch3\u003eEclipse\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eUn’ombra che indossi: fresca al tatto e opaca anche in pieno riverbero.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e☀️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eProtezione UV certificata UPF 50+\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e👁️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eNon trasparente, nemmeno da bagnata\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e❄️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eFilato con tecnologia a effetto fresco\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🎯\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eVestibilità su misura, totalmente traspirante\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\"\u003eCome si muove\u003cbr\u003econ te.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDalla prima remata all’ultima passeggiata al tramonto: un tessuto che senti reattivo fin dal primo minuto.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"perf-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eCostruita per il movimento\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003ePrestazioni in quattro direzioni · comfort tutto il giorno\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\u003eVestibilità a compressione\u003c\/h4\u003e\n        \u003cp\u003eAderisce come una seconda pelle, per il massimo supporto muscolare e zero distrazioni in line-up.\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\u003eTotale libertà di movimento: ogni remata, torsione e pop-up senza il minimo vincolo.\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\u003eAsciugatura rapida\u003c\/h4\u003e\n        \u003cp\u003eL’umidità viene portata in superficie ed evapora in fretta: comfort dal mare alla sabbia.\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\u003eResta liscia lavaggio dopo lavaggio: niente pelucchi, niente pallini, niente invecchiamento precoce.\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 ; PERSONALIZZA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eRendila\u003cbr\u003etua.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna rashguard personalizzata, costruita sulla tua squadra. Stampa logo, numeri e sponsor su una lycra italiana da 220 g\/m², più densa dello standard: pronta per la squadra già dal primo pezzo.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"custom-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eLa tua rashguard personalizzata, a modo tuo\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003eLogo · Numeri · Sponsor · Colori squadra\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\u003eStampa il tuo logo\u003c\/h4\u003e\n        \u003cp\u003eStampa a sublimazione su petto, maniche e schiena. Dettaglio fotografico su una rashguard in lycra personalizzata che non si crepa, non si screpola e non sbiadisce.\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\u003eNumeri e nomi\u003c\/h4\u003e\n        \u003cp\u003ePronta per la rosa: aggiungi numeri di gioco, nomi o blocchi sponsor. Perfetta per surf club, team di sport acquatici e squadre da evento.\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\u003eDa 1 pezzo\u003c\/h4\u003e\n        \u003cp\u003eNessun ordine minimo per una rashguard personalizzata: dal pezzo unico fino ai kit squadra con taglie miste da 50+, con gli sconti quantità applicati in automatico.\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\u003eTagliata, cucita e stampata in Italia su una maglia italiana da 220 g\/m². Lo stesso tessuto con cui la tua squadra si allena e gareggia: nessun compromesso sulla personalizzazione.\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 ; UTILIZZI\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eIndossala come\u003cbr\u003eun’armatura.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna maglia più densa e pesante di una rashguard standard, pensata per proteggerti attivamente da sole, vento, abrasioni e impatti, mentre il taglio a compressione mantiene tutto aerodinamico.\u003cstrong\u003e\u003c\/strong\u003e\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\u003eCompressione armor-grade\u003c\/div\u003e\n\n      \u003cdiv class=\"fit-headline\"\u003e\n        \u003ch3\u003eSecond-skin \u003cspan class=\"em\"\u003eun’armatura.\u003c\/span\u003e\n\u003c\/h3\u003e\n        \u003cp class=\"compare-lead\"\u003eUna maglia italiana più spessa e densa di una rashguard normale, pensata per proteggere e non solo per coprire. Il taglio a compressione fascia i muscoli: scegli una taglia in più se preferisci una vestibilità più morbida.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"fit-mark\"\u003e\n        \u003cspan\u003eMaglia più pesante\u003c\/span\u003e\n        \u003cspan\u003eTaglie atletiche\u003c\/span\u003e\n        \u003cspan\u003eProtezione attiva\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\u003eLunghe \u003cspan class=\"ital\"\u003eremate\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eLa compressione sostiene le spalle e la maglia densa protegge le costole dallo sfregamento della tavola.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eSurf\u003c\/span\u003e\u003cspan\u003eSUP\u003c\/span\u003e\u003cspan\u003eBodyboard\u003c\/span\u003e\u003cspan\u003eCanottaggio costiero\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 \/ Nuoto\u003c\/div\u003e\n        \u003ch4\u003eAcque \u003cspan class=\"ital\"\u003elibere\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eIdrodinamica e opaca: meno attrito nell’acqua e bracciate più veloci.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eNuoto in acque libere\u003c\/span\u003e\u003cspan\u003eTriathlon\u003c\/span\u003e\u003cspan\u003eCanottaggio costiero\u003c\/span\u003e\u003cspan\u003eNuoto in vasca\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 \/ Strato\u003c\/div\u003e\n        \u003ch4\u003eSotto la \u003cspan class=\"ital\"\u003emuta\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eSi indossa con scioltezza: previene gli sfregamenti e aggiunge uno strato termico.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eStrato base sotto muta\u003c\/span\u003e\u003cspan\u003eMuta shorty\u003c\/span\u003e\u003cspan\u003eAcqua fredda\u003c\/span\u003e\u003cspan\u003eMuta stagna tecnica\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 \/ Sole\u003c\/div\u003e\n        \u003ch4\u003eTutto il giorno \u003cspan class=\"ital\"\u003eUV\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eUPF 50+ Eclipse: blocca il 98% di UVA \/ UVB, anche dai riflessi.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eTropici\u003c\/span\u003e\u003cspan\u003eVela\u003c\/span\u003e\u003cspan\u003eKayak\u003c\/span\u003e\u003cspan\u003eGiornate in barca\u003c\/span\u003e\u003cspan\u003ePesca\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 \/ Sport acquatici\u003c\/div\u003e\n        \u003ch4\u003eVelocità e \u003cspan class=\"ital\"\u003espruzzi\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eResta ben aderente sotto la pressione dell’imbracatura e ti protegge dal freddo del vento alle alte velocità.\u003c\/b\u003e\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\u003eSci nautico\u003c\/span\u003e\u003cspan\u003eMoto d’acqua\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 \/ Immersione\u003c\/div\u003e\n        \u003ch4\u003eSnorkeling e \u003cspan class=\"ital\"\u003eapnea\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eMaglia densa: tiene caldo nelle lunghe nuotate e fa da barriera contro meduse e scogli.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eSnorkeling\u003c\/span\u003e\u003cspan\u003eApnea\u003c\/span\u003e\u003cspan\u003ePesca in apnea\u003c\/span\u003e\u003cspan\u003eCoasteering\u003c\/span\u003e\u003cspan\u003eSeabob\u003c\/span\u003e\u003cspan\u003eStrato base per sub\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 ; STANDARD\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eFatta con onestà.\u003cbr\u003eMade in Italy.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eControllata in modo indipendente, dal filato al capo finito: nessuna dichiarazione senza prove.\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\"\u003eOrigine e certificazioni\u003c\/h3\u003e\n      \u003cdiv class=\"stamp\" data-anim=\"right\"\u003eVerificato · Controllato · Tracciabile\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 · stabilimento SITIP\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 · Classe 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\"\u003eFiliera approvata\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\"\u003eTinture e finissaggi a basso impatto\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\"\u003eDomande,\u003cbr\u003erisposte.\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\u003ePosso stampare il mio logo sulla rashguard?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eAncora meglio: puoi creare la tua rashguard da zero con il nostro configuratore 3D avanzato. Cambia i colori, aggiungi il logo, scrivi il tuo nome, posiziona gli sponsor e combina le fantasie, vedendo tutto in anteprima live in 3D. Servono idee? Il nostro AI Designer genera grafiche personalizzate da una semplice descrizione testuale: massima libertà creativa, senza bisogno di saper disegnare.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQual è l’ordine minimo per un kit squadra personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nBasta un pezzo: non c’è un minimo. Ordina una singola rashguard personalizzata o un kit completo da 50+, con gli sconti quantità che partono in automatico già da 3 pezzi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQuanto tempo richiede un ordine personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eDi solito la produzione richiede 2-3 settimane dal checkout, più i tempi di spedizione. Controlla la pagina del carrello per il tempo di produzione esatto del tuo ordine.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eChe taglia devo scegliere?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eNessun problema: la guida alle taglie ti verrà suggerita direttamente durante la configurazione, con misure calibrate sulla vestibilità a compressione di questo modello.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eIl tessuto è davvero UPF 50+?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eSì. La finitura Eclipse è certificata UPF 50+ e blocca il 98% delle radiazioni UVA\/UVB. È testata e certificata secondo lo UV Standard 801, e la protezione è intessuta nel filato: non se ne va con i lavaggi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003ePosso usarla per sport diversi dal surf?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eConsigliamo questo modello per tutti gli sport a contatto con l’acqua: surf, SUP, kitesurf, nuoto, apnea, snorkeling, vela, wakeboard e guida di mezzi acquatici. La maglia più densa da 220 g\/m² lo rende ideale ogni volta che sei dentro o sopra l’acqua.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eDove è prodotta?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nInteramente prodotta in Italia, nel nostro stabilimento di abbigliamento tecnico a Parma. Il tessuto è realizzato da SITIP a Bergamo, poi tagliato, cucito, stampato e rifinito internamente dal nostro team.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eCome si lava?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eSciacquala in acqua dolce dopo ogni sessione. Lavaggio in lavatrice a freddo (30°C) con ciclo delicato, senza ammorbidente e senza asciugatrice. Falla asciugare stesa; va bene anche al sole. Trattata bene, durerà più di tre rashguard standard.\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\": \"Pro Lycra Compression Rashguard\",\n    \"description\": \"Custom armor-grade rashguard. Italian 4-way stretch knit at 220 g\/m² with Acquazero water-repellent finish and Eclipse UPF 50+ sun protection. Custom printable from 1 piece. Made in Italy.\",\n    \"category\": \"Sportswear \/ Watersports\",\n    \"brand\": { \"@type\": \"Brand\", \"name\": \"Inferno Beachwear\" },\n    \"material\": \"Italian Lycra · SITIP · Acquazero · 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 compression fit of this model.\"\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\u003eTessuti italiani premium\u003c\/span\u003e\n      \u003cspan\u003ePowered by SITIP\u003c\/span\u003e\n      \u003cspan\u003eAcquazero Idrorepellente\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\u003eTessuti italiani premium\u003c\/span\u003e\n      \u003cspan\u003ePowered by SITIP\u003c\/span\u003e\n      \u003cspan\u003eAcquazero Idrorepellente\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":58201473876355,"sku":"PRO-LS-XS","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"S","offer_id":58201473909123,"sku":"PRO-LS-S","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"M","offer_id":58201473941891,"sku":"PRO-LS-M","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"L","offer_id":58201473974659,"sku":"PRO-LS-L","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"XL","offer_id":58201474007427,"sku":"PRO-LS-XL","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"XXL","offer_id":58201474040195,"sku":"PRO-LS-XXL","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"3XL","offer_id":58201474072963,"sku":"PRO-LS-3XL","price":69.0,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0988\/4323\/0595\/files\/ac31738d60a4cae9fc708701c1ec0449.jpg?v=1780911230"},{"product_id":"men-s-comfort-fit-rashguard-ss-mode-water","title":"Comfort Fit Rashguard Uomo Manica Corta - 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 ; Tessuti italiani premium\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\u003eCompletamente personalizzabile\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\"\u003eComfort Fit Rashguard Uomo Manica Corta - THUNDER MASTER\u003c\/p\u003e\n    \u003cp class=\"subline\" data-anim=\"blur\"\u003e\u003cstrong\u003eRashguard relaxed-fit personalizzata. Stessa maglia italiana 4-way stretch da 220 g\/m² e stesse prestazioni SITIP, ma con manica raglan e una silhouette rilassata che cade morbida invece di comprimere. Stampa il tuo logo, i numeri e gli sponsor, dalla singola maglia ai kit completi per la squadra: comfort tutto il giorno per ogni fisico, senza bisogno di una corporatura atletica.\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n    \u003cdiv class=\"feature-tabs\" data-anim-stagger=\"60\"\u003e\n      \u003cspan data-anim=\"rise\"\u003e✎ Stampa personalizzata\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        Modifica 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        Crea un nuovo 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\"\u003eSconti \u003cspan class=\"em\" style=\"padding: 2px 50px 0px 0px\"\u003equantità\u003c\/span\u003e\n\u003c\/h3\u003e\n          \u003cp class=\"pricing-sub\"\u003eTrascina il cursore · più ordini, più risparmi\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\"\u003eQuantità\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)\"\u003epz\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% di sconto\u003c\/div\u003e\n          \u003cspan class=\"save\" id=\"save-line\" style=\"color: rgb(0, 0, 0)\"\u003eScegli 2+ pz per iniziare a risparmiare\u003c\/span\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"readout-price\"\u003e\n          \u003cdiv class=\"label\"\u003eIl tuo prezzo\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)\"\u003eTotale: \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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc zero\"\u003e0%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−5%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.95 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−15%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.85 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−25%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.75 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−35%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.65 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−45%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.55 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−50%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.50 | money }} cad.\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+ pezzi\u003c\/div\u003e\n          \u003ch4\u003eTi serve un kit completo per la squadra? Parliamone.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h4\u003e\n          \u003cp\u003ePrezzi dedicati per club, squadre ed eventi da 50+ pezzi: ti inviamo un preventivo entro 24 ore.\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          Richiedi un preventivo\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⚓ Richiesta quantità · 50+ pezzi\u003c\/div\u003e\n            \u003ch3 id=\"quote-modal-title\"\u003eRicevi il tuo preventivo personalizzato.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h3\u003e\n            \u003cp\u003eRaccontaci della tua squadra e ti rispondiamo entro 24h con prezzi e tempi di consegna.\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\"\u003eNome club \/ azienda \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\"\u003eInserisci il nome del club o dell’azienda\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\"\u003ePaese \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\"\u003eObbligatorio\u003c\/div\u003e\n                \u003c\/div\u003e\n                \u003cdiv class=\"quote-field\"\u003e\n                  \u003clabel for=\"qf-vat\"\u003ePartita IVA \u003cspan class=\"opt\"\u003e(se presente)\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\"\u003eQuantità \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\"\u003eDeve essere almeno 50\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\"\u003eÈ richiesta un’email valida\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\"\u003eNote \u003cspan class=\"opt\"\u003e(facoltativo — raccontaci della squadra, del design, delle scadenze, ecc.)\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\"\u003eSito web (lascia vuoto — 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                Invia richiesta\n              \u003c\/button\u003e\n              \u003cdiv class=\"quote-modal-footnote\"\u003eTi risponderemo entro 24h all’email che ci indichi. Contatto alternativo: custominferno@gmail.com.\u003cstrong\u003e\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      Tessuti italiani premium\n    \u003c\/div\u003e\n    \u003ch2 data-anim=\"reveal\"\u003eProgettata per l’\u003cbr\u003e\u003cspan class=\"ital\"\u003eacqua.\u003c\/span\u003e Tagliata per il sole.\u003c\/h2\u003e\n    \u003cp data-anim=\"blur\"\u003eRealizzata con i tessuti tecnici SITIP, l’azienda di Bergamo che tesse filati ad alte prestazioni dal 1956. Ogni metro di tessuto è rifinito per resistere a salsedine, sole e mille lavaggi.\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\"\u003eTestata nel Mediterraneo\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+ · Idrorepellente\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        Nuovo tessuto SITIP · MONICA\n      \u003cstrong\u003e\u003c\/strong\u003e\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 ; TECNOLOGIA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eDue finiture.\u003cbr\u003eUn solo oceano.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDue trattamenti SITIP brevettati lavorano in coppia: uno respinge ciò che ti lancia l’acqua, l’altro ti scherma da ciò che ti manda il sole.\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◐ Sistema idrorepellente\u003c\/div\u003e\n      \u003ch3\u003eAcquazero\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eL’acqua scivola via, il sale scivola via e le macchie non attecchiscono.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💧\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eIdrorepellente senza fluoro\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🌿\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eChimica senza PFOA ed eco-friendly\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🧼\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eResistente ai lavaggi: le prestazioni durano nel tempo\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💨\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eTraspirante e morbida al tatto\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☀ Sistema di protezione solare\u003c\/div\u003e\n      \u003ch3\u003eEclipse\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eUn’ombra che indossi: fresca al tatto e opaca anche in pieno riverbero.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e☀️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eProtezione UV certificata UPF 50+\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e👁️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eNon trasparente, nemmeno da bagnata\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e❄️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eFilato con tecnologia a effetto fresco\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🎯\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eVestibilità su misura, totalmente traspirante\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\"\u003eCome si muove\u003cbr\u003econ te.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDalla prima remata all’ultima passeggiata al tramonto: un tessuto che senti reattivo fin dal primo minuto.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"perf-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eCostruita per il movimento\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003ePrestazioni in quattro direzioni · comfort tutto il giorno\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\u003eSilhouette rilassata con manica raglan: cade morbida su ogni fisico, senza compressione e senza effetto seconda pelle.\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\u003eTotale libertà di movimento: ogni remata, torsione e pop-up senza il minimo vincolo.\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\u003eAsciugatura rapida\u003c\/h4\u003e\n        \u003cp\u003eL’umidità viene portata in superficie ed evapora in fretta: comfort dal mare alla sabbia.\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\u003eResta liscia lavaggio dopo lavaggio: niente pelucchi, niente pallini, niente invecchiamento precoce.\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 ; PERSONALIZZA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eRendila\u003cbr\u003etua.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna rashguard personalizzata, costruita sulla tua squadra. Stampa logo, numeri e sponsor su una lycra italiana da 220 g\/m², più densa dello standard: pronta per la squadra già dal primo pezzo.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"custom-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eLa tua rashguard personalizzata, a modo tuo\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003eLogo · Numeri · Sponsor · Colori squadra\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\u003eStampa il tuo logo\u003c\/h4\u003e\n        \u003cp\u003eStampa a sublimazione su petto, maniche e schiena. Dettaglio fotografico su una rashguard in lycra personalizzata che non si crepa, non si screpola e non sbiadisce.\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\u003eNumeri e nomi\u003c\/h4\u003e\n        \u003cp\u003ePronta per la rosa: aggiungi numeri di gioco, nomi o blocchi sponsor. Perfetta per surf club, team di sport acquatici e squadre da evento.\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\u003eDa 1 pezzo\u003c\/h4\u003e\n        \u003cp\u003eNessun ordine minimo per una rashguard personalizzata: dal pezzo unico fino ai kit squadra con taglie miste da 50+, con gli sconti quantità applicati in automatico.\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\u003eTagliata, cucita e stampata in Italia su una maglia italiana da 220 g\/m². Lo stesso tessuto con cui la tua squadra si allena e gareggia: nessun compromesso sulla personalizzazione.\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 ; UTILIZZI\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eIndossala come\u003cbr\u003ela tua t-shirt preferita.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna maglia più densa e pesante di una rashguard standard, con la stessa protezione della Pro Lycra, ma tagliata con manica raglan e una silhouette rilassata che si muove con te invece di stringere.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\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\u003eVestibilità comfort rilassata\u003c\/div\u003e\n\n      \u003cdiv class=\"fit-headline\"\u003e\n        \u003ch3\u003eComfort \u003cspan class=\"em\"\u003erilassato.\u003c\/span\u003e\n\u003c\/h3\u003e\n        \u003cp class=\"compare-lead\"\u003eUna maglia italiana più spessa e densa di una rashguard normale, pensata per proteggere e non solo per coprire. Manica raglan e silhouette rilassata: cade morbida su ogni fisico, senza bisogno di essere in forma atletica per indossarla.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"fit-mark\"\u003e\n        \u003cspan\u003eManica raglan\u003c\/span\u003e\n        \u003cspan\u003eSilhouette rilassata\u003c\/span\u003e\n        \u003cspan\u003eOgni fisico\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\u003eLunghe \u003cspan class=\"ital\"\u003eremate\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eLa manica raglan dà totale libertà alle spalle e la maglia densa protegge le costole dallo sfregamento della tavola.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eSurf\u003c\/span\u003e\u003cspan\u003eSUP\u003c\/span\u003e\u003cspan\u003eBodyboard\u003c\/span\u003e\u003cspan\u003eCanottaggio costiero\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 \/ Nuoto\u003c\/div\u003e\n        \u003ch4\u003eAcque \u003cspan class=\"ital\"\u003elibere\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eIdrodinamica e opaca: meno attrito nell’acqua e bracciate più veloci.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eNuoto in acque libere\u003c\/span\u003e\u003cspan\u003eTriathlon\u003c\/span\u003e\u003cspan\u003eCanottaggio costiero\u003c\/span\u003e\u003cspan\u003eNuoto in vasca\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 \/ Strato\u003c\/div\u003e\n        \u003ch4\u003eSotto la \u003cspan class=\"ital\"\u003emuta\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eSi indossa con scioltezza: previene gli sfregamenti e aggiunge uno strato termico.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eStrato base sotto muta\u003c\/span\u003e\u003cspan\u003eMuta shorty\u003c\/span\u003e\u003cspan\u003eAcqua fredda\u003c\/span\u003e\u003cspan\u003eMuta stagna tecnica\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 \/ Sole\u003c\/div\u003e\n        \u003ch4\u003eTutto il giorno \u003cspan class=\"ital\"\u003eUV\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eUPF 50+ Eclipse: blocca il 98% di UVA \/ UVB, anche dai riflessi.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eTropici\u003c\/span\u003e\u003cspan\u003eVela\u003c\/span\u003e\u003cspan\u003eKayak\u003c\/span\u003e\u003cspan\u003eGiornate in barca\u003c\/span\u003e\u003cspan\u003ePesca\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 \/ Sport acquatici\u003c\/div\u003e\n        \u003ch4\u003eVelocità e \u003cspan class=\"ital\"\u003espruzzi\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eResta ben aderente sotto la pressione dell’imbracatura e ti protegge dal freddo del vento alle alte velocità.\u003c\/b\u003e\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\u003eSci nautico\u003c\/span\u003e\u003cspan\u003eMoto d’acqua\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 \/ Immersione\u003c\/div\u003e\n        \u003ch4\u003eSnorkeling e \u003cspan class=\"ital\"\u003eapnea\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eMaglia densa: tiene caldo nelle lunghe nuotate e fa da barriera contro meduse e scogli.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eSnorkeling\u003c\/span\u003e\u003cspan\u003eApnea\u003c\/span\u003e\u003cspan\u003ePesca in apnea\u003c\/span\u003e\u003cspan\u003eCoasteering\u003c\/span\u003e\u003cspan\u003eSeabob\u003c\/span\u003e\u003cspan\u003eStrato base per sub\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 ; STANDARD\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eFatta con onestà.\u003cbr\u003eMade in Italy.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eControllata in modo indipendente, dal filato al capo finito: nessuna dichiarazione senza prove.\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\"\u003eOrigine e certificazioni\u003c\/h3\u003e\n      \u003cdiv class=\"stamp\" data-anim=\"right\"\u003eVerificato · Controllato · Tracciabile\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 · stabilimento SITIP\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 · Classe 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\"\u003eFiliera approvata\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\"\u003eTinture e finissaggi a basso impatto\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\"\u003eDomande,\u003cbr\u003erisposte.\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\u003ePosso stampare il mio logo sulla rashguard?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eAncora meglio: puoi creare la tua rashguard da zero con il nostro configuratore 3D avanzato. Cambia i colori, aggiungi il logo, scrivi il tuo nome, posiziona gli sponsor e combina le fantasie, vedendo tutto in anteprima live in 3D. Servono idee? Il nostro AI Designer genera grafiche personalizzate da una semplice descrizione testuale: massima libertà creativa, senza bisogno di saper disegnare.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQual è l’ordine minimo per un kit squadra personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nBasta un pezzo: non c’è un minimo. Ordina una singola rashguard personalizzata o un kit completo da 50+, con gli sconti quantità che partono in automatico già da 3 pezzi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQuanto tempo richiede un ordine personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eDi solito la produzione richiede 2-3 settimane dal checkout, più i tempi di spedizione. Controlla la pagina del carrello per il tempo di produzione esatto del tuo ordine.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eChe taglia devo scegliere?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eNessun problema: la guida alle taglie ti verrà suggerita direttamente durante la configurazione, con misure calibrate sulla vestibilità comfort rilassata di questo modello. Non serve essere atleti per indossarla: la silhouette è tagliata per cadere morbida su ogni fisico.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eIl tessuto è davvero UPF 50+?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eSì. La finitura Eclipse è certificata UPF 50+ e blocca il 98% delle radiazioni UVA\/UVB. È testata e certificata secondo lo UV Standard 801, e la protezione è intessuta nel filato: non se ne va con i lavaggi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003ePosso usarla per sport diversi dal surf?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eConsigliamo questo modello per tutti gli sport a contatto con l’acqua: surf, SUP, kitesurf, nuoto, apnea, snorkeling, vela, wakeboard e guida di mezzi acquatici. La maglia più densa da 220 g\/m² lo rende ideale ogni volta che sei dentro o sopra l’acqua.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eDove è prodotta?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nInteramente prodotta in Italia, nel nostro stabilimento di abbigliamento tecnico a Parma. Il tessuto è realizzato da SITIP a Bergamo, poi tagliato, cucito, stampato e rifinito internamente dal nostro team.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eCome si lava?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eSciacquala in acqua dolce dopo ogni sessione. Lavaggio in lavatrice a freddo (30°C) con ciclo delicato, senza ammorbidente e senza asciugatrice. Falla asciugare stesa; va bene anche al sole. Trattata bene, durerà più di tre rashguard standard.\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\u003eTessuti italiani premium\u003c\/span\u003e\n      \u003cspan\u003ePowered by SITIP\u003c\/span\u003e\n      \u003cspan\u003eAcquazero Idrorepellente\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\u003eTessuti italiani premium\u003c\/span\u003e\n      \u003cspan\u003ePowered by SITIP\u003c\/span\u003e\n      \u003cspan\u003eAcquazero Idrorepellente\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"},{"product_id":"men-s-comfort-fit-rashguard-ls-stefan-boltzmann","title":"Comfort Fit Rashguard Uomo Manica Lunga - 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 ; Tessuti italiani premium\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\u003eCompletamente personalizzabile\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\"\u003eComfort Fit Rashguard Uomo Manica Lunga - THUNDER MASTER\u003c\/p\u003e\n    \u003cp class=\"subline\" data-anim=\"blur\"\u003e\u003cstrong\u003eRashguard relaxed-fit personalizzata. Stessa maglia italiana 4-way stretch da 220 g\/m² e stesse prestazioni SITIP, ma con manica raglan e una silhouette rilassata che cade morbida invece di comprimere. Stampa il tuo logo, i numeri e gli sponsor, dalla singola maglia ai kit completi per la squadra: comfort tutto il giorno per ogni fisico, senza bisogno di una corporatura atletica.\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n    \u003cdiv class=\"feature-tabs\" data-anim-stagger=\"60\"\u003e\n      \u003cspan data-anim=\"rise\"\u003e✎ Stampa personalizzata\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=e689841ac79d17935a9ee478c20fb7b1\" 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        Modifica 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        Crea un nuovo 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\"\u003eSconti \u003cspan class=\"em\" style=\"padding: 2px 50px 0px 0px\"\u003equantità\u003c\/span\u003e\n\u003c\/h3\u003e\n          \u003cp class=\"pricing-sub\"\u003eTrascina il cursore · più ordini, più risparmi\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\"\u003eQuantità\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)\"\u003epz\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% di sconto\u003c\/div\u003e\n          \u003cspan class=\"save\" id=\"save-line\" style=\"color: rgb(0, 0, 0)\"\u003eScegli 2+ pz per iniziare a risparmiare\u003c\/span\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"readout-price\"\u003e\n          \u003cdiv class=\"label\"\u003eIl tuo prezzo\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)\"\u003eTotale: \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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc zero\"\u003e0%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−5%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.95 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−15%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.85 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−25%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.75 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−35%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.65 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−45%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.55 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−50%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.50 | money }} cad.\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+ pezzi\u003c\/div\u003e\n          \u003ch4\u003eTi serve un kit completo per la squadra? Parliamone.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h4\u003e\n          \u003cp\u003ePrezzi dedicati per club, squadre ed eventi da 50+ pezzi: ti inviamo un preventivo entro 24 ore.\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          Richiedi un preventivo\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⚓ Richiesta quantità · 50+ pezzi\u003c\/div\u003e\n            \u003ch3 id=\"quote-modal-title\"\u003eRicevi il tuo preventivo personalizzato.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h3\u003e\n            \u003cp\u003eRaccontaci della tua squadra e ti rispondiamo entro 24h con prezzi e tempi di consegna.\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 LS - 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\"\u003eNome club \/ azienda \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\"\u003eInserisci il nome del club o dell’azienda\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\"\u003ePaese \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\"\u003eObbligatorio\u003c\/div\u003e\n                \u003c\/div\u003e\n                \u003cdiv class=\"quote-field\"\u003e\n                  \u003clabel for=\"qf-vat\"\u003ePartita IVA \u003cspan class=\"opt\"\u003e(se presente)\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\"\u003eQuantità \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\"\u003eDeve essere almeno 50\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\"\u003eÈ richiesta un’email valida\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\"\u003eNote \u003cspan class=\"opt\"\u003e(facoltativo — raccontaci della squadra, del design, delle scadenze, ecc.)\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\"\u003eSito web (lascia vuoto — 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                Invia richiesta\n              \u003c\/button\u003e\n              \u003cdiv class=\"quote-modal-footnote\"\u003eTi risponderemo entro 24h all’email che ci indichi. Contatto alternativo: custominferno@gmail.com.\u003cstrong\u003e\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      Tessuti italiani premium\n    \u003c\/div\u003e\n    \u003ch2 data-anim=\"reveal\"\u003eProgettata per l’\u003cbr\u003e\u003cspan class=\"ital\"\u003eacqua.\u003c\/span\u003e Tagliata per il sole.\u003c\/h2\u003e\n    \u003cp data-anim=\"blur\"\u003eRealizzata con i tessuti tecnici SITIP, l’azienda di Bergamo che tesse filati ad alte prestazioni dal 1956. Ogni metro di tessuto è rifinito per resistere a salsedine, sole e mille lavaggi.\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\"\u003eTestata nel Mediterraneo\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+ · Idrorepellente\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        Nuovo tessuto SITIP · MONICA\n      \u003cstrong\u003e\u003c\/strong\u003e\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 ; TECNOLOGIA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eDue finiture.\u003cbr\u003eUn solo oceano.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDue trattamenti SITIP brevettati lavorano in coppia: uno respinge ciò che ti lancia l’acqua, l’altro ti scherma da ciò che ti manda il sole.\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◐ Sistema idrorepellente\u003c\/div\u003e\n      \u003ch3\u003eAcquazero\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eL’acqua scivola via, il sale scivola via e le macchie non attecchiscono.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💧\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eIdrorepellente senza fluoro\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🌿\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eChimica senza PFOA ed eco-friendly\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🧼\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eResistente ai lavaggi: le prestazioni durano nel tempo\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💨\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eTraspirante e morbida al tatto\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☀ Sistema di protezione solare\u003c\/div\u003e\n      \u003ch3\u003eEclipse\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eUn’ombra che indossi: fresca al tatto e opaca anche in pieno riverbero.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e☀️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eProtezione UV certificata UPF 50+\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e👁️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eNon trasparente, nemmeno da bagnata\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e❄️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eFilato con tecnologia a effetto fresco\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🎯\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eVestibilità su misura, totalmente traspirante\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\"\u003eCome si muove\u003cbr\u003econ te.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDalla prima remata all’ultima passeggiata al tramonto: un tessuto che senti reattivo fin dal primo minuto.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"perf-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eCostruita per il movimento\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003ePrestazioni in quattro direzioni · comfort tutto il giorno\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\u003eSilhouette rilassata con manica raglan: cade morbida su ogni fisico, senza compressione e senza effetto seconda pelle.\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\u003eTotale libertà di movimento: ogni remata, torsione e pop-up senza il minimo vincolo.\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\u003eAsciugatura rapida\u003c\/h4\u003e\n        \u003cp\u003eL’umidità viene portata in superficie ed evapora in fretta: comfort dal mare alla sabbia.\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\u003eResta liscia lavaggio dopo lavaggio: niente pelucchi, niente pallini, niente invecchiamento precoce.\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 ; PERSONALIZZA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eRendila\u003cbr\u003etua.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna rashguard personalizzata, costruita sulla tua squadra. Stampa logo, numeri e sponsor su una lycra italiana da 220 g\/m², più densa dello standard: pronta per la squadra già dal primo pezzo.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"custom-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eLa tua rashguard personalizzata, a modo tuo\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003eLogo · Numeri · Sponsor · Colori squadra\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\u003eStampa il tuo logo\u003c\/h4\u003e\n        \u003cp\u003eStampa a sublimazione su petto, maniche e schiena. Dettaglio fotografico su una rashguard in lycra personalizzata che non si crepa, non si screpola e non sbiadisce.\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\u003eNumeri e nomi\u003c\/h4\u003e\n        \u003cp\u003ePronta per la rosa: aggiungi numeri di gioco, nomi o blocchi sponsor. Perfetta per surf club, team di sport acquatici e squadre da evento.\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\u003eDa 1 pezzo\u003c\/h4\u003e\n        \u003cp\u003eNessun ordine minimo per una rashguard personalizzata: dal pezzo unico fino ai kit squadra con taglie miste da 50+, con gli sconti quantità applicati in automatico.\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\u003eTagliata, cucita e stampata in Italia su una maglia italiana da 220 g\/m². Lo stesso tessuto con cui la tua squadra si allena e gareggia: nessun compromesso sulla personalizzazione.\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 ; UTILIZZI\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eIndossala come\u003cbr\u003ela tua t-shirt preferita.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna maglia più densa e pesante di una rashguard standard, con la stessa protezione della Pro Lycra, ma tagliata con manica raglan e una silhouette rilassata che si muove con te invece di stringere.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\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\u003eVestibilità comfort rilassata\u003c\/div\u003e\n\n      \u003cdiv class=\"fit-headline\"\u003e\n        \u003ch3\u003eComfort \u003cspan class=\"em\"\u003erilassato.\u003c\/span\u003e\n\u003c\/h3\u003e\n        \u003cp class=\"compare-lead\"\u003eUna maglia italiana più spessa e densa di una rashguard normale, pensata per proteggere e non solo per coprire. Manica raglan e silhouette rilassata: cade morbida su ogni fisico, senza bisogno di essere in forma atletica per indossarla.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"fit-mark\"\u003e\n        \u003cspan\u003eManica raglan\u003c\/span\u003e\n        \u003cspan\u003eSilhouette rilassata\u003c\/span\u003e\n        \u003cspan\u003eOgni fisico\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\u003eLunghe \u003cspan class=\"ital\"\u003eremate\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eLa manica raglan dà totale libertà alle spalle e la maglia densa protegge le costole dallo sfregamento della tavola.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eSurf\u003c\/span\u003e\u003cspan\u003eSUP\u003c\/span\u003e\u003cspan\u003eBodyboard\u003c\/span\u003e\u003cspan\u003eCanottaggio costiero\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 \/ Nuoto\u003c\/div\u003e\n        \u003ch4\u003eAcque \u003cspan class=\"ital\"\u003elibere\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eIdrodinamica e opaca: meno attrito nell’acqua e bracciate più veloci.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eNuoto in acque libere\u003c\/span\u003e\u003cspan\u003eTriathlon\u003c\/span\u003e\u003cspan\u003eCanottaggio costiero\u003c\/span\u003e\u003cspan\u003eNuoto in vasca\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 \/ Strato\u003c\/div\u003e\n        \u003ch4\u003eSotto la \u003cspan class=\"ital\"\u003emuta\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eSi indossa con scioltezza: previene gli sfregamenti e aggiunge uno strato termico.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eStrato base sotto muta\u003c\/span\u003e\u003cspan\u003eMuta shorty\u003c\/span\u003e\u003cspan\u003eAcqua fredda\u003c\/span\u003e\u003cspan\u003eMuta stagna tecnica\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 \/ Sole\u003c\/div\u003e\n        \u003ch4\u003eTutto il giorno \u003cspan class=\"ital\"\u003eUV\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eUPF 50+ Eclipse: blocca il 98% di UVA \/ UVB, anche dai riflessi.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eTropici\u003c\/span\u003e\u003cspan\u003eVela\u003c\/span\u003e\u003cspan\u003eKayak\u003c\/span\u003e\u003cspan\u003eGiornate in barca\u003c\/span\u003e\u003cspan\u003ePesca\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 \/ Sport acquatici\u003c\/div\u003e\n        \u003ch4\u003eVelocità e \u003cspan class=\"ital\"\u003espruzzi\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eResta ben aderente sotto la pressione dell’imbracatura e ti protegge dal freddo del vento alle alte velocità.\u003c\/b\u003e\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\u003eSci nautico\u003c\/span\u003e\u003cspan\u003eMoto d’acqua\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 \/ Immersione\u003c\/div\u003e\n        \u003ch4\u003eSnorkeling e \u003cspan class=\"ital\"\u003eapnea\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eMaglia densa: tiene caldo nelle lunghe nuotate e fa da barriera contro meduse e scogli.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eSnorkeling\u003c\/span\u003e\u003cspan\u003eApnea\u003c\/span\u003e\u003cspan\u003ePesca in apnea\u003c\/span\u003e\u003cspan\u003eCoasteering\u003c\/span\u003e\u003cspan\u003eSeabob\u003c\/span\u003e\u003cspan\u003eStrato base per sub\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 ; STANDARD\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eFatta con onestà.\u003cbr\u003eMade in Italy.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eControllata in modo indipendente, dal filato al capo finito: nessuna dichiarazione senza prove.\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\"\u003eOrigine e certificazioni\u003c\/h3\u003e\n      \u003cdiv class=\"stamp\" data-anim=\"right\"\u003eVerificato · Controllato · Tracciabile\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 · stabilimento SITIP\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 · Classe 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\"\u003eFiliera approvata\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\"\u003eTinture e finissaggi a basso impatto\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\"\u003eDomande,\u003cbr\u003erisposte.\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\u003ePosso stampare il mio logo sulla rashguard?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eAncora meglio: puoi creare la tua rashguard da zero con il nostro configuratore 3D avanzato. Cambia i colori, aggiungi il logo, scrivi il tuo nome, posiziona gli sponsor e combina le fantasie, vedendo tutto in anteprima live in 3D. Servono idee? Il nostro AI Designer genera grafiche personalizzate da una semplice descrizione testuale: massima libertà creativa, senza bisogno di saper disegnare.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQual è l’ordine minimo per un kit squadra personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nBasta un pezzo: non c’è un minimo. Ordina una singola rashguard personalizzata o un kit completo da 50+, con gli sconti quantità che partono in automatico già da 3 pezzi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQuanto tempo richiede un ordine personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eDi solito la produzione richiede 2-3 settimane dal checkout, più i tempi di spedizione. Controlla la pagina del carrello per il tempo di produzione esatto del tuo ordine.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eChe taglia devo scegliere?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eNessun problema: la guida alle taglie ti verrà suggerita direttamente durante la configurazione, con misure calibrate sulla vestibilità comfort rilassata di questo modello. Non serve essere atleti per indossarla: la silhouette è tagliata per cadere morbida su ogni fisico.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eIl tessuto è davvero UPF 50+?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eSì. La finitura Eclipse è certificata UPF 50+ e blocca il 98% delle radiazioni UVA\/UVB. È testata e certificata secondo lo UV Standard 801, e la protezione è intessuta nel filato: non se ne va con i lavaggi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003ePosso usarla per sport diversi dal surf?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eConsigliamo questo modello per tutti gli sport a contatto con l’acqua: surf, SUP, kitesurf, nuoto, apnea, snorkeling, vela, wakeboard e guida di mezzi acquatici. La maglia più densa da 220 g\/m² lo rende ideale ogni volta che sei dentro o sopra l’acqua.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eDove è prodotta?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nInteramente prodotta in Italia, nel nostro stabilimento di abbigliamento tecnico a Parma. Il tessuto è realizzato da SITIP a Bergamo, poi tagliato, cucito, stampato e rifinito internamente dal nostro team.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eCome si lava?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eSciacquala in acqua dolce dopo ogni sessione. Lavaggio in lavatrice a freddo (30°C) con ciclo delicato, senza ammorbidente e senza asciugatrice. Falla asciugare stesa; va bene anche al sole. Trattata bene, durerà più di tre rashguard standard.\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\u003eTessuti italiani premium\u003c\/span\u003e\n      \u003cspan\u003ePowered by SITIP\u003c\/span\u003e\n      \u003cspan\u003eAcquazero Idrorepellente\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\u003eTessuti italiani premium\u003c\/span\u003e\n      \u003cspan\u003ePowered by SITIP\u003c\/span\u003e\n      \u003cspan\u003eAcquazero Idrorepellente\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":58201478562179,"sku":"COM-LS-XS","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"S","offer_id":58201478594947,"sku":"COM-LS-S","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"M","offer_id":58201478627715,"sku":"COM-LS-M","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"L","offer_id":58201478660483,"sku":"COM-LS-L","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"XL","offer_id":58201478693251,"sku":"COM-LS-XL","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"XXL","offer_id":58201478726019,"sku":"COM-LS-XXL","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"3XL","offer_id":58201478758787,"sku":"COM-LS-3XL","price":69.0,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0988\/4323\/0595\/files\/51765f64688701925fdc06dbaf371beb.jpg?v=1781694989"},{"product_id":"men-s-compression-rashguard-ss-seafinder","title":"Compression Rashguard Uomo Manica Corta - 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\u003eDescrizione prodotto ; Tessuti italiani premium\u003c\/title\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\u003eCompletamente personalizzabile\u003c\/div\u003e\n      \u003cdiv class=\"meta-row\" data-anim=\"right\"\u003e\n        \u003cspan\u003eSKU · PRO-RG-01\u003c\/span\u003e\n        \u003cspan\u003ePro Series\u003c\/span\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"kicker\" data-anim=\"left\"\u003ePro Lycra · Compression Series\u003c\/div\u003e\n    \u003ch1 data-anim=\"reveal\"\u003ePro Lycra Compression\u003cbr\u003e\u003cspan class=\"accent\"\u003eRashguard\u003c\/span\u003e\n\u003c\/h1\u003e\n    \u003cp class=\"product-full-title\" data-anim=\"rise\"\u003eCompression Rashguard Uomo Manica Corta - THUNDER MASTER\u003c\/p\u003e\n    \u003cp class=\"subline\" data-anim=\"blur\"\u003e\u003cstrong\u003eRashguard armor-grade personalizzata. Maglia italiana 4-way stretch da 220 g\/m²: stampa il tuo logo, i numeri e gli sponsor su un tessuto più denso dello standard e ad alta resistenza all’abrasione. Dalla singola maglia ai kit completi per la squadra, con una compressione second-skin pensata per surfisti, nuotatori e amanti del mare che non scendono a compromessi.\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n    \u003cdiv class=\"feature-tabs\" data-anim-stagger=\"60\"\u003e\n      \u003cspan data-anim=\"rise\"\u003e✎ Stampa personalizzata\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=ec4260794c3d06d63b9278d9f51046cc\" 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        Modifica 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        Crea un nuovo 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\"\u003eSconti \u003cspan class=\"em\" style=\"padding: 2px 50px 0px 0px\"\u003equantità\u003c\/span\u003e\n\u003c\/h3\u003e\n          \u003cp class=\"pricing-sub\"\u003eTrascina il cursore · più ordini, più risparmi\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\"\u003eQuantità\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)\"\u003epz\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% di sconto\u003c\/div\u003e\n          \u003cspan class=\"save\" id=\"save-line\" style=\"color: rgb(0, 0, 0)\"\u003eScegli 2+ pz per iniziare a risparmiare\u003c\/span\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"readout-price\"\u003e\n          \u003cdiv class=\"label\"\u003eIl tuo prezzo\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)\"\u003eTotale: \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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc zero\"\u003e0%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−5%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.95 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−15%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.85 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−25%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.75 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−35%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.65 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−45%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.55 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−50%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.50 | money }} cad.\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+ pezzi\u003c\/div\u003e\n          \u003ch4\u003eTi serve un kit completo per la squadra? Parliamone.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h4\u003e\n          \u003cp\u003ePrezzi dedicati per club, squadre ed eventi da 50+ pezzi: ti inviamo un preventivo entro 24 ore.\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          Richiedi un preventivo\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⚓ Richiesta quantità · 50+ pezzi\u003c\/div\u003e\n            \u003ch3 id=\"quote-modal-title\"\u003eRicevi il tuo preventivo personalizzato.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h3\u003e\n            \u003cp\u003eRaccontaci della tua squadra e ti rispondiamo entro 24h con prezzi e tempi di consegna.\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 Compression 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\"\u003eNome club \/ azienda \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\"\u003eInserisci il nome del club o dell’azienda\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\"\u003ePaese \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\"\u003eObbligatorio\u003c\/div\u003e\n                \u003c\/div\u003e\n                \u003cdiv class=\"quote-field\"\u003e\n                  \u003clabel for=\"qf-vat\"\u003ePartita IVA \u003cspan class=\"opt\"\u003e(se presente)\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\"\u003eQuantità \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\"\u003eDeve essere almeno 50\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\"\u003eÈ richiesta un’email valida\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\"\u003eNote \u003cspan class=\"opt\"\u003e(facoltativo — raccontaci della squadra, del design, delle scadenze, ecc.)\u003c\/span\u003e\u003c\/label\u003e\n                  \u003ctextarea id=\"qf-notes\" name=\"contact[Notes]\" rows=\"4\" autocomplete=\"off\" placeholder=\"e.g. 80 compression tops for our triathlon 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\"\u003eSito web (lascia vuoto — 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                Invia richiesta\n              \u003c\/button\u003e\n              \u003cdiv class=\"quote-modal-footnote\"\u003eTi risponderemo entro 24h all’email che ci indichi. Contatto alternativo: custominferno@gmail.com.\u003cstrong\u003e\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      Tessuti italiani premium\n    \u003c\/div\u003e\n    \u003ch2 data-anim=\"reveal\"\u003eProgettata per l’\u003cbr\u003e\u003cspan class=\"ital\"\u003eacqua.\u003c\/span\u003e Tagliata per il sole.\u003c\/h2\u003e\n    \u003cp data-anim=\"blur\"\u003eRealizzata con i tessuti tecnici SITIP, l’azienda di Bergamo che tesse filati ad alte prestazioni dal 1956. Ogni metro di tessuto è rifinito per resistere a salsedine, sole e mille lavaggi.\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\"\u003eTestata nel Mediterraneo\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+ · Idrorepellente\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        Nuovo tessuto SITIP · MONICA\n      \u003cstrong\u003e\u003c\/strong\u003e\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 ; TECNOLOGIA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eDue finiture.\u003cbr\u003eUn solo oceano.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDue trattamenti SITIP brevettati lavorano in coppia: uno respinge ciò che ti lancia l’acqua, l’altro ti scherma da ciò che ti manda il sole.\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◐ Sistema idrorepellente\u003c\/div\u003e\n      \u003ch3\u003eAcquazero\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eL’acqua scivola via, il sale scivola via e le macchie non attecchiscono.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💧\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eIdrorepellente senza fluoro\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🌿\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eChimica senza PFOA ed eco-friendly\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🧼\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eResistente ai lavaggi: le prestazioni durano nel tempo\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💨\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eTraspirante e morbida al tatto\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☀ Sistema di protezione solare\u003c\/div\u003e\n      \u003ch3\u003eEclipse\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eUn’ombra che indossi: fresca al tatto e opaca anche in pieno riverbero.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e☀️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eProtezione UV certificata UPF 50+\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e👁️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eNon trasparente, nemmeno da bagnata\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e❄️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eFilato con tecnologia a effetto fresco\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🎯\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eVestibilità su misura, totalmente traspirante\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\"\u003eCome si muove\u003cbr\u003econ te.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDalla prima remata all’ultima passeggiata al tramonto: un tessuto che senti reattivo fin dal primo minuto.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"perf-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eCostruita per il movimento\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003ePrestazioni in quattro direzioni · comfort tutto il giorno\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\u003eVestibilità a compressione\u003c\/h4\u003e\n        \u003cp\u003eAderisce come una seconda pelle, per il massimo supporto muscolare e zero distrazioni in line-up.\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\u003eTotale libertà di movimento: ogni remata, torsione e pop-up senza il minimo vincolo.\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\u003eAsciugatura rapida\u003c\/h4\u003e\n        \u003cp\u003eL’umidità viene portata in superficie ed evapora in fretta: comfort dal mare alla sabbia.\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\u003eResta liscia lavaggio dopo lavaggio: niente pelucchi, niente pallini, niente invecchiamento precoce.\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 ; PERSONALIZZA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eRendila\u003cbr\u003etua.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna rashguard personalizzata, costruita sulla tua squadra. Stampa logo, numeri e sponsor su una lycra italiana da 220 g\/m², più densa dello standard: pronta per la squadra già dal primo pezzo.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"custom-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eLa tua rashguard personalizzata, a modo tuo\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003eLogo · Numeri · Sponsor · Colori squadra\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\u003eStampa il tuo logo\u003c\/h4\u003e\n        \u003cp\u003eStampa a sublimazione su petto, maniche e schiena. Dettaglio fotografico su una rashguard in lycra personalizzata che non si crepa, non si screpola e non sbiadisce.\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\u003eNumeri e nomi\u003c\/h4\u003e\n        \u003cp\u003ePronta per la rosa: aggiungi numeri di gioco, nomi o blocchi sponsor. Perfetta per surf club, team di sport acquatici e squadre da evento.\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\u003eDa 1 pezzo\u003c\/h4\u003e\n        \u003cp\u003eNessun ordine minimo per una rashguard personalizzata: dal pezzo unico fino ai kit squadra con taglie miste da 50+, con gli sconti quantità applicati in automatico.\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\u003eTagliata, cucita e stampata in Italia su una maglia italiana da 220 g\/m². Lo stesso tessuto con cui la tua squadra si allena e gareggia: nessun compromesso sulla personalizzazione.\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 ; UTILIZZI\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eIndossala come\u003cbr\u003eun’armatura.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna maglia più densa e pesante di una rashguard standard, pensata per proteggerti attivamente da sole, vento, abrasioni e impatti, mentre il taglio a compressione mantiene tutto aerodinamico.\u003cstrong\u003e\u003c\/strong\u003e\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\u003eCompressione armor-grade\u003c\/div\u003e\n\n      \u003cdiv class=\"fit-headline\"\u003e\n        \u003ch3\u003eSecond-skin \u003cspan class=\"em\"\u003eun’armatura.\u003c\/span\u003e\n\u003c\/h3\u003e\n        \u003cp class=\"compare-lead\"\u003eUna maglia italiana più spessa e densa di una rashguard normale, pensata per proteggere e non solo per coprire. Il taglio a compressione fascia i muscoli: scegli una taglia in più se preferisci una vestibilità più morbida.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"fit-mark\"\u003e\n        \u003cspan\u003eMaglia più pesante\u003c\/span\u003e\n        \u003cspan\u003eTaglie atletiche\u003c\/span\u003e\n        \u003cspan\u003eProtezione attiva\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\u003eLunghe \u003cspan class=\"ital\"\u003eremate\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eLa compressione sostiene le spalle e la maglia densa protegge le costole dallo sfregamento della tavola.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eSurf\u003c\/span\u003e\u003cspan\u003eSUP\u003c\/span\u003e\u003cspan\u003eBodyboard\u003c\/span\u003e\u003cspan\u003eCanottaggio costiero\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 \/ Nuoto\u003c\/div\u003e\n        \u003ch4\u003eAcque \u003cspan class=\"ital\"\u003elibere\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eIdrodinamica e opaca: meno attrito nell’acqua e bracciate più veloci.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eNuoto in acque libere\u003c\/span\u003e\u003cspan\u003eTriathlon\u003c\/span\u003e\u003cspan\u003eCanottaggio costiero\u003c\/span\u003e\u003cspan\u003eNuoto in vasca\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 \/ Strato\u003c\/div\u003e\n        \u003ch4\u003eSotto la \u003cspan class=\"ital\"\u003emuta\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eSi indossa con scioltezza: previene gli sfregamenti e aggiunge uno strato termico.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eStrato base sotto muta\u003c\/span\u003e\u003cspan\u003eMuta shorty\u003c\/span\u003e\u003cspan\u003eAcqua fredda\u003c\/span\u003e\u003cspan\u003eMuta stagna tecnica\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 \/ Sole\u003c\/div\u003e\n        \u003ch4\u003eTutto il giorno \u003cspan class=\"ital\"\u003eUV\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eUPF 50+ Eclipse: blocca il 98% di UVA \/ UVB, anche dai riflessi.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eTropici\u003c\/span\u003e\u003cspan\u003eVela\u003c\/span\u003e\u003cspan\u003eKayak\u003c\/span\u003e\u003cspan\u003eGiornate in barca\u003c\/span\u003e\u003cspan\u003ePesca\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 \/ Sport acquatici\u003c\/div\u003e\n        \u003ch4\u003eVelocità e \u003cspan class=\"ital\"\u003espruzzi\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eResta ben aderente sotto la pressione dell’imbracatura e ti protegge dal freddo del vento alle alte velocità.\u003c\/b\u003e\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\u003eSci nautico\u003c\/span\u003e\u003cspan\u003eMoto d’acqua\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 \/ Immersione\u003c\/div\u003e\n        \u003ch4\u003eSnorkeling e \u003cspan class=\"ital\"\u003eapnea\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eMaglia densa: tiene caldo nelle lunghe nuotate e fa da barriera contro meduse e scogli.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eSnorkeling\u003c\/span\u003e\u003cspan\u003eApnea\u003c\/span\u003e\u003cspan\u003ePesca in apnea\u003c\/span\u003e\u003cspan\u003eCoasteering\u003c\/span\u003e\u003cspan\u003eSeabob\u003c\/span\u003e\u003cspan\u003eStrato base per sub\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 ; STANDARD\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eFatta con onestà.\u003cbr\u003eMade in Italy.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eControllata in modo indipendente, dal filato al capo finito: nessuna dichiarazione senza prove.\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\"\u003eOrigine e certificazioni\u003c\/h3\u003e\n      \u003cdiv class=\"stamp\" data-anim=\"right\"\u003eVerificato · Controllato · Tracciabile\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 · stabilimento SITIP\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 · Classe 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\"\u003eFiliera approvata\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\"\u003eTinture e finissaggi a basso impatto\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\"\u003eDomande,\u003cbr\u003erisposte.\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\u003ePosso stampare il mio logo sulla rashguard?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eAncora meglio: puoi creare la tua rashguard da zero con il nostro configuratore 3D avanzato. Cambia i colori, aggiungi il logo, scrivi il tuo nome, posiziona gli sponsor e combina le fantasie, vedendo tutto in anteprima live in 3D. Servono idee? Il nostro AI Designer genera grafiche personalizzate da una semplice descrizione testuale: massima libertà creativa, senza bisogno di saper disegnare.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQual è l’ordine minimo per un kit squadra personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nBasta un pezzo: non c’è un minimo. Ordina una singola rashguard personalizzata o un kit completo da 50+, con gli sconti quantità che partono in automatico già da 3 pezzi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQuanto tempo richiede un ordine personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eDi solito la produzione richiede 2-3 settimane dal checkout, più i tempi di spedizione. Controlla la pagina del carrello per il tempo di produzione esatto del tuo ordine.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eChe taglia devo scegliere?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eNessun problema: la guida alle taglie ti verrà suggerita direttamente durante la configurazione, con misure calibrate sulla vestibilità a compressione di questo modello.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eIl tessuto è davvero UPF 50+?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eSì. La finitura Eclipse è certificata UPF 50+ e blocca il 98% delle radiazioni UVA\/UVB. È testata e certificata secondo lo UV Standard 801, e la protezione è intessuta nel filato: non se ne va con i lavaggi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003ePosso usarla per sport diversi dal surf?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eConsigliamo questo modello per tutti gli sport a contatto con l’acqua: surf, SUP, kitesurf, nuoto, apnea, snorkeling, vela, wakeboard e guida di mezzi acquatici. La maglia più densa da 220 g\/m² lo rende ideale ogni volta che sei dentro o sopra l’acqua.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eDove è prodotta?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nInteramente prodotta in Italia, nel nostro stabilimento di abbigliamento tecnico a Parma. Il tessuto è realizzato da SITIP a Bergamo, poi tagliato, cucito, stampato e rifinito internamente dal nostro team.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eCome si lava?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eSciacquala in acqua dolce dopo ogni sessione. Lavaggio in lavatrice a freddo (30°C) con ciclo delicato, senza ammorbidente e senza asciugatrice. Falla asciugare stesa; va bene anche al sole. Trattata bene, durerà più di tre rashguard standard.\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\": \"Pro Lycra Compression Rashguard\",\n    \"description\": \"Custom armor-grade rashguard. Italian 4-way stretch knit at 220 g\/m² with Acquazero water-repellent finish and Eclipse UPF 50+ sun protection. Custom printable from 1 piece. Made in Italy.\",\n    \"category\": \"Sportswear \/ Watersports\",\n    \"brand\": { \"@type\": \"Brand\", \"name\": \"Inferno Beachwear\" },\n    \"material\": \"Italian Lycra · SITIP · Acquazero · 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 compression fit of this model.\"\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\u003eTessuti italiani premium\u003c\/span\u003e\n      \u003cspan\u003ePowered by SITIP\u003c\/span\u003e\n      \u003cspan\u003eAcquazero Idrorepellente\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\u003eTessuti italiani premium\u003c\/span\u003e\n      \u003cspan\u003ePowered by SITIP\u003c\/span\u003e\n      \u003cspan\u003eAcquazero Idrorepellente\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":58201482199427,"sku":"PRO-SS-XS","price":64.0,"currency_code":"EUR","in_stock":true},{"title":"S","offer_id":58201482232195,"sku":"PRO-SS-S","price":64.0,"currency_code":"EUR","in_stock":true},{"title":"M","offer_id":58201482264963,"sku":"PRO-SS-M","price":64.0,"currency_code":"EUR","in_stock":true},{"title":"L","offer_id":58201482297731,"sku":"PRO-SS-L","price":64.0,"currency_code":"EUR","in_stock":true},{"title":"XL","offer_id":58201482330499,"sku":"PRO-SS-XL","price":64.0,"currency_code":"EUR","in_stock":true},{"title":"XXL","offer_id":58201482363267,"sku":"PRO-SS-XXL","price":64.0,"currency_code":"EUR","in_stock":true},{"title":"XXXL","offer_id":58201482396035,"sku":"PRO-SS-XXXL","price":64.0,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0988\/4323\/0595\/files\/f2426eefbae3dda446f46f1eab8e8a69.jpg?v=1780911399"},{"product_id":"women-s-compression-rashguard-seafinder","title":"Compression Rashguard Donna Manica Corta - 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\u003eDescrizione prodotto ; Tessuti italiani premium\u003c\/title\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\u003eCompletamente personalizzabile\u003c\/div\u003e\n      \u003cdiv class=\"meta-row\" data-anim=\"right\"\u003e\n        \u003cspan\u003eSKU · PRO-RG-01\u003c\/span\u003e\n        \u003cspan\u003ePro Series\u003c\/span\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"kicker\" data-anim=\"left\"\u003ePro Lycra · Compression Series\u003c\/div\u003e\n    \u003ch1 data-anim=\"reveal\"\u003ePro Lycra Compression\u003cbr\u003e\u003cspan class=\"accent\"\u003eRashguard\u003c\/span\u003e\n\u003c\/h1\u003e\n    \u003cp class=\"product-full-title\" data-anim=\"rise\"\u003eCompression Rashguard Donna Manica Corta - THUNDER MASTER\u003c\/p\u003e\n    \u003cp class=\"subline\" data-anim=\"blur\"\u003e\u003cstrong\u003eRashguard armor-grade personalizzata. Maglia italiana 4-way stretch da 220 g\/m²: stampa il tuo logo, i numeri e gli sponsor su un tessuto più denso dello standard e ad alta resistenza all’abrasione. Dalla singola maglia ai kit completi per la squadra, con una compressione second-skin pensata per surfisti, nuotatori e amanti del mare che non scendono a compromessi.\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n    \u003cdiv class=\"feature-tabs\" data-anim-stagger=\"60\"\u003e\n      \u003cspan data-anim=\"rise\"\u003e✎ Stampa personalizzata\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=5a6c6a37b314bc94ee5d281f727ac863\" 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        Modifica 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        Crea un nuovo 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\"\u003eSconti \u003cspan class=\"em\" style=\"padding: 2px 50px 0px 0px\"\u003equantità\u003c\/span\u003e\n\u003c\/h3\u003e\n          \u003cp class=\"pricing-sub\"\u003eTrascina il cursore · più ordini, più risparmi\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\"\u003eQuantità\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)\"\u003epz\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% di sconto\u003c\/div\u003e\n          \u003cspan class=\"save\" id=\"save-line\" style=\"color: rgb(0, 0, 0)\"\u003eScegli 2+ pz per iniziare a risparmiare\u003c\/span\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"readout-price\"\u003e\n          \u003cdiv class=\"label\"\u003eIl tuo prezzo\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)\"\u003eTotale: \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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc zero\"\u003e0%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−5%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.95 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−15%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.85 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−25%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.75 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−35%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.65 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−45%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.55 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−50%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.50 | money }} cad.\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+ pezzi\u003c\/div\u003e\n          \u003ch4\u003eTi serve un kit completo per la squadra? Parliamone.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h4\u003e\n          \u003cp\u003ePrezzi dedicati per club, squadre ed eventi da 50+ pezzi: ti inviamo un preventivo entro 24 ore.\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          Richiedi un preventivo\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⚓ Richiesta quantità · 50+ pezzi\u003c\/div\u003e\n            \u003ch3 id=\"quote-modal-title\"\u003eRicevi il tuo preventivo personalizzato.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h3\u003e\n            \u003cp\u003eRaccontaci della tua squadra e ti rispondiamo entro 24h con prezzi e tempi di consegna.\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=\"Women’s Compression 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\"\u003eNome club \/ azienda \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\"\u003eInserisci il nome del club o dell’azienda\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\"\u003ePaese \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\"\u003eObbligatorio\u003c\/div\u003e\n                \u003c\/div\u003e\n                \u003cdiv class=\"quote-field\"\u003e\n                  \u003clabel for=\"qf-vat\"\u003ePartita IVA \u003cspan class=\"opt\"\u003e(se presente)\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\"\u003eQuantità \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\"\u003eDeve essere almeno 50\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\"\u003eÈ richiesta un’email valida\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\"\u003eNote \u003cspan class=\"opt\"\u003e(facoltativo — raccontaci della squadra, del design, delle scadenze, ecc.)\u003c\/span\u003e\u003c\/label\u003e\n                  \u003ctextarea id=\"qf-notes\" name=\"contact[Notes]\" rows=\"4\" autocomplete=\"off\" placeholder=\"e.g. 80 compression tops for our triathlon 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\"\u003eSito web (lascia vuoto — 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                Invia richiesta\n              \u003c\/button\u003e\n              \u003cdiv class=\"quote-modal-footnote\"\u003eTi risponderemo entro 24h all’email che ci indichi. Contatto alternativo: custominferno@gmail.com.\u003cstrong\u003e\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      Tessuti italiani premium\n    \u003c\/div\u003e\n    \u003ch2 data-anim=\"reveal\"\u003eProgettata per l’\u003cbr\u003e\u003cspan class=\"ital\"\u003eacqua.\u003c\/span\u003e Tagliata per il sole.\u003c\/h2\u003e\n    \u003cp data-anim=\"blur\"\u003eRealizzata con i tessuti tecnici SITIP, l’azienda di Bergamo che tesse filati ad alte prestazioni dal 1956. Ogni metro di tessuto è rifinito per resistere a salsedine, sole e mille lavaggi.\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\"\u003eTestata nel Mediterraneo\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+ · Idrorepellente\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        Nuovo tessuto SITIP · MONICA\n      \u003cstrong\u003e\u003c\/strong\u003e\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 ; TECNOLOGIA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eDue finiture.\u003cbr\u003eUn solo oceano.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDue trattamenti SITIP brevettati lavorano in coppia: uno respinge ciò che ti lancia l’acqua, l’altro ti scherma da ciò che ti manda il sole.\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◐ Sistema idrorepellente\u003c\/div\u003e\n      \u003ch3\u003eAcquazero\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eL’acqua scivola via, il sale scivola via e le macchie non attecchiscono.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💧\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eIdrorepellente senza fluoro\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🌿\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eChimica senza PFOA ed eco-friendly\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🧼\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eResistente ai lavaggi: le prestazioni durano nel tempo\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💨\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eTraspirante e morbida al tatto\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☀ Sistema di protezione solare\u003c\/div\u003e\n      \u003ch3\u003eEclipse\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eUn’ombra che indossi: fresca al tatto e opaca anche in pieno riverbero.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e☀️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eProtezione UV certificata UPF 50+\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e👁️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eNon trasparente, nemmeno da bagnata\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e❄️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eFilato con tecnologia a effetto fresco\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🎯\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eVestibilità su misura, totalmente traspirante\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\"\u003eCome si muove\u003cbr\u003econ te.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDalla prima remata all’ultima passeggiata al tramonto: un tessuto che senti reattivo fin dal primo minuto.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"perf-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eCostruita per il movimento\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003ePrestazioni in quattro direzioni · comfort tutto il giorno\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\u003eVestibilità a compressione\u003c\/h4\u003e\n        \u003cp\u003eAderisce come una seconda pelle, per il massimo supporto muscolare e zero distrazioni in line-up.\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\u003eTotale libertà di movimento: ogni remata, torsione e pop-up senza il minimo vincolo.\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\u003eAsciugatura rapida\u003c\/h4\u003e\n        \u003cp\u003eL’umidità viene portata in superficie ed evapora in fretta: comfort dal mare alla sabbia.\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\u003eResta liscia lavaggio dopo lavaggio: niente pelucchi, niente pallini, niente invecchiamento precoce.\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 ; PERSONALIZZA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eRendila\u003cbr\u003etua.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna rashguard personalizzata, costruita sulla tua squadra. Stampa logo, numeri e sponsor su una lycra italiana da 220 g\/m², più densa dello standard: pronta per la squadra già dal primo pezzo.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"custom-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eLa tua rashguard personalizzata, a modo tuo\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003eLogo · Numeri · Sponsor · Colori squadra\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\u003eStampa il tuo logo\u003c\/h4\u003e\n        \u003cp\u003eStampa a sublimazione su petto, maniche e schiena. Dettaglio fotografico su una rashguard in lycra personalizzata che non si crepa, non si screpola e non sbiadisce.\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\u003eNumeri e nomi\u003c\/h4\u003e\n        \u003cp\u003ePronta per la rosa: aggiungi numeri di gioco, nomi o blocchi sponsor. Perfetta per surf club, team di sport acquatici e squadre da evento.\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\u003eDa 1 pezzo\u003c\/h4\u003e\n        \u003cp\u003eNessun ordine minimo per una rashguard personalizzata: dal pezzo unico fino ai kit squadra con taglie miste da 50+, con gli sconti quantità applicati in automatico.\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\u003eTagliata, cucita e stampata in Italia su una maglia italiana da 220 g\/m². Lo stesso tessuto con cui la tua squadra si allena e gareggia: nessun compromesso sulla personalizzazione.\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 ; UTILIZZI\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eIndossala come\u003cbr\u003eun’armatura.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna maglia più densa e pesante di una rashguard standard, pensata per proteggerti attivamente da sole, vento, abrasioni e impatti, mentre il taglio a compressione mantiene tutto aerodinamico.\u003cstrong\u003e\u003c\/strong\u003e\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\u003eCompressione armor-grade\u003c\/div\u003e\n\n      \u003cdiv class=\"fit-headline\"\u003e\n        \u003ch3\u003eSecond-skin \u003cspan class=\"em\"\u003eun’armatura.\u003c\/span\u003e\n\u003c\/h3\u003e\n        \u003cp class=\"compare-lead\"\u003eUna maglia italiana più spessa e densa di una rashguard normale, pensata per proteggere e non solo per coprire. Il taglio a compressione fascia i muscoli: scegli una taglia in più se preferisci una vestibilità più morbida.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"fit-mark\"\u003e\n        \u003cspan\u003eMaglia più pesante\u003c\/span\u003e\n        \u003cspan\u003eTaglie atletiche\u003c\/span\u003e\n        \u003cspan\u003eProtezione attiva\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\u003eLunghe \u003cspan class=\"ital\"\u003eremate\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eLa compressione sostiene le spalle e la maglia densa protegge le costole dallo sfregamento della tavola.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eSurf\u003c\/span\u003e\u003cspan\u003eSUP\u003c\/span\u003e\u003cspan\u003eBodyboard\u003c\/span\u003e\u003cspan\u003eCanottaggio costiero\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 \/ Nuoto\u003c\/div\u003e\n        \u003ch4\u003eAcque \u003cspan class=\"ital\"\u003elibere\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eIdrodinamica e opaca: meno attrito nell’acqua e bracciate più veloci.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eNuoto in acque libere\u003c\/span\u003e\u003cspan\u003eTriathlon\u003c\/span\u003e\u003cspan\u003eCanottaggio costiero\u003c\/span\u003e\u003cspan\u003eNuoto in vasca\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 \/ Strato\u003c\/div\u003e\n        \u003ch4\u003eSotto la \u003cspan class=\"ital\"\u003emuta\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eSi indossa con scioltezza: previene gli sfregamenti e aggiunge uno strato termico.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eStrato base sotto muta\u003c\/span\u003e\u003cspan\u003eMuta shorty\u003c\/span\u003e\u003cspan\u003eAcqua fredda\u003c\/span\u003e\u003cspan\u003eMuta stagna tecnica\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 \/ Sole\u003c\/div\u003e\n        \u003ch4\u003eTutto il giorno \u003cspan class=\"ital\"\u003eUV\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eUPF 50+ Eclipse: blocca il 98% di UVA \/ UVB, anche dai riflessi.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eTropici\u003c\/span\u003e\u003cspan\u003eVela\u003c\/span\u003e\u003cspan\u003eKayak\u003c\/span\u003e\u003cspan\u003eGiornate in barca\u003c\/span\u003e\u003cspan\u003ePesca\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 \/ Sport acquatici\u003c\/div\u003e\n        \u003ch4\u003eVelocità e \u003cspan class=\"ital\"\u003espruzzi\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eResta ben aderente sotto la pressione dell’imbracatura e ti protegge dal freddo del vento alle alte velocità.\u003c\/b\u003e\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\u003eSci nautico\u003c\/span\u003e\u003cspan\u003eMoto d’acqua\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 \/ Immersione\u003c\/div\u003e\n        \u003ch4\u003eSnorkeling e \u003cspan class=\"ital\"\u003eapnea\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eMaglia densa: tiene caldo nelle lunghe nuotate e fa da barriera contro meduse e scogli.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eSnorkeling\u003c\/span\u003e\u003cspan\u003eApnea\u003c\/span\u003e\u003cspan\u003ePesca in apnea\u003c\/span\u003e\u003cspan\u003eCoasteering\u003c\/span\u003e\u003cspan\u003eSeabob\u003c\/span\u003e\u003cspan\u003eStrato base per sub\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 ; STANDARD\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eFatta con onestà.\u003cbr\u003eMade in Italy.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eControllata in modo indipendente, dal filato al capo finito: nessuna dichiarazione senza prove.\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\"\u003eOrigine e certificazioni\u003c\/h3\u003e\n      \u003cdiv class=\"stamp\" data-anim=\"right\"\u003eVerificato · Controllato · Tracciabile\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 · stabilimento SITIP\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 · Classe 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\"\u003eFiliera approvata\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\"\u003eTinture e finissaggi a basso impatto\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\"\u003eDomande,\u003cbr\u003erisposte.\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\u003ePosso stampare il mio logo sulla rashguard?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eAncora meglio: puoi creare la tua rashguard da zero con il nostro configuratore 3D avanzato. Cambia i colori, aggiungi il logo, scrivi il tuo nome, posiziona gli sponsor e combina le fantasie, vedendo tutto in anteprima live in 3D. Servono idee? Il nostro AI Designer genera grafiche personalizzate da una semplice descrizione testuale: massima libertà creativa, senza bisogno di saper disegnare.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQual è l’ordine minimo per un kit squadra personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nBasta un pezzo: non c’è un minimo. Ordina una singola rashguard personalizzata o un kit completo da 50+, con gli sconti quantità che partono in automatico già da 3 pezzi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQuanto tempo richiede un ordine personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eDi solito la produzione richiede 2-3 settimane dal checkout, più i tempi di spedizione. Controlla la pagina del carrello per il tempo di produzione esatto del tuo ordine.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eChe taglia devo scegliere?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eNessun problema: la guida alle taglie ti verrà suggerita direttamente durante la configurazione, con misure calibrate sulla vestibilità a compressione di questo modello.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eIl tessuto è davvero UPF 50+?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eSì. La finitura Eclipse è certificata UPF 50+ e blocca il 98% delle radiazioni UVA\/UVB. È testata e certificata secondo lo UV Standard 801, e la protezione è intessuta nel filato: non se ne va con i lavaggi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003ePosso usarla per sport diversi dal surf?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eConsigliamo questo modello per tutti gli sport a contatto con l’acqua: surf, SUP, kitesurf, nuoto, apnea, snorkeling, vela, wakeboard e guida di mezzi acquatici. La maglia più densa da 220 g\/m² lo rende ideale ogni volta che sei dentro o sopra l’acqua.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eDove è prodotta?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nInteramente prodotta in Italia, nel nostro stabilimento di abbigliamento tecnico a Parma. Il tessuto è realizzato da SITIP a Bergamo, poi tagliato, cucito, stampato e rifinito internamente dal nostro team.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eCome si lava?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eSciacquala in acqua dolce dopo ogni sessione. Lavaggio in lavatrice a freddo (30°C) con ciclo delicato, senza ammorbidente e senza asciugatrice. Falla asciugare stesa; va bene anche al sole. Trattata bene, durerà più di tre rashguard standard.\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\": \"Pro Lycra Compression Rashguard\",\n    \"description\": \"Custom armor-grade rashguard. Italian 4-way stretch knit at 220 g\/m² with Acquazero water-repellent finish and Eclipse UPF 50+ sun protection. Custom printable from 1 piece. Made in Italy.\",\n    \"category\": \"Sportswear \/ Watersports\",\n    \"brand\": { \"@type\": \"Brand\", \"name\": \"Inferno Beachwear\" },\n    \"material\": \"Italian Lycra · SITIP · Acquazero · 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 compression fit of this model.\"\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\u003eTessuti italiani premium\u003c\/span\u003e\n      \u003cspan\u003ePowered by SITIP\u003c\/span\u003e\n      \u003cspan\u003eAcquazero Idrorepellente\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\u003eTessuti italiani premium\u003c\/span\u003e\n      \u003cspan\u003ePowered by SITIP\u003c\/span\u003e\n      \u003cspan\u003eAcquazero Idrorepellente\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":58201483968899,"sku":"PRO-SS-W-XS","price":64.0,"currency_code":"EUR","in_stock":true},{"title":"S","offer_id":58201484001667,"sku":"PRO-SS-W-S","price":64.0,"currency_code":"EUR","in_stock":true},{"title":"M","offer_id":58201484034435,"sku":"PRO-SS-W-M","price":64.0,"currency_code":"EUR","in_stock":true},{"title":"L","offer_id":58201484067203,"sku":"PRO-SS-W-L","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"XL","offer_id":58201484099971,"sku":"PRO-SS-W-XL","price":64.0,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0988\/4323\/0595\/files\/34fed9cb5318628fe55089415a52da3b.jpg?v=1780992999"},{"product_id":"women-s-compression-rashguard-ls-seafinder","title":"Compression Rashguard Donna Manica Lunga - 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\u003eDescrizione prodotto ; Tessuti italiani premium\u003c\/title\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\u003eCompletamente personalizzabile\u003c\/div\u003e\n      \u003cdiv class=\"meta-row\" data-anim=\"right\"\u003e\n        \u003cspan\u003eSKU · PRO-RG-01\u003c\/span\u003e\n        \u003cspan\u003ePro Series\u003c\/span\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"kicker\" data-anim=\"left\"\u003ePro Lycra · Compression Series\u003c\/div\u003e\n    \u003ch1 data-anim=\"reveal\"\u003ePro Lycra Compression\u003cbr\u003e\u003cspan class=\"accent\"\u003eRashguard\u003c\/span\u003e\n\u003c\/h1\u003e\n    \u003cp class=\"product-full-title\" data-anim=\"rise\"\u003eCompression Rashguard Donna Manica Lunga - THUNDER MASTER\u003c\/p\u003e\n    \u003cp class=\"subline\" data-anim=\"blur\"\u003e\u003cstrong\u003eRashguard armor-grade personalizzata. Maglia italiana 4-way stretch da 220 g\/m²: stampa il tuo logo, i numeri e gli sponsor su un tessuto più denso dello standard e ad alta resistenza all’abrasione. Dalla singola maglia ai kit completi per la squadra, con una compressione second-skin pensata per surfisti, nuotatori e amanti del mare che non scendono a compromessi.\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n    \u003cdiv class=\"feature-tabs\" data-anim-stagger=\"60\"\u003e\n      \u003cspan data-anim=\"rise\"\u003e✎ Stampa personalizzata\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=0c509aec5953d4eb8407315b8652d3de\" 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        Modifica 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        Crea un nuovo 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\"\u003eSconti \u003cspan class=\"em\" style=\"padding: 2px 50px 0px 0px\"\u003equantità\u003c\/span\u003e\n\u003c\/h3\u003e\n          \u003cp class=\"pricing-sub\"\u003eTrascina il cursore · più ordini, più risparmi\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\"\u003eQuantità\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)\"\u003epz\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% di sconto\u003c\/div\u003e\n          \u003cspan class=\"save\" id=\"save-line\" style=\"color: rgb(0, 0, 0)\"\u003eScegli 2+ pz per iniziare a risparmiare\u003c\/span\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"readout-price\"\u003e\n          \u003cdiv class=\"label\"\u003eIl tuo prezzo\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)\"\u003eTotale: \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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc zero\"\u003e0%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−5%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.95 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−15%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.85 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−25%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.75 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−35%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.65 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−45%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.55 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−50%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.50 | money }} cad.\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+ pezzi\u003c\/div\u003e\n          \u003ch4\u003eTi serve un kit completo per la squadra? Parliamone.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h4\u003e\n          \u003cp\u003ePrezzi dedicati per club, squadre ed eventi da 50+ pezzi: ti inviamo un preventivo entro 24 ore.\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          Richiedi un preventivo\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⚓ Richiesta quantità · 50+ pezzi\u003c\/div\u003e\n            \u003ch3 id=\"quote-modal-title\"\u003eRicevi il tuo preventivo personalizzato.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h3\u003e\n            \u003cp\u003eRaccontaci della tua squadra e ti rispondiamo entro 24h con prezzi e tempi di consegna.\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=\"Women’s Compression Rashguard LS - 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\"\u003eNome club \/ azienda \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\"\u003eInserisci il nome del club o dell’azienda\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\"\u003ePaese \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\"\u003eObbligatorio\u003c\/div\u003e\n                \u003c\/div\u003e\n                \u003cdiv class=\"quote-field\"\u003e\n                  \u003clabel for=\"qf-vat\"\u003ePartita IVA \u003cspan class=\"opt\"\u003e(se presente)\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\"\u003eQuantità \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\"\u003eDeve essere almeno 50\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\"\u003eÈ richiesta un’email valida\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\"\u003eNote \u003cspan class=\"opt\"\u003e(facoltativo — raccontaci della squadra, del design, delle scadenze, ecc.)\u003c\/span\u003e\u003c\/label\u003e\n                  \u003ctextarea id=\"qf-notes\" name=\"contact[Notes]\" rows=\"4\" autocomplete=\"off\" placeholder=\"e.g. 80 compression tops for our triathlon 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\"\u003eSito web (lascia vuoto — 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                Invia richiesta\n              \u003c\/button\u003e\n              \u003cdiv class=\"quote-modal-footnote\"\u003eTi risponderemo entro 24h all’email che ci indichi. Contatto alternativo: custominferno@gmail.com.\u003cstrong\u003e\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      Tessuti italiani premium\n    \u003c\/div\u003e\n    \u003ch2 data-anim=\"reveal\"\u003eProgettata per l’\u003cbr\u003e\u003cspan class=\"ital\"\u003eacqua.\u003c\/span\u003e Tagliata per il sole.\u003c\/h2\u003e\n    \u003cp data-anim=\"blur\"\u003eRealizzata con i tessuti tecnici SITIP, l’azienda di Bergamo che tesse filati ad alte prestazioni dal 1956. Ogni metro di tessuto è rifinito per resistere a salsedine, sole e mille lavaggi.\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\"\u003eTestata nel Mediterraneo\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+ · Idrorepellente\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        Nuovo tessuto SITIP · MONICA\n      \u003cstrong\u003e\u003c\/strong\u003e\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 ; TECNOLOGIA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eDue finiture.\u003cbr\u003eUn solo oceano.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDue trattamenti SITIP brevettati lavorano in coppia: uno respinge ciò che ti lancia l’acqua, l’altro ti scherma da ciò che ti manda il sole.\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◐ Sistema idrorepellente\u003c\/div\u003e\n      \u003ch3\u003eAcquazero\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eL’acqua scivola via, il sale scivola via e le macchie non attecchiscono.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💧\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eIdrorepellente senza fluoro\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🌿\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eChimica senza PFOA ed eco-friendly\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🧼\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eResistente ai lavaggi: le prestazioni durano nel tempo\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💨\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eTraspirante e morbida al tatto\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☀ Sistema di protezione solare\u003c\/div\u003e\n      \u003ch3\u003eEclipse\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eUn’ombra che indossi: fresca al tatto e opaca anche in pieno riverbero.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e☀️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eProtezione UV certificata UPF 50+\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e👁️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eNon trasparente, nemmeno da bagnata\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e❄️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eFilato con tecnologia a effetto fresco\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🎯\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eVestibilità su misura, totalmente traspirante\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\"\u003eCome si muove\u003cbr\u003econ te.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDalla prima remata all’ultima passeggiata al tramonto: un tessuto che senti reattivo fin dal primo minuto.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"perf-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eCostruita per il movimento\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003ePrestazioni in quattro direzioni · comfort tutto il giorno\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\u003eVestibilità a compressione\u003c\/h4\u003e\n        \u003cp\u003eAderisce come una seconda pelle, per il massimo supporto muscolare e zero distrazioni in line-up.\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\u003eTotale libertà di movimento: ogni remata, torsione e pop-up senza il minimo vincolo.\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\u003eAsciugatura rapida\u003c\/h4\u003e\n        \u003cp\u003eL’umidità viene portata in superficie ed evapora in fretta: comfort dal mare alla sabbia.\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\u003eResta liscia lavaggio dopo lavaggio: niente pelucchi, niente pallini, niente invecchiamento precoce.\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 ; PERSONALIZZA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eRendila\u003cbr\u003etua.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna rashguard personalizzata, costruita sulla tua squadra. Stampa logo, numeri e sponsor su una lycra italiana da 220 g\/m², più densa dello standard: pronta per la squadra già dal primo pezzo.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"custom-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eLa tua rashguard personalizzata, a modo tuo\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003eLogo · Numeri · Sponsor · Colori squadra\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\u003eStampa il tuo logo\u003c\/h4\u003e\n        \u003cp\u003eStampa a sublimazione su petto, maniche e schiena. Dettaglio fotografico su una rashguard in lycra personalizzata che non si crepa, non si screpola e non sbiadisce.\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\u003eNumeri e nomi\u003c\/h4\u003e\n        \u003cp\u003ePronta per la rosa: aggiungi numeri di gioco, nomi o blocchi sponsor. Perfetta per surf club, team di sport acquatici e squadre da evento.\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\u003eDa 1 pezzo\u003c\/h4\u003e\n        \u003cp\u003eNessun ordine minimo per una rashguard personalizzata: dal pezzo unico fino ai kit squadra con taglie miste da 50+, con gli sconti quantità applicati in automatico.\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\u003eTagliata, cucita e stampata in Italia su una maglia italiana da 220 g\/m². Lo stesso tessuto con cui la tua squadra si allena e gareggia: nessun compromesso sulla personalizzazione.\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 ; UTILIZZI\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eIndossala come\u003cbr\u003eun’armatura.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna maglia più densa e pesante di una rashguard standard, pensata per proteggerti attivamente da sole, vento, abrasioni e impatti, mentre il taglio a compressione mantiene tutto aerodinamico.\u003cstrong\u003e\u003c\/strong\u003e\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\u003eCompressione armor-grade\u003c\/div\u003e\n\n      \u003cdiv class=\"fit-headline\"\u003e\n        \u003ch3\u003eSecond-skin \u003cspan class=\"em\"\u003eun’armatura.\u003c\/span\u003e\n\u003c\/h3\u003e\n        \u003cp class=\"compare-lead\"\u003eUna maglia italiana più spessa e densa di una rashguard normale, pensata per proteggere e non solo per coprire. Il taglio a compressione fascia i muscoli: scegli una taglia in più se preferisci una vestibilità più morbida.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"fit-mark\"\u003e\n        \u003cspan\u003eMaglia più pesante\u003c\/span\u003e\n        \u003cspan\u003eTaglie atletiche\u003c\/span\u003e\n        \u003cspan\u003eProtezione attiva\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\u003eLunghe \u003cspan class=\"ital\"\u003eremate\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eLa compressione sostiene le spalle e la maglia densa protegge le costole dallo sfregamento della tavola.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eSurf\u003c\/span\u003e\u003cspan\u003eSUP\u003c\/span\u003e\u003cspan\u003eBodyboard\u003c\/span\u003e\u003cspan\u003eCanottaggio costiero\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 \/ Nuoto\u003c\/div\u003e\n        \u003ch4\u003eAcque \u003cspan class=\"ital\"\u003elibere\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eIdrodinamica e opaca: meno attrito nell’acqua e bracciate più veloci.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eNuoto in acque libere\u003c\/span\u003e\u003cspan\u003eTriathlon\u003c\/span\u003e\u003cspan\u003eCanottaggio costiero\u003c\/span\u003e\u003cspan\u003eNuoto in vasca\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 \/ Strato\u003c\/div\u003e\n        \u003ch4\u003eSotto la \u003cspan class=\"ital\"\u003emuta\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eSi indossa con scioltezza: previene gli sfregamenti e aggiunge uno strato termico.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eStrato base sotto muta\u003c\/span\u003e\u003cspan\u003eMuta shorty\u003c\/span\u003e\u003cspan\u003eAcqua fredda\u003c\/span\u003e\u003cspan\u003eMuta stagna tecnica\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 \/ Sole\u003c\/div\u003e\n        \u003ch4\u003eTutto il giorno \u003cspan class=\"ital\"\u003eUV\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eUPF 50+ Eclipse: blocca il 98% di UVA \/ UVB, anche dai riflessi.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eTropici\u003c\/span\u003e\u003cspan\u003eVela\u003c\/span\u003e\u003cspan\u003eKayak\u003c\/span\u003e\u003cspan\u003eGiornate in barca\u003c\/span\u003e\u003cspan\u003ePesca\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 \/ Sport acquatici\u003c\/div\u003e\n        \u003ch4\u003eVelocità e \u003cspan class=\"ital\"\u003espruzzi\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eResta ben aderente sotto la pressione dell’imbracatura e ti protegge dal freddo del vento alle alte velocità.\u003c\/b\u003e\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\u003eSci nautico\u003c\/span\u003e\u003cspan\u003eMoto d’acqua\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 \/ Immersione\u003c\/div\u003e\n        \u003ch4\u003eSnorkeling e \u003cspan class=\"ital\"\u003eapnea\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eMaglia densa: tiene caldo nelle lunghe nuotate e fa da barriera contro meduse e scogli.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eSnorkeling\u003c\/span\u003e\u003cspan\u003eApnea\u003c\/span\u003e\u003cspan\u003ePesca in apnea\u003c\/span\u003e\u003cspan\u003eCoasteering\u003c\/span\u003e\u003cspan\u003eSeabob\u003c\/span\u003e\u003cspan\u003eStrato base per sub\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 ; STANDARD\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eFatta con onestà.\u003cbr\u003eMade in Italy.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eControllata in modo indipendente, dal filato al capo finito: nessuna dichiarazione senza prove.\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\"\u003eOrigine e certificazioni\u003c\/h3\u003e\n      \u003cdiv class=\"stamp\" data-anim=\"right\"\u003eVerificato · Controllato · Tracciabile\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 · stabilimento SITIP\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 · Classe 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\"\u003eFiliera approvata\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\"\u003eTinture e finissaggi a basso impatto\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\"\u003eDomande,\u003cbr\u003erisposte.\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\u003ePosso stampare il mio logo sulla rashguard?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eAncora meglio: puoi creare la tua rashguard da zero con il nostro configuratore 3D avanzato. Cambia i colori, aggiungi il logo, scrivi il tuo nome, posiziona gli sponsor e combina le fantasie, vedendo tutto in anteprima live in 3D. Servono idee? Il nostro AI Designer genera grafiche personalizzate da una semplice descrizione testuale: massima libertà creativa, senza bisogno di saper disegnare.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQual è l’ordine minimo per un kit squadra personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nBasta un pezzo: non c’è un minimo. Ordina una singola rashguard personalizzata o un kit completo da 50+, con gli sconti quantità che partono in automatico già da 3 pezzi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQuanto tempo richiede un ordine personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eDi solito la produzione richiede 2-3 settimane dal checkout, più i tempi di spedizione. Controlla la pagina del carrello per il tempo di produzione esatto del tuo ordine.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eChe taglia devo scegliere?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eNessun problema: la guida alle taglie ti verrà suggerita direttamente durante la configurazione, con misure calibrate sulla vestibilità a compressione di questo modello.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eIl tessuto è davvero UPF 50+?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eSì. La finitura Eclipse è certificata UPF 50+ e blocca il 98% delle radiazioni UVA\/UVB. È testata e certificata secondo lo UV Standard 801, e la protezione è intessuta nel filato: non se ne va con i lavaggi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003ePosso usarla per sport diversi dal surf?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eConsigliamo questo modello per tutti gli sport a contatto con l’acqua: surf, SUP, kitesurf, nuoto, apnea, snorkeling, vela, wakeboard e guida di mezzi acquatici. La maglia più densa da 220 g\/m² lo rende ideale ogni volta che sei dentro o sopra l’acqua.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eDove è prodotta?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nInteramente prodotta in Italia, nel nostro stabilimento di abbigliamento tecnico a Parma. Il tessuto è realizzato da SITIP a Bergamo, poi tagliato, cucito, stampato e rifinito internamente dal nostro team.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eCome si lava?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eSciacquala in acqua dolce dopo ogni sessione. Lavaggio in lavatrice a freddo (30°C) con ciclo delicato, senza ammorbidente e senza asciugatrice. Falla asciugare stesa; va bene anche al sole. Trattata bene, durerà più di tre rashguard standard.\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\": \"Pro Lycra Compression Rashguard\",\n    \"description\": \"Custom armor-grade rashguard. Italian 4-way stretch knit at 220 g\/m² with Acquazero water-repellent finish and Eclipse UPF 50+ sun protection. Custom printable from 1 piece. Made in Italy.\",\n    \"category\": \"Sportswear \/ Watersports\",\n    \"brand\": { \"@type\": \"Brand\", \"name\": \"Inferno Beachwear\" },\n    \"material\": \"Italian Lycra · SITIP · Acquazero · 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 compression fit of this model.\"\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\u003eTessuti italiani premium\u003c\/span\u003e\n      \u003cspan\u003ePowered by SITIP\u003c\/span\u003e\n      \u003cspan\u003eAcquazero Idrorepellente\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\u003eTessuti italiani premium\u003c\/span\u003e\n      \u003cspan\u003ePowered by SITIP\u003c\/span\u003e\n      \u003cspan\u003eAcquazero Idrorepellente\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":58201484820867,"sku":"PRO-LS-W-XS","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"S","offer_id":58201484853635,"sku":"PRO-LS-W-S","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"M","offer_id":58201484886403,"sku":"PRO-LS-W-M","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"L","offer_id":58201484919171,"sku":"PRO-LS-W-L","price":69.0,"currency_code":"EUR","in_stock":true},{"title":"XL","offer_id":58201484951939,"sku":"PRO-LS-W-XL","price":69.0,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0988\/4323\/0595\/files\/eac3121d14d9d1ce80ed363da9974003.jpg?v=1780992962"},{"product_id":"ultralight-technical-t-shirt-seafinder","title":"Ultralight Technical T-Shirt - 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\u003eThe Beach Shirt ; maglia honeycomb ultraleggera per beach volley e beach sport\u003c\/title\u003e\n\u003cmeta name=\"description\" content=\"The Beach Shirt — ultralight 95 g\/m² honeycomb-knit jersey by SITIP. Recycled NATIVE yarn, MICROSENSE soft-touch finish, breathable as a sea breeze. Custom team kits for beach volley, beach tennis, footvolley and beach sports. Made in Italy.\"\u003e\n\u003cmeta name=\"keywords\" content=\"beach volley jersey, beach tennis shirt, ultralight sports shirt, breathable beach shirt, honeycomb knit jersey, recycled polyester sportswear, custom beach volley kit, SITIP NATIVE LINDA, MICROSENSE, beach sports apparel, 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\u003eCompletamente personalizzabile\u003c\/div\u003e\n      \u003cdiv class=\"meta-row\" data-anim=\"right\"\u003e\n        \u003cspan\u003eSKU · BCH-SH-01\u003c\/span\u003e\n        \u003cspan\u003e95 g\/m² · Honeycomb\u003c\/span\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"kicker\" data-anim=\"left\"\u003eHoneycomb Knit · Beach Performance Series\u003c\/div\u003e\n    \u003ch1 data-anim=\"reveal\"\u003eThe Beach\u003cbr\u003e\u003cspan class=\"accent\"\u003eShirt\u003c\/span\u003e\n\u003c\/h1\u003e\n    \u003cp class=\"product-full-title\" data-anim=\"rise\"\u003eComfort Fit Rashguard Uomo Manica Lunga - THUNDER MASTER\u003c\/p\u003e\n    \u003cp class=\"subline\" data-anim=\"blur\"\u003e\u003cstrong\u003eLa maglia da spiaggia ultraleggera. Una maglia italiana piuma da 95 g\/m² con struttura honeycomb che lascia passare l’aria come una brezza marina. Filato riciclato NATIVE, finitura morbida MICROSENSE. Tagliata per beach volley, beach tennis e ogni sport sulla sabbia: stampa il tuo logo, i numeri e gli sponsor, dalla singola maglia ai kit completi per la squadra. Più leggera, fresca e traspirante di qualsiasi altro capo della linea.\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n    \u003cdiv class=\"feature-tabs\" data-anim-stagger=\"60\"\u003e\n      \u003cspan data-anim=\"rise\"\u003e✎ Stampa personalizzata\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003e🍃 95 g\/m² Ultraleggero\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003e⬡ Honeycomb Knit\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003e♻ NATIVE Riciclato\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=2b71495da5f2a38c4a790449fa8e9b4f\" 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        Modifica 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        Crea un nuovo 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\"\u003eSconti \u003cspan class=\"em\" style=\"padding: 2px 50px 0px 0px\"\u003equantità\u003c\/span\u003e\n\u003c\/h3\u003e\n          \u003cp class=\"pricing-sub\"\u003eTrascina il cursore · più ordini, più risparmi\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\"\u003eQuantità\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)\"\u003epz\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% di sconto\u003c\/div\u003e\n          \u003cspan class=\"save\" id=\"save-line\" style=\"color: rgb(0, 0, 0)\"\u003eScegli 2+ pz per iniziare a risparmiare\u003c\/span\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"readout-price\"\u003e\n          \u003cdiv class=\"label\"\u003eIl tuo prezzo\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)\"\u003eTotale: \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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc zero\"\u003e0%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−5%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.95 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−15%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.85 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−25%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.75 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−35%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.65 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−45%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.55 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−50%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.50 | money }} cad.\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+ pezzi\u003c\/div\u003e\n          \u003ch4\u003eTi serve un kit completo per la squadra? Parliamone.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h4\u003e\n          \u003cp\u003ePrezzi dedicati per club, squadre ed eventi da 50+ pezzi: ti inviamo un preventivo entro 24 ore.\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          Richiedi un preventivo\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⚓ Richiesta quantità · 50+ pezzi\u003c\/div\u003e\n            \u003ch3 id=\"quote-modal-title\"\u003eRicevi il tuo preventivo personalizzato.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h3\u003e\n            \u003cp\u003eRaccontaci della tua squadra e ti rispondiamo entro 24h con prezzi e tempi di consegna.\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 LS - 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\"\u003eNome club \/ azienda \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\"\u003eInserisci il nome del club o dell’azienda\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\"\u003ePaese \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\"\u003eObbligatorio\u003c\/div\u003e\n                \u003c\/div\u003e\n                \u003cdiv class=\"quote-field\"\u003e\n                  \u003clabel for=\"qf-vat\"\u003ePartita IVA \u003cspan class=\"opt\"\u003e(se presente)\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\"\u003eQuantità \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\"\u003eDeve essere almeno 50\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\"\u003eÈ richiesta un’email valida\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\"\u003eNote \u003cspan class=\"opt\"\u003e(facoltativo — raccontaci della squadra, del design, delle scadenze, ecc.)\u003c\/span\u003e\u003c\/label\u003e\n                  \u003ctextarea id=\"qf-notes\" name=\"contact[Notes]\" rows=\"4\" autocomplete=\"off\" placeholder=\"e.g. 80 jerseys for our beach volley 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\"\u003eSito web (lascia vuoto — 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                Invia richiesta\n              \u003c\/button\u003e\n              \u003cdiv class=\"quote-modal-footnote\"\u003eTi risponderemo entro 24h all’email che ci indichi. Contatto alternativo: custominferno@gmail.com.\u003cstrong\u003e\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      Tessuti italiani premium\n    \u003c\/div\u003e\n    \u003ch2 data-anim=\"reveal\"\u003ePiù leggero di\u003cbr\u003e\u003cspan class=\"ital\"\u003euna brezza marina.\u003c\/span\u003e\n\u003c\/h2\u003e\n    \u003cp data-anim=\"blur\"\u003eUna maglia honeycomb da 95 g\/m² tessuta da SITIP a Bergamo sulla base NATIVE LINDA: l’aria la attraversa come scorre sulla sabbia. La maglia più leggera, fresca e traspirante che produciamo, pensata per beach volley, beach tennis e ogni sport giocato a piedi nudi.\u003c\/p\u003e\n    \u003cdiv class=\"hero-meta\" data-anim-stagger=\"80\"\u003e\n      \u003cspan data-anim=\"rise\"\u003e95 g\/m² · Honeycomb knit\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003eFilato 100% riciclato\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003eMade in Italy\u003c\/span\u003e\n    \u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"hero-visual\" data-anim=\"zoom\" aria-label=\"Macro view of white honeycomb knit fabric, showing the open hexagonal structure that gives the shirt its lightness and breathability\"\u003e\n      \u003cspan class=\"hc-feather\"\u003e95 g\/m² · Piuma\u003c\/span\u003e\n      \u003cimg class=\"honeycomb\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0988\/4323\/0595\/files\/native-linda-honeycomb.png?v=1778759184\" alt=\"Macro view of NATIVE LINDA honeycomb knit fabric, showing the open hexagonal mesh structure that gives the shirt its lightness and breathability\" decoding=\"async\" fetchpriority=\"high\" width=\"460\" height=\"460\"\u003e\n      \u003cspan class=\"hc-label\"\u003e\n        Honeycomb Knit SITIP · NATIVE LINDA\n      \u003cstrong\u003e\u003c\/strong\u003e\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 ; TECNOLOGIA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eDue innovazioni.\u003cbr\u003eUna sola brezza.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDue tecnologie SITIP combinate su un’unica base da 95 g\/m²: una rende il tessuto morbido come seta sulla pelle, l’altra lo ricostruisce da filato riciclato con il minor impatto possibile.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003cdiv class=\"tech-grid\" data-anim-stagger=\"180\"\u003e\n    \u003c!-- MICROSENSE --\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·SOFT\u003c\/div\u003e\n      \u003cdiv class=\"badge\"\u003e◐ Soft Performance System\u003c\/div\u003e\n      \u003ch3\u003eMicrosense\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eFilato in microfilamento che imita la seta. Delicato sulla pelle, implacabile col sudore.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🪶\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eMorbidezza sulla pelle simile alla seta\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💨\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eAssorbimento dell’umidità superiore\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e⚡\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eAsciuga più in fretta delle fibre naturali\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e👕\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eFacile da curare: non serve stirare\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·ECO\u003c\/div\u003e\n      \u003cdiv class=\"badge\"\u003e♻ Recycled Yarn System\u003c\/div\u003e\n      \u003ch3\u003eNative\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eFilato riciclato pre e post-consumo, chimica a basso impatto, minor consumo di energia.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e♻️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eFilato in poliestere 100% riciclato\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🌍\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eCertificato GRS e ISO 14001\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🧪\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eChimica senza fluoro e a basso impatto\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e⚡\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eMinor uso di energia non rinnovabile\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\"\u003eCome si muove\u003cbr\u003econ te.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDal primo set sulla sabbia all’ultimo punto del torneo: un tessuto così leggero che dimenticherai di indossarlo.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"perf-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eProgettato per la sabbia\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003eUltraleggero · Massima ventilazione · Fresco tutto il giorno\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\u003e95 g\/m² Ultraleggero\u003c\/h4\u003e\n        \u003cp\u003eMeno della metà del peso di una t-shirt tecnica standard: la dimentichi addosso.\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\u003eHoneycomb Knit\u003c\/h4\u003e\n        \u003cp\u003eUna struttura a maglia esagonale fa circolare l’aria fresca all’interno come una brezza attraverso una finestra.\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\u003eElasticità in ogni direzione: salti, tuffi e difese in allungo senza alcun vincolo.\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\u003eAsciugatura rapida\u003c\/h4\u003e\n        \u003cp\u003eIl sudore viene portato in superficie e sparisce in pochi minuti. Resta fresco, resta asciutto, resta leggero.\u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n  \u003c\/section\u003e\n\n  \u003c!-- ============ CUSTOM PRINT (SEO: custom beach volley shirt, beach team kits, custom beach tennis jersey) ============ --\u003e\n  \u003cdiv class=\"section-head\"\u003e\n    \u003cdiv\u003e\n      \u003cdiv class=\"num\" data-anim=\"left\"\u003e03 ; PERSONALIZZA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eRendila\u003cbr\u003etua.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna maglia da spiaggia personalizzata, costruita sulla tua squadra. Stampa logo, numeri e sponsor sulla maglia honeycomb italiana più leggera, da 95 g\/m²: pronta per la squadra già dal primo pezzo.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"custom-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eLa tua maglia da spiaggia personalizzata, a modo tuo\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003eLogo · Numeri · Sponsor · Colori squadra\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\u003eStampa il tuo logo\u003c\/h4\u003e\n        \u003cp\u003eStampa a sublimazione su petto, maniche e schiena. Dettaglio fotografico su una maglia da beach volley personalizzata che non si crepa, non si screpola e non sbiadisce, nemmeno dopo cento partite al sole.\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\u003eNumeri e nomi\u003c\/h4\u003e\n        \u003cp\u003ePronta per il torneo: aggiungi numeri di gioco, nomi o blocchi sponsor. Perfetta per club di beach volley, squadre di beach tennis e team di sport sulla sabbia.\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\u003eDa 1 pezzo\u003c\/h4\u003e\n        \u003cp\u003eNessun ordine minimo per una maglia da spiaggia personalizzata: dal pezzo unico fino ai kit squadra con taglie miste da 50+, con gli sconti quantità applicati in automatico.\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\u003eTagliato, cucito e stampato in Italia su una maglia honeycomb da 95 g\/m² tessuta da SITIP a Bergamo. Lo stesso tessuto con cui la tua squadra si allena e gareggia: nessun compromesso sulla personalizzazione.\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 ; UTILIZZI\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eIndossala come\u003cbr\u003eproprio nulla.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna maglia più leggera e aperta di qualsiasi t-shirt sportiva standard. Pensata per far passare l’aria nel tessuto come una brezza marina attraversa un’amaca: pura ventilazione, pura freschezza, tutto il giorno.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\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\u003eVestibilità da spiaggia piuma\u003c\/div\u003e\n\n      \u003cdiv class=\"fit-headline\"\u003e\n        \u003ch3\u003ePiuma \u003cspan class=\"em\"\u003efreschezza.\u003c\/span\u003e\n\u003c\/h3\u003e\n        \u003cp class=\"compare-lead\"\u003eUna maglia italiana più sottile e leggera di qualsiasi t-shirt sportiva standard, pensata per respirare e non solo per coprire. La rete honeycomb fa fluire l’aria fresca nel tessuto ed espelle quella umida: resti fresco anche a 35 °C sulla sabbia.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"fit-mark\"\u003e\n        \u003cspan\u003e95 g\/m² ultraleggero\u003c\/span\u003e\n        \u003cspan\u003eRete honeycomb\u003c\/span\u003e\n        \u003cspan\u003eMassima ventilazione\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 \/ Beach Volley\u003c\/div\u003e\n        \u003ch4\u003eSabbia e \u003cspan class=\"ital\"\u003eschiacciate\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eVentilazione honeycomb: resta fresco nelle lunghe partite al sole e non si appiccica mai alla pelle.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eBeach volley\u003c\/span\u003e\u003cspan\u003e2v2\u003c\/span\u003e\u003cspan\u003e4v4\u003c\/span\u003e\u003cspan\u003eTornei\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 \/ Beach Tennis\u003c\/div\u003e\n        \u003ch4\u003eScambi \u003cspan class=\"ital\"\u003eveloci\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003e4-way stretch + 95 g\/m² ultraleggero: nessun impaccio sulle schiacciate, nessun peso sugli scatti.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eBeach tennis\u003c\/span\u003e\u003cspan\u003eBeach padel\u003c\/span\u003e\u003cspan\u003ePickleball\u003c\/span\u003e\u003cspan\u003eCampo in sabbia\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 \/ Caldo\u003c\/div\u003e\n        \u003ch4\u003e35 °C e \u003cspan class=\"ital\"\u003eoltre\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eAssorbimento Microsense + rete aperta: l’umidità esce più velocemente di quanto si formi.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eEstate mediterranea\u003c\/span\u003e\u003cspan\u003eClimi tropicali\u003c\/span\u003e\u003cspan\u003eAllenamenti sotto il sole\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 \/ Sport sulla sabbia\u003c\/div\u003e\n        \u003ch4\u003eAtletica \u003cspan class=\"ital\"\u003eda spiaggia\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003ePiuma: massima libertà di movimento per footvolley, beach handball e beach soccer.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eFootvolley\u003c\/span\u003e\u003cspan\u003eBeach handball\u003c\/span\u003e\u003cspan\u003eBeach soccer\u003c\/span\u003e\u003cspan\u003eBeach rugby\u003c\/span\u003e\u003cspan\u003eBeach ultimate\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 \/ Allenamento\u003c\/div\u003e\n        \u003ch4\u003eAtletica \u003cspan class=\"ital\"\u003efitness\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eAsciuga in pochi minuti tra un set e l’altro: resta fresco dalle corse all’alba agli allenamenti al tramonto.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eBeach running\u003c\/span\u003e\u003cspan\u003eAllenamenti sulla sabbia\u003c\/span\u003e\u003cspan\u003eHIIT\u003c\/span\u003e\u003cspan\u003eCrossFit in spiaggia\u003c\/span\u003e\u003cspan\u003eYoga\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 \/ Lifestyle\u003c\/div\u003e\n        \u003ch4\u003eTempo \u003cspan class=\"ital\"\u003elibero\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eMicrosense morbido al tatto: si indossa come una t-shirt premium dal beach club alla cena.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eBeach club\u003c\/span\u003e\u003cspan\u003eLungomare\u003c\/span\u003e\u003cspan\u003eViaggi\u003c\/span\u003e\u003cspan\u003eResort wear\u003c\/span\u003e\u003cspan\u003eFestival\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 ; STANDARD\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eFatta con onestà.\u003cbr\u003eMade in Italy.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eControllata in modo indipendente, dal filato al capo finito: nessuna dichiarazione senza prove.\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\"\u003eOrigine e certificazioni\u003c\/h3\u003e\n      \u003cdiv class=\"stamp\" data-anim=\"right\"\u003eVerificato · Controllato · Tracciabile\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 · stabilimento SITIP\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\"\u003eCertificato GRS\u003c\/div\u003e\n          \u003cdiv class=\"meta\"\u003eGlobal Recycle Standard\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 · Classe 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® · ZDHC\u003c\/div\u003e\n          \u003cdiv class=\"meta\"\u003eISO 14001 · Filiera certificata\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\"\u003eDomande,\u003cbr\u003erisposte.\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\u003eQuanto è leggera davvero The Beach Shirt?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\n95 g\/m². Meno della metà del peso di una t-shirt tecnica standard e circa un terzo di una rashguard. La struttura della maglia honeycomb toglie peso senza perdere resistenza: sentirai la differenza nell’istante in cui la indossi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eCos’è la maglia honeycomb e perché è importante?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eÈ una struttura a maglia esagonale intessuta nel tessuto stesso, non una stampa né una perforazione. Le celle aperte fanno entrare l’aria fresca e uscire quella umida, esattamente come una brezza che passa da una finestra aperta. Sulla sabbia a 35 °C la differenza è abissale.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003ePosso stampare il mio logo sulla maglia da spiaggia?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eAncora meglio: puoi creare la tua maglia da spiaggia da zero con il nostro configuratore 3D avanzato. Cambia i colori, aggiungi il logo, scrivi il tuo nome, posiziona gli sponsor e combina le fantasie, vedendo tutto in anteprima live in 3D. Servono idee? Il nostro AI Designer genera grafiche personalizzate da una semplice descrizione testuale: massima libertà creativa, senza bisogno di saper disegnare.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQual è l’ordine minimo per un kit squadra personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nBasta un pezzo: non c’è un minimo. Ordina una singola maglia da spiaggia personalizzata o un kit completo da 50+, con gli sconti quantità che partono in automatico già da 3 pezzi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eDi cosa è fatto?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nPoliestere 100% riciclato della gamma NATIVE di SITIP: filato riciclato pre e post-consumo, certificato GRS, prodotto con chimica a basso impatto e minor uso di energia non rinnovabile. Lo stesso tessuto è poi rifinito con la tecnologia MICROSENSE per una sensazione sulla pelle simile alla seta e un assorbimento dell’umidità superiore.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003ePer quali sport è ideale?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eProgettata per beach volley, beach tennis, footvolley, beach handball, beach soccer, beach running e ogni sport in cui ventilazione e sensazione ultraleggera contano più dello spessore o della compressione. Funziona benissimo anche nel tempo libero, come t-shirt premium da spiaggia e resort.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQuanto tempo richiede un ordine personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eDi solito la produzione richiede 2-3 settimane dal checkout, più i tempi di spedizione. Controlla la pagina del carrello per il tempo di produzione esatto del tuo ordine.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eChe taglia devo scegliere?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eNessun problema: la guida alle taglie ti verrà suggerita direttamente durante la configurazione, con misure calibrate sulla vestibilità sportiva regolare di questo modello.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eDove è prodotta?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nInteramente prodotto in Italia, nel nostro stabilimento di abbigliamento tecnico a Parma. Il tessuto (NATIVE LINDA) è realizzato da SITIP a Bergamo, poi tagliato, cucito, stampato e rifinito internamente dal nostro team.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eCome si lava?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eLavaggio in lavatrice a freddo (30°C) con ciclo delicato, senza ammorbidente e senza asciugatrice. Non serve stirare: la tecnologia MICROSENSE mantiene il tessuto liscio da solo. Appendilo ad asciugare; sarà pronto in pochi minuti.\u003cstrong\u003e\u003c\/strong\u003e\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\": \"The Beach Shirt\",\n    \"description\": \"Ultralight 95 g\/m² honeycomb-knit jersey for beach volley, beach tennis and beach sports. 100% recycled polyester (SITIP NATIVE LINDA) with MICROSENSE soft-touch finish. Custom printable from 1 piece. Made in Italy.\",\n    \"category\": \"Sportswear \/ Beach Sports\",\n    \"brand\": { \"@type\": \"Brand\", \"name\": \"Inferno Beachwear\" },\n    \"material\": \"100% Recycled Polyester (PLR) · SITIP NATIVE LINDA · MICROSENSE\",\n    \"weight\": { \"@type\": \"QuantitativeValue\", \"value\": 95, \"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\": \"How light is The Beach Shirt, really?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"95 g\/m². That is less than half the weight of a standard performance tee and about a third of a rashguard. The honeycomb knit structure removes mass without losing strength.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"What is the honeycomb knit and why does it matter?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"A hexagonal mesh structure woven into the fabric itself, not a print or perforation. The open cells let fresh air flow in and humid air escape, like a breeze through an open window.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"Can I print my own logo on the beach shirt?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Yes. You can build your beach shirt 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.\"\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 beach shirt or a full team kit of 50+ pieces. Bulk discounts apply automatically from 3 pieces upwards.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"What is it made of?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"100% recycled polyester from SITIP's NATIVE range; pre- and post-consumer recycled yarn, GRS certified, produced with low-impact chemistry and reduced non-renewable energy. Finished with MICROSENSE technology for a silk-like next-to-skin feel and superior moisture-wicking.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"What sports is it best for?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Engineered for beach volley, beach tennis, footvolley, beach handball, beach soccer, beach running and any sport where ventilation and ultralight feel matter more than thickness or compression.\"\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.\"\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 regular sport fit of this model.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"Where is it made?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Entirely produced in Italy. Fabric (NATIVE LINDA) is woven by SITIP in Bergamo, then cut, sewn, printed and finished in our facility in Parma.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"How do I care for The Beach Shirt?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Machine wash cold (30°C) on a gentle cycle, no fabric softener, no tumble dry. No ironing required thanks to MICROSENSE technology. Hang to dry.\"\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\u003eThe Beach Shirt\u003c\/span\u003e\n      \u003cspan\u003e95 g\/m² Ultraleggero\u003c\/span\u003e\n      \u003cspan\u003eHoneycomb Knit\u003c\/span\u003e\n      \u003cspan\u003eNATIVE Recycled Yarn\u003c\/span\u003e\n      \u003cspan\u003eMICROSENSE Soft Touch\u003c\/span\u003e\n      \u003cspan\u003eMade in Italy\u003c\/span\u003e\n      \u003cspan\u003eThe Beach Shirt\u003c\/span\u003e\n      \u003cspan\u003e95 g\/m² Ultraleggero\u003c\/span\u003e\n      \u003cspan\u003eHoneycomb Knit\u003c\/span\u003e\n      \u003cspan\u003eNATIVE Recycled Yarn\u003c\/span\u003e\n      \u003cspan\u003eMICROSENSE Soft Touch\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":58201486786947,"sku":"TT-XS","price":49.0,"currency_code":"EUR","in_stock":true},{"title":"S","offer_id":58201486819715,"sku":"TT-S","price":49.0,"currency_code":"EUR","in_stock":true},{"title":"M","offer_id":58201486852483,"sku":"TT-M","price":49.0,"currency_code":"EUR","in_stock":true},{"title":"L","offer_id":58201486885251,"sku":"TT-L","price":49.0,"currency_code":"EUR","in_stock":true},{"title":"XL","offer_id":58201486918019,"sku":"TT-XL","price":49.0,"currency_code":"EUR","in_stock":true},{"title":"XXL","offer_id":58201486950787,"sku":"TT-XXL","price":49.0,"currency_code":"EUR","in_stock":true},{"title":"3XL","offer_id":58201486983555,"sku":"TT-3XL","price":49.0,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0988\/4323\/0595\/files\/d2bbfc78175fe49f28365188ebf0672a.jpg?v=1780911492"},{"product_id":"ultralight-technical-tank-top-deepdrake","title":"Ultralight Technical Tank Top - 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\u003eThe Beach Tank ; canotta honeycomb ultraleggera senza maniche per beach volley e beach sport\u003c\/title\u003e\n\u003cmeta name=\"description\" content=\"The Beach Tank — ultralight 95 g\/m² sleeveless honeycomb-knit tank top by SITIP. Recycled NATIVE yarn, MICROSENSE soft-touch finish, total freedom of movement on the arms. Custom team kits for beach volley, beach tennis, footvolley and beach sports. Made in Italy.\"\u003e\n\u003cmeta name=\"keywords\" content=\"beach volley tank top, beach tennis tank, ultralight sleeveless jersey, breathable beach tank, honeycomb knit tank top, recycled polyester sportswear, custom beach volley kit, SITIP NATIVE LINDA, MICROSENSE, beach sports apparel, 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  .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\u003eCompletamente personalizzabile\u003c\/div\u003e\n      \u003cdiv class=\"meta-row\" data-anim=\"right\"\u003e\n        \u003cspan\u003eSKU · BCH-TK-01\u003c\/span\u003e\n        \u003cspan\u003e95 g\/m² · Honeycomb\u003c\/span\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"kicker\" data-anim=\"left\"\u003eHoneycomb Knit · Sleeveless Performance Series\u003c\/div\u003e\n    \u003ch1 data-anim=\"reveal\"\u003eThe Beach\u003cbr\u003e\u003cspan class=\"accent\"\u003eTank\u003c\/span\u003e\n\u003c\/h1\u003e\n    \u003cp class=\"product-full-title\" data-anim=\"rise\"\u003eUltralight Technical Tank Top - THUNDER MASTER\u003c\/p\u003e\n    \u003cp class=\"subline\" data-anim=\"blur\"\u003e\u003cstrong\u003eLa canotta da spiaggia ultraleggera senza maniche. Una maglia italiana piuma da 95 g\/m² con struttura honeycomb e una costruzione smanicata che apre le spalle alla brezza. Filato riciclato NATIVE, finitura morbida MICROSENSE. Tagliata per le schiacciate del beach volley, gli smash del beach tennis e ogni sport sulla sabbia: stampa il tuo logo, i numeri e gli sponsor, dalla singola maglia ai kit completi per la squadra. Totale libertà sulle braccia, massima ventilazione sul corpo.\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n    \u003cdiv class=\"feature-tabs\" data-anim-stagger=\"60\"\u003e\n      \u003cspan data-anim=\"rise\"\u003e✎ Stampa personalizzata\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003e🍃 95 g\/m² Ultraleggero\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003e⬡ Honeycomb Knit\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003e💪 Taglio smanicato\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003e♻ NATIVE Riciclato\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\" style=\"height: 80px\"\u003e\n      \u003cspan class=\"liquid-tag\"\u003e\u003c\/span\u003e\n      \u003ca href=\"https:\/\/dqavr9-dh.myshopify.com\/pages\/configurator?design=be877e422a48719edb2c677f4637742d\" 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        Modifica 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        Crea un nuovo 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\"\u003eSconti \u003cspan class=\"em\" style=\"padding: 2px 50px 0px 0px\"\u003equantità\u003c\/span\u003e\n\u003c\/h3\u003e\n          \u003cp class=\"pricing-sub\"\u003eTrascina il cursore · più ordini, più risparmi\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\"\u003eQuantità\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)\"\u003epz\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% di sconto\u003c\/div\u003e\n          \u003cspan class=\"save\" id=\"save-line\" style=\"color: rgb(0, 0, 0)\"\u003eScegli 2+ pz per iniziare a risparmiare\u003c\/span\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"readout-price\"\u003e\n          \u003cdiv class=\"label\"\u003eIl tuo prezzo\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)\"\u003eTotale: \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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc zero\"\u003e0%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−5%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.95 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−15%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.85 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−25%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.75 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−35%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.65 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−45%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.55 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−50%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.50 | money }} cad.\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+ pezzi\u003c\/div\u003e\n          \u003ch4\u003eTi serve un kit completo per la squadra? Parliamone.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h4\u003e\n          \u003cp\u003ePrezzi dedicati per club, squadre ed eventi da 50+ pezzi: ti inviamo un preventivo entro 24 ore.\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          Richiedi un preventivo\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⚓ Richiesta quantità · 50+ pezzi\u003c\/div\u003e\n            \u003ch3 id=\"quote-modal-title\"\u003eRicevi il tuo preventivo personalizzato.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h3\u003e\n            \u003cp\u003eRaccontaci della tua squadra e ti rispondiamo entro 24h con prezzi e tempi di consegna.\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=\"Ultralight Technical Tank Top - 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\"\u003eNome club \/ azienda \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\"\u003eInserisci il nome del club o dell’azienda\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\"\u003ePaese \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\"\u003eObbligatorio\u003c\/div\u003e\n                \u003c\/div\u003e\n                \u003cdiv class=\"quote-field\"\u003e\n                  \u003clabel for=\"qf-vat\"\u003ePartita IVA \u003cspan class=\"opt\"\u003e(se presente)\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\"\u003eQuantità \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\"\u003eDeve essere almeno 50\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\"\u003eÈ richiesta un’email valida\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\"\u003eNote \u003cspan class=\"opt\"\u003e(facoltativo — raccontaci della squadra, del design, delle scadenze, ecc.)\u003c\/span\u003e\u003c\/label\u003e\n                  \u003ctextarea id=\"qf-notes\" name=\"contact[Notes]\" rows=\"4\" autocomplete=\"off\" placeholder=\"e.g. 80 jerseys for our beach volley 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\"\u003eSito web (lascia vuoto — 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                Invia richiesta\n              \u003c\/button\u003e\n              \u003cdiv class=\"quote-modal-footnote\"\u003eTi risponderemo entro 24h all’email che ci indichi. Contatto alternativo: custominferno@gmail.com.\u003cstrong\u003e\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          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        \/\/ ===== 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        (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 = window.location.href;\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 it),\n            \/\/ fall back to mailto: rather than letting Shopify 422 the submit.\n            var qfToken = document.getElementById('qf-token');\n            if (!qfToken || !qfToken.value) {\n              e.preventDefault();\n              window.location.href = 'mailto:custominferno@gmail.com'\n                + '?subject=' + encodeURIComponent(subject)\n                + '\u0026body=' + encodeURIComponent(body);\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      Tessuti italiani premium\n    \u003c\/div\u003e\n    \u003ch2 data-anim=\"reveal\"\u003ePiù leggero di\u003cbr\u003e\u003cspan class=\"ital\"\u003euna brezza marina.\u003c\/span\u003e\n\u003c\/h2\u003e\n    \u003cp data-anim=\"blur\"\u003eUna maglia honeycomb da 95 g\/m² tessuta da SITIP a Bergamo sulla base NATIVE LINDA: l’aria la attraversa come scorre sulla sabbia. Lo short più leggero, fresco e traspirante che produciamo — taglio comfort rilassato, pensato per beach volley, beach tennis e ogni sport giocato a piedi nudi.\u003c\/p\u003e\n    \u003cdiv class=\"hero-meta\" data-anim-stagger=\"80\"\u003e\n      \u003cspan data-anim=\"rise\"\u003e95 g\/m² · Honeycomb knit\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003eFilato 100% riciclato\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003eMade in Italy\u003c\/span\u003e\n    \u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"hero-visual\" data-anim=\"zoom\" aria-label=\"Macro view of white honeycomb knit fabric, showing the open hexagonal structure that gives the tank its lightness and breathability\"\u003e\n      \u003cspan class=\"hc-feather\"\u003e95 g\/m² · Piuma\u003c\/span\u003e\n      \u003cimg class=\"honeycomb\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0988\/4323\/0595\/files\/native-linda-honeycomb.png?v=1778759184\" alt=\"Macro view of NATIVE LINDA honeycomb knit fabric, showing the open hexagonal mesh structure that gives the tank its lightness and breathability\" decoding=\"async\" fetchpriority=\"high\" width=\"460\" height=\"460\"\u003e\n      \u003cspan class=\"hc-label\"\u003e\n        Honeycomb Knit SITIP · NATIVE LINDA\n      \u003cstrong\u003e\u003c\/strong\u003e\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 ; TECNOLOGIA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eDue innovazioni.\u003cbr\u003eUna sola brezza.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDue tecnologie SITIP combinate su un’unica base da 95 g\/m²: una rende il tessuto morbido come seta sulla pelle, l’altra lo ricostruisce da filato riciclato con il minor impatto possibile.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003cdiv class=\"tech-grid\" data-anim-stagger=\"180\"\u003e\n    \u003c!-- MICROSENSE --\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·SOFT\u003c\/div\u003e\n      \u003cdiv class=\"badge\"\u003e◐ Soft Performance System\u003c\/div\u003e\n      \u003ch3\u003eMicrosense\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eFilato in microfilamento che imita la seta. Delicato sulla pelle, implacabile col sudore.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🪶\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eMorbidezza sulla pelle simile alla seta\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💨\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eAssorbimento dell’umidità superiore\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e⚡\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eAsciuga più in fretta delle fibre naturali\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e👕\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eFacile da curare: non serve stirare\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·ECO\u003c\/div\u003e\n      \u003cdiv class=\"badge\"\u003e♻ Recycled Yarn System\u003c\/div\u003e\n      \u003ch3\u003eNative\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eFilato riciclato pre e post-consumo, chimica a basso impatto, minor consumo di energia.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e♻️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eFilato in poliestere 100% riciclato\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🌍\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eCertificato GRS e ISO 14001\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🧪\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eChimica senza fluoro e a basso impatto\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e⚡\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eMinor uso di energia non rinnovabile\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\"\u003eCome si muove\u003cbr\u003econ te.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDal primo set sulla sabbia all’ultimo punto del torneo: un tessuto così leggero che dimenticherai di indossarlo.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"perf-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eProgettato per la sabbia\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003eUltraleggera · Massima ventilazione · Totale libertà di braccia\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\u003e95 g\/m² Ultraleggero\u003c\/h4\u003e\n        \u003cp\u003eMeno della metà del peso di una canotta tecnica standard: la dimentichi addosso.\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\u003eHoneycomb Knit\u003c\/h4\u003e\n        \u003cp\u003eUna struttura a maglia esagonale fa circolare l’aria fresca all’interno come una brezza attraverso una finestra.\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\u003eTaglio smanicato\u003c\/h4\u003e\n        \u003cp\u003eSpalle libere, zero tessuto sulle braccia: schiacciate, servizi e difese senza nulla che ostacoli.\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\u003eAsciugatura rapida\u003c\/h4\u003e\n        \u003cp\u003eIl sudore viene portato in superficie e sparisce in pochi minuti. Resta fresco, resta asciutto, resta leggero.\u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n  \u003c\/section\u003e\n\n  \u003c!-- ============ CUSTOM PRINT (SEO: custom beach volley tank, beach team kits, custom beach tennis tank top) ============ --\u003e\n  \u003cdiv class=\"section-head\"\u003e\n    \u003cdiv\u003e\n      \u003cdiv class=\"num\" data-anim=\"left\"\u003e03 ; PERSONALIZZA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eRendila\u003cbr\u003etua.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna canotta da spiaggia personalizzata, costruita sulla tua squadra. Stampa logo, numeri e sponsor sulla maglia honeycomb italiana più leggera, da 95 g\/m²: pronta per la squadra già dal primo pezzo.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"custom-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eLa tua canotta da spiaggia personalizzata, a modo tuo\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003eLogo · Numeri · Sponsor · Colori squadra\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\u003eStampa il tuo logo\u003c\/h4\u003e\n        \u003cp\u003eStampa a sublimazione su petto, schiena e spalle. Dettaglio fotografico su una canotta da beach volley personalizzata che non si crepa, non si screpola e non sbiadisce, nemmeno dopo cento partite al sole.\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\u003eNumeri e nomi\u003c\/h4\u003e\n        \u003cp\u003ePronta per il torneo: aggiungi numeri di gioco, nomi o blocchi sponsor. Perfetta per club di beach volley, squadre di beach tennis e team di sport sulla sabbia.\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\u003eDa 1 pezzo\u003c\/h4\u003e\n        \u003cp\u003eNessun ordine minimo per una canotta da spiaggia personalizzata: dal pezzo unico fino ai kit squadra con taglie miste da 50+, con gli sconti quantità applicati in automatico.\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\u003eTagliato, cucito e stampato in Italia su una maglia honeycomb da 95 g\/m² tessuta da SITIP a Bergamo. Lo stesso tessuto con cui la tua squadra si allena e gareggia: nessun compromesso sulla personalizzazione.\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 ; UTILIZZI\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eIndossala come\u003cbr\u003eproprio nulla.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna maglia più leggera e aperta di qualsiasi canotta sportiva standard, tagliata smanicata per liberare le spalle. Pensata per far passare l’aria nel tessuto come una brezza marina attraversa un’amaca: pura ventilazione, pura freschezza, tutto il giorno.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\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\u003eVestibilità piuma smanicata\u003c\/div\u003e\n\n      \u003cdiv class=\"fit-headline\"\u003e\n        \u003ch3\u003eSmanicata \u003cspan class=\"em\"\u003efreschezza.\u003c\/span\u003e\n\u003c\/h3\u003e\n        \u003cp class=\"compare-lead\"\u003eUna maglia italiana più sottile e leggera di qualsiasi canotta sportiva standard, pensata per respirare e non solo per coprire. La rete honeycomb fa fluire l’aria fresca nel tessuto ed espelle quella umida, mentre il taglio smanicato aperto non oppone nulla alle spalle: resti fresco anche a 35 °C sulla sabbia.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"fit-mark\"\u003e\n        \u003cspan\u003e95 g\/m² ultraleggero\u003c\/span\u003e\n        \u003cspan\u003eRete honeycomb\u003c\/span\u003e\n        \u003cspan\u003eLibertà smanicata\u003c\/span\u003e\n        \u003cspan\u003eMassima ventilazione\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 \/ Beach Volley\u003c\/div\u003e\n        \u003ch4\u003eSabbia e \u003cspan class=\"ital\"\u003eschiacciate\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eSpalle libere + ventilazione honeycomb: rotazione completa del braccio su ogni schiacciata, senza mai appiccicarsi alla pelle sotto il sole.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eBeach volley\u003c\/span\u003e\u003cspan\u003e2v2\u003c\/span\u003e\u003cspan\u003e4v4\u003c\/span\u003e\u003cspan\u003eTornei\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 \/ Beach Tennis\u003c\/div\u003e\n        \u003ch4\u003eScambi \u003cspan class=\"ital\"\u003eveloci\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eTaglio smanicato + 95 g\/m² ultraleggero: nessun impaccio sulle schiacciate, niente tessuto nello swing, nessun peso sugli scatti.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eBeach tennis\u003c\/span\u003e\u003cspan\u003eBeach padel\u003c\/span\u003e\u003cspan\u003ePickleball\u003c\/span\u003e\u003cspan\u003eCampo in sabbia\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 \/ Caldo\u003c\/div\u003e\n        \u003ch4\u003e35 °C e \u003cspan class=\"ital\"\u003eoltre\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eAssorbimento Microsense + rete aperta: l’umidità esce più velocemente di quanto si formi.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eEstate mediterranea\u003c\/span\u003e\u003cspan\u003eClimi tropicali\u003c\/span\u003e\u003cspan\u003eAllenamenti sotto il sole\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 \/ Sport sulla sabbia\u003c\/div\u003e\n        \u003ch4\u003eAtletica \u003cspan class=\"ital\"\u003eda spiaggia\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003ePiuma + smanicata: massima libertà di movimento per footvolley, beach handball e beach soccer.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eFootvolley\u003c\/span\u003e\u003cspan\u003eBeach handball\u003c\/span\u003e\u003cspan\u003eBeach soccer\u003c\/span\u003e\u003cspan\u003eBeach rugby\u003c\/span\u003e\u003cspan\u003eBeach ultimate\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 \/ Allenamento\u003c\/div\u003e\n        \u003ch4\u003eAtletica \u003cspan class=\"ital\"\u003efitness\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eAsciuga in pochi minuti tra un set e l’altro: resta fresco dalle corse all’alba agli allenamenti al tramonto.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eBeach running\u003c\/span\u003e\u003cspan\u003eAllenamenti sulla sabbia\u003c\/span\u003e\u003cspan\u003eHIIT\u003c\/span\u003e\u003cspan\u003eCrossFit in spiaggia\u003c\/span\u003e\u003cspan\u003eYoga\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 \/ Lifestyle\u003c\/div\u003e\n        \u003ch4\u003eTempo \u003cspan class=\"ital\"\u003elibero\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eMicrosense morbido al tatto: si indossa come una canotta premium dal beach club al bar al tramonto.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eBeach club\u003c\/span\u003e\u003cspan\u003eLungomare\u003c\/span\u003e\u003cspan\u003eViaggi\u003c\/span\u003e\u003cspan\u003eResort wear\u003c\/span\u003e\u003cspan\u003eFestival\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 ; STANDARD\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eFatta con onestà.\u003cbr\u003eMade in Italy.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eControllata in modo indipendente, dal filato al capo finito: nessuna dichiarazione senza prove.\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\"\u003eOrigine e certificazioni\u003c\/h3\u003e\n      \u003cdiv class=\"stamp\" data-anim=\"right\"\u003eVerificato · Controllato · Tracciabile\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 · stabilimento SITIP\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\"\u003eCertificato GRS\u003c\/div\u003e\n          \u003cdiv class=\"meta\"\u003eGlobal Recycle Standard\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 · Classe 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® · ZDHC\u003c\/div\u003e\n          \u003cdiv class=\"meta\"\u003eISO 14001 · Filiera certificata\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\"\u003eDomande,\u003cbr\u003erisposte.\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\u003eQuanto è leggera davvero The Beach Tank?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\n95 g\/m². Meno della metà del peso di una canotta tecnica standard e circa un terzo di una rashguard. La struttura della maglia honeycomb toglie peso senza perdere resistenza, e il taglio smanicato scende ancora più in basso: sentirai la differenza nell’istante in cui la indossi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eCos’è la maglia honeycomb e perché è importante?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eÈ una struttura a maglia esagonale intessuta nel tessuto stesso, non una stampa né una perforazione. Le celle aperte fanno entrare l’aria fresca e uscire quella umida, esattamente come una brezza che passa da una finestra aperta. Sulla sabbia a 35 °C la differenza è abissale.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003ePerché un taglio smanicato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003ePerché gli sport da spiaggia vivono nelle spalle. Una schiacciata a volley, uno smash nel beach tennis, un servizio, un lancio: tutti vogliono le braccia libere, con zero tessuto a ostacolare. The Beach Tank ti dà rotazione completa della spalla, più pelle esposta alla brezza e meno peso da portarti dietro. È lo stesso DNA honeycomb di The Beach Shirt, ridotto all’essenziale.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003ePosso stampare il mio logo sulla canotta da spiaggia?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eAncora meglio: puoi creare la tua canotta da spiaggia da zero con il nostro configuratore 3D avanzato. Cambia i colori, aggiungi il logo, scrivi il tuo nome, posiziona gli sponsor e combina le fantasie, vedendo tutto in anteprima live in 3D. Servono idee? Il nostro AI Designer genera grafiche personalizzate da una semplice descrizione testuale: massima libertà creativa, senza bisogno di saper disegnare.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQual è l’ordine minimo per un kit squadra personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nBasta un pezzo: non c’è un minimo. Ordina una singola canotta da spiaggia personalizzata o un kit completo da 50+, con gli sconti quantità che partono in automatico già da 3 pezzi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eDi cosa è fatto?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nPoliestere 100% riciclato della gamma NATIVE di SITIP: filato riciclato pre e post-consumo, certificato GRS, prodotto con chimica a basso impatto e minor uso di energia non rinnovabile. Lo stesso tessuto è poi rifinito con la tecnologia MICROSENSE per una sensazione sulla pelle simile alla seta e un assorbimento dell’umidità superiore.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003ePer quali sport è ideale?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eProgettata per beach volley, beach tennis, footvolley, beach handball, beach soccer, beach running e ogni sport in cui ventilazione, libertà di braccia e sensazione ultraleggera contano più dello spessore o della compressione. Funziona benissimo anche nel tempo libero, come canotta premium da spiaggia e resort.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQuanto tempo richiede un ordine personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eDi solito la produzione richiede 2-3 settimane dal checkout, più i tempi di spedizione. Controlla la pagina del carrello per il tempo di produzione esatto del tuo ordine.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eChe taglia devo scegliere?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eNessun problema: la guida alle taglie ti verrà suggerita direttamente durante la configurazione, con misure calibrate sulla vestibilità sportiva regolare di questo modello.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eDove è prodotta?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nInteramente prodotto in Italia, nel nostro stabilimento di abbigliamento tecnico a Parma. Il tessuto (NATIVE LINDA) è realizzato da SITIP a Bergamo, poi tagliato, cucito, stampato e rifinito internamente dal nostro team.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eCome si lava The Beach Tank?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eLavaggio in lavatrice a freddo (30°C) con ciclo delicato, senza ammorbidente e senza asciugatrice. Non serve stirare: la tecnologia MICROSENSE mantiene il tessuto liscio da solo. Appendilo ad asciugare; sarà pronto in pochi minuti.\u003cstrong\u003e\u003c\/strong\u003e\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\": \"The Beach Tank\",\n    \"description\": \"Ultralight 95 g\/m² sleeveless honeycomb-knit tank top for beach volley, beach tennis and beach sports. 100% recycled polyester (SITIP NATIVE LINDA) with MICROSENSE soft-touch finish. Custom printable from 1 piece. Made in Italy.\",\n    \"category\": \"Sportswear \/ Beach Sports\",\n    \"brand\": { \"@type\": \"Brand\", \"name\": \"Inferno Beachwear\" },\n    \"material\": \"100% Recycled Polyester (PLR) · SITIP NATIVE LINDA · MICROSENSE\",\n    \"weight\": { \"@type\": \"QuantitativeValue\", \"value\": 95, \"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\": \"How light is The Beach Tank, really?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"95 g\/m². That is less than half the weight of a standard performance tank and about a third of a rashguard. The honeycomb knit structure removes mass without losing strength, and the sleeveless cut strips even more weight off the shoulders.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"What is the honeycomb knit and why does it matter?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"A hexagonal mesh structure woven into the fabric itself, not a print or perforation. The open cells let fresh air flow in and humid air escape, like a breeze through an open window.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"Why a sleeveless cut?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Beach sports live in the shoulders. The sleeveless cut gives full arm rotation for volley spikes, beach tennis smashes, serves and throws, with more skin exposed to the breeze and less fabric weight to drag around.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"Can I print my own logo on the beach tank?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Yes. You can build your beach tank 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.\"\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 beach tank or a full team kit of 50+ pieces. Bulk discounts apply automatically from 3 pieces upwards.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"What is it made of?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"100% recycled polyester from SITIP's NATIVE range; pre- and post-consumer recycled yarn, GRS certified, produced with low-impact chemistry and reduced non-renewable energy. Finished with MICROSENSE technology for a silk-like next-to-skin feel and superior moisture-wicking.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"What sports is it best for?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Engineered for beach volley, beach tennis, footvolley, beach handball, beach soccer, beach running and any sport where ventilation, arm freedom and ultralight feel matter more than thickness or compression.\"\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.\"\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 regular sport fit of this model.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"Where is it made?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Entirely produced in Italy. Fabric (NATIVE LINDA) is woven by SITIP in Bergamo, then cut, sewn, printed and finished in our facility in Parma.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"How do I care for The Beach Tank?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Machine wash cold (30°C) on a gentle cycle, no fabric softener, no tumble dry. No ironing required thanks to MICROSENSE technology. Hang to dry.\"\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\u003eThe Beach Tank\u003c\/span\u003e\n      \u003cspan\u003e95 g\/m² Ultraleggero\u003c\/span\u003e\n      \u003cspan\u003eHoneycomb Knit\u003c\/span\u003e\n      \u003cspan\u003eNATIVE Recycled Yarn\u003c\/span\u003e\n      \u003cspan\u003eMICROSENSE Soft Touch\u003c\/span\u003e\n      \u003cspan\u003eMade in Italy\u003c\/span\u003e\n      \u003cspan\u003eThe Beach Tank\u003c\/span\u003e\n      \u003cspan\u003e95 g\/m² Ultraleggero\u003c\/span\u003e\n      \u003cspan\u003eHoneycomb Knit\u003c\/span\u003e\n      \u003cspan\u003eNATIVE Recycled Yarn\u003c\/span\u003e\n      \u003cspan\u003eMICROSENSE Soft Touch\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":58201487147395,"sku":"TANK-SS-XS","price":39.0,"currency_code":"EUR","in_stock":true},{"title":"S","offer_id":58201487180163,"sku":"TANK-SS-S","price":39.0,"currency_code":"EUR","in_stock":true},{"title":"M","offer_id":58201487212931,"sku":"TANK-SS-M","price":39.0,"currency_code":"EUR","in_stock":true},{"title":"L","offer_id":58201487245699,"sku":"TANK-SS-L","price":39.0,"currency_code":"EUR","in_stock":true},{"title":"XL","offer_id":58201487278467,"sku":"TANK-SS-XL","price":39.0,"currency_code":"EUR","in_stock":true},{"title":"XXL","offer_id":58201487311235,"sku":"TANK-SS-XXL","price":39.0,"currency_code":"EUR","in_stock":true},{"title":"3XL","offer_id":58201487344003,"sku":"TANK-SS-3XL","price":39.0,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0988\/4323\/0595\/files\/b432c2041d567b527159ffe9ec94d37b.jpg?v=1780911498"},{"product_id":"ultralight-technical-short-porcelain-desert-varnish","title":"Ultralight Technical Short - 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\u003eThe Beach Short ; short honeycomb ultraleggeri per beach volley e beach sport\u003c\/title\u003e\n\u003cmeta name=\"description\" content=\"The Beach Short — ultralight 95 g\/m² honeycomb-knit performance shorts by SITIP. Recycled NATIVE yarn, MICROSENSE soft-touch finish, relaxed comfort fit, breathable as a sea breeze. Custom team kits for beach volley, beach tennis, footvolley and beach sports. Made in Italy.\"\u003e\n\u003cmeta name=\"keywords\" content=\"beach volley shorts, beach tennis shorts, ultralight sports shorts, breathable beach shorts, honeycomb knit shorts, recycled polyester sportswear, custom beach volley kit, SITIP NATIVE LINDA, MICROSENSE, beach sports apparel, no-pocket shorts, 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\u003eCompletamente personalizzabile\u003c\/div\u003e\n      \u003cdiv class=\"meta-row\" data-anim=\"right\"\u003e\n        \u003cspan\u003eSKU · BCH-SR-01\u003c\/span\u003e\n        \u003cspan\u003e95 g\/m² · Honeycomb\u003c\/span\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"kicker\" data-anim=\"left\"\u003eHoneycomb Knit · Beach Performance Series\u003c\/div\u003e\n    \u003ch1 data-anim=\"reveal\"\u003eThe Beach\u003cbr\u003e\u003cspan class=\"accent\"\u003eShort\u003c\/span\u003e\n\u003c\/h1\u003e\n    \u003cp class=\"product-full-title\" data-anim=\"rise\"\u003eUltralight Technical Short - THUNDER MASTER\u003c\/p\u003e\n    \u003cp class=\"subline\" data-anim=\"blur\"\u003e\u003cstrong\u003eLo short da spiaggia ultraleggero. Una maglia italiana piuma da 95 g\/m² con struttura honeycomb che lascia passare l’aria come una brezza marina. Filato riciclato NATIVE, finitura morbida MICROSENSE, taglio comfort rilassato con elastico in vita e coulisse interna. Pensato per beach volley, beach tennis e ogni sport giocato a piedi nudi: stampa il tuo logo, i numeri e gli sponsor, dalla singola maglia ai kit completi per la squadra.\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n    \u003cdiv class=\"feature-tabs\" data-anim-stagger=\"60\"\u003e\n      \u003cspan data-anim=\"rise\"\u003e✎ Stampa personalizzata\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003e🍃 95 g\/m² Ultraleggero\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003e⬡ Honeycomb Knit\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003e♻ NATIVE Riciclato\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=b82ed9a1c124d12e0d5550d0b4a1d5ae\" 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        Modifica 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        Crea un nuovo 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\"\u003eSconti \u003cspan class=\"em\" style=\"padding: 2px 50px 0px 0px\"\u003equantità\u003c\/span\u003e\n\u003c\/h3\u003e\n          \u003cp class=\"pricing-sub\"\u003eTrascina il cursore · più ordini, più risparmi\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\"\u003eQuantità\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)\"\u003epz\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% di sconto\u003c\/div\u003e\n          \u003cspan class=\"save\" id=\"save-line\" style=\"color: rgb(0, 0, 0)\"\u003eScegli 2+ pz per iniziare a risparmiare\u003c\/span\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"readout-price\"\u003e\n          \u003cdiv class=\"label\"\u003eIl tuo prezzo\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)\"\u003eTotale: \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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc zero\"\u003e0%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−5%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.95 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−15%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.85 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−25%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.75 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−35%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.65 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−45%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.55 | money }} cad.\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 pz\u003c\/div\u003e\n          \u003cdiv class=\"disc\"\u003e−50%\u003c\/div\u003e\n          \u003cdiv class=\"price-each\"\u003e{{ product.price | times: 0.50 | money }} cad.\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+ pezzi\u003c\/div\u003e\n          \u003ch4\u003eTi serve un kit completo per la squadra? Parliamone.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h4\u003e\n          \u003cp\u003ePrezzi dedicati per club, squadre ed eventi da 50+ pezzi: ti inviamo un preventivo entro 24 ore.\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          Richiedi un preventivo\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⚓ Richiesta quantità · 50+ pezzi\u003c\/div\u003e\n            \u003ch3 id=\"quote-modal-title\"\u003eRicevi il tuo preventivo personalizzato.\n\u003cem\u003e\u003c\/em\u003e\u003c\/h3\u003e\n            \u003cp\u003eRaccontaci della tua squadra e ti rispondiamo entro 24h con prezzi e tempi di consegna.\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=\"Ultralight Technical Short - 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\"\u003eNome club \/ azienda \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\"\u003eInserisci il nome del club o dell’azienda\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\"\u003ePaese \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\"\u003eObbligatorio\u003c\/div\u003e\n                \u003c\/div\u003e\n                \u003cdiv class=\"quote-field\"\u003e\n                  \u003clabel for=\"qf-vat\"\u003ePartita IVA \u003cspan class=\"opt\"\u003e(se presente)\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\"\u003eQuantità \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\"\u003eDeve essere almeno 50\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\"\u003eÈ richiesta un’email valida\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\"\u003eNote \u003cspan class=\"opt\"\u003e(facoltativo — raccontaci della squadra, del design, delle scadenze, ecc.)\u003c\/span\u003e\u003c\/label\u003e\n                  \u003ctextarea id=\"qf-notes\" name=\"contact[Notes]\" rows=\"4\" autocomplete=\"off\" placeholder=\"e.g. 80 jerseys for our beach volley 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\"\u003eSito web (lascia vuoto — 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                Invia richiesta\n              \u003c\/button\u003e\n              \u003cdiv class=\"quote-modal-footnote\"\u003eTi risponderemo entro 24h all’email che ci indichi. Contatto alternativo: custominferno@gmail.com.\u003cstrong\u003e\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      Tessuti italiani premium\n    \u003c\/div\u003e\n    \u003ch2 data-anim=\"reveal\"\u003ePiù leggero di\u003cbr\u003e\u003cspan class=\"ital\"\u003euna brezza marina.\u003c\/span\u003e\n\u003c\/h2\u003e\n    \u003cp data-anim=\"blur\"\u003eUna maglia honeycomb da 95 g\/m² tessuta da SITIP a Bergamo sulla base NATIVE LINDA: l’aria la attraversa come scorre sulla sabbia. Lo short più leggero, fresco e traspirante che produciamo — taglio comfort rilassato, pensato per beach volley, beach tennis e ogni sport giocato a piedi nudi.\u003c\/p\u003e\n    \u003cdiv class=\"hero-meta\" data-anim-stagger=\"80\"\u003e\n      \u003cspan data-anim=\"rise\"\u003e95 g\/m² · Honeycomb knit\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003eFilato 100% riciclato\u003c\/span\u003e\n      \u003cspan data-anim=\"rise\"\u003eMade in Italy\u003c\/span\u003e\n    \u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"hero-visual\" data-anim=\"zoom\" aria-label=\"Macro view of white honeycomb knit fabric, showing the open hexagonal structure that gives the short its lightness and breathability\"\u003e\n      \u003cspan class=\"hc-feather\"\u003e95 g\/m² · Piuma\u003c\/span\u003e\n      \u003cimg class=\"honeycomb\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0988\/4323\/0595\/files\/native-linda-honeycomb.png?v=1778759184\" alt=\"Macro view of NATIVE LINDA honeycomb knit fabric, showing the open hexagonal mesh structure that gives the short its lightness and breathability\" decoding=\"async\" fetchpriority=\"high\" width=\"460\" height=\"460\"\u003e\n      \u003cspan class=\"hc-label\"\u003e\n        Honeycomb Knit SITIP · NATIVE LINDA\n      \u003cstrong\u003e\u003c\/strong\u003e\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 ; TECNOLOGIA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eDue innovazioni.\u003cbr\u003eUna sola brezza.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDue tecnologie SITIP combinate su un’unica base da 95 g\/m²: una rende il tessuto morbido come seta sulla pelle, l’altra lo ricostruisce da filato riciclato con il minor impatto possibile.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003cdiv class=\"tech-grid\" data-anim-stagger=\"180\"\u003e\n    \u003c!-- MICROSENSE --\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·SOFT\u003c\/div\u003e\n      \u003cdiv class=\"badge\"\u003e◐ Soft Performance System\u003c\/div\u003e\n      \u003ch3\u003eMicrosense\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eFilato in microfilamento che imita la seta. Delicato sulla pelle, implacabile col sudore.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🪶\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eMorbidezza sulla pelle simile alla seta\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e💨\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eAssorbimento dell’umidità superiore\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e⚡\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eAsciuga più in fretta delle fibre naturali\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e👕\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eFacile da curare: non serve stirare\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·ECO\u003c\/div\u003e\n      \u003cdiv class=\"badge\"\u003e♻ Recycled Yarn System\u003c\/div\u003e\n      \u003ch3\u003eNative\u003c\/h3\u003e\n      \u003cp class=\"tagline\"\u003eFilato riciclato pre e post-consumo, chimica a basso impatto, minor consumo di energia.\u003c\/p\u003e\n      \u003cul class=\"tech-features\"\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e♻️\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eFilato in poliestere 100% riciclato\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🌍\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eCertificato GRS e ISO 14001\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e🧪\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eChimica senza fluoro e a basso impatto\u003c\/div\u003e\n        \u003c\/li\u003e\n        \u003cli\u003e\n          \u003cdiv class=\"ico\"\u003e⚡\u003c\/div\u003e\n          \u003cdiv class=\"label\"\u003eMinor uso di energia non rinnovabile\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\"\u003eCome si muove\u003cbr\u003econ te.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eDal primo set sulla sabbia all’ultimo punto del torneo: un tessuto così leggero che dimenticherai di indossarlo.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"perf-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eProgettato per la sabbia\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003eUltraleggero · Massima ventilazione · Fresco tutto il giorno\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\u003e95 g\/m² Ultraleggero\u003c\/h4\u003e\n        \u003cp\u003eMeno della metà del peso di uno short tecnico standard: dimenticherai di averlo addosso.\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\u003eHoneycomb Knit\u003c\/h4\u003e\n        \u003cp\u003eUna struttura a maglia esagonale fa circolare l’aria fresca all’interno come una brezza attraverso una finestra.\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\u003eElasticità in ogni direzione: salti, tuffi e difese in allungo senza alcun vincolo.\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\u003eAsciugatura rapida\u003c\/h4\u003e\n        \u003cp\u003eIl sudore viene portato in superficie e sparisce in pochi minuti. Resta fresco, resta asciutto, resta leggero.\u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n  \u003c\/section\u003e\n\n  \u003c!-- ============ CUSTOM PRINT (SEO: custom beach volley shorts, beach team kits, custom beach tennis shorts) ============ --\u003e\n  \u003cdiv class=\"section-head\"\u003e\n    \u003cdiv\u003e\n      \u003cdiv class=\"num\" data-anim=\"left\"\u003e03 ; PERSONALIZZA\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eRendila\u003cbr\u003etua.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUno short da spiaggia personalizzato, costruito sulla tua squadra. Stampa logo, sponsor e colori squadra sulla maglia honeycomb italiana più leggera, da 95 g\/m²: pronto per la squadra già dal primo pezzo.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"custom-strip\" data-anim=\"rise-lg\"\u003e\n    \u003ch3 data-anim=\"reveal\"\u003eIl tuo short da spiaggia personalizzato, a modo tuo\u003c\/h3\u003e\n    \u003cp class=\"sub\" data-anim=\"fade\"\u003eLogo · Bande laterali · Sponsor · Colori squadra\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\u003eStampa il tuo logo\u003c\/h4\u003e\n        \u003cp\u003eStampa a sublimazione totale su gambe, fascia in vita e pannelli laterali. Dettaglio fotografico su uno short da beach volley personalizzato che non si crepa, non si screpola e non sbiadisce, nemmeno dopo cento partite al sole.\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\u003eFantasie squadra\u003c\/h4\u003e\n        \u003cp\u003ePronto per il torneo: aggiungi bande laterali, blocchi sponsor, pannelli sfumati o stampe all-over. Perfetto per club di beach volley, squadre di beach tennis e team di sport sulla sabbia.\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\u003eDa 1 pezzo\u003c\/h4\u003e\n        \u003cp\u003eNessun ordine minimo per uno short da spiaggia personalizzato: dal pezzo unico fino ai kit squadra con taglie miste da 50+, con gli sconti quantità applicati in automatico.\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\u003eTagliato, cucito e stampato in Italia su una maglia honeycomb da 95 g\/m² tessuta da SITIP a Bergamo. Lo stesso tessuto con cui la tua squadra si allena e gareggia: nessun compromesso sulla personalizzazione.\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 ; UTILIZZI\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eIndossala come\u003cbr\u003eproprio nulla.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eUna maglia più leggera e aperta di qualsiasi short sportivo standard. Pensata per far passare l’aria nel tessuto come una brezza marina attraversa un’amaca: pura ventilazione, pura freschezza, zero peso sulle gambe.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\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\u003eVestibilità da spiaggia piuma\u003c\/div\u003e\n\n      \u003cdiv class=\"fit-headline\"\u003e\n        \u003ch3\u003ePiuma \u003cspan class=\"em\"\u003efreschezza.\u003c\/span\u003e\n\u003c\/h3\u003e\n        \u003cp class=\"compare-lead\"\u003eUna maglia italiana più sottile e leggera di qualsiasi short sportivo standard, pensata per respirare e non solo per coprire. La rete honeycomb fa fluire l’aria fresca nel tessuto ed espelle quella umida: le tue gambe restano fresche anche a 35 °C sulla sabbia. Taglio comfort rilassato con elastico in vita e coulisse interna; niente tasche, per scelta.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"fit-mark\"\u003e\n        \u003cspan\u003e95 g\/m² ultraleggero\u003c\/span\u003e\n        \u003cspan\u003eRete honeycomb\u003c\/span\u003e\n        \u003cspan\u003eMassima ventilazione\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 \/ Beach Volley\u003c\/div\u003e\n        \u003ch4\u003eSabbia e \u003cspan class=\"ital\"\u003eschiacciate\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eVentilazione honeycomb: resta fresco nelle lunghe partite al sole e non si appiccica mai alla pelle.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eBeach volley\u003c\/span\u003e\u003cspan\u003e2v2\u003c\/span\u003e\u003cspan\u003e4v4\u003c\/span\u003e\u003cspan\u003eTornei\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 \/ Beach Tennis\u003c\/div\u003e\n        \u003ch4\u003eScambi \u003cspan class=\"ital\"\u003eveloci\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003e4-way stretch + 95 g\/m² ultraleggero: nessun impaccio sulle schiacciate, nessun peso sugli scatti.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eBeach tennis\u003c\/span\u003e\u003cspan\u003eBeach padel\u003c\/span\u003e\u003cspan\u003ePickleball\u003c\/span\u003e\u003cspan\u003eCampo in sabbia\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 \/ Caldo\u003c\/div\u003e\n        \u003ch4\u003e35 °C e \u003cspan class=\"ital\"\u003eoltre\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eAssorbimento Microsense + rete aperta: l’umidità esce più velocemente di quanto si formi.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eEstate mediterranea\u003c\/span\u003e\u003cspan\u003eClimi tropicali\u003c\/span\u003e\u003cspan\u003eAllenamenti sotto il sole\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 \/ Sport sulla sabbia\u003c\/div\u003e\n        \u003ch4\u003eAtletica \u003cspan class=\"ital\"\u003eda spiaggia\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003ePiuma: massima libertà di movimento per footvolley, beach handball e beach soccer.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eFootvolley\u003c\/span\u003e\u003cspan\u003eBeach handball\u003c\/span\u003e\u003cspan\u003eBeach soccer\u003c\/span\u003e\u003cspan\u003eBeach rugby\u003c\/span\u003e\u003cspan\u003eBeach ultimate\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 \/ Allenamento\u003c\/div\u003e\n        \u003ch4\u003eAtletica \u003cspan class=\"ital\"\u003efitness\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eAsciuga in pochi minuti tra un set e l’altro: resta fresco dalle corse all’alba agli allenamenti al tramonto.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eBeach running\u003c\/span\u003e\u003cspan\u003eAllenamenti sulla sabbia\u003c\/span\u003e\u003cspan\u003eHIIT\u003c\/span\u003e\u003cspan\u003eCrossFit in spiaggia\u003c\/span\u003e\u003cspan\u003eYoga\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 \/ Lifestyle\u003c\/div\u003e\n        \u003ch4\u003eTempo \u003cspan class=\"ital\"\u003elibero\u003c\/span\u003e\n\u003c\/h4\u003e\n        \u003cp class=\"uc-benefit\"\u003e\u003cb\u003eMicrosense morbido al tatto: si indossa come loungewear premium dal beach club alla cena al tramonto.\u003c\/b\u003e\u003c\/p\u003e\n        \u003cdiv class=\"uc-tags\"\u003e\n\u003cspan\u003eBeach club\u003c\/span\u003e\u003cspan\u003eLungomare\u003c\/span\u003e\u003cspan\u003eViaggi\u003c\/span\u003e\u003cspan\u003eResort wear\u003c\/span\u003e\u003cspan\u003eFestival\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 ; STANDARD\u003c\/div\u003e\n      \u003ch2 data-anim=\"reveal\"\u003eFatta con onestà.\u003cbr\u003eMade in Italy.\u003c\/h2\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"lede\" data-anim=\"blur\"\u003eControllata in modo indipendente, dal filato al capo finito: nessuna dichiarazione senza prove.\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\"\u003eOrigine e certificazioni\u003c\/h3\u003e\n      \u003cdiv class=\"stamp\" data-anim=\"right\"\u003eVerificato · Controllato · Tracciabile\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 · stabilimento SITIP\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\"\u003eCertificato GRS\u003c\/div\u003e\n          \u003cdiv class=\"meta\"\u003eGlobal Recycle Standard\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 · Classe 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® · ZDHC\u003c\/div\u003e\n          \u003cdiv class=\"meta\"\u003eISO 14001 · Filiera certificata\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\"\u003eDomande,\u003cbr\u003erisposte.\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\u003eQuanto è leggero davvero The Beach Short?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\n95 g\/m². Meno della metà del peso di uno short tecnico standard. La struttura della maglia honeycomb toglie peso senza perdere resistenza: sulla sabbia lo sentirai muoversi con te, non contro di te.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eCos’è la maglia honeycomb e perché è importante?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eÈ una struttura a maglia esagonale intessuta nel tessuto stesso, non una stampa né una perforazione. Le celle aperte fanno entrare l’aria fresca e uscire quella umida, esattamente come una brezza che passa da una finestra aperta. Sulla sabbia a 35 °C le tue gambe restano fresche mentre tutti gli altri si surriscaldano.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003ePerché The Beach Short non ha tasche?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nPer scelta. Su uno short da spiaggia le tasche sono peso morto: sulla sabbia si riempiono di sabbia, in un tuffo si riempiono d’acqua, in un salto sbattono contro le cosce. Le abbiamo eliminate per tre motivi:\n        \u003cstrong\u003e\u003c\/strong\u003e\u003cbr\u003e\u003cbr\u003e\n        1. Performance: niente che trascini, niente che rimbalzi, niente che si impigli nella sabbia. Massima libertà di movimento per tuffi, scatti e difese in allungo.\n        \u003cstrong\u003e\u003c\/strong\u003e\u003cbr\u003e\n        2. Leggerezza: le tasche significano pannelli di tessuto in più, cuciture in più, grammi in più. Abbiamo mantenuto onesta la promessa dei 95 g\/m² togliendo tutto ciò che non fosse ventilazione.\n        \u003cstrong\u003e\u003c\/strong\u003e\u003cbr\u003e\n        3. Comfort: niente sacche delle tasche che sfregano sulle cosce, niente tessuto ripiegato che trattiene il sudore, niente spessore in vita. Solo lo short e la brezza.\n        \u003cstrong\u003e\u003c\/strong\u003e\u003cbr\u003e\u003cbr\u003e\n        Chiavi, telefono e carte stanno nella borsa da spiaggia: lo short è fatto per giocare.\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eCome resta in posizione senza tasche?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nFascia elastica larga + coulisse interna. La fascia aderisce piatta sui fianchi senza arrotolarsi, e la morbida coulisse interna ti permette di fissare la vestibilità prima di una partita lunga. Niente passanti, niente patta ingombrante: in vita solo ciò che tiene su lo short.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003ePosso stampare il mio logo sullo short da spiaggia?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eAncora meglio: puoi creare il tuo short da spiaggia da zero con il nostro configuratore 3D avanzato. Cambia i colori, aggiungi il logo, posiziona gli sponsor sui pannelli laterali, combina le fantasie, aggiungi bande laterali: vedi tutto in anteprima live in 3D. Servono idee? Il nostro AI Designer genera grafiche personalizzate da una semplice descrizione testuale: massima libertà creativa, senza bisogno di saper disegnare.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQual è l’ordine minimo per un kit squadra personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nBasta un pezzo: non c’è un minimo. Ordina un singolo short da spiaggia personalizzato o un kit completo da 50+, con gli sconti quantità che partono in automatico già da 3 pezzi. Abbinalo a The Beach Shirt o The Beach Tank per il look completo della squadra.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eDi cosa è fatto?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nPoliestere 100% riciclato della gamma NATIVE di SITIP: filato riciclato pre e post-consumo, certificato GRS, prodotto con chimica a basso impatto e minor uso di energia non rinnovabile. Lo stesso tessuto è poi rifinito con la tecnologia MICROSENSE per una sensazione sulla pelle simile alla seta e un assorbimento dell’umidità superiore.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003ePer quali sport è ideale?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eProgettato per beach volley, beach tennis, footvolley, beach handball, beach soccer, beach running e ogni sport in cui ventilazione e libertà di movimento contano più della copertura o delle tasche. Funziona benissimo anche nel tempo libero, come short premium da spiaggia e resort.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQuanto è lungo lo short?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eUn taglio a metà coscia: abbastanza lungo per una copertura completa durante tuffi e salti, abbastanza corto da non limitare mai la falcata. La silhouette comfort rilassata cade sulla gamba senza aderire, così l’aria continua a circolare all’interno mentre giochi.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eC’è uno slip o una fodera interna?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eNo: The Beach Short è uno short tecnico monostrato, per scelta. Meno tessuto significa più ventilazione e asciugatura più rapida. Indossalo con la base che preferisci, o anche senza nulla sotto: la morbida finitura MICROSENSE è delicata sulla pelle.\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eQuanto tempo richiede un ordine personalizzato?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eDi solito la produzione richiede 2-3 settimane dal checkout, più i tempi di spedizione. Controlla la pagina del carrello per il tempo di produzione esatto del tuo ordine.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eChe taglia devo scegliere?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eNessun problema: la guida alle taglie ti verrà suggerita direttamente durante la configurazione, con misure calibrate sulla vestibilità comfort rilassata di questo modello.\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eDove è prodotta?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003e\nInteramente prodotto in Italia, nel nostro stabilimento di abbigliamento tecnico a Parma. Il tessuto (NATIVE LINDA) è realizzato da SITIP a Bergamo, poi tagliato, cucito, stampato e rifinito internamente dal nostro team.\u003cstrong\u003e\u003c\/strong\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n      \u003c\/details\u003e\n      \u003cdetails class=\"faq-item\" data-anim=\"rise\"\u003e\n        \u003csummary\u003eCome si lava?\u003c\/summary\u003e\n        \u003cdiv class=\"answer\"\u003eLavaggio in lavatrice a freddo (30°C) con ciclo delicato, senza ammorbidente e senza asciugatrice. Non serve stirare: la tecnologia MICROSENSE mantiene il tessuto liscio da solo. Appendilo ad asciugare; sarà pronto in pochi minuti.\u003cstrong\u003e\u003c\/strong\u003e\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\": \"The Beach Short\",\n    \"description\": \"Ultralight 95 g\/m² honeycomb-knit performance shorts for beach volley, beach tennis and beach sports. 100% recycled polyester (SITIP NATIVE LINDA) with MICROSENSE soft-touch finish. Relaxed comfort fit, no pockets by design. Custom printable from 1 piece. Made in Italy.\",\n    \"category\": \"Sportswear \/ Beach Sports \/ Shorts\",\n    \"brand\": { \"@type\": \"Brand\", \"name\": \"Inferno Beachwear\" },\n    \"material\": \"100% Recycled Polyester (PLR) · SITIP NATIVE LINDA · MICROSENSE\",\n    \"weight\": { \"@type\": \"QuantitativeValue\", \"value\": 95, \"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\": \"How light is The Beach Short, really?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"95 g\/m². That is less than half the weight of a standard performance short. The honeycomb knit structure removes mass without losing strength.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"What is the honeycomb knit and why does it matter?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"A hexagonal mesh structure woven into the fabric itself, not a print or perforation. The open cells let fresh air flow in and humid air escape, like a breeze through an open window.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"Why doesn't The Beach Short have pockets?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"By design. Pockets fill with sand on the beach, with water on a dive, and slap against the thighs on a jump. Removing them improves performance (no drag, total range of motion), keeps the 95 g\/m² weight honest (fewer panels, fewer seams), and removes bulk and chafe at the waistband. Phone, keys and cards belong in the beach bag; the short is for playing.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"How does it stay in place without pockets?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"A wide elastic waistband sits flat on the hips with no roll-over, and a soft internal drawcord lets you lock the fit before a long match. No belt loops, no bulky fly.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"Can I print my own logo on the beach short?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Yes. You can build your beach short from scratch with our advanced 3D configurator: change colours, add your logo, place sponsors on side panels, mix patterns and add side stripes, with a live 3D preview. Our AI Designer also generates custom artwork from a simple text prompt.\"\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 beach short or a full team kit of 50+ pieces. Bulk discounts apply automatically from 3 pieces upwards.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"What is it made of?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"100% recycled polyester from SITIP's NATIVE range; pre- and post-consumer recycled yarn, GRS certified, produced with low-impact chemistry and reduced non-renewable energy. Finished with MICROSENSE technology for a silk-like next-to-skin feel and superior moisture-wicking.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"What sports is it best for?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Engineered for beach volley, beach tennis, footvolley, beach handball, beach soccer, beach running and any sport where ventilation and freedom of movement matter more than coverage or pockets.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"How long is the short?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"A mid-thigh cut, long enough for full coverage during dives and jumps, short enough to never restrict your stride. Relaxed comfort silhouette that drapes over the leg without clinging.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"Is there an inner brief or liner?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"No. The Beach Short is a single-layer performance short. Less fabric means more airflow and faster drying.\"\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.\"\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.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"Where is it made?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Entirely produced in Italy. Fabric (NATIVE LINDA) is woven by SITIP in Bergamo, then cut, sewn, printed and finished in our facility in Parma.\"\n        }\n      },\n      {\n        \"@type\": \"Question\",\n        \"name\": \"How do I care for The Beach Short?\",\n        \"acceptedAnswer\": {\n          \"@type\": \"Answer\",\n          \"text\": \"Machine wash cold (30°C) on a gentle cycle, no fabric softener, no tumble dry. No ironing required thanks to MICROSENSE technology. Hang to dry.\"\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\u003eThe Beach Short\u003c\/span\u003e\n      \u003cspan\u003e95 g\/m² Ultraleggero\u003c\/span\u003e\n      \u003cspan\u003eHoneycomb Knit\u003c\/span\u003e\n      \u003cspan\u003eNATIVE Recycled Yarn\u003c\/span\u003e\n      \u003cspan\u003eMICROSENSE Soft Touch\u003c\/span\u003e\n      \u003cspan\u003eMade in Italy\u003c\/span\u003e\n      \u003cspan\u003eThe Beach Short\u003c\/span\u003e\n      \u003cspan\u003e95 g\/m² Ultraleggero\u003c\/span\u003e\n      \u003cspan\u003eHoneycomb Knit\u003c\/span\u003e\n      \u003cspan\u003eNATIVE Recycled Yarn\u003c\/span\u003e\n      \u003cspan\u003eMICROSENSE Soft Touch\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":58201499369859,"sku":"SHORT-XS","price":39.0,"currency_code":"EUR","in_stock":true},{"title":"S","offer_id":58201499402627,"sku":"SHORT-S","price":39.0,"currency_code":"EUR","in_stock":true},{"title":"M","offer_id":58201499435395,"sku":"SHORT-M","price":39.0,"currency_code":"EUR","in_stock":true},{"title":"L","offer_id":58201499468163,"sku":"SHORT-L","price":39.0,"currency_code":"EUR","in_stock":true},{"title":"XL","offer_id":58201499500931,"sku":"SHORT-XL","price":39.0,"currency_code":"EUR","in_stock":true},{"title":"XXL","offer_id":58201499533699,"sku":"SHORT-XXL","price":39.0,"currency_code":"EUR","in_stock":true},{"title":"3XL","offer_id":58201499566467,"sku":"SHORT-3XL","price":39.0,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0988\/4323\/0595\/files\/2c870d68fb1787156089f8fa238bffb6.jpg?v=1780911706"}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0988\/4323\/0595\/collections\/THUNDER_MASTER_76658ef7-2f5c-49ea-9983-530ab409e7e7.png?v=1781534186","url":"https:\/\/infernobeachwear.com\/it\/collections\/thunder-master-1.oembed","provider":"Inferno Beachwear","version":"1.0","type":"link"}