@lystech/sections 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2096 @@
1
+ import { jsx as n, jsxs as v, Fragment as ue } from "react/jsx-runtime";
2
+ import { createRoot as Ae } from "react-dom/client";
3
+ import { C as ke, A as fe, E as Be, s as we } from "./constantes-BwBWlNYy.js";
4
+ import { useState as I, useRef as V, useEffect as R, useMemo as re, useCallback as W, Suspense as me, lazy as Ce } from "react";
5
+ function je({
6
+ jeton: r,
7
+ site: e,
8
+ apiBaseUrl: o,
9
+ surJetonRefuse: i
10
+ }) {
11
+ const t = {
12
+ "Content-Type": "application/json",
13
+ Authorization: "Bearer " + r
14
+ };
15
+ function s(c, h) {
16
+ if (h && (c.status === 401 || c.status === 403) && i(), !c.ok) throw new Error(String(c.status));
17
+ }
18
+ async function a(c, h = !0) {
19
+ const A = await fetch(o + c, {
20
+ headers: h ? t : void 0
21
+ });
22
+ return s(A, h), await A.json();
23
+ }
24
+ async function f(c, h, A) {
25
+ const k = await fetch(o + c, {
26
+ method: h,
27
+ headers: t,
28
+ body: A === void 0 ? void 0 : JSON.stringify(A)
29
+ });
30
+ return s(k, !0), await k.json();
31
+ }
32
+ async function u(c, h = {}) {
33
+ const A = new Headers(h.headers);
34
+ A.set("Authorization", "Bearer " + r), typeof h.body == "string" && !A.has("Content-Type") && A.set("Content-Type", "application/json");
35
+ const k = await fetch(o + c, { ...h, headers: A });
36
+ return k.status === 401 && i(), k;
37
+ }
38
+ return {
39
+ brut: u,
40
+ /** Les blocs que le site a déclaré savoir afficher. Route publique. */
41
+ schemas: () => a("/site-sections/public/" + encodeURIComponent(e) + "/schemas", !1),
42
+ /** Ce qui existe sur une page, brouillons compris. */
43
+ pourPage: (c) => a("/site-sections?page=" + encodeURIComponent(c)),
44
+ creer: (c, h, A) => f("/site-sections", "POST", { page: c, blockType: h, draft: A }),
45
+ enregistrerBrouillon: (c, h) => f("/site-sections/" + c + "/draft", "PUT", { draft: h }),
46
+ publier: (c) => f("/site-sections/" + c + "/publish", "POST"),
47
+ /** Ramène le brouillon à ce qui est en ligne. */
48
+ annuler: (c) => f("/site-sections/" + c + "/revert", "POST"),
49
+ /** Qui peut voir la section. S'applique TOUT DE SUITE (pas de brouillon). */
50
+ audience: (c, h) => f("/site-sections/" + c + "/audience", "POST", { audience: h }),
51
+ /** Les plans d'abonnement de la boutique, pour « Visible pour : plans… ». */
52
+ optionsAudience: () => a("/site-sections/audience-options")
53
+ };
54
+ }
55
+ const Re = "data:image/png;base64,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", Qe = {
56
+ apiKey: "AIzaSyCpAeHlt1wZvM5KtYg7X7MDVnWVJT86gvc",
57
+ authDomain: "lystech.firebaseapp.com",
58
+ projectId: "lystech",
59
+ storageBucket: "lystech.appspot.com",
60
+ messagingSenderId: "237347321732",
61
+ appId: "1:237347321732:web:7f9586d48e488d73ddcfd1"
62
+ };
63
+ function Fe() {
64
+ return /* @__PURE__ */ v("span", { className: "marque", children: [
65
+ /* @__PURE__ */ n("img", { src: Re, alt: "", width: 22, height: 22 }),
66
+ /* @__PURE__ */ n("span", { className: "marque__mot", children: "Lystech" })
67
+ ] });
68
+ }
69
+ function Ve() {
70
+ return /* @__PURE__ */ v("svg", { viewBox: "0 0 18 18", "aria-hidden": "true", focusable: "false", className: "logo", children: [
71
+ /* @__PURE__ */ n("path", { fill: "#4285F4", d: "M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.91c1.7-1.57 2.69-3.88 2.69-6.62z" }),
72
+ /* @__PURE__ */ n("path", { fill: "#34A853", d: "M9 18c2.43 0 4.47-.8 5.96-2.18l-2.91-2.26c-.81.54-1.84.86-3.05.86-2.34 0-4.33-1.58-5.04-3.71H.96v2.33A9 9 0 0 0 9 18z" }),
73
+ /* @__PURE__ */ n("path", { fill: "#FBBC05", d: "M3.96 10.71a5.41 5.41 0 0 1 0-3.42V4.96H.96a9 9 0 0 0 0 8.08l3-2.33z" }),
74
+ /* @__PURE__ */ n("path", { fill: "#EA4335", d: "M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.59C13.46.89 11.43 0 9 0A9 9 0 0 0 .96 4.96l3 2.33C4.67 5.16 6.66 3.58 9 3.58z" })
75
+ ] });
76
+ }
77
+ function Ye() {
78
+ return /* @__PURE__ */ n("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", className: "logo", children: /* @__PURE__ */ n(
79
+ "path",
80
+ {
81
+ fill: "#fff",
82
+ d: "M22 12.06C22 6.5 17.52 2 12 2S2 6.5 2 12.06c0 5.02 3.66 9.18 8.44 9.94v-7.03H7.9v-2.91h2.54V9.85c0-2.52 1.49-3.91 3.77-3.91 1.09 0 2.24.2 2.24.2v2.46h-1.26c-1.24 0-1.63.78-1.63 1.57v1.89h2.78l-.45 2.91h-2.33V22c4.78-.76 8.44-4.92 8.44-9.94z"
83
+ }
84
+ ) });
85
+ }
86
+ function Xe({
87
+ site: r,
88
+ apiBaseUrl: e,
89
+ methodes: o = ["google", "facebook"],
90
+ surJeton: i,
91
+ surFermer: t
92
+ }) {
93
+ const [s, a] = I({ nom: "repos" }), f = (A) => {
94
+ switch (A) {
95
+ case "auth/popup-blocked":
96
+ return "Votre navigateur a bloqué la fenêtre de connexion. Autorisez les fenêtres pour ce site, puis réessayez.";
97
+ case "auth/popup-closed-by-user":
98
+ case "auth/cancelled-popup-request":
99
+ return "Connexion annulée.";
100
+ case "auth/unauthorized-domain":
101
+ return "Ce domaine n'est pas encore autorisé côté Lystech. Prévenez la personne qui gère le site.";
102
+ case "auth/account-exists-with-different-credential":
103
+ return "Cette adresse est déjà associée à un autre mode de connexion. Essayez l'autre bouton.";
104
+ case "auth/network-request-failed":
105
+ return "Connexion au réseau impossible. Vérifiez votre lien Internet.";
106
+ default:
107
+ return "La connexion a échoué. Réessayez dans un instant.";
108
+ }
109
+ }, u = async (A, k = !1) => {
110
+ const T = await fetch(e + "/site-sections/edit-login/third-party", {
111
+ method: "POST",
112
+ headers: { "Content-Type": "application/json" },
113
+ body: JSON.stringify({
114
+ site: r,
115
+ token: A,
116
+ tokenType: "firebase",
117
+ demanderAcces: k
118
+ })
119
+ });
120
+ if (T.status === 429) {
121
+ a({
122
+ nom: "erreur",
123
+ texte: "Trop de tentatives. Réessayez dans quelques minutes."
124
+ });
125
+ return;
126
+ }
127
+ const S = await T.json().catch(() => null);
128
+ if (S?.ok && S?.token) {
129
+ i(S.token);
130
+ return;
131
+ }
132
+ switch (S?.raison) {
133
+ case "sans_acces":
134
+ a({ nom: "sans-acces", jeton: A });
135
+ return;
136
+ case "demande_envoyee":
137
+ a({ nom: "demande-envoyee" });
138
+ return;
139
+ case "trop_de_demandes":
140
+ a({
141
+ nom: "erreur",
142
+ texte: "Trop de demandes aujourd'hui. Réessayez demain."
143
+ });
144
+ return;
145
+ case "aucun_compte":
146
+ a({ nom: "aucun-compte", adresse: "" });
147
+ return;
148
+ case "adresse_non_verifiee":
149
+ a({
150
+ nom: "erreur",
151
+ texte: "Votre fournisseur n'a pas confirmé cette adresse courriel. Vérifiez-la chez lui, puis réessayez."
152
+ });
153
+ return;
154
+ default:
155
+ a({
156
+ nom: "erreur",
157
+ texte: "La connexion a échoué. Réessayez dans un instant."
158
+ });
159
+ }
160
+ }, c = async (A) => {
161
+ a({ nom: "envoi", quoi: A });
162
+ try {
163
+ const [{ initializeApp: k, getApps: T }, S] = await Promise.all([
164
+ import("./index.esm-B4AB50RA.js"),
165
+ import("./index.esm-B4hL1FOE.js")
166
+ ]), y = T().find((m) => m.name === "lystech-edition") ?? k(Qe, "lystech-edition"), D = A === "google" ? new S.GoogleAuthProvider() : new S.FacebookAuthProvider(), p = await (await S.signInWithPopup(S.getAuth(y), D)).user.getIdToken();
167
+ await u(p);
168
+ } catch (k) {
169
+ a({ nom: "erreur", texte: f(String(k?.code ?? "")) });
170
+ }
171
+ }, h = s.nom === "envoi";
172
+ return /* @__PURE__ */ n("div", { className: "voile", role: "dialog", "aria-modal": "true", "aria-label": "Modifier ce site", children: /* @__PURE__ */ v("div", { className: "fenetre", children: [
173
+ /* @__PURE__ */ n(
174
+ "button",
175
+ {
176
+ type: "button",
177
+ className: "fenetre__fermer",
178
+ onClick: t,
179
+ "aria-label": "Fermer",
180
+ children: "✕"
181
+ }
182
+ ),
183
+ /* @__PURE__ */ v("div", { className: "fenetre__tete", children: [
184
+ /* @__PURE__ */ n(Fe, {}),
185
+ /* @__PURE__ */ n("h2", { className: "fenetre__titre", children: "Modifier ce site" }),
186
+ /* @__PURE__ */ n("p", { className: "fenetre__sous", children: "Vous vous connectez à Lystech. Cet accès ne sert qu'à modifier le contenu de ce site." })
187
+ ] }),
188
+ /* @__PURE__ */ v("div", { className: "fenetre__corps", children: [
189
+ s.nom === "erreur" && /* @__PURE__ */ n("p", { className: "message message--erreur", children: s.texte }),
190
+ s.nom === "aucun-compte" && /* @__PURE__ */ n("p", { className: "message message--info", children: "Aucun compte Lystech ne correspond à cette adresse. Adressez-vous à la personne responsable du site." }),
191
+ s.nom === "sans-acces" && /* @__PURE__ */ n("p", { className: "message message--info", children: "Vous êtes bien reconnu, mais vous n'avez pas encore le droit de modifier ce site. Vous pouvez le demander : la personne responsable recevra un courriel." }),
192
+ s.nom === "demande-envoyee" && /* @__PURE__ */ n("p", { className: "message message--ok", children: "Demande envoyée. La personne responsable du site vous répondra." }),
193
+ s.nom === "sans-acces" ? /* @__PURE__ */ n(
194
+ "button",
195
+ {
196
+ type: "button",
197
+ className: "bouton bouton--principal bouton--large",
198
+ onClick: () => {
199
+ u(s.jeton, !0);
200
+ },
201
+ children: "Demander l'accès"
202
+ }
203
+ ) : s.nom === "demande-envoyee" || s.nom === "aucun-compte" ? /* @__PURE__ */ n(
204
+ "button",
205
+ {
206
+ type: "button",
207
+ className: "bouton bouton--large",
208
+ onClick: t,
209
+ children: "Fermer"
210
+ }
211
+ ) : /* @__PURE__ */ v("div", { className: "fournisseurs", children: [
212
+ o.includes("google") && /* @__PURE__ */ v(
213
+ "button",
214
+ {
215
+ type: "button",
216
+ className: "fournisseur fournisseur--google",
217
+ disabled: h,
218
+ onClick: () => {
219
+ c("google");
220
+ },
221
+ children: [
222
+ /* @__PURE__ */ n(Ve, {}),
223
+ /* @__PURE__ */ n("span", { children: s.nom === "envoi" && s.quoi === "google" ? "Connexion…" : "Continuer avec Google" })
224
+ ]
225
+ }
226
+ ),
227
+ o.includes("facebook") && /* @__PURE__ */ v(
228
+ "button",
229
+ {
230
+ type: "button",
231
+ className: "fournisseur fournisseur--facebook",
232
+ disabled: h,
233
+ onClick: () => {
234
+ c("facebook");
235
+ },
236
+ children: [
237
+ /* @__PURE__ */ n(Ye, {}),
238
+ /* @__PURE__ */ n("span", { children: s.nom === "envoi" && s.quoi === "facebook" ? "Connexion…" : "Continuer avec Facebook" })
239
+ ]
240
+ }
241
+ )
242
+ ] })
243
+ ] })
244
+ ] }) });
245
+ }
246
+ function We(r, e) {
247
+ const o = r && typeof r == "object" && !Array.isArray(r) ? Object.keys(r).filter((t) => /^[a-z]{2}(-[A-Za-z]{2})?$/.test(t)) : [], i = e.slice(0, 2);
248
+ return Array.from(/* @__PURE__ */ new Set([i, ...o]));
249
+ }
250
+ function He(r) {
251
+ switch (r.type) {
252
+ case "number":
253
+ return 0;
254
+ case "boolean":
255
+ return !1;
256
+ case "list":
257
+ return [];
258
+ default:
259
+ return "";
260
+ }
261
+ }
262
+ function be({ champ: r, valeur: e, changer: o }) {
263
+ switch (r.type) {
264
+ case "richText":
265
+ return /* @__PURE__ */ n(
266
+ "textarea",
267
+ {
268
+ value: String(e ?? ""),
269
+ onChange: (i) => o(i.target.value)
270
+ }
271
+ );
272
+ case "number":
273
+ return /* @__PURE__ */ n(
274
+ "input",
275
+ {
276
+ type: "number",
277
+ value: e === "" || e == null ? "" : String(e),
278
+ onChange: (i) => o(i.target.value === "" ? "" : Number(i.target.value))
279
+ }
280
+ );
281
+ case "boolean":
282
+ return /* @__PURE__ */ v("label", { className: "bascule", children: [
283
+ /* @__PURE__ */ n(
284
+ "input",
285
+ {
286
+ type: "checkbox",
287
+ checked: e === !0,
288
+ onChange: (i) => o(i.target.checked)
289
+ }
290
+ ),
291
+ /* @__PURE__ */ n("span", { children: e === !0 ? "Oui" : "Non" })
292
+ ] });
293
+ case "date":
294
+ return /* @__PURE__ */ n(
295
+ "input",
296
+ {
297
+ type: "date",
298
+ value: String(e ?? "").slice(0, 10),
299
+ onChange: (i) => o(i.target.value)
300
+ }
301
+ );
302
+ case "choice":
303
+ return /* @__PURE__ */ v(
304
+ "select",
305
+ {
306
+ value: String(e ?? ""),
307
+ onChange: (i) => o(i.target.value),
308
+ children: [
309
+ /* @__PURE__ */ n("option", { value: "", children: "—" }),
310
+ (r.options ?? []).map((i) => /* @__PURE__ */ n("option", { value: i, children: i }, i))
311
+ ]
312
+ }
313
+ );
314
+ case "url":
315
+ return /* @__PURE__ */ n(
316
+ "input",
317
+ {
318
+ type: "url",
319
+ value: String(e ?? ""),
320
+ onChange: (i) => o(i.target.value),
321
+ placeholder: "https://"
322
+ }
323
+ );
324
+ case "image":
325
+ return /* @__PURE__ */ v(ue, { children: [
326
+ /* @__PURE__ */ n(
327
+ "input",
328
+ {
329
+ type: "url",
330
+ value: String(e ?? ""),
331
+ onChange: (i) => o(i.target.value),
332
+ placeholder: "https://…"
333
+ }
334
+ ),
335
+ String(e ?? "").startsWith("http") && /* @__PURE__ */ n("img", { className: "vignette", src: String(e), alt: "" })
336
+ ] });
337
+ default:
338
+ return /* @__PURE__ */ n(
339
+ "input",
340
+ {
341
+ type: "text",
342
+ value: String(e ?? ""),
343
+ onChange: (i) => o(i.target.value)
344
+ }
345
+ );
346
+ }
347
+ }
348
+ function Ee({ champ: r, valeur: e, changer: o, langue: i }) {
349
+ if (r.type === "list") {
350
+ const t = Array.isArray(e) ? e : [], s = r.of ?? [], a = (f, u, c) => {
351
+ const h = t.map((A, k) => k === f ? { ...A, [u]: c } : A);
352
+ o(h);
353
+ };
354
+ return /* @__PURE__ */ v("div", { className: "champ", children: [
355
+ /* @__PURE__ */ n("span", { className: "champ__etiquette", children: r.label }),
356
+ r.help && /* @__PURE__ */ n("p", { className: "champ__aide", children: r.help }),
357
+ t.map((f, u) => /* @__PURE__ */ v("div", { className: "liste__item", children: [
358
+ /* @__PURE__ */ v("div", { className: "liste__tete", children: [
359
+ /* @__PURE__ */ n("span", { className: "liste__rang", children: u + 1 }),
360
+ /* @__PURE__ */ v("span", { style: { display: "flex", gap: 4 }, children: [
361
+ /* @__PURE__ */ n(
362
+ "button",
363
+ {
364
+ type: "button",
365
+ className: "bouton bouton--icone bouton--discret",
366
+ title: "Monter",
367
+ disabled: u === 0,
368
+ onClick: () => {
369
+ const c = [...t];
370
+ [c[u - 1], c[u]] = [c[u], c[u - 1]], o(c);
371
+ },
372
+ children: "↑"
373
+ }
374
+ ),
375
+ /* @__PURE__ */ n(
376
+ "button",
377
+ {
378
+ type: "button",
379
+ className: "bouton bouton--icone bouton--discret",
380
+ title: "Descendre",
381
+ disabled: u === t.length - 1,
382
+ onClick: () => {
383
+ const c = [...t];
384
+ [c[u], c[u + 1]] = [c[u + 1], c[u]], o(c);
385
+ },
386
+ children: "↓"
387
+ }
388
+ ),
389
+ /* @__PURE__ */ n(
390
+ "button",
391
+ {
392
+ type: "button",
393
+ className: "bouton bouton--icone bouton--discret",
394
+ title: "Retirer",
395
+ onClick: () => o(t.filter((c, h) => h !== u)),
396
+ children: "✕"
397
+ }
398
+ )
399
+ ] })
400
+ ] }),
401
+ s.map((c) => /* @__PURE__ */ n(
402
+ Ee,
403
+ {
404
+ champ: c,
405
+ langue: i,
406
+ valeur: f?.[c.key],
407
+ changer: (h) => a(u, c.key, h)
408
+ },
409
+ c.key
410
+ ))
411
+ ] }, u)),
412
+ /* @__PURE__ */ n(
413
+ "button",
414
+ {
415
+ type: "button",
416
+ className: "bouton",
417
+ onClick: () => o([
418
+ ...t,
419
+ Object.fromEntries(s.map((f) => [f.key, He(f)]))
420
+ ]),
421
+ children: "+ Ajouter"
422
+ }
423
+ )
424
+ ] });
425
+ }
426
+ if (r.localized) {
427
+ const t = We(e, i), s = e && typeof e == "object" && !Array.isArray(e) ? e : {};
428
+ return /* @__PURE__ */ v("div", { className: "champ", children: [
429
+ /* @__PURE__ */ n("span", { className: "champ__etiquette", children: r.label }),
430
+ r.help && /* @__PURE__ */ n("p", { className: "champ__aide", children: r.help }),
431
+ t.map((a) => /* @__PURE__ */ v("div", { style: { marginBottom: 8 }, children: [
432
+ /* @__PURE__ */ n("span", { className: "champ__langue", children: a }),
433
+ /* @__PURE__ */ n(
434
+ be,
435
+ {
436
+ champ: r,
437
+ valeur: s[a],
438
+ changer: (f) => o({ ...s, [a]: f })
439
+ }
440
+ )
441
+ ] }, a))
442
+ ] });
443
+ }
444
+ return /* @__PURE__ */ v("div", { className: "champ", children: [
445
+ /* @__PURE__ */ n("label", { className: "champ__etiquette", children: r.label }),
446
+ /* @__PURE__ */ n(be, { champ: r, valeur: e, changer: o }),
447
+ r.help && /* @__PURE__ */ n("p", { className: "champ__aide", children: r.help })
448
+ ] });
449
+ }
450
+ const Ne = "data-lystech-champ", Ge = ["lystech-editeur-hote", "lystech-connexion-hote"], Ze = ["number", "text", "url", "date"], Je = "outline:2px dashed rgba(59,165,141,.85);outline-offset:3px;border-radius:3px;cursor:text;";
451
+ function ae(r) {
452
+ if (!(r instanceof Element)) return null;
453
+ const e = r.closest(`[${Ne}]`);
454
+ return !e || e.closest("." + ke) || Ge.some((o) => e.closest("#" + o)) ? null : e;
455
+ }
456
+ function he(r) {
457
+ const e = r.getAttribute(Ne) ?? "", o = e.lastIndexOf(":");
458
+ return o <= 0 || o === e.length - 1 ? null : { blockType: e.slice(0, o), champ: e.slice(o + 1) };
459
+ }
460
+ function se(r) {
461
+ const e = r.dataset.lysStyleAvant;
462
+ e !== void 0 && (delete r.dataset.lysStyleAvant, e ? r.setAttribute("style", e) : r.removeAttribute("style"));
463
+ }
464
+ function Ke(r, e) {
465
+ if (r === "number") {
466
+ const o = e.replace(/\s/g, "").replace(",", "."), i = Number(o);
467
+ return o === "" || !Number.isFinite(i) ? { ok: !1, erreur: "Un nombre, en chiffres — par exemple 85 ou 85,50." } : { ok: !0, valeur: i };
468
+ }
469
+ return { ok: !0, valeur: e.trim() };
470
+ }
471
+ function $e({
472
+ actif: r,
473
+ lire: e,
474
+ enregistrer: o,
475
+ ouvrirPanneau: i
476
+ }) {
477
+ const [t, s] = I(null), a = V(null), f = V(1), u = V(null), c = V(null), h = V({ lire: e, enregistrer: o, ouvrirPanneau: i });
478
+ h.current = { lire: e, enregistrer: o, ouvrirPanneau: i }, R(() => {
479
+ if (!r) {
480
+ s(null);
481
+ return;
482
+ }
483
+ const y = /* @__PURE__ */ new Set(), D = (w) => {
484
+ const E = ae(w.target);
485
+ if (!E) return;
486
+ const O = he(E);
487
+ !O || !h.current.lire(O.blockType, O.champ) || (E.dataset.lysStyleAvant === void 0 && (E.dataset.lysStyleAvant = E.getAttribute("style") ?? ""), E.setAttribute("style", E.dataset.lysStyleAvant + Je), y.add(E));
488
+ }, C = (w) => {
489
+ const E = ae(w.target);
490
+ if (!E) return;
491
+ const O = w.relatedTarget;
492
+ O instanceof Node && E.contains(O) || (se(E), y.delete(E));
493
+ }, p = (w) => {
494
+ const E = ae(w.target);
495
+ if (!E) return;
496
+ const O = he(E);
497
+ if (!O) return;
498
+ const Y = h.current.lire(O.blockType, O.champ);
499
+ if (!Y) return;
500
+ if (w.preventDefault(), w.stopPropagation(), se(E), y.delete(E), !Ze.includes(Y.type)) {
501
+ h.current.ouvrirPanneau(O.blockType);
502
+ return;
503
+ }
504
+ const x = getComputedStyle(E);
505
+ s({
506
+ jeton: f.current++,
507
+ ...O,
508
+ info: Y,
509
+ el: E,
510
+ rect: E.getBoundingClientRect(),
511
+ police: {
512
+ fontFamily: x.fontFamily,
513
+ fontSize: x.fontSize,
514
+ fontWeight: x.fontWeight,
515
+ letterSpacing: x.letterSpacing
516
+ },
517
+ texte: Y.valeur == null ? "" : String(Y.valeur),
518
+ erreur: null,
519
+ envoi: !1
520
+ });
521
+ }, m = () => s((w) => w && { ...w, rect: w.el.getBoundingClientRect() });
522
+ return document.addEventListener("mouseover", D, !0), document.addEventListener("mouseout", C, !0), document.addEventListener("click", p, !0), window.addEventListener("scroll", m, { capture: !0, passive: !0 }), window.addEventListener("resize", m), () => {
523
+ document.removeEventListener("mouseover", D, !0), document.removeEventListener("mouseout", C, !0), document.removeEventListener("click", p, !0), window.removeEventListener("scroll", m, { capture: !0 }), window.removeEventListener("resize", m);
524
+ for (const w of y) se(w);
525
+ };
526
+ }, [r]);
527
+ const A = t?.jeton;
528
+ if (R(() => {
529
+ A != null && (a.current?.focus(), a.current?.select());
530
+ }, [A]), !t) return null;
531
+ const k = (y) => s((D) => D && D.jeton === y ? null : D);
532
+ async function T(y) {
533
+ if (u.current === y.jeton || c.current === y.jeton) return;
534
+ const D = y.info.valeur == null ? "" : String(y.info.valeur);
535
+ if (y.texte.trim() === D.trim()) {
536
+ k(y.jeton);
537
+ return;
538
+ }
539
+ const C = Ke(y.info.type, y.texte);
540
+ if (!C.ok) {
541
+ s((m) => m && m.jeton === y.jeton ? { ...m, erreur: C.erreur } : m);
542
+ return;
543
+ }
544
+ s((m) => m && m.jeton === y.jeton ? { ...m, envoi: !0, erreur: null } : m), u.current = y.jeton;
545
+ let p = !1;
546
+ try {
547
+ p = await h.current.enregistrer(y.blockType, y.champ, C.valeur);
548
+ } finally {
549
+ u.current = null;
550
+ }
551
+ p ? k(y.jeton) : s(
552
+ (m) => m && m.jeton === y.jeton ? { ...m, envoi: !1, erreur: "Enregistrement impossible — la valeur en ligne n'a pas changé." } : m
553
+ );
554
+ }
555
+ const S = Math.max(t.rect.width + 40, 110);
556
+ return /* @__PURE__ */ v(
557
+ "form",
558
+ {
559
+ className: "saisie",
560
+ style: { top: t.rect.top - 28, left: t.rect.left - 8 },
561
+ onSubmit: (y) => {
562
+ y.preventDefault(), T(t);
563
+ },
564
+ children: [
565
+ /* @__PURE__ */ n("span", { className: "saisie__libelle", children: t.info.libelle }),
566
+ /* @__PURE__ */ n(
567
+ "input",
568
+ {
569
+ ref: a,
570
+ className: "saisie__champ",
571
+ style: { ...t.police, width: S },
572
+ value: t.texte,
573
+ inputMode: t.info.type === "number" ? "decimal" : void 0,
574
+ disabled: t.envoi,
575
+ "aria-label": t.info.libelle,
576
+ onChange: (y) => {
577
+ const D = y.target.value;
578
+ s((C) => C && { ...C, texte: D, erreur: null });
579
+ },
580
+ onKeyDown: (y) => {
581
+ if (y.key === "Enter") {
582
+ y.preventDefault(), T(t);
583
+ return;
584
+ }
585
+ y.key === "Escape" && (y.preventDefault(), c.current = t.jeton, k(t.jeton));
586
+ },
587
+ onBlur: () => {
588
+ T(t);
589
+ }
590
+ }
591
+ ),
592
+ t.erreur ? /* @__PURE__ */ n("span", { className: "saisie__erreur", children: t.erreur }) : /* @__PURE__ */ n("span", { className: "saisie__aide", children: "Entrée pour enregistrer · Échap pour annuler" })
593
+ ]
594
+ }
595
+ );
596
+ }
597
+ class ge extends Error {
598
+ constructor(e, o, i = {}, t = null) {
599
+ super(e), this.statut = o, this.erreurs = i, this.raison = t;
600
+ }
601
+ }
602
+ const et = "/site-sections/boutique";
603
+ function tt(r) {
604
+ async function e(t, s = {}) {
605
+ let a;
606
+ try {
607
+ a = await r(et + t, s);
608
+ } catch {
609
+ throw new ge("Pas de connexion au serveur. Vérifiez Internet et réessayez.", 0);
610
+ }
611
+ let f = null;
612
+ try {
613
+ f = await a.json();
614
+ } catch {
615
+ f = null;
616
+ }
617
+ if (!a.ok) {
618
+ const u = f?.error ?? (a.status === 403 ? "La boutique se gère par un administrateur de l'organisation." : a.status === 413 ? "Envoi trop volumineux." : "L'opération a échoué. Réessayez.");
619
+ throw new ge(u, a.status, f?.erreurs ?? {}, f?.raison ?? null);
620
+ }
621
+ return f;
622
+ }
623
+ const o = (t, s) => ({
624
+ method: t,
625
+ body: JSON.stringify(s)
626
+ }), i = (t) => "/produits/" + encodeURIComponent(t);
627
+ return {
628
+ /** Le module s'affiche-t-il ? Faux en cas de doute (ancien serveur, éditeur). */
629
+ droits: async () => {
630
+ try {
631
+ return (await e("/droits")).catalogue === !0;
632
+ } catch {
633
+ return !1;
634
+ }
635
+ },
636
+ produits: () => e("/produits"),
637
+ produit: (t) => e(i(t)),
638
+ creer: (t) => e("/produits", o("POST", t)),
639
+ modifier: (t, s) => e(i(t), o("PATCH", s)),
640
+ visible: (t, s) => e(i(t) + "/visible", o("POST", { visible: s })),
641
+ supprimer: (t) => e(i(t), o("DELETE", { confirmer: !0 })),
642
+ ajouterPhoto: (t, s, a) => {
643
+ const f = new FormData();
644
+ return f.set("photo", s, a), e(i(t) + "/photos", { method: "POST", body: f });
645
+ },
646
+ principale: (t, s) => e(i(t) + "/photos/" + encodeURIComponent(s) + "/principale", o("POST", {})),
647
+ retirerPhoto: (t, s) => e(i(t) + "/photos/" + encodeURIComponent(s), o("DELETE", {})),
648
+ collections: () => e("/collections"),
649
+ creerCollection: (t) => e("/collections", o("POST", { nom: t })),
650
+ modifierCollection: (t, s) => e("/collections/" + encodeURIComponent(t), o("PATCH", s)),
651
+ garnirCollection: (t, s, a) => e("/collections/" + encodeURIComponent(t) + "/produits", o("POST", { ajouter: s, retirer: a }))
652
+ };
653
+ }
654
+ function wt(r) {
655
+ return new Intl.NumberFormat("fr-CA", { style: "currency", currency: "CAD" }).format(r);
656
+ }
657
+ const nt = ["lystech-editeur-hote", "lystech-connexion-hote"];
658
+ function rt(r) {
659
+ return ((r.innerText || "").split(`
660
+ `).map((o) => o.trim()).find((o) => o && !/^\d/.test(o) && o.length > 2) ?? "ce bijou").slice(0, 60);
661
+ }
662
+ function ot(r, e) {
663
+ const o = r[r.length - 1], i = r[0];
664
+ if (!o || !i) return null;
665
+ const t = r.filter((c) => Math.abs(c.top - i.top) < 4), s = t.length > 1 ? t[1].left - (t[0].left + t[0].width) : 16, a = r.find((c) => c.top > i.top + 4), f = a ? a.top - (i.top + i.height) : 16, u = o.left + o.width + Math.max(0, s);
666
+ return u + o.width <= e.left + e.width + 2 ? { top: o.top, left: u, width: o.width, height: o.height } : { top: o.top + o.height + Math.max(0, f), left: i.left, width: o.width, height: o.height };
667
+ }
668
+ function it({ actif: r, ouvrir: e }) {
669
+ const [o, i] = I([]), [t, s] = I(null);
670
+ return R(() => {
671
+ if (!r) {
672
+ i([]), s(null);
673
+ return;
674
+ }
675
+ let a = 0;
676
+ const f = () => {
677
+ a = 0;
678
+ const h = Array.from(document.querySelectorAll(`[${fe}]`)).filter(
679
+ (p) => !nt.some((m) => p.closest("#" + m))
680
+ ), A = window.innerHeight, k = [];
681
+ for (const p of h) {
682
+ const m = p.getBoundingClientRect();
683
+ m.width < 24 || m.bottom < 0 || m.top > A || k.push({ UID: p.getAttribute(fe) ?? "", nom: rt(p), r: { top: m.top, left: m.left, width: m.width, height: m.height } });
684
+ }
685
+ i(k.filter((p) => p.UID));
686
+ const T = h[h.length - 1], S = T?.parentElement;
687
+ if (!T || !S) return s(null);
688
+ const y = h.filter((p) => p.parentElement === S).map((p) => p.getBoundingClientRect()), D = S.getBoundingClientRect(), C = ot(y, { top: D.top, left: D.left, width: D.width, height: D.height });
689
+ s(C && C.top < A && C.top + C.height > 0 ? C : null);
690
+ }, u = () => {
691
+ a || (a = requestAnimationFrame(f));
692
+ };
693
+ f();
694
+ const c = new MutationObserver(u);
695
+ return c.observe(document.body, { childList: !0, subtree: !0 }), window.addEventListener("scroll", u, { capture: !0, passive: !0 }), window.addEventListener("resize", u), () => {
696
+ c.disconnect(), window.removeEventListener("scroll", u, !0), window.removeEventListener("resize", u), a && cancelAnimationFrame(a);
697
+ };
698
+ }, [r]), r ? /* @__PURE__ */ v(ue, { children: [
699
+ o.map((a) => /* @__PURE__ */ n(
700
+ "button",
701
+ {
702
+ type: "button",
703
+ className: "crayon",
704
+ style: { top: a.r.top + 8, left: a.r.left + a.r.width - 52 },
705
+ onClick: () => e(a.UID),
706
+ "aria-label": "Modifier " + a.nom,
707
+ title: "Modifier " + a.nom,
708
+ children: /* @__PURE__ */ v("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
709
+ /* @__PURE__ */ n("path", { d: "M12 20h9" }),
710
+ /* @__PURE__ */ n("path", { d: "M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z" })
711
+ ] })
712
+ },
713
+ a.UID + ":" + a.r.top
714
+ )),
715
+ t && /* @__PURE__ */ v(
716
+ "button",
717
+ {
718
+ type: "button",
719
+ className: "tuile-ajout",
720
+ style: { top: t.top, left: t.left, width: t.width, height: Math.min(t.height, t.width * 1.1) },
721
+ onClick: () => e("nouveau"),
722
+ children: [
723
+ /* @__PURE__ */ n("b", { "aria-hidden": "true", children: "+" }),
724
+ "Ajouter un bijou"
725
+ ]
726
+ }
727
+ )
728
+ ] }) : null;
729
+ }
730
+ const at = ["lystech-editeur-hote", "lystech-connexion-hote"];
731
+ function st(r, e) {
732
+ const o = /* @__PURE__ */ new Map();
733
+ for (const [i, t] of Object.entries(r))
734
+ for (const [s, a] of Object.entries(t)) {
735
+ const f = String(a ?? "").trim();
736
+ if (f.length < 2 || f.includes("{{")) continue;
737
+ const u = e(i, s);
738
+ if (u <= 0) continue;
739
+ const c = o.get(f);
740
+ c ? c.push({ ns: i, chemin: s, rang: u }) : o.set(f, [{ ns: i, chemin: s, rang: u }]);
741
+ }
742
+ return o;
743
+ }
744
+ function lt(r) {
745
+ const e = /* @__PURE__ */ new Map(), o = document.body.querySelectorAll("*");
746
+ for (const i of o) {
747
+ if (at.some((a) => i.id === a || i.closest("#" + a)) || i.closest("." + ke) || i.closest("[data-lystech-champ]") || i.children.length > 0) continue;
748
+ const t = (i.textContent ?? "").trim();
749
+ if (t.length < 2) continue;
750
+ const s = r.get(t);
751
+ s && e.set(i, { valeur: t, candidats: s });
752
+ }
753
+ return e;
754
+ }
755
+ function ct({
756
+ source: r,
757
+ actif: e,
758
+ pertinence: o,
759
+ surModification: i
760
+ }) {
761
+ const t = V(/* @__PURE__ */ new Map()), s = V(null), [a, f] = I(null), u = V(r);
762
+ u.current = r;
763
+ const c = V(i);
764
+ c.current = i;
765
+ const h = V(o);
766
+ h.current = o;
767
+ const A = V(null);
768
+ return R(() => {
769
+ if (!e) return;
770
+ const k = () => {
771
+ const x = u.current, b = st(
772
+ x.dictionnaire(x.langueCourante()),
773
+ h.current
774
+ );
775
+ t.current = lt(b);
776
+ };
777
+ A.current = k, k();
778
+ let T;
779
+ const S = new MutationObserver(() => {
780
+ s.current || (clearTimeout(T), T = setTimeout(k, 250));
781
+ });
782
+ S.observe(document.body, { childList: !0, subtree: !0 });
783
+ const y = "outline:2px dashed rgba(59,165,141,.85);outline-offset:3px;border-radius:3px;cursor:text;", D = (x) => {
784
+ const b = x.target;
785
+ !(b instanceof HTMLElement) || s.current || t.current.has(b) && (b.dataset.lysStyleAvant || (b.dataset.lysStyleAvant = b.getAttribute("style") ?? ""), b.setAttribute(
786
+ "style",
787
+ (b.dataset.lysStyleAvant ?? "") + y
788
+ ));
789
+ }, C = (x) => {
790
+ const b = x.target;
791
+ if (!(b instanceof HTMLElement) || s.current?.el === b || b.dataset.lysStyleAvant === void 0) return;
792
+ const B = b.dataset.lysStyleAvant;
793
+ delete b.dataset.lysStyleAvant, B ? b.setAttribute("style", B) : b.removeAttribute("style");
794
+ }, p = (x, b) => {
795
+ const B = x.getAttribute("style") ?? "";
796
+ s.current = {
797
+ el: x,
798
+ avant: (x.textContent ?? "").trim(),
799
+ ns: b.ns,
800
+ chemin: b.chemin,
801
+ styleAvant: x.dataset.lysStyleAvant ?? B
802
+ }, x.setAttribute("contenteditable", "plaintext-only"), x.setAttribute(
803
+ "style",
804
+ (x.dataset.lysStyleAvant ?? "") + "outline:2px solid #3ba58d;outline-offset:3px;border-radius:3px;"
805
+ ), x.focus();
806
+ const Q = window.getSelection(), j = document.createRange();
807
+ j.selectNodeContents(x), Q?.removeAllRanges(), Q?.addRange(j);
808
+ }, m = async (x) => {
809
+ const b = s.current;
810
+ if (!b) return;
811
+ s.current = null;
812
+ const B = (b.el.textContent ?? "").trim();
813
+ b.el.removeAttribute("contenteditable");
814
+ const Q = b.el.dataset.lysStyleAvant;
815
+ if (delete b.el.dataset.lysStyleAvant, Q ? b.el.setAttribute("style", Q) : b.el.removeAttribute("style"), x || B === b.avant) {
816
+ x && (b.el.textContent = b.avant);
817
+ return;
818
+ }
819
+ const j = u.current.langueCourante();
820
+ u.current.poser(j, b.ns, b.chemin, B), await c.current(b.ns, b.chemin, j, B);
821
+ }, w = (x) => {
822
+ const b = x.target;
823
+ if (!(b instanceof HTMLElement)) return;
824
+ if (s.current) {
825
+ if (s.current.el === b) return;
826
+ m(!1);
827
+ }
828
+ const B = t.current.get(b);
829
+ if (!B) return;
830
+ x.preventDefault(), x.stopPropagation();
831
+ const Q = Math.max(...B.candidats.map(($) => $.rang)), j = B.candidats.filter(($) => $.rang === Q);
832
+ if (j.length === 1) {
833
+ p(b, j[0]);
834
+ return;
835
+ }
836
+ f({
837
+ el: b,
838
+ candidats: j,
839
+ x: x.clientX,
840
+ y: x.clientY
841
+ });
842
+ }, E = (x) => {
843
+ s.current && (x.key === "Escape" ? (x.preventDefault(), m(!0)) : x.key === "Enter" && !x.shiftKey && (x.preventDefault(), m(!1)));
844
+ }, O = () => {
845
+ s.current && m(!1);
846
+ };
847
+ document.addEventListener("mouseover", D, !0), document.addEventListener("mouseout", C, !0), document.addEventListener("click", w, !0);
848
+ const Y = (x) => {
849
+ if (!s.current) return;
850
+ const b = x.inputType;
851
+ (b === "insertParagraph" || b === "insertLineBreak") && (x.preventDefault(), m(!1));
852
+ };
853
+ return document.addEventListener("beforeinput", Y, !0), document.addEventListener("keydown", E, !0), document.addEventListener("focusout", O, !0), window.__lysChoisir = (x, b) => {
854
+ f(null), p(b, x);
855
+ }, () => {
856
+ A.current = null, clearTimeout(T), S.disconnect(), document.removeEventListener("mouseover", D, !0), document.removeEventListener("mouseout", C, !0), document.removeEventListener("click", w, !0), document.removeEventListener("beforeinput", Y, !0), document.removeEventListener("keydown", E, !0), document.removeEventListener("focusout", O, !0), s.current && m(!0), delete window.__lysChoisir;
857
+ };
858
+ }, [e]), R(() => {
859
+ s.current || A.current?.();
860
+ }, [o]), a ? /* @__PURE__ */ v(
861
+ "div",
862
+ {
863
+ className: "choix",
864
+ style: {
865
+ top: Math.min(a.y + 10, window.innerHeight - 200),
866
+ left: Math.min(a.x, window.innerWidth - 280)
867
+ },
868
+ children: [
869
+ /* @__PURE__ */ n("p", { className: "choix__titre", children: "Ce texte apparaît à plusieurs endroits." }),
870
+ /* @__PURE__ */ n("p", { className: "choix__aide", children: "Lequel corrigez-vous ?" }),
871
+ a.candidats.map((k) => /* @__PURE__ */ v(
872
+ "button",
873
+ {
874
+ type: "button",
875
+ className: "choix__option",
876
+ onClick: () => window.__lysChoisir?.(k, a.el),
877
+ children: [
878
+ /* @__PURE__ */ n("span", { className: "choix__chemin", children: k.chemin }),
879
+ /* @__PURE__ */ n("span", { className: "choix__ns", children: k.ns })
880
+ ]
881
+ },
882
+ k.ns + ":" + k.chemin
883
+ )),
884
+ /* @__PURE__ */ n(
885
+ "button",
886
+ {
887
+ type: "button",
888
+ className: "bouton bouton--discret",
889
+ onClick: () => f(null),
890
+ children: "Annuler"
891
+ }
892
+ )
893
+ ]
894
+ }
895
+ ) : null;
896
+ }
897
+ const xe = {
898
+ everyone: "Tout le monde",
899
+ loggedIn: "Clients connectés",
900
+ nonMembers: "Non-membres (visiteurs compris)",
901
+ members: "Tous les membres",
902
+ plans: "Membres de certains plans"
903
+ }, ve = {
904
+ everyone: "Tous les visiteurs voient cette section.",
905
+ loggedIn: "Seuls les clients connectés à leur compte la voient.",
906
+ nonMembers: "Les visiteurs et les clients sans adhésion active la voient ; les membres non.",
907
+ members: "Seuls les clients dont l'adhésion est active la voient.",
908
+ plans: "Seuls les membres actifs des plans cochés la voient."
909
+ };
910
+ function ut({
911
+ api: r,
912
+ section: e,
913
+ apresChangement: o
914
+ }) {
915
+ const i = e?.audience ?? { mode: "everyone" }, [t, s] = I(i.mode), [a, f] = I(i.mode === "plans" ? i.plans : []), [u, c] = I(null), [h, A] = I(!1), [k, T] = I(null), S = e ? e.UID + JSON.stringify(e.audience ?? null) : "";
916
+ if (R(() => {
917
+ const p = e?.audience ?? { mode: "everyone" };
918
+ s(p.mode), f(p.mode === "plans" ? p.plans : []), T(null);
919
+ }, [S]), R(() => {
920
+ let p = !0;
921
+ return r.optionsAudience().then((m) => p && c(m.plans ?? [])).catch(() => p && c([])), () => {
922
+ p = !1;
923
+ };
924
+ }, [r]), !e?.UID)
925
+ return /* @__PURE__ */ v("div", { className: "champ", children: [
926
+ /* @__PURE__ */ n("span", { className: "champ__etiquette", children: "Visible pour" }),
927
+ /* @__PURE__ */ n("p", { className: "champ__aide", children: "Enregistrez d'abord ce contenu : vous pourrez ensuite choisir qui le voit (membres, clients connectés…)." })
928
+ ] });
929
+ const y = t !== i.mode || t === "plans" && JSON.stringify([...a].sort()) !== JSON.stringify(i.mode === "plans" ? [...i.plans].sort() : []), D = async () => {
930
+ if (t === "plans" && a.length === 0) {
931
+ T({ ton: "erreur", texte: "Cochez au moins un plan." });
932
+ return;
933
+ }
934
+ A(!0), T(null);
935
+ try {
936
+ await r.audience(e.UID, t === "plans" ? { mode: t, plans: a } : { mode: t }), await o(), T({ ton: "ok", texte: "Appliqué. " + ve[t] });
937
+ } catch {
938
+ T({ ton: "erreur", texte: "Le changement n'a pas pu être appliqué." });
939
+ } finally {
940
+ A(!1);
941
+ }
942
+ }, C = u !== null && u.length === 0;
943
+ return /* @__PURE__ */ v("div", { className: "champ", "data-audience": !0, children: [
944
+ /* @__PURE__ */ n("label", { className: "champ__etiquette", htmlFor: "lystech-audience", children: "Visible pour" }),
945
+ /* @__PURE__ */ n(
946
+ "select",
947
+ {
948
+ id: "lystech-audience",
949
+ value: t,
950
+ onChange: (p) => s(p.target.value),
951
+ disabled: h,
952
+ children: Object.keys(xe).map((p) => /* @__PURE__ */ n("option", { value: p, disabled: p === "plans" && C, children: xe[p] }, p))
953
+ }
954
+ ),
955
+ t === "plans" && /* @__PURE__ */ v("div", { style: { marginTop: 8 }, children: [
956
+ u === null && /* @__PURE__ */ n("p", { className: "champ__aide", children: "Chargement des plans…" }),
957
+ u?.map((p) => /* @__PURE__ */ v("label", { style: { display: "flex", gap: 8, alignItems: "center", margin: "4px 0", fontSize: 13 }, children: [
958
+ /* @__PURE__ */ n(
959
+ "input",
960
+ {
961
+ type: "checkbox",
962
+ style: { width: "auto" },
963
+ checked: a.includes(p.UID),
964
+ onChange: (m) => f((w) => m.target.checked ? [...w, p.UID] : w.filter((E) => E !== p.UID))
965
+ }
966
+ ),
967
+ p.name ?? "Plan sans nom"
968
+ ] }, p.UID))
969
+ ] }),
970
+ /* @__PURE__ */ v("p", { className: "champ__aide", children: [
971
+ ve[t],
972
+ " Le contenu réservé n'est jamais envoyé aux autres visiteurs.",
973
+ C ? " (Aucun plan d'abonnement dans cette boutique.)" : ""
974
+ ] }),
975
+ k && /* @__PURE__ */ n("p", { className: "message message--" + k.ton, children: k.texte }),
976
+ y && /* @__PURE__ */ n("button", { type: "button", className: "bouton bouton--principal", onClick: D, disabled: h, style: { marginTop: 8 }, children: "Appliquer" })
977
+ ] });
978
+ }
979
+ const dt = Ce(() => import("./ModuleBoutique-BYBYDBN0.js")), pt = Ce(() => import("./ApercuMobile-RzxSOXyF.js")), K = /^i18n:([^:]+):(.*)$/, le = "commun", ce = "lystech-edit-mode";
980
+ function ye(r, e) {
981
+ return JSON.stringify(r ?? {}) === JSON.stringify(e ?? {});
982
+ }
983
+ function ft({ api: r, pont: e }) {
984
+ const [o, i] = I([]), [t, s] = I([]), [a, f] = I(e.page), [u, c] = I(null), [h, A] = I({}), [k, T] = I(!1), [S, y] = I(() => {
985
+ try {
986
+ return window.localStorage.getItem(ce) === "circuler" ? "circuler" : "modifier";
987
+ } catch {
988
+ return "modifier";
989
+ }
990
+ }), D = () => y((l) => {
991
+ const d = l === "modifier" ? "circuler" : "modifier";
992
+ try {
993
+ window.localStorage.setItem(ce, d);
994
+ } catch {
995
+ }
996
+ return d;
997
+ }), [C, p] = I(!1), [m, w] = I(
998
+ null
999
+ ), E = re(() => tt(r.brut), [r]), [O, Y] = I(!1), [x, b] = I(null), [B, Q] = I(!1);
1000
+ R(() => {
1001
+ let l = !0;
1002
+ return E.droits().then((d) => l && Y(d)), () => {
1003
+ l = !1;
1004
+ };
1005
+ }, [E]);
1006
+ const j = W((l) => {
1007
+ b((d) => ({ cible: l, n: (d?.n ?? 0) + 1 })), Q(!1), c(null), T(!1);
1008
+ }, []);
1009
+ R(() => (e.ouvrirBoutique = O ? (l) => (j(l), !0) : void 0, () => {
1010
+ e.ouvrirBoutique = void 0;
1011
+ }), [e, O, j]);
1012
+ const $ = W((l) => {
1013
+ window.dispatchEvent(new CustomEvent(Be, { detail: l }));
1014
+ }, []);
1015
+ R(() => (e.surChangementDePage = (l) => {
1016
+ f(l), c(null), T(!1);
1017
+ }, () => {
1018
+ e.surChangementDePage = void 0;
1019
+ }), [e]);
1020
+ const X = W(async () => {
1021
+ try {
1022
+ const [l, d] = await Promise.all([
1023
+ r.pourPage(a),
1024
+ a === le ? Promise.resolve([]) : r.pourPage(le)
1025
+ ]), g = [...l, ...d];
1026
+ return s(g), g;
1027
+ } catch {
1028
+ return w({
1029
+ ton: "erreur",
1030
+ texte: "Impossible de lire le contenu du site."
1031
+ }), [];
1032
+ }
1033
+ }, [r, a]);
1034
+ R(() => {
1035
+ r.schemas().then(i).catch(() => i([]));
1036
+ }, [r]), R(() => {
1037
+ X();
1038
+ }, [X]);
1039
+ const ne = W(
1040
+ (l, d) => {
1041
+ let g = null, N = -1;
1042
+ for (const M of o) {
1043
+ const L = K.exec(M.blockType);
1044
+ if (!L || L[1] !== l) continue;
1045
+ const _ = L[2];
1046
+ (_ === "" || d === _ || d.startsWith(_ + ".")) && _.length > N && (g = M, N = _.length);
1047
+ }
1048
+ if (!g) return null;
1049
+ const z = K.exec(g.blockType)?.[2] ?? "", P = z ? d.slice(z.length + 1) : d;
1050
+ return { bloc: g, champ: P };
1051
+ },
1052
+ [o]
1053
+ ), Le = W(
1054
+ (l, d) => {
1055
+ const g = ne(l, d);
1056
+ return g ? (g.bloc.pages ?? []).includes(a) ? 2 : 1 : 0;
1057
+ },
1058
+ [ne, a]
1059
+ ), G = W(
1060
+ (l) => o.find((d) => d.blockType === l),
1061
+ [o]
1062
+ ), de = re(
1063
+ () => o.filter((l) => {
1064
+ const d = l.pages ?? [];
1065
+ return d.includes(a) || d.includes(le);
1066
+ }),
1067
+ [o, a]
1068
+ ), q = re(
1069
+ () => t.filter((l) => l.draft && !ye(l.draft, l.data)),
1070
+ [t]
1071
+ );
1072
+ R(() => {
1073
+ if (q.length === 0) return;
1074
+ for (const g of q)
1075
+ K.test(g.blockType) || e.poserApercu(g.blockType, g.draft);
1076
+ const l = q.filter((g) => K.test(g.blockType)), d = e.sourceTexte;
1077
+ l.length && d && import("./sourceTexte-BMPMpNg9.js").then(
1078
+ ({ appliquerAuxTextes: g }) => g(
1079
+ l.map((N) => ({ blockType: N.blockType, data: N.draft })),
1080
+ d
1081
+ )
1082
+ );
1083
+ }, [q, e]);
1084
+ const _e = W(
1085
+ async (l, d, g, N) => {
1086
+ const z = ne(l, d);
1087
+ if (!z) {
1088
+ w({
1089
+ ton: "erreur",
1090
+ texte: `Ce texte (${l}:${d}) n'appartient à aucun bloc déclaré.`
1091
+ });
1092
+ return;
1093
+ }
1094
+ const P = t.find((U) => U.blockType === z.bloc.blockType), M = P?.draft ?? P?.data ?? {}, L = M[z.champ], _ = z.bloc.fields.find((U) => U.key === z.champ), F = (
1095
+ /* `!declare.localized` et non `=== false` : un champ non traduit
1096
+ OMET la cle plutot que de la mettre a faux. Tester l'egalite
1097
+ stricte ne se declenchait donc jamais. */
1098
+ _ && !_.localized ? N : L && typeof L == "object" && !Array.isArray(L) ? { ...L, [g]: N } : { [g]: N }
1099
+ ), H = { ...M, [z.champ]: F };
1100
+ try {
1101
+ if (P?.UID)
1102
+ await r.enregistrerBrouillon(P.UID, H);
1103
+ else {
1104
+ const U = z.bloc.pages?.[0] ?? a;
1105
+ await r.creer(U, z.bloc.blockType, H);
1106
+ }
1107
+ await X(), w(null);
1108
+ } catch {
1109
+ w({
1110
+ ton: "erreur",
1111
+ texte: "Enregistrement impossible. Votre texte est toujours à l'écran."
1112
+ });
1113
+ }
1114
+ },
1115
+ [r, ne, a, X, t]
1116
+ ), De = W(
1117
+ (l, d) => {
1118
+ const g = G(l), N = g?.fields.find((_) => _.key === d);
1119
+ if (!g || !N) return null;
1120
+ const z = t.find((_) => _.blockType === l);
1121
+ let L = {
1122
+ ...e.replis?.[l] ?? {},
1123
+ ...z?.data ?? {},
1124
+ ...z?.draft ?? {}
1125
+ }[d];
1126
+ return N.localized && L && typeof L == "object" && !Array.isArray(L) && (L = L[e.langue]), { libelle: N.label, type: N.type, valeur: L };
1127
+ },
1128
+ [G, t, e]
1129
+ ), ze = W(
1130
+ async (l, d, g) => {
1131
+ const N = G(l), z = N?.fields.find((U) => U.key === d);
1132
+ if (!N || !z) return !1;
1133
+ const P = t.find((U) => U.blockType === l), L = {
1134
+ ...e.replis?.[l] ?? {},
1135
+ ...P?.data ?? {},
1136
+ ...P?.draft ?? {}
1137
+ }, _ = L[d], F = z.localized ? {
1138
+ ..._ && typeof _ == "object" && !Array.isArray(_) ? _ : {},
1139
+ [e.langue]: g
1140
+ } : g, H = { ...L, [d]: F };
1141
+ try {
1142
+ return P?.UID ? await r.enregistrerBrouillon(P.UID, H) : await r.creer(N.pages?.[0] ?? a, l, H), await X(), e.poserApercu(l, H), w(null), !0;
1143
+ } catch {
1144
+ return w({
1145
+ ton: "erreur",
1146
+ texte: "Enregistrement impossible. La valeur en ligne n'a pas changé."
1147
+ }), !1;
1148
+ }
1149
+ },
1150
+ [r, a, e, X, G, t]
1151
+ ), Ie = async () => {
1152
+ if (!q.length) return;
1153
+ p(!0), w(null);
1154
+ const l = q.length;
1155
+ try {
1156
+ for (const d of q) await r.publier(d.UID);
1157
+ await X();
1158
+ for (const d of q) e.poserApercu(d.blockType, null);
1159
+ e.recharger(), w({
1160
+ ton: "ok",
1161
+ texte: l === 1 ? "Publié. Vos visiteurs le voient maintenant." : `${l} modifications publiées.`
1162
+ });
1163
+ } catch {
1164
+ w({
1165
+ ton: "erreur",
1166
+ texte: "La publication a échoué. Rien n'a été mis en ligne."
1167
+ });
1168
+ } finally {
1169
+ p(!1);
1170
+ }
1171
+ }, Oe = async () => {
1172
+ p(!0);
1173
+ try {
1174
+ const l = q.map((g) => g.blockType);
1175
+ for (const g of q) await r.annuler(g.UID);
1176
+ const d = await X();
1177
+ for (const g of l) e.poserApercu(g, null);
1178
+ if (e.sourceTexte) {
1179
+ const { appliquerAuxTextes: g } = await import("./sourceTexte-BMPMpNg9.js");
1180
+ g(
1181
+ d.map((N) => ({ blockType: N.blockType, data: N.data })),
1182
+ e.sourceTexte
1183
+ );
1184
+ }
1185
+ w({
1186
+ ton: "info",
1187
+ texte: "Modifications abandonnées. On est revenu à ce qui est en ligne."
1188
+ });
1189
+ } finally {
1190
+ p(!1);
1191
+ }
1192
+ }, pe = (l) => {
1193
+ const d = t.find((M) => M.blockType === l), g = d?.draft ?? d?.data ?? {}, N = G(l), z = K.exec(l), P = {};
1194
+ if (!z) {
1195
+ const M = e.replis?.[l];
1196
+ M && typeof M == "object" && !Array.isArray(M) && Object.assign(P, M);
1197
+ }
1198
+ if (z && N && e.sourceTexte) {
1199
+ const M = z[1], L = z[2], _ = e.sourceTexte.langues(), F = {};
1200
+ for (const U of _)
1201
+ F[U] = e.sourceTexte.dictionnaire(U)[M] ?? {};
1202
+ const H = e.sourceTexte.langueCourante();
1203
+ for (const U of N.fields) {
1204
+ const oe = L ? L + "." + U.key : U.key;
1205
+ if (!U.localized) {
1206
+ const te = F[H]?.[oe] ?? _.map((J) => F[J]?.[oe]).find((J) => typeof J == "string");
1207
+ typeof te == "string" && (P[U.key] = te);
1208
+ continue;
1209
+ }
1210
+ const ie = {};
1211
+ for (const te of _) {
1212
+ const J = F[te]?.[oe];
1213
+ typeof J == "string" && (ie[te] = J);
1214
+ }
1215
+ Object.keys(ie).length && (P[U.key] = ie);
1216
+ }
1217
+ }
1218
+ for (const [M, L] of Object.entries(g)) {
1219
+ const _ = P[M], F = L && typeof L == "object" && !Array.isArray(L) && _ && typeof _ == "object" && !Array.isArray(_);
1220
+ P[M] = F ? { ..._, ...L } : L;
1221
+ }
1222
+ A(P), c(l), T(!1), w(null);
1223
+ }, Pe = (l, d) => A((g) => ({ ...g, [l]: d })), Me = async () => {
1224
+ if (u) {
1225
+ p(!0);
1226
+ try {
1227
+ const l = t.find((g) => g.blockType === u);
1228
+ if (l?.UID) await r.enregistrerBrouillon(l.UID, h);
1229
+ else {
1230
+ const g = G(u)?.pages?.[0] ?? a;
1231
+ await r.creer(g, u, h);
1232
+ }
1233
+ const d = await X();
1234
+ if (e.sourceTexte) {
1235
+ const { appliquerAuxTextes: g } = await import("./sourceTexte-BMPMpNg9.js");
1236
+ g(
1237
+ d.map((N) => ({ blockType: N.blockType, data: N.draft ?? N.data })),
1238
+ e.sourceTexte
1239
+ );
1240
+ }
1241
+ K.test(u) || e.poserApercu(u, h), w({
1242
+ ton: "ok",
1243
+ texte: "Enregistré. Rien n'a encore changé pour vos visiteurs."
1244
+ });
1245
+ } catch {
1246
+ w({ ton: "erreur", texte: "L'enregistrement a échoué." });
1247
+ } finally {
1248
+ p(!1);
1249
+ }
1250
+ }
1251
+ }, qe = () => {
1252
+ try {
1253
+ window.localStorage.removeItem(ce);
1254
+ } catch {
1255
+ }
1256
+ we();
1257
+ }, Z = u ? G(u) : void 0, ee = !u && !k && !x && !B, Ue = re(
1258
+ () => q.map((l) => ({ blockType: l.blockType, data: l.draft })),
1259
+ [q]
1260
+ );
1261
+ return /* @__PURE__ */ v("div", { className: "calque", children: [
1262
+ /* @__PURE__ */ n(
1263
+ "div",
1264
+ {
1265
+ className: "cadre-global" + (S === "circuler" ? " cadre-global--circuler" : ""),
1266
+ "aria-hidden": "true"
1267
+ }
1268
+ ),
1269
+ e.sourceTexte && /* @__PURE__ */ n(
1270
+ ct,
1271
+ {
1272
+ source: e.sourceTexte,
1273
+ actif: ee && !C && S === "modifier",
1274
+ pertinence: Le,
1275
+ surModification: _e
1276
+ }
1277
+ ),
1278
+ /* @__PURE__ */ n(
1279
+ $e,
1280
+ {
1281
+ actif: ee && !C && S === "modifier",
1282
+ lire: De,
1283
+ enregistrer: ze,
1284
+ ouvrirPanneau: pe
1285
+ }
1286
+ ),
1287
+ /* @__PURE__ */ n(
1288
+ it,
1289
+ {
1290
+ actif: O && ee && !C && S === "modifier",
1291
+ ouvrir: j
1292
+ }
1293
+ ),
1294
+ x && /* @__PURE__ */ n(me, { fallback: /* @__PURE__ */ n("div", { className: "panneau", children: /* @__PURE__ */ n("p", { className: "panneau__corps", children: "Chargement de la boutique…" }) }), children: /* @__PURE__ */ n(
1295
+ dt,
1296
+ {
1297
+ api: E,
1298
+ demande: x,
1299
+ signaler: $,
1300
+ surFermer: () => b(null)
1301
+ }
1302
+ ) }),
1303
+ B && /* @__PURE__ */ n(me, { fallback: /* @__PURE__ */ n("div", { className: "apercu", children: /* @__PURE__ */ n("p", { children: "Préparation de l'aperçu…" }) }), children: /* @__PURE__ */ n(pt, { brouillons: Ue, surFermer: () => Q(!1) }) }),
1304
+ ee && /* @__PURE__ */ v("div", { className: "barre", children: [
1305
+ /* @__PURE__ */ n("span", { className: "barre__point" }),
1306
+ /* @__PURE__ */ n("span", { className: "barre__texte", children: S === "modifier" ? "Cliquez un texte pour le corriger" : "Navigation libre — les clics ouvrent les liens" }),
1307
+ /* @__PURE__ */ n(
1308
+ "button",
1309
+ {
1310
+ type: "button",
1311
+ className: "bouton " + (S === "circuler" ? "bouton--principal" : ""),
1312
+ onClick: D,
1313
+ title: S === "modifier" ? "Passer en navigation pour changer de page" : "Revenir a la modification des textes",
1314
+ children: S === "modifier" ? "Circuler" : "Modifier"
1315
+ }
1316
+ ),
1317
+ O && /* @__PURE__ */ v(
1318
+ "button",
1319
+ {
1320
+ type: "button",
1321
+ className: "bouton",
1322
+ onClick: () => j(null),
1323
+ title: "Vos bijoux et vos collections",
1324
+ children: [
1325
+ /* @__PURE__ */ n("span", { "aria-hidden": "true", children: "◇" }),
1326
+ " Boutique"
1327
+ ]
1328
+ }
1329
+ ),
1330
+ /* @__PURE__ */ n(
1331
+ "button",
1332
+ {
1333
+ type: "button",
1334
+ className: "bouton bouton--bureau-seul",
1335
+ onClick: () => Q(!0),
1336
+ title: "Voir la page comme sur un téléphone",
1337
+ children: "Mobile"
1338
+ }
1339
+ ),
1340
+ q.length > 0 ? /* @__PURE__ */ v(ue, { children: [
1341
+ /* @__PURE__ */ n("span", { className: "barre__compte", children: q.length === 1 ? "1 texte non publié" : `${q.length} textes non publiés` }),
1342
+ /* @__PURE__ */ v(
1343
+ "button",
1344
+ {
1345
+ type: "button",
1346
+ className: "bouton bouton--principal",
1347
+ onClick: Ie,
1348
+ disabled: C,
1349
+ "aria-label": `Publier ${q.length} modification${q.length > 1 ? "s" : ""}`,
1350
+ children: [
1351
+ "Publier ",
1352
+ /* @__PURE__ */ n("span", { className: "barre__pastille", children: q.length })
1353
+ ]
1354
+ }
1355
+ ),
1356
+ /* @__PURE__ */ n(
1357
+ "button",
1358
+ {
1359
+ type: "button",
1360
+ className: "bouton bouton--discret",
1361
+ onClick: Oe,
1362
+ disabled: C,
1363
+ children: "Abandonner"
1364
+ }
1365
+ )
1366
+ ] }) : /* @__PURE__ */ n("span", { className: "barre__compte", children: "tout est publié" }),
1367
+ /* @__PURE__ */ n(
1368
+ "button",
1369
+ {
1370
+ type: "button",
1371
+ className: "bouton bouton--icone bouton--discret",
1372
+ onClick: () => T(!0),
1373
+ title: "Tous les contenus",
1374
+ "aria-label": "Tous les contenus",
1375
+ children: "⋮"
1376
+ }
1377
+ ),
1378
+ /* @__PURE__ */ n(
1379
+ "button",
1380
+ {
1381
+ type: "button",
1382
+ className: "bouton bouton--icone bouton--sortie",
1383
+ onClick: qe,
1384
+ title: "Quitter le mode édition",
1385
+ "aria-label": "Quitter le mode édition",
1386
+ children: "✕"
1387
+ }
1388
+ )
1389
+ ] }),
1390
+ m && ee && /* @__PURE__ */ n("div", { className: "flottant", children: /* @__PURE__ */ n("p", { className: "message message--" + m.ton, children: m.texte }) }),
1391
+ k && /* @__PURE__ */ v("div", { className: "panneau", role: "dialog", "aria-label": "Tous les contenus", children: [
1392
+ /* @__PURE__ */ v("div", { className: "panneau__tete", children: [
1393
+ /* @__PURE__ */ v("div", { style: { flex: 1 }, children: [
1394
+ /* @__PURE__ */ n("h2", { className: "panneau__titre", children: "Tous les contenus" }),
1395
+ /* @__PURE__ */ n("p", { className: "panneau__sous", children: "Y compris ce qui ne s'affiche pas dans la page : titre de l'onglet, description dans les moteurs de recherche, textes contenant une valeur calculée." })
1396
+ ] }),
1397
+ /* @__PURE__ */ n(
1398
+ "button",
1399
+ {
1400
+ type: "button",
1401
+ className: "bouton bouton--icone bouton--discret",
1402
+ onClick: () => T(!1),
1403
+ "aria-label": "Fermer",
1404
+ children: "✕"
1405
+ }
1406
+ )
1407
+ ] }),
1408
+ /* @__PURE__ */ v("div", { className: "panneau__corps", children: [
1409
+ de.length === 0 && /* @__PURE__ */ n("p", { className: "message message--info", children: "Aucun contenu déclaré pour cette page." }),
1410
+ de.map((l) => {
1411
+ const d = t.find((N) => N.blockType === l.blockType), g = d?.draft && !ye(d.draft, d.data);
1412
+ return /* @__PURE__ */ v(
1413
+ "button",
1414
+ {
1415
+ type: "button",
1416
+ className: "rangee",
1417
+ onClick: () => pe(l.blockType),
1418
+ children: [
1419
+ /* @__PURE__ */ n("span", { className: "rangee__nom", children: l.label }),
1420
+ /* @__PURE__ */ n("span", { className: "rangee__info", children: g ? "non publié" : `${l.fields.length} textes` })
1421
+ ]
1422
+ },
1423
+ l.blockType
1424
+ );
1425
+ })
1426
+ ] })
1427
+ ] }),
1428
+ u && Z && /* @__PURE__ */ v(
1429
+ "div",
1430
+ {
1431
+ className: "panneau",
1432
+ role: "dialog",
1433
+ "aria-label": "Modifier " + Z.label,
1434
+ children: [
1435
+ /* @__PURE__ */ v("div", { className: "panneau__tete", children: [
1436
+ /* @__PURE__ */ v("div", { style: { flex: 1 }, children: [
1437
+ /* @__PURE__ */ n("h2", { className: "panneau__titre", children: Z.label }),
1438
+ Z.description && /* @__PURE__ */ n("p", { className: "panneau__sous", children: Z.description })
1439
+ ] }),
1440
+ /* @__PURE__ */ n(
1441
+ "button",
1442
+ {
1443
+ type: "button",
1444
+ className: "bouton bouton--icone bouton--discret",
1445
+ onClick: () => c(null),
1446
+ "aria-label": "Fermer",
1447
+ children: "✕"
1448
+ }
1449
+ )
1450
+ ] }),
1451
+ /* @__PURE__ */ v("div", { className: "panneau__corps", children: [
1452
+ m && /* @__PURE__ */ n("p", { className: "message message--" + m.ton, children: m.texte }),
1453
+ /* @__PURE__ */ n(
1454
+ ut,
1455
+ {
1456
+ api: r,
1457
+ section: t.find((l) => l.blockType === u) ?? null,
1458
+ apresChangement: async () => {
1459
+ await X(), e.recharger();
1460
+ }
1461
+ }
1462
+ ),
1463
+ Z.fields.map((l) => /* @__PURE__ */ n(
1464
+ Ee,
1465
+ {
1466
+ champ: l,
1467
+ langue: e.langue,
1468
+ valeur: h[l.key],
1469
+ changer: (d) => Pe(l.key, d)
1470
+ },
1471
+ l.key
1472
+ ))
1473
+ ] }),
1474
+ /* @__PURE__ */ v("div", { className: "panneau__pied", children: [
1475
+ /* @__PURE__ */ n(
1476
+ "button",
1477
+ {
1478
+ type: "button",
1479
+ className: "bouton bouton--discret",
1480
+ onClick: () => c(null),
1481
+ disabled: C,
1482
+ children: "Fermer"
1483
+ }
1484
+ ),
1485
+ /* @__PURE__ */ n("span", { className: "espace" }),
1486
+ /* @__PURE__ */ n(
1487
+ "button",
1488
+ {
1489
+ type: "button",
1490
+ className: "bouton bouton--principal",
1491
+ onClick: Me,
1492
+ disabled: C,
1493
+ children: "Enregistrer"
1494
+ }
1495
+ )
1496
+ ] })
1497
+ ]
1498
+ }
1499
+ )
1500
+ ] });
1501
+ }
1502
+ const mt = `
1503
+ :host {
1504
+ all: initial;
1505
+ --fond: #16181d;
1506
+ --fond-clair: #21242b;
1507
+ --bord: #333844;
1508
+ --texte: #f2f3f5;
1509
+ --texte-doux: #a3a9b6;
1510
+ --accent: #3ba58d;
1511
+ --accent-sombre: #2d8570;
1512
+ --danger: #d9776a;
1513
+ font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
1514
+ "Helvetica Neue", Arial, sans-serif;
1515
+ font-size: 14px;
1516
+ line-height: 1.45;
1517
+ color: var(--texte);
1518
+ }
1519
+
1520
+ * { box-sizing: border-box; }
1521
+
1522
+ /* LE CALQUE LAISSE PASSER LES CLICS. Un conteneur fixe en plein écran qui
1523
+ intercepte tout rendrait le site inutilisable derrière lui : on ne pourrait
1524
+ plus naviguer, ni même faire défiler correctement. Seuls ses ENFANTS
1525
+ reprennent les clics. */
1526
+ .calque {
1527
+ position: fixed;
1528
+ inset: 0;
1529
+ pointer-events: none;
1530
+ z-index: 2147483000;
1531
+ }
1532
+ .calque > * { pointer-events: auto; }
1533
+
1534
+ /* ---------------------------------------------------------- CADRES ------ */
1535
+
1536
+ .cadre {
1537
+ position: fixed;
1538
+ border: 2px dashed rgba(59, 165, 141, 0.55);
1539
+ border-radius: 6px;
1540
+ pointer-events: none;
1541
+ transition: border-color 120ms ease;
1542
+ }
1543
+ .cadre--actif { border-color: var(--accent); border-style: solid; }
1544
+
1545
+ .pastille {
1546
+ position: fixed;
1547
+ display: inline-flex;
1548
+ align-items: center;
1549
+ gap: 6px;
1550
+ padding: 5px 10px;
1551
+ border: 0;
1552
+ border-radius: 999px;
1553
+ background: var(--accent);
1554
+ color: #06120e;
1555
+ font-size: 12px;
1556
+ font-weight: 650;
1557
+ letter-spacing: 0.01em;
1558
+ cursor: pointer;
1559
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
1560
+ }
1561
+ .pastille:hover { background: #45bda2; }
1562
+ .pastille:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
1563
+
1564
+ /* ------------------------------------------------------------ BARRE ----- */
1565
+
1566
+ .barre {
1567
+ position: fixed;
1568
+ left: 50%;
1569
+ bottom: 18px;
1570
+ transform: translateX(-50%);
1571
+ display: flex;
1572
+ align-items: center;
1573
+ gap: 14px;
1574
+ padding: 9px 14px;
1575
+ border: 1px solid var(--bord);
1576
+ border-radius: 999px;
1577
+ background: var(--fond);
1578
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45);
1579
+ max-width: calc(100vw - 24px);
1580
+ }
1581
+ .barre__point {
1582
+ width: 8px; height: 8px; border-radius: 50%;
1583
+ background: var(--accent);
1584
+ flex: none;
1585
+ }
1586
+ .barre__texte { font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
1587
+ .barre__texte b { font-weight: 650; }
1588
+ .barre__compte { color: var(--texte-doux); font-size: 12px; white-space: nowrap; }
1589
+
1590
+ /* ----------------------------------------------------------- PANNEAU ---- */
1591
+
1592
+ .panneau {
1593
+ position: fixed;
1594
+ top: 0; right: 0; bottom: 0;
1595
+ width: min(420px, 100vw);
1596
+ display: flex;
1597
+ flex-direction: column;
1598
+ background: var(--fond);
1599
+ border-left: 1px solid var(--bord);
1600
+ box-shadow: -12px 0 40px rgba(0, 0, 0, 0.4);
1601
+ }
1602
+ @media (max-width: 520px) {
1603
+ .panneau { top: auto; height: 78vh; border-left: 0; border-top: 1px solid var(--bord); }
1604
+ }
1605
+
1606
+ .panneau__tete {
1607
+ display: flex; align-items: flex-start; gap: 10px;
1608
+ padding: 16px 16px 12px;
1609
+ border-bottom: 1px solid var(--bord);
1610
+ }
1611
+ .panneau__titre { font-size: 15px; font-weight: 650; margin: 0; }
1612
+ .panneau__sous { margin: 3px 0 0; font-size: 12px; color: var(--texte-doux); }
1613
+ .panneau__corps { flex: 1; overflow-y: auto; padding: 14px 16px 18px; }
1614
+ .panneau__pied {
1615
+ display: flex; gap: 8px; align-items: center;
1616
+ padding: 12px 16px;
1617
+ border-top: 1px solid var(--bord);
1618
+ background: var(--fond-clair);
1619
+ }
1620
+ .panneau__pied .espace { flex: 1; }
1621
+
1622
+ /* --------------------------------------------------- CONNEXION ---------- */
1623
+
1624
+ /* LA CONNEXION EST CLAIRE, AUX COULEURS DE LYSTECH. L'éditeur reste un outil
1625
+ sombre qui s'efface derrière le travail ; la connexion, elle, est l'instant
1626
+ où quelqu'un décide de faire confiance. Il doit y reconnaître Lystech — la
1627
+ fleur, son pétrole et son turquoise, sur du blanc — et non une boîte noire
1628
+ posée sur son site.
1629
+
1630
+ Le thème se redéfinit ICI, sur le voile : les boutons, messages et champs
1631
+ partagés avec l'éditeur suivent ces variables sans une règle de plus, et
1632
+ l'éditeur garde les siennes. Clair quel que soit le thème du système :
1633
+ c'est un choix de marque. */
1634
+ .voile {
1635
+ --fond: #ffffff;
1636
+ --fond-clair: #f4f7f8;
1637
+ --bord: #dfe6e9;
1638
+ --texte: #0b1f26;
1639
+ --texte-doux: #52666f;
1640
+ --petrole: #084050;
1641
+ --petrole-survol: #0b5468;
1642
+ --turquoise: #10b8b0;
1643
+ --focus: #0c8f89;
1644
+
1645
+ position: fixed;
1646
+ inset: 0;
1647
+ display: flex;
1648
+ align-items: center;
1649
+ justify-content: center;
1650
+ padding: 16px;
1651
+ /* Le voile PREND les clics, lui : une boîte de dialogue qui demande une
1652
+ identité ne doit pas laisser cliquer la page derrière elle. C'est
1653
+ l'exception à la règle du calque, et elle est volontaire. Teinté pétrole
1654
+ plutôt que noir : on assombrit le site sans l'éteindre. */
1655
+ background: rgba(8, 44, 56, 0.34);
1656
+ backdrop-filter: blur(4px) saturate(115%);
1657
+ color: var(--texte);
1658
+ }
1659
+
1660
+ .fenetre {
1661
+ position: relative;
1662
+ width: min(400px, 100%);
1663
+ max-height: 92vh;
1664
+ overflow-y: auto;
1665
+ padding: 34px 30px 26px;
1666
+ border: 1px solid rgba(8, 64, 80, 0.10);
1667
+ border-radius: 20px;
1668
+ /* La lueur turquoise de la fleur, à peine, en haut de la carte. */
1669
+ background:
1670
+ radial-gradient(90% 60% at 50% -12%, rgba(16, 184, 176, 0.13), transparent 70%),
1671
+ var(--fond);
1672
+ box-shadow:
1673
+ 0 1px 2px rgba(8, 64, 80, 0.06),
1674
+ 0 28px 64px -18px rgba(8, 44, 56, 0.45);
1675
+ text-align: center;
1676
+ }
1677
+
1678
+ .fenetre__fermer {
1679
+ position: absolute; top: 14px; right: 14px;
1680
+ width: 32px; height: 32px;
1681
+ display: inline-flex; align-items: center; justify-content: center;
1682
+ border: 0; border-radius: 9px;
1683
+ background: transparent; color: var(--texte-doux);
1684
+ font: inherit; font-size: 14px; cursor: pointer;
1685
+ }
1686
+ .fenetre__fermer:hover { background: var(--fond-clair); color: var(--texte); }
1687
+ .fenetre__fermer:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
1688
+
1689
+ /* ------------------------------------------------------------ MARQUE ---- */
1690
+
1691
+ .marque {
1692
+ display: inline-flex; flex-direction: column; align-items: center; gap: 8px;
1693
+ margin-bottom: 18px;
1694
+ }
1695
+ .marque img {
1696
+ width: 44px; height: 44px; display: block;
1697
+ filter: drop-shadow(0 6px 14px rgba(16, 184, 176, 0.28));
1698
+ }
1699
+ .marque__mot {
1700
+ font-size: 11.5px; font-weight: 700;
1701
+ letter-spacing: 0.24em; text-transform: uppercase;
1702
+ color: var(--petrole);
1703
+ }
1704
+
1705
+ .fenetre__titre {
1706
+ margin: 0 0 8px;
1707
+ font-size: 21px; font-weight: 700; letter-spacing: -0.015em;
1708
+ color: var(--texte);
1709
+ text-wrap: balance;
1710
+ }
1711
+ .fenetre__sous {
1712
+ margin: 0 auto 24px;
1713
+ max-width: 36ch;
1714
+ font-size: 13.5px; line-height: 1.55; color: var(--texte-doux);
1715
+ text-wrap: balance;
1716
+ }
1717
+ .fenetre__corps { text-align: left; }
1718
+
1719
+ /* ------------------------------------------------------ FOURNISSEURS ---- */
1720
+
1721
+ .fournisseurs { display: flex; flex-direction: column; gap: 10px; }
1722
+
1723
+ .fournisseur {
1724
+ display: flex; align-items: center; justify-content: center; gap: 10px;
1725
+ width: 100%; min-height: 46px; padding: 12px 16px;
1726
+ border: 1px solid transparent; border-radius: 12px;
1727
+ font: inherit; font-size: 14px; font-weight: 600;
1728
+ cursor: pointer;
1729
+ transition: transform 90ms ease, background-color 120ms ease, box-shadow 120ms ease;
1730
+ }
1731
+ .fournisseur:active { transform: translateY(1px); }
1732
+ .fournisseur:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
1733
+ .fournisseur[disabled] { opacity: 0.55; cursor: default; transform: none; }
1734
+ .fournisseur .logo { width: 18px; height: 18px; flex: none; display: block; }
1735
+
1736
+ /* LES COULEURS DE CHAQUE MARQUE, telles qu'elles les publient. Un bouton
1737
+ Google repeint aux couleurs du site devient moins reconnaissable — et un
1738
+ bouton de connexion qu'on ne reconnaît pas est un bouton sur lequel on
1739
+ hésite à cliquer. */
1740
+ .fournisseur--google {
1741
+ background: #fff; color: #1f1f1f; border-color: #dadce0;
1742
+ box-shadow: 0 1px 2px rgba(8, 64, 80, 0.06);
1743
+ }
1744
+ .fournisseur--google:hover:not([disabled]) { background: #f6f9fa; border-color: #c9d3d8; }
1745
+ .fournisseur--facebook { background: #1877f2; color: #fff; }
1746
+ .fournisseur--facebook:hover:not([disabled]) { background: #166fe5; }
1747
+
1748
+ .bouton--large { width: 100%; padding: 12px 16px; font-size: 14px; }
1749
+
1750
+ /* Les boutons et messages PARTAGÉS avec l'éditeur, en version claire. */
1751
+ .voile .bouton {
1752
+ min-height: 44px; border-radius: 12px;
1753
+ background: #fff; color: var(--texte); border-color: #cfd9dd;
1754
+ }
1755
+ .voile .bouton:hover { background: var(--fond-clair); }
1756
+ .voile .bouton:focus-visible { outline-color: var(--focus); }
1757
+ .voile .bouton--principal { background: var(--petrole); border-color: var(--petrole); color: #fff; }
1758
+ .voile .bouton--principal:hover { background: var(--petrole-survol); }
1759
+
1760
+ .voile .message { font-size: 13px; line-height: 1.5; border-radius: 10px; }
1761
+ .voile .message--erreur { background: #fdf0ee; border-color: #f4c7bf; color: #a3321f; }
1762
+ .voile .message--ok { background: #e8f7f5; border-color: #a9e2dc; color: #0a5c57; }
1763
+ .voile .message--info { background: var(--fond-clair); border-color: var(--bord); color: #3a5159; }
1764
+
1765
+ @media (prefers-reduced-motion: reduce) {
1766
+ .fournisseur { transition: none; }
1767
+ }
1768
+
1769
+ /* ------------------------------------------------------------ CHAMPS ---- */
1770
+
1771
+ .champ { margin-bottom: 16px; }
1772
+ .champ__etiquette {
1773
+ display: block; margin-bottom: 5px;
1774
+ font-size: 12px; font-weight: 600; color: var(--texte);
1775
+ }
1776
+ .champ__aide { margin: 4px 0 0; font-size: 11.5px; color: var(--texte-doux); }
1777
+ .champ__langue {
1778
+ display: inline-block; margin: 0 0 4px;
1779
+ font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em;
1780
+ text-transform: uppercase; color: var(--texte-doux);
1781
+ }
1782
+
1783
+ /* TOUS les types de champs, pas seulement ceux auxquels on pensait. Un
1784
+ type oublie — « password », « email » — retombe sur le style brut du
1785
+ navigateur : une ligne blanche au milieu d'un panneau sombre. */
1786
+ input[type="text"], input[type="url"], input[type="number"], input[type="date"],
1787
+ input[type="password"], input[type="email"], input[type="tel"], input[type="search"],
1788
+ select, textarea {
1789
+ width: 100%;
1790
+ padding: 8px 10px;
1791
+ border: 1px solid var(--bord);
1792
+ border-radius: 6px;
1793
+ background: var(--fond-clair);
1794
+ color: var(--texte);
1795
+ font: inherit;
1796
+ font-size: 13px;
1797
+ }
1798
+ textarea { min-height: 92px; resize: vertical; line-height: 1.5; }
1799
+ input:focus, select:focus, textarea:focus {
1800
+ outline: none; border-color: var(--accent);
1801
+ box-shadow: 0 0 0 3px rgba(59, 165, 141, 0.18);
1802
+ }
1803
+
1804
+ .bascule { display: flex; align-items: center; gap: 8px; }
1805
+ .bascule input { width: 16px; height: 16px; accent-color: var(--accent); }
1806
+
1807
+ .vignette {
1808
+ margin-top: 8px; max-height: 110px; border-radius: 6px;
1809
+ border: 1px solid var(--bord); display: block;
1810
+ }
1811
+
1812
+ /* --------------------------------------------------------- LISTES ------- */
1813
+
1814
+ .liste__item {
1815
+ border: 1px solid var(--bord); border-radius: 8px;
1816
+ padding: 12px; margin-bottom: 10px; background: var(--fond-clair);
1817
+ }
1818
+ .liste__tete {
1819
+ display: flex; align-items: center; justify-content: space-between;
1820
+ margin-bottom: 8px;
1821
+ }
1822
+ .liste__rang { font-size: 11px; font-weight: 700; color: var(--texte-doux); }
1823
+
1824
+ /* --------------------------------------------------------- BOUTONS ------ */
1825
+
1826
+ .bouton {
1827
+ display: inline-flex; align-items: center; justify-content: center; gap: 6px;
1828
+ padding: 8px 14px; border-radius: 7px; border: 1px solid transparent;
1829
+ font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
1830
+ background: var(--fond-clair); color: var(--texte); border-color: var(--bord);
1831
+ }
1832
+ .bouton:hover { background: #2a2e37; }
1833
+ .bouton:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
1834
+ .bouton--principal { background: var(--accent); border-color: var(--accent); color: #06120e; }
1835
+ .bouton--principal:hover { background: #45bda2; }
1836
+ .bouton--discret { background: transparent; border-color: transparent; color: var(--texte-doux); }
1837
+ .bouton--discret:hover { background: var(--fond-clair); color: var(--texte); }
1838
+ .bouton[disabled] { opacity: 0.5; cursor: default; }
1839
+ .bouton--icone { padding: 6px 9px; }
1840
+
1841
+ .message {
1842
+ margin: 0 0 12px; padding: 9px 11px; border-radius: 7px;
1843
+ font-size: 12.5px; border: 1px solid;
1844
+ }
1845
+ .message--erreur { background: rgba(217, 119, 106, 0.12); border-color: rgba(217, 119, 106, 0.4); color: #f0b3a9; }
1846
+ .message--ok { background: rgba(59, 165, 141, 0.12); border-color: rgba(59, 165, 141, 0.4); color: #8fd9c6; }
1847
+ .message--info { background: var(--fond-clair); border-color: var(--bord); color: var(--texte-doux); }
1848
+
1849
+ @media (prefers-reduced-motion: reduce) {
1850
+ * { transition: none !important; animation: none !important; }
1851
+ }
1852
+ `, bt = `
1853
+ /* --------------------------------------------------------- SAISIE ------- */
1854
+
1855
+ /* Une valeur marquée par le site (un prix, un numéro) se corrige dans une
1856
+ saisie posée EXACTEMENT dessus, dans la police de la page : on écrit là où
1857
+ on lisait. Le libellé au-dessus dit quel champ on touche — « Séance
1858
+ d'acupuncture », pas « seance ». */
1859
+ .saisie {
1860
+ position: fixed;
1861
+ display: flex;
1862
+ flex-direction: column;
1863
+ align-items: flex-start;
1864
+ gap: 4px;
1865
+ }
1866
+ .saisie__libelle,
1867
+ .saisie__aide,
1868
+ .saisie__erreur {
1869
+ padding: 3px 8px;
1870
+ border-radius: 6px;
1871
+ font: 600 11px/1.35 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
1872
+ white-space: nowrap;
1873
+ }
1874
+ .saisie__libelle { background: var(--fond); color: var(--texte); }
1875
+ .saisie__aide { background: rgba(22, 24, 29, 0.82); color: var(--texte-doux); font-weight: 500; }
1876
+ .saisie__erreur { background: #b3261e; color: #fff; }
1877
+ .saisie__champ {
1878
+ min-width: 0;
1879
+ padding: 2px 8px;
1880
+ border: 2px solid var(--accent);
1881
+ border-radius: 6px;
1882
+ background: #fff;
1883
+ color: #111;
1884
+ line-height: 1.2;
1885
+ box-shadow: 0 10px 28px rgba(0, 0, 0, 0.28);
1886
+ outline: none;
1887
+ }
1888
+ .saisie__champ:focus { box-shadow: 0 0 0 3px rgba(59, 165, 141, 0.35), 0 10px 28px rgba(0, 0, 0, 0.28); }
1889
+ .saisie__champ:disabled { opacity: 0.7; }
1890
+
1891
+ /* --------------------------------------------------------- CHOIX -------- */
1892
+
1893
+ /* Quand un meme texte vient de plusieurs cles, on demande laquelle plutot que
1894
+ de deviner — et de modifier la mauvaise sans que personne le voie. */
1895
+ .choix {
1896
+ position: fixed;
1897
+ width: 260px;
1898
+ padding: 12px;
1899
+ border: 1px solid var(--bord);
1900
+ border-radius: 10px;
1901
+ background: var(--fond);
1902
+ box-shadow: 0 14px 40px rgba(0, 0, 0, 0.45);
1903
+ }
1904
+ .choix__titre { margin: 0 0 2px; font-size: 12.5px; font-weight: 650; }
1905
+ .choix__aide { margin: 0 0 10px; font-size: 11.5px; color: var(--texte-doux); }
1906
+ .choix__option {
1907
+ display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
1908
+ width: 100%; margin-bottom: 6px; padding: 7px 9px;
1909
+ border: 1px solid var(--bord); border-radius: 7px;
1910
+ background: var(--fond-clair); color: var(--texte);
1911
+ font: inherit; text-align: left; cursor: pointer;
1912
+ }
1913
+ .choix__option:hover { background: #2a2e37; border-color: var(--accent); }
1914
+ .choix__chemin { font-size: 12px; font-weight: 600; }
1915
+ .choix__ns { font-size: 10.5px; color: var(--texte-doux); }
1916
+
1917
+ /* ------------------------------------------------------- RANGEES -------- */
1918
+
1919
+ .rangee {
1920
+ display: flex; align-items: center; justify-content: space-between; gap: 10px;
1921
+ width: 100%; margin-bottom: 6px; padding: 10px 12px;
1922
+ border: 1px solid var(--bord); border-radius: 8px;
1923
+ background: var(--fond-clair); color: var(--texte);
1924
+ font: inherit; text-align: left; cursor: pointer;
1925
+ }
1926
+ .rangee:hover { background: #2a2e37; border-color: var(--accent); }
1927
+ .rangee__nom { font-size: 13px; font-weight: 600; }
1928
+ .rangee__info { font-size: 11.5px; color: var(--texte-doux); white-space: nowrap; }
1929
+
1930
+ /* ------------------------------------------------------ FLOTTANT -------- */
1931
+
1932
+ /* Un message au-dessus de la barre, pour confirmer sans ouvrir de panneau. */
1933
+ .flottant {
1934
+ position: fixed;
1935
+ left: 50%; bottom: 76px;
1936
+ transform: translateX(-50%);
1937
+ max-width: min(460px, calc(100vw - 24px));
1938
+ }
1939
+ .flottant .message { margin: 0; box-shadow: 0 8px 26px rgba(0,0,0,.4); }
1940
+ `, ht = `
1941
+ /* ON NE DOIT JAMAIS SE DEMANDER SI ON EST EN MODE EDITION. Une barre en bas
1942
+ se confond avec un bandeau de temoins ; un lisere qui borde tout l'ecran,
1943
+ present sur chaque page, ne se confond avec rien. Il ne prend aucun clic. */
1944
+ .cadre-global {
1945
+ position: fixed;
1946
+ inset: 0;
1947
+ pointer-events: none;
1948
+ border: 2px solid var(--accent);
1949
+ border-radius: 4px;
1950
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25);
1951
+ opacity: 0.85;
1952
+ }
1953
+
1954
+ /* EN MODE CIRCULER, le cadre change d'allure. On est toujours connecte — le
1955
+ dire reste necessaire — mais les clics rendent la main aux liens, et rien
1956
+ ne serait plus desagreable que de croire qu'on edite alors qu'on navigue,
1957
+ ou l'inverse. Trait interrompu et plus efface : present, mais en retrait. */
1958
+ .cadre-global--circuler {
1959
+ border-style: dashed;
1960
+ border-color: var(--texte-doux);
1961
+ opacity: 0.5;
1962
+ }
1963
+
1964
+ /* La sortie est rouge au survol seulement : visible quand on la cherche,
1965
+ discrete le reste du temps — c'est le geste qu'on fait une fois. */
1966
+ .bouton--sortie { color: var(--texte-doux); background: transparent; border-color: transparent; }
1967
+ .bouton--sortie:hover { background: rgba(217, 119, 106, 0.16); color: var(--danger); }
1968
+
1969
+ .barre__pastille {
1970
+ display: inline-block; min-width: 18px; padding: 0 5px; border-radius: 999px;
1971
+ background: rgba(6, 18, 14, 0.25); font-size: 11px; line-height: 18px; text-align: center;
1972
+ }
1973
+
1974
+ /* LA BARRE AU TÉLÉPHONE. Une pilule de 600 px ne tient pas dans 390 : elle
1975
+ devient une bande pleine largeur, en bas, et chaque bouton fait au moins
1976
+ 44 px — la taille d'un doigt, pas d'un pointeur. On tait ce qui se lit
1977
+ ailleurs (la phrase d'aide, le compte, que la pastille du bouton Publier
1978
+ porte déjà). L'aperçu mobile n'a pas de sens sur un téléphone. */
1979
+ @media (max-width: 640px) {
1980
+ .barre {
1981
+ left: 8px; right: 8px; bottom: 8px; transform: none;
1982
+ max-width: none; gap: 6px; padding: 6px;
1983
+ border-radius: 18px; justify-content: space-between;
1984
+ padding-bottom: calc(6px + env(safe-area-inset-bottom, 0px));
1985
+ }
1986
+ .barre .bouton { min-height: 44px; padding: 8px 12px; }
1987
+ .barre .bouton--icone { min-width: 44px; }
1988
+ .barre__texte, .barre__compte, .barre__point, .bouton--bureau-seul { display: none; }
1989
+ .flottant { bottom: 84px; }
1990
+ }
1991
+
1992
+ /* ------------------------------------------------ BOUTIQUE SUR LA PAGE --- */
1993
+
1994
+ /* LE CRAYON d'une carte produit : rond, sombre, 44 px — visible sur toutes
1995
+ les photos, claires comme foncées. */
1996
+ .crayon {
1997
+ position: fixed; width: 44px; height: 44px; border-radius: 50%; border: 0;
1998
+ display: grid; place-items: center; cursor: pointer;
1999
+ background: var(--fond); color: #fff;
2000
+ box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
2001
+ }
2002
+ .crayon svg { width: 18px; height: 18px; }
2003
+ .crayon:hover, .crayon:focus-visible { background: var(--accent); color: #06120e; outline: 2px solid #fff; outline-offset: 2px; }
2004
+
2005
+ /* LA TUILE « + AJOUTER » : là où irait le prochain bijou. */
2006
+ .tuile-ajout {
2007
+ position: fixed; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
2008
+ border: 2px dashed var(--accent); border-radius: 14px; cursor: pointer;
2009
+ background: rgba(240, 250, 247, 0.92); color: #1f6f5d;
2010
+ font: 650 13px/1.3 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
2011
+ }
2012
+ .tuile-ajout b { font-size: 32px; font-weight: 400; line-height: 1; }
2013
+ .tuile-ajout:hover, .tuile-ajout:focus-visible { background: rgba(220, 244, 237, 0.97); outline: 2px solid var(--accent); outline-offset: 2px; }
2014
+
2015
+ /* --------------------------------------------------- APERÇU MOBILE ------ */
2016
+ .apercu {
2017
+ position: fixed; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
2018
+ background: rgba(16, 18, 22, 0.82); backdrop-filter: blur(3px);
2019
+ }
2020
+ .apercu__barre {
2021
+ display: flex; align-items: center; gap: 10px; padding: 6px 6px 6px 14px;
2022
+ background: var(--fond); border: 1px solid var(--bord); border-radius: 999px; font-size: 12.5px;
2023
+ }
2024
+ .apercu__tel { padding: 12px; border-radius: 44px; background: #0b0c0f; box-shadow: 0 30px 70px rgba(0, 0, 0, 0.55); }
2025
+ .apercu__tel iframe { display: block; border: 0; border-radius: 32px; background: #fff; }
2026
+ `, gt = "lystech-editeur-hote", xt = "lystech-connexion-hote";
2027
+ function Se(r) {
2028
+ document.getElementById(r)?.remove();
2029
+ const e = document.createElement("div");
2030
+ e.id = r, e.style.position = "relative", e.style.zIndex = "2147483000", document.body.appendChild(e);
2031
+ const o = e.attachShadow({ mode: "open" }), i = document.createElement("style");
2032
+ i.textContent = mt + bt + ht, o.appendChild(i);
2033
+ const t = document.createElement("div");
2034
+ return o.appendChild(t), { hote: e, point: t };
2035
+ }
2036
+ function Te(r, e) {
2037
+ let o = r;
2038
+ return () => {
2039
+ const i = o;
2040
+ o = null, setTimeout(() => {
2041
+ i?.unmount(), e.remove();
2042
+ }, 0);
2043
+ };
2044
+ }
2045
+ function Ct({
2046
+ site: r,
2047
+ apiBaseUrl: e,
2048
+ methodes: o,
2049
+ surJeton: i
2050
+ }) {
2051
+ const { hote: t, point: s } = Se(xt), a = Ae(s), f = () => u();
2052
+ a.render(
2053
+ /* @__PURE__ */ n(
2054
+ Xe,
2055
+ {
2056
+ site: r,
2057
+ apiBaseUrl: e,
2058
+ ...o ? { methodes: o } : {},
2059
+ surJeton: (c) => {
2060
+ u(), i(c);
2061
+ },
2062
+ surFermer: f
2063
+ }
2064
+ )
2065
+ );
2066
+ const u = Te(a, t);
2067
+ return u;
2068
+ }
2069
+ function Et({
2070
+ jeton: r,
2071
+ site: e,
2072
+ apiBaseUrl: o,
2073
+ pont: i
2074
+ }) {
2075
+ const { hote: t, point: s } = Se(gt), a = Ae(s);
2076
+ return a.render(
2077
+ /* @__PURE__ */ n(
2078
+ ft,
2079
+ {
2080
+ api: je({
2081
+ jeton: r,
2082
+ site: e,
2083
+ apiBaseUrl: o,
2084
+ surJetonRefuse: we
2085
+ }),
2086
+ pont: i
2087
+ }
2088
+ )
2089
+ ), Te(a, t);
2090
+ }
2091
+ export {
2092
+ ge as E,
2093
+ Ct as a,
2094
+ Et as b,
2095
+ wt as m
2096
+ };