@lystech/sections 0.5.1 → 0.6.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.
- package/README.md +20 -2
- package/dist/editeur/ChampsEnPlace.d.ts +15 -0
- package/dist/editeur/TexteEnPlace.d.ts +7 -4
- package/dist/editeur/styles.d.ts +1 -1
- package/dist/editeur.js +801 -553
- package/dist/index.d.ts +1 -1
- package/dist/index.js +91 -87
- package/dist/useSection.d.ts +21 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ JavaScript et 1,2 Mo de CSS. Une clinique qui veut changer trois textes n'a
|
|
|
10
10
|
aucune raison de charger un magasin, un panier et PayPal — et beaucoup de sites
|
|
11
11
|
clients sont en React 19.
|
|
12
12
|
|
|
13
|
-
Ce paquet pèse **
|
|
13
|
+
Ce paquet pèse **11 Ko** en lecture (4,4 Ko compressé) et ne dépend que de
|
|
14
14
|
React. `core` le réexporte, pour qu'une boutique qui l'a déjà n'ait rien de
|
|
15
15
|
plus à installer.
|
|
16
16
|
|
|
@@ -59,7 +59,7 @@ une version anglaise oubliée vaut mieux affichée en français qu'absente.
|
|
|
59
59
|
|
|
60
60
|
La personne qui édite ouvre SON site avec un jeton dans l'adresse. Le paquet le
|
|
61
61
|
détecte, le retire aussitôt de la barre d'adresse, et charge l'interface
|
|
62
|
-
d'édition —
|
|
62
|
+
d'édition — 24 Ko compressés qu'aucun visiteur ne télécharge jamais, parce que le
|
|
63
63
|
`import()` qui y mène n'est atteint que s'il y a un jeton.
|
|
64
64
|
|
|
65
65
|
Elle voit alors son site, ses polices, sa mise en page, avec chaque bloc
|
|
@@ -77,6 +77,24 @@ return <section {...ancrage}>…</section>;
|
|
|
77
77
|
|
|
78
78
|
Hors édition, c'est un attribut `data-` inerte : aucun poids, aucun effet.
|
|
79
79
|
|
|
80
|
+
### Corriger un prix sur place : `champ`
|
|
81
|
+
|
|
82
|
+
Un texte traduit se retrouve tout seul dans la page. Un prix, non : « 85 $ » ne
|
|
83
|
+
dit pas que ce 85 est le prix de la séance. Le site pose `champ(…)` sur
|
|
84
|
+
l'élément qui ne contient QUE la valeur :
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
const { contenu, champ } = useSection("tarifs", { defaut });
|
|
88
|
+
return <p><span {...champ("seance")}>{contenu.seance}</span> $</p>;
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
En mode « modifier », un clic sur la valeur ouvre une saisie posée dessus :
|
|
92
|
+
Entrée enregistre le brouillon, Échap annule, et la page montre aussitôt la
|
|
93
|
+
nouvelle valeur. Un champ qui ne se saisit pas sur une ligne (image, liste,
|
|
94
|
+
texte riche) ouvre plutôt le panneau de son bloc. Si le format vient d'une
|
|
95
|
+
traduction (« {{amount}} $ »), découpez-le autour de la valeur au lieu de
|
|
96
|
+
rendre la phrase d'un bloc : seul le nombre doit porter `champ`.
|
|
97
|
+
|
|
80
98
|
### Trois états, jamais confondus
|
|
81
99
|
|
|
82
100
|
| | Qui le voit |
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { TypeDeChamp } from '../types';
|
|
2
|
+
export type InfoChamp = {
|
|
3
|
+
libelle: string;
|
|
4
|
+
type: TypeDeChamp;
|
|
5
|
+
valeur: unknown;
|
|
6
|
+
};
|
|
7
|
+
export declare function ChampsEnPlace({ actif, lire, enregistrer, ouvrirPanneau, }: {
|
|
8
|
+
/** Faux hors du mode « modifier », ou pendant qu'un panneau est ouvert. */
|
|
9
|
+
actif: boolean;
|
|
10
|
+
/** Ce qu'on sait de ce champ — null s'il n'appartient à aucun bloc déclaré. */
|
|
11
|
+
lire: (blockType: string, champ: string) => InfoChamp | null;
|
|
12
|
+
/** Enregistre la valeur dans le brouillon du bloc ; faux si ça a échoué. */
|
|
13
|
+
enregistrer: (blockType: string, champ: string, valeur: unknown) => Promise<boolean>;
|
|
14
|
+
ouvrirPanneau: (blockType: string) => void;
|
|
15
|
+
}): import("react").JSX.Element | null;
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { SourceTexte } from '../sourceTexte';
|
|
2
|
-
export declare function TexteEnPlace({ source, actif,
|
|
2
|
+
export declare function TexteEnPlace({ source, actif, pertinence, surModification, }: {
|
|
3
3
|
source: SourceTexte;
|
|
4
4
|
/** Faux pendant qu'un panneau est ouvert : on ne veut pas deux modes. */
|
|
5
5
|
actif: boolean;
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* 0 : ce texte n'a aucun bloc où s'enregistrer — on ne le repère pas.
|
|
8
|
+
* Au-delà, plus c'est haut, plus il est proche de la page affichée : un
|
|
9
|
+
* même texte présent sur deux pages (« Séances et tarifs ») se corrige
|
|
10
|
+
* d'office sur la page qu'on regarde, sans demander lequel. Change quand
|
|
11
|
+
* le catalogue arrive : avant lui, rien n'est repéré — le bon défaut.
|
|
9
12
|
*/
|
|
10
|
-
|
|
13
|
+
pertinence: (ns: string, chemin: string) => number;
|
|
11
14
|
surModification: (ns: string, chemin: string, langue: string, valeur: string) => void | Promise<void>;
|
|
12
15
|
}): import("react").JSX.Element | null;
|
package/dist/editeur/styles.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
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
|
-
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";
|
|
2
|
+
export declare const CSS_EN_PLACE = "\n/* --------------------------------------------------------- SAISIE ------- */\n\n/* Une valeur marqu\u00E9e par le site (un prix, un num\u00E9ro) se corrige dans une\n saisie pos\u00E9e EXACTEMENT dessus, dans la police de la page : on \u00E9crit l\u00E0 o\u00F9\n on lisait. Le libell\u00E9 au-dessus dit quel champ on touche \u2014 \u00AB S\u00E9ance\n d'acupuncture \u00BB, pas \u00AB seance \u00BB. */\n.saisie {\n position: fixed;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n}\n.saisie__libelle,\n.saisie__aide,\n.saisie__erreur {\n padding: 3px 8px;\n border-radius: 6px;\n font: 600 11px/1.35 ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif;\n white-space: nowrap;\n}\n.saisie__libelle { background: var(--fond); color: var(--texte); }\n.saisie__aide { background: rgba(22, 24, 29, 0.82); color: var(--texte-doux); font-weight: 500; }\n.saisie__erreur { background: #b3261e; color: #fff; }\n.saisie__champ {\n min-width: 0;\n padding: 2px 8px;\n border: 2px solid var(--accent);\n border-radius: 6px;\n background: #fff;\n color: #111;\n line-height: 1.2;\n box-shadow: 0 10px 28px rgba(0, 0, 0, 0.28);\n outline: none;\n}\n.saisie__champ:focus { box-shadow: 0 0 0 3px rgba(59, 165, 141, 0.35), 0 10px 28px rgba(0, 0, 0, 0.28); }\n.saisie__champ:disabled { opacity: 0.7; }\n\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";
|