/* Opinion Pro — feuille de style maison (aucune dépendance externe) */

:root {
  --primary: #4f46e5;
  --primary-dark: #4338ca;
  --primary-light: #eef2ff;
  --star: #f59e0b;
  --ink: #111827;
  --muted: #6b7280;
  --line: #e5e7eb;
  --bg: #f7f7fb;
  --surface: #ffffff;
  --success: #059669;
  --success-bg: #ecfdf5;
  --danger: #dc2626;
  --danger-bg: #fef2f2;
  --radius: 14px;
  --card-pad: 20px;
  --shadow: 0 1px 2px rgba(16, 24, 40, .05), 0 8px 24px rgba(16, 24, 40, .06);
}

* { box-sizing: border-box; }

/* `hidden` doit gagner : sinon un `display` pose par une classe (.btn) l'annule */
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  background: var(--bg);
  color: var(--ink);
  line-height: 1.55;
  /* un lien ou un mot tres long coupe plutot que d'elargir la page */
  overflow-wrap: break-word;
}

img { max-width: 100%; }

a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }

.container { max-width: 1080px; margin: 0 auto; padding: 0 20px; }
.narrow { max-width: 560px; }

/* ---------- Navigation ---------- */
.navbar {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 20;
}
.navbar .container {
  display: flex; align-items: center; gap: 18px;
  min-height: 62px; flex-wrap: wrap;
}
.brand {
  font-weight: 800; font-size: 1.15rem; color: var(--ink);
  display: flex; align-items: center; gap: 8px;
}
.brand:hover { text-decoration: none; }
.brand span { color: var(--primary); }
.nav-links { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.nav-links a { padding: 8px 12px; border-radius: 8px; color: var(--muted); font-weight: 500; }
.nav-links a:hover { background: var(--primary-light); color: var(--primary); text-decoration: none; }
/* un lien stylise en bouton garde le texte blanc du bouton */
.nav-links a.btn, .nav-links a.btn:hover { color: #fff; background: var(--primary); }
.nav-links a.btn:hover { background: var(--primary-dark); }
.nav-form { display: inline-flex; }

/* ---------- Titres & texte ---------- */
h1 { font-size: 1.9rem; margin: 0 0 6px; letter-spacing: -.02em; }
h2 { font-size: 1.3rem; margin: 0 0 14px; }
h3 { font-size: 1.05rem; margin: 0 0 8px; }
.page-head { margin: 28px 0 20px; display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
.page-head .grow { flex: 1; min-width: 240px; }
.subtitle { color: var(--muted); margin: 0; }
.muted { color: var(--muted); }
/* `anywhere` et non `break-word` : seul le premier reduit vraiment la largeur
   minimale de l'element, donc empeche une URL sans espace d'elargir la page */
code { font-size: .9em; overflow-wrap: anywhere; }
.small { font-size: .875rem; }
.center { text-align: center; }

/* ---------- Cartes ---------- */
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: var(--card-pad); box-shadow: var(--shadow);
}
/* l'empilement vertical est gere par .stack : pas de marge automatique entre
   cartes, sinon les cellules d'une .grid se retrouvent decalees entre elles */
.grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); align-items: start; }
.stack > * + * { margin-top: 16px; }

/* Deux colonnes (colonne laterale + contenu). Elles s'empilent des que la somme
   des largeurs minimales ne tient plus : sinon la page deborde horizontalement. */
.grid-split { grid-template-columns: minmax(260px, 1fr) minmax(320px, 1.4fr); }
.grid-split-lg { grid-template-columns: minmax(240px, 1fr) minmax(320px, 2fr); }
/* `minmax(0, 1fr)` et non `1fr` : sinon la colonne s'elargit jusqu'au contenu le
   moins compressible qu'elle abrite, et c'est toute la page qui deborde. */
@media (max-width: 760px) {
  .grid-split, .grid-split-lg { grid-template-columns: minmax(0, 1fr); }
}

/* Fiche profil. Les blocs sont des enfants directs de la grille — et non deux
   colonnes imbriquees — pour que l'ordre du HTML soit celui du mobile :
   note du mois, puis formulaire d'avis, puis partage, puis historique.
   Sur grand ecran, chacun est replace ici : le formulaire a droite, le reste
   a gauche, dans l'ordre habituel. */
.profil-grid {
  display: grid; gap: 16px; align-items: start;
  grid-template-columns: minmax(260px, 1fr) minmax(320px, 1.4fr);
}
.profil-grid > .bloc-note { grid-column: 1; grid-row: 1; }
.profil-grid > .bloc-partage { grid-column: 1; grid-row: 2; }
.profil-grid > .bloc-historique { grid-column: 1; grid-row: 3; }
.profil-grid > .bloc-avis { grid-column: 2; grid-row: 1 / -1; align-self: start; }

@media (max-width: 760px) {
  .profil-grid { grid-template-columns: minmax(0, 1fr); }
  /* Une seule colonne : on rend la main au flux du document. Il faut rappeler
     chaque classe — une media query n'ajoute aucune spécificité, et `> *` perdrait
     contre les `> .bloc-…` ci-dessus, laissant le formulaire dans une 2e colonne. */
  .profil-grid > .bloc-note,
  .profil-grid > .bloc-avis,
  .profil-grid > .bloc-partage,
  .profil-grid > .bloc-historique { grid-column: 1; grid-row: auto; }
}

.profile-card { display: flex; flex-direction: column; height: 100%; }
.profile-card .avatar { margin-bottom: 12px; }
.profile-card .card-footer {
  margin-top: auto; padding-top: 14px; border-top: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}

/* Carte façon fil d'actualité : la photo occupe toute la largeur de la carte.
   Les marges négatives valent la même chose que le padding, d'où --card-pad. */
.feed-card { overflow: hidden; }
.feed-photo {
  display: block; margin: calc(var(--card-pad) * -1) calc(var(--card-pad) * -1) 14px;
  background: var(--primary-light); line-height: 0;
}
.feed-photo:hover { text-decoration: none; }
/* Format portrait (3:4) : c'est le cadrage d'une photo de personne. `aspect-ratio`
   plutôt qu'une hauteur fixe, pour que le cadre suive la largeur de la carte. */
.feed-photo img {
  display: block; width: 100%; aspect-ratio: 3 / 4; object-fit: cover;
  transition: transform .25s;
}
.feed-photo:hover img { transform: scale(1.03); }
.feed-photo-empty {
  display: flex; align-items: center; justify-content: center;
  width: 100%; aspect-ratio: 3 / 4; font-size: 3.4rem; font-weight: 800;
  color: var(--primary); line-height: 1;
}
.feed-head h3 a { color: var(--ink); }
.feed-head h3 a:hover { color: var(--primary); }

/* Photo en grand sur la fiche du profil, en portrait elle aussi. Elle est bornée
   en largeur et centrée : en pleine largeur d'écran, un portrait 3:4 ferait une
   image démesurément haute qu'il faudrait faire défiler pour lire le nom. */
.hero-photo {
  display: block; margin: 16px auto 0; max-width: 340px;
  border-radius: var(--radius);
  overflow: hidden; box-shadow: var(--shadow); background: var(--primary-light); line-height: 0;
}
.hero-photo img { display: block; width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }

.avatar {
  width: 64px; height: 64px; border-radius: 50%; object-fit: cover;
  background: var(--primary-light); color: var(--primary);
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 1.4rem; overflow: hidden; flex: none;
}
.avatar-lg { width: 96px; height: 96px; font-size: 2rem; }

/* ---------- Étoiles ---------- */
.stars { color: var(--star); letter-spacing: 1px; white-space: nowrap; font-size: 1rem; }
.stars.lg { font-size: 1.5rem; }
.stars .empty { color: #d1d5db; }
.score { font-weight: 700; font-size: 1.05rem; }
.score-lg { font-size: 2.6rem; font-weight: 800; line-height: 1; letter-spacing: -.03em; }

/* ---------- Répartition ---------- */
.dist-row { display: flex; align-items: center; gap: 10px; font-size: .85rem; margin-bottom: 6px; }
.dist-row .label { width: 42px; color: var(--muted); white-space: nowrap; }
.dist-row .count { width: 32px; text-align: right; color: var(--muted); }
.bar { flex: 1; height: 8px; background: var(--line); border-radius: 99px; overflow: hidden; }
.bar > i { display: block; height: 100%; background: var(--star); border-radius: 99px; }

/* ---------- Statistiques ---------- */
.stat-row { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.stat {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px;
}
.stat .value { font-size: 1.7rem; font-weight: 800; letter-spacing: -.02em; }
.stat .label { color: var(--muted); font-size: .82rem; text-transform: uppercase; letter-spacing: .04em; }

/* ---------- Chiffres cles (bandeau compact) ----------
   Variante resserree de .stat : trois vignettes qui tiennent cote a cote des
   320px, la ou .stat-row (minmax 150px) retomberait a deux colonnes et ferait
   passer la troisieme a la ligne toute seule. minmax(0, 1fr) et non 1fr :
   sinon la colonne s'elargit jusqu'a son contenu le moins compressible. */
/* max-width : sur grand ecran, trois vignettes etirees sur toute la largeur
   font beaucoup de vide autour d'un seul chiffre. Sans effet sous 560px. */
.chiffres-cles {
  display: grid; gap: 8px; grid-template-columns: repeat(3, minmax(0, 1fr));
  max-width: 560px;
}
.chiffres-cles .vignette {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 10px 6px; text-align: center; min-width: 0;
}
.chiffres-cles .valeur { font-size: 1.3rem; font-weight: 800; letter-spacing: -.02em; }
.chiffres-cles .intitule {
  color: var(--muted); font-size: .68rem; text-transform: uppercase;
  letter-spacing: .04em; overflow-wrap: anywhere;
}

/* ---------- Tuiles d'action ----------
   Deux colonnes sur telephone, une seule rangee des que la place le permet.
   `min(150px, 100%)` dans le minmax : sans le min(), une tuile plus large que
   l'ecran forcerait un debordement horizontal au lieu de se resserrer. */
.tuiles-actions {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
}
.tuile {
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  gap: 6px; padding: 16px 10px; text-align: center; min-width: 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--ink); text-decoration: none;
  font-size: .9rem; font-weight: 600; line-height: 1.25;
}
.tuile:hover, .tuile:focus-visible { border-color: var(--primary); background: var(--primary-light); color: var(--primary); }
.tuile .icone { font-size: 1.5rem; line-height: 1; }
.tuile .detail { font-weight: 400; font-size: .78rem; color: var(--muted); }
.tuile:hover .detail, .tuile:focus-visible .detail { color: inherit; }

/* ---------- Badges ---------- */
.badge {
  display: inline-block; padding: 3px 10px; border-radius: 99px;
  font-size: .75rem; font-weight: 600; background: var(--primary-light); color: var(--primary);
}
.badge-muted { background: #f3f4f6; color: var(--muted); }
.badge-success { background: var(--success-bg); color: var(--success); }
.badge-danger { background: var(--danger-bg); color: var(--danger); }
.rank { font-weight: 800; color: var(--muted); width: 28px; display: inline-block; }
.rank-1 { color: var(--star); }

/* ---------- Boutons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 7px; justify-content: center;
  padding: 10px 18px; border-radius: 10px; border: 1px solid transparent;
  background: var(--primary); color: #fff; font-weight: 600; font-size: .93rem;
  cursor: pointer; font-family: inherit; transition: background .15s, box-shadow .15s;
}
.btn:hover { background: var(--primary-dark); text-decoration: none; color: #fff; }
.btn-outline { background: transparent; color: var(--primary); border-color: var(--line); }
.btn-outline:hover { background: var(--primary-light); color: var(--primary-dark); }
.btn-ghost { background: transparent; color: var(--muted); }
.btn-ghost:hover { background: #f3f4f6; color: var(--ink); }
.btn-danger { background: var(--danger); }
.btn-danger:hover { background: #b91c1c; }
.btn-sm { padding: 6px 12px; font-size: .82rem; }
.btn-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }

/* ---------- Formulaires ---------- */
.form-control, select.form-control {
  width: 100%; padding: 10px 12px; border: 1px solid var(--line);
  border-radius: 10px; font-size: .95rem; font-family: inherit;
  background: var(--surface); color: var(--ink);
}
.form-control:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(79, 70, 229, .15);
}
.field { margin-bottom: 16px; }
.field > label { display: block; font-weight: 600; font-size: .9rem; margin-bottom: 6px; }
.field .helptext { display: block; color: var(--muted); font-size: .82rem; margin-top: 4px; }
.field .errorlist { color: var(--danger); font-size: .85rem; margin: 6px 0 0; padding-left: 18px; }
/* `flex-start` et non `center` : une case dont le libellé tient sur deux lignes —
   celui de la politique de confidentialité — verrait sinon sa case flotter au
   milieu du texte. Le décalage de 2px la réaligne sur la première ligne. */
.form-check { display: flex; align-items: flex-start; gap: 8px; }
.form-check-input {
  width: 18px; height: 18px; accent-color: var(--primary);
  flex: none; margin-top: 2px;
}
.form-check label { font-weight: 400; }

/* Notation par étoiles cliquables (RadioSelect rend un <div> par choix) */
div.star-input { display: flex; gap: 8px; flex-wrap: wrap; padding: 0; margin: 0; }
div.star-input > div { flex: none; }
div.star-input label {
  display: block; padding: 8px 14px; border: 1px solid var(--line);
  border-radius: 10px; cursor: pointer; font-weight: 600; font-size: .95rem;
  background: var(--surface); transition: all .15s; white-space: nowrap;
}
div.star-input label:hover { border-color: var(--star); background: #fffbeb; }
div.star-input input { position: absolute; opacity: 0; width: 0; height: 0; }
div.star-input > div:has(input:checked) label {
  background: var(--star); border-color: var(--star); color: #fff;
  box-shadow: 0 2px 8px rgba(245, 158, 11, .35);
}
div.star-input > div:has(input:focus-visible) label { box-shadow: 0 0 0 3px rgba(79, 70, 229, .3); }

/* ---------- Notation en un clic (listes de profils) ---------- */
.quick-rate {
  margin-top: 12px; padding: 10px 12px;
  background: #fffbeb; border: 1px solid #fde68a; border-radius: 10px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
}
.quick-rate-label { font-size: .82rem; color: #92400e; }
.quick-stars { display: flex; gap: 2px; }
.star-btn {
  border: none; background: none; padding: 0 2px; cursor: pointer;
  font-size: 1.45rem; line-height: 1; color: #e5d5b0;
  font-family: inherit; transition: color .12s, transform .12s;
}
.star-btn.on { color: var(--star); }
/* survol : on remplit jusqu'a l'etoile pointee, et on efface l'ancienne note
   pour que l'apercu corresponde vraiment a ce qui sera enregistre */
.quick-stars:hover .star-btn.on { color: #e5d5b0; }
.quick-stars .star-btn:hover,
.quick-stars .star-btn:has(~ .star-btn:hover) { color: var(--star); }
.star-btn:hover { transform: scale(1.15); }
.star-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 4px; }

/* ---------- Barre de recherche ---------- */
.search-bar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.search-bar .form-control { flex: 1; min-width: 200px; }
/* pendant une requete, les resultats palissent legerement : on voit qu'ils bougent
   sans que la page ne saute (la hauteur ne change pas) */
[aria-busy="true"] { opacity: .55; transition: opacity .12s; }

/* ---------- Réactions « J'aime » / « J'adore » ---------- */
.reactions { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
/* Boutons a l'emoji seul : le libelle vit dans title/aria-label */
.react-btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 12px; border-radius: 99px; border: 1px solid var(--line);
  background: var(--surface); color: var(--muted);
  font-family: inherit; font-size: 1.05rem; line-height: 1.2; cursor: pointer;
  transition: border-color .15s, background .15s, color .15s, transform .12s;
}
.react-btn:hover { border-color: var(--primary); background: var(--primary-light); transform: translateY(-1px); }
.react-btn.on { border-color: var(--primary); background: var(--primary-light); }
.react-btn .count {
  font-size: .82rem; font-weight: 700; min-width: 12px; text-align: center;
  font-family: system-ui, sans-serif;
}
.react-btn.on .count { color: var(--primary-dark); }
/* le pouce vers le bas ne se pare pas des couleurs de marque quand il est actif */
.react-down:hover, .react-down.on { border-color: #fca5a5; background: var(--danger-bg); }
.react-down.on .count { color: var(--danger); }
.react-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* ---------- Volets repliés (<details> natifs, sans JavaScript) ----------
   Les boutons sont côte à côte ; celui qu'on ouvre prend toute la ligne grâce à
   `flex-basis: 100%`, et son panneau s'affiche donc en pleine largeur. */
.volets { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-start; }
.volet { flex: 0 0 auto; }
.volet[open] { flex: 1 1 100%; }
/* un `display` autre que `list-item` suffit à retirer le triangle, mais
   Safari a besoin qu'on vise aussi son pseudo-élément */
.volet > summary { cursor: pointer; list-style: none; }
.volet > summary::-webkit-details-marker { display: none; }
.volet > summary:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.volet-corps { margin-top: 10px; }

/* ---------- Partage & QR codes ---------- */
.share-card .qr { width: 170px; height: 170px; display: block; margin: 0 auto; }
.share-card input { text-align: center; font-size: .8rem; }

/* Le lien et son bouton « Copier » côte à côte ; le bouton passe dessous quand
   c'est trop étroit. `min-width: 0` sur le champ, sinon l'URL empêche le flex
   de le rétrécir et la page déborde. */
.copie { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.copie > .form-control { flex: 1 1 180px; min-width: 0; }
.copie > .btn { flex: 0 0 auto; white-space: nowrap; }
.share-card .copie { justify-content: center; }

/* ---------- Texte long dépliable (includes/texte_long.html) ---------- */
.texte-long > summary { display: block; cursor: pointer; list-style: none; }
.texte-long > summary::-webkit-details-marker { display: none; }
/* ouvert, l'aperçu ferait doublon avec le texte entier */
.texte-long[open] > summary .apercu { display: none; }
.texte-long .bascule { display: block; margin-top: 4px; font-size: .85rem;
  font-weight: 600; color: var(--primary); }
.texte-long .bascule::after { content: 'Lire la suite ▾'; }
.texte-long[open] .bascule::after { content: 'Réduire ▴'; }
.texte-long > summary:hover .bascule { text-decoration: underline; }
.texte-long > summary:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }
.texte-entier { overflow-wrap: anywhere; }

/* ---------- Pagination ---------- */
.pagination {
  display: flex; gap: 12px; align-items: center; justify-content: center;
  flex-wrap: wrap; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line);
}
.pagination [aria-disabled] { opacity: .45; cursor: default; }

/* La carte du QR de la boutique : le texte à gauche, le code à droite */
.qr-boutique { display: flex; gap: 20px; align-items: center; margin-top: 20px; }
.qr-boutique .grow { flex: 1; min-width: 0; }
.qr-boutique .qr { width: 150px; height: 150px; flex: none; }

.qr-sheet {
  display: grid; gap: 16px; margin-top: 20px;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}
.qr-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 18px; text-align: center; box-shadow: var(--shadow);
}
.qr-card .qr { width: 100%; max-width: 180px; height: auto; margin: 10px auto 0; display: block; }
.qr-shop { font-size: .75rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.qr-name { font-size: 1.15rem; font-weight: 800; letter-spacing: -.01em; margin-top: 2px; }
.qr-role { color: var(--muted); font-size: .85rem; }
.qr-call { margin-top: 8px; font-size: .85rem; font-weight: 600; color: var(--primary); }

/* ---------- Supervision : graphiques ----------
   Une seule teinte pour toutes les marques de données : ces graphiques disent une
   grandeur (« combien »), pas une identité. Une palette catégorielle ici ne ferait
   que redire la hauteur des barres avec une deuxième couleur.
   Traits fins, grille en filet, remplissages saturés reserves aux petites marques. */
.etiquette { text-transform: uppercase; letter-spacing: .05em; }

.filtre-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 14px var(--card-pad);
}
.filtre-bar label { font-weight: 600; font-size: .9rem; }
.filtre-bar .form-control { width: auto; flex: 1 1 180px; }

/* Colonnes : une par mois, hauteur proportionnelle au nombre d'avis */
.chart-cols { display: flex; align-items: flex-end; gap: 6px; margin-top: 18px; }
.chart-col {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column;
  align-items: center; gap: 6px;
}
.chart-valeur { font-size: .78rem; font-weight: 700; font-variant-numeric: tabular-nums; }
/* les mois ordinaires s'effacent : seuls le sommet et le mois affiché sont annoncés */
.chart-valeur.discret { color: var(--muted); font-weight: 500; }
.chart-fut {
  display: flex; align-items: flex-end; justify-content: center;
  width: 100%; height: 140px;
}
/* pas de `min-height` : un mois sans aucun avis ne doit pas laisser un talon
   qui se lirait comme « presque rien » plutôt que comme « rien » */
.chart-fut > i {
  display: block; width: 100%; max-width: 34px;
  background: var(--primary); border-radius: 4px 4px 0 0;
}
.chart-col.courant .chart-fut > i { background: var(--primary-dark); }
.chart-axe {
  font-size: .72rem; color: var(--muted); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
.chart-col.courant .chart-axe { color: var(--ink); font-weight: 700; }
.chart-axe-seul { margin-top: 6px; align-items: flex-start; }

/* Courbe : échelle fixe 0→5, une seule série, donc pas de légende à porter */
.chart-line { display: flex; gap: 10px; margin-top: 18px; }
.chart-line svg { flex: 1; min-width: 0; height: 120px; }
.chart-echelle {
  display: flex; flex-direction: column; justify-content: space-between;
  font-size: .72rem; color: var(--muted); height: 120px; flex: none;
  font-variant-numeric: tabular-nums;
}
.chart-line .grille { stroke: var(--line); stroke-width: 1; vector-effect: non-scaling-stroke; }
.chart-line .aire { fill: var(--primary); opacity: .1; }
.chart-line .trait {
  fill: none; stroke: var(--primary); stroke-width: 2;
  stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke;
}
/* anneau de la couleur du fond plutôt qu'un contour : les points restent lisibles
   là où ils chevauchent le trait */
.chart-line .point { fill: var(--primary); stroke: var(--surface); stroke-width: 2; opacity: .55; }
.chart-line .point.vif { opacity: 1; r: 5; }

/* Classement : la barre se lit sur l'échelle de notation (0→5), pas sur le maximum */
.rank-row { display: flex; align-items: center; gap: 12px; padding: 10px 0; }
.rank-row + .rank-row { border-top: 1px solid var(--line); }
.rank-corps { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
/* `.bar` porte `flex: 1` pour la répartition des étoiles ; dans cette colonne
   flex, ce `flex-basis: 0` écraserait sa hauteur — on le neutralise */
.rank-corps .bar { flex: none; width: 100%; height: 6px; margin-top: 3px; }
.rank-corps .bar > i { background: var(--primary); }
.rank-chiffres {
  flex: none; text-align: right; display: flex; flex-direction: column; line-height: 1.25;
}

.signaux { list-style: none; margin: 0; padding: 0; }
.signaux li {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 0; font-size: .9rem;
}
.signaux li + li { border-top: 1px solid var(--line); }
.signaux .badge { flex: none; min-width: 34px; text-align: center; font-variant-numeric: tabular-nums; }

details.card > summary { cursor: pointer; }

/* ---------- Avis ---------- */
.review { padding: 16px 0; border-bottom: 1px solid var(--line); }
.review:last-child { border-bottom: none; }
.review-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.review-author { font-weight: 600; }
.review p { margin: 6px 0 0; }
.review.hidden-review { opacity: .55; }

/* ---------- Tableaux ---------- */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: .92rem; }
th, td { padding: 12px 10px; text-align: left; border-bottom: 1px solid var(--line); vertical-align: middle; }
th { font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 700; }
tbody tr:hover { background: #fafafe; }
td.num, th.num { text-align: right; }

/* Cellule « profil » d'un tableau : pastille + nom. Trois precautions, sans
   lesquelles le nom deborde sa colonne et vient se coller au role de la colonne
   voisine — deja serre a 390px, franchement superpose a 320px avec un nom un
   peu long :
   - la pastille ne doit PAS retrecir (flex-shrink par defaut vaut 1), sinon le
     cercle s'ovalise et le nom gagne quand meme trop peu de place ;
   - un enfant de flex a besoin de min-width: 0 pour pouvoir se compresser,
     sinon il impose la largeur de son plus long mot et deborde ;
   - la colonne garde une largeur minimale : le tableau s'elargit alors et
     defile dans son .table-wrap, ce qui est le comportement voulu sur mobile. */
.cellule-profil { display: flex; align-items: center; gap: 10px; min-width: 0; }
.cellule-profil .avatar { flex: 0 0 auto; width: 36px; height: 36px; font-size: .9rem; }
.cellule-profil strong { min-width: 0; overflow-wrap: anywhere; }
th.col-profil, td.col-profil { min-width: 150px; }

/* ---------- Ligne de tableau cliquable, sans JavaScript ----------
   Le HTML n'autorise pas d'envelopper un <tr> dans un <a>, et un `onclick`
   sur la ligne demanderait du script — le projet s'en passe. Chaque cellule
   d'information recoit donc son propre lien de niveau bloc vers la meme page.

   Le point qui compte : la marge interieure DESCEND de la cellule vers le
   lien. En la laissant sur le <td>, les 10px du bord de chaque cellule
   resteraient une bande morte, et la ligne ne serait cliquable qu'au milieu —
   exactement le defaut qu'on cherche a corriger. */
td.cellule-lien { padding: 0; }
.lien-cellule { display: block; padding: 12px 10px; color: inherit; text-decoration: none; }
.lien-cellule:hover { text-decoration: none; }

/* ---------- Messages ---------- */
.messages { margin: 18px 0 0; padding: 0; list-style: none; }
.messages li {
  padding: 12px 16px; border-radius: 10px; margin-bottom: 10px;
  background: var(--primary-light); color: var(--primary-dark); font-size: .92rem;
}
.messages li.success { background: var(--success-bg); color: var(--success); }
.messages li.error { background: var(--danger-bg); color: var(--danger); }

/* ---------- État vide ---------- */
.empty { text-align: center; padding: 48px 20px; color: var(--muted); }
.empty .icon { font-size: 2.5rem; display: block; margin-bottom: 10px; }

/* ---------- Bannière reset mensuel ---------- */
.notice {
  background: linear-gradient(135deg, #eef2ff, #f5f3ff);
  border: 1px solid #ddd6fe; border-radius: var(--radius);
  padding: 14px 18px; font-size: .9rem; color: #4338ca;
  display: flex; gap: 10px; align-items: center;
}
/* sans `min-width: 0`, un enfant de flex refuse de descendre sous sa largeur minimale */
.notice > * { min-width: 0; }
/* une suppression définitive ne se signale pas dans la même couleur qu'une info */
.notice-danger {
  background: #fef2f2; border-color: #fecaca; color: #991b1b;
  align-items: flex-start;
}
.notice-danger a { color: inherit; text-decoration: underline; }
/* ---------- Contact & horaires d'une boutique ---------- */
/* Deux colonnes qui s'empilent d'elles-mêmes : `auto-fit` + `minmax` évitent
   d'écrire une media query, et un seul bloc renseigné occupe toute la largeur. */
.contact-boutique {
  display: grid; gap: 16px 32px;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.contact-bloc h3 { margin-bottom: 6px; font-size: .95rem; }
.contact-ligne { margin: 0 0 4px; font-size: .92rem; }

/* Un bouton de formulaire qui doit se lire comme un lien : le geste est
   secondaire, mais il modifie des données — donc un POST, donc un <button>. */
.lien-bouton {
  background: none; border: 0; padding: 0; font: inherit; font-size: .85rem;
  color: var(--primary); cursor: pointer; text-align: left;
}
.lien-bouton:hover { text-decoration: underline; }
details > summary.lien-bouton { list-style: none; }
details > summary.lien-bouton::-webkit-details-marker { display: none; }

.liste-suppression { margin: 0; padding-left: 20px; font-size: .92rem; }
.liste-suppression li { margin-bottom: 4px; }

/* ---------- Pied de page ---------- */
footer {
  margin-top: 56px; padding: 28px 0; border-top: 1px solid var(--line);
  color: var(--muted); font-size: .87rem; background: var(--surface);
}
footer a { color: var(--muted); text-decoration: underline; }
footer a:hover { color: var(--primary); }

/* ---------- Page légale ---------- */
/* Une page de texte se lit sur une colonne étroite : au-delà d'environ 70
   caractères, l'œil perd le début de la ligne suivante. */
.legal { max-width: 760px; }
.legal h2 { font-size: 1.15rem; margin: 26px 0 8px; }
.legal h2:first-of-type { margin-top: 0; }
.legal h3 { font-size: 1rem; margin: 18px 0 6px; color: var(--primary-dark); }
.legal p { margin: 0 0 12px; }
.legal ul { margin: 0 0 12px; padding-left: 22px; }
.legal li { margin-bottom: 6px; }
.legal table { font-size: .9rem; }

/* ---------- Mobile ----------
   Tout s'empile a la verticale : rien ne doit deborder sur le cote, la page ne
   defile que vers le bas. Ce qui reste large par nature (tableaux, planche de QR)
   defile a l'interieur de son propre cadre. */
@media (max-width: 640px) {
  h1 { font-size: 1.5rem; }
  h2 { font-size: 1.15rem; }
  :root { --card-pad: 16px; }
  .container { padding: 0 14px; }

  /* Navigation : la marque sur sa ligne, puis les liens qui se partagent
     toute la largeur a parts egales — une seule rangee, pas de retour a la ligne */
  .navbar .container {
    flex-direction: column; align-items: stretch;
    gap: 8px; padding: 10px 14px; min-height: 0;
  }
  .brand { justify-content: center; font-size: 1.05rem; }
  .nav-links {
    width: 100%; margin-left: 0; gap: 6px;
    flex-wrap: nowrap; align-items: stretch;
  }
  /* `flex: 1 1 0` : les items se partagent la largeur a parts strictement egales,
     quelle que soit la longueur de leur libelle */
  .nav-links > *, .nav-form { flex: 1 1 0; min-width: 0; }
  .nav-links a, .nav-form .btn {
    display: flex; width: 100%; height: 100%;
    align-items: center; justify-content: center; text-align: center;
    padding: 8px 4px; font-size: .8rem; line-height: 1.2;
    /* un libelle trop long passe a la ligne DANS son propre bouton plutot que
       d'etre tronque ou de renvoyer l'item suivant a la ligne suivante */
    white-space: normal;
  }
  .nav-court { display: none; } /* « ma boutique », « (demo) » : superflu sur mobile */

  /* Fiche profil : photo, note, partage, formulaire, avis — les uns sous les autres */
  .page-head { flex-direction: column; align-items: stretch; gap: 12px; }
  .page-head .avatar { align-self: center; }
  /* le portrait garde son ratio ; on borne seulement sa largeur */
  .hero-photo { max-width: 260px; }
  .share-card .qr { width: 100%; max-width: 200px; height: auto; }

  /* Les rangees d'actions restent lisibles plutot que de se tasser */
  .btn-row { width: 100%; }
  .btn-row > .btn { flex: 1 1 auto; }
  .search-bar .btn { flex: 1 1 auto; }
  .stat-row { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); }
  .quick-rate { justify-content: center; }
  .reactions { justify-content: space-between; }
  .qr-sheet { grid-template-columns: 1fr; }
  /* le QR passe au-dessus du texte, et les volets prennent toute la largeur */
  .qr-boutique { flex-direction: column-reverse; text-align: center; }
  .qr-boutique .btn-row { justify-content: center; }
  .volet, .volet > summary { width: 100%; }

  /* Un tableau est large par nature : plutot que de tasser ses colonnes, on le
     laisse defiler horizontalement DANS son cadre (.table-wrap). La page, elle,
     ne defile que vers le bas. */
  /* les graphiques se resserrent au lieu de forcer un defilement lateral */
  .chart-cols { gap: 3px; }
  .chart-fut { height: 110px; }
  .chart-valeur { font-size: .68rem; }
  .chart-axe { font-size: .62rem; }
  .filtre-bar .form-control, .filtre-bar .btn { flex: 1 1 100%; width: 100%; }

  .table-wrap { -webkit-overflow-scrolling: touch; }
  .table-wrap table { min-width: 460px; }
  th, td { padding: 10px 8px; }
  /* la cellule cliquable garde une marge nulle : c'est son lien qui la porte,
     sinon la ligne cesse d'etre cliquable sur ses bords (voir .lien-cellule) */
  td.cellule-lien { padding: 0; }
  .lien-cellule { padding: 10px 8px; }
}

/* ---------- Impression (planche de QR codes) ---------- */
@media print {
  .navbar, footer, .no-print, .messages { display: none !important; }
  body { background: #fff; }
  .container { max-width: none; padding: 0; }
  .qr-sheet { grid-template-columns: repeat(2, 1fr); gap: 10mm; }
  .qr-card { break-inside: avoid; box-shadow: none; }
}
