From 2971f5516dfc736b1844310e1f35ecbbfe73d6c2 Mon Sep 17 00:00:00 2001 From: gcch Date: Sun, 5 Apr 2026 13:11:21 +0200 Subject: [PATCH] 2026-04-05 --- .zed/settings.json | 14 ++- bun.lock | 44 ++++--- cfg/oxlint.config.ts | 10 +- cfg/playwright.config.ts | 36 +++--- cfg/stylelint.config.ts | 71 +++++++---- cfg/vite.config.ts | 2 +- composer.lock | 28 ++--- cspell.json | 3 +- lib/stylelint.d.ts | 8 -- package.json | 14 +-- scripts/pull-container-images.ts | 89 +++++++++----- tests/playwright/capture.spec.ts | 8 +- tests/playwright/product.spec.ts | 14 +-- tests/playwright/shop.spec.ts | 10 +- tsconfig.json | 1 - .../haiku-atelier-2024/archive-product.php | 14 +-- .../haiku-atelier-2024/assets/css/main.css | 2 +- .../assets/css/main.css.map | 2 +- .../assets/css/main.min.css | 2 +- .../vendor/controle-personnalise-tinymce.js | 10 +- .../themes/haiku-atelier-2024/front-page.php | 12 +- .../themes/haiku-atelier-2024/page-about.php | 11 +- .../themes/haiku-atelier-2024/page-cart.php | 12 +- .../haiku-atelier-2024/page-contact.php | 12 +- .../haiku-atelier-2024/page-failed-order.php | 12 +- .../page-terms-and-conditions.php | 14 +-- .../haiku-atelier-2024/single-product.php | 12 +- .../haiku-atelier-2024/src/inc/APIRest.php | 1 - .../src/inc/Data/Attribute.php | 2 + .../src/inc/Data/Product.php | 17 ++- .../src/inc/Fonctionnalites.php | 16 +-- .../haiku-atelier-2024/src/inc/Taxonomies.php | 9 +- .../src/inc/TraitementInformations.php | 113 +----------------- .../src/inc/WP/HaikuProduct.php | 2 + .../haiku-atelier-2024/src/inc/WP/Post.php | 2 + .../src/inc/WP/Resource.php | 15 ++- .../src/sass/base/elements/_boutons.scss | 2 +- .../src/scripts-effect/lib/dom.ts | 6 +- .../src/scripts-effect/lib/utils.ts | 2 +- .../src/scripts/lib/animations.ts | 10 +- .../src/scripts/lib/erreurs.ts | 8 +- .../src/scripts/lib/evenements/panier.ts | 8 +- .../src/scripts/lib/messages.ts | 3 +- .../src/scripts/lib/reseau.ts | 17 ++- .../src/scripts/lib/schemas/api/adresses.ts | 2 +- .../src/scripts/lib/session-storage.ts | 3 +- .../src/scripts/lib/types/reseau.d.ts | 4 +- .../src/scripts/lib/utils.ts | 3 +- .../src/scripts/lib/validation.ts | 3 +- .../scripts-page-panier-adresses.ts | 83 +++++++------ .../scripts-page-panier-code-promo.ts | 6 +- .../scripts-page-panier-methodes-livraison.ts | 12 +- .../scripts-page-panier-panneau-produits.ts | 3 +- .../scripts/scripts-bouton-retour-sommet.ts | 8 +- .../src/scripts/scripts-menu-categories.ts | 10 +- .../src/scripts/scripts-page-accueil.ts | 2 +- .../src/scripts/scripts-page-boutique.ts | 12 +- .../src/scripts/scripts-page-panier.ts | 3 +- .../src/scripts/scripts-page-produit.ts | 33 +++-- .../src/scripts/vite.env.d.ts | 6 +- .../taxonomy-product_cat.php | 41 +++---- .../parts/pages/shop/grille-produits.twig | 2 +- 62 files changed, 439 insertions(+), 497 deletions(-) delete mode 100755 lib/stylelint.d.ts delete mode 100755 web/app/themes/haiku-atelier-2024/src/inc/APIRest.php diff --git a/.zed/settings.json b/.zed/settings.json index ed664dc6..becfd951 100644 --- a/.zed/settings.json +++ b/.zed/settings.json @@ -8,5 +8,17 @@ "!vtsls", "..." ], - "languages": {} + "lsp": { + "oxlint": { + "initialization_options": { + "settings": { + "configPath": "cfg/oxlint.config.ts", + "run": "onType", + "disableNestedConfig": false, + "fixKind": "safe_fix", + "unusedDisableDirectives": "deny" + } + } + } + } } diff --git a/bun.lock b/bun.lock index 889275b5..bcff6e5a 100644 --- a/bun.lock +++ b/bun.lock @@ -7,9 +7,9 @@ "dependencies": { "@mobily/ts-belt": "v4.0.0-rc.5", "@sentry/browser": "^10.47.0", - "a11y-dialog": "^8.1.4", + "a11y-dialog": "^8.1.5", "effect": "^4.0.0-beta.43", - "lit-html": "^3.3.1", + "lit-html": "^3.3.2", "purify-ts": "2.1.2", "ts-pattern": "^5.9.0", "valibot": "1.1.0", @@ -17,17 +17,17 @@ "devDependencies": { "@effect/language-service": "^0.84.3", "@gcch/configuration-eslint": "git+https://git.gcch.fr/gcch/configuration-eslint#62ee424274", - "@gcch/configuration-oxlint": "git+https://git.gcch.fr/gcch/configuration-oxlint#93dd909919", + "@gcch/configuration-oxlint": "git+https://git.gcch.fr/gcch/configuration-oxlint#3e49f5e2fb", "@gcch/configuration-prettier": "git+https://git.gcch.fr/gcch/configuration-prettier#8de937e801", "@playwright/test": "^1.59.1", "@sentry/core": "^10.47.0", "@types/bun": "^1.3.11", - "@types/node": "^25.5.1", + "@types/node": "^25.5.2", "@vitejs/plugin-legacy": "^8.0.1", "better-typescript-lib": "^2.12.0", "browserslist": "^4.28.2", - "caniuse-lite": "^1.0.30001784", - "eslint": "^10.1.0", + "caniuse-lite": "^1.0.30001785", + "eslint": "^10.2.0", "eslint-plugin-functional": "^9.0.4", "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-oxlint": "^1.58.0", @@ -53,7 +53,7 @@ "stylelint-declaration-block-no-ignored-properties": "^3.0.0", "stylelint-plugin-logical-css": "^2.1.0", "typescript": "6.0.2", - "typescript-eslint": "^8.48.1", + "typescript-eslint": "^8.58.0", "vite": "^8.0.3", "vite-tsconfig-paths": "^6.1.1", }, @@ -282,21 +282,21 @@ "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="], - "@eslint/config-array": ["@eslint/config-array@0.23.3", "", { "dependencies": { "@eslint/object-schema": "^3.0.3", "debug": "^4.3.1", "minimatch": "^10.2.4" } }, "sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw=="], + "@eslint/config-array": ["@eslint/config-array@0.23.4", "", { "dependencies": { "@eslint/object-schema": "^3.0.4", "debug": "^4.3.1", "minimatch": "^10.2.4" } }, "sha512-lf19F24LSMfF8weXvW5QEtnLqW70u7kgit5e9PSx0MsHAFclGd1T9ynvWEMDT1w5J4Qt54tomGeAhdoAku1Xow=="], - "@eslint/config-helpers": ["@eslint/config-helpers@0.5.3", "", { "dependencies": { "@eslint/core": "^1.1.1" } }, "sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw=="], + "@eslint/config-helpers": ["@eslint/config-helpers@0.5.4", "", { "dependencies": { "@eslint/core": "^1.2.0" } }, "sha512-jJhqiY3wPMlWWO3370M86CPJ7pt8GmEwSLglMfQhjXal07RCvhmU0as4IuUEW5SJeunfItiEetHmSxCCe9lDBg=="], - "@eslint/core": ["@eslint/core@1.1.1", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ=="], + "@eslint/core": ["@eslint/core@1.2.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-8FTGbNzTvmSlc4cZBaShkC6YvFMG0riksYWRFKXztqVdXaQbcZLXlFbSpC05s70sGEsXAw0qwhx69JiW7hQS7A=="], "@eslint/js": ["@eslint/js@10.0.1", "", { "peerDependencies": { "eslint": "^10.0.0" }, "optionalPeers": ["eslint"] }, "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA=="], - "@eslint/object-schema": ["@eslint/object-schema@3.0.3", "", {}, "sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ=="], + "@eslint/object-schema": ["@eslint/object-schema@3.0.4", "", {}, "sha512-55lO/7+Yp0ISKRP0PsPtNTeNGapXaO085aELZmWCVc5SH3jfrqpuU6YgOdIxMS99ZHkQN1cXKE+cdIqwww9ptw=="], - "@eslint/plugin-kit": ["@eslint/plugin-kit@0.6.1", "", { "dependencies": { "@eslint/core": "^1.1.1", "levn": "^0.4.1" } }, "sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ=="], + "@eslint/plugin-kit": ["@eslint/plugin-kit@0.7.0", "", { "dependencies": { "@eslint/core": "^1.2.0", "levn": "^0.4.1" } }, "sha512-ejvBr8MQCbVsWNZnCwDXjUKq40MDmHalq7cJ6e9s/qzTUFIIo/afzt1Vui9T97FM/V/pN4YsFVoed5NIa96RDg=="], "@gcch/configuration-eslint": ["@gcch/configuration-eslint@git+https://git.gcch.fr/gcch/configuration-eslint#62ee424274f0bfebd5135a728960644f4b1cdcb8", { "dependencies": { "@eslint/js": "^10.0.1", "astro-eslint-parser": "^1.3.0", "eslint": "^10.0.3", "eslint-plugin-astro": "^1.6.0", "eslint-plugin-functional": "^9.0.4", "eslint-plugin-jsdoc": "^62.8.0", "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-perfectionist": "^5.6.0", "eslint-plugin-sonarjs": "^4.0.2", "eslint-plugin-unicorn": "^63.0.0", "globals": "^17.4.0", "typescript-eslint": "^8.57.0" }, "peerDependencies": { "eslint": "^10.0.3", "typescript": "^6.0.1-rc" } }, "62ee424274f0bfebd5135a728960644f4b1cdcb8"], - "@gcch/configuration-oxlint": ["@gcch/configuration-oxlint@git+https://git.gcch.fr/gcch/configuration-oxlint#93dd9099199603d2fe2c334227e8051104b8f1a0", { "dependencies": { "globals": "^17.4.0", "oxlint": "^1.58.0", "oxlint-tsgolint": "^0.19.0" }, "optionalDependencies": { "eslint-plugin-astro": "^1.6.0" }, "peerDependencies": { "eslint-plugin-astro": "^1.6.0", "eslint-plugin-functional": "^9.0.4", "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-perfectionist": "^5.7.0", "eslint-plugin-sonarjs": "^4.0.2", "oxlint": "^1.58.0", "oxlint-tsgolint": "^0.19.0", "typescript": "^6.0.2" } }, "93dd9099199603d2fe2c334227e8051104b8f1a0"], + "@gcch/configuration-oxlint": ["@gcch/configuration-oxlint@git+https://git.gcch.fr/gcch/configuration-oxlint#3e49f5e2fbfde01ad3d75acbff0da8023d5a3802", { "dependencies": { "eslint-plugin-astro": "^1.6.0", "eslint-plugin-functional": "^9.0.4", "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-perfectionist": "^5.8.0", "eslint-plugin-sonarjs": "^4.0.2", "globals": "^17.4.0", "oxlint": "^1.58.0", "oxlint-tsgolint": "^0.19.0" }, "peerDependencies": { "eslint-plugin-astro": "^1.6.0", "eslint-plugin-functional": "^9.0.4", "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-perfectionist": "^5.8.0", "eslint-plugin-sonarjs": "^4.0.2", "oxlint": "^1.58.0", "oxlint-tsgolint": "^0.19.0", "typescript": "^6.0.2" } }, "3e49f5e2fbfde01ad3d75acbff0da8023d5a3802"], "@gcch/configuration-prettier": ["@gcch/configuration-prettier@git+https://git.gcch.fr/gcch/configuration-prettier#8de937e801bd44784ac91e0ff6e038d838f7eea1", { "dependencies": { "prettier": "^3.8.1", "prettier-plugin-curly": "^0.4.1", "prettier-plugin-ini": "^1.3.0", "prettier-plugin-jsdoc": "^1.8.0", "prettier-plugin-pkg": "^0.22.0", "prettier-plugin-sh": "^0.18.0", "prettier-plugin-sort-json": "^4.2.0" }, "peerDependencies": { "prettier": "^3.8.1" } }, "8de937e801bd44784ac91e0ff6e038d838f7eea1"], @@ -726,7 +726,7 @@ "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], - "caniuse-lite": ["caniuse-lite@1.0.30001784", "", {}, "sha512-WU346nBTklUV9YfUl60fqRbU5ZqyXlqvo1SgigE1OAXK5bFL8LL9q1K7aap3N739l4BvNqnkm3YrGHiY9sfUQw=="], + "caniuse-lite": ["caniuse-lite@1.0.30001785", "", {}, "sha512-blhOL/WNR+Km1RI/LCVAvA73xplXA7ZbjzI4YkMK9pa6T/P3F2GxjNpEkyw5repTw9IvkyrjyHpwjnhZ5FOvYQ=="], "change-case": ["change-case@5.4.4", "", {}, "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w=="], @@ -826,7 +826,7 @@ "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], - "eslint": ["eslint@10.1.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.3", "@eslint/config-helpers": "^0.5.3", "@eslint/core": "^1.1.1", "@eslint/plugin-kit": "^0.6.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^9.1.2", "eslint-visitor-keys": "^5.0.1", "espree": "^11.2.0", "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "minimatch": "^10.2.4", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-S9jlY/ELKEUwwQnqWDO+f+m6sercqOPSqXM5Go94l7DOmxHVDgmSFGWEzeE/gwgTAr0W103BWt0QLe/7mabIvA=="], + "eslint": ["eslint@10.2.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.4", "@eslint/config-helpers": "^0.5.4", "@eslint/core": "^1.2.0", "@eslint/plugin-kit": "^0.7.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^9.1.2", "eslint-visitor-keys": "^5.0.1", "espree": "^11.2.0", "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "minimatch": "^10.2.4", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-+L0vBFYGIpSNIt/KWTpFonPrqYvgKw1eUI5Vn7mEogrQcWtWYtNQ7dNqC+px/J0idT3BAkiWrhfS7k+Tum8TUA=="], "eslint-compat-utils": ["eslint-compat-utils@0.6.5", "", { "dependencies": { "semver": "^7.5.4" }, "peerDependencies": { "eslint": ">=6.0.0" } }, "sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ=="], @@ -1632,6 +1632,8 @@ "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], + "@gcch/configuration-eslint/eslint": ["eslint@10.1.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.3", "@eslint/config-helpers": "^0.5.3", "@eslint/core": "^1.1.1", "@eslint/plugin-kit": "^0.6.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^9.1.2", "eslint-visitor-keys": "^5.0.1", "espree": "^11.2.0", "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "minimatch": "^10.2.4", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-S9jlY/ELKEUwwQnqWDO+f+m6sercqOPSqXM5Go94l7DOmxHVDgmSFGWEzeE/gwgTAr0W103BWt0QLe/7mabIvA=="], + "@keyv/bigmap/keyv": ["keyv@5.6.0", "", { "dependencies": { "@keyv/serialize": "^1.1.1" } }, "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw=="], "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], @@ -1644,6 +1646,8 @@ "babel-plugin-polyfill-corejs2/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "browserslist/caniuse-lite": ["caniuse-lite@1.0.30001784", "", {}, "sha512-WU346nBTklUV9YfUl60fqRbU5ZqyXlqvo1SgigE1OAXK5bFL8LL9q1K7aap3N739l4BvNqnkm3YrGHiY9sfUQw=="], + "browserslist-to-esbuild/meow": ["meow@13.2.0", "", {}, "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA=="], "cacheable/keyv": ["keyv@5.6.0", "", { "dependencies": { "@keyv/serialize": "^1.1.1" } }, "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw=="], @@ -1690,6 +1694,14 @@ "vite/fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + "@gcch/configuration-eslint/eslint/@eslint/config-array": ["@eslint/config-array@0.23.3", "", { "dependencies": { "@eslint/object-schema": "^3.0.3", "debug": "^4.3.1", "minimatch": "^10.2.4" } }, "sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw=="], + + "@gcch/configuration-eslint/eslint/@eslint/config-helpers": ["@eslint/config-helpers@0.5.3", "", { "dependencies": { "@eslint/core": "^1.1.1" } }, "sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw=="], + + "@gcch/configuration-eslint/eslint/@eslint/core": ["@eslint/core@1.1.1", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ=="], + + "@gcch/configuration-eslint/eslint/@eslint/plugin-kit": ["@eslint/plugin-kit@0.6.1", "", { "dependencies": { "@eslint/core": "^1.1.1", "levn": "^0.4.1" } }, "sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ=="], + "eslint-plugin-jsx-a11y/minimatch/brace-expansion": ["brace-expansion@1.1.13", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w=="], "stylelint/file-entry-cache/flat-cache": ["flat-cache@6.1.22", "", { "dependencies": { "cacheable": "^2.3.4", "flatted": "^3.4.2", "hookified": "^1.15.0" } }, "sha512-N2dnzVJIphnNsjHcrxGW7DePckJ6haPrSFqpsBUhHYgwtKGVq4JrBGielEGD2fCVnsGm1zlBVZ8wGhkyuetgug=="], @@ -1700,6 +1712,8 @@ "table/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "@gcch/configuration-eslint/eslint/@eslint/config-array/@eslint/object-schema": ["@eslint/object-schema@3.0.3", "", {}, "sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ=="], + "eslint-plugin-jsx-a11y/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], } } diff --git a/cfg/oxlint.config.ts b/cfg/oxlint.config.ts index eee5bb11..ae0a50aa 100644 --- a/cfg/oxlint.config.ts +++ b/cfg/oxlint.config.ts @@ -1,3 +1,11 @@ -import config from "@gcch/configuration-oxlint"; +import gcchConfig from "@gcch/configuration-oxlint"; +import { OxlintConfig } from "oxlint"; + +const config: OxlintConfig = { + ...gcchConfig, + globals: { + Bun: "readonly", + }, +}; export default config; diff --git a/cfg/playwright.config.ts b/cfg/playwright.config.ts index bb0c375b..c27c1459 100644 --- a/cfg/playwright.config.ts +++ b/cfg/playwright.config.ts @@ -2,24 +2,6 @@ import { defineConfig, devices } from "@playwright/test"; export default defineConfig({ fullyParallel: true, - reporter: "list", - retries: 1, - testDir: "../tests", - timeout: 10_000, - workers: "100%", - use: { - /* Base URL to use in actions like `await page.goto('/')`. */ - baseURL: "https://haikuatelier.gcch.local", - trace: "retry-with-trace", - clientCertificates: [ - { - origin: "https://haikuatelier.gcch.local", - certPath: "../containers/data/certs/_wildcard.gcch.local.pem", - keyPath: "../containers/data/certs/_wildcard.gcch.local-key.pem", - }, - ], - ignoreHTTPSErrors: true, - }, projects: [ { name: "desktop-chromium-1920", @@ -62,4 +44,22 @@ export default defineConfig({ // use: { ...devices["Pixel 7 landscape"] }, // }, ], + reporter: "list", + retries: 1, + testDir: "../tests", + timeout: 10_000, + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: "https://haikuatelier.gcch.local", + trace: "retry-with-trace", + clientCertificates: [ + { + origin: "https://haikuatelier.gcch.local", + certPath: "../containers/data/certs/_wildcard.gcch.local.pem", + keyPath: "../containers/data/certs/_wildcard.gcch.local-key.pem", + }, + ], + ignoreHTTPSErrors: true, + }, + workers: "100%", }); diff --git a/cfg/stylelint.config.ts b/cfg/stylelint.config.ts index b665a0da..29c371b0 100755 --- a/cfg/stylelint.config.ts +++ b/cfg/stylelint.config.ts @@ -1,40 +1,59 @@ -// @ts-expect-error -- La dépendance ne dispose pas de types. +import { pipe, Array as FxArray } from "effect"; +import type stylelint from "stylelint"; import { propertyGroups } from "stylelint-config-clean-order"; -/** @type {string[][]} */ -// eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- Impossible de typer correctement avec JSDoc. -const groupesProprietes = Array.from(/** @type {GroupeProprietes} */ propertyGroups); +/** + * Définition d'un groupe de Propriétés _CSS_ du plugin `stylelint-config-clean-order` pour _Stylelint_. + */ +type StylelintConfigCleanOrderPropertyGroup = { + emptyLineBefore: "never" | "threshold"; + noEmptyLineBetween: boolean; + properties: ReadonlyArray | string; +}; -/** @import { StylelintConfigCleanOrderPropertyGroup } from "./lib/stylelint" */ -/** @type {Array} */ -const ordreProprietes = groupesProprietes.map((properties) => ({ - emptyLineBefore: "never", - noEmptyLineBetween: true, - properties, -})); +const ordreProprietes: ReadonlyArray = pipe( + Array.from(propertyGroups), + FxArray.map((properties: ReadonlyArray) => ({ + emptyLineBefore: "never", + noEmptyLineBetween: true, + properties, + })), +); -/** @type {import("stylelint").Config} */ -export default { +const stylelintConfig: stylelint.Config = { extends: ["stylelint-config-standard-scss", "stylelint-config-sass-guidelines", "stylelint-config-clean-order"], plugins: ["stylelint-declaration-block-no-ignored-properties"], rules: { - "@stylistic/function-parentheses-space-inside": null, - "@stylistic/selector-list-comma-newline-after": null, - "@stylistic/string-quotes": null, - "custom-property-pattern": null, + "@stylistic/function-parentheses-space-inside": undefined, + "@stylistic/selector-list-comma-newline-after": undefined, + "@stylistic/string-quotes": undefined, + "custom-property-pattern": undefined, "declaration-block-no-duplicate-custom-properties": true, "declaration-block-no-duplicate-properties": true, "declaration-block-no-redundant-longhand-properties": true, "declaration-block-no-shorthand-property-overrides": true, - "max-nesting-depth": null, - "no-descending-specificity": null, - "no-duplicate-selectors": [true, { disallowInList: false }], - "order/properties-order": [ordreProprietes, { severity: "error", unspecified: "bottomAlphabetical" }], + "max-nesting-depth": undefined, + "no-descending-specificity": undefined, + "no-duplicate-selectors": [ + true, + { + disallowInList: false, + }, + ], + "order/properties-order": [ + ordreProprietes, + { + severity: "error", + unspecified: "bottomAlphabetical", + }, + ], "plugin/declaration-block-no-ignored-properties": true, - "selector-class-pattern": null, - "selector-id-pattern": null, - "selector-max-compound-selectors": null, - "selector-max-id": null, - "selector-no-qualifying-type": null, + "selector-class-pattern": undefined, + "selector-id-pattern": undefined, + "selector-max-compound-selectors": undefined, + "selector-max-id": undefined, + "selector-no-qualifying-type": undefined, }, }; + +export default stylelintConfig; diff --git a/cfg/vite.config.ts b/cfg/vite.config.ts index 81aafd8b..5e049c19 100755 --- a/cfg/vite.config.ts +++ b/cfg/vite.config.ts @@ -17,7 +17,6 @@ export default defineConfig(({ mode }) => { return { base: "/", - cacheDir: ".cache/vite", build: { assetsDir: ".", cssMinify: "lightningcss", @@ -40,6 +39,7 @@ export default defineConfig(({ mode }) => { target: "es2020", write: true, }, + cacheDir: ".cache/vite", css: { devSourcemap: true, transformer: "lightningcss", diff --git a/composer.lock b/composer.lock index fcf3835a..e5325f84 100644 --- a/composer.lock +++ b/composer.lock @@ -5129,12 +5129,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "958bc6ccdb194912236265e4f36256e55bb0c9da" + "reference": "db78064456eb735e368677828095fb7fe5aeda6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/958bc6ccdb194912236265e4f36256e55bb0c9da", - "reference": "958bc6ccdb194912236265e4f36256e55bb0c9da", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/db78064456eb735e368677828095fb7fe5aeda6f", + "reference": "db78064456eb735e368677828095fb7fe5aeda6f", "shasum": "" }, "conflict": { @@ -5555,7 +5555,7 @@ "knplabs/knp-snappy": "<=1.4.2", "kohana/core": "<3.3.3", "koillection/koillection": "<1.6.12", - "krayin/laravel-crm": "<=1.3", + "krayin/laravel-crm": "<=2.2", "kreait/firebase-php": ">=3.2,<3.8.1", "kumbiaphp/kumbiapp": "<=1.1.1", "la-haute-societe/tcpdf": "<6.2.22", @@ -5818,7 +5818,7 @@ "roadiz/documents": "<2.3.42|>=2.4,<2.5.44|>=2.6,<2.6.28|>=2.7,<2.7.9", "robrichards/xmlseclibs": "<3.1.5", "roots/soil": "<4.1", - "roundcube/roundcubemail": "<1.5.10|>=1.6,<1.6.11", + "roundcube/roundcubemail": "<1.5.10|>=1.6,<1.6.11|>=1.7.0.0-beta,<1.7.0.0-RC5-dev", "rudloff/alltube": "<3.0.3", "rudloff/rtmpdump-bin": "<=2.3.1", "s-cart/core": "<=9.0.5", @@ -6171,20 +6171,20 @@ "type": "tidelift" } ], - "time": "2026-04-03T04:48:53+00:00" + "time": "2026-04-04T07:24:55+00:00" }, { "name": "sebastian/diff", - "version": "8.0.0", + "version": "8.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "a2b6d09d7729ee87d605a439469f9dcc39be5ea3" + "reference": "9c957d730257f49c873f3761674559bd90098a7d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/a2b6d09d7729ee87d605a439469f9dcc39be5ea3", - "reference": "a2b6d09d7729ee87d605a439469f9dcc39be5ea3", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/9c957d730257f49c873f3761674559bd90098a7d", + "reference": "9c957d730257f49c873f3761674559bd90098a7d", "shasum": "" }, "require": { @@ -6197,7 +6197,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "8.0-dev" + "dev-main": "8.1-dev" } }, "autoload": { @@ -6230,7 +6230,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/8.0.0" + "source": "https://github.com/sebastianbergmann/diff/tree/8.1.0" }, "funding": [ { @@ -6250,7 +6250,7 @@ "type": "tidelift" } ], - "time": "2026-02-06T04:42:27+00:00" + "time": "2026-04-05T12:02:33+00:00" }, { "name": "symfony/console", @@ -7483,5 +7483,5 @@ "php": ">=8.5" }, "platform-dev": {}, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } diff --git a/cspell.json b/cspell.json index 6eca639e..b5e1476b 100644 --- a/cspell.json +++ b/cspell.json @@ -25,7 +25,8 @@ "curryfication", "giftcard", "taplo", - "phpactor" + "phpactor", + "gcch" ], "words": [ "GLITCHTIP", diff --git a/lib/stylelint.d.ts b/lib/stylelint.d.ts deleted file mode 100755 index e02b5ee7..00000000 --- a/lib/stylelint.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Définition d'un groupe de Propriétés _CSS_ du plugin `stylelint-config-clean-order` pour _Stylelint_. - */ -export type stylelintconfigcleanorderpropertygroup = { - emptyLineBefore: "never" | "threshold"; - noEmptyLineBetween: boolean; - properties: string | array; -}; diff --git a/package.json b/package.json index a91ed454..7f6520c9 100755 --- a/package.json +++ b/package.json @@ -13,9 +13,9 @@ "dependencies": { "@mobily/ts-belt": "v4.0.0-rc.5", "@sentry/browser": "^10.47.0", - "a11y-dialog": "^8.1.4", + "a11y-dialog": "^8.1.5", "effect": "^4.0.0-beta.43", - "lit-html": "^3.3.1", + "lit-html": "^3.3.2", "purify-ts": "2.1.2", "ts-pattern": "^5.9.0", "valibot": "1.1.0" @@ -23,17 +23,17 @@ "devDependencies": { "@effect/language-service": "^0.84.3", "@gcch/configuration-eslint": "git+https://git.gcch.fr/gcch/configuration-eslint#62ee424274", - "@gcch/configuration-oxlint": "git+https://git.gcch.fr/gcch/configuration-oxlint#93dd909919", + "@gcch/configuration-oxlint": "git+https://git.gcch.fr/gcch/configuration-oxlint#3e49f5e2fb", "@gcch/configuration-prettier": "git+https://git.gcch.fr/gcch/configuration-prettier#8de937e801", "@playwright/test": "^1.59.1", "@sentry/core": "^10.47.0", "@types/bun": "^1.3.11", - "@types/node": "^25.5.1", + "@types/node": "^25.5.2", "@vitejs/plugin-legacy": "^8.0.1", "better-typescript-lib": "^2.12.0", "browserslist": "^4.28.2", - "caniuse-lite": "^1.0.30001784", - "eslint": "^10.1.0", + "caniuse-lite": "^1.0.30001785", + "eslint": "^10.2.0", "eslint-plugin-functional": "^9.0.4", "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-oxlint": "^1.58.0", @@ -59,7 +59,7 @@ "stylelint-declaration-block-no-ignored-properties": "^3.0.0", "stylelint-plugin-logical-css": "^2.1.0", "typescript": "6.0.2", - "typescript-eslint": "^8.48.1", + "typescript-eslint": "^8.58.0", "vite": "^8.0.3", "vite-tsconfig-paths": "^6.1.1" }, diff --git a/scripts/pull-container-images.ts b/scripts/pull-container-images.ts index f3b47da6..d10556ee 100644 --- a/scripts/pull-container-images.ts +++ b/scripts/pull-container-images.ts @@ -1,45 +1,69 @@ import { YAML } from "bun"; -import { Array as EffectArray, Console, Data, Effect, pipe, Record, Schema, SchemaIssue } from "effect"; -import { NoSuchElementError } from "effect/Cause"; -import { type ReadonlyRecord } from "effect/Record"; +import { Console, Data, Effect, Array as EffectArray, pipe, Record, Schema, SchemaIssue } from "effect"; import { SchemaError } from "effect/Schema"; const COMPOSE_PATH = "compose.yaml"; +const DEFAULT_CMD_TIMEOUT = 10_000; +class Compose extends Schema.Class("Compose")({ + name: Schema.String, + services: Schema.Record(Schema.String, Schema.Unknown), +}) {} class ScriptError extends Data.TaggedError("ScriptError")<{ cause: unknown }> {} -const ComposeSchema = Schema.Record(Schema.Union([Schema.String, Schema.Symbol]), Schema.Any); +// Const composeSchema = Schema.Record(Schema.Union([Schema.String, Schema.Symbol]), Schema.Unknown); +// type YamlRecord = ReadonlyRecord; -type ComposeYaml = ReadonlyRecord; +/* */ -const getObjectKey = (key: string, yaml: ComposeYaml): Effect.Effect, ScriptError> => - pipe( - Record.get(key)(yaml), - Effect.fromOption, - Effect.map((yaml: any) => Record.keys(yaml)), - Effect.mapError((e: NoSuchElementError) => new ScriptError({ cause: e })), - ); +/** + * Retourne les noms des services déclarés dans un ficher _Compose_. + * @param compose Le fichier _Compose_ sous forme d'objet. + * @returns Les noms des Services sous forme de tableau. + */ +const getServicesFromComposeYaml: (compose: Compose) => ReadonlyArray = (compose) => + Record.keys(compose.services); -const getFileContent = Effect.fn("getFileContent")(function* (filePath: string) { - const fileRef = Bun.file(filePath); +/** + * Récupère le contenu texte d'un fichier pour un chemin donné. + * + * @param filePath Le chemin du fichier dont on souhaite le contenu. + * @returns Le contenu textuel du fichier sous forme de chaîne de caractères. + */ +const getFileContent: (filePath: string) => Effect.Effect = Effect.fn("getFileContent")( + function* (filePath) { + const fileRef: Bun.BunFile = Bun.file(filePath); - yield* Effect.tryPromise({ - try: () => fileRef.exists(), - catch: (_) => new ScriptError({ cause: "The wanted file does not exist." }), - }); + yield* Effect.tryPromise({ + catch: (_): ScriptError => new ScriptError({ cause: "The wanted file does not exist." }), + try: async (): Promise => fileRef.exists(), + }); - return yield* Effect.tryPromise({ - try: () => fileRef.text(), - catch: (_) => new ScriptError({ cause: "Can't retrieve the file's text content." }), - }); -}); + return yield* Effect.tryPromise({ + catch: (_): ScriptError => new ScriptError({ cause: "Can't retrieve the file's text content." }), + try: async (): Promise => fileRef.text(), + }); + }, +); -const getComposeYaml = (filePath: string, schema: Schema.Schema) => - pipe( - getFileContent(filePath), - Effect.map((text: string) => YAML.parse(text)), - Effect.flatMap((yaml: unknown) => Schema.decodeUnknownEffect(schema)(yaml, { errors: "all" })), - Effect.mapError((error) => { +/** + * Récupère le contenu _YAML_ d'un fichier _Compose_ sous forme de `Record`. + * + * @param path Le chemin du fichier _Compose_. + * @param schema Le `Schema` utilisée pour le parsage des données du fichier. + * @returns Un `Record` des données du fichier. + */ +const getComposeYaml: ( + path: string, + schema: Schema.Schema, +) => Effect.Effect = Effect.fn("getComposeYaml")(function* (path, schema) { + return yield* pipe( + getFileContent(path), + Effect.map((text: string): unknown => YAML.parse(text)), + Effect.flatMap((yaml: unknown) => + Schema.decodeUnknownEffect(schema)(yaml, { errors: "all", onExcessProperty: "ignore" }), + ), + Effect.mapError((error): ScriptError => { if (error instanceof SchemaError) { return new ScriptError({ cause: SchemaIssue.makeFormatterStandardSchemaV1()(error.issue) }); } else { @@ -47,14 +71,15 @@ const getComposeYaml = (filePath: string, schema: Schema.Schema) => } }), ); +}); const program: Effect.Effect, ScriptError> = pipe( - getComposeYaml(COMPOSE_PATH, ComposeSchema), - Effect.flatMap((yaml: ComposeYaml) => getObjectKey("services", yaml)), + getComposeYaml(COMPOSE_PATH, Compose), + Effect.map((compose: Compose) => getServicesFromComposeYaml(compose)), Effect.map((keys: ReadonlyArray) => EffectArray.filter(keys, (key) => key !== "wordpress")), Effect.orElseSucceed(() => [""]), Effect.tap((services: ReadonlyArray) => { - Bun.spawn({ cmd: ["podman", "compose", "pull", ...services], timeout: 10000 }); + Bun.spawn({ cmd: ["podman", "compose", "pull", ...services], timeout: DEFAULT_CMD_TIMEOUT }); return Effect.succeed(services); }), Effect.tapCause(Console.error), diff --git a/tests/playwright/capture.spec.ts b/tests/playwright/capture.spec.ts index 81e6e89a..2b2ee074 100644 --- a/tests/playwright/capture.spec.ts +++ b/tests/playwright/capture.spec.ts @@ -1,14 +1,12 @@ -import { expect, type Page, test } from "@playwright/test"; +import { expect, test } from "@playwright/test"; +import type { Page } from "@playwright/test"; type TestPage = { pageName: string; url: string; }; -const genTimestamp = (): string => - Intl.DateTimeFormat("sv-SE", { - dateStyle: "short", - }).format(Date.now()); +const genTimestamp = (): string => Intl.DateTimeFormat("sv-SE", { dateStyle: "short" }).format(Date.now()); const takeFullPageScreenshot = async (page: Page, name: string): Promise => { await page.screenshot({ fullPage: false, path: `captures/${name}`, type: "png" }); diff --git a/tests/playwright/product.spec.ts b/tests/playwright/product.spec.ts index 721181df..ab8abb85 100644 --- a/tests/playwright/product.spec.ts +++ b/tests/playwright/product.spec.ts @@ -24,8 +24,8 @@ type ProductsFixture = { type ProductsKinds = { allProducts: WCV3Products; simpleProducts: WCV3Products; - simpleProductsWithStock: WCV3Products; simpleProductsWithoutStock: WCV3Products; + simpleProductsWithStock: WCV3Products; }; export const test = base.extend({ @@ -34,7 +34,7 @@ export const test = base.extend({ const backendHeaders: BackendHeaders = await getBackendHeadersFromHtml(page); const response = await request.get("/wp-json/wc/v3/products?page=1&per_page=100&status=publish", { - headers: { Nonce: backendHeaders.nonce, Authorization: `Basic ${backendHeaders.authString}` }, + headers: { Authorization: `Basic ${backendHeaders.authString}`, Nonce: backendHeaders.nonce }, }); expect(response.ok(), "The API returned the list of every Product").toBeTruthy(); @@ -50,15 +50,15 @@ export const test = base.extend({ const kinds = { allProducts, simpleProducts, - simpleProductsWithStock, simpleProductsWithoutStock, + simpleProductsWithStock, } satisfies ProductsKinds; await use(kinds); }, }); -test("can add a Product without variation with stock to the Cart", async ({ products, page }) => { +test("can add a Product without variation with stock to the Cart", async ({ page, products }) => { // Prend un produit au hasard. const randomProductIndex = getRandomIntInclusive(0, products.simpleProductsWithStock.length - 1); const randomProduct = products.simpleProductsWithStock.at(randomProductIndex); @@ -71,7 +71,7 @@ test("can add a Product without variation with stock to the Cart", async ({ prod await page.goto(randomProduct.permalink); // Vérifie le bon état du bouton de l'ajout au Panier. - const addToCartButton = page.getByRole("button", { name: "Add to cart", disabled: false }); + const addToCartButton = page.getByRole("button", { disabled: false, name: "Add to cart" }); await addToCartButton.scrollIntoViewIfNeeded(); await expect(addToCartButton, "The add to cart button must be visible").toBeVisible(); await expect(addToCartButton, "The add to cart button must be enabled").toBeEnabled(); @@ -91,7 +91,7 @@ test("can add a Product without variation with stock to the Cart", async ({ prod expect(cartLink, "The cart items' indicator has been incremented").toBeDefined(); }); -test("can't add a Product without variation without stock to the Cart", async ({ products, page }) => { +test("can't add a Product without variation without stock to the Cart", async ({ page, products }) => { // Prend un produit au hasard. const randomProductIndex = getRandomIntInclusive(0, products.simpleProductsWithoutStock.length - 1); const randomProduct = products.simpleProductsWithoutStock.at(randomProductIndex); @@ -104,7 +104,7 @@ test("can't add a Product without variation without stock to the Cart", async ({ await page.goto(randomProduct.permalink); // Vérifie le bon état du bouton de l'ajout au Panier. - const outOfStockButton = page.getByRole("button", { name: "Out of stock", disabled: true }); + const outOfStockButton = page.getByRole("button", { disabled: true, name: "Out of stock" }); await outOfStockButton.scrollIntoViewIfNeeded(); await expect(outOfStockButton, "The add to cart button must be visible").toBeVisible(); await expect(outOfStockButton, "The add to cart button must be disabled").toBeDisabled(); diff --git a/tests/playwright/shop.spec.ts b/tests/playwright/shop.spec.ts index b3810997..b3f23c9b 100644 --- a/tests/playwright/shop.spec.ts +++ b/tests/playwright/shop.spec.ts @@ -1,8 +1,8 @@ -import { test, expect, Page, Locator, Response, APIRequestContext } from "@playwright/test"; +import { APIRequestContext, expect, Locator, Page, Response, test } from "@playwright/test"; import { WCV3Products } from "../../web/app/themes/haiku-atelier-2024/src/scripts/lib/types/api/v3/products"; import { BackendHeaders, getBackendHeadersFromHtml } from "./utils.ts"; -test.describe.configure({ mode: "parallel", timeout: 60000 }); +test.describe.configure({ mode: "parallel", timeout: 60_000 }); test("can scroll to the end of the grid", async ({ page }): Promise => { await scrollToGridsEnd(page); @@ -22,12 +22,10 @@ test.skip("can access all Products' pages", async ({ page, request }): Promise> => { const backendHeaders: BackendHeaders = await getBackendHeadersFromHtml(page); const response = await request.get("/wp-json/wc/v3/products?page=1&per_page=100&status=publish", { - headers: { Nonce: backendHeaders.nonce, Authorization: `Basic ${backendHeaders.authString}` }, + headers: { Authorization: `Basic ${backendHeaders.authString}`, Nonce: backendHeaders.nonce }, }); const json = (await response.json()) as WCV3Products; - const links = json.map((p) => p.permalink); - - return links; + return json.map((p) => p.permalink); }; const scrollToGridsEnd = async (page: Page): Promise => { diff --git a/tsconfig.json b/tsconfig.json index 7e93c916..9c727d57 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -25,7 +25,6 @@ "noImplicitReturns": true, "noImplicitThis": true, "noPropertyAccessFromIndexSignature": true, - "noStrictGenericChecks": false, "noUncheckedIndexedAccess": true, "noUncheckedSideEffectImports": true, "noUnusedLocals": true, diff --git a/web/app/themes/haiku-atelier-2024/archive-product.php b/web/app/themes/haiku-atelier-2024/archive-product.php index 6e6c7788..8cba877d 100755 --- a/web/app/themes/haiku-atelier-2024/archive-product.php +++ b/web/app/themes/haiku-atelier-2024/archive-product.php @@ -8,7 +8,6 @@ declare(strict_types=1); namespace HaikuAtelier; -use Exception; use HaikuAtelier\Data\Product; use HaikuAtelier\WP\Resource; use Timber\Timber; @@ -18,8 +17,6 @@ use function add_action; use function array_map; use function wc_get_products; -require_once __DIR__ . '/src/inc/TraitementInformations.php'; - $context = Timber::context(); $templates = ['boutique.twig']; @@ -32,12 +29,7 @@ $products = array_map( ); $context['products'] = $products; -/** - * Charge les scripts et styles de la page. - * - * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger - */ -function load_page_resources(): void { +add_action('wp_enqueue_scripts', function (): void { Resource::enqueue_style_file( handle: 'haiku-atelier-2024-styles-page-boutique', path: '/assets/css/pages/page-boutique.css', @@ -50,9 +42,7 @@ function load_page_resources(): void { id: 'haiku-atelier-2024-scripts-menu-categories', path: '/assets/js/scripts-menu-categories.js', ); -} - -add_action('wp_enqueue_scripts', load_page_resources(...)); +}); Timber::render( data: $context, diff --git a/web/app/themes/haiku-atelier-2024/assets/css/main.css b/web/app/themes/haiku-atelier-2024/assets/css/main.css index 80a8b5c5..2d3811bb 100755 --- a/web/app/themes/haiku-atelier-2024/assets/css/main.css +++ b/web/app/themes/haiku-atelier-2024/assets/css/main.css @@ -310,6 +310,7 @@ button.bouton-blanc-sur-noir { } button.bouton-retour-haut { position: fixed; + z-index: 500; right: var(--espace-xl); bottom: calc(var(--espace-l) + var(--pied-de-page-hauteur)); transform: rotate(180deg); @@ -321,7 +322,6 @@ button.bouton-retour-haut { background: var(--couleur-fond); box-shadow: initial; transition: 0.2s background, 0.2s opacity, 0.2s visibility; - z-index: 500; } button.bouton-retour-haut img { width: 1rem; diff --git a/web/app/themes/haiku-atelier-2024/assets/css/main.css.map b/web/app/themes/haiku-atelier-2024/assets/css/main.css.map index 2b8a8376..159315a7 100755 --- a/web/app/themes/haiku-atelier-2024/assets/css/main.css.map +++ b/web/app/themes/haiku-atelier-2024/assets/css/main.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../../src/sass/base/polices/_lato.scss","../../src/sass/base/polices/_myriad.scss","../../src/sass/abstracts/_variables.scss","../../src/sass/base/_base.scss","../../src/sass/base/_typographie.scss","../../src/sass/base/elements/_boutons.scss","../../src/sass/base/elements/_formulaires.scss","../../src/sass/base/elements/_images.scss","../../src/sass/base/elements/_liens.scss","../../src/sass/base/elements/_listes.scss","../../src/sass/layouts/_bandeau.scss","../../src/sass/layouts/_menu-mobile.scss","../../src/sass/layouts/_en-tete.scss","../../src/sass/layouts/_menu-categories-produits.scss","../../src/sass/layouts/_colonnes-photos.scss","../../src/sass/layouts/_grille-produits.scss","../../src/sass/layouts/_informations-produit.scss","../../src/sass/layouts/_produits-similaires.scss","../../src/sass/layouts/_pied-de-page.scss"],"names":[],"mappings":";AAAA;EACE;EACA;EACA;EACA;EACA,KACE;EAQF,eACE;;AAmBJ;EACE;EACA;EACA;EACA;EACA,KACE;EAQF,eACE;;ACjDJ;EACE;EACA;EACA;EACA;EACA;EACA,KACE;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA,KACE;;ACjBJ;AACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AAEA;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;EAGA;EACA;AAAA;AAAA;EAGA;AAAA;AAAA;AAAA;AAKA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACjDF;AAAA;AAAA;AAGA;EACE;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAIA;EACE;EACA;EACA;;;AAGF;AAAA;AAAA;AAGA;EACE;;;AAGF;AAAA;AAAA;AAGA;EACE;;;AAGF;AACA;EACE;;;AAGF;AACA;EACE;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;;;AAGF;AAAA;AAAA;AAGA;EACE;IACE;IACA;IACA;;EAGF;IACE;;;AC5FJ;AAAA;AAAA;AAAA;AAIA;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AC1BA;AAAA;AAAA;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;IACE;IACA;;;AAKN;EACE;EAEA;;AAIF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAKN;EACE;EACA;;AAIA;EADF;IAEI;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;IACE;IACA;;;;AC/FV;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EAEA;;;AAKF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;;AAQJ;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGA;EACE;EACA;EACA;EACA;;AAGF;EACE;IACE;;;AAKN;EACE;;AA3BJ;AA8BE;AAAA;AAAA;;AAGA;EACE;EACA;;AAGF;EACE;IACE;;;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMJ;EACE;IACE;;;;AC7HN;AAAA;AAAA;AAAA;AAAA;AAKA;EACE;EACA;;;AAGF;EACE;EACA;;;ACZF;AAAA;AAAA;AAAA;AAAA;AAKA;AACE;EACA;EAEA;EACA;EACA;EACA,YACE,uIAM4B;EAE9B;AAEA;;AACA;EACE;;AApBJ;AAuBE;;AACA;AACE;EACA;EACA;AAEA;EACA;EAEA;EACA;AAEA;;AACA;EACE;;AAbJ;AAgBE;;AACA;EACE;;AAlBJ;AAqBE;;AACA;EACE;IACE;;;AAhDR;AAqDE;;AACA;EACE;;AAEA;EACE;EACA;;AAGF;EACE;IACE;IACA;;;AAjER;AAsEE;;AAEE;EACE;IACE;;;;AC/ER;AAAA;AAAA;AAAA;AAAA;AAKA;EACE;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAMA;AACE;EACA;AAEA;EACA;AAEA;EACA;;AAEA;EACE;EACA,qLAEkE;;;AC9BxE;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAEA;EACE;;AAKN;EAEI;IACE;;;;AAMR;EACE;IACE;;EAGF;IACE;;;AC/CJ;EACE;EACA;;;AAGF;EAEE;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;;AAOV;EArEF;IAsEI;;;;AAIJ;EACE;IACE;;;AAIJ;EACE;IACE;;;AAIJ;EACE;IACE;;;AC5FJ;EAEE;EACA;EAGA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAEA;EACE;EACA;AAEA;EACA;EACA;EACA;EACA;;AAtCN;AA0CE;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAbJ;AAgBE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AASA;AACE;EACA;EACA;EACA;AAEA;EACA;;AAGA;EACE;;AAKF;EACE;;AAIF;EACE;EACA,yFAC2C;EAE3C;;AAGF;EACE;IACE;;;AAOJ;EADF;IAEI;;;AAKN;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGA;EACE;EACA;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAKN;EACE;EACA;;AAGF;EACE;EAEA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAIF;EAdF;IAeI;;;AAIJ;EAxKF;IAyKI;;;;AC3KJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AACE;EACA;EAGA;EACA;EAIA;EACA;;AAGE;EACE;;AAKF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAIF;EApBF;IAqBI;;;AA9CN;AAkDE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAOA;EACE;EACA,uBACE;EAEF;EACA;AAEA;AAAA;AAAA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;EACA;EACA;;AAEA;EACE;IACE;;;AAlBV;AAwBE;AAAA;AAAA;AAAA;AAAA;;AAKA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;IACE;IACA;;;AAMR;EA7DF;IA8DI;IAEA;IACA;IACA;;EAEA;IACE;IACA;;EAEA;IACE;IACA;;;AAMN;EAhFF;IAiFI;IACA;IACA;;EAEA;IACE;IACA;;;;ACtJR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;EAEE;EAGA;EACA;AAAA;AAAA;EAGA;EAGA;EAEA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGA;EACE;;AAKF;EACE;EACA;;AAIF;EACE;EACA;;AAMN;EApDF;IAqDI;IACA;AAEA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;;EAEA;IACE;;EAGF;IACE;IACA;IACA;;EAEA;IACE;;EAGF;IACE;;EAGF;IACE;IACA;IACA;;EAGF;IACE;;EAEA;IACE;IACA;;EAGF;IACE;;;;AC1GV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA;EAEE;EACA;EACA;EACA;EAEA;EACA;EACA,uBACE;EAEF;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAEA;EAEI;IACE;IACA;IACA;;;AAMR;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAMR;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAIJ;EACE;IACE;;EAEA;IACE;;;;AAMR;EACE;IACE;;;AClJJ;AAAA;AAAA;AAAA;AAIA;EAEE;EAGA;EAGA;EAGA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;AAEA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;AAEA;;AACA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;IACE;;;AAKN;EACE;;AA9BJ;AAiCE;;AACA;EACE;AAEA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEI;IACE;IACA;;;AAKN;EAEI;IACE;IACA;;;AAOV;EACE;;AAIJ;EAtIF;IAuII;IACA;;;AAGF;EA3IF;IA4II;IACA;IACA;IACA;;;AAGF;EACE;IACE;IACA;;EAEA;IACE;;;;AAMR;AAAA;AAAA;AAAA;AAIA;EACE;EACA;EACA;EACA;EACA;EAEA;;AAEA;EACE;EACA;EACA;;AAGE;EACE;;AAIF;EACE;;AAGF;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAMJ;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAOR;EACE;EAEA;EACA;EACA;EACA;;AAGA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAIE;EACE;IACE;;;;ACzPZ;EAEE;EACA;EACA;EAEA;EACA;EACA,qBACE;EAEF;EACA;EACA;AAEA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAEA;EAEI;IACE;IACA;IACA;;;AAMR;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAMR;EACE;IACE;;EAEA;IACE;;;;ACjHV;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA","file":"main.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../../src/sass/base/polices/_lato.scss","../../src/sass/base/polices/_myriad.scss","../../src/sass/abstracts/_variables.scss","../../src/sass/base/_base.scss","../../src/sass/base/_typographie.scss","../../src/sass/base/elements/_boutons.scss","../../src/sass/base/elements/_formulaires.scss","../../src/sass/base/elements/_images.scss","../../src/sass/base/elements/_liens.scss","../../src/sass/base/elements/_listes.scss","../../src/sass/layouts/_bandeau.scss","../../src/sass/layouts/_menu-mobile.scss","../../src/sass/layouts/_en-tete.scss","../../src/sass/layouts/_menu-categories-produits.scss","../../src/sass/layouts/_colonnes-photos.scss","../../src/sass/layouts/_grille-produits.scss","../../src/sass/layouts/_informations-produit.scss","../../src/sass/layouts/_produits-similaires.scss","../../src/sass/layouts/_pied-de-page.scss"],"names":[],"mappings":";AAAA;EACE;EACA;EACA;EACA;EACA,KACE;EAQF,eACE;;AAmBJ;EACE;EACA;EACA;EACA;EACA,KACE;EAQF,eACE;;ACjDJ;EACE;EACA;EACA;EACA;EACA;EACA,KACE;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA,KACE;;ACjBJ;AACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AAEA;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;EAGA;EACA;AAAA;AAAA;EAGA;AAAA;AAAA;AAAA;AAKA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACjDF;AAAA;AAAA;AAGA;EACE;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAIA;EACE;EACA;EACA;;;AAGF;AAAA;AAAA;AAGA;EACE;;;AAGF;AAAA;AAAA;AAGA;EACE;;;AAGF;AACA;EACE;;;AAGF;AACA;EACE;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;;;AAGF;AAAA;AAAA;AAGA;EACE;IACE;IACA;IACA;;EAGF;IACE;;;AC5FJ;AAAA;AAAA;AAAA;AAIA;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AC1BA;AAAA;AAAA;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;IACE;IACA;;;AAKN;EACE;EAEA;;AAIF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAKN;EACE;EACA;;AAIA;EADF;IAEI;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;IACE;IACA;;;;AC/FV;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EAEA;;;AAKF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;;AAQJ;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGA;EACE;EACA;EACA;EACA;;AAGF;EACE;IACE;;;AAKN;EACE;;AA3BJ;AA8BE;AAAA;AAAA;;AAGA;EACE;EACA;;AAGF;EACE;IACE;;;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMJ;EACE;IACE;;;;AC7HN;AAAA;AAAA;AAAA;AAAA;AAKA;EACE;EACA;;;AAGF;EACE;EACA;;;ACZF;AAAA;AAAA;AAAA;AAAA;AAKA;AACE;EACA;EAEA;EACA;EACA;EACA,YACE,uIAM4B;EAE9B;AAEA;;AACA;EACE;;AApBJ;AAuBE;;AACA;AACE;EACA;EACA;AAEA;EACA;EAEA;EACA;AAEA;;AACA;EACE;;AAbJ;AAgBE;;AACA;EACE;;AAlBJ;AAqBE;;AACA;EACE;IACE;;;AAhDR;AAqDE;;AACA;EACE;;AAEA;EACE;EACA;;AAGF;EACE;IACE;IACA;;;AAjER;AAsEE;;AAEE;EACE;IACE;;;;AC/ER;AAAA;AAAA;AAAA;AAAA;AAKA;EACE;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAMA;AACE;EACA;AAEA;EACA;AAEA;EACA;;AAEA;EACE;EACA,qLAEkE;;;AC9BxE;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAEA;EACE;;AAKN;EAEI;IACE;;;;AAMR;EACE;IACE;;EAGF;IACE;;;AC/CJ;EACE;EACA;;;AAGF;EAEE;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;;AAOV;EArEF;IAsEI;;;;AAIJ;EACE;IACE;;;AAIJ;EACE;IACE;;;AAIJ;EACE;IACE;;;AC5FJ;EAEE;EACA;EAGA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAEA;EACE;EACA;AAEA;EACA;EACA;EACA;EACA;;AAtCN;AA0CE;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAbJ;AAgBE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AASA;AACE;EACA;EACA;EACA;AAEA;EACA;;AAGA;EACE;;AAKF;EACE;;AAIF;EACE;EACA,yFAC2C;EAE3C;;AAGF;EACE;IACE;;;AAOJ;EADF;IAEI;;;AAKN;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGA;EACE;EACA;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAKN;EACE;EACA;;AAGF;EACE;EAEA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAIF;EAdF;IAeI;;;AAIJ;EAxKF;IAyKI;;;;AC3KJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AACE;EACA;EAGA;EACA;EAIA;EACA;;AAGE;EACE;;AAKF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAIF;EApBF;IAqBI;;;AA9CN;AAkDE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAOA;EACE;EACA;EAEA;EACA;AAEA;AAAA;AAAA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;EACA;EACA;;AAEA;EACE;IACE;;;AAlBV;AAwBE;AAAA;AAAA;AAAA;AAAA;;AAKA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;IACE;IACA;;;AAMR;EA5DF;IA6DI;IAEA;IACA;IACA;;EAEA;IACE;IACA;;EAEA;IACE;IACA;;;AAMN;EA/EF;IAgFI;IACA;IACA;;EAEA;IACE;IACA;;;;ACrJR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;EAEE;EAGA;EACA;AAAA;AAAA;EAGA;EAGA;EAEA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGA;EACE;;AAKF;EACE;EACA;;AAIF;EACE;EACA;;AAMN;EApDF;IAqDI;IACA;AAEA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;;EAEA;IACE;;EAGF;IACE;IACA;IACA;;EAEA;IACE;;EAGF;IACE;;EAGF;IACE;IACA;IACA;;EAGF;IACE;;EAEA;IACE;IACA;;EAGF;IACE;;;;AC1GV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA;EAEE;EACA;EACA;EACA;EAEA;EACA;EACA;EAEA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAEA;EAEI;IACE;IACA;IACA;;;AAMR;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAMR;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAIJ;EACE;IACE;;EAEA;IACE;;;;AAMR;EACE;IACE;;;ACjJJ;AAAA;AAAA;AAAA;AAIA;EAEE;EAGA;EAGA;EAGA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;AAEA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;AAEA;;AACA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;IACE;;;AAKN;EACE;;AA9BJ;AAiCE;;AACA;EACE;AAEA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEI;IACE;IACA;;;AAKN;EAEI;IACE;IACA;;;AAOV;EACE;;AAIJ;EAtIF;IAuII;IACA;;;AAGF;EA3IF;IA4II;IACA;IACA;IACA;;;AAGF;EACE;IACE;IACA;;EAEA;IACE;;;;AAMR;AAAA;AAAA;AAAA;AAIA;EACE;EACA;EACA;EACA;EACA;EAEA;;AAEA;EACE;EACA;EACA;;AAGE;EACE;;AAIF;EACE;;AAGF;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAMJ;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAOR;EACE;EAEA;EACA;EACA;EACA;;AAGA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAIE;EACE;IACE;;;;ACzPZ;EAEE;EACA;EACA;EAEA;EACA;EACA,qBACE;EAEF;EACA;EACA;AAEA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAEA;EAEI;IACE;IACA;IACA;;;AAMR;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAMR;EACE;IACE;;EAEA;IACE;;;;ACjHV;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA","file":"main.css"} \ No newline at end of file diff --git a/web/app/themes/haiku-atelier-2024/assets/css/main.min.css b/web/app/themes/haiku-atelier-2024/assets/css/main.min.css index 608ddce3..118b2cc7 100755 --- a/web/app/themes/haiku-atelier-2024/assets/css/main.min.css +++ b/web/app/themes/haiku-atelier-2024/assets/css/main.min.css @@ -1 +1 @@ -@font-face{font-family:Lato;font-weight:100 900;font-style:normal;font-display:swap;src:url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-webfont.woff2)format("woff2")tech(variations),url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-webfont.woff2)format("woff2-variations"),url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-webfont.woff2)format("woff2"),url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-webfont.ttf)format("truetype");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Lato;font-weight:100 900;font-style:italic;font-display:swap;src:url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-italic-webfont.woff2)format("woff2")tech(variations),url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-italic-webfont.woff2)format("woff2-variations"),url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-italic-webfont.woff2)format("woff2"),url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-italic-webfont.ttf)format("truetype");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Myriad;font-weight:300 900;font-style:normal;font-display:swap;font-stretch:70% 110%;src:url(/app/themes/haiku-atelier-2024/assets/fonts/myriad/myriad-variable.woff2)format("woff2"),url(/app/themes/haiku-atelier-2024/assets/fonts/myriad/myriad-variable.ttf)format("truetype")}@font-face{font-family:Myriad;font-weight:300 900;font-style:italic;font-display:swap;font-stretch:70% 110%;src:url(/app/themes/haiku-atelier-2024/assets/fonts/myriad/myriad-variable-italic.woff2)format("woff2"),url(/app/themes/haiku-atelier-2024/assets/fonts/myriad/myriad-variable-italic.ttf)format("truetype")}:root{--couleur-blanc:#fff;--couleur-blanc-fond:#ffffffe6;--couleur-gris:#eceaeb;--couleur-gris-fonce:gray;--couleur-gris-fonce-fond:#808080cc;--couleur-bordeaux:#490918;--couleur-bordeaux-fond:#490918cc;--couleur-jaune:#defdb5;--couleur-jaune-fond:#ebffb8cc;--couleur-noir:#202020;--couleur-fond:#eceaebcc;--police-lato:"Lato", sans-serif;--hauteur-ligne-classique:1.5;--hauteur-ligne-moitie:1.2;--hauteur-ligne-compacte:1.1;--hauteur-ligne-rapprochee:1;--espacement-inter-lettres-rapproche-m:-1px;--espacement-inter-lettres-rapproche-s:-.5px;--espacement-inter-lettres-etendu-s:.5px;--espacement-inter-lettres-etendu-m:1px;--espacement-inter-lettres-etendu-l:1.5px;--espacement-inter-lettres-etendu-xl:2px;--en-tete-hauteur:61px;--menu-categories-produits-hauteur:calc(var(--espace-m) * 2 + 1rlh);--pied-de-page-hauteur:calc(.8rem * 1.5 * 3 + var(--espace-s) * 2);--contenu-page-hauteur-minimale-sans-categories:calc(100svh - var(--en-tete-hauteur) - var(--pied-de-page-hauteur));--contenu-page-hauteur-minimale-avec-categories:calc(100svh - var(--en-tete-hauteur) - var(--pied-de-page-hauteur) - var(--menu-categories-produits-hauteur));--espace-2xs:.1rem;--espace-xs:.25rem;--espace-s:.5rem;--espace-m:1rem;--espace-l:1.25rem;--espace-xl:2rem}html{box-sizing:border-box}*,:before,:after{box-sizing:inherit;font:inherit;color:inherit;outline-offset:-2px;outline:2px dashed #0000;margin:0;padding:0}@view-transition{navigation:auto}body{overscroll-behavior:none;accent-color:var(--couleur-jaune);background:var(--couleur-gris)}button,input,select,textarea{font:inherit}::selection{background:var(--couleur-jaune)}[hidden]{display:none!important}:focus-visible{outline-color:var(--couleur-noir);transition:outline-color .2s}.visuellement-cache:not(:focus,:active,:focus-within){white-space:nowrap;clip-path:inset(50%);width:1px;height:1px;position:absolute;overflow:hidden}[disabled]{cursor:not-allowed}@media (prefers-reduced-motion){*,:before,:after{scroll-behavior:auto!important;transition:none!important;animation-duration:0s!important}@view-transition{}}html{font:1rem/var(--hauteur-ligne-classique) Lato;font-optical-sizing:auto;font-variant-ligatures:common-ligatures no-discretionary-ligatures no-historical-ligatures contextual;font-kerning:normal;color:var(--couleur-noir);text-decoration-skip-ink:auto;text-size-adjust:none;text-rendering:geometricprecision;letter-spacing:var(--espacement-inter-lettres-etendu-s);-webkit-font-smoothing:antialiased}strong{font-weight:600}em{font-style:italic}button{all:initial;cursor:pointer;box-sizing:border-box;text-align:center;letter-spacing:inherit;outline-offset:-2px;outline:2px dashed #0000;font-family:Lato;transition:background .2s,color .2s,outline-color .2s}button:not[disabled]:focus-visible{z-index:5;outline-color:var(--couleur-noir)}button:not[disabled]:active{color:var(--couleur-blanc)!important;background:var(--couleur-noir)!important}@media (hover:hover){button:not[disabled]:hover{color:var(--couleur-noir);background:var(--couleur-jaune)}}button:disabled,button[disabled]{background:repeating-conic-gradient(var(--couleur-noir) 0% 25%, transparent 0% 100%) 1px .5px/2px 2px;outline-color:#0000}button.bouton-case-pleine{width:100%;height:100%}button.bouton-case-pleine.bouton-blanc-sur-noir{text-transform:uppercase;letter-spacing:var(--espacement-inter-lettres-etendu-m);font-style:italic}button.bouton-case-pleine.bouton-blanc-sur-noir:focus-visible{color:var(--couleur-noir);background:var(--couleur-jaune)}button.bouton-blanc-sur-noir{color:var(--couleur-blanc);background:var(--couleur-noir)}@media (hover:hover){button.bouton-fleche{background:initial}}button.bouton-retour-haut{right:var(--espace-xl);bottom:calc(var(--espace-l) + var(--pied-de-page-hauteur));padding:var(--espace-m);border:1px solid var(--couleur-noir);visibility:hidden;opacity:0;background:var(--couleur-fond);box-shadow:initial;z-index:500;border-radius:100%;transition:background .2s,opacity .2s,visibility .2s;position:fixed;transform:rotate(180deg)}button.bouton-retour-haut img{background:0 0;width:1rem;height:1rem}button.bouton-retour-haut[data-actif]{visibility:visible;opacity:.6}@media (hover:hover){button.bouton-retour-haut[data-actif]:hover{opacity:1;background:var(--couleur-jaune-fond)}}fieldset{all:initial;margin-top:var(--espace-l);font:inherit;flex-flow:column;display:flex}input,select,textarea{padding:var(--espace-xs);border:1px solid var(--couleur-noir);accent-color:var(--couleur-jaune);background:var(--couleur-gris);transition:background .2s}input:focus-visible,input:focus-within,input:active,select:focus-visible,select:focus-within,select:active,textarea:focus-visible,textarea:focus-within,textarea:active{z-index:10;outline:2px dashed var(--couleur-noir)}input:disabled,input[disabled],select:disabled,select[disabled],textarea:disabled,textarea[disabled]{background:repeating-conic-gradient(var(--couleur-noir) 0% 25%, transparent 0% 100%) 1px .5px/2px 2px;outline-color:#0000}input:is([type=email],[type=text],[type=tel])::placeholder,textarea::placeholder{text-transform:lowercase;letter-spacing:var(--espacement-inter-lettres-etendu-s)}input:is([type=email],[type=text],[type=tel])::selection,textarea::selection{color:var(--couleur-blanc);background:var(--couleur-noir)}input:is([type=email],[type=text],[type=tel]):user-valid,textarea:user-valid{background:var(--couleur-jaune)}input:is([type=email],[type=text],[type=tel]):user-invalid,textarea:user-invalid{background:var(--couleur-gris)}input,label,select,textarea{cursor:pointer}input[type=checkbox],input[type=radio]{width:var(--espace-l);height:var(--espace-l);padding:initial;border:1px solid var(--couleur-noir);appearance:none;transition:background .2s}input[type=checkbox]:checked,input[type=radio]:checked{background:var(--couleur-jaune)}input[type=checkbox]:checked:before,input[type=radio]:checked:before{content:"x";position:relative;bottom:.1rem;left:.35rem}@media (hover:hover){input[type=checkbox]:checked:hover,input[type=radio]:checked:hover{color:var(--couleur-noir)}}input[type=checkbox]:not(:checked):user-valid,input[type=radio]:not(:checked):user-valid{background:initial}label:has(~input[type=checkbox],~input[type=radio]),input[type=checkbox]+label,input[type=radio]+label{padding-top:1px;font-size:.9rem}@media (hover:hover){input[type=checkbox]:hover,input[type=radio]:hover{background:var(--couleur-jaune)}}input[type=radio]{appearance:initial;border-radius:100%}input[type=radio]:checked{place-content:center;place-items:center;display:inline-flex}input[type=radio]:checked:before{content:" ";inset:initial;width:calc(var(--espace-l) / 2);height:calc(var(--espace-l) / 2);background:var(--couleur-noir);border-radius:100%;display:inline-block}@media (hover:hover){textarea:hover{color:var(--couleur-noir)}}img,picture{max-width:100%;display:block}img{object-fit:cover;background:var(--couleur-jaune)}a{--lien-contour-couleur-focus:var(--couleur-noir);text-decoration-skip-ink:auto;text-decoration-skip:edges;text-decoration:underline #0000;transition:background .2s,border-color .2s,color .2s,font-weight .2s,outline-color .2s,letter-spacing .2s,text-decoration-color .2s}a:focus-visible{outline-color:var(--lien-contour-couleur-focus)}a.lien-bouton{--lien-bouton-marges-internes-bloc:var(--espace-xs);--lien-bouton-marges-internes-ligne:var(--espace-m);--lien-bouton-arriere-plan-couleur-survol:var(--couleur-jaune);padding:var(--lien-bouton-marges-internes-bloc) var(--lien-bouton-marges-internes-ligne);border:1px solid var(--couleur-noir)}a.lien-bouton:focus-visible{background:var(--lien-bouton-arriere-plan-couleur-survol)}a.lien-bouton:active{border-color:var(--lien-bouton-arriere-plan-couleur-survol)}@media (hover:hover){a.lien-bouton:hover{background:var(--lien-bouton-arriere-plan-couleur-survol)}}a.lien-lien{text-decoration:underline}a.lien-lien:active{text-decoration-color:var(--couleur-jaune);background:var(--couleur-jaune)}@media (hover:hover){a.lien-lien:hover{text-decoration-color:var(--couleur-jaune);background:var(--couleur-jaune)}a:not([class]):hover{text-decoration-color:var(--couleur-noir)}}ul{list-style:none}ul.avec-puce-cercle{--liste-puce-cercle-lien-marges-internes-ligne-debut:2ch;--liste-puce-cercle-puce-position-horizontale:1ch;--liste-puce-cercle-puce-taille:1.25ex}ul.avec-puce-cercle a{padding-left:var(--liste-puce-cercle-lien-marges-internes-ligne-debut);background:no-repeat var(--liste-puce-cercle-puce-position-horizontale) center/var(--liste-puce-cercle-puce-taille) url(/app/themes/haiku-atelier-2024/assets/img/icons/dot.svg)}.bandeau{column-gap:var(--espace-m);border-top:1px solid var(--couleur-noir);width:100%;color:var(--couleur-noir);text-transform:uppercase;white-space:nowrap;background:var(--couleur-jaune);font-style:italic;display:flex;overflow:hidden}.bandeau__conteneur{column-gap:var(--espace-m);flex-flow:row;animation:15s linear infinite both marquee;display:flex}.bandeau__conteneur ::selection{color:var(--couleur-jaune);background:var(--couleur-noir)}.bandeau__conteneur p{padding:var(--espace-s) 0;display:inline-block}.bandeau__conteneur p strong{font-weight:600}@media (hover:hover){.bandeau:hover .bandeau__conteneur{animation-play-state:paused}}@keyframes marquee{0%{transform:translate(0%)}to{transform:translate(-100%)}}body:has(#menu-mobile:not([aria-hidden=true])){touch-action:none;overflow:hidden}#menu-mobile{--menu-mobile-hauteur:calc(100svh - var(--en-tete-hauteur));z-index:997;inset:var(--en-tete-hauteur) 0 0 0;overscroll-behavior:contain;width:100vw;height:var(--menu-mobile-hauteur);transition:display .4s;transition:display .4s allow-discrete;-webkit-overflow-scrolling:none;display:flex;position:fixed;overflow:hidden}#menu-mobile[aria-hidden=true]{animation:.4s both fade-out;display:none}#menu-mobile[aria-hidden=true] .menu-modale__fond{animation:.4s both fade-out}#menu-mobile .menu-modale__fond{z-index:998;inset:var(--en-tete-hauteur) 0 0 0;height:var(--menu-mobile-hauteur);opacity:0;background-color:var(--couleur-fond);animation:.4s both fade-in;position:fixed}#menu-mobile .menu-modale__conteneur{z-index:999;width:100%;height:fit-content;padding:var(--espace-xl);border-bottom:1px solid var(--couleur-noir);opacity:0;background-color:var(--couleur-gris);flex-flow:column;animation:.4s .2s both fade-in;display:flex;position:relative}#menu-mobile .menu-modale__conteneur .menu-navigation{grid-template-columns:1fr}#menu-mobile .menu-modale__conteneur .menu-navigation ul{grid-column:initial;flex-flow:column;place-items:center}#menu-mobile .menu-modale__conteneur .menu-navigation ul>span{width:fit-content}#menu-mobile .menu-modale__conteneur .menu-navigation ul>span li a{padding-top:var(--espace-m);padding-bottom:var(--espace-m)}@media (width>1000px){#menu-mobile{display:none}}@keyframes fade-in{to{opacity:1}}@keyframes fade-out{to{opacity:0}}@keyframes slide-in{to{transform:translateY(0)}}#en-tete{--en-tete-marges-internes-ligne:var(--espace-xl);--en-tete-marges-internes-bloc:var(--espace-m);--en-tete-section-hauteur:var(--en-tete-hauteur);--en-tete-logo-longueur:160px;z-index:60;min-width:100vw;max-width:100vw;height:var(--en-tete-hauteur);padding:var(--en-tete-marges-internes-bloc) var(--en-tete-marges-internes-ligne);border-bottom:1px solid var(--couleur-noir);background:var(--couleur-gris);flex-flow:row;justify-content:space-between;place-items:center;display:flex;position:fixed;top:0}#en-tete picture,#en-tete img{background:0 0}#en-tete .logo{width:var(--en-tete-logo-longueur)}#en-tete .logo img{object-fit:contain;width:100%;height:40px;image-rendering:crisp-edges;shape-rendering:geometricprecision;margin-left:-6px}#en-tete .menu-navigation{text-align:center;text-transform:lowercase;flex:1;grid-template-columns:1fr auto 1fr;font-size:1.1rem;display:grid}#en-tete .menu-navigation ul{gap:var(--espace-m);flex-flow:row;grid-column:2;justify-content:space-between;display:flex}#en-tete .menu-navigation__entree{--nav-entree-marges-internes-bloc:var(--espace-xs);--nav-entree-marges-internes-ligne:3rem;--liste-puce-cercle-lien-marges-internes-ligne-debut:calc(var(--espace-m) + 1.5ch);--liste-puce-cercle-puce-position-horizontale:3.5ch}#en-tete .menu-navigation__entree:has(a[aria-current=page]),#en-tete .menu-navigation__entree--courante{background:url(/app/themes/haiku-atelier-2024/assets/img/icons/cloud-penche.svg) 50%/auto 90% no-repeat}#en-tete .menu-navigation__entree a{padding:var(--nav-entree-marges-internes-bloc) var(--nav-entree-marges-internes-ligne);text-align:center;display:inline-block}@media (hover:hover){#en-tete .menu-navigation__entree:hover{background:url(/app/themes/haiku-atelier-2024/assets/img/icons/cloud-penche.svg) 50%/auto 90% no-repeat}}@media (width<=1000px){#en-tete .menu-navigation#menu-navigation-en-tete{display:none}}#en-tete .compte-panier{text-align:center;flex-flow:row;place-items:center;gap:1rem;display:flex}#en-tete .compte-panier[disabled]{background:repeating-conic-gradient(var(--couleur-noir) 0% 25%, transparent 0% 100%) 1px .5px/2px 2px}#en-tete .compte-panier[disabled] a:hover,#en-tete .compte-panier[disabled] a:active,#en-tete .compte-panier[disabled] a:focus-within{border:1px solid var(--couleur-noir);background:initial}#en-tete .compte-panier a{padding-block:var(--espace-2xs);padding-inline:var(--espace-s);text-transform:lowercase}#en-tete .compte-panier a.lien-compte{border-color:#0000}#en-tete .compte-panier a[data-contient-articles=true]{background:var(--couleur-jaune)}#en-tete .conteneur{column-gap:var(--espace-m);display:flex}#en-tete .bouton-menu-mobile{--hauteur-bouton-menu:22px;align-content:center;display:none}#en-tete .bouton-menu-mobile img{height:var(--hauteur-bouton-menu);object-fit:contain;image-rendering:crisp-edges;shape-rendering:geometricprecision}@media (width<=1000px){#en-tete .bouton-menu-mobile{display:block}}@media (width<=600px){#en-tete{--en-tete-marges-internes-ligne:var(--espace-l)}}#menu-categories-produits{--menu-entree-longueur-minimale:13ch;--menu-section-marges-bloc-debut:var(--en-tete-hauteur);--menu-entree-marges-internes-ligne:var(--espace-m);margin-top:var(--menu-section-marges-bloc-debut);position:relative}#menu-categories-produits[data-entrees-presentes-debut] svg:first-of-type,#menu-categories-produits[data-entrees-presentes-fin] svg:last-of-type{opacity:1}#menu-categories-produits svg{pointer-events:none;opacity:0;mix-blend-mode:exclusion;shape-rendering:geometricprecision;width:.8rem;height:.8rem;transition:opacity .2s;position:absolute;bottom:calc(17.59px - .35rem)}#menu-categories-produits svg:first-of-type{left:var(--espace-xs)}#menu-categories-produits svg:last-of-type{right:var(--espace-xs)}@media (width>600px){#menu-categories-produits svg{visibility:hidden}}#menu-categories-produits ul{grid-template-columns:repeat(auto-fit, minmax(var(--menu-entree-longueur-minimale), 1fr));place-items:center;gap:1px;display:grid}#menu-categories-produits ul li{width:100%;color:var(--couleur-gris);text-align:center;text-transform:uppercase;letter-spacing:var(--espacement-inter-lettres-etendu-m);background:var(--couleur-noir);font-style:italic;font-weight:450}#menu-categories-produits ul li.categorie-courante a{color:var(--couleur-noir);background:var(--couleur-jaune);font-weight:600}@media (hover:hover){#menu-categories-produits ul li.categorie-courante a:hover{color:var(--couleur-noir)}}#menu-categories-produits ul li a{width:inherit;padding:var(--menu-entree-marges-internes-ligne) 0;outline:initial;text-decoration:none;display:inline-block}#menu-categories-produits ul li a:focus-visible{color:var(--couleur-jaune);outline:initial}@media (hover:hover){#menu-categories-produits ul li a:hover{color:var(--couleur-noir);background:var(--couleur-jaune)}}@media (width<=1000px){#menu-categories-produits ul{--menu-entree-marges-internes-ligne:var(--espace-s);flex-flow:wrap;font-size:.8rem;display:flex}#menu-categories-produits ul li{flex-grow:1;width:min(140px,100%)}#menu-categories-produits ul li a{border:initial;width:100%}}@media (width<=600px){#menu-categories-produits ul{scrollbar-width:none;flex-flow:row;overflow-x:scroll}#menu-categories-produits ul li{width:initial;min-width:140px}}.photos-produit{--colonne-gauche-position-haut:var(--menu-categories-produits-hauteur);--colonne-gauche-photo-hauteur:calc(100svh - var(--menu-categories-produits-hauteur));--colonne-droite-photo-hauteur-minimale:calc(100svh + var(--en-tete-hauteur) + var(--menu-categories-produits-hauteur));--colonne-photo-longueur-minimale:30rem;--section-marges-externes-bloc-fin:1rem;flex-flow:row;max-width:100%;display:flex;position:relative}.photos-produit .colonne{width:min(var(--colonne-photo-longueur-minimale), 100%);flex-flow:column;flex-grow:1;display:flex;position:relative}.photos-produit .colonne.colonne-gauche{top:var(--colonne-gauche-position-haut);height:var(--colonne-gauche-photo-hauteur);position:sticky}.photos-produit .colonne.colonne-gauche figure,.photos-produit .colonne.colonne-gauche picture,.photos-produit .colonne.colonne-gauche img{height:100%}.photos-produit .colonne.colonne-droite img{width:100%;max-height:var(--colonne-droite-photo-hauteur-minimale)}.photos-produit .colonne.colonne-droite figure picture img:only-child{min-height:var(--colonne-droite-photo-hauteur-minimale);max-height:var(--colonne-droite-photo-hauteur-minimale)}@media (width<=60rem){.photos-produit{--colonne-droite-photo-hauteur-minimale:var(--photo-hauteur-maximum);--photo-longueur-maximum:calc(100% - var(--espace-xl));--photo-hauteur-maximum:calc(100svh - var(--en-tete-hauteur) - 87px);scroll-behavior:smooth;scrollbar-width:none;scroll-snap-type:x mandatory;width:fit-content;max-width:initial;flex-flow:row;overflow-x:scroll}.photos-produit::-webkit-scrollbar{display:none}.photos-produit .colonne{scroll-snap-type:x mandatory;width:100%;min-width:100%}.photos-produit .colonne figure{scroll-snap-align:none center}.photos-produit .colonne img{max-height:var(--photo-hauteur-maximum)}.photos-produit .colonne.colonne-gauche{position:initial;min-width:var(--photo-longueur-maximum);height:initial}.photos-produit .colonne.colonne-droite{flex-flow:row}.photos-produit .colonne.colonne-droite figure{min-width:var(--photo-longueur-maximum);flex-grow:1}.photos-produit .colonne.colonne-droite:has(figure:only-child){min-width:var(--photo-longueur-maximum)}}.grille-produits{--grille-produits-hauteur-minimale:var(--contenu-page-hauteur-minimale-avec-categories);--aucun-produit-hauteur:var(--contenu-page-hauteur-minimale-avec-categories);--carte-produit-longueur-minimale:448px;--carte-produit-longueur-maximale:1000px;grid-auto-rows:1fr;grid-template-columns:repeat(auto-fit, minmax(var(--carte-produit-longueur-minimale), 1fr));min-height:var(--grille-produits-hauteur-minimale);gap:1px;display:grid}.grille-produits article{max-width:var(--carte-produit-longueur-maximale);box-shadow:0 0 0 1px var(--couleur-noir)}.grille-produits article figure{row-gap:var(--espace-xl);flex-flow:column;display:flex}.grille-produits article figure a{position:relative}@media (hover:hover){.grille-produits article figure a:hover .produit__illustration__survol{visibility:visible;opacity:1;transition:opacity .3s,visibility .3s}}.grille-produits article figure img{position:inherit;aspect-ratio:9/16;object-fit:cover;background:0 0;width:100%;max-height:70vh}.grille-produits article figure .produit__illustration__principale{display:block}.grille-produits article figure .produit__illustration__principale:before{content:"";z-index:-1;opacity:0;filter:opacity(20%);background-image:url(/app/themes/haiku-atelier-2024/assets/img/icons/cloud-gris.svg);background-position:50%;background-repeat:no-repeat;background-size:50%;width:100%;height:100%;animation:1.5s linear .5s infinite alternate both test;position:absolute;top:0;left:0}.grille-produits article figure .produit__illustration__principale img{opacity:0;transition:opacity 1s}.grille-produits article figure .produit__illustration__survol{visibility:hidden;opacity:0;width:100%;height:100%;transition:opacity .15s,visibility .15s;display:block;position:absolute;top:0;left:0}.grille-produits article figure .produit__illustration__survol img{background:var(--couleur-fond)}.grille-produits article figure figcaption{margin-bottom:var(--espace-xl);padding:var(--espace-m);flex-flow:row;justify-content:space-between;display:flex}.grille-produits article figure figcaption h3{letter-spacing:var(--espacement-inter-lettres-etendu-m);font-style:italic}.grille-produits article figure figcaption p{letter-spacing:var(--espacement-inter-lettres-rapproche-s);font-weight:500}.grille-produits__aucun-produit{min-height:var(--aucun-produit-hauteur);text-align:center;grid-column:span 3;align-content:center}.grille-produits__aucun-produit p+p{margin-top:var(--espace-l);font-size:1.25rem}@media (width<=700px){.grille-produits{grid-template-columns:100%}.grille-produits article figure img{max-height:50svh}}@keyframes test{to{opacity:1}}.resume-produit{--resume-position-basse:0%;--section-marges-internes:var(--espace-l);--espace-inter-colonne:var(--espace-xl);--resume-police-graisse:500;--resume-police-style:italic;--resume-police-taille:var(--espace-l);--resume-police-nom-taille:1.33rem;--resume-police-selecteur-graisse:400;--resume-police-selecteur-taille:var(--espace-m);bottom:var(--resume-position-basse);position:sticky}.resume-produit .selecteur-produit{column-gap:var(--espace-inter-colonne);border-block:1px solid var(--couleur-noir);font-size:var(--resume-police-taille);font-weight:var(--resume-police-graisse);font-style:var(--resume-police-style);line-height:var(--hauteur-ligne-compacte);background:var(--couleur-blanc-fond);grid-template-columns:repeat(3,1fr);grid-auto-flow:column;place-items:center;display:grid;position:relative}.resume-produit .selecteur-produit>*{width:100%;height:100%;padding:var(--section-marges-internes);flex-flow:row;place-content:center;place-items:center;display:flex}.resume-produit .selecteur-produit>:nth-child(2){border-inline-start:1px solid var(--couleur-noir);border-inline-end:1px solid var(--couleur-noir)}.resume-produit .selecteur-produit__nom{font-size:var(--resume-police-nom-taille)}.resume-produit .selecteur-produit__attribut-variation{gap:var(--espace-m) var(--espace-l);font-size:var(--resume-police-selecteur-taille);font-weight:var(--resume-police-selecteur-graisse);text-transform:lowercase;flex-flow:wrap;display:flex}.resume-produit .selecteur-produit__attribut-variation label{margin-right:var(--espace-s)}.resume-produit .selecteur-produit__attribut-variation select{padding:var(--espace-xs) var(--espace-l);border:1px solid var(--couleur-noir);text-align:center;letter-spacing:initial;appearance:none;background:var(--couleur-fond);position:relative}@supports selector(:user-valid){.resume-produit .selecteur-produit__attribut-variation select:user-valid{background:var(--couleur-jaune-fond)}}.resume-produit .selecteur-produit__attribut-variation option{background:var(--couleur-fond)}.resume-produit .selecteur-produit__attribut-variation__selecteurs{position:relative}.resume-produit .selecteur-produit__attribut-variation__selecteurs:after{pointer-events:none;content:" ";text-align:center;visibility:visible;opacity:1;background:url(/app/themes/haiku-atelier-2024/assets/img/icons/arrow.svg) no-repeat;width:.9rem;height:.9rem;transition:opacity .2s,visibility .2s;display:inline-block;position:absolute;top:7px;right:.4rem}@supports not selector(:user-valid){.resume-produit .selecteur-produit__attribut-variation__selecteurs:has(select:valid):after{visibility:hidden;opacity:0}}@supports selector(:user-valid){.resume-produit .selecteur-produit__attribut-variation__selecteurs:has(select:user-valid):after{visibility:hidden;opacity:0}}.resume-produit .selecteur-produit__prix{font-style:initial}@media (width<=800px){.resume-produit{--section-marges-internes:var(--espace-m);--espace-inter-colonne:var(--espace-m)}}@media (width<=700px){.resume-produit{--resume-police-taille:var(--espace-m);--resume-police-nom-taille:var(--espace-m);--section-marges-internes:var(--espace-m);--espace-inter-colonne:var(--espace-s)}}@media (width<=500px){.resume-produit .selecteur-produit__selection-variation-attribut{row-gap:var(--espace-inter-colonne);flex-flow:column}.resume-produit .selecteur-produit__selection-variation-attribut h3{flex-basis:100%}}.details-produit{--bouton-marges-internes-bloc:var(--espace-l);--espace-inter-lignes:var(--espace-l);--espace-inter-texte:var(--espace-m);--section-marges-internes:var(--espace-l);--textuel-marges-internes-ligne:calc(var(--espace-l) * 2);background-color:var(--couleur-blanc)}.details-produit__textes{grid-template-columns:1fr;grid-auto-flow:row;display:grid}.details-produit__textes .section-textuelle:not(:last-of-type){border-block-end:1px solid var(--couleur-noir)}.details-produit__textes .section-textuelle:has(button[aria-expanded=false]) .section-textuelle__contenu{display:none}.details-produit__textes .section-textuelle h3{line-height:var(--hauteur-ligne-rapprochee)}.details-produit__textes .section-textuelle h3 button{width:100%;min-block-size:1lh;padding:var(--section-marges-internes);text-align:start;display:inline-block}.details-produit__textes .section-textuelle .section-textuelle__contenu{padding-block-end:var(--section-marges-internes);padding-inline:var(--textuel-marges-internes-ligne)}.details-produit__textes .section-textuelle .section-textuelle__contenu ul{list-style:inside}.details-produit__textes .section-textuelle .section-textuelle__contenu a{text-decoration-color:var(--couleur-noir)}.details-produit__textes .section-textuelle .section-textuelle__contenu>*+*{margin-top:var(--espace-inter-texte)}.details-produit__actions{--section-marges-internes:var(--espace-l);border-block:1px solid var(--couleur-noir);background:var(--couleur-jaune);transition:background .2s;overflow:hidden}.details-produit__actions:has(button[disabled]){background:var(--couleur-fond)}.details-produit__actions button{height:initial;padding:var(--section-marges-internes);text-transform:uppercase;font-style:italic;transition:background .2s,font-weight .2s}@media (hover:hover){.details-produit__actions button:not([disabled]):hover{font-weight:600}}.produits-similaires{--carte-produit-longueur-minimale:448px;--carte-produit-longueur-maximale:1000px;--en-tete-flottante-hauteur:calc(1rem + var(--espace-l) * 2 + 1px);grid-template-rows:1fr auto;grid-template-columns:repeat(3,1fr);grid-template-areas:"en-tete en-tete en-tete""produits produits produits";place-items:center;display:grid;position:relative}.produits-similaires header{z-index:10;top:var(--en-tete-flottante-hauteur);width:100%;padding:var(--espace-l) 0;color:var(--couleur-blanc);text-align:center;background:var(--couleur-noir);grid-area:en-tete;position:sticky}.produits-similaires header h2{font-style:italic;line-height:var(--hauteur-ligne-rapprochee);text-transform:uppercase;letter-spacing:var(--espacement-inter-lettres-etendu-m)}.produits-similaires .grille-produits-similaires{grid-area:produits;grid-auto-rows:1fr;grid-template-columns:repeat(auto-fit, minmax(var(--carte-produit-longueur-minimale), 1fr));gap:1px;width:100%;display:grid}.produits-similaires .grille-produits-similaires article{max-width:var(--carte-produit-longueur-maximale);box-shadow:0 0 0 1px var(--couleur-noir)}.produits-similaires .grille-produits-similaires article figure{row-gap:var(--espace-xl);flex-flow:column;display:flex}.produits-similaires .grille-produits-similaires article figure a{position:relative}@media (hover:hover){.produits-similaires .grille-produits-similaires article figure a:hover .produit__illustration__survol{visibility:visible;opacity:1;transition:opacity .3s,visibility .3s}}.produits-similaires .grille-produits-similaires article figure .produit__illustration__principale{display:block}.produits-similaires .grille-produits-similaires article figure .produit__illustration__survol{visibility:hidden;opacity:0;width:100%;height:100%;transition:opacity .15s,visibility .15s;display:block;position:absolute;top:0;left:0}.produits-similaires .grille-produits-similaires article figure img{aspect-ratio:9/16;object-fit:cover;width:100%;max-height:70svh}.produits-similaires .grille-produits-similaires article figure figcaption{margin-bottom:var(--espace-xl);padding:0 var(--espace-m);flex-flow:row;justify-content:space-between;display:flex}.produits-similaires .grille-produits-similaires article figure figcaption h3{letter-spacing:var(--espacement-inter-lettres-etendu-m);font-style:italic}.produits-similaires .grille-produits-similaires article figure figcaption p{letter-spacing:var(--espacement-inter-lettres-rapproche-s);font-weight:500}@media (width<=700px){.produits-similaires .grille-produits-similaires{grid-template-columns:100%}.produits-similaires .grille-produits-similaires article figure img{max-height:50svh}}#pied-de-page{max-width:100vw;height:var(--pied-de-page-hauteur);padding:var(--espace-s) var(--espace-m);border-top:1px solid var(--couleur-noir);background:var(--couleur-jaune);grid-template-columns:1fr 1fr;place-items:center;font-size:.8rem;display:grid}#pied-de-page .zone-menu-navigation-secondaire{text-transform:lowercase;justify-self:start;width:100%;height:100%}#pied-de-page .zone-liens-reseaux-sociaux{text-align:right;justify-items:end;width:100%;height:100%} \ No newline at end of file +@font-face{font-family:Lato;font-weight:100 900;font-style:normal;font-display:swap;src:url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-webfont.woff2)format("woff2")tech(variations),url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-webfont.woff2)format("woff2-variations"),url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-webfont.woff2)format("woff2"),url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-webfont.ttf)format("truetype");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Lato;font-weight:100 900;font-style:italic;font-display:swap;src:url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-italic-webfont.woff2)format("woff2")tech(variations),url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-italic-webfont.woff2)format("woff2-variations"),url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-italic-webfont.woff2)format("woff2"),url(/app/themes/haiku-atelier-2024/assets/fonts/lato/lato-variable-italic-webfont.ttf)format("truetype");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Myriad;font-weight:300 900;font-style:normal;font-display:swap;font-stretch:70% 110%;src:url(/app/themes/haiku-atelier-2024/assets/fonts/myriad/myriad-variable.woff2)format("woff2"),url(/app/themes/haiku-atelier-2024/assets/fonts/myriad/myriad-variable.ttf)format("truetype")}@font-face{font-family:Myriad;font-weight:300 900;font-style:italic;font-display:swap;font-stretch:70% 110%;src:url(/app/themes/haiku-atelier-2024/assets/fonts/myriad/myriad-variable-italic.woff2)format("woff2"),url(/app/themes/haiku-atelier-2024/assets/fonts/myriad/myriad-variable-italic.ttf)format("truetype")}:root{--couleur-blanc:#fff;--couleur-blanc-fond:#ffffffe6;--couleur-gris:#eceaeb;--couleur-gris-fonce:gray;--couleur-gris-fonce-fond:#808080cc;--couleur-bordeaux:#490918;--couleur-bordeaux-fond:#490918cc;--couleur-jaune:#defdb5;--couleur-jaune-fond:#ebffb8cc;--couleur-noir:#202020;--couleur-fond:#eceaebcc;--police-lato:"Lato", sans-serif;--hauteur-ligne-classique:1.5;--hauteur-ligne-moitie:1.2;--hauteur-ligne-compacte:1.1;--hauteur-ligne-rapprochee:1;--espacement-inter-lettres-rapproche-m:-1px;--espacement-inter-lettres-rapproche-s:-.5px;--espacement-inter-lettres-etendu-s:.5px;--espacement-inter-lettres-etendu-m:1px;--espacement-inter-lettres-etendu-l:1.5px;--espacement-inter-lettres-etendu-xl:2px;--en-tete-hauteur:61px;--menu-categories-produits-hauteur:calc(var(--espace-m) * 2 + 1rlh);--pied-de-page-hauteur:calc(.8rem * 1.5 * 3 + var(--espace-s) * 2);--contenu-page-hauteur-minimale-sans-categories:calc(100svh - var(--en-tete-hauteur) - var(--pied-de-page-hauteur));--contenu-page-hauteur-minimale-avec-categories:calc(100svh - var(--en-tete-hauteur) - var(--pied-de-page-hauteur) - var(--menu-categories-produits-hauteur));--espace-2xs:.1rem;--espace-xs:.25rem;--espace-s:.5rem;--espace-m:1rem;--espace-l:1.25rem;--espace-xl:2rem}html{box-sizing:border-box}*,:before,:after{box-sizing:inherit;font:inherit;color:inherit;outline-offset:-2px;outline:2px dashed #0000;margin:0;padding:0}@view-transition{navigation:auto}body{overscroll-behavior:none;accent-color:var(--couleur-jaune);background:var(--couleur-gris)}button,input,select,textarea{font:inherit}::selection{background:var(--couleur-jaune)}[hidden]{display:none!important}:focus-visible{outline-color:var(--couleur-noir);transition:outline-color .2s}.visuellement-cache:not(:focus,:active,:focus-within){white-space:nowrap;clip-path:inset(50%);width:1px;height:1px;position:absolute;overflow:hidden}[disabled]{cursor:not-allowed}@media (prefers-reduced-motion){*,:before,:after{scroll-behavior:auto!important;transition:none!important;animation-duration:0s!important}@view-transition{}}html{font:1rem/var(--hauteur-ligne-classique) Lato;font-optical-sizing:auto;font-variant-ligatures:common-ligatures no-discretionary-ligatures no-historical-ligatures contextual;font-kerning:normal;color:var(--couleur-noir);text-decoration-skip-ink:auto;text-size-adjust:none;text-rendering:geometricprecision;letter-spacing:var(--espacement-inter-lettres-etendu-s);-webkit-font-smoothing:antialiased}strong{font-weight:600}em{font-style:italic}button{all:initial;cursor:pointer;box-sizing:border-box;text-align:center;letter-spacing:inherit;outline-offset:-2px;outline:2px dashed #0000;font-family:Lato;transition:background .2s,color .2s,outline-color .2s}button:not[disabled]:focus-visible{z-index:5;outline-color:var(--couleur-noir)}button:not[disabled]:active{color:var(--couleur-blanc)!important;background:var(--couleur-noir)!important}@media (hover:hover){button:not[disabled]:hover{color:var(--couleur-noir);background:var(--couleur-jaune)}}button:disabled,button[disabled]{background:repeating-conic-gradient(var(--couleur-noir) 0% 25%, transparent 0% 100%) 1px .5px/2px 2px;outline-color:#0000}button.bouton-case-pleine{width:100%;height:100%}button.bouton-case-pleine.bouton-blanc-sur-noir{text-transform:uppercase;letter-spacing:var(--espacement-inter-lettres-etendu-m);font-style:italic}button.bouton-case-pleine.bouton-blanc-sur-noir:focus-visible{color:var(--couleur-noir);background:var(--couleur-jaune)}button.bouton-blanc-sur-noir{color:var(--couleur-blanc);background:var(--couleur-noir)}@media (hover:hover){button.bouton-fleche{background:initial}}button.bouton-retour-haut{z-index:500;right:var(--espace-xl);bottom:calc(var(--espace-l) + var(--pied-de-page-hauteur));padding:var(--espace-m);border:1px solid var(--couleur-noir);visibility:hidden;opacity:0;background:var(--couleur-fond);box-shadow:initial;border-radius:100%;transition:background .2s,opacity .2s,visibility .2s;position:fixed;transform:rotate(180deg)}button.bouton-retour-haut img{background:0 0;width:1rem;height:1rem}button.bouton-retour-haut[data-actif]{visibility:visible;opacity:.6}@media (hover:hover){button.bouton-retour-haut[data-actif]:hover{opacity:1;background:var(--couleur-jaune-fond)}}fieldset{all:initial;margin-top:var(--espace-l);font:inherit;flex-flow:column;display:flex}input,select,textarea{padding:var(--espace-xs);border:1px solid var(--couleur-noir);accent-color:var(--couleur-jaune);background:var(--couleur-gris);transition:background .2s}input:focus-visible,input:focus-within,input:active,select:focus-visible,select:focus-within,select:active,textarea:focus-visible,textarea:focus-within,textarea:active{z-index:10;outline:2px dashed var(--couleur-noir)}input:disabled,input[disabled],select:disabled,select[disabled],textarea:disabled,textarea[disabled]{background:repeating-conic-gradient(var(--couleur-noir) 0% 25%, transparent 0% 100%) 1px .5px/2px 2px;outline-color:#0000}input:is([type=email],[type=text],[type=tel])::placeholder,textarea::placeholder{text-transform:lowercase;letter-spacing:var(--espacement-inter-lettres-etendu-s)}input:is([type=email],[type=text],[type=tel])::selection,textarea::selection{color:var(--couleur-blanc);background:var(--couleur-noir)}input:is([type=email],[type=text],[type=tel]):user-valid,textarea:user-valid{background:var(--couleur-jaune)}input:is([type=email],[type=text],[type=tel]):user-invalid,textarea:user-invalid{background:var(--couleur-gris)}input,label,select,textarea{cursor:pointer}input[type=checkbox],input[type=radio]{width:var(--espace-l);height:var(--espace-l);padding:initial;border:1px solid var(--couleur-noir);appearance:none;transition:background .2s}input[type=checkbox]:checked,input[type=radio]:checked{background:var(--couleur-jaune)}input[type=checkbox]:checked:before,input[type=radio]:checked:before{content:"x";position:relative;bottom:.1rem;left:.35rem}@media (hover:hover){input[type=checkbox]:checked:hover,input[type=radio]:checked:hover{color:var(--couleur-noir)}}input[type=checkbox]:not(:checked):user-valid,input[type=radio]:not(:checked):user-valid{background:initial}label:has(~input[type=checkbox],~input[type=radio]),input[type=checkbox]+label,input[type=radio]+label{padding-top:1px;font-size:.9rem}@media (hover:hover){input[type=checkbox]:hover,input[type=radio]:hover{background:var(--couleur-jaune)}}input[type=radio]{appearance:initial;border-radius:100%}input[type=radio]:checked{place-content:center;place-items:center;display:inline-flex}input[type=radio]:checked:before{content:" ";inset:initial;width:calc(var(--espace-l) / 2);height:calc(var(--espace-l) / 2);background:var(--couleur-noir);border-radius:100%;display:inline-block}@media (hover:hover){textarea:hover{color:var(--couleur-noir)}}img,picture{max-width:100%;display:block}img{object-fit:cover;background:var(--couleur-jaune)}a{--lien-contour-couleur-focus:var(--couleur-noir);text-decoration-skip-ink:auto;text-decoration-skip:edges;text-decoration:underline #0000;transition:background .2s,border-color .2s,color .2s,font-weight .2s,outline-color .2s,letter-spacing .2s,text-decoration-color .2s}a:focus-visible{outline-color:var(--lien-contour-couleur-focus)}a.lien-bouton{--lien-bouton-marges-internes-bloc:var(--espace-xs);--lien-bouton-marges-internes-ligne:var(--espace-m);--lien-bouton-arriere-plan-couleur-survol:var(--couleur-jaune);padding:var(--lien-bouton-marges-internes-bloc) var(--lien-bouton-marges-internes-ligne);border:1px solid var(--couleur-noir)}a.lien-bouton:focus-visible{background:var(--lien-bouton-arriere-plan-couleur-survol)}a.lien-bouton:active{border-color:var(--lien-bouton-arriere-plan-couleur-survol)}@media (hover:hover){a.lien-bouton:hover{background:var(--lien-bouton-arriere-plan-couleur-survol)}}a.lien-lien{text-decoration:underline}a.lien-lien:active{text-decoration-color:var(--couleur-jaune);background:var(--couleur-jaune)}@media (hover:hover){a.lien-lien:hover{text-decoration-color:var(--couleur-jaune);background:var(--couleur-jaune)}a:not([class]):hover{text-decoration-color:var(--couleur-noir)}}ul{list-style:none}ul.avec-puce-cercle{--liste-puce-cercle-lien-marges-internes-ligne-debut:2ch;--liste-puce-cercle-puce-position-horizontale:1ch;--liste-puce-cercle-puce-taille:1.25ex}ul.avec-puce-cercle a{padding-left:var(--liste-puce-cercle-lien-marges-internes-ligne-debut);background:no-repeat var(--liste-puce-cercle-puce-position-horizontale) center/var(--liste-puce-cercle-puce-taille) url(/app/themes/haiku-atelier-2024/assets/img/icons/dot.svg)}.bandeau{column-gap:var(--espace-m);border-top:1px solid var(--couleur-noir);width:100%;color:var(--couleur-noir);text-transform:uppercase;white-space:nowrap;background:var(--couleur-jaune);font-style:italic;display:flex;overflow:hidden}.bandeau__conteneur{column-gap:var(--espace-m);flex-flow:row;animation:15s linear infinite both marquee;display:flex}.bandeau__conteneur ::selection{color:var(--couleur-jaune);background:var(--couleur-noir)}.bandeau__conteneur p{padding:var(--espace-s) 0;display:inline-block}.bandeau__conteneur p strong{font-weight:600}@media (hover:hover){.bandeau:hover .bandeau__conteneur{animation-play-state:paused}}@keyframes marquee{0%{transform:translate(0%)}to{transform:translate(-100%)}}body:has(#menu-mobile:not([aria-hidden=true])){touch-action:none;overflow:hidden}#menu-mobile{--menu-mobile-hauteur:calc(100svh - var(--en-tete-hauteur));z-index:997;inset:var(--en-tete-hauteur) 0 0 0;overscroll-behavior:contain;width:100vw;height:var(--menu-mobile-hauteur);transition:display .4s;transition:display .4s allow-discrete;-webkit-overflow-scrolling:none;display:flex;position:fixed;overflow:hidden}#menu-mobile[aria-hidden=true]{animation:.4s both fade-out;display:none}#menu-mobile[aria-hidden=true] .menu-modale__fond{animation:.4s both fade-out}#menu-mobile .menu-modale__fond{z-index:998;inset:var(--en-tete-hauteur) 0 0 0;height:var(--menu-mobile-hauteur);opacity:0;background-color:var(--couleur-fond);animation:.4s both fade-in;position:fixed}#menu-mobile .menu-modale__conteneur{z-index:999;width:100%;height:fit-content;padding:var(--espace-xl);border-bottom:1px solid var(--couleur-noir);opacity:0;background-color:var(--couleur-gris);flex-flow:column;animation:.4s .2s both fade-in;display:flex;position:relative}#menu-mobile .menu-modale__conteneur .menu-navigation{grid-template-columns:1fr}#menu-mobile .menu-modale__conteneur .menu-navigation ul{grid-column:initial;flex-flow:column;place-items:center}#menu-mobile .menu-modale__conteneur .menu-navigation ul>span{width:fit-content}#menu-mobile .menu-modale__conteneur .menu-navigation ul>span li a{padding-top:var(--espace-m);padding-bottom:var(--espace-m)}@media (width>1000px){#menu-mobile{display:none}}@keyframes fade-in{to{opacity:1}}@keyframes fade-out{to{opacity:0}}@keyframes slide-in{to{transform:translateY(0)}}#en-tete{--en-tete-marges-internes-ligne:var(--espace-xl);--en-tete-marges-internes-bloc:var(--espace-m);--en-tete-section-hauteur:var(--en-tete-hauteur);--en-tete-logo-longueur:160px;z-index:60;min-width:100vw;max-width:100vw;height:var(--en-tete-hauteur);padding:var(--en-tete-marges-internes-bloc) var(--en-tete-marges-internes-ligne);border-bottom:1px solid var(--couleur-noir);background:var(--couleur-gris);flex-flow:row;justify-content:space-between;place-items:center;display:flex;position:fixed;top:0}#en-tete picture,#en-tete img{background:0 0}#en-tete .logo{width:var(--en-tete-logo-longueur)}#en-tete .logo img{object-fit:contain;width:100%;height:40px;image-rendering:crisp-edges;shape-rendering:geometricprecision;margin-left:-6px}#en-tete .menu-navigation{text-align:center;text-transform:lowercase;flex:1;grid-template-columns:1fr auto 1fr;font-size:1.1rem;display:grid}#en-tete .menu-navigation ul{gap:var(--espace-m);flex-flow:row;grid-column:2;justify-content:space-between;display:flex}#en-tete .menu-navigation__entree{--nav-entree-marges-internes-bloc:var(--espace-xs);--nav-entree-marges-internes-ligne:3rem;--liste-puce-cercle-lien-marges-internes-ligne-debut:calc(var(--espace-m) + 1.5ch);--liste-puce-cercle-puce-position-horizontale:3.5ch}#en-tete .menu-navigation__entree:has(a[aria-current=page]),#en-tete .menu-navigation__entree--courante{background:url(/app/themes/haiku-atelier-2024/assets/img/icons/cloud-penche.svg) 50%/auto 90% no-repeat}#en-tete .menu-navigation__entree a{padding:var(--nav-entree-marges-internes-bloc) var(--nav-entree-marges-internes-ligne);text-align:center;display:inline-block}@media (hover:hover){#en-tete .menu-navigation__entree:hover{background:url(/app/themes/haiku-atelier-2024/assets/img/icons/cloud-penche.svg) 50%/auto 90% no-repeat}}@media (width<=1000px){#en-tete .menu-navigation#menu-navigation-en-tete{display:none}}#en-tete .compte-panier{text-align:center;flex-flow:row;place-items:center;gap:1rem;display:flex}#en-tete .compte-panier[disabled]{background:repeating-conic-gradient(var(--couleur-noir) 0% 25%, transparent 0% 100%) 1px .5px/2px 2px}#en-tete .compte-panier[disabled] a:hover,#en-tete .compte-panier[disabled] a:active,#en-tete .compte-panier[disabled] a:focus-within{border:1px solid var(--couleur-noir);background:initial}#en-tete .compte-panier a{padding-block:var(--espace-2xs);padding-inline:var(--espace-s);text-transform:lowercase}#en-tete .compte-panier a.lien-compte{border-color:#0000}#en-tete .compte-panier a[data-contient-articles=true]{background:var(--couleur-jaune)}#en-tete .conteneur{column-gap:var(--espace-m);display:flex}#en-tete .bouton-menu-mobile{--hauteur-bouton-menu:22px;align-content:center;display:none}#en-tete .bouton-menu-mobile img{height:var(--hauteur-bouton-menu);object-fit:contain;image-rendering:crisp-edges;shape-rendering:geometricprecision}@media (width<=1000px){#en-tete .bouton-menu-mobile{display:block}}@media (width<=600px){#en-tete{--en-tete-marges-internes-ligne:var(--espace-l)}}#menu-categories-produits{--menu-entree-longueur-minimale:13ch;--menu-section-marges-bloc-debut:var(--en-tete-hauteur);--menu-entree-marges-internes-ligne:var(--espace-m);margin-top:var(--menu-section-marges-bloc-debut);position:relative}#menu-categories-produits[data-entrees-presentes-debut] svg:first-of-type,#menu-categories-produits[data-entrees-presentes-fin] svg:last-of-type{opacity:1}#menu-categories-produits svg{pointer-events:none;opacity:0;mix-blend-mode:exclusion;shape-rendering:geometricprecision;width:.8rem;height:.8rem;transition:opacity .2s;position:absolute;bottom:calc(17.59px - .35rem)}#menu-categories-produits svg:first-of-type{left:var(--espace-xs)}#menu-categories-produits svg:last-of-type{right:var(--espace-xs)}@media (width>600px){#menu-categories-produits svg{visibility:hidden}}#menu-categories-produits ul{grid-template-columns:repeat(auto-fit, minmax(var(--menu-entree-longueur-minimale), 1fr));place-items:center;gap:1px;display:grid}#menu-categories-produits ul li{width:100%;color:var(--couleur-gris);text-align:center;text-transform:uppercase;letter-spacing:var(--espacement-inter-lettres-etendu-m);background:var(--couleur-noir);font-style:italic;font-weight:450}#menu-categories-produits ul li.categorie-courante a{color:var(--couleur-noir);background:var(--couleur-jaune);font-weight:600}@media (hover:hover){#menu-categories-produits ul li.categorie-courante a:hover{color:var(--couleur-noir)}}#menu-categories-produits ul li a{width:inherit;padding:var(--menu-entree-marges-internes-ligne) 0;outline:initial;text-decoration:none;display:inline-block}#menu-categories-produits ul li a:focus-visible{color:var(--couleur-jaune);outline:initial}@media (hover:hover){#menu-categories-produits ul li a:hover{color:var(--couleur-noir);background:var(--couleur-jaune)}}@media (width<=1000px){#menu-categories-produits ul{--menu-entree-marges-internes-ligne:var(--espace-s);flex-flow:wrap;font-size:.8rem;display:flex}#menu-categories-produits ul li{flex-grow:1;width:min(140px,100%)}#menu-categories-produits ul li a{border:initial;width:100%}}@media (width<=600px){#menu-categories-produits ul{scrollbar-width:none;flex-flow:row;overflow-x:scroll}#menu-categories-produits ul li{width:initial;min-width:140px}}.photos-produit{--colonne-gauche-position-haut:var(--menu-categories-produits-hauteur);--colonne-gauche-photo-hauteur:calc(100svh - var(--menu-categories-produits-hauteur));--colonne-droite-photo-hauteur-minimale:calc(100svh + var(--en-tete-hauteur) + var(--menu-categories-produits-hauteur));--colonne-photo-longueur-minimale:30rem;--section-marges-externes-bloc-fin:1rem;flex-flow:row;max-width:100%;display:flex;position:relative}.photos-produit .colonne{width:min(var(--colonne-photo-longueur-minimale), 100%);flex-flow:column;flex-grow:1;display:flex;position:relative}.photos-produit .colonne.colonne-gauche{top:var(--colonne-gauche-position-haut);height:var(--colonne-gauche-photo-hauteur);position:sticky}.photos-produit .colonne.colonne-gauche figure,.photos-produit .colonne.colonne-gauche picture,.photos-produit .colonne.colonne-gauche img{height:100%}.photos-produit .colonne.colonne-droite img{width:100%;max-height:var(--colonne-droite-photo-hauteur-minimale)}.photos-produit .colonne.colonne-droite figure picture img:only-child{min-height:var(--colonne-droite-photo-hauteur-minimale);max-height:var(--colonne-droite-photo-hauteur-minimale)}@media (width<=60rem){.photos-produit{--colonne-droite-photo-hauteur-minimale:var(--photo-hauteur-maximum);--photo-longueur-maximum:calc(100% - var(--espace-xl));--photo-hauteur-maximum:calc(100svh - var(--en-tete-hauteur) - 87px);scroll-behavior:smooth;scrollbar-width:none;scroll-snap-type:x mandatory;width:fit-content;max-width:initial;flex-flow:row;overflow-x:scroll}.photos-produit::-webkit-scrollbar{display:none}.photos-produit .colonne{scroll-snap-type:x mandatory;width:100%;min-width:100%}.photos-produit .colonne figure{scroll-snap-align:none center}.photos-produit .colonne img{max-height:var(--photo-hauteur-maximum)}.photos-produit .colonne.colonne-gauche{position:initial;min-width:var(--photo-longueur-maximum);height:initial}.photos-produit .colonne.colonne-droite{flex-flow:row}.photos-produit .colonne.colonne-droite figure{min-width:var(--photo-longueur-maximum);flex-grow:1}.photos-produit .colonne.colonne-droite:has(figure:only-child){min-width:var(--photo-longueur-maximum)}}.grille-produits{--grille-produits-hauteur-minimale:var(--contenu-page-hauteur-minimale-avec-categories);--aucun-produit-hauteur:var(--contenu-page-hauteur-minimale-avec-categories);--carte-produit-longueur-minimale:448px;--carte-produit-longueur-maximale:1000px;grid-auto-rows:1fr;grid-template-columns:repeat(auto-fit, minmax(var(--carte-produit-longueur-minimale), 1fr));min-height:var(--grille-produits-hauteur-minimale);gap:1px;display:grid}.grille-produits article{max-width:var(--carte-produit-longueur-maximale);box-shadow:0 0 0 1px var(--couleur-noir)}.grille-produits article figure{row-gap:var(--espace-xl);flex-flow:column;display:flex}.grille-produits article figure a{position:relative}@media (hover:hover){.grille-produits article figure a:hover .produit__illustration__survol{visibility:visible;opacity:1;transition:opacity .3s,visibility .3s}}.grille-produits article figure img{position:inherit;aspect-ratio:9/16;object-fit:cover;background:0 0;width:100%;max-height:70vh}.grille-produits article figure .produit__illustration__principale{display:block}.grille-produits article figure .produit__illustration__principale:before{content:"";z-index:-1;opacity:0;filter:opacity(20%);background-image:url(/app/themes/haiku-atelier-2024/assets/img/icons/cloud-gris.svg);background-position:50%;background-repeat:no-repeat;background-size:50%;width:100%;height:100%;animation:1.5s linear .5s infinite alternate both test;position:absolute;top:0;left:0}.grille-produits article figure .produit__illustration__principale img{opacity:0;transition:opacity 1s}.grille-produits article figure .produit__illustration__survol{visibility:hidden;opacity:0;width:100%;height:100%;transition:opacity .15s,visibility .15s;display:block;position:absolute;top:0;left:0}.grille-produits article figure .produit__illustration__survol img{background:var(--couleur-fond)}.grille-produits article figure figcaption{margin-bottom:var(--espace-xl);padding:var(--espace-m);flex-flow:row;justify-content:space-between;display:flex}.grille-produits article figure figcaption h3{letter-spacing:var(--espacement-inter-lettres-etendu-m);font-style:italic}.grille-produits article figure figcaption p{letter-spacing:var(--espacement-inter-lettres-rapproche-s);font-weight:500}.grille-produits__aucun-produit{min-height:var(--aucun-produit-hauteur);text-align:center;grid-column:span 3;align-content:center}.grille-produits__aucun-produit p+p{margin-top:var(--espace-l);font-size:1.25rem}@media (width<=700px){.grille-produits{grid-template-columns:100%}.grille-produits article figure img{max-height:50svh}}@keyframes test{to{opacity:1}}.resume-produit{--resume-position-basse:0%;--section-marges-internes:var(--espace-l);--espace-inter-colonne:var(--espace-xl);--resume-police-graisse:500;--resume-police-style:italic;--resume-police-taille:var(--espace-l);--resume-police-nom-taille:1.33rem;--resume-police-selecteur-graisse:400;--resume-police-selecteur-taille:var(--espace-m);bottom:var(--resume-position-basse);position:sticky}.resume-produit .selecteur-produit{column-gap:var(--espace-inter-colonne);border-block:1px solid var(--couleur-noir);font-size:var(--resume-police-taille);font-weight:var(--resume-police-graisse);font-style:var(--resume-police-style);line-height:var(--hauteur-ligne-compacte);background:var(--couleur-blanc-fond);grid-template-columns:repeat(3,1fr);grid-auto-flow:column;place-items:center;display:grid;position:relative}.resume-produit .selecteur-produit>*{width:100%;height:100%;padding:var(--section-marges-internes);flex-flow:row;place-content:center;place-items:center;display:flex}.resume-produit .selecteur-produit>:nth-child(2){border-inline-start:1px solid var(--couleur-noir);border-inline-end:1px solid var(--couleur-noir)}.resume-produit .selecteur-produit__nom{font-size:var(--resume-police-nom-taille)}.resume-produit .selecteur-produit__attribut-variation{gap:var(--espace-m) var(--espace-l);font-size:var(--resume-police-selecteur-taille);font-weight:var(--resume-police-selecteur-graisse);text-transform:lowercase;flex-flow:wrap;display:flex}.resume-produit .selecteur-produit__attribut-variation label{margin-right:var(--espace-s)}.resume-produit .selecteur-produit__attribut-variation select{padding:var(--espace-xs) var(--espace-l);border:1px solid var(--couleur-noir);text-align:center;letter-spacing:initial;appearance:none;background:var(--couleur-fond);position:relative}@supports selector(:user-valid){.resume-produit .selecteur-produit__attribut-variation select:user-valid{background:var(--couleur-jaune-fond)}}.resume-produit .selecteur-produit__attribut-variation option{background:var(--couleur-fond)}.resume-produit .selecteur-produit__attribut-variation__selecteurs{position:relative}.resume-produit .selecteur-produit__attribut-variation__selecteurs:after{pointer-events:none;content:" ";text-align:center;visibility:visible;opacity:1;background:url(/app/themes/haiku-atelier-2024/assets/img/icons/arrow.svg) no-repeat;width:.9rem;height:.9rem;transition:opacity .2s,visibility .2s;display:inline-block;position:absolute;top:7px;right:.4rem}@supports not selector(:user-valid){.resume-produit .selecteur-produit__attribut-variation__selecteurs:has(select:valid):after{visibility:hidden;opacity:0}}@supports selector(:user-valid){.resume-produit .selecteur-produit__attribut-variation__selecteurs:has(select:user-valid):after{visibility:hidden;opacity:0}}.resume-produit .selecteur-produit__prix{font-style:initial}@media (width<=800px){.resume-produit{--section-marges-internes:var(--espace-m);--espace-inter-colonne:var(--espace-m)}}@media (width<=700px){.resume-produit{--resume-police-taille:var(--espace-m);--resume-police-nom-taille:var(--espace-m);--section-marges-internes:var(--espace-m);--espace-inter-colonne:var(--espace-s)}}@media (width<=500px){.resume-produit .selecteur-produit__selection-variation-attribut{row-gap:var(--espace-inter-colonne);flex-flow:column}.resume-produit .selecteur-produit__selection-variation-attribut h3{flex-basis:100%}}.details-produit{--bouton-marges-internes-bloc:var(--espace-l);--espace-inter-lignes:var(--espace-l);--espace-inter-texte:var(--espace-m);--section-marges-internes:var(--espace-l);--textuel-marges-internes-ligne:calc(var(--espace-l) * 2);background-color:var(--couleur-blanc)}.details-produit__textes{grid-template-columns:1fr;grid-auto-flow:row;display:grid}.details-produit__textes .section-textuelle:not(:last-of-type){border-block-end:1px solid var(--couleur-noir)}.details-produit__textes .section-textuelle:has(button[aria-expanded=false]) .section-textuelle__contenu{display:none}.details-produit__textes .section-textuelle h3{line-height:var(--hauteur-ligne-rapprochee)}.details-produit__textes .section-textuelle h3 button{width:100%;min-block-size:1lh;padding:var(--section-marges-internes);text-align:start;display:inline-block}.details-produit__textes .section-textuelle .section-textuelle__contenu{padding-block-end:var(--section-marges-internes);padding-inline:var(--textuel-marges-internes-ligne)}.details-produit__textes .section-textuelle .section-textuelle__contenu ul{list-style:inside}.details-produit__textes .section-textuelle .section-textuelle__contenu a{text-decoration-color:var(--couleur-noir)}.details-produit__textes .section-textuelle .section-textuelle__contenu>*+*{margin-top:var(--espace-inter-texte)}.details-produit__actions{--section-marges-internes:var(--espace-l);border-block:1px solid var(--couleur-noir);background:var(--couleur-jaune);transition:background .2s;overflow:hidden}.details-produit__actions:has(button[disabled]){background:var(--couleur-fond)}.details-produit__actions button{height:initial;padding:var(--section-marges-internes);text-transform:uppercase;font-style:italic;transition:background .2s,font-weight .2s}@media (hover:hover){.details-produit__actions button:not([disabled]):hover{font-weight:600}}.produits-similaires{--carte-produit-longueur-minimale:448px;--carte-produit-longueur-maximale:1000px;--en-tete-flottante-hauteur:calc(1rem + var(--espace-l) * 2 + 1px);grid-template-rows:1fr auto;grid-template-columns:repeat(3,1fr);grid-template-areas:"en-tete en-tete en-tete""produits produits produits";place-items:center;display:grid;position:relative}.produits-similaires header{z-index:10;top:var(--en-tete-flottante-hauteur);width:100%;padding:var(--espace-l) 0;color:var(--couleur-blanc);text-align:center;background:var(--couleur-noir);grid-area:en-tete;position:sticky}.produits-similaires header h2{font-style:italic;line-height:var(--hauteur-ligne-rapprochee);text-transform:uppercase;letter-spacing:var(--espacement-inter-lettres-etendu-m)}.produits-similaires .grille-produits-similaires{grid-area:produits;grid-auto-rows:1fr;grid-template-columns:repeat(auto-fit, minmax(var(--carte-produit-longueur-minimale), 1fr));gap:1px;width:100%;display:grid}.produits-similaires .grille-produits-similaires article{max-width:var(--carte-produit-longueur-maximale);box-shadow:0 0 0 1px var(--couleur-noir)}.produits-similaires .grille-produits-similaires article figure{row-gap:var(--espace-xl);flex-flow:column;display:flex}.produits-similaires .grille-produits-similaires article figure a{position:relative}@media (hover:hover){.produits-similaires .grille-produits-similaires article figure a:hover .produit__illustration__survol{visibility:visible;opacity:1;transition:opacity .3s,visibility .3s}}.produits-similaires .grille-produits-similaires article figure .produit__illustration__principale{display:block}.produits-similaires .grille-produits-similaires article figure .produit__illustration__survol{visibility:hidden;opacity:0;width:100%;height:100%;transition:opacity .15s,visibility .15s;display:block;position:absolute;top:0;left:0}.produits-similaires .grille-produits-similaires article figure img{aspect-ratio:9/16;object-fit:cover;width:100%;max-height:70svh}.produits-similaires .grille-produits-similaires article figure figcaption{margin-bottom:var(--espace-xl);padding:0 var(--espace-m);flex-flow:row;justify-content:space-between;display:flex}.produits-similaires .grille-produits-similaires article figure figcaption h3{letter-spacing:var(--espacement-inter-lettres-etendu-m);font-style:italic}.produits-similaires .grille-produits-similaires article figure figcaption p{letter-spacing:var(--espacement-inter-lettres-rapproche-s);font-weight:500}@media (width<=700px){.produits-similaires .grille-produits-similaires{grid-template-columns:100%}.produits-similaires .grille-produits-similaires article figure img{max-height:50svh}}#pied-de-page{max-width:100vw;height:var(--pied-de-page-hauteur);padding:var(--espace-s) var(--espace-m);border-top:1px solid var(--couleur-noir);background:var(--couleur-jaune);grid-template-columns:1fr 1fr;place-items:center;font-size:.8rem;display:grid}#pied-de-page .zone-menu-navigation-secondaire{text-transform:lowercase;justify-self:start;width:100%;height:100%}#pied-de-page .zone-liens-reseaux-sociaux{text-align:right;justify-items:end;width:100%;height:100%} \ No newline at end of file diff --git a/web/app/themes/haiku-atelier-2024/assets/vendor/controle-personnalise-tinymce.js b/web/app/themes/haiku-atelier-2024/assets/vendor/controle-personnalise-tinymce.js index 292ef834..41e22ee0 100755 --- a/web/app/themes/haiku-atelier-2024/assets/vendor/controle-personnalise-tinymce.js +++ b/web/app/themes/haiku-atelier-2024/assets/vendor/controle-personnalise-tinymce.js @@ -11,18 +11,18 @@ jQuery(document).ready(function ($) { $(".customize-control-tinymce-editor").each(function () { // Get the toolbar strings that were passed from the PHP Class - var tinyMCEToolbar1String = _wpCustomizeSettings.controls[$(this).attr("id")].skyrockettinymcetoolbar1; - var tinyMCEToolbar2String = _wpCustomizeSettings.controls[$(this).attr("id")].skyrockettinymcetoolbar2; - var tinyMCEMediaButtons = _wpCustomizeSettings.controls[$(this).attr("id")].skyrocketmediabuttons; + const tinyMCEToolbar1String = _wpCustomizeSettings.controls[$(this).attr("id")].skyrockettinymcetoolbar1; + const tinyMCEToolbar2String = _wpCustomizeSettings.controls[$(this).attr("id")].skyrockettinymcetoolbar2; + const tinyMCEMediaButtons = _wpCustomizeSettings.controls[$(this).attr("id")].skyrocketmediabuttons; wp.editor.initialize($(this).attr("id"), { + mediaButtons: tinyMCEMediaButtons, + quicktags: true, tinymce: { wpautop: true, toolbar1: tinyMCEToolbar1String, toolbar2: tinyMCEToolbar2String, }, - quicktags: true, - mediaButtons: tinyMCEMediaButtons, }); }); $(document).on("tinymce-editor-init", function (event, editor) { diff --git a/web/app/themes/haiku-atelier-2024/front-page.php b/web/app/themes/haiku-atelier-2024/front-page.php index bcf1a730..b4963c8f 100755 --- a/web/app/themes/haiku-atelier-2024/front-page.php +++ b/web/app/themes/haiku-atelier-2024/front-page.php @@ -8,7 +8,6 @@ declare(strict_types=1); namespace HaikuAtelier; -use Exception; use HaikuAtelier\WP\Resource; use Timber\Timber; @@ -17,12 +16,7 @@ use function add_action; $context = Timber::context(); $templates = ['accueil.twig']; -/** - * Charge les scripts et styles de la page. - * - * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger - */ -function load_page_resources(): void { +add_action('wp_enqueue_scripts', function (): void { Resource::enqueue_style_file( handle: 'haiku-atelier-2024-styles-page-accueil', path: '/assets/css/pages/page-accueil.css', @@ -31,9 +25,7 @@ function load_page_resources(): void { id: 'haiku-atelier-2024-scripts-page-accueil', path: '/assets/js/scripts-page-accueil.js', ); -} - -add_action('wp_enqueue_scripts', load_page_resources(...)); +}); Timber::render( data: $context, diff --git a/web/app/themes/haiku-atelier-2024/page-about.php b/web/app/themes/haiku-atelier-2024/page-about.php index c57e6c1b..e4b8b1e4 100755 --- a/web/app/themes/haiku-atelier-2024/page-about.php +++ b/web/app/themes/haiku-atelier-2024/page-about.php @@ -29,12 +29,7 @@ if (is_bool($image_dimensions)) { $context['image_dimensions'] = $image_dimensions; -/** - * Charge les scripts et styles de la page. - * - * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger - */ -function load_page_resources(): void { +add_action('wp_enqueue_scripts', function (): void { Resource::enqueue_style_file( handle: 'haiku-atelier-2024-styles-page-a-propos', path: '/assets/css/pages/page-a-propos.css', @@ -43,9 +38,7 @@ function load_page_resources(): void { id: 'haiku-atelier-2024-scripts-page-a-propos', path: '/assets/js/scripts-page-a-propos.js', ); -} - -add_action('wp_enqueue_scripts', load_page_resources(...)); +}); Timber::render( data: $context, diff --git a/web/app/themes/haiku-atelier-2024/page-cart.php b/web/app/themes/haiku-atelier-2024/page-cart.php index 6fe3b726..c1c8ab4b 100755 --- a/web/app/themes/haiku-atelier-2024/page-cart.php +++ b/web/app/themes/haiku-atelier-2024/page-cart.php @@ -8,7 +8,6 @@ declare(strict_types=1); namespace HaikuAtelier; -use Exception; use HaikuAtelier\Data\Cart; use HaikuAtelier\WP\Resource; use Illuminate\Support\Number; @@ -99,12 +98,7 @@ $context['pays_livraison'] = $allowed_countries; $context['sous_total_livraison'] = $shipping_subtotal; $context['methodes_livraison'] = $methodes_livraison; -/** - * Charge les scripts et styles de la page. - * - * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger - */ -function load_page_resources(): void { +add_action('wp_enqueue_scripts', function (): void { Resource::enqueue_style_file( handle: 'haiku-atelier-2024-styles-page-panier', path: '/assets/css/pages/page-panier.css', @@ -113,9 +107,7 @@ function load_page_resources(): void { id: 'haiku-atelier-2024-scripts-page-panier', path: '/assets/js/scripts-page-panier.js', ); -} - -add_action('wp_enqueue_scripts', load_page_resources(...)); +}); // Rendu Timber::render( diff --git a/web/app/themes/haiku-atelier-2024/page-contact.php b/web/app/themes/haiku-atelier-2024/page-contact.php index 51004234..8a557b91 100755 --- a/web/app/themes/haiku-atelier-2024/page-contact.php +++ b/web/app/themes/haiku-atelier-2024/page-contact.php @@ -8,7 +8,6 @@ declare(strict_types=1); namespace HaikuAtelier; -use Exception; use HaikuAtelier\WP\Resource; use Timber\Timber; @@ -17,19 +16,12 @@ use function add_action; $context = Timber::context(); $templates = ['contact.twig']; -/** - * Charge les scripts et styles de la page. - * - * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger - */ -function load_page_resources(): void { +add_action('wp_enqueue_scripts', function (): void { Resource::enqueue_style_file( handle: 'haiku-atelier-2024-styles-page-contact', path: '/assets/css/pages/page-contact.css', ); -} - -add_action('wp_enqueue_scripts', load_page_resources(...)); +}); // Rendu Timber::render( diff --git a/web/app/themes/haiku-atelier-2024/page-failed-order.php b/web/app/themes/haiku-atelier-2024/page-failed-order.php index 81826e7f..df6cdc94 100755 --- a/web/app/themes/haiku-atelier-2024/page-failed-order.php +++ b/web/app/themes/haiku-atelier-2024/page-failed-order.php @@ -8,7 +8,6 @@ declare(strict_types=1); namespace HaikuAtelier; -use Exception; use HaikuAtelier\WP\Resource; use Timber\Timber; @@ -17,19 +16,12 @@ use function add_action; $context = Timber::context(); $templates = ['echec-commande.twig']; -/** - * Charge les scripts et styles de la page. - * - * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger - */ -function load_page_resources(): void { +add_action('wp_enqueue_scripts', function (): void { Resource::enqueue_style_file( handle: 'haiku-atelier-2024-styles-page-modele-simple', path: '/assets/css/pages/page-modele-simple.css', ); -} - -add_action('wp_enqueue_scripts', load_page_resources(...)); +}); // Rendu Timber::render( diff --git a/web/app/themes/haiku-atelier-2024/page-terms-and-conditions.php b/web/app/themes/haiku-atelier-2024/page-terms-and-conditions.php index d9b9f1ea..2d3c1cce 100755 --- a/web/app/themes/haiku-atelier-2024/page-terms-and-conditions.php +++ b/web/app/themes/haiku-atelier-2024/page-terms-and-conditions.php @@ -8,26 +8,20 @@ declare(strict_types=1); namespace HaikuAtelier; -use Exception; use HaikuAtelier\WP\Resource; use Timber\Timber; +use function add_action; + $context = Timber::context(); $templates = ['cgv.twig']; -/** - * Charge les scripts et styles de la page. - * - * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger - */ -function load_page_resources(): void { +add_action('wp_enqueue_scripts', function (): void { Resource::enqueue_style_file( handle: '/assets/css/pages/page-modele-simple.css', path: '/assets/css/pages/page-modele-simple.css', ); -} - -add_action('wp_enqueue_scripts', load_page_resources(...)); +}); // Rendu Timber::render( diff --git a/web/app/themes/haiku-atelier-2024/single-product.php b/web/app/themes/haiku-atelier-2024/single-product.php index 6d706129..d45a7281 100755 --- a/web/app/themes/haiku-atelier-2024/single-product.php +++ b/web/app/themes/haiku-atelier-2024/single-product.php @@ -20,7 +20,6 @@ use function add_action; use function assert; use function collect; use function is_array; -use function is_bool; use function recupere_produits_meme_collection; use function wc_get_product; use function wp_json_encode; @@ -56,12 +55,7 @@ $context['product_json'] = wp_json_encode($product); $context['maximum_price'] = $maximum_price; $context['same_collection_products'] = $same_collection_products; -/** - * Charge les scripts et styles de la page. - * - * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger - */ -function load_page_resources(): void { +add_action('wp_enqueue_scripts', function (): void { Resource::enqueue_script_module_file( id: 'haiku-atelier-2024-scripts-page-produit', path: '/assets/js/scripts-page-produit.js', @@ -70,9 +64,7 @@ function load_page_resources(): void { id: 'haiku-atelier-2024-scripts-menu-categories', path: '/assets/js/scripts-menu-categories.js', ); -} - -add_action('wp_enqueue_scripts', load_page_resources(...)); +}); // Rendu Timber::render( diff --git a/web/app/themes/haiku-atelier-2024/src/inc/APIRest.php b/web/app/themes/haiku-atelier-2024/src/inc/APIRest.php deleted file mode 100755 index 8b137891..00000000 --- a/web/app/themes/haiku-atelier-2024/src/inc/APIRest.php +++ /dev/null @@ -1 +0,0 @@ - diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Data/Attribute.php b/web/app/themes/haiku-atelier-2024/src/inc/Data/Attribute.php index d50dad4a..e65da73d 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/Data/Attribute.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/Data/Attribute.php @@ -8,6 +8,8 @@ use Illuminate\Support\Arr; use WC_Product_Attribute; use WP_Term; +use function wc_attribute_label; + final readonly class Attribute { /** * @param list $options diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Data/Product.php b/web/app/themes/haiku-atelier-2024/src/inc/Data/Product.php index caace9aa..17f1489f 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/Data/Product.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/Data/Product.php @@ -11,14 +11,17 @@ use Psl\Option; use WC_Product; use WP_Term; +use function HaikuAtelier\genere_balise_img_multiformats; +use function head; use function Psl\Option\from_nullable; +use function wpautop; final readonly class Product { /** * @param list $attributes * @param list $left_column_photos * @param list $right_column_photos - * @param list $variations + * @param array $variations */ private function __construct( public array $attributes, @@ -43,11 +46,11 @@ final readonly class Product { */ public static function get_attributes_for_product(WC_Product $product): array { /** @var list */ - return $product->get_attributes() |> (static fn($attributes) => Arr::map($attributes, Attribute::new(...))); + return $product->get_attributes() + |> (static fn(array $attributes): array => Arr::map($attributes, Attribute::new(...))); } public static function new(WC_Product $product): self { - /** @var list */ $attributes = self::get_attributes_for_product($product); /** @var lowercase-string */ $category = $product->get_id() |> wc_get_product_category_list(...) |> strtolower(...); @@ -74,9 +77,13 @@ final readonly class Product { $hover_photo = $right_column_photos[0] ?? genere_balise_img_multiformats('-1', true); $slug = $product->get_slug(); $stock = $product->get_stock_quantity() ?? 1; + /** @var array */ $variations = $product->get_children() - |> (static fn($ids) => Arr::map($ids, wc_get_product(...))) - |> (static fn($products) => Arr::map($products, ProductVariation::new(...))); + |> (static fn(/** @var list */ array $ids): array => Arr::map($ids, wc_get_product(...))) + |> (static fn(/** @var list */ array $products): array => Arr::map( + $products, + ProductVariation::new(...), + )); $url = $product->get_permalink(); return new self( diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Fonctionnalites.php b/web/app/themes/haiku-atelier-2024/src/inc/Fonctionnalites.php index e054b7c9..771f1c3d 100755 --- a/web/app/themes/haiku-atelier-2024/src/inc/Fonctionnalites.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/Fonctionnalites.php @@ -1,10 +1,12 @@ get_price() <=> $a->get_price(); -} - -/** - * Récupère les informations utilisées pour la grille des Produits et les retourne sous forme - * de tableau associatif. - * - * @return mixed un tableau avec uniquement les informations pour la Grille de Produits - */ -function recupere_informations_produit_shop(WC_Product $produit): mixed { - /** @var int $prix_maximal Le prix maximal du Produit. */ - $prix_maximal = pipe( - // Récupère les Variations - $produit->get_children(), - // Récupère les informations de chaque Variation - static fn($enfants): array => array_map( - callback: wc_get_product(...), - array: $enfants, - ), - // Trie les Variations par prix descendant - static fn($variations): array => array_map( - callback: static fn($variation) => $variation->get_price(), - array: $variations, - ), - // Récupère le Prix de la Variation la plus chère - static fn($prix) => collect($prix)->max(), - // Récupère le Prix pour la Variation la plus chère OU le prix du Produit simple - static fn($prix_variation_maximale) => $prix_variation_maximale ?? $produit->get_price(), - ); - - // TEMP: Cas de la Carte Cadeau où aucun prix ne doit être affiché. Idéalement utiliser un système d'étiquettes pour ces cas là. - if ($produit->get_sku() === 'GIFTcard') { - $prix_maximal = ''; - } - - return [ - // Identifiant du Produit - 'id' => $produit->get_id(), - // Nom affiché du Produit - 'nom' => $produit->get_name(), - // Prix affiché du Produit - 'prix' => "{$prix_maximal}", - // Photo du Produit affichée par défaut - 'photo_repos' => genere_balise_img_multiformats( - get_post_meta($post_id = $produit->get_id(), $key = '_photos_colonne_gauche|||0|value')[0] ?? -1, - false, - ), - // Photo du Produit affichée au survol de l'image - 'photo_survol' => genere_balise_img_multiformats( - get_post_meta($post_id = $produit->get_id(), $key = '_photos_colonne_droite|||0|value')[0] ?? -1, - true, - ), - // URL du Produit pour les liens vers celui-ci - 'url' => $produit->get_permalink(), - ]; -} - // Page Produit -/** - * Retourne un tableau associatif des informations affichées sur la page Produit depuis les données brutes d'un Produit. - */ -function recupere_informations_produit_page_produit(WC_Product $product): mixed { - /** @var list */ - $attributs = Product::get_attributes_for_product($product); - - return [ - // Attributs du Produit - 'attributs' => $attributs, - // Catégorie du Produit - 'categorie' => pipe($product->get_id(), wc_get_product_category_list(...), strtolower(...)), - // Slug de la Collection - Peut ne pas avoir été défini - 'collection' => get_the_terms($product->get_id(), 'collection')[0]->slug ?? '', - // Détails (Description) du Produit - 'details' => wpautop($product->get_description()), - // Identifiant du Produit - 'id' => $product->get_id(), - // Nom affiché du Produit - 'nom' => $product->get_name(), - // Prix affiché du Produit - 'prix' => $product->get_price(), - 'photos_colonne_gauche' => array_map( - callback: genere_balise_img_multiformats(...), - array: get_post_meta($post_id = $product->get_id(), $key = '_photos_colonne_gauche|||0|value'), - ), - 'photos_colonne_droite' => array_map( - callback: genere_balise_img_multiformats(...), - array: carbon_get_the_post_meta('photos_colonne_droite'), - ), - 'photo_repos' => genere_balise_img_multiformats( - get_post_meta($post_id = $product->get_id(), $key = '_photos_colonne_gauche|||0|value')[0] ?? -1, - false, - ), - 'photo_survol' => genere_balise_img_multiformats( - get_post_meta($post_id = $product->get_id(), $key = '_photos_colonne_droite|||0|value')[0] ?? -1, - true, - ), - // Slug du Produit - 'slug' => $product->get_slug(), - // Quantité de Produit en stock - 'stock' => $product->get_stock_quantity() ?? 1, - // Variations du Produit - 'variations_ids' => $product->get_children(), - // URL du Produit - 'url' => $product->get_permalink(), - ]; -} - /** * Récupère les informations utilisées pour la grille des Produits similaires (de la même * collection) et les retourne sous forme de tableau associatif. diff --git a/web/app/themes/haiku-atelier-2024/src/inc/WP/HaikuProduct.php b/web/app/themes/haiku-atelier-2024/src/inc/WP/HaikuProduct.php index 125654b4..cd195b72 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/WP/HaikuProduct.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/WP/HaikuProduct.php @@ -6,6 +6,8 @@ namespace HaikuAtelier\WP; use Illuminate\Support\Arr; +use function carbon_get_post_meta; +use function HaikuAtelier\genere_balise_img_multiformats; use function is_array; use function is_string; diff --git a/web/app/themes/haiku-atelier-2024/src/inc/WP/Post.php b/web/app/themes/haiku-atelier-2024/src/inc/WP/Post.php index b65fd217..116eb07b 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/WP/Post.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/WP/Post.php @@ -8,6 +8,8 @@ use Psl\Option; use WP_Error; use WP_Term; +use function get_post_meta; +use function get_the_terms; use function is_array; use function Psl\Option\none; use function Psl\Option\some; diff --git a/web/app/themes/haiku-atelier-2024/src/inc/WP/Resource.php b/web/app/themes/haiku-atelier-2024/src/inc/WP/Resource.php index 05d10bad..b0151dfc 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/WP/Resource.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/WP/Resource.php @@ -6,9 +6,17 @@ namespace HaikuAtelier\WP; use Exception; +use function filemtime; +use function get_template_directory; +use function get_template_directory_uri; use function is_bool; +use function wp_enqueue_script_module; +use function wp_enqueue_style; final readonly class Resource { + /** + * @throws Exception Lève une `Exception` s'il est impossible d'obtenir les attributs du fichier au chemin passé en paramètre. + */ public static function enqueue_script_module_file(string $path, string $id): void { $file_uri = get_template_directory_uri() . $path; @@ -16,7 +24,7 @@ final readonly class Resource { $file_mtime = filemtime($file_path); if (is_bool($file_mtime)) { - throw new Exception("Could not get modification time of file: {$file_uri} "); + throw new Exception("Impossible de récupérer la date de modification du fichier : {$file_uri}."); } $version = (string) $file_mtime; @@ -29,6 +37,9 @@ final readonly class Resource { ); } + /** + * @throws Exception Lève une `Exception` s'il est impossible d'obtenir les attributs du fichier au chemin passé en paramètre. + */ public static function enqueue_style_file(string $path, string $handle): void { $file_uri = get_template_directory_uri() . $path; @@ -36,7 +47,7 @@ final readonly class Resource { $file_mtime = filemtime($file_path); if (is_bool($file_mtime)) { - throw new Exception("Could not get modification time of file: {$file_uri} "); + throw new Exception("Impossible de récupérer la date de modification du fichier : {$file_uri}."); } $ver = (string) $file_mtime; diff --git a/web/app/themes/haiku-atelier-2024/src/sass/base/elements/_boutons.scss b/web/app/themes/haiku-atelier-2024/src/sass/base/elements/_boutons.scss index e58e4713..73c711b1 100755 --- a/web/app/themes/haiku-atelier-2024/src/sass/base/elements/_boutons.scss +++ b/web/app/themes/haiku-atelier-2024/src/sass/base/elements/_boutons.scss @@ -69,6 +69,7 @@ button { &.bouton-retour-haut { position: fixed; + z-index: 500; right: var(--espace-xl); bottom: calc(var(--espace-l) + var(--pied-de-page-hauteur)); transform: rotate(180deg); @@ -80,7 +81,6 @@ button { background: var(--couleur-fond); box-shadow: initial; transition: 0.2s background, 0.2s opacity, 0.2s visibility; - z-index: 500; img { width: 1rem; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts-effect/lib/dom.ts b/web/app/themes/haiku-atelier-2024/src/scripts-effect/lib/dom.ts index 68fdfdbf..e618c8c7 100644 --- a/web/app/themes/haiku-atelier-2024/src/scripts-effect/lib/dom.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts-effect/lib/dom.ts @@ -1,5 +1,5 @@ import { Option, pipe } from "effect"; -import { Array as EffectArray } from "effect"; +import { Array as FxArray } from "effect"; import { NonEmptyReadonlyArray } from "effect/Array"; import { getOptionOrThrowWithError } from "./utils"; @@ -27,8 +27,8 @@ export const getAllSelectorFromParent = pipe( parent.querySelectorAll(selector), // Convertis NodeListOf en Array. - Array.from, - (xs: Array) => Option.liftPredicate(EffectArray.isNonEmptyReadonlyArray)(xs), + (xs: NodeListOf) => Array.from(xs), + (xs: Array) => Option.liftPredicate(FxArray.isReadonlyArrayNonEmpty)(xs), ); export const getAllSelectorFromDocument = ( diff --git a/web/app/themes/haiku-atelier-2024/src/scripts-effect/lib/utils.ts b/web/app/themes/haiku-atelier-2024/src/scripts-effect/lib/utils.ts index 999a9d66..a550ffe2 100644 --- a/web/app/themes/haiku-atelier-2024/src/scripts-effect/lib/utils.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts-effect/lib/utils.ts @@ -1,4 +1,4 @@ -import { pipe, Option } from "effect"; +import { Option, pipe } from "effect"; export const getOptionOrThrowWithError = (message: string) => diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/lib/animations.ts b/web/app/themes/haiku-atelier-2024/src/scripts/lib/animations.ts index 0f3c04de..cca67760 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/lib/animations.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/lib/animations.ts @@ -3,18 +3,18 @@ import { ATTRIBUT_CHARGEMENT } from "../constantes/dom"; // Types -interface AnimationCycleTexte { +type AnimationCycleTexte = { callback: () => void; etapes: Array; index: number; interval: NodeJS.Timeout; -} +}; -interface ParametresAnimationCycleTexte { +type ParametresAnimationCycleTexte = { attribut: string; element: HTMLElement; etapes: Array; -} +}; /** * Créer le nécessaire pour une animation s'exécutant jusqu'à ce que un interval soit manuellement arrêté. L'animation @@ -39,7 +39,7 @@ const lanceAnimationCycleTexte = (args: ParametresAnimationCycleTexte): Animatio }, etapes: args.etapes, index: 0, - interval: setInterval(() => {}, 2147483647), + interval: setInterval(() => {}, 2_147_483_647), }; return animation; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/lib/erreurs.ts b/web/app/themes/haiku-atelier-2024/src/scripts/lib/erreurs.ts index c5fc107a..879d14c5 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/lib/erreurs.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/lib/erreurs.ts @@ -123,8 +123,12 @@ export const reporteEtLeveErreur = (erreur: E): never => { export const reporteEtJournaliseErreur = (erreur: E): void => { reporteErreur(erreur); console.error(erreur); - if (erreur instanceof ValiError) console.error(erreur.issues); - if (erreur instanceof ErreurAdresseInvalide) console.error(erreur.problemes); + if (erreur instanceof ValiError) { + console.error(erreur.issues); + } + if (erreur instanceof ErreurAdresseInvalide) { + console.error(erreur.problemes); + } }; export const reporteEtRetourneErreur = (erreur: E): E => { diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/lib/evenements/panier.ts b/web/app/themes/haiku-atelier-2024/src/scripts/lib/evenements/panier.ts index aba342ce..7e4fa0b3 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/lib/evenements/panier.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/lib/evenements/panier.ts @@ -7,12 +7,12 @@ export const CODE_PROMO_MAJ_EVENT = new CustomEvent(CODE_PROMO_MAJ, {}); // Interfaces -export interface UpdatedShippingRatesEvent extends Event { +export type UpdatedShippingRatesEvent = { detail: { refresh_methods: boolean; shipping_rates: ReadonlyArray }; -} -export interface UpdatedTotalsEvent extends Event { +} & Event; +export type UpdatedTotalsEvent = { detail: { totals: WCStoreCartTotals }; -} +} & Event; // Méthodes diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/lib/messages.ts b/web/app/themes/haiku-atelier-2024/src/scripts/lib/messages.ts index a843ab7b..49d411fe 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/lib/messages.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/lib/messages.ts @@ -1,6 +1,7 @@ import { pipe } from "@mobily/ts-belt"; import { Either } from "purify-ts"; -import { parse, type ValiError } from "valibot"; +import { parse } from "valibot"; +import type { ValiError } from "valibot"; import type { MessageMajBoutonPanier, diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/lib/reseau.ts b/web/app/themes/haiku-atelier-2024/src/scripts/lib/reseau.ts index 9aa75472..76e655c5 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/lib/reseau.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/lib/reseau.ts @@ -36,7 +36,7 @@ type ArgumentsPostBackendWC = { route: string; }; -// fetch +// Fetch export const getBackend = (args: ArgumentsGetBackendWC): Promise => fetch(args.route, { @@ -120,19 +120,16 @@ export const safeFetch = (f: Promise): EitherAsync(async () => await f); // Réponses Simplifiées -export const newPartialResponse = async (reponse: Response): Promise => { - return { - body: await reponse.json(), - status: reponse.status, - }; -}; +export const newPartialResponse = async (reponse: Response): Promise => ({ + body: await reponse.json(), + status: reponse.status, +}); -export const traiteErreursBackendWooCommerce = (rs: SimplifiedResponse): HttpCodeErrors => { - return match(rs) +export const traiteErreursBackendWooCommerce = (rs: SimplifiedResponse): HttpCodeErrors => + match(rs) .with({ status: 400 }, () => new BadRequestError()) .with({ status: 401 }, () => new UnauthorizedError()) .with({ status: 403 }, () => new ForbiddenError()) .with({ status: 404 }, () => new NotFoundError()) .with({ status: 500 }, () => new ServerError()) .otherwise((rs) => new Error(String(rs.status))); -}; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/api/adresses.ts b/web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/api/adresses.ts index 0e915289..9cd2f9ec 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/api/adresses.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/lib/schemas/api/adresses.ts @@ -6,7 +6,7 @@ export const WCStoreBillingAddressSchema = v.object({ city: v.string(), company: v.string(), country: v.string(), - // email: v.optional(v.pipe(v.string(), v.email())), + // Email: v.optional(v.pipe(v.string(), v.email())), email: v.string(), first_name: v.string(), last_name: v.string(), diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/lib/session-storage.ts b/web/app/themes/haiku-atelier-2024/src/scripts/lib/session-storage.ts index 879ac1c0..e6597b2c 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/lib/session-storage.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/lib/session-storage.ts @@ -3,7 +3,8 @@ import type { GenericSchema, InferOutput, ValiError } from "valibot"; import { Either, Maybe } from "purify-ts"; import { safeJsonParse } from "./dom.ts"; -import { ErreurEntreeInexistante, type NonExistingKeyError } from "./erreurs.ts"; +import { ErreurEntreeInexistante } from "./erreurs.ts"; +import type { NonExistingKeyError } from "./erreurs.ts"; import { safeSchemaParse, safeSchemaParseCurried } from "./validation.ts"; export type GetSessionStorage = Either, InferOutput>; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/lib/types/reseau.d.ts b/web/app/themes/haiku-atelier-2024/src/scripts/lib/types/reseau.d.ts index 1cc58404..21f1c2be 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/lib/types/reseau.d.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/lib/types/reseau.d.ts @@ -4,7 +4,7 @@ export type FetchErrors = DOMException | Error | TypeError; export type HttpCodeErrors = BadRequestError | Error | ForbiddenError | NotFoundError | ServerError | UnauthorizedError; -export interface SimplifiedResponse { +export type SimplifiedResponse = { body: unknown; status: number; -} +}; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/lib/utils.ts b/web/app/themes/haiku-atelier-2024/src/scripts/lib/utils.ts index a2d7b52c..49b3b12b 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/lib/utils.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/lib/utils.ts @@ -1,5 +1,6 @@ import { D } from "@mobily/ts-belt"; -import { type Either, Maybe } from "purify-ts"; +import { Maybe } from "purify-ts"; +import type { Either } from "purify-ts"; import { CleNonTrouveError } from "./erreurs"; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/lib/validation.ts b/web/app/themes/haiku-atelier-2024/src/scripts/lib/validation.ts index c1d9f4dc..42141e52 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/lib/validation.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/lib/validation.ts @@ -3,7 +3,8 @@ */ import { Either } from "purify-ts"; -import { type GenericSchema, type InferOutput, parse, type ValiError } from "valibot"; +import { parse } from "valibot"; +import type { GenericSchema, InferOutput, ValiError } from "valibot"; export const safeSchemaParse = ( valeur: unknown, diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-adresses.ts b/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-adresses.ts index 3acf4b7e..0773bca6 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-adresses.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-adresses.ts @@ -4,7 +4,8 @@ import { map as dictMap, values as dictValues } from "@mobily/ts-belt/Dict"; import { trim as stringTrim } from "@mobily/ts-belt/String"; import { EitherAsync, Maybe } from "purify-ts"; import { match, P } from "ts-pattern"; -import { type AnySchema, ValiError } from "valibot"; +import { ValiError } from "valibot"; +import type { AnySchema } from "valibot"; import type { WCStoreBillingAddress, WCStoreShippingAddress } from "../lib/types/api/adresses"; import type { WCStoreCart, WCStoreShippingRate, WCStoreShippingRateShippingRate } from "../lib/types/api/cart"; @@ -43,10 +44,10 @@ import { safeSchemaParse } from "../lib/validation"; import { E } from "./scripts-page-panier-elements"; import { getShippingRatesLS } from "./scripts-page-panier-local-storage"; -interface Addresses { +type Addresses = { billing_address: WCStoreBillingAddress; shipping_address: WCStoreShippingAddress; -} +}; // @ts-expect-error -- États injectés par le modèle PHP // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- États injectés par le modèle PHP @@ -65,35 +66,33 @@ export const initCartFormEventEmitters = (): void => { }); }; -export const getAddressesFromForm = (formFields: Record, areAddressesMerged: boolean): Addresses => { - return { - billing_address: { - address_1: formFields["facturation-adresse"] ?? formFields["livraison-adresse"] ?? "", - address_2: "", - city: formFields["facturation-ville"] ?? formFields["livraison-ville"] ?? "", - company: "", - country: areAddressesMerged ? (formFields["facturation-pays"] ?? "") : (formFields["livraison-pays"] ?? ""), - email: formFields["facturation-email"] ?? formFields["livraison-email"] ?? "", - first_name: formFields["facturation-prenom"] ?? formFields["livraison-prenom"] ?? "", - last_name: formFields["facturation-nom"] ?? formFields["livraison-nom"] ?? "", - phone: formFields["facturation-telephone"] ?? formFields["livraison-telephone"] ?? "", - postcode: formFields["facturation-code-postal"] ?? formFields["livraison-code-postal"] ?? "", - state: formFields["facturation-region-etat"] ?? formFields["livraison-region-etat"] ?? "", - }, - shipping_address: { - address_1: formFields["livraison-adresse"] ?? "", - address_2: "", - city: formFields["livraison-ville"] ?? "", - company: "", - country: formFields["livraison-pays"] ?? "", - first_name: formFields["livraison-prenom"] ?? "", - last_name: formFields["livraison-nom"] ?? "", - phone: formFields["livraison-telephone"] ?? "", - postcode: formFields["livraison-code-postal"] ?? "", - state: formFields["livraison-region-etat"] ?? "", - }, - }; -}; +export const getAddressesFromForm = (formFields: Record, areAddressesMerged: boolean): Addresses => ({ + billing_address: { + address_1: formFields["facturation-adresse"] ?? formFields["livraison-adresse"] ?? "", + address_2: "", + city: formFields["facturation-ville"] ?? formFields["livraison-ville"] ?? "", + company: "", + country: areAddressesMerged ? (formFields["facturation-pays"] ?? "") : (formFields["livraison-pays"] ?? ""), + email: formFields["facturation-email"] ?? formFields["livraison-email"] ?? "", + first_name: formFields["facturation-prenom"] ?? formFields["livraison-prenom"] ?? "", + last_name: formFields["facturation-nom"] ?? formFields["livraison-nom"] ?? "", + phone: formFields["facturation-telephone"] ?? formFields["livraison-telephone"] ?? "", + postcode: formFields["facturation-code-postal"] ?? formFields["livraison-code-postal"] ?? "", + state: formFields["facturation-region-etat"] ?? formFields["livraison-region-etat"] ?? "", + }, + shipping_address: { + address_1: formFields["livraison-adresse"] ?? "", + address_2: "", + city: formFields["livraison-ville"] ?? "", + company: "", + country: formFields["livraison-pays"] ?? "", + first_name: formFields["livraison-prenom"] ?? "", + last_name: formFields["livraison-nom"] ?? "", + phone: formFields["livraison-telephone"] ?? "", + postcode: formFields["livraison-code-postal"] ?? "", + state: formFields["livraison-region-etat"] ?? "", + }, +}); export const initShippingCalculationButton = (): void => { // Déclenche au clic sur le Bouton de soumission du Formulaire la requête pour le calcul des frais de livraison @@ -119,11 +118,11 @@ export const initShippingCalculationButton = (): void => { void EitherAsync.liftEither(safeSchemaParse(formArgs, WCStoreCartUpdateCustomerArgsSchema)) // Désactive le Bouton pour empêcher des requêtes concurrentes .ifRight((): void => setButtonLoadingState(E.BOUTON_ACTIONS_FORMULAIRE, true)) - .chain((args: WCStoreCartUpdateCustomerArgs) => { - return safeFetch(postBackend(ROUTE_API_MAJ_CLIENT, JSON.stringify(args), false)); - }) - .chain((rs: Response) => { - return EitherAsync( + .chain((args: WCStoreCartUpdateCustomerArgs) => + safeFetch(postBackend(ROUTE_API_MAJ_CLIENT, JSON.stringify(args), false)), + ) + .chain((rs: Response) => + EitherAsync( async ({ throwE }): Promise => match(await newPartialResponse(rs)) .with({ status: 200 }, (rs): unknown => rs.body) @@ -135,8 +134,8 @@ export const initShippingCalculationButton = (): void => { (rs): never => throwE(new ErreurAdresseInvalide(rs.body.data.params)), ) .otherwise((rs): never => throwE(traiteErreursBackendWooCommerce(rs))), - ); - }) + ), + ) .chain((b: unknown) => EitherAsync.liftEither(safeSchemaParse(b, WCStoreCartSchema))) .ifRight((cart: WCStoreCart): void => { /** La méthode de livraison sélectionnée dans le SessionStorage */ @@ -299,9 +298,9 @@ export const initOrderCreationButton = (): void => { void EitherAsync.liftEither(safeSchemaParse(formArgs, WCV3OrdersArgsSchema)) // Désactive le Bouton pour empêcher des requêtes concurrentes .ifRight((): void => setButtonLoadingState(E.BOUTON_ACTIONS_FORMULAIRE, true)) - .chain((args: WCV3OrdersArgs) => { - return safeFetch(postBackend(ROUTE_API_NOUVELLE_COMMANDES, JSON.stringify(args), true)); - }) + .chain((args: WCV3OrdersArgs) => + safeFetch(postBackend(ROUTE_API_NOUVELLE_COMMANDES, JSON.stringify(args), true)), + ) .chain((rs: Response) => EitherAsync( async ({ throwE }): Promise => diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-code-promo.ts b/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-code-promo.ts index 7ffd10c8..f37e0298 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-code-promo.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-code-promo.ts @@ -130,7 +130,7 @@ export const initialiseElementsCodePromo = (): void => { ); window.dispatchEvent(CODE_PROMO_MAJ_EVENT); - // emetUniqueMessageBroadcastChannel(NOM_CANAL_REVALIDATION_LIVRAISON, true); + // EmetUniqueMessageBroadcastChannel(NOM_CANAL_REVALIDATION_LIVRAISON, true); }) .ifLeft((erreur) => { // Rétablis le texte d'origine @@ -194,7 +194,9 @@ export const initialiseElementsCodePromo = (): void => { ) .chain((reponse: Response) => EitherAsync(async ({ throwE }) => { - if (estReponse500(reponse)) throwE(new ServerError("500 server Error")); + if (estReponse500(reponse)) { + throwE(new ServerError("500 server Error")); + } return await reponse.json(); }), ) diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-methodes-livraison.ts b/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-methodes-livraison.ts index b0569ff8..23fe3afe 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-methodes-livraison.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-methodes-livraison.ts @@ -1,5 +1,6 @@ import { forEach as arrayForEach, map as arrayMap } from "@mobily/ts-belt/Array"; -import { html, render, type TemplateResult } from "lit-html"; +import { html, render } from "lit-html"; +import type { TemplateResult } from "lit-html"; import type { WCStoreCartTotals, WCStoreShippingRateShippingRate } from "../lib/types/api/cart"; import type { WCStoreShippingRateShippingRates } from "../lib/types/api/couts-livraison"; @@ -66,8 +67,9 @@ export const generateShippingRatesHTML = ( getDOMElementsWithSelector(container)("div[data-methode-initiale]").ifRight(arrayForEach((div) => div.remove())); const selectedShippingRate: string = shippingRates.find((sr) => sr.selected)?.method_id ?? ""; - const shippingRatesHTML: ReadonlyArray = arrayMap(shippingRates, (methode) => { - return html`
+ const shippingRatesHTML: ReadonlyArray = arrayMap( + shippingRates, + (methode) => html`
${methode.name} (${formateEnEuros(methode.price)}) -
`; - }); +
`, + ); // Ajoute les nouveaux Produits dans le DOM container.removeAttribute(ATTRIBUT_HIDDEN); diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-panneau-produits.ts b/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-panneau-produits.ts index fdfa1def..ca604516 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-panneau-produits.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/page-panier/scripts-page-panier-panneau-produits.ts @@ -4,7 +4,8 @@ import { pipe } from "@mobily/ts-belt"; import { forEach as arrayForEach, map as arrayMap } from "@mobily/ts-belt/Array"; import { EitherAsync, Maybe } from "purify-ts"; import { match, P } from "ts-pattern"; -import { type AnySchema, ValiError } from "valibot"; +import { ValiError } from "valibot"; +import type { AnySchema } from "valibot"; import type { WCStoreCart } from "../lib/types/api/cart"; import type { WCStoreCartRemoveItemArgs } from "../lib/types/api/cart-remove-item"; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-bouton-retour-sommet.ts b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-bouton-retour-sommet.ts index 83fa22f8..8d209918 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-bouton-retour-sommet.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-bouton-retour-sommet.ts @@ -59,9 +59,13 @@ const initialiseObservationFenetre = (): void => { // Met à jour la valeur du défilement vertical dans la page defilementY = majDefilementY(); // Vérifie que le Ratio soit le bon - if (ratioActuel < RATIO_MINIMUM_PAGE_PAR_FENETRE) return; + if (ratioActuel < RATIO_MINIMUM_PAGE_PAR_FENETRE) { + return; + } // Attend la prochaine étape - if (etapePlanifiee) return; + if (etapePlanifiee) { + return; + } etapePlanifiee = true; requestAnimationFrame((): void => diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-menu-categories.ts b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-menu-categories.ts index 4556a097..eb30992e 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-menu-categories.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-menu-categories.ts @@ -17,12 +17,16 @@ document.addEventListener("DOMContentLoaded", (): void => { // Créé un nouvel Observer pour la première et dernière entrée. EffectArray.forEach(firstAndLastEntries, (menuEntry, _index) => { - if (Predicate.isUndefined(menuEntry)) return; + if (Predicate.isUndefined(menuEntry)) { + return; + } new IntersectionObserver( EffectArray.forEach((intersectionEntry) => { // Ne déclenche rien si le scroll n'est pas horizontal - if (intersectionEntry.boundingClientRect.top <= 0) return; + if (intersectionEntry.boundingClientRect.top <= 0) { + return; + } Match.value([intersectionEntry.isIntersecting]).pipe( Match.when([true, 0], () => productsCategoriesMenu.removeAttribute("data-entrees-presentes-debut")), @@ -32,7 +36,7 @@ document.addEventListener("DOMContentLoaded", (): void => { Match.orElse(() => {}), ); }), - { root: null, threshold: 0.9 }, + { root: undefined, threshold: 0.9 }, ).observe(menuEntry); }); }); diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-accueil.ts b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-accueil.ts index 710f80df..e073a4fe 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-accueil.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-accueil.ts @@ -102,7 +102,7 @@ const initGestionAnimation = (): void => { A.at(E.IMAGES_STORYTELLING, 0), O.tap((img) => { const options: IntersectionObserverInit = { - root: null, + root: undefined, rootMargin: "0px", threshold: 0, }; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-boutique.ts b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-boutique.ts index 6bab1901..b215ace9 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-boutique.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-boutique.ts @@ -92,13 +92,13 @@ const initialisePageBoutique = (): void => { ) // 4. Traite les cas d'Erreurs et récupère le Corps de la Réponse .chain((reponse: Response) => - EitherAsync(async ({ throwE }) => { - return match(await newPartialResponse(reponse)) + EitherAsync(async ({ throwE }) => + match(await newPartialResponse(reponse)) .with({ status: 500 }, () => throwE(new ServerError("500 Server Error"))) .with({ status: 400 }, () => throwE(new BadRequestError("400 Server Error"))) .with({ status: 200 }, (r) => r.body) - .run(); - }), + .run(), + ), ) // 5. Vérifie le Schéma de la Réponse .chain((corpsReponse: unknown) => EitherAsync.liftEither(safeSchemaParse(corpsReponse, WCV3ProductsSchema))) @@ -139,12 +139,12 @@ const initialisePageBoutique = (): void => { `, - tap((article) => fragment.appendChild(article)), + tap((article) => fragment.append(article)), ); } // Ajoute les nouveaux Produits dans le DOM - E.GRILLE_PRODUITS.appendChild(fragment); + E.GRILLE_PRODUITS.append(fragment); E.GRILLE_PRODUITS.setAttribute(ATTRIBUT_PAGE, String(nouveauNumeroPage)); E.BOUTON_PLUS_DE_PRODUITS.textContent = "Show more"; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-panier.ts b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-panier.ts index 863dcfe9..6198bb0f 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-panier.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-panier.ts @@ -21,7 +21,8 @@ import { } from "./constantes/dom.ts"; import { NOM_CANAL_BOUTON_PANIER, NOM_CANAL_CONTENU_PANIER } from "./constantes/messages.ts"; import { getDOMElementsWithSelector, recupereElementAvecSelecteur, recupereElementOuLeve } from "./lib/dom.ts"; -import { type CleNonTrouveError, reporteErreur } from "./lib/erreurs.ts"; +import { reporteErreur } from "./lib/erreurs.ts"; +import type { CleNonTrouveError } from "./lib/erreurs.ts"; import { valideMessageMajBoutonPanier, valideMessageMajContenuPanier } from "./lib/messages.ts"; import { arrondisADeuxDecimales, diviseParCent, formateEnEuros, inverseNombre } from "./lib/nombres.ts"; import { propEither } from "./lib/utils.ts"; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts index 58eab125..c4176417 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts @@ -7,7 +7,8 @@ import { tap as optionTap } from "@mobily/ts-belt/Option"; import { pipe as epipe } from "effect"; import { EitherAsync, Maybe } from "purify-ts"; import { match, P } from "ts-pattern"; -import { type AnySchema, ValiError } from "valibot"; +import { ValiError } from "valibot"; +import type { AnySchema } from "valibot"; import type { WCStoreCart } from "./lib/types/api/cart"; import type { WCStoreCartAddItemArgs, WCStoreCartAddItemArgsItems } from "./lib/types/api/cart-add-item.ts"; @@ -79,8 +80,12 @@ const gereAccordeonDetailsProduit = (): void => { const idContenu: null | string = bouton.getAttribute(ATTRIBUT_ARIA_CONTROLS); const sectionCorrespondante: HTMLDivElement | undefined = E.CONTENUS_ACCORDEON[index]; - if (!idContenu) throw new Error("Le lien ne dispose pas d'ID !"); - if (!sectionCorrespondante) throw new Error("Le lien ne dispose pas de section correspondante !"); + if (!idContenu) { + throw new Error("Le lien ne dispose pas d'ID !"); + } + if (!sectionCorrespondante) { + throw new Error("Le lien ne dispose pas de section correspondante !"); + } contenus.set(idContenu, [bouton, sectionCorrespondante]); @@ -93,7 +98,9 @@ const gereAccordeonDetailsProduit = (): void => { pipe(contenus.values(), Array.from, deplieToutesSections); // Ne fais rien de plus si l'onglet sélectionné était le courant - if (estAncienContenuDeplie) return; + if (estAncienContenuDeplie) { + return; + } // Ouvre le nouvel onglet sélectionné bouton.setAttribute(ATTRIBUT_ARIA_EXPANDED, "true"); @@ -130,14 +137,14 @@ const getAttributesFromDom = (): ReadonlyArray => { document.querySelectorAll(".selecteur-produit select"), Array.from, ); - if (selectElements.length === 0) return []; + if (selectElements.length === 0) { + return []; + } - const attributes = selectElements.map((select: HTMLSelectElement) => { - return { - attribute: select.id, - value: select.value, - } satisfies WCStoreCartAddItemArgsItems; - }); + const attributes = selectElements.map((select: HTMLSelectElement) => ({ + attribute: select.id, + value: select.value, + })); return attributes; }; @@ -176,9 +183,9 @@ const ajouteProduitAuPanier = (event: MouseEvent): void => { id: E.DOM_VARIATION.map((selecteur: HTMLSelectElement): number => Number(selecteur.value)) // Récupère l'ID du Produit de la Page pour les Produits simples .orDefault(ETATS_PAGE.idProduit), - // id: ETATS_PAGE.idProduit, + // Id: ETATS_PAGE.idProduit, quantity: 1, - // variation: getAttributeValuesFromDom(), + // Variation: getAttributeValuesFromDom(), }; // Réalise la Requête et traite sa Réponse diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/vite.env.d.ts b/web/app/themes/haiku-atelier-2024/src/scripts/vite.env.d.ts index 628c10cb..e1aa1375 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/vite.env.d.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/vite.env.d.ts @@ -1,7 +1,7 @@ /// -interface ImportMeta { +type ImportMeta = { readonly env: ImportMetaEnv; -} +}; -interface ImportMetaEnv {} +type ImportMetaEnv = {}; diff --git a/web/app/themes/haiku-atelier-2024/taxonomy-product_cat.php b/web/app/themes/haiku-atelier-2024/taxonomy-product_cat.php index 5939114f..d402c0e5 100755 --- a/web/app/themes/haiku-atelier-2024/taxonomy-product_cat.php +++ b/web/app/themes/haiku-atelier-2024/taxonomy-product_cat.php @@ -8,7 +8,6 @@ declare(strict_types=1); namespace HaikuAtelier; -use Exception; use HaikuAtelier\Data\Product; use HaikuAtelier\WP\Resource; use Illuminate\Support\Arr; @@ -16,38 +15,36 @@ use Timber\Timber; use WC_Product; use WP_Term; -require_once __DIR__ . '/src/inc/TraitementInformations.php'; +use function add_action; +use function assert; +use function get_queried_object; +use function is_array; +use function wc_get_products; $context = Timber::context(); $templates = ['boutique.twig']; -/** @var WP_Term */ +/** @var WP_Term La Catégorie affichée. */ $current_term = get_queried_object(); -$category_slug = $current_term->slug; -/** @var list $raw_products Les informations brutes des Produits. */ -$raw_products = wc_get_products([ - 'category' => [$category_slug], +/** @var list Les Produits de la Catégorie affichée. */ +$products = wc_get_products([ + 'category' => [$current_term->slug], 'limit' => 12, 'order' => 'DESC', 'orderby' => 'date', 'status' => 'publish', -]); +]) + |> function (/** @var list|stdClass */ mixed $products): array { + assert(is_array($products), 'Les Produits de la Catégorie doivent être un tableau.'); + return $products; + } + |> (static fn(/** @var list */ array $products): array => Arr::map($products, Product::new(...))); -/** @var list */ -$products = Arr::map($raw_products, Product::new(...)); $context['products'] = $products; +$context['category_id'] = $current_term->term_id; -/** @var string */ -$products_category_id = array_shift($raw_products)?->get_category_ids()[0] ?? ''; -$context['products_category_id'] = $products_category_id; - -/** - * Charge les scripts et styles de la page. - * - * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger - */ -function load_page_resources(): void { +add_action('wp_enqueue_scripts', function (): void { Resource::enqueue_style_file( handle: 'haiku-atelier-2024-styles-page-boutique', path: '/assets/css/pages/page-boutique.css', @@ -60,9 +57,7 @@ function load_page_resources(): void { id: 'haiku-atelier-2024-scripts-menu-categories', path: '/assets/js/scripts-menu-categories.js', ); -} - -add_action('wp_enqueue_scripts', load_page_resources(...)); +}); // Rendu Timber::render( diff --git a/web/app/themes/haiku-atelier-2024/views/parts/pages/shop/grille-produits.twig b/web/app/themes/haiku-atelier-2024/views/parts/pages/shop/grille-produits.twig index 31a6e83d..abe8c60a 100755 --- a/web/app/themes/haiku-atelier-2024/views/parts/pages/shop/grille-produits.twig +++ b/web/app/themes/haiku-atelier-2024/views/parts/pages/shop/grille-produits.twig @@ -1,7 +1,7 @@
{% if products|length > 0 %} {% for product in products %}