@lystech/sections 0.5.0 → 0.5.1

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.
@@ -1,3 +1,3 @@
1
- export declare const CSS = "\n:host {\n all: initial;\n --fond: #16181d;\n --fond-clair: #21242b;\n --bord: #333844;\n --texte: #f2f3f5;\n --texte-doux: #a3a9b6;\n --accent: #3ba58d;\n --accent-sombre: #2d8570;\n --danger: #d9776a;\n font-family: ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto,\n \"Helvetica Neue\", Arial, sans-serif;\n font-size: 14px;\n line-height: 1.45;\n color: var(--texte);\n}\n\n* { box-sizing: border-box; }\n\n/* LE CALQUE LAISSE PASSER LES CLICS. Un conteneur fixe en plein \u00E9cran qui\n intercepte tout rendrait le site inutilisable derri\u00E8re lui : on ne pourrait\n plus naviguer, ni m\u00EAme faire d\u00E9filer correctement. Seuls ses ENFANTS\n reprennent les clics. */\n.calque {\n position: fixed;\n inset: 0;\n pointer-events: none;\n z-index: 2147483000;\n}\n.calque > * { pointer-events: auto; }\n\n/* ---------------------------------------------------------- CADRES ------ */\n\n.cadre {\n position: fixed;\n border: 2px dashed rgba(59, 165, 141, 0.55);\n border-radius: 6px;\n pointer-events: none;\n transition: border-color 120ms ease;\n}\n.cadre--actif { border-color: var(--accent); border-style: solid; }\n\n.pastille {\n position: fixed;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border: 0;\n border-radius: 999px;\n background: var(--accent);\n color: #06120e;\n font-size: 12px;\n font-weight: 650;\n letter-spacing: 0.01em;\n cursor: pointer;\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);\n}\n.pastille:hover { background: #45bda2; }\n.pastille:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }\n\n/* ------------------------------------------------------------ BARRE ----- */\n\n.barre {\n position: fixed;\n left: 50%;\n bottom: 18px;\n transform: translateX(-50%);\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 9px 14px;\n border: 1px solid var(--bord);\n border-radius: 999px;\n background: var(--fond);\n box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45);\n max-width: calc(100vw - 24px);\n}\n.barre__point {\n width: 8px; height: 8px; border-radius: 50%;\n background: var(--accent);\n flex: none;\n}\n.barre__texte { font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.barre__texte b { font-weight: 650; }\n.barre__compte { color: var(--texte-doux); font-size: 12px; white-space: nowrap; }\n\n/* ----------------------------------------------------------- PANNEAU ---- */\n\n.panneau {\n position: fixed;\n top: 0; right: 0; bottom: 0;\n width: min(420px, 100vw);\n display: flex;\n flex-direction: column;\n background: var(--fond);\n border-left: 1px solid var(--bord);\n box-shadow: -12px 0 40px rgba(0, 0, 0, 0.4);\n}\n@media (max-width: 520px) {\n .panneau { top: auto; height: 78vh; border-left: 0; border-top: 1px solid var(--bord); }\n}\n\n.panneau__tete {\n display: flex; align-items: flex-start; gap: 10px;\n padding: 16px 16px 12px;\n border-bottom: 1px solid var(--bord);\n}\n.panneau__titre { font-size: 15px; font-weight: 650; margin: 0; }\n.panneau__sous { margin: 3px 0 0; font-size: 12px; color: var(--texte-doux); }\n.panneau__corps { flex: 1; overflow-y: auto; padding: 14px 16px 18px; }\n.panneau__pied {\n display: flex; gap: 8px; align-items: center;\n padding: 12px 16px;\n border-top: 1px solid var(--bord);\n background: var(--fond-clair);\n}\n.panneau__pied .espace { flex: 1; }\n\n/* --------------------------------------------------- CONNEXION ---------- */\n\n/* Le voile PREND les clics, lui : une boite de dialogue qui demande un mot de\n passe ne doit pas laisser cliquer la page derriere elle. C'est l'exception\n a la regle du calque, et elle est volontaire. */\n.voile {\n position: fixed;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 16px;\n background: rgba(8, 10, 14, 0.62);\n backdrop-filter: blur(2px);\n}\n\n.fenetre {\n position: relative;\n width: min(408px, 100%);\n max-height: 92vh;\n overflow-y: auto;\n padding: 30px 28px 20px;\n border: 1px solid var(--bord);\n border-radius: 18px;\n /* Une lueur d'accent dans le coin superieur : de la presence, sans le\n degrade violet-bleu qu'on voit sur une page d'accueil sur deux. */\n background:\n radial-gradient(120% 90% at 50% -20%, rgba(59, 165, 141, 0.16), transparent 62%),\n var(--fond);\n box-shadow: 0 28px 70px rgba(0, 0, 0, 0.55);\n text-align: center;\n}\n\n.fenetre__fermer {\n position: absolute; top: 12px; right: 12px;\n width: 30px; height: 30px;\n display: inline-flex; align-items: center; justify-content: center;\n border: 0; border-radius: 8px;\n background: transparent; color: var(--texte-doux);\n font: inherit; font-size: 14px; cursor: pointer;\n}\n.fenetre__fermer:hover { background: var(--fond-clair); color: var(--texte); }\n\n/* ------------------------------------------------------------ MARQUE ---- */\n\n.marque {\n display: inline-flex; align-items: center; gap: 8px;\n margin-bottom: 18px;\n}\n.marque img { width: 22px; height: 22px; display: block; }\n.marque__mot {\n font-size: 12px; font-weight: 600;\n letter-spacing: 0.18em; text-transform: uppercase;\n color: #6fd3bd;\n}\n\n.fenetre__titre {\n margin: 0 0 6px;\n font-size: 20px; font-weight: 640; letter-spacing: -0.01em;\n color: var(--texte);\n}\n.fenetre__sous {\n margin: 0 auto 22px;\n max-width: 30ch;\n font-size: 13px; line-height: 1.5; color: var(--texte-doux);\n}\n.fenetre__corps { text-align: left; }\n\n/* ------------------------------------------------------ FOURNISSEURS ---- */\n\n.fournisseurs { display: flex; flex-direction: column; gap: 10px; }\n\n.fournisseur {\n display: flex; align-items: center; justify-content: center; gap: 10px;\n width: 100%; padding: 12px 16px;\n border: 1px solid transparent; border-radius: 10px;\n font: inherit; font-size: 14px; font-weight: 600;\n cursor: pointer;\n transition: transform 90ms ease, filter 90ms ease;\n}\n.fournisseur:hover { filter: brightness(1.06); }\n.fournisseur:active { transform: translateY(1px); }\n.fournisseur:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }\n.fournisseur[disabled] { opacity: 0.55; cursor: default; transform: none; filter: none; }\n.fournisseur .logo { width: 18px; height: 18px; flex: none; display: block; }\n\n/* LES COULEURS DE CHAQUE MARQUE, telles qu'elles les publient. Un bouton\n Google repeint aux couleurs du site devient moins reconnaissable \u2014 et un\n bouton de connexion qu'on ne reconnait pas est un bouton sur lequel on\n hesite a cliquer. */\n.fournisseur--google { background: #fff; color: #1f1f1f; border-color: #dadce0; }\n.fournisseur--facebook { background: #1877f2; color: #fff; }\n\n.bouton--large { width: 100%; padding: 12px 16px; font-size: 14px; }\n\n@media (prefers-reduced-motion: reduce) {\n .fournisseur { transition: none; }\n}\n\n/* ------------------------------------------------------------ CHAMPS ---- */\n\n.champ { margin-bottom: 16px; }\n.champ__etiquette {\n display: block; margin-bottom: 5px;\n font-size: 12px; font-weight: 600; color: var(--texte);\n}\n.champ__aide { margin: 4px 0 0; font-size: 11.5px; color: var(--texte-doux); }\n.champ__langue {\n display: inline-block; margin: 0 0 4px;\n font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em;\n text-transform: uppercase; color: var(--texte-doux);\n}\n\n/* TOUS les types de champs, pas seulement ceux auxquels on pensait. Un\n type oublie \u2014 \u00AB password \u00BB, \u00AB email \u00BB \u2014 retombe sur le style brut du\n navigateur : une ligne blanche au milieu d'un panneau sombre. */\ninput[type=\"text\"], input[type=\"url\"], input[type=\"number\"], input[type=\"date\"],\ninput[type=\"password\"], input[type=\"email\"], input[type=\"tel\"], input[type=\"search\"],\nselect, textarea {\n width: 100%;\n padding: 8px 10px;\n border: 1px solid var(--bord);\n border-radius: 6px;\n background: var(--fond-clair);\n color: var(--texte);\n font: inherit;\n font-size: 13px;\n}\ntextarea { min-height: 92px; resize: vertical; line-height: 1.5; }\ninput:focus, select:focus, textarea:focus {\n outline: none; border-color: var(--accent);\n box-shadow: 0 0 0 3px rgba(59, 165, 141, 0.18);\n}\n\n.bascule { display: flex; align-items: center; gap: 8px; }\n.bascule input { width: 16px; height: 16px; accent-color: var(--accent); }\n\n.vignette {\n margin-top: 8px; max-height: 110px; border-radius: 6px;\n border: 1px solid var(--bord); display: block;\n}\n\n/* --------------------------------------------------------- LISTES ------- */\n\n.liste__item {\n border: 1px solid var(--bord); border-radius: 8px;\n padding: 12px; margin-bottom: 10px; background: var(--fond-clair);\n}\n.liste__tete {\n display: flex; align-items: center; justify-content: space-between;\n margin-bottom: 8px;\n}\n.liste__rang { font-size: 11px; font-weight: 700; color: var(--texte-doux); }\n\n/* --------------------------------------------------------- BOUTONS ------ */\n\n.bouton {\n display: inline-flex; align-items: center; justify-content: center; gap: 6px;\n padding: 8px 14px; border-radius: 7px; border: 1px solid transparent;\n font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;\n background: var(--fond-clair); color: var(--texte); border-color: var(--bord);\n}\n.bouton:hover { background: #2a2e37; }\n.bouton:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }\n.bouton--principal { background: var(--accent); border-color: var(--accent); color: #06120e; }\n.bouton--principal:hover { background: #45bda2; }\n.bouton--discret { background: transparent; border-color: transparent; color: var(--texte-doux); }\n.bouton--discret:hover { background: var(--fond-clair); color: var(--texte); }\n.bouton[disabled] { opacity: 0.5; cursor: default; }\n.bouton--icone { padding: 6px 9px; }\n\n.message {\n margin: 0 0 12px; padding: 9px 11px; border-radius: 7px;\n font-size: 12.5px; border: 1px solid;\n}\n.message--erreur { background: rgba(217, 119, 106, 0.12); border-color: rgba(217, 119, 106, 0.4); color: #f0b3a9; }\n.message--ok { background: rgba(59, 165, 141, 0.12); border-color: rgba(59, 165, 141, 0.4); color: #8fd9c6; }\n.message--info { background: var(--fond-clair); border-color: var(--bord); color: var(--texte-doux); }\n\n@media (prefers-reduced-motion: reduce) {\n * { transition: none !important; animation: none !important; }\n}\n";
1
+ export declare const CSS = "\n:host {\n all: initial;\n --fond: #16181d;\n --fond-clair: #21242b;\n --bord: #333844;\n --texte: #f2f3f5;\n --texte-doux: #a3a9b6;\n --accent: #3ba58d;\n --accent-sombre: #2d8570;\n --danger: #d9776a;\n font-family: ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto,\n \"Helvetica Neue\", Arial, sans-serif;\n font-size: 14px;\n line-height: 1.45;\n color: var(--texte);\n}\n\n* { box-sizing: border-box; }\n\n/* LE CALQUE LAISSE PASSER LES CLICS. Un conteneur fixe en plein \u00E9cran qui\n intercepte tout rendrait le site inutilisable derri\u00E8re lui : on ne pourrait\n plus naviguer, ni m\u00EAme faire d\u00E9filer correctement. Seuls ses ENFANTS\n reprennent les clics. */\n.calque {\n position: fixed;\n inset: 0;\n pointer-events: none;\n z-index: 2147483000;\n}\n.calque > * { pointer-events: auto; }\n\n/* ---------------------------------------------------------- CADRES ------ */\n\n.cadre {\n position: fixed;\n border: 2px dashed rgba(59, 165, 141, 0.55);\n border-radius: 6px;\n pointer-events: none;\n transition: border-color 120ms ease;\n}\n.cadre--actif { border-color: var(--accent); border-style: solid; }\n\n.pastille {\n position: fixed;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border: 0;\n border-radius: 999px;\n background: var(--accent);\n color: #06120e;\n font-size: 12px;\n font-weight: 650;\n letter-spacing: 0.01em;\n cursor: pointer;\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);\n}\n.pastille:hover { background: #45bda2; }\n.pastille:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }\n\n/* ------------------------------------------------------------ BARRE ----- */\n\n.barre {\n position: fixed;\n left: 50%;\n bottom: 18px;\n transform: translateX(-50%);\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 9px 14px;\n border: 1px solid var(--bord);\n border-radius: 999px;\n background: var(--fond);\n box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45);\n max-width: calc(100vw - 24px);\n}\n.barre__point {\n width: 8px; height: 8px; border-radius: 50%;\n background: var(--accent);\n flex: none;\n}\n.barre__texte { font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.barre__texte b { font-weight: 650; }\n.barre__compte { color: var(--texte-doux); font-size: 12px; white-space: nowrap; }\n\n/* ----------------------------------------------------------- PANNEAU ---- */\n\n.panneau {\n position: fixed;\n top: 0; right: 0; bottom: 0;\n width: min(420px, 100vw);\n display: flex;\n flex-direction: column;\n background: var(--fond);\n border-left: 1px solid var(--bord);\n box-shadow: -12px 0 40px rgba(0, 0, 0, 0.4);\n}\n@media (max-width: 520px) {\n .panneau { top: auto; height: 78vh; border-left: 0; border-top: 1px solid var(--bord); }\n}\n\n.panneau__tete {\n display: flex; align-items: flex-start; gap: 10px;\n padding: 16px 16px 12px;\n border-bottom: 1px solid var(--bord);\n}\n.panneau__titre { font-size: 15px; font-weight: 650; margin: 0; }\n.panneau__sous { margin: 3px 0 0; font-size: 12px; color: var(--texte-doux); }\n.panneau__corps { flex: 1; overflow-y: auto; padding: 14px 16px 18px; }\n.panneau__pied {\n display: flex; gap: 8px; align-items: center;\n padding: 12px 16px;\n border-top: 1px solid var(--bord);\n background: var(--fond-clair);\n}\n.panneau__pied .espace { flex: 1; }\n\n/* --------------------------------------------------- CONNEXION ---------- */\n\n/* LA CONNEXION EST CLAIRE, AUX COULEURS DE LYSTECH. L'\u00E9diteur reste un outil\n sombre qui s'efface derri\u00E8re le travail ; la connexion, elle, est l'instant\n o\u00F9 quelqu'un d\u00E9cide de faire confiance. Il doit y reconna\u00EEtre Lystech \u2014 la\n fleur, son p\u00E9trole et son turquoise, sur du blanc \u2014 et non une bo\u00EEte noire\n pos\u00E9e sur son site.\n\n Le th\u00E8me se red\u00E9finit ICI, sur le voile : les boutons, messages et champs\n partag\u00E9s avec l'\u00E9diteur suivent ces variables sans une r\u00E8gle de plus, et\n l'\u00E9diteur garde les siennes. Clair quel que soit le th\u00E8me du syst\u00E8me :\n c'est un choix de marque. */\n.voile {\n --fond: #ffffff;\n --fond-clair: #f4f7f8;\n --bord: #dfe6e9;\n --texte: #0b1f26;\n --texte-doux: #52666f;\n --petrole: #084050;\n --petrole-survol: #0b5468;\n --turquoise: #10b8b0;\n --focus: #0c8f89;\n\n position: fixed;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 16px;\n /* Le voile PREND les clics, lui : une bo\u00EEte de dialogue qui demande une\n identit\u00E9 ne doit pas laisser cliquer la page derri\u00E8re elle. C'est\n l'exception \u00E0 la r\u00E8gle du calque, et elle est volontaire. Teint\u00E9 p\u00E9trole\n plut\u00F4t que noir : on assombrit le site sans l'\u00E9teindre. */\n background: rgba(8, 44, 56, 0.34);\n backdrop-filter: blur(4px) saturate(115%);\n color: var(--texte);\n}\n\n.fenetre {\n position: relative;\n width: min(400px, 100%);\n max-height: 92vh;\n overflow-y: auto;\n padding: 34px 30px 26px;\n border: 1px solid rgba(8, 64, 80, 0.10);\n border-radius: 20px;\n /* La lueur turquoise de la fleur, \u00E0 peine, en haut de la carte. */\n background:\n radial-gradient(90% 60% at 50% -12%, rgba(16, 184, 176, 0.13), transparent 70%),\n var(--fond);\n box-shadow:\n 0 1px 2px rgba(8, 64, 80, 0.06),\n 0 28px 64px -18px rgba(8, 44, 56, 0.45);\n text-align: center;\n}\n\n.fenetre__fermer {\n position: absolute; top: 14px; right: 14px;\n width: 32px; height: 32px;\n display: inline-flex; align-items: center; justify-content: center;\n border: 0; border-radius: 9px;\n background: transparent; color: var(--texte-doux);\n font: inherit; font-size: 14px; cursor: pointer;\n}\n.fenetre__fermer:hover { background: var(--fond-clair); color: var(--texte); }\n.fenetre__fermer:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }\n\n/* ------------------------------------------------------------ MARQUE ---- */\n\n.marque {\n display: inline-flex; flex-direction: column; align-items: center; gap: 8px;\n margin-bottom: 18px;\n}\n.marque img {\n width: 44px; height: 44px; display: block;\n filter: drop-shadow(0 6px 14px rgba(16, 184, 176, 0.28));\n}\n.marque__mot {\n font-size: 11.5px; font-weight: 700;\n letter-spacing: 0.24em; text-transform: uppercase;\n color: var(--petrole);\n}\n\n.fenetre__titre {\n margin: 0 0 8px;\n font-size: 21px; font-weight: 700; letter-spacing: -0.015em;\n color: var(--texte);\n text-wrap: balance;\n}\n.fenetre__sous {\n margin: 0 auto 24px;\n max-width: 36ch;\n font-size: 13.5px; line-height: 1.55; color: var(--texte-doux);\n text-wrap: balance;\n}\n.fenetre__corps { text-align: left; }\n\n/* ------------------------------------------------------ FOURNISSEURS ---- */\n\n.fournisseurs { display: flex; flex-direction: column; gap: 10px; }\n\n.fournisseur {\n display: flex; align-items: center; justify-content: center; gap: 10px;\n width: 100%; min-height: 46px; padding: 12px 16px;\n border: 1px solid transparent; border-radius: 12px;\n font: inherit; font-size: 14px; font-weight: 600;\n cursor: pointer;\n transition: transform 90ms ease, background-color 120ms ease, box-shadow 120ms ease;\n}\n.fournisseur:active { transform: translateY(1px); }\n.fournisseur:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }\n.fournisseur[disabled] { opacity: 0.55; cursor: default; transform: none; }\n.fournisseur .logo { width: 18px; height: 18px; flex: none; display: block; }\n\n/* LES COULEURS DE CHAQUE MARQUE, telles qu'elles les publient. Un bouton\n Google repeint aux couleurs du site devient moins reconnaissable \u2014 et un\n bouton de connexion qu'on ne reconna\u00EEt pas est un bouton sur lequel on\n h\u00E9site \u00E0 cliquer. */\n.fournisseur--google {\n background: #fff; color: #1f1f1f; border-color: #dadce0;\n box-shadow: 0 1px 2px rgba(8, 64, 80, 0.06);\n}\n.fournisseur--google:hover:not([disabled]) { background: #f6f9fa; border-color: #c9d3d8; }\n.fournisseur--facebook { background: #1877f2; color: #fff; }\n.fournisseur--facebook:hover:not([disabled]) { background: #166fe5; }\n\n.bouton--large { width: 100%; padding: 12px 16px; font-size: 14px; }\n\n/* Les boutons et messages PARTAG\u00C9S avec l'\u00E9diteur, en version claire. */\n.voile .bouton {\n min-height: 44px; border-radius: 12px;\n background: #fff; color: var(--texte); border-color: #cfd9dd;\n}\n.voile .bouton:hover { background: var(--fond-clair); }\n.voile .bouton:focus-visible { outline-color: var(--focus); }\n.voile .bouton--principal { background: var(--petrole); border-color: var(--petrole); color: #fff; }\n.voile .bouton--principal:hover { background: var(--petrole-survol); }\n\n.voile .message { font-size: 13px; line-height: 1.5; border-radius: 10px; }\n.voile .message--erreur { background: #fdf0ee; border-color: #f4c7bf; color: #a3321f; }\n.voile .message--ok { background: #e8f7f5; border-color: #a9e2dc; color: #0a5c57; }\n.voile .message--info { background: var(--fond-clair); border-color: var(--bord); color: #3a5159; }\n\n@media (prefers-reduced-motion: reduce) {\n .fournisseur { transition: none; }\n}\n\n/* ------------------------------------------------------------ CHAMPS ---- */\n\n.champ { margin-bottom: 16px; }\n.champ__etiquette {\n display: block; margin-bottom: 5px;\n font-size: 12px; font-weight: 600; color: var(--texte);\n}\n.champ__aide { margin: 4px 0 0; font-size: 11.5px; color: var(--texte-doux); }\n.champ__langue {\n display: inline-block; margin: 0 0 4px;\n font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em;\n text-transform: uppercase; color: var(--texte-doux);\n}\n\n/* TOUS les types de champs, pas seulement ceux auxquels on pensait. Un\n type oublie \u2014 \u00AB password \u00BB, \u00AB email \u00BB \u2014 retombe sur le style brut du\n navigateur : une ligne blanche au milieu d'un panneau sombre. */\ninput[type=\"text\"], input[type=\"url\"], input[type=\"number\"], input[type=\"date\"],\ninput[type=\"password\"], input[type=\"email\"], input[type=\"tel\"], input[type=\"search\"],\nselect, textarea {\n width: 100%;\n padding: 8px 10px;\n border: 1px solid var(--bord);\n border-radius: 6px;\n background: var(--fond-clair);\n color: var(--texte);\n font: inherit;\n font-size: 13px;\n}\ntextarea { min-height: 92px; resize: vertical; line-height: 1.5; }\ninput:focus, select:focus, textarea:focus {\n outline: none; border-color: var(--accent);\n box-shadow: 0 0 0 3px rgba(59, 165, 141, 0.18);\n}\n\n.bascule { display: flex; align-items: center; gap: 8px; }\n.bascule input { width: 16px; height: 16px; accent-color: var(--accent); }\n\n.vignette {\n margin-top: 8px; max-height: 110px; border-radius: 6px;\n border: 1px solid var(--bord); display: block;\n}\n\n/* --------------------------------------------------------- LISTES ------- */\n\n.liste__item {\n border: 1px solid var(--bord); border-radius: 8px;\n padding: 12px; margin-bottom: 10px; background: var(--fond-clair);\n}\n.liste__tete {\n display: flex; align-items: center; justify-content: space-between;\n margin-bottom: 8px;\n}\n.liste__rang { font-size: 11px; font-weight: 700; color: var(--texte-doux); }\n\n/* --------------------------------------------------------- BOUTONS ------ */\n\n.bouton {\n display: inline-flex; align-items: center; justify-content: center; gap: 6px;\n padding: 8px 14px; border-radius: 7px; border: 1px solid transparent;\n font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;\n background: var(--fond-clair); color: var(--texte); border-color: var(--bord);\n}\n.bouton:hover { background: #2a2e37; }\n.bouton:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }\n.bouton--principal { background: var(--accent); border-color: var(--accent); color: #06120e; }\n.bouton--principal:hover { background: #45bda2; }\n.bouton--discret { background: transparent; border-color: transparent; color: var(--texte-doux); }\n.bouton--discret:hover { background: var(--fond-clair); color: var(--texte); }\n.bouton[disabled] { opacity: 0.5; cursor: default; }\n.bouton--icone { padding: 6px 9px; }\n\n.message {\n margin: 0 0 12px; padding: 9px 11px; border-radius: 7px;\n font-size: 12.5px; border: 1px solid;\n}\n.message--erreur { background: rgba(217, 119, 106, 0.12); border-color: rgba(217, 119, 106, 0.4); color: #f0b3a9; }\n.message--ok { background: rgba(59, 165, 141, 0.12); border-color: rgba(59, 165, 141, 0.4); color: #8fd9c6; }\n.message--info { background: var(--fond-clair); border-color: var(--bord); color: var(--texte-doux); }\n\n@media (prefers-reduced-motion: reduce) {\n * { transition: none !important; animation: none !important; }\n}\n";
2
2
  export declare const CSS_EN_PLACE = "\n/* --------------------------------------------------------- CHOIX -------- */\n\n/* Quand un meme texte vient de plusieurs cles, on demande laquelle plutot que\n de deviner \u2014 et de modifier la mauvaise sans que personne le voie. */\n.choix {\n position: fixed;\n width: 260px;\n padding: 12px;\n border: 1px solid var(--bord);\n border-radius: 10px;\n background: var(--fond);\n box-shadow: 0 14px 40px rgba(0, 0, 0, 0.45);\n}\n.choix__titre { margin: 0 0 2px; font-size: 12.5px; font-weight: 650; }\n.choix__aide { margin: 0 0 10px; font-size: 11.5px; color: var(--texte-doux); }\n.choix__option {\n display: flex; flex-direction: column; align-items: flex-start; gap: 2px;\n width: 100%; margin-bottom: 6px; padding: 7px 9px;\n border: 1px solid var(--bord); border-radius: 7px;\n background: var(--fond-clair); color: var(--texte);\n font: inherit; text-align: left; cursor: pointer;\n}\n.choix__option:hover { background: #2a2e37; border-color: var(--accent); }\n.choix__chemin { font-size: 12px; font-weight: 600; }\n.choix__ns { font-size: 10.5px; color: var(--texte-doux); }\n\n/* ------------------------------------------------------- RANGEES -------- */\n\n.rangee {\n display: flex; align-items: center; justify-content: space-between; gap: 10px;\n width: 100%; margin-bottom: 6px; padding: 10px 12px;\n border: 1px solid var(--bord); border-radius: 8px;\n background: var(--fond-clair); color: var(--texte);\n font: inherit; text-align: left; cursor: pointer;\n}\n.rangee:hover { background: #2a2e37; border-color: var(--accent); }\n.rangee__nom { font-size: 13px; font-weight: 600; }\n.rangee__info { font-size: 11.5px; color: var(--texte-doux); white-space: nowrap; }\n\n/* ------------------------------------------------------ FLOTTANT -------- */\n\n/* Un message au-dessus de la barre, pour confirmer sans ouvrir de panneau. */\n.flottant {\n position: fixed;\n left: 50%; bottom: 76px;\n transform: translateX(-50%);\n max-width: min(460px, calc(100vw - 24px));\n}\n.flottant .message { margin: 0; box-shadow: 0 8px 26px rgba(0,0,0,.4); }\n";
3
3
  export declare const CSS_MODE = "\n/* ON NE DOIT JAMAIS SE DEMANDER SI ON EST EN MODE EDITION. Une barre en bas\n se confond avec un bandeau de temoins ; un lisere qui borde tout l'ecran,\n present sur chaque page, ne se confond avec rien. Il ne prend aucun clic. */\n.cadre-global {\n position: fixed;\n inset: 0;\n pointer-events: none;\n border: 2px solid var(--accent);\n border-radius: 4px;\n box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25);\n opacity: 0.85;\n}\n\n/* EN MODE CIRCULER, le cadre change d'allure. On est toujours connecte \u2014 le\n dire reste necessaire \u2014 mais les clics rendent la main aux liens, et rien\n ne serait plus desagreable que de croire qu'on edite alors qu'on navigue,\n ou l'inverse. Trait interrompu et plus efface : present, mais en retrait. */\n.cadre-global--circuler {\n border-style: dashed;\n border-color: var(--texte-doux);\n opacity: 0.5;\n}\n\n/* La sortie est rouge au survol seulement : visible quand on la cherche,\n discrete le reste du temps \u2014 c'est le geste qu'on fait une fois. */\n.bouton--sortie { color: var(--texte-doux); background: transparent; border-color: transparent; }\n.bouton--sortie:hover { background: rgba(217, 119, 106, 0.16); color: var(--danger); }\n";
package/dist/editeur.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsx as e, jsxs as m, Fragment as ae } from "react/jsx-runtime";
2
2
  import { createRoot as se } from "react-dom/client";
3
3
  import { C as ge, s as ie } from "./morceaux/constantes-BPZxUYge.js";
4
- import { useState as M, useRef as j, useEffect as W, useCallback as X, useMemo as ne } from "react";
4
+ import { useState as P, useRef as Y, useEffect as W, useCallback as X, useMemo as ne } from "react";
5
5
  function xe({
6
6
  jeton: o,
7
7
  site: t,
@@ -79,7 +79,7 @@ function Ce({
79
79
  surJeton: r,
80
80
  surFermer: d
81
81
  }) {
82
- const [s, l] = M({ nom: "repos" }), g = (v) => {
82
+ const [s, l] = P({ nom: "repos" }), g = (v) => {
83
83
  switch (v) {
84
84
  case "auth/popup-blocked":
85
85
  return "Votre navigateur a bloqué la fenêtre de connexion. Autorisez les fenêtres pour ce site, puis réessayez.";
@@ -152,8 +152,8 @@ function Ce({
152
152
  const [{ initializeApp: A, getApps: T }, y] = await Promise.all([
153
153
  import("./morceaux/index.esm-B4AB50RA.js"),
154
154
  import("./morceaux/index.esm-B4hL1FOE.js")
155
- ]), V = T().find((S) => S.name === "lystech-edition") ?? A(ve, "lystech-edition"), U = v === "google" ? new y.GoogleAuthProvider() : new y.FacebookAuthProvider(), P = await (await y.signInWithPopup(y.getAuth(V), U)).user.getIdToken();
156
- await n(P);
155
+ ]), j = T().find((S) => S.name === "lystech-edition") ?? A(ve, "lystech-edition"), U = v === "google" ? new y.GoogleAuthProvider() : new y.FacebookAuthProvider(), O = await (await y.signInWithPopup(y.getAuth(j), U)).user.getIdToken();
156
+ await n(O);
157
157
  } catch (A) {
158
158
  l({ nom: "erreur", texte: g(String(A?.code ?? "")) });
159
159
  }
@@ -465,13 +465,13 @@ function ze({
465
465
  modifiable: a,
466
466
  surModification: r
467
467
  }) {
468
- const d = j(/* @__PURE__ */ new Map()), s = j(null), [l, g] = M(null), n = j(o);
468
+ const d = Y(/* @__PURE__ */ new Map()), s = Y(null), [l, g] = P(null), n = Y(o);
469
469
  n.current = o;
470
- const u = j(r);
470
+ const u = Y(r);
471
471
  u.current = r;
472
- const x = j(a);
472
+ const x = Y(a);
473
473
  x.current = a;
474
- const v = j(null);
474
+ const v = Y(null);
475
475
  return W(() => {
476
476
  if (!t) return;
477
477
  const A = () => {
@@ -487,18 +487,18 @@ function ze({
487
487
  s.current || (clearTimeout(T), T = setTimeout(A, 250));
488
488
  });
489
489
  y.observe(document.body, { childList: !0, subtree: !0 });
490
- const V = "outline:2px dashed rgba(59,165,141,.85);outline-offset:3px;border-radius:3px;cursor:text;", U = (p) => {
490
+ const j = "outline:2px dashed rgba(59,165,141,.85);outline-offset:3px;border-radius:3px;cursor:text;", U = (p) => {
491
491
  const i = p.target;
492
492
  !(i instanceof HTMLElement) || s.current || d.current.has(i) && (i.dataset.lysStyleAvant || (i.dataset.lysStyleAvant = i.getAttribute("style") ?? ""), i.setAttribute(
493
493
  "style",
494
- (i.dataset.lysStyleAvant ?? "") + V
494
+ (i.dataset.lysStyleAvant ?? "") + j
495
495
  ));
496
496
  }, I = (p) => {
497
497
  const i = p.target;
498
498
  if (!(i instanceof HTMLElement) || s.current?.el === i || i.dataset.lysStyleAvant === void 0) return;
499
499
  const h = i.dataset.lysStyleAvant;
500
500
  delete i.dataset.lysStyleAvant, h ? i.setAttribute("style", h) : i.removeAttribute("style");
501
- }, P = (p, i) => {
501
+ }, O = (p, i) => {
502
502
  const h = p.getAttribute("style") ?? "";
503
503
  s.current = {
504
504
  el: p,
@@ -510,21 +510,21 @@ function ze({
510
510
  "style",
511
511
  (p.dataset.lysStyleAvant ?? "") + "outline:2px solid #3ba58d;outline-offset:3px;border-radius:3px;"
512
512
  ), p.focus();
513
- const Q = window.getSelection(), q = document.createRange();
514
- q.selectNodeContents(p), Q?.removeAllRanges(), Q?.addRange(q);
513
+ const B = window.getSelection(), Q = document.createRange();
514
+ Q.selectNodeContents(p), B?.removeAllRanges(), B?.addRange(Q);
515
515
  }, S = async (p) => {
516
516
  const i = s.current;
517
517
  if (!i) return;
518
518
  s.current = null;
519
519
  const h = (i.el.textContent ?? "").trim();
520
520
  i.el.removeAttribute("contenteditable");
521
- const Q = i.el.dataset.lysStyleAvant;
522
- if (delete i.el.dataset.lysStyleAvant, Q ? i.el.setAttribute("style", Q) : i.el.removeAttribute("style"), p || h === i.avant) {
521
+ const B = i.el.dataset.lysStyleAvant;
522
+ if (delete i.el.dataset.lysStyleAvant, B ? i.el.setAttribute("style", B) : i.el.removeAttribute("style"), p || h === i.avant) {
523
523
  p && (i.el.textContent = i.avant);
524
524
  return;
525
525
  }
526
- const q = n.current.langueCourante();
527
- n.current.poser(q, i.ns, i.chemin, h), await u.current(i.ns, i.chemin, q, h);
526
+ const Q = n.current.langueCourante();
527
+ n.current.poser(Q, i.ns, i.chemin, h), await u.current(i.ns, i.chemin, Q, h);
528
528
  }, D = (p) => {
529
529
  const i = p.target;
530
530
  if (!(i instanceof HTMLElement)) return;
@@ -535,7 +535,7 @@ function ze({
535
535
  const h = d.current.get(i);
536
536
  if (h) {
537
537
  if (p.preventDefault(), p.stopPropagation(), h.candidats.length === 1) {
538
- P(i, h.candidats[0]);
538
+ O(i, h.candidats[0]);
539
539
  return;
540
540
  }
541
541
  g({
@@ -545,21 +545,21 @@ function ze({
545
545
  y: p.clientY
546
546
  });
547
547
  }
548
- }, L = (p) => {
548
+ }, M = (p) => {
549
549
  s.current && (p.key === "Escape" ? (p.preventDefault(), S(!0)) : p.key === "Enter" && !p.shiftKey && (p.preventDefault(), S(!1)));
550
550
  }, _ = () => {
551
551
  s.current && S(!1);
552
552
  };
553
553
  document.addEventListener("mouseover", U, !0), document.addEventListener("mouseout", I, !0), document.addEventListener("click", D, !0);
554
- const Z = (p) => {
554
+ const G = (p) => {
555
555
  if (!s.current) return;
556
556
  const i = p.inputType;
557
557
  (i === "insertParagraph" || i === "insertLineBreak") && (p.preventDefault(), S(!1));
558
558
  };
559
- return document.addEventListener("beforeinput", Z, !0), document.addEventListener("keydown", L, !0), document.addEventListener("focusout", _, !0), window.__lysChoisir = (p, i) => {
560
- g(null), P(i, p);
559
+ return document.addEventListener("beforeinput", G, !0), document.addEventListener("keydown", M, !0), document.addEventListener("focusout", _, !0), window.__lysChoisir = (p, i) => {
560
+ g(null), O(i, p);
561
561
  }, () => {
562
- v.current = null, clearTimeout(T), y.disconnect(), document.removeEventListener("mouseover", U, !0), document.removeEventListener("mouseout", I, !0), document.removeEventListener("click", D, !0), document.removeEventListener("beforeinput", Z, !0), document.removeEventListener("keydown", L, !0), document.removeEventListener("focusout", _, !0), s.current && S(!0), delete window.__lysChoisir;
562
+ v.current = null, clearTimeout(T), y.disconnect(), document.removeEventListener("mouseover", U, !0), document.removeEventListener("mouseout", I, !0), document.removeEventListener("click", D, !0), document.removeEventListener("beforeinput", G, !0), document.removeEventListener("keydown", M, !0), document.removeEventListener("focusout", _, !0), s.current && S(!0), delete window.__lysChoisir;
563
563
  };
564
564
  }, [t]), W(() => {
565
565
  s.current || v.current?.();
@@ -600,25 +600,25 @@ function ze({
600
600
  }
601
601
  ) : null;
602
602
  }
603
- const H = /^i18n:([^:]+):(.*)$/, ee = "commun", te = "lystech-edit-mode";
603
+ const Z = /^i18n:([^:]+):(.*)$/, ee = "commun", te = "lystech-edit-mode";
604
604
  function re(o, t) {
605
605
  return JSON.stringify(o ?? {}) === JSON.stringify(t ?? {});
606
606
  }
607
607
  function Te({ api: o, pont: t }) {
608
- const [a, r] = M([]), [d, s] = M([]), [l, g] = M(t.page), [n, u] = M(null), [x, v] = M({}), [A, T] = M(!1), [y, V] = M(() => {
608
+ const [a, r] = P([]), [d, s] = P([]), [l, g] = P(t.page), [n, u] = P(null), [x, v] = P({}), [A, T] = P(!1), [y, j] = P(() => {
609
609
  try {
610
610
  return window.localStorage.getItem(te) === "circuler" ? "circuler" : "modifier";
611
611
  } catch {
612
612
  return "modifier";
613
613
  }
614
- }), U = () => V((c) => {
614
+ }), U = () => j((c) => {
615
615
  const f = c === "modifier" ? "circuler" : "modifier";
616
616
  try {
617
617
  window.localStorage.setItem(te, f);
618
618
  } catch {
619
619
  }
620
620
  return f;
621
- }), [I, P] = M(!1), [S, D] = M(
621
+ }), [I, O] = P(!1), [S, D] = P(
622
622
  null
623
623
  );
624
624
  W(() => (t.surChangementDePage = (c) => {
@@ -626,7 +626,7 @@ function Te({ api: o, pont: t }) {
626
626
  }, () => {
627
627
  t.surChangementDePage = void 0;
628
628
  }), [t]);
629
- const L = X(async () => {
629
+ const M = X(async () => {
630
630
  try {
631
631
  const [c, f] = await Promise.all([
632
632
  o.pourPage(l),
@@ -643,23 +643,23 @@ function Te({ api: o, pont: t }) {
643
643
  W(() => {
644
644
  o.schemas().then(r).catch(() => r([]));
645
645
  }, [o]), W(() => {
646
- L();
647
- }, [L]);
646
+ M();
647
+ }, [M]);
648
648
  const _ = X(
649
649
  (c, f) => {
650
650
  let b = null, k = -1;
651
651
  for (const C of a) {
652
- const N = H.exec(C.blockType);
652
+ const N = Z.exec(C.blockType);
653
653
  if (!N || N[1] !== c) continue;
654
654
  const w = N[2];
655
655
  (w === "" || f === w || f.startsWith(w + ".")) && w.length > k && (b = C, k = w.length);
656
656
  }
657
657
  if (!b) return null;
658
- const E = H.exec(b.blockType)?.[2] ?? "", O = E ? f.slice(E.length + 1) : f;
659
- return { bloc: b, champ: O };
658
+ const E = Z.exec(b.blockType)?.[2] ?? "", L = E ? f.slice(E.length + 1) : f;
659
+ return { bloc: b, champ: L };
660
660
  },
661
661
  [a]
662
- ), Z = X(
662
+ ), G = X(
663
663
  (c, f) => _(c, f) !== null,
664
664
  [_]
665
665
  ), p = X(
@@ -674,7 +674,7 @@ function Te({ api: o, pont: t }) {
674
674
  ), h = ne(
675
675
  () => d.filter((c) => c.draft && !re(c.draft, c.data)),
676
676
  [d]
677
- ), Q = X(
677
+ ), B = X(
678
678
  async (c, f, b, k) => {
679
679
  const E = _(c, f);
680
680
  if (!E) {
@@ -684,20 +684,20 @@ function Te({ api: o, pont: t }) {
684
684
  });
685
685
  return;
686
686
  }
687
- const O = d.find((z) => z.blockType === E.bloc.blockType), C = O?.draft ?? O?.data ?? {}, N = C[E.champ], w = E.bloc.fields.find((z) => z.key === E.champ), B = (
687
+ const L = d.find((z) => z.blockType === E.bloc.blockType), C = L?.draft ?? L?.data ?? {}, N = C[E.champ], w = E.bloc.fields.find((z) => z.key === E.champ), q = (
688
688
  /* `!declare.localized` et non `=== false` : un champ non traduit
689
689
  OMET la cle plutot que de la mettre a faux. Tester l'egalite
690
690
  stricte ne se declenchait donc jamais. */
691
691
  w && !w.localized ? k : N && typeof N == "object" && !Array.isArray(N) ? { ...N, [b]: k } : { [b]: k }
692
- ), G = { ...C, [E.champ]: B };
692
+ ), H = { ...C, [E.champ]: q };
693
693
  try {
694
- if (O?.UID)
695
- await o.enregistrerBrouillon(O.UID, G);
694
+ if (L?.UID)
695
+ await o.enregistrerBrouillon(L.UID, H);
696
696
  else {
697
697
  const z = E.bloc.pages?.[0] ?? l;
698
- await o.creer(z, E.bloc.blockType, G);
698
+ await o.creer(z, E.bloc.blockType, H);
699
699
  }
700
- await L(), D(null);
700
+ await M(), D(null);
701
701
  } catch {
702
702
  D({
703
703
  ton: "erreur",
@@ -705,14 +705,14 @@ function Te({ api: o, pont: t }) {
705
705
  });
706
706
  }
707
707
  },
708
- [o, _, l, L, d]
709
- ), q = async () => {
708
+ [o, _, l, M, d]
709
+ ), Q = async () => {
710
710
  if (!h.length) return;
711
- P(!0), D(null);
711
+ O(!0), D(null);
712
712
  const c = h.length;
713
713
  try {
714
714
  for (const f of h) await o.publier(f.UID);
715
- await L();
715
+ await M();
716
716
  for (const f of h) t.poserApercu(f.blockType, null);
717
717
  t.recharger(), D({
718
718
  ton: "ok",
@@ -724,14 +724,14 @@ function Te({ api: o, pont: t }) {
724
724
  texte: "La publication a échoué. Rien n'a été mis en ligne."
725
725
  });
726
726
  } finally {
727
- P(!1);
727
+ O(!1);
728
728
  }
729
729
  }, de = async () => {
730
- P(!0);
730
+ O(!0);
731
731
  try {
732
732
  const c = h.map((b) => b.blockType);
733
733
  for (const b of h) await o.annuler(b.UID);
734
- const f = await L();
734
+ const f = await M();
735
735
  for (const b of c) t.poserApercu(b, null);
736
736
  if (t.sourceTexte) {
737
737
  const { appliquerAuxTextes: b } = await import("./morceaux/sourceTexte-BMPMpNg9.js");
@@ -745,42 +745,42 @@ function Te({ api: o, pont: t }) {
745
745
  texte: "Modifications abandonnées. On est revenu à ce qui est en ligne."
746
746
  });
747
747
  } finally {
748
- P(!1);
748
+ O(!1);
749
749
  }
750
750
  }, pe = (c) => {
751
- const f = d.find((C) => C.blockType === c), b = f?.draft ?? f?.data ?? {}, k = p(c), E = H.exec(c), O = {};
751
+ const f = d.find((C) => C.blockType === c), b = f?.draft ?? f?.data ?? {}, k = p(c), E = Z.exec(c), L = {};
752
752
  if (!E) {
753
753
  const C = t.replis?.[c];
754
- C && typeof C == "object" && !Array.isArray(C) && Object.assign(O, C);
754
+ C && typeof C == "object" && !Array.isArray(C) && Object.assign(L, C);
755
755
  }
756
756
  if (E && k && t.sourceTexte) {
757
- const C = E[1], N = E[2], w = t.sourceTexte.langues(), B = {};
757
+ const C = E[1], N = E[2], w = t.sourceTexte.langues(), q = {};
758
758
  for (const z of w)
759
- B[z] = t.sourceTexte.dictionnaire(z)[C] ?? {};
760
- const G = t.sourceTexte.langueCourante();
759
+ q[z] = t.sourceTexte.dictionnaire(z)[C] ?? {};
760
+ const H = t.sourceTexte.langueCourante();
761
761
  for (const z of k.fields) {
762
762
  const K = N ? N + "." + z.key : z.key;
763
763
  if (!z.localized) {
764
- const Y = B[G]?.[K] ?? w.map((R) => B[R]?.[K]).find((R) => typeof R == "string");
765
- typeof Y == "string" && (O[z.key] = Y);
764
+ const V = q[H]?.[K] ?? w.map((F) => q[F]?.[K]).find((F) => typeof F == "string");
765
+ typeof V == "string" && (L[z.key] = V);
766
766
  continue;
767
767
  }
768
768
  const $ = {};
769
- for (const Y of w) {
770
- const R = B[Y]?.[K];
771
- typeof R == "string" && ($[Y] = R);
769
+ for (const V of w) {
770
+ const F = q[V]?.[K];
771
+ typeof F == "string" && ($[V] = F);
772
772
  }
773
- Object.keys($).length && (O[z.key] = $);
773
+ Object.keys($).length && (L[z.key] = $);
774
774
  }
775
775
  }
776
776
  for (const [C, N] of Object.entries(b)) {
777
- const w = O[C], B = N && typeof N == "object" && !Array.isArray(N) && w && typeof w == "object" && !Array.isArray(w);
778
- O[C] = B ? { ...w, ...N } : N;
777
+ const w = L[C], q = N && typeof N == "object" && !Array.isArray(N) && w && typeof w == "object" && !Array.isArray(w);
778
+ L[C] = q ? { ...w, ...N } : N;
779
779
  }
780
- v(O), u(c), T(!1), D(null);
780
+ v(L), u(c), T(!1), D(null);
781
781
  }, fe = (c, f) => v((b) => ({ ...b, [c]: f })), me = async () => {
782
782
  if (n) {
783
- P(!0);
783
+ O(!0);
784
784
  try {
785
785
  const c = d.find((b) => b.blockType === n);
786
786
  if (c?.UID) await o.enregistrerBrouillon(c.UID, x);
@@ -788,7 +788,7 @@ function Te({ api: o, pont: t }) {
788
788
  const b = p(n)?.pages?.[0] ?? l;
789
789
  await o.creer(b, n, x);
790
790
  }
791
- const f = await L();
791
+ const f = await M();
792
792
  if (t.sourceTexte) {
793
793
  const { appliquerAuxTextes: b } = await import("./morceaux/sourceTexte-BMPMpNg9.js");
794
794
  b(
@@ -796,14 +796,14 @@ function Te({ api: o, pont: t }) {
796
796
  t.sourceTexte
797
797
  );
798
798
  }
799
- H.test(n) || t.poserApercu(n, x), D({
799
+ Z.test(n) || t.poserApercu(n, x), D({
800
800
  ton: "ok",
801
801
  texte: "Enregistré. Rien n'a encore changé pour vos visiteurs."
802
802
  });
803
803
  } catch {
804
804
  D({ ton: "erreur", texte: "L'enregistrement a échoué." });
805
805
  } finally {
806
- P(!1);
806
+ O(!1);
807
807
  }
808
808
  }
809
809
  }, be = () => {
@@ -812,7 +812,7 @@ function Te({ api: o, pont: t }) {
812
812
  } catch {
813
813
  }
814
814
  ie();
815
- }, F = n ? p(n) : void 0, J = !n && !A;
815
+ }, R = n ? p(n) : void 0, J = !n && !A;
816
816
  return /* @__PURE__ */ m("div", { className: "calque", children: [
817
817
  /* @__PURE__ */ e(
818
818
  "div",
@@ -826,8 +826,8 @@ function Te({ api: o, pont: t }) {
826
826
  {
827
827
  source: t.sourceTexte,
828
828
  actif: J && !I && y === "modifier",
829
- modifiable: Z,
830
- surModification: Q
829
+ modifiable: G,
830
+ surModification: B
831
831
  }
832
832
  ),
833
833
  J && /* @__PURE__ */ m("div", { className: "barre", children: [
@@ -850,7 +850,7 @@ function Te({ api: o, pont: t }) {
850
850
  {
851
851
  type: "button",
852
852
  className: "bouton bouton--principal",
853
- onClick: q,
853
+ onClick: Q,
854
854
  disabled: I,
855
855
  children: "Publier"
856
856
  }
@@ -927,17 +927,17 @@ function Te({ api: o, pont: t }) {
927
927
  })
928
928
  ] })
929
929
  ] }),
930
- n && F && /* @__PURE__ */ m(
930
+ n && R && /* @__PURE__ */ m(
931
931
  "div",
932
932
  {
933
933
  className: "panneau",
934
934
  role: "dialog",
935
- "aria-label": "Modifier " + F.label,
935
+ "aria-label": "Modifier " + R.label,
936
936
  children: [
937
937
  /* @__PURE__ */ m("div", { className: "panneau__tete", children: [
938
938
  /* @__PURE__ */ m("div", { style: { flex: 1 }, children: [
939
- /* @__PURE__ */ e("h2", { className: "panneau__titre", children: F.label }),
940
- F.description && /* @__PURE__ */ e("p", { className: "panneau__sous", children: F.description })
939
+ /* @__PURE__ */ e("h2", { className: "panneau__titre", children: R.label }),
940
+ R.description && /* @__PURE__ */ e("p", { className: "panneau__sous", children: R.description })
941
941
  ] }),
942
942
  /* @__PURE__ */ e(
943
943
  "button",
@@ -952,7 +952,7 @@ function Te({ api: o, pont: t }) {
952
952
  ] }),
953
953
  /* @__PURE__ */ m("div", { className: "panneau__corps", children: [
954
954
  S && /* @__PURE__ */ e("p", { className: "message message--" + S.ton, children: S.texte }),
955
- F.fields.map((c) => /* @__PURE__ */ e(
955
+ R.fields.map((c) => /* @__PURE__ */ e(
956
956
  ce,
957
957
  {
958
958
  champ: c,
@@ -991,7 +991,7 @@ function Te({ api: o, pont: t }) {
991
991
  )
992
992
  ] });
993
993
  }
994
- const Oe = `
994
+ const Le = `
995
995
  :host {
996
996
  all: initial;
997
997
  --fond: #16181d;
@@ -1113,69 +1113,98 @@ const Oe = `
1113
1113
 
1114
1114
  /* --------------------------------------------------- CONNEXION ---------- */
1115
1115
 
1116
- /* Le voile PREND les clics, lui : une boite de dialogue qui demande un mot de
1117
- passe ne doit pas laisser cliquer la page derriere elle. C'est l'exception
1118
- a la regle du calque, et elle est volontaire. */
1116
+ /* LA CONNEXION EST CLAIRE, AUX COULEURS DE LYSTECH. L'éditeur reste un outil
1117
+ sombre qui s'efface derrière le travail ; la connexion, elle, est l'instant
1118
+ où quelqu'un décide de faire confiance. Il doit y reconnaître Lystech — la
1119
+ fleur, son pétrole et son turquoise, sur du blanc — et non une boîte noire
1120
+ posée sur son site.
1121
+
1122
+ Le thème se redéfinit ICI, sur le voile : les boutons, messages et champs
1123
+ partagés avec l'éditeur suivent ces variables sans une règle de plus, et
1124
+ l'éditeur garde les siennes. Clair quel que soit le thème du système :
1125
+ c'est un choix de marque. */
1119
1126
  .voile {
1127
+ --fond: #ffffff;
1128
+ --fond-clair: #f4f7f8;
1129
+ --bord: #dfe6e9;
1130
+ --texte: #0b1f26;
1131
+ --texte-doux: #52666f;
1132
+ --petrole: #084050;
1133
+ --petrole-survol: #0b5468;
1134
+ --turquoise: #10b8b0;
1135
+ --focus: #0c8f89;
1136
+
1120
1137
  position: fixed;
1121
1138
  inset: 0;
1122
1139
  display: flex;
1123
1140
  align-items: center;
1124
1141
  justify-content: center;
1125
1142
  padding: 16px;
1126
- background: rgba(8, 10, 14, 0.62);
1127
- backdrop-filter: blur(2px);
1143
+ /* Le voile PREND les clics, lui : une boîte de dialogue qui demande une
1144
+ identité ne doit pas laisser cliquer la page derrière elle. C'est
1145
+ l'exception à la règle du calque, et elle est volontaire. Teinté pétrole
1146
+ plutôt que noir : on assombrit le site sans l'éteindre. */
1147
+ background: rgba(8, 44, 56, 0.34);
1148
+ backdrop-filter: blur(4px) saturate(115%);
1149
+ color: var(--texte);
1128
1150
  }
1129
1151
 
1130
1152
  .fenetre {
1131
1153
  position: relative;
1132
- width: min(408px, 100%);
1154
+ width: min(400px, 100%);
1133
1155
  max-height: 92vh;
1134
1156
  overflow-y: auto;
1135
- padding: 30px 28px 20px;
1136
- border: 1px solid var(--bord);
1137
- border-radius: 18px;
1138
- /* Une lueur d'accent dans le coin superieur : de la presence, sans le
1139
- degrade violet-bleu qu'on voit sur une page d'accueil sur deux. */
1157
+ padding: 34px 30px 26px;
1158
+ border: 1px solid rgba(8, 64, 80, 0.10);
1159
+ border-radius: 20px;
1160
+ /* La lueur turquoise de la fleur, à peine, en haut de la carte. */
1140
1161
  background:
1141
- radial-gradient(120% 90% at 50% -20%, rgba(59, 165, 141, 0.16), transparent 62%),
1162
+ radial-gradient(90% 60% at 50% -12%, rgba(16, 184, 176, 0.13), transparent 70%),
1142
1163
  var(--fond);
1143
- box-shadow: 0 28px 70px rgba(0, 0, 0, 0.55);
1164
+ box-shadow:
1165
+ 0 1px 2px rgba(8, 64, 80, 0.06),
1166
+ 0 28px 64px -18px rgba(8, 44, 56, 0.45);
1144
1167
  text-align: center;
1145
1168
  }
1146
1169
 
1147
1170
  .fenetre__fermer {
1148
- position: absolute; top: 12px; right: 12px;
1149
- width: 30px; height: 30px;
1171
+ position: absolute; top: 14px; right: 14px;
1172
+ width: 32px; height: 32px;
1150
1173
  display: inline-flex; align-items: center; justify-content: center;
1151
- border: 0; border-radius: 8px;
1174
+ border: 0; border-radius: 9px;
1152
1175
  background: transparent; color: var(--texte-doux);
1153
1176
  font: inherit; font-size: 14px; cursor: pointer;
1154
1177
  }
1155
1178
  .fenetre__fermer:hover { background: var(--fond-clair); color: var(--texte); }
1179
+ .fenetre__fermer:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
1156
1180
 
1157
1181
  /* ------------------------------------------------------------ MARQUE ---- */
1158
1182
 
1159
1183
  .marque {
1160
- display: inline-flex; align-items: center; gap: 8px;
1184
+ display: inline-flex; flex-direction: column; align-items: center; gap: 8px;
1161
1185
  margin-bottom: 18px;
1162
1186
  }
1163
- .marque img { width: 22px; height: 22px; display: block; }
1187
+ .marque img {
1188
+ width: 44px; height: 44px; display: block;
1189
+ filter: drop-shadow(0 6px 14px rgba(16, 184, 176, 0.28));
1190
+ }
1164
1191
  .marque__mot {
1165
- font-size: 12px; font-weight: 600;
1166
- letter-spacing: 0.18em; text-transform: uppercase;
1167
- color: #6fd3bd;
1192
+ font-size: 11.5px; font-weight: 700;
1193
+ letter-spacing: 0.24em; text-transform: uppercase;
1194
+ color: var(--petrole);
1168
1195
  }
1169
1196
 
1170
1197
  .fenetre__titre {
1171
- margin: 0 0 6px;
1172
- font-size: 20px; font-weight: 640; letter-spacing: -0.01em;
1198
+ margin: 0 0 8px;
1199
+ font-size: 21px; font-weight: 700; letter-spacing: -0.015em;
1173
1200
  color: var(--texte);
1201
+ text-wrap: balance;
1174
1202
  }
1175
1203
  .fenetre__sous {
1176
- margin: 0 auto 22px;
1177
- max-width: 30ch;
1178
- font-size: 13px; line-height: 1.5; color: var(--texte-doux);
1204
+ margin: 0 auto 24px;
1205
+ max-width: 36ch;
1206
+ font-size: 13.5px; line-height: 1.55; color: var(--texte-doux);
1207
+ text-wrap: balance;
1179
1208
  }
1180
1209
  .fenetre__corps { text-align: left; }
1181
1210
 
@@ -1185,27 +1214,46 @@ const Oe = `
1185
1214
 
1186
1215
  .fournisseur {
1187
1216
  display: flex; align-items: center; justify-content: center; gap: 10px;
1188
- width: 100%; padding: 12px 16px;
1189
- border: 1px solid transparent; border-radius: 10px;
1217
+ width: 100%; min-height: 46px; padding: 12px 16px;
1218
+ border: 1px solid transparent; border-radius: 12px;
1190
1219
  font: inherit; font-size: 14px; font-weight: 600;
1191
1220
  cursor: pointer;
1192
- transition: transform 90ms ease, filter 90ms ease;
1221
+ transition: transform 90ms ease, background-color 120ms ease, box-shadow 120ms ease;
1193
1222
  }
1194
- .fournisseur:hover { filter: brightness(1.06); }
1195
1223
  .fournisseur:active { transform: translateY(1px); }
1196
- .fournisseur:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
1197
- .fournisseur[disabled] { opacity: 0.55; cursor: default; transform: none; filter: none; }
1224
+ .fournisseur:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
1225
+ .fournisseur[disabled] { opacity: 0.55; cursor: default; transform: none; }
1198
1226
  .fournisseur .logo { width: 18px; height: 18px; flex: none; display: block; }
1199
1227
 
1200
1228
  /* LES COULEURS DE CHAQUE MARQUE, telles qu'elles les publient. Un bouton
1201
1229
  Google repeint aux couleurs du site devient moins reconnaissable — et un
1202
- bouton de connexion qu'on ne reconnait pas est un bouton sur lequel on
1203
- hesite a cliquer. */
1204
- .fournisseur--google { background: #fff; color: #1f1f1f; border-color: #dadce0; }
1230
+ bouton de connexion qu'on ne reconnaît pas est un bouton sur lequel on
1231
+ hésite à cliquer. */
1232
+ .fournisseur--google {
1233
+ background: #fff; color: #1f1f1f; border-color: #dadce0;
1234
+ box-shadow: 0 1px 2px rgba(8, 64, 80, 0.06);
1235
+ }
1236
+ .fournisseur--google:hover:not([disabled]) { background: #f6f9fa; border-color: #c9d3d8; }
1205
1237
  .fournisseur--facebook { background: #1877f2; color: #fff; }
1238
+ .fournisseur--facebook:hover:not([disabled]) { background: #166fe5; }
1206
1239
 
1207
1240
  .bouton--large { width: 100%; padding: 12px 16px; font-size: 14px; }
1208
1241
 
1242
+ /* Les boutons et messages PARTAGÉS avec l'éditeur, en version claire. */
1243
+ .voile .bouton {
1244
+ min-height: 44px; border-radius: 12px;
1245
+ background: #fff; color: var(--texte); border-color: #cfd9dd;
1246
+ }
1247
+ .voile .bouton:hover { background: var(--fond-clair); }
1248
+ .voile .bouton:focus-visible { outline-color: var(--focus); }
1249
+ .voile .bouton--principal { background: var(--petrole); border-color: var(--petrole); color: #fff; }
1250
+ .voile .bouton--principal:hover { background: var(--petrole-survol); }
1251
+
1252
+ .voile .message { font-size: 13px; line-height: 1.5; border-radius: 10px; }
1253
+ .voile .message--erreur { background: #fdf0ee; border-color: #f4c7bf; color: #a3321f; }
1254
+ .voile .message--ok { background: #e8f7f5; border-color: #a9e2dc; color: #0a5c57; }
1255
+ .voile .message--info { background: var(--fond-clair); border-color: var(--bord); color: #3a5159; }
1256
+
1209
1257
  @media (prefers-reduced-motion: reduce) {
1210
1258
  .fournisseur { transition: none; }
1211
1259
  }
@@ -1293,7 +1341,7 @@ input:focus, select:focus, textarea:focus {
1293
1341
  @media (prefers-reduced-motion: reduce) {
1294
1342
  * { transition: none !important; animation: none !important; }
1295
1343
  }
1296
- `, Pe = `
1344
+ `, Oe = `
1297
1345
  /* --------------------------------------------------------- CHOIX -------- */
1298
1346
 
1299
1347
  /* Quand un meme texte vient de plusieurs cles, on demande laquelle plutot que
@@ -1343,7 +1391,7 @@ input:focus, select:focus, textarea:focus {
1343
1391
  max-width: min(460px, calc(100vw - 24px));
1344
1392
  }
1345
1393
  .flottant .message { margin: 0; box-shadow: 0 8px 26px rgba(0,0,0,.4); }
1346
- `, Me = `
1394
+ `, Pe = `
1347
1395
  /* ON NE DOIT JAMAIS SE DEMANDER SI ON EST EN MODE EDITION. Une barre en bas
1348
1396
  se confond avec un bandeau de temoins ; un lisere qui borde tout l'ecran,
1349
1397
  present sur chaque page, ne se confond avec rien. Il ne prend aucun clic. */
@@ -1371,13 +1419,13 @@ input:focus, select:focus, textarea:focus {
1371
1419
  discrete le reste du temps — c'est le geste qu'on fait une fois. */
1372
1420
  .bouton--sortie { color: var(--texte-doux); background: transparent; border-color: transparent; }
1373
1421
  .bouton--sortie:hover { background: rgba(217, 119, 106, 0.16); color: var(--danger); }
1374
- `, Le = "lystech-editeur-hote", Ie = "lystech-connexion-hote";
1422
+ `, Me = "lystech-editeur-hote", Ie = "lystech-connexion-hote";
1375
1423
  function le(o) {
1376
1424
  document.getElementById(o)?.remove();
1377
1425
  const t = document.createElement("div");
1378
- t.id = o, document.body.appendChild(t);
1426
+ t.id = o, t.style.position = "relative", t.style.zIndex = "2147483000", document.body.appendChild(t);
1379
1427
  const a = t.attachShadow({ mode: "open" }), r = document.createElement("style");
1380
- r.textContent = Oe + Pe + Me, a.appendChild(r);
1428
+ r.textContent = Le + Oe + Pe, a.appendChild(r);
1381
1429
  const d = document.createElement("div");
1382
1430
  return a.appendChild(d), { hote: t, point: d };
1383
1431
  }
@@ -1414,13 +1462,13 @@ function Ue({
1414
1462
  const n = ue(l, d);
1415
1463
  return n;
1416
1464
  }
1417
- function Fe({
1465
+ function Re({
1418
1466
  jeton: o,
1419
1467
  site: t,
1420
1468
  apiBaseUrl: a,
1421
1469
  pont: r
1422
1470
  }) {
1423
- const { hote: d, point: s } = le(Le), l = se(s);
1471
+ const { hote: d, point: s } = le(Me), l = se(s);
1424
1472
  return l.render(
1425
1473
  /* @__PURE__ */ e(
1426
1474
  Te,
@@ -1438,5 +1486,5 @@ function Fe({
1438
1486
  }
1439
1487
  export {
1440
1488
  Ue as monterConnexion,
1441
- Fe as monterEditeur
1489
+ Re as monterEditeur
1442
1490
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lystech/sections",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Contenu de site editable par le client — lecture legere, edition chargee a la demande.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",