{"product_id":"cmp-panier-ecumoire-style-waterway-blanc","title":"CMP 25140-000-900 – Waterway-Style Skimmer Basket, White","description":"\u003cdiv class=\"afi-ap\" lang=\"en\"\u003e\n\n  \u003cp class=\"afi-ap-eyebrow\"\u003eCMP 25140-000-900\u003c\/p\u003e\n  \u003cp class=\"afi-ap-lede\"\u003eThe skimmer basket that replaces the Waterway 542-3240.\u003c\/p\u003e\n  \u003cp class=\"afi-ap-intro\"\u003eWhite Waterway-style pool skimmer basket with a handle. CMP lists it as the equivalent of the Waterway 542-3240 basket, the one used in Renegade in-ground skimmers. It catches leaves, insects and debris before they reach the pump.\u003c\/p\u003e\n\n  \u003cdiv class=\"afi-ap-nums\"\u003e\n    \u003cdiv\u003e\u003cb\u003e8-1\/4 in\u003c\/b\u003e\u003cspan\u003eTop diameter, at the rim\u003c\/span\u003e\u003c\/div\u003e\n    \u003cdiv\u003e\u003cb\u003e5-1\/8 in\u003c\/b\u003e\u003cspan\u003eHeight\u003c\/span\u003e\u003c\/div\u003e\n    \u003cdiv\u003e\u003cb\u003e5-7\/8 in\u003c\/b\u003e\u003cspan\u003eBottom diameter\u003c\/span\u003e\u003c\/div\u003e\n    \u003cdiv\u003e\u003cb\u003e542-3240\u003c\/b\u003e\u003cspan\u003eWaterway basket it replaces\u003c\/span\u003e\u003c\/div\u003e\n  \u003c\/div\u003e\n\n  \u003csection class=\"afi-ap-mod afi-ap-x\" hidden data-mod=\"bascule\" aria-labelledby=\"afi-ap-dim-h\"\u003e\n    \u003ch2 class=\"afi-ap-h\" id=\"afi-ap-dim-h\"\u003eCompare with your basket\u003c\/h2\u003e\n    \u003cp class=\"afi-ap-sub\"\u003eSet your current basket on a table and measure the top (across the rim), the bottom and the height.\u003c\/p\u003e\n    \u003cdiv class=\"afi-ap-seg\" role=\"radiogroup\" aria-label=\"Unit of measure\"\u003e\n      \u003ci class=\"afi-ap-segthumb\"\u003e\u003c\/i\u003e\n      \u003cbutton type=\"button\" role=\"radio\" aria-checked=\"true\"\u003eInches\u003c\/button\u003e\n      \u003cbutton type=\"button\" role=\"radio\" aria-checked=\"false\" tabindex=\"-1\"\u003eCentimetres\u003c\/button\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"afi-ap-bbox\"\u003e\n      \u003cdiv class=\"afi-ap-bfig afi-ap-bkfig\" aria-hidden=\"true\"\u003e\n        \u003csvg viewBox=\"0 0 256 150\"\u003e\n          \u003cpath class=\"afi-ap-bk\" d=\"M38 32H162L147 114H53Z\"\/\u003e\n          \u003cpath class=\"afi-ap-bkslot\" d=\"M60 44l4 58M78 44l2 58M96 44v58M114 44v58M132 44l-2 58M150 44l-4 58\"\/\u003e\n          \u003cpath class=\"afi-ap-bkrim\" d=\"M34 32H166\"\/\u003e\n          \u003cpath class=\"afi-ap-dim\" d=\"M34 18H166M34 13v10M166 13v10M53 128H147M53 123v10M147 123v10M180 32V114M175 32h10M175 114h10\"\/\u003e\n          \u003ctext class=\"afi-ap-dt\" x=\"100\" y=\"11\" text-anchor=\"middle\" data-t0=\"8-1\/4 in\" data-t1=\"21.0 cm\"\u003e8-1\/4 in\u003c\/text\u003e\n          \u003ctext class=\"afi-ap-dt\" x=\"100\" y=\"146\" text-anchor=\"middle\" data-t0=\"5-7\/8 in\" data-t1=\"14.9 cm\"\u003e5-7\/8 in\u003c\/text\u003e\n          \u003ctext class=\"afi-ap-dt\" x=\"190\" y=\"77\" data-t0=\"5-1\/8 in\" data-t1=\"13.0 cm\"\u003e5-1\/8 in\u003c\/text\u003e\n        \u003c\/svg\u003e\n      \u003c\/div\u003e\n      \u003cdiv class=\"afi-ap-btxt\" aria-live=\"polite\"\u003e\n        \u003cb data-t0=\"Top 8-1\/4 in, bottom 5-7\/8 in, height 5-1\/8 in.\" data-t1=\"Top 21.0 cm, bottom 14.9 cm, height 13.0 cm.\"\u003eTop 8-1\/4 in, bottom 5-7\/8 in, height 5-1\/8 in.\u003c\/b\u003e\n        \u003cp\u003eIf your basket has the same measurements, or carries the number 542-3240, this is the one. A few millimetres off can keep it from sitting properly in the skimmer.\u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cp class=\"afi-ap-note\"\u003eTop measured across the rim; bottom and height published by CMP, converted to the nearest millimetre. The drawing shows the dimensions, not the exact shape of the basket.\u003c\/p\u003e\n  \u003c\/section\u003e\n\n  \u003csection class=\"afi-ap-band\" aria-labelledby=\"afi-ap-why-h\"\u003e\n    \u003cdiv class=\"afi-ap-bandtop\"\u003e\n      \u003ch2 class=\"afi-ap-h afi-ap-hw\" id=\"afi-ap-why-h\"\u003eBefore you order\u003c\/h2\u003e\n      \u003cdiv class=\"afi-ap-nav afi-ap-x\" hidden\u003e\n        \u003cbutton type=\"button\" class=\"afi-ap-prev\" aria-label=\"Previous\"\u003e\u003csvg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"M12.5 4 6.5 10l6 6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/\u003e\u003c\/svg\u003e\u003c\/button\u003e\n        \u003cbutton type=\"button\" class=\"afi-ap-next\" aria-label=\"Next\"\u003e\u003csvg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"M7.5 4l6 6-6 6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/\u003e\u003c\/svg\u003e\u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"afi-ap-vp\"\u003e\n      \u003cul class=\"afi-ap-cards\"\u003e\n        \u003cli\u003e\u003csvg viewBox=\"0 0 24 24\" width=\"26\" height=\"26\" aria-hidden=\"true\"\u003e\u003cpath d=\"M4 12h6M14 12h6M8 8l-4 4 4 4M16 8l4 4-4 4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/\u003e\u003c\/svg\u003e\u003cb\u003eA CMP equivalent\u003c\/b\u003e\u003cspan\u003eThis is not the original Waterway part: CMP lists it as the equivalent of the 542-3240.\u003c\/span\u003e\u003c\/li\u003e\n        \u003cli\u003e\u003csvg viewBox=\"0 0 24 24\" width=\"26\" height=\"26\" aria-hidden=\"true\"\u003e\u003cpath d=\"M5 9h14l-2 11H7Z\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linejoin=\"round\"\/\u003e\u003cpath d=\"M8 9a4 4 0 0 1 8 0\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"\/\u003e\u003c\/svg\u003e\u003cb\u003eWith a handle\u003c\/b\u003e\u003cspan\u003eLift it out of the skimmer and empty it without reaching into the debris.\u003c\/span\u003e\u003c\/li\u003e\n        \u003cli\u003e\u003csvg viewBox=\"0 0 24 24\" width=\"26\" height=\"26\" aria-hidden=\"true\"\u003e\u003ccircle cx=\"12\" cy=\"12\" r=\"8\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"\/\u003e\u003cpath d=\"M12 7v5l3 2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/\u003e\u003c\/svg\u003e\u003cb\u003eEmpty it often\u003c\/b\u003e\u003cspan\u003eA full basket slows the water going to the pump. In the fall, check it more often.\u003c\/span\u003e\u003c\/li\u003e\n        \u003cli\u003e\u003csvg viewBox=\"0 0 24 24\" width=\"26\" height=\"26\" aria-hidden=\"true\"\u003e\u003cpath d=\"M12 3 3 20h18Z\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linejoin=\"round\"\/\u003e\u003cpath d=\"M12 10v4M12 17v.5\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"\/\u003e\u003c\/svg\u003e\u003cb\u003eCracked? Replace it\u003c\/b\u003e\u003cspan\u003eA split basket or one missing its handle lets debris through to the pump.\u003c\/span\u003e\u003c\/li\u003e\n      \u003c\/ul\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"afi-ap-dots afi-ap-x\" hidden aria-hidden=\"true\"\u003e\u003c\/div\u003e\n  \u003c\/section\u003e\n\n  \u003ch2 class=\"afi-ap-h\"\u003eSpecifications\u003c\/h2\u003e\n  \u003cdl class=\"afi-ap-spec\"\u003e\n    \u003cdiv\u003e\u003cdt\u003eProduct\u003c\/dt\u003e\u003cdd\u003ePool skimmer basket, Waterway style\u003c\/dd\u003e\u003c\/div\u003e\n    \u003cdiv\u003e\u003cdt\u003eBrand\u003c\/dt\u003e\u003cdd\u003eCMP\u003c\/dd\u003e\u003c\/div\u003e\n    \u003cdiv\u003e\u003cdt\u003eManufacturer no.\u003c\/dt\u003e\u003cdd\u003e25140-000-900\u003c\/dd\u003e\u003c\/div\u003e\n    \u003cdiv\u003e\u003cdt\u003eReplaces\u003c\/dt\u003e\u003cdd\u003eWaterway 542-3240\u003c\/dd\u003e\u003c\/div\u003e\n    \u003cdiv\u003e\u003cdt\u003eColour\u003c\/dt\u003e\u003cdd\u003eWhite\u003c\/dd\u003e\u003c\/div\u003e\n    \u003cdiv\u003e\u003cdt\u003eDimensions\u003c\/dt\u003e\u003cdd\u003eTop 8-1\/4 in at the rim, bottom 5-7\/8 in, height 5-1\/8 in\u003c\/dd\u003e\u003c\/div\u003e\n  \u003c\/dl\u003e\n\n  \u003cdiv class=\"afi-ap-cols\"\u003e\n  \u003cdiv\u003e\n  \u003ch2 class=\"afi-ap-h\"\u003eReplacing it\u003c\/h2\u003e\n  \u003col class=\"afi-ap-steps\"\u003e\n    \u003cli\u003eTurn off the pump.\u003c\/li\u003e\n    \u003cli\u003eRemove the skimmer lid and lift the old basket out by its handle.\u003c\/li\u003e\n    \u003cli\u003eClear any debris left at the bottom of the skimmer.\u003c\/li\u003e\n    \u003cli\u003eSet the new basket flat in its seat, then put the lid back on.\u003c\/li\u003e\n    \u003cli\u003eRestart the pump and check that the water flows normally.\u003c\/li\u003e\n  \u003c\/ol\u003e\n  \u003c\/div\u003e\n  \u003cdiv\u003e\n  \u003ch2 class=\"afi-ap-h\"\u003eFrequently asked questions\u003c\/h2\u003e\n  \u003cdiv class=\"afi-ap-faq\"\u003e\n    \u003ch3\u003eWill it fit my skimmer?\u003c\/h3\u003e\n    \u003cp\u003eIt replaces the Waterway 542-3240 basket, the one used in Renegade in-ground skimmers. Retailers disagree on which versions it covers (vinyl liner, fibreglass or concrete), so go by the measurements of your current basket, or send us a photo of your skimmer.\u003c\/p\u003e\n    \u003ch3\u003eIs it an original Waterway part?\u003c\/h3\u003e\n    \u003cp\u003eNo. It is made by CMP, which lists it as the equivalent of the Waterway 542-3240.\u003c\/p\u003e\n    \u003ch3\u003eWhen should the basket be replaced?\u003c\/h3\u003e\n    \u003cp\u003eAs soon as it is cracked, its handle is broken or it no longer sits flat: debris then gets through to the pump.\u003c\/p\u003e\n  \u003c\/div\u003e\n  \u003c\/div\u003e\n  \u003c\/div\u003e\n\n  \u003cdiv class=\"afi-ap-contact\"\u003e\n    \u003cdiv\u003e\u003cb\u003eNot sure it's the right basket?\u003c\/b\u003e\u003cspan\u003eSend us a photo of your skimmer or your current basket. We'll confirm before you order.\u003c\/span\u003e\u003c\/div\u003e\n    \u003ca class=\"afi-ap-btn\" href=\"mailto:commercial@aquafibreinnovation.ca\"\u003eEmail us\u003c\/a\u003e\n    \u003ca class=\"afi-ap-btn afi-ap-btn2\" href=\"tel:+14188710658\"\u003e(418) 871-0658\u003c\/a\u003e\n  \u003c\/div\u003e\n\n\u003c\/div\u003e\n\u003cstyle\u003e\n.afi-ap{--fg:#1d1d1f;--fg2:#424a53;--fg3:#5f6873;--line:#d9dde2;--bg2:#f5f6f8;--bg3:#ffffff;--blue:#0b72b9;--bluet:#0a66a6;--navy:#0d2b45;--lever:#2a2f35;--ok:#1d7a4c;--warn:#a65a00;--bad:#c0392b;--glass:rgba(255,255,255,.16);--glassb:rgba(255,255,255,.34);\n  max-width:680px;container:afiap\/inline-size;color:var(--fg);font-family:-apple-system,BlinkMacSystemFont,\"SF Pro Text\",\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif;font-size:17px;line-height:1.55;letter-spacing:-.01em;font-optical-sizing:auto;-webkit-font-smoothing:antialiased;}\n.afi-ap,.afi-ap *{box-sizing:border-box;}\n.afi-ap p{margin:0 0 16px;}\n.afi-ap b{font-weight:600;}\n.afi-ap a{color:var(--bluet);text-decoration:underline;text-underline-offset:2px;}\n.afi-ap .afi-ap-eyebrow{margin:0 0 8px;font-size:13px;line-height:1.3;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--blue);}\n.afi-ap .afi-ap-lede{margin:0 0 18px;font-size:34px;line-height:1.1;font-weight:700;letter-spacing:-.022em;color:var(--fg);}\n.afi-ap .afi-ap-intro{color:var(--fg2);}\n.afi-ap .afi-ap-nums{display:grid;grid-template-columns:repeat(4,1fr);margin:32px 0 48px;}\n.afi-ap .afi-ap-nums div{padding:4px 8px;text-align:center;}\n.afi-ap .afi-ap-nums div+div{border-left:1px solid var(--line);}\n.afi-ap .afi-ap-nums b,.afi-ap .afi-ap-vinfo b{display:block;font-size:28px;line-height:1.05;font-weight:700;letter-spacing:-.02em;color:var(--fg);white-space:nowrap;font-variant-numeric:tabular-nums;}\n.afi-ap .afi-ap-nums span{display:block;margin-top:6px;font-size:13px;line-height:1.35;letter-spacing:.005em;color:var(--fg3);}\n.afi-ap .afi-ap-h{margin:0 0 10px;font-family:inherit;font-size:26px;line-height:1.18;font-weight:700;letter-spacing:-.018em;color:var(--fg);}\n.afi-ap .afi-ap-sub{color:var(--fg2);margin-bottom:22px;}\n.afi-ap .afi-ap-mod{margin:0 0 48px;container:afimod\/inline-size;}\n.afi-ap .afi-ap-mod[hidden],.afi-ap .afi-ap-x[hidden]{display:none;}\n.afi-ap .afi-ap-rail{position:relative;height:56px;margin:0;padding:0 24px;border-radius:0 0 20px 20px;background:var(--bg2);cursor:pointer;touch-action:pan-y;user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:transparent;outline:none;}\n.afi-ap .afi-ap-track{position:absolute;left:24px;right:24px;top:26px;height:4px;border-radius:2px;background:var(--line);}\n.afi-ap .afi-ap-tfill{position:absolute;left:0;top:0;bottom:0;width:100%;border-radius:2px;background:var(--blue);transform-origin:0 50%;transform:scaleX(.375);will-change:transform;}\n.afi-ap .afi-ap-tick{position:absolute;top:26px;width:4px;height:4px;margin-left:-2px;border-radius:50%;background:rgba(0,0,0,.22);pointer-events:none;}\n.afi-ap .afi-ap-tsep{position:absolute;top:20px;width:2px;height:16px;margin-left:-1px;border-radius:1px;background:var(--fg3);opacity:.55;pointer-events:none;}\n.afi-ap .afi-ap-knob{position:absolute;left:24px;top:14px;width:28px;height:28px;margin-left:-14px;border-radius:50%;background:#fff;box-shadow:0 0 0 .5px rgba(0,0,0,.08),0 2px 8px rgba(0,0,0,.18),0 1px 2px rgba(0,0,0,.12);will-change:transform;transition:box-shadow .1s ease-out;}\n.afi-ap .afi-ap-rail.afi-ap-on .afi-ap-knob{box-shadow:0 0 0 .5px rgba(0,0,0,.08),0 4px 14px rgba(0,0,0,.22),0 0 0 6px rgba(11,114,185,.16);}\n.afi-ap .afi-ap-rail:focus-visible .afi-ap-knob{box-shadow:0 0 0 3px #fff,0 0 0 5px var(--blue);}\n.afi-ap .afi-ap-ends{display:flex;justify-content:space-between;gap:12px;margin:10px 4px 0;font-size:13px;line-height:1.35;letter-spacing:.005em;color:var(--fg3);}\n.afi-ap .afi-ap-ends span+span{text-align:right;}\n.afi-ap .afi-ap-note{margin:14px 4px 0;font-size:13px;line-height:1.5;letter-spacing:.005em;color:var(--fg3);}\n\/* Bande atouts *\/\n.afi-ap .afi-ap-band{position:relative;margin:0 0 48px;padding:28px 0 24px;border-radius:24px;color:#fff;background:radial-gradient(120% 90% at 0% 0%,#1f5a8a 0%,rgba(31,90,138,0) 60%),radial-gradient(90% 80% at 100% 100%,#0b72b9 0%,rgba(11,114,185,0) 55%),#0d2b45;overflow:hidden;}\n.afi-ap .afi-ap-bandtop{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:0 28px;margin-bottom:18px;}\n.afi-ap .afi-ap-hw{margin:0;color:#fff;}\n.afi-ap .afi-ap-nav{display:flex;gap:8px;}\n.afi-ap .afi-ap-nav button{display:flex;align-items:center;justify-content:center;width:36px;height:36px;margin:0;padding:0;border:0;border-radius:50%;color:#fff;background:var(--glass);-webkit-backdrop-filter:blur(20px) saturate(180%);backdrop-filter:blur(20px) saturate(180%);box-shadow:inset 0 1px 0 var(--glassb);cursor:pointer;-webkit-appearance:none;appearance:none;-webkit-tap-highlight-color:transparent;transition:opacity .2s ease;}\n.afi-ap .afi-ap-nav button[disabled]{opacity:.35;cursor:default;}\n.afi-ap .afi-ap-nav button:focus-visible{outline:2px solid #fff;outline-offset:2px;}\n.afi-ap .afi-ap-vp{padding:0 28px;}\n.afi-ap .afi-ap-cards{display:grid;grid-template-columns:1fr 1fr;gap:20px 28px;margin:0;padding:0;list-style:none;}\n.afi-ap .afi-ap-cards li{margin:0;padding:0;}\n.afi-ap .afi-ap-cards svg{display:block;margin-bottom:10px;color:#8ccaf2;}\n.afi-ap .afi-ap-cards b{display:block;margin-bottom:4px;font-size:17px;line-height:1.3;letter-spacing:-.01em;color:#fff;}\n.afi-ap .afi-ap-cards span{display:block;font-size:15px;line-height:1.5;letter-spacing:0;color:#d3e2ee;}\n.afi-ap.afi-ap-js .afi-ap-vp{padding:0;overflow:hidden;touch-action:pan-y;cursor:grab;}\n.afi-ap.afi-ap-js .afi-ap-vp.afi-ap-drag{cursor:grabbing;}\n.afi-ap.afi-ap-js .afi-ap-cards{display:flex;gap:14px;padding:0 28px;width:max-content;will-change:transform;user-select:none;-webkit-user-select:none;}\n.afi-ap.afi-ap-js .afi-ap-cards li{flex:0 0 auto;width:260px;min-height:186px;padding:20px;border-radius:18px;background:rgba(255,255,255,.08);box-shadow:inset 0 1px 0 rgba(255,255,255,.14);}\n.afi-ap .afi-ap-dots{display:flex;justify-content:center;gap:8px;margin-top:18px;}\n.afi-ap .afi-ap-dots i{width:7px;height:7px;border-radius:50%;background:rgba(255,255,255,.32);transition:background-color .25s ease,transform .25s ease;}\n.afi-ap .afi-ap-dots i.afi-ap-cur{background:#fff;transform:scale(1.15);}\n\/* Fiche technique, en liste groupée *\/\n.afi-ap .afi-ap-spec{margin:6px 0 48px;padding:0 0 0 18px;border-radius:16px;background:var(--bg2);}\n.afi-ap .afi-ap-spec div{display:flex;justify-content:space-between;gap:16px;padding:13px 18px 13px 0;}\n.afi-ap .afi-ap-spec div+div{border-top:.5px solid var(--line);}\n.afi-ap .afi-ap-spec dt{flex:0 0 auto;margin:0;font-size:15px;color:var(--fg3);}\n.afi-ap .afi-ap-spec dd{margin:0;font-size:15px;font-weight:600;text-align:right;color:var(--fg);}\n.afi-ap .afi-ap-steps{margin:6px 0 16px;padding:0;list-style:none;counter-reset:afiap;}\n.afi-ap .afi-ap-steps li{position:relative;margin:0 0 12px;padding-left:40px;font-size:16px;line-height:1.5;color:var(--fg2);counter-increment:afiap;}\n.afi-ap .afi-ap-steps li::before{content:counter(afiap);position:absolute;left:0;top:-1px;width:26px;height:26px;border-radius:50%;background:var(--bg2);color:var(--blue);font-size:13px;font-weight:700;line-height:26px;text-align:center;}\n.afi-ap .afi-ap-small{font-size:13px;line-height:1.55;letter-spacing:.005em;color:var(--fg3);}\n.afi-ap .afi-ap-steps+.afi-ap-small{margin-bottom:48px;}\n.afi-ap .afi-ap-faq{margin:6px 0 0;}\n.afi-ap .afi-ap-faq h3{margin:0;padding:18px 0 6px;border-top:.5px solid var(--line);font-family:inherit;font-size:17px;line-height:1.35;font-weight:600;letter-spacing:-.01em;color:var(--fg);}\n.afi-ap .afi-ap-faq p{margin:0 0 6px;font-size:16px;color:var(--fg2);}\n.afi-ap .afi-ap-contact{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-top:40px;padding:24px;border-radius:20px;background:var(--bg2);}\n.afi-ap .afi-ap-contact div{flex:1 1 240px;}\n.afi-ap .afi-ap-contact b{display:block;font-size:19px;line-height:1.3;letter-spacing:-.015em;color:var(--fg);}\n.afi-ap .afi-ap-contact span{display:block;margin-top:4px;font-size:15px;color:var(--fg2);}\n.afi-ap a.afi-ap-btn{display:inline-block;padding:11px 20px;border-radius:980px;background:var(--blue);color:#fff;font-size:15px;font-weight:600;letter-spacing:-.005em;text-decoration:none;white-space:nowrap;-webkit-tap-highlight-color:transparent;}\n.afi-ap a.afi-ap-btn2{background:transparent;color:var(--bluet);box-shadow:inset 0 0 0 1px var(--line);}\n.afi-ap a.afi-ap-btn:hover{background:#0a67a7;}\n.afi-ap a.afi-ap-btn2:hover{background:rgba(11,114,185,.06);}\n\/* Retour au toucher : immédiat, à l'appui *\/\n.afi-ap a.afi-ap-btn,.afi-ap .afi-ap-pos button,.afi-ap .afi-ap-nav button{transition:transform .1s ease-out,background-color .2s ease,opacity .2s ease,color .2s ease;}\n.afi-ap a.afi-ap-btn:active,.afi-ap .afi-ap-pos button:active,.afi-ap .afi-ap-nav button:not([disabled]):active{transform:scale(.97);}\n\/* Apparition au défilement *\/\n@media (prefers-reduced-motion:no-preference){\n.afi-ap.afi-ap-js .afi-ap-rv{opacity:0;transform:translateY(18px);transition:opacity .6s cubic-bezier(.22,1,.36,1),transform .7s cubic-bezier(.22,1,.36,1);}\n.afi-ap.afi-ap-js .afi-ap-rv.afi-ap-in{opacity:1;transform:none;}\n}\n@media (prefers-reduced-motion:reduce){\n.afi-ap.afi-ap-js .afi-ap-rv{opacity:0;transition:opacity .2s ease;}\n.afi-ap.afi-ap-js .afi-ap-rv.afi-ap-in{opacity:1;}\n.afi-ap a.afi-ap-btn:active,.afi-ap .afi-ap-pos button:active,.afi-ap .afi-ap-nav button:active{transform:none;}\n}\n\/* Modules étroits (cellulaire, ou côte à côte sur ordinateur) *\/\n@container afimod (max-width:500px){\n.afi-ap .afi-ap-rail{padding:0 18px;}\n.afi-ap .afi-ap-meter{padding:4px 18px 8px;}\n.afi-ap .afi-ap-track{left:18px;right:18px;}\n.afi-ap .afi-ap-knob{left:18px;}\n}\n@container afimod (max-width:400px){\n.afi-ap .afi-ap-ends{flex-direction:column;gap:2px;}\n.afi-ap .afi-ap-ends span+span{text-align:left;}\n}\n@container afiap (max-width:560px){\n.afi-ap .afi-ap-intro,.afi-ap .afi-ap-faq p{font-size:16px;}\n.afi-ap .afi-ap-lede{font-size:28px;line-height:1.12;letter-spacing:-.02em;}\n.afi-ap .afi-ap-h{font-size:22px;line-height:1.2;letter-spacing:-.015em;}\n.afi-ap .afi-ap-nums{grid-template-columns:1fr 1fr;row-gap:22px;}\n.afi-ap .afi-ap-nums div:nth-child(3){border-left:0;}\n.afi-ap .afi-ap-nums b{font-size:24px;}\n.afi-ap .afi-ap-band{border-radius:20px;padding:24px 0 20px;}\n.afi-ap .afi-ap-bandtop,.afi-ap .afi-ap-vp{padding:0 18px;}\n.afi-ap .afi-ap-cards{grid-template-columns:1fr;}\n.afi-ap.afi-ap-js .afi-ap-cards{padding:0 18px;gap:12px;}\n.afi-ap.afi-ap-js .afi-ap-cards li{width:240px;min-height:200px;padding:18px;}\n.afi-ap .afi-ap-spec div{flex-wrap:wrap;gap:2px 16px;}\n.afi-ap .afi-ap-spec dd{text-align:left;}\n}\n\/* Pleine largeur : quand la fiche passe sous les photos *\/\n.afi-ap-wide{margin-top:72px;}\n.afi-ap-wide .afi-ap{max-width:1040px;margin:0 auto;}\n@container afiap (min-width:820px){\n.afi-ap .afi-ap-eyebrow,.afi-ap .afi-ap-lede,.afi-ap .afi-ap-intro{text-align:center;margin-left:auto;margin-right:auto;}\n.afi-ap .afi-ap-lede{max-width:820px;font-size:52px;line-height:1.06;letter-spacing:-.028em;}\n.afi-ap .afi-ap-intro{max-width:680px;font-size:19px;line-height:1.55;}\n.afi-ap .afi-ap-nums{max-width:820px;margin:48px auto 72px;}\n.afi-ap .afi-ap-nums b{font-size:40px;letter-spacing:-.025em;}\n.afi-ap .afi-ap-nums span{font-size:14px;}\n.afi-ap .afi-ap-h{font-size:32px;line-height:1.14;letter-spacing:-.022em;}\n.afi-ap .afi-ap-duo{display:grid;grid-template-columns:1fr 1fr;gap:40px;align-items:start;margin-bottom:72px;}\n.afi-ap .afi-ap-duo .afi-ap-mod{margin:0;}\n.afi-ap .afi-ap-band{margin-bottom:72px;padding:36px 0 28px;border-radius:28px;}\n.afi-ap .afi-ap-bandtop,.afi-ap .afi-ap-vp{padding:0 36px;}\n.afi-ap.afi-ap-js .afi-ap-vp{padding:0;}\n.afi-ap.afi-ap-js .afi-ap-cards{padding:0 36px;gap:16px;}\n.afi-ap.afi-ap-js .afi-ap-cards li{width:290px;}\n.afi-ap .afi-ap-cards{grid-template-columns:1fr 1fr 1fr;}\n.afi-ap .afi-ap-spec{display:grid;grid-template-columns:1fr 1fr;column-gap:36px;padding:0 0 0 22px;margin-bottom:72px;}\n.afi-ap .afi-ap-spec div+div{border-top:0;}\n.afi-ap .afi-ap-spec div:nth-child(n+3){border-top:.5px solid var(--line);}\n.afi-ap .afi-ap-cols{display:grid;grid-template-columns:1fr 1fr;gap:56px;align-items:start;}\n.afi-ap .afi-ap-steps+.afi-ap-small{margin-bottom:0;}\n.afi-ap .afi-ap-contact{margin-top:72px;padding:32px 36px;border-radius:28px;}\n}\n@media (prefers-color-scheme:dark){\nhtml body .afi-ap{--fg:#f2f3f5;--fg2:#c5ccd3;--fg3:#9aa5b0;--line:#38424c;--bg2:#1c242c;--bg3:#232c35;--bluet:#5aaee8;--lever:#0e1216;--ok:#5fd08f;--warn:#f0a23a;--bad:#ff7a6b;color:var(--fg);}\nhtml body .afi-ap .afi-ap-pl,html body .afi-ap .afi-ap-eyebrow,html body .afi-ap .afi-ap-steps li::before{color:#5aaee8;}\nhtml body .afi-ap .afi-ap-tick{background:rgba(255,255,255,.28);}\nhtml body .afi-ap .afi-ap-band{background:radial-gradient(120% 90% at 0% 0%,#18466c 0%,rgba(24,70,108,0) 60%),radial-gradient(90% 80% at 100% 100%,#0a5a92 0%,rgba(10,90,146,0) 55%),#0c1f31;box-shadow:inset 0 0 0 1px #23415c;}\nhtml body .afi-ap a.afi-ap-btn{background:#0b72b9;color:#fff;}\nhtml body .afi-ap a.afi-ap-btn2{background:transparent;color:#5aaee8;box-shadow:inset 0 0 0 1px #3a5268;}\nhtml body .afi-ap .afi-ap-rail:focus-visible .afi-ap-knob{box-shadow:0 0 0 3px #12161a,0 0 0 5px #5aaee8;}\n}\n@media (prefers-reduced-transparency:reduce){\n.afi-ap .afi-ap-nav button{background:#24557f;-webkit-backdrop-filter:none;backdrop-filter:none;}\n.afi-ap.afi-ap-js .afi-ap-cards li{background:#173a5a;}\n}\n@media (prefers-contrast:more){\n.afi-ap{--fg2:#1d1d1f;--fg3:#3d454d;--line:#7b848d;}\n.afi-ap .afi-ap-nav button{background:#0d2b45;box-shadow:inset 0 0 0 1px #fff;-webkit-backdrop-filter:none;backdrop-filter:none;}\n.afi-ap.afi-ap-js .afi-ap-cards li{background:#0d2b45;box-shadow:inset 0 0 0 1px rgba(255,255,255,.6);}\n.afi-ap .afi-ap-spec,.afi-ap .afi-ap-valve,.afi-ap .afi-ap-speed,.afi-ap .afi-ap-rail,.afi-ap .afi-ap-pos button{box-shadow:inset 0 0 0 1px var(--line);}\n}\n\/* Bascule à deux états : pouce à ressort, textes et schéma qui changent avec l'état *\/\n.afi-ap .afi-ap-seg{position:relative;display:flex;width:320px;max-width:100%;padding:3px;margin:0 0 18px;border-radius:12px;background:#e6e8ec;touch-action:pan-y;user-select:none;-webkit-user-select:none;}\n.afi-ap .afi-ap-segthumb{position:absolute;top:3px;left:3px;bottom:3px;width:calc(50% - 3px);border-radius:9px;background:#fff;box-shadow:0 3px 8px rgba(0,0,0,.12),0 0 0 .5px rgba(0,0,0,.04);will-change:transform;}\n.afi-ap .afi-ap-seg button{position:relative;flex:1 1 0;margin:0;padding:8px 4px;border:0;border-radius:9px;background:none;font:inherit;font-size:14px;line-height:1.3;font-weight:600;letter-spacing:-.005em;color:var(--fg2);cursor:pointer;-webkit-appearance:none;appearance:none;-webkit-tap-highlight-color:transparent;transition:color .2s ease,transform .1s ease-out;}\n.afi-ap .afi-ap-seg button[aria-checked=\"true\"]{color:var(--fg);}\n.afi-ap .afi-ap-seg button:active{transform:scale(.97);}\n.afi-ap .afi-ap-seg button:focus-visible{outline:2px solid var(--blue);outline-offset:1px;}\n.afi-ap .afi-ap-bbox{display:flex;align-items:center;gap:24px;padding:20px 24px;border-radius:20px;background:var(--bg2);}\n.afi-ap .afi-ap-bfig{flex:0 0 200px;}\n.afi-ap .afi-ap-bfig svg{display:block;width:100%;height:auto;}\n.afi-ap .afi-ap-btxt{flex:1 1 auto;min-width:0;font-size:15px;line-height:1.55;color:var(--fg2);}\n.afi-ap .afi-ap-btxt b{display:block;margin-bottom:4px;font-size:19px;line-height:1.3;color:var(--fg);}\n.afi-ap .afi-ap-btxt p{margin:0;}\n\/* Schéma du filtre : l'eau passe par la cartouche, ou contourne par la soupape *\/\n.afi-ap .afi-ap-tank{fill:var(--bg3);stroke:var(--fg3);stroke-width:1.5;}\n.afi-ap .afi-ap-cart{fill:#dfe9f2;stroke:var(--fg3);stroke-width:1;transition:fill .4s ease;}\n.afi-ap .afi-ap-pleat{stroke:var(--fg3);stroke-width:1;opacity:.45;}\n.afi-ap .afi-ap-flow{fill:none;stroke-width:3;stroke-linecap:round;stroke-dasharray:6 7;transition:opacity .4s ease;}\n.afi-ap .afi-ap-thru{stroke:var(--blue);}\n.afi-ap .afi-ap-byp{stroke:var(--warn);opacity:0;}\n.afi-ap .afi-ap-flap{fill:var(--fg3);transform-box:fill-box;transform-origin:0% 50%;transition:transform .45s cubic-bezier(.34,1.4,.64,1);}\n.afi-ap [data-state=\"1\"] .afi-ap-cart{fill:#c9b89a;}\n.afi-ap [data-state=\"1\"] .afi-ap-thru{opacity:.35;}\n.afi-ap [data-state=\"1\"] .afi-ap-byp{opacity:1;}\n.afi-ap [data-state=\"1\"] .afi-ap-flap{transform:rotate(-38deg);}\n@media (prefers-reduced-motion:no-preference){\n.afi-ap.afi-ap-js .afi-ap-flow{animation:afiApFlow 1s linear infinite;}\n}\n@keyframes afiApFlow{to{stroke-dashoffset:-13;}}\n@container afimod (max-width:460px){\n.afi-ap .afi-ap-bbox{flex-direction:column;align-items:flex-start;padding:18px;}\n.afi-ap .afi-ap-bfig{flex-basis:auto;width:180px;align-self:center;}\n}\n@container afiap (min-width:820px){.afi-ap .afi-ap-mod[data-mod=\"bascule\"]{max-width:760px;margin:0 auto 72px;}}\n@media (prefers-color-scheme:dark){\nhtml body .afi-ap .afi-ap-seg{background:#2a333c;}\nhtml body .afi-ap .afi-ap-segthumb{background:#55606b;box-shadow:0 3px 8px rgba(0,0,0,.4);}\nhtml body .afi-ap .afi-ap-cart{fill:#2c3f52;}\nhtml body .afi-ap [data-state=\"1\"] .afi-ap-cart{fill:#5b4a33;}\nhtml body .afi-ap .afi-ap-thru{stroke:#5aaee8;}\n}\n@media (prefers-reduced-motion:reduce){.afi-ap .afi-ap-seg button:active{transform:none;}.afi-ap .afi-ap-flap{transition:none;}}\n@media (prefers-contrast:more){.afi-ap .afi-ap-bbox{box-shadow:inset 0 0 0 1px var(--line);}}\n\/* Schéma coté du panier (bascule pouces \/ centimètres) *\/\n.afi-ap .afi-ap-bkfig{flex-basis:270px;}\n.afi-ap .afi-ap-bk{fill:var(--bg3);stroke:var(--fg3);stroke-width:1.5;stroke-linejoin:round;}\n.afi-ap .afi-ap-bkslot{fill:none;stroke:var(--fg3);stroke-width:1;opacity:.4;}\n.afi-ap .afi-ap-bkrim{fill:none;stroke:var(--fg3);stroke-width:4;stroke-linecap:round;}\n.afi-ap .afi-ap-dim{fill:none;stroke:var(--bluet);stroke-width:1.2;}\n.afi-ap .afi-ap-dt{fill:var(--fg);font-size:12px;font-weight:600;letter-spacing:0;font-variant-numeric:tabular-nums;}\n@container afimod (max-width:460px){.afi-ap .afi-ap-bkfig{flex-basis:auto;width:256px;max-width:100%;}}\n\u003c\/style\u003e\n\u003cscript\u003e\n(function(){\n  var RM = window.matchMedia \u0026\u0026 matchMedia('(prefers-reduced-motion: reduce)').matches;\n\n  \/* Ressort amorti (réglage façon Apple : amortissement + réponse). Il part toujours\n     de la valeur affichée et garde sa vitesse quand on change de cible. *\/\n  function Spring(x, onUpdate){\n    this.x = x; this.v = 0; this.t = x; this.d = 1; this.r = .4; this.id = 0; this.cb = onUpdate;\n  }\n  Spring.prototype.stop = function(){ cancelAnimationFrame(this.id); this.id = 0; };\n  Spring.prototype.set = function(x){ this.stop(); this.x = this.t = x; this.v = 0; this.cb(x); };\n  Spring.prototype.to = function(t, o){\n    o = o || {};\n    this.t = t; this.d = o.damping || 1; this.r = o.response || .4;\n    if (o.velocity !== undefined) this.v = o.velocity;\n    if (RM) { this.set(t); return; }\n    if (this.id) return;\n    var s = this, last = performance.now();\n    function f(now){\n      var dt = Math.min((now - last) \/ 1000, 1 \/ 30), n = 4, h = dt \/ n; last = now;\n      var k = Math.pow(2 * Math.PI \/ s.r, 2), c = 4 * Math.PI * s.d \/ s.r;\n      for (var i = 0; i \u003c n; i++){ s.v += (-k * (s.x - s.t) - c * s.v) * h; s.x += s.v * h; }\n      if (Math.abs(s.x - s.t) \u003c .2 \u0026\u0026 Math.abs(s.v) \u003c 4){ s.x = s.t; s.v = 0; s.id = 0; s.cb(s.x); return; }\n      s.cb(s.x); s.id = requestAnimationFrame(f);\n    }\n    this.id = requestAnimationFrame(f);\n  };\n\n  \/* Vitesse du doigt sur les 100 dernières ms (unités\/s) *\/\n  function Tracker(){ this.p = []; }\n  Tracker.prototype.add = function(x){ var t = performance.now(); this.p.push([x, t]); while (this.p.length \u003e 2 \u0026\u0026 t - this.p[0][1] \u003e 100) this.p.shift(); };\n  Tracker.prototype.v = function(){ var p = this.p; if (p.length \u003c 2) return 0; var a = p[0], b = p[p.length - 1], dt = b[1] - a[1]; return dt \u003e 0 ? (b[0] - a[0]) \/ dt * 1000 : 0; };\n  \/* Projection d'élan d'Apple ; 0,998 pour un défilement, 0,99 pour un cran plus sec *\/\n  function project(v, rate){ rate = rate || .998; return v \/ 1000 * rate \/ (1 - rate); }\n  \/* Résistance élastique au-delà d'une limite *\/\n  function rubber(o, dim){ var c = .55; return o * dim * c \/ (dim + c * Math.abs(o)); }\n  function clampRubber(x, min, max, dim){ return x \u003c min ? min + rubber(x - min, dim) : x \u003e max ? max + rubber(x - max, dim) : x; }\n  function haptic(){ if (navigator.vibrate) try { navigator.vibrate(8); } catch (e) {} }\n  var sp3 = function(n){ return String(n).replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, '\u0026nbsp;'); };\n\n  var MODS = {};\n  \/* Bascule à deux états. Les éléments [data-t0][data-t1] reçoivent le texte de l'état choisi ;\n     data-state sur la section pilote le schéma en CSS. Pouce à ressort, glissé avec élan, clavier. *\/\n  MODS['bascule'] = function(el){\n    var seg = el.querySelector('.afi-ap-seg'); if (!seg) return;\n    var thumb = seg.querySelector('.afi-ap-segthumb'), btns = seg.querySelectorAll('button'),\n        tgts = el.querySelectorAll('[data-t0]'), span = 1, cur = 0;\n    function measure(){ span = Math.max(seg.clientWidth - 6, 2) \/ 2; }\n    var sp = new Spring(0, function(x){ thumb.style.transform = 'translate3d(' + x + 'px,0,0)'; });\n    function commit(i){\n      if (i === cur) return;\n      var dir = i \u003e cur ? 1 : -1; cur = i;\n      el.setAttribute('data-state', i);\n      btns.forEach(function(b, j){ b.setAttribute('aria-checked', j === i ? 'true' : 'false'); b.tabIndex = j === i ? 0 : -1; });\n      tgts.forEach(function(t){\n        t.innerHTML = t.getAttribute('data-t' + i);\n        if (!RM \u0026\u0026 t.animate) t.animate([{ opacity: 0, transform: 'translateX(' + (dir * 10) + 'px)' }, { opacity: 1, transform: 'none' }], { duration: 260, easing: 'cubic-bezier(.22,1,.36,1)' });\n      });\n      haptic();                                                            \/\/ à la même image que le changement\n    }\n    el.setAttribute('data-state', 0);\n    measure();\n    var drag = null, tr = new Tracker(), moved = false;\n    seg.addEventListener('pointerdown', function(e){\n      if (e.button \u0026\u0026 e.button !== 0) return;\n      measure(); sp.stop();\n      var r = seg.getBoundingClientRect(), px = e.clientX - r.left - 3;\n      drag = { id: e.pointerId, sx: e.clientX, sy: e.clientY, base: sp.x, onThumb: px \u003e= sp.x \u0026\u0026 px \u003c= sp.x + span, locked: false };\n      tr = new Tracker(); tr.add(sp.x); moved = false;\n    });\n    seg.addEventListener('pointermove', function(e){\n      if (!drag || e.pointerId !== drag.id || !drag.onThumb) return;\n      var dx = e.clientX - drag.sx, dy = e.clientY - drag.sy;\n      if (!drag.locked){\n        if (Math.hypot(dx, dy) \u003c 10) return;\n        if (Math.abs(dy) \u003e Math.abs(dx)){ drag = null; return; }\n        drag.locked = true; moved = true; seg.setPointerCapture(e.pointerId);\n        drag.sx = e.clientX; drag.base = sp.x; dx = 0;\n      }\n      var x = clampRubber(drag.base + dx, 0, span, span);\n      sp.x = x; sp.cb(x); tr.add(x);\n      commit(x \u003e span \/ 2 ? 1 : 0);\n    });\n    function end(e){\n      if (!drag || e.pointerId !== drag.id) { drag = null; return; }\n      var d = drag; drag = null;\n      if (!d.locked) return;\n      var v = tr.v(), i = sp.x + project(v) \u003e span \/ 2 ? 1 : 0;\n      commit(i);\n      sp.to(i * span, { damping: Math.abs(v) \u003e 300 ? .8 : 1, response: .3, velocity: v });\n    }\n    seg.addEventListener('pointerup', end);\n    seg.addEventListener('pointercancel', function(e){ if (drag \u0026\u0026 drag.locked) end(e); else drag = null; });\n    btns.forEach(function(b, i){\n      b.addEventListener('click', function(){ if (moved) { moved = false; return; } measure(); commit(i); sp.to(i * span, { response: .3 }); });\n    });\n    seg.addEventListener('keydown', function(e){\n      var i = e.key === 'ArrowRight' || e.key === 'ArrowDown' ? 1 : e.key === 'ArrowLeft' || e.key === 'ArrowUp' ? 0 : -1;\n      if (i \u003c 0) return; e.preventDefault(); measure(); commit(i); btns[i].focus(); sp.to(i * span, { response: .3 });\n    });\n    function relayout(){ measure(); sp.set(cur * span); }\n    if ('ResizeObserver' in window) new ResizeObserver(relayout).observe(seg); else window.addEventListener('resize', relayout);\n  };\n  function carousel(root){\n    var EN = (root.closest('.afi-ap') || root).getAttribute('lang') === 'en';\n    var vp = root.querySelector('.afi-ap-vp'), list = root.querySelector('.afi-ap-cards'); if (!vp || !list) return;\n    var cards = list.children, prev = root.querySelector('.afi-ap-prev'), next = root.querySelector('.afi-ap-next'),\n        dotsBox = root.querySelector('.afi-ap-dots'), dots = [], snaps = [], minX = 0, idx = 0;\n    for (var i = 0; i \u003c cards.length; i++){\n      cards[i].setAttribute('role', 'group'); cards[i].setAttribute('aria-roledescription', EN ? 'slide' : 'diapositive');\n      cards[i].setAttribute('aria-label', (i + 1) + (EN ? ' of ' : ' sur ') + cards.length);\n      dots.push(dotsBox.appendChild(document.createElement('i')));\n    }\n    vp.setAttribute('role', 'region'); vp.setAttribute('aria-roledescription', EN ? 'carousel' : 'carrousel'); vp.setAttribute('aria-label', (root.querySelector('.afi-ap-h') || {}).textContent || ''); vp.tabIndex = 0;\n    function measure(){\n      var padL = cards[0].offsetLeft; minX = Math.min(0, vp.clientWidth - list.scrollWidth);\n      snaps = []; for (var i = 0; i \u003c cards.length; i++){ var s = Math.max(minX, -(cards[i].offsetLeft - padL)); if (!snaps.length || Math.abs(snaps[snaps.length - 1] - s) \u003e 1) snaps.push(s); }\n    }\n    function nearest(x){ var b = 0; for (var i = 1; i \u003c snaps.length; i++) if (Math.abs(snaps[i] - x) \u003c Math.abs(snaps[b] - x)) b = i; return b; }\n    function state(i){\n      idx = i;\n      prev.disabled = i === 0; next.disabled = i === snaps.length - 1;\n      dots.forEach(function(d, j){ d.style.display = j \u003c snaps.length ? '' : 'none'; d.className = j === i ? 'afi-ap-cur' : ''; });\n    }\n    var sp = new Spring(0, function(x){ list.style.transform = 'translate3d(' + x + 'px,0,0)'; });\n    function go(i, v){\n      i = Math.max(0, Math.min(snaps.length - 1, i)); state(i);\n      sp.to(snaps[i], { damping: v \u0026\u0026 Math.abs(v) \u003e 300 ? .8 : 1, response: .4, velocity: v || 0 });\n    }\n    measure(); state(0);\n    var drag = null, tr = new Tracker();\n    vp.addEventListener('pointerdown', function(e){\n      if (e.button \u0026\u0026 e.button !== 0) return;\n      sp.stop();                                                          \/\/ attrape la carte en plein vol\n      drag = { id: e.pointerId, sx: e.clientX, sy: e.clientY, base: sp.x, locked: false };\n      tr = new Tracker(); tr.add(sp.x);\n    });\n    vp.addEventListener('pointermove', function(e){\n      if (!drag || e.pointerId !== drag.id) return;\n      var dx = e.clientX - drag.sx, dy = e.clientY - drag.sy;\n      if (!drag.locked){\n        if (Math.hypot(dx, dy) \u003c 10) return;\n        if (Math.abs(dy) \u003e Math.abs(dx)){ drag = null; go(nearest(sp.x)); return; }\n        drag.locked = true; vp.setPointerCapture(e.pointerId); vp.classList.add('afi-ap-drag');\n        drag.sx = e.clientX; drag.base = sp.x; dx = 0;\n      }\n      var x = clampRubber(drag.base + dx, minX, 0, vp.clientWidth);\n      sp.x = x; sp.cb(x); tr.add(x);\n    });\n    function end(e){\n      if (!drag || e.pointerId !== drag.id) return;\n      var d = drag; drag = null; vp.classList.remove('afi-ap-drag');\n      var v = d.locked ? tr.v() : 0;\n      go(nearest(sp.x + project(v)), v);                                  \/\/ élan projeté, puis vitesse transmise\n    }\n    vp.addEventListener('pointerup', end);\n    vp.addEventListener('pointercancel', end);\n    prev.addEventListener('click', function(){ go(idx - 1); });\n    next.addEventListener('click', function(){ go(idx + 1); });\n    vp.addEventListener('keydown', function(e){\n      if (e.key === 'ArrowRight') { e.preventDefault(); go(idx + 1); }\n      else if (e.key === 'ArrowLeft') { e.preventDefault(); go(idx - 1); }\n    });\n    window.addEventListener('resize', function(){ measure(); var i = Math.min(idx, snaps.length - 1); state(i); sp.set(snaps[i]); });\n  }\n\n  function reveal(root){\n    if (!('IntersectionObserver' in window)) return;\n    var els = root.querySelectorAll('.afi-ap-eyebrow,.afi-ap-lede,.afi-ap-intro,.afi-ap-nums div,.afi-ap-mod,.afi-ap-band,.afi-ap-h,.afi-ap-spec,.afi-ap-steps li,.afi-ap-faq h3,.afi-ap-faq p,.afi-ap-contact');\n    var io = new IntersectionObserver(function(list){\n      var n = 0;\n      list.forEach(function(en){\n        if (!en.isIntersecting) return;\n        en.target.style.transitionDelay = Math.min(n++ * 70, 350) + 'ms';\n        en.target.classList.add('afi-ap-in'); io.unobserve(en.target);\n      });\n    }, { threshold: .1 });\n    els.forEach(function(el){ el.classList.add('afi-ap-rv'); io.observe(el); });\n  }\n\n  \/* Sur la page produit, la fiche passe sous les photos et prend toute la largeur.\n     Sans script, elle reste à sa place habituelle dans la colonne de droite. *\/\n  function widen(root){\n    var desc = root.closest('.product__description'), grid = desc \u0026\u0026 desc.closest('.product');\n    if (!grid || !grid.closest('product-info') || desc.closest('.quick-add-modal')) return;\n    desc.classList.add('afi-ap-wide');\n    grid.parentNode.insertBefore(desc, grid.nextSibling);\n  }\n\n  document.querySelectorAll('.afi-ap:not(.afi-ap-js)').forEach(function(root){\n    widen(root);\n    root.classList.add('afi-ap-js');\n    root.querySelectorAll('.afi-ap-x[hidden]').forEach(function(el){ el.hidden = false; });\n    root.querySelectorAll('[data-mod]').forEach(function(el){ var f = MODS[el.getAttribute('data-mod')]; if (f) f(el); });\n    var band = root.querySelector('.afi-ap-band'); if (band) carousel(band);\n    reveal(root);\n  });\n})();\n\u003c\/script\u003e\n","brand":"CMP","offers":[{"title":"Default Title","offer_id":67993939673387,"sku":"25140-000-900","price":19.99,"currency_code":"CAD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0968\/6168\/4011\/files\/daf7a2ca-4439-4ece-bce9-c6d2765727b5.png?v=1793741418","url":"https:\/\/boutique.aquafibreinnovation.ca\/en\/products\/cmp-panier-ecumoire-style-waterway-blanc","provider":"AQUA FIBRE INNOVATION","version":"1.0","type":"link"}