@lystech/sections 0.1.0 → 0.2.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,719 @@
1
+ import { jsxs as p, jsx as o, Fragment as V } from "react/jsx-runtime";
2
+ import { createRoot as H } from "react-dom/client";
3
+ import { useState as g, useEffect as T, useCallback as S, useMemo as Q, useRef as W } from "react";
4
+ function X({
5
+ jeton: n,
6
+ site: t,
7
+ apiBaseUrl: s,
8
+ surJetonRefuse: r
9
+ }) {
10
+ const c = {
11
+ "Content-Type": "application/json",
12
+ Authorization: "Bearer " + n
13
+ };
14
+ function b(e, a) {
15
+ if (a && (e.status === 401 || e.status === 403) && r(), !e.ok) throw new Error(String(e.status));
16
+ }
17
+ async function d(e, a = !0) {
18
+ const u = await fetch(s + e, {
19
+ headers: a ? c : void 0
20
+ });
21
+ return b(u, a), await u.json();
22
+ }
23
+ async function l(e, a, u) {
24
+ const m = await fetch(s + e, {
25
+ method: a,
26
+ headers: c,
27
+ body: u === void 0 ? void 0 : JSON.stringify(u)
28
+ });
29
+ return b(m, !0), await m.json();
30
+ }
31
+ return {
32
+ /** Les blocs que le site a déclaré savoir afficher. Route publique. */
33
+ schemas: () => d("/site-sections/public/" + encodeURIComponent(t) + "/schemas", !1),
34
+ /** Ce qui existe sur une page, brouillons compris. */
35
+ pourPage: (e) => d("/site-sections?page=" + encodeURIComponent(e)),
36
+ creer: (e, a, u) => l("/site-sections", "POST", { page: e, blockType: a, draft: u }),
37
+ enregistrerBrouillon: (e, a) => l("/site-sections/" + e + "/draft", "PUT", { draft: a }),
38
+ publier: (e) => l("/site-sections/" + e + "/publish", "POST"),
39
+ /** Ramène le brouillon à ce qui est en ligne. */
40
+ annuler: (e) => l("/site-sections/" + e + "/revert", "POST")
41
+ };
42
+ }
43
+ function Z(n, t) {
44
+ const s = n && typeof n == "object" && !Array.isArray(n) ? Object.keys(n).filter((c) => /^[a-z]{2}(-[A-Za-z]{2})?$/.test(c)) : [], r = t.slice(0, 2);
45
+ return Array.from(/* @__PURE__ */ new Set([r, ...s]));
46
+ }
47
+ function $(n) {
48
+ switch (n.type) {
49
+ case "number":
50
+ return 0;
51
+ case "boolean":
52
+ return !1;
53
+ case "list":
54
+ return [];
55
+ default:
56
+ return "";
57
+ }
58
+ }
59
+ function j({ champ: n, valeur: t, changer: s }) {
60
+ switch (n.type) {
61
+ case "richText":
62
+ return /* @__PURE__ */ o(
63
+ "textarea",
64
+ {
65
+ value: String(t ?? ""),
66
+ onChange: (r) => s(r.target.value)
67
+ }
68
+ );
69
+ case "number":
70
+ return /* @__PURE__ */ o(
71
+ "input",
72
+ {
73
+ type: "number",
74
+ value: t === "" || t == null ? "" : String(t),
75
+ onChange: (r) => s(r.target.value === "" ? "" : Number(r.target.value))
76
+ }
77
+ );
78
+ case "boolean":
79
+ return /* @__PURE__ */ p("label", { className: "bascule", children: [
80
+ /* @__PURE__ */ o(
81
+ "input",
82
+ {
83
+ type: "checkbox",
84
+ checked: t === !0,
85
+ onChange: (r) => s(r.target.checked)
86
+ }
87
+ ),
88
+ /* @__PURE__ */ o("span", { children: t === !0 ? "Oui" : "Non" })
89
+ ] });
90
+ case "date":
91
+ return /* @__PURE__ */ o(
92
+ "input",
93
+ {
94
+ type: "date",
95
+ value: String(t ?? "").slice(0, 10),
96
+ onChange: (r) => s(r.target.value)
97
+ }
98
+ );
99
+ case "choice":
100
+ return /* @__PURE__ */ p(
101
+ "select",
102
+ {
103
+ value: String(t ?? ""),
104
+ onChange: (r) => s(r.target.value),
105
+ children: [
106
+ /* @__PURE__ */ o("option", { value: "", children: "—" }),
107
+ (n.options ?? []).map((r) => /* @__PURE__ */ o("option", { value: r, children: r }, r))
108
+ ]
109
+ }
110
+ );
111
+ case "url":
112
+ return /* @__PURE__ */ o(
113
+ "input",
114
+ {
115
+ type: "url",
116
+ value: String(t ?? ""),
117
+ onChange: (r) => s(r.target.value),
118
+ placeholder: "https://"
119
+ }
120
+ );
121
+ case "image":
122
+ return /* @__PURE__ */ p(V, { children: [
123
+ /* @__PURE__ */ o(
124
+ "input",
125
+ {
126
+ type: "url",
127
+ value: String(t ?? ""),
128
+ onChange: (r) => s(r.target.value),
129
+ placeholder: "https://…"
130
+ }
131
+ ),
132
+ String(t ?? "").startsWith("http") && /* @__PURE__ */ o("img", { className: "vignette", src: String(t), alt: "" })
133
+ ] });
134
+ default:
135
+ return /* @__PURE__ */ o(
136
+ "input",
137
+ {
138
+ type: "text",
139
+ value: String(t ?? ""),
140
+ onChange: (r) => s(r.target.value)
141
+ }
142
+ );
143
+ }
144
+ }
145
+ function P({ champ: n, valeur: t, changer: s, langue: r }) {
146
+ if (n.type === "list") {
147
+ const c = Array.isArray(t) ? t : [], b = n.of ?? [], d = (l, e, a) => {
148
+ const u = c.map((m, _) => _ === l ? { ...m, [e]: a } : m);
149
+ s(u);
150
+ };
151
+ return /* @__PURE__ */ p("div", { className: "champ", children: [
152
+ /* @__PURE__ */ o("span", { className: "champ__etiquette", children: n.label }),
153
+ n.help && /* @__PURE__ */ o("p", { className: "champ__aide", children: n.help }),
154
+ c.map((l, e) => /* @__PURE__ */ p("div", { className: "liste__item", children: [
155
+ /* @__PURE__ */ p("div", { className: "liste__tete", children: [
156
+ /* @__PURE__ */ o("span", { className: "liste__rang", children: e + 1 }),
157
+ /* @__PURE__ */ p("span", { style: { display: "flex", gap: 4 }, children: [
158
+ /* @__PURE__ */ o(
159
+ "button",
160
+ {
161
+ type: "button",
162
+ className: "bouton bouton--icone bouton--discret",
163
+ title: "Monter",
164
+ disabled: e === 0,
165
+ onClick: () => {
166
+ const a = [...c];
167
+ [a[e - 1], a[e]] = [a[e], a[e - 1]], s(a);
168
+ },
169
+ children: "↑"
170
+ }
171
+ ),
172
+ /* @__PURE__ */ o(
173
+ "button",
174
+ {
175
+ type: "button",
176
+ className: "bouton bouton--icone bouton--discret",
177
+ title: "Descendre",
178
+ disabled: e === c.length - 1,
179
+ onClick: () => {
180
+ const a = [...c];
181
+ [a[e], a[e + 1]] = [a[e + 1], a[e]], s(a);
182
+ },
183
+ children: "↓"
184
+ }
185
+ ),
186
+ /* @__PURE__ */ o(
187
+ "button",
188
+ {
189
+ type: "button",
190
+ className: "bouton bouton--icone bouton--discret",
191
+ title: "Retirer",
192
+ onClick: () => s(c.filter((a, u) => u !== e)),
193
+ children: "✕"
194
+ }
195
+ )
196
+ ] })
197
+ ] }),
198
+ b.map((a) => /* @__PURE__ */ o(
199
+ P,
200
+ {
201
+ champ: a,
202
+ langue: r,
203
+ valeur: l?.[a.key],
204
+ changer: (u) => d(e, a.key, u)
205
+ },
206
+ a.key
207
+ ))
208
+ ] }, e)),
209
+ /* @__PURE__ */ o(
210
+ "button",
211
+ {
212
+ type: "button",
213
+ className: "bouton",
214
+ onClick: () => s([
215
+ ...c,
216
+ Object.fromEntries(b.map((l) => [l.key, $(l)]))
217
+ ]),
218
+ children: "+ Ajouter"
219
+ }
220
+ )
221
+ ] });
222
+ }
223
+ if (n.localized) {
224
+ const c = Z(t, r), b = t && typeof t == "object" && !Array.isArray(t) ? t : {};
225
+ return /* @__PURE__ */ p("div", { className: "champ", children: [
226
+ /* @__PURE__ */ o("span", { className: "champ__etiquette", children: n.label }),
227
+ n.help && /* @__PURE__ */ o("p", { className: "champ__aide", children: n.help }),
228
+ c.map((d) => /* @__PURE__ */ p("div", { style: { marginBottom: 8 }, children: [
229
+ /* @__PURE__ */ o("span", { className: "champ__langue", children: d }),
230
+ /* @__PURE__ */ o(
231
+ j,
232
+ {
233
+ champ: n,
234
+ valeur: b[d],
235
+ changer: (l) => s({ ...b, [d]: l })
236
+ }
237
+ )
238
+ ] }, d))
239
+ ] });
240
+ }
241
+ return /* @__PURE__ */ p("div", { className: "champ", children: [
242
+ /* @__PURE__ */ o("label", { className: "champ__etiquette", children: n.label }),
243
+ /* @__PURE__ */ o(j, { champ: n, valeur: t, changer: s }),
244
+ n.help && /* @__PURE__ */ o("p", { className: "champ__aide", children: n.help })
245
+ ] });
246
+ }
247
+ function G(n, t) {
248
+ const s = n.haut - 12, r = t + 8, c = n.haut + n.hauteur - 34;
249
+ return Math.min(Math.max(s, r), Math.max(r, c));
250
+ }
251
+ function K() {
252
+ let n = 0;
253
+ return document.querySelectorAll("header, nav, [class*='header'], [class*='nav']").forEach((t) => {
254
+ const s = getComputedStyle(t);
255
+ if (s.position !== "fixed" && s.position !== "sticky") return;
256
+ const r = t.getBoundingClientRect();
257
+ r.top <= 4 && r.height > 0 && r.height < 200 && (n = Math.max(n, r.bottom));
258
+ }), n;
259
+ }
260
+ function Y() {
261
+ const [n, t] = g([]), [s, r] = g(0), c = W("");
262
+ return T(() => {
263
+ let b = 0;
264
+ const d = () => {
265
+ const a = [];
266
+ document.querySelectorAll("[data-lystech-section]").forEach((_) => {
267
+ const y = _.getAttribute("data-lystech-section");
268
+ if (!y) return;
269
+ const x = _.getBoundingClientRect();
270
+ x.width < 8 || x.height < 8 || a.push({
271
+ blockType: y,
272
+ haut: x.top,
273
+ gauche: x.left,
274
+ largeur: x.width,
275
+ hauteur: x.height
276
+ });
277
+ });
278
+ const u = K(), m = JSON.stringify(a) + "|" + u;
279
+ m !== c.current && (c.current = m, t(a), r(u));
280
+ }, l = () => {
281
+ cancelAnimationFrame(b), b = requestAnimationFrame(d);
282
+ };
283
+ d(), window.addEventListener("scroll", l, !0), window.addEventListener("resize", l);
284
+ const e = new MutationObserver(l);
285
+ return e.observe(document.body, { childList: !0, subtree: !0 }), () => {
286
+ cancelAnimationFrame(b), window.removeEventListener("scroll", l, !0), window.removeEventListener("resize", l), e.disconnect();
287
+ };
288
+ }, []), { ancres: n, enTete: s };
289
+ }
290
+ function ee({ api: n, pont: t }) {
291
+ const [s, r] = g([]), [c, b] = g([]), [d, l] = g(t.page), [e, a] = g(null), [u, m] = g({}), [_, y] = g(!1), [x, w] = g(!1), [z, f] = g(null), { ancres: I, enTete: R } = Y();
292
+ T(() => (t.surChangementDePage = (i) => {
293
+ l(i), a(null);
294
+ }, () => {
295
+ t.surChangementDePage = void 0;
296
+ }), [t]);
297
+ const C = S(async () => {
298
+ try {
299
+ const i = await n.pourPage(d);
300
+ return b(i), i;
301
+ } catch {
302
+ return f({ ton: "erreur", texte: "Impossible de lire le contenu du site." }), [];
303
+ }
304
+ }, [n, d]);
305
+ T(() => {
306
+ n.schemas().then(r).catch(() => r([]));
307
+ }, [n]), T(() => {
308
+ C();
309
+ }, [C]);
310
+ const A = S(
311
+ (i) => s.find((h) => h.blockType === i),
312
+ [s]
313
+ ), E = Q(
314
+ () => I.filter((i) => A(i.blockType)),
315
+ [I, A]
316
+ ), U = S(
317
+ (i) => {
318
+ const h = c.find((N) => N.blockType === i), v = h?.draft ?? h?.data ?? {};
319
+ m({ ...v }), a(i), y(!1), f(
320
+ h?.draft && JSON.stringify(h.draft) !== JSON.stringify(h.data ?? {}) ? { ton: "info", texte: "Un brouillon non publié est en cours." } : null
321
+ );
322
+ },
323
+ [c]
324
+ ), q = S(() => {
325
+ e && t.poserApercu(e, null), a(null), y(!1), f(null);
326
+ }, [e, t]), L = S(
327
+ (i, h) => {
328
+ m((v) => {
329
+ const N = { ...v, [i]: h };
330
+ return e && t.poserApercu(e, N), N;
331
+ }), y(!0);
332
+ },
333
+ [e, t]
334
+ ), O = S(async () => {
335
+ if (!e) return null;
336
+ const i = c.find((v) => v.blockType === e);
337
+ return i?.UID ? (await n.enregistrerBrouillon(i.UID, u), i.UID) : (await n.creer(d, e, u)).UID;
338
+ }, [n, e, d, c, u]), M = async () => {
339
+ w(!0), f(null);
340
+ try {
341
+ await O(), await C(), y(!1), f({ ton: "ok", texte: "Brouillon enregistré. Rien n'a encore changé pour vos visiteurs." });
342
+ } catch {
343
+ f({ ton: "erreur", texte: "L'enregistrement a échoué. Votre texte est toujours là — réessayez." });
344
+ } finally {
345
+ w(!1);
346
+ }
347
+ }, B = async () => {
348
+ w(!0), f(null);
349
+ try {
350
+ const i = await O();
351
+ if (!i) throw new Error("sans identifiant");
352
+ await n.publier(i), await C(), e && t.poserApercu(e, null), t.recharger(), y(!1), f({ ton: "ok", texte: "Publié. Vos visiteurs le voient maintenant." });
353
+ } catch {
354
+ f({ ton: "erreur", texte: "La publication a échoué. Rien n'a été mis en ligne." });
355
+ } finally {
356
+ w(!1);
357
+ }
358
+ }, F = async () => {
359
+ if (!e) return;
360
+ const i = c.find((h) => h.blockType === e);
361
+ w(!0);
362
+ try {
363
+ i?.UID && await n.annuler(i.UID);
364
+ const v = (await C()).find((N) => N.blockType === e);
365
+ m({ ...v?.data ?? {} }), t.poserApercu(e, null), y(!1), f({ ton: "info", texte: "Brouillon abandonné. On est revenu à ce qui est en ligne." });
366
+ } catch {
367
+ f({ ton: "erreur", texte: "Impossible d'abandonner le brouillon." });
368
+ } finally {
369
+ w(!1);
370
+ }
371
+ }, J = () => {
372
+ try {
373
+ window.sessionStorage.removeItem("lystech-edit");
374
+ } catch {
375
+ }
376
+ window.location.reload();
377
+ }, k = e ? A(e) : void 0;
378
+ return /* @__PURE__ */ p("div", { className: "calque", children: [
379
+ E.map((i) => /* @__PURE__ */ p("div", { children: [
380
+ /* @__PURE__ */ o(
381
+ "div",
382
+ {
383
+ className: "cadre" + (e === i.blockType ? " cadre--actif" : ""),
384
+ style: {
385
+ top: i.haut - 4,
386
+ left: i.gauche - 4,
387
+ width: i.largeur + 8,
388
+ height: i.hauteur + 8
389
+ }
390
+ }
391
+ ),
392
+ /* @__PURE__ */ p(
393
+ "button",
394
+ {
395
+ type: "button",
396
+ className: "pastille",
397
+ style: { top: G(i, R), left: i.gauche + 6 },
398
+ onClick: () => U(i.blockType),
399
+ children: [
400
+ "✎ ",
401
+ A(i.blockType)?.label ?? i.blockType
402
+ ]
403
+ }
404
+ )
405
+ ] }, i.blockType)),
406
+ !e && /* @__PURE__ */ p("div", { className: "barre", children: [
407
+ /* @__PURE__ */ o("span", { className: "barre__point" }),
408
+ /* @__PURE__ */ p("span", { className: "barre__texte", children: [
409
+ "Mode édition — ",
410
+ /* @__PURE__ */ o("b", { children: t.site })
411
+ ] }),
412
+ /* @__PURE__ */ o("span", { className: "barre__compte", children: E.length === 0 ? "aucune section sur cette page" : E.length === 1 ? "1 section modifiable" : E.length + " sections modifiables" }),
413
+ /* @__PURE__ */ o("button", { type: "button", className: "bouton bouton--discret", onClick: J, children: "Quitter" })
414
+ ] }),
415
+ e && k && /* @__PURE__ */ p("div", { className: "panneau", role: "dialog", "aria-label": "Modifier " + k.label, children: [
416
+ /* @__PURE__ */ p("div", { className: "panneau__tete", children: [
417
+ /* @__PURE__ */ p("div", { style: { flex: 1 }, children: [
418
+ /* @__PURE__ */ o("h2", { className: "panneau__titre", children: k.label }),
419
+ k.description && /* @__PURE__ */ o("p", { className: "panneau__sous", children: k.description })
420
+ ] }),
421
+ /* @__PURE__ */ o(
422
+ "button",
423
+ {
424
+ type: "button",
425
+ className: "bouton bouton--icone bouton--discret",
426
+ onClick: q,
427
+ "aria-label": "Fermer",
428
+ children: "✕"
429
+ }
430
+ )
431
+ ] }),
432
+ /* @__PURE__ */ p("div", { className: "panneau__corps", children: [
433
+ z && /* @__PURE__ */ o("p", { className: "message message--" + z.ton, children: z.texte }),
434
+ k.fields.map((i) => /* @__PURE__ */ o(
435
+ P,
436
+ {
437
+ champ: i,
438
+ langue: t.langue,
439
+ valeur: u[i.key],
440
+ changer: (h) => L(i.key, h)
441
+ },
442
+ i.key
443
+ ))
444
+ ] }),
445
+ /* @__PURE__ */ p("div", { className: "panneau__pied", children: [
446
+ /* @__PURE__ */ o(
447
+ "button",
448
+ {
449
+ type: "button",
450
+ className: "bouton bouton--discret",
451
+ onClick: F,
452
+ disabled: x,
453
+ children: "Abandonner"
454
+ }
455
+ ),
456
+ /* @__PURE__ */ o("span", { className: "espace" }),
457
+ /* @__PURE__ */ o(
458
+ "button",
459
+ {
460
+ type: "button",
461
+ className: "bouton",
462
+ onClick: M,
463
+ disabled: x || !_,
464
+ children: "Enregistrer"
465
+ }
466
+ ),
467
+ /* @__PURE__ */ o(
468
+ "button",
469
+ {
470
+ type: "button",
471
+ className: "bouton bouton--principal",
472
+ onClick: B,
473
+ disabled: x,
474
+ children: "Publier"
475
+ }
476
+ )
477
+ ] })
478
+ ] })
479
+ ] });
480
+ }
481
+ const te = `
482
+ :host {
483
+ all: initial;
484
+ --fond: #16181d;
485
+ --fond-clair: #21242b;
486
+ --bord: #333844;
487
+ --texte: #f2f3f5;
488
+ --texte-doux: #a3a9b6;
489
+ --accent: #3ba58d;
490
+ --accent-sombre: #2d8570;
491
+ --danger: #d9776a;
492
+ font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
493
+ "Helvetica Neue", Arial, sans-serif;
494
+ font-size: 14px;
495
+ line-height: 1.45;
496
+ color: var(--texte);
497
+ }
498
+
499
+ * { box-sizing: border-box; }
500
+
501
+ /* LE CALQUE LAISSE PASSER LES CLICS. Un conteneur fixe en plein écran qui
502
+ intercepte tout rendrait le site inutilisable derrière lui : on ne pourrait
503
+ plus naviguer, ni même faire défiler correctement. Seuls ses ENFANTS
504
+ reprennent les clics. */
505
+ .calque {
506
+ position: fixed;
507
+ inset: 0;
508
+ pointer-events: none;
509
+ z-index: 2147483000;
510
+ }
511
+ .calque > * { pointer-events: auto; }
512
+
513
+ /* ---------------------------------------------------------- CADRES ------ */
514
+
515
+ .cadre {
516
+ position: fixed;
517
+ border: 2px dashed rgba(59, 165, 141, 0.55);
518
+ border-radius: 6px;
519
+ pointer-events: none;
520
+ transition: border-color 120ms ease;
521
+ }
522
+ .cadre--actif { border-color: var(--accent); border-style: solid; }
523
+
524
+ .pastille {
525
+ position: fixed;
526
+ display: inline-flex;
527
+ align-items: center;
528
+ gap: 6px;
529
+ padding: 5px 10px;
530
+ border: 0;
531
+ border-radius: 999px;
532
+ background: var(--accent);
533
+ color: #06120e;
534
+ font-size: 12px;
535
+ font-weight: 650;
536
+ letter-spacing: 0.01em;
537
+ cursor: pointer;
538
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
539
+ }
540
+ .pastille:hover { background: #45bda2; }
541
+ .pastille:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
542
+
543
+ /* ------------------------------------------------------------ BARRE ----- */
544
+
545
+ .barre {
546
+ position: fixed;
547
+ left: 50%;
548
+ bottom: 18px;
549
+ transform: translateX(-50%);
550
+ display: flex;
551
+ align-items: center;
552
+ gap: 14px;
553
+ padding: 9px 14px;
554
+ border: 1px solid var(--bord);
555
+ border-radius: 999px;
556
+ background: var(--fond);
557
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45);
558
+ max-width: calc(100vw - 24px);
559
+ }
560
+ .barre__point {
561
+ width: 8px; height: 8px; border-radius: 50%;
562
+ background: var(--accent);
563
+ flex: none;
564
+ }
565
+ .barre__texte { font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
566
+ .barre__texte b { font-weight: 650; }
567
+ .barre__compte { color: var(--texte-doux); font-size: 12px; white-space: nowrap; }
568
+
569
+ /* ----------------------------------------------------------- PANNEAU ---- */
570
+
571
+ .panneau {
572
+ position: fixed;
573
+ top: 0; right: 0; bottom: 0;
574
+ width: min(420px, 100vw);
575
+ display: flex;
576
+ flex-direction: column;
577
+ background: var(--fond);
578
+ border-left: 1px solid var(--bord);
579
+ box-shadow: -12px 0 40px rgba(0, 0, 0, 0.4);
580
+ }
581
+ @media (max-width: 520px) {
582
+ .panneau { top: auto; height: 78vh; border-left: 0; border-top: 1px solid var(--bord); }
583
+ }
584
+
585
+ .panneau__tete {
586
+ display: flex; align-items: flex-start; gap: 10px;
587
+ padding: 16px 16px 12px;
588
+ border-bottom: 1px solid var(--bord);
589
+ }
590
+ .panneau__titre { font-size: 15px; font-weight: 650; margin: 0; }
591
+ .panneau__sous { margin: 3px 0 0; font-size: 12px; color: var(--texte-doux); }
592
+ .panneau__corps { flex: 1; overflow-y: auto; padding: 14px 16px 18px; }
593
+ .panneau__pied {
594
+ display: flex; gap: 8px; align-items: center;
595
+ padding: 12px 16px;
596
+ border-top: 1px solid var(--bord);
597
+ background: var(--fond-clair);
598
+ }
599
+ .panneau__pied .espace { flex: 1; }
600
+
601
+ /* ------------------------------------------------------------ CHAMPS ---- */
602
+
603
+ .champ { margin-bottom: 16px; }
604
+ .champ__etiquette {
605
+ display: block; margin-bottom: 5px;
606
+ font-size: 12px; font-weight: 600; color: var(--texte);
607
+ }
608
+ .champ__aide { margin: 4px 0 0; font-size: 11.5px; color: var(--texte-doux); }
609
+ .champ__langue {
610
+ display: inline-block; margin: 0 0 4px;
611
+ font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em;
612
+ text-transform: uppercase; color: var(--texte-doux);
613
+ }
614
+
615
+ input[type="text"], input[type="url"], input[type="number"], input[type="date"],
616
+ select, textarea {
617
+ width: 100%;
618
+ padding: 8px 10px;
619
+ border: 1px solid var(--bord);
620
+ border-radius: 6px;
621
+ background: var(--fond-clair);
622
+ color: var(--texte);
623
+ font: inherit;
624
+ font-size: 13px;
625
+ }
626
+ textarea { min-height: 92px; resize: vertical; line-height: 1.5; }
627
+ input:focus, select:focus, textarea:focus {
628
+ outline: none; border-color: var(--accent);
629
+ box-shadow: 0 0 0 3px rgba(59, 165, 141, 0.18);
630
+ }
631
+
632
+ .bascule { display: flex; align-items: center; gap: 8px; }
633
+ .bascule input { width: 16px; height: 16px; accent-color: var(--accent); }
634
+
635
+ .vignette {
636
+ margin-top: 8px; max-height: 110px; border-radius: 6px;
637
+ border: 1px solid var(--bord); display: block;
638
+ }
639
+
640
+ /* --------------------------------------------------------- LISTES ------- */
641
+
642
+ .liste__item {
643
+ border: 1px solid var(--bord); border-radius: 8px;
644
+ padding: 12px; margin-bottom: 10px; background: var(--fond-clair);
645
+ }
646
+ .liste__tete {
647
+ display: flex; align-items: center; justify-content: space-between;
648
+ margin-bottom: 8px;
649
+ }
650
+ .liste__rang { font-size: 11px; font-weight: 700; color: var(--texte-doux); }
651
+
652
+ /* --------------------------------------------------------- BOUTONS ------ */
653
+
654
+ .bouton {
655
+ display: inline-flex; align-items: center; justify-content: center; gap: 6px;
656
+ padding: 8px 14px; border-radius: 7px; border: 1px solid transparent;
657
+ font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
658
+ background: var(--fond-clair); color: var(--texte); border-color: var(--bord);
659
+ }
660
+ .bouton:hover { background: #2a2e37; }
661
+ .bouton:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
662
+ .bouton--principal { background: var(--accent); border-color: var(--accent); color: #06120e; }
663
+ .bouton--principal:hover { background: #45bda2; }
664
+ .bouton--discret { background: transparent; border-color: transparent; color: var(--texte-doux); }
665
+ .bouton--discret:hover { background: var(--fond-clair); color: var(--texte); }
666
+ .bouton[disabled] { opacity: 0.5; cursor: default; }
667
+ .bouton--icone { padding: 6px 9px; }
668
+
669
+ .message {
670
+ margin: 0 0 12px; padding: 9px 11px; border-radius: 7px;
671
+ font-size: 12.5px; border: 1px solid;
672
+ }
673
+ .message--erreur { background: rgba(217, 119, 106, 0.12); border-color: rgba(217, 119, 106, 0.4); color: #f0b3a9; }
674
+ .message--ok { background: rgba(59, 165, 141, 0.12); border-color: rgba(59, 165, 141, 0.4); color: #8fd9c6; }
675
+ .message--info { background: var(--fond-clair); border-color: var(--bord); color: var(--texte-doux); }
676
+
677
+ @media (prefers-reduced-motion: reduce) {
678
+ * { transition: none !important; animation: none !important; }
679
+ }
680
+ `, D = "lystech-editeur-hote";
681
+ function ae({
682
+ jeton: n,
683
+ site: t,
684
+ apiBaseUrl: s,
685
+ pont: r
686
+ }) {
687
+ document.getElementById(D)?.remove();
688
+ const c = document.createElement("div");
689
+ c.id = D, document.body.appendChild(c);
690
+ const b = c.attachShadow({ mode: "open" }), d = document.createElement("style");
691
+ d.textContent = te, b.appendChild(d);
692
+ const l = document.createElement("div");
693
+ b.appendChild(l);
694
+ let e = H(l);
695
+ const a = () => {
696
+ try {
697
+ window.sessionStorage.removeItem("lystech-edit");
698
+ } catch {
699
+ }
700
+ window.location.reload();
701
+ };
702
+ return e.render(
703
+ /* @__PURE__ */ o(
704
+ ee,
705
+ {
706
+ api: X({ jeton: n, site: t, apiBaseUrl: s, surJetonRefuse: a }),
707
+ pont: r
708
+ }
709
+ )
710
+ ), () => {
711
+ const u = e;
712
+ e = null, setTimeout(() => {
713
+ u?.unmount(), c.remove();
714
+ }, 0);
715
+ };
716
+ }
717
+ export {
718
+ ae as monterEditeur
719
+ };