/* =============================================================================
   components.css — briques réutilisables sur tout le site public + admin
   ========================================================================== */

/* --- Boutons ------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  padding: 16px 26px;
  font-size: 14px;
  letter-spacing: .03em;
  border: 1px solid transparent;
  cursor: pointer;
  background: none;
  text-align: center;
}
.btn-primary { background: var(--color-text); color: var(--color-bg); }
.btn-primary:hover { background: #0f1c2e; color: var(--color-bg); }
.btn-accent { background: var(--color-accent-deep); color: var(--color-bg); }
.btn-accent:hover { background: #6a8f8b; color: var(--color-bg); }
.btn-outline { border-color: var(--color-border); color: var(--color-text); background: transparent; }
.btn-outline:hover { border-color: var(--color-text); color: var(--color-text); }
.btn-block { width: 100%; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }

/* --- Badges ---------------------------------------------------------------*/
.badge {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .1em;
  padding: 5px 9px;
  background: var(--color-accent-deep);
  color: var(--color-bg);
}
.badge-dark { background: var(--color-text); }

/* --- Nav publique ---------------------------------------------------------*/
/* Barre flottante, qui reste visible quand on descend dans la page : le menu,
   le nom de l'atelier et le panier restent à portée sans avoir à remonter.
   `sticky` plutôt que `fixed` : la barre garde sa place dans le flux, donc le
   contenu n'a pas besoin d'être décalé d'une hauteur écrite en dur, qui se
   désynchroniserait au premier changement de taille de police ou de logo.
   Elle reste un élément positionné, le menu mobile déroulant en dessous
   continue donc de s'ancrer sur elle.

   Marge extérieure et retrait intérieur s'additionnent pour retomber sur
   var(--space-lg), la marge de tout le contenu du site : le nom de l'atelier
   reste donc aligné avec les titres des sections en dessous.

   Fond volontairement plus clair que la page : posée sur un aplat de la même
   couleur, la barre ne se distinguerait que par son ombre. Angles droits, le
   design n'utilise aucun arrondi (voir --radius dans tokens.css). */
.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 14px var(--space-sm);
  padding: 18px var(--space-md);
  border: 1px solid var(--color-border);
  background: var(--color-input-bg);
  box-shadow: var(--shadow-entete);
  position: sticky;
  top: 14px;
  z-index: 50;
}
.site-header .brand {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-title);
  font-size: 19px;
  /* Sans cette ligne, le nom hérite de la couleur des liens (vert) alors
     qu'il doit être en bleu marine, comme dans la maquette. */
  color: var(--color-text);
}
.site-header .brand:hover { color: var(--color-accent-deep); }
.site-header .brand img { width: 38px; height: 38px; object-fit: contain; flex: 0 0 auto; }
.site-nav { display: flex; align-items: center; gap: 34px; font-size: 14px; }
.site-nav a { color: var(--color-text); }
.site-nav a.active { border-bottom: 1px solid var(--color-text); padding-bottom: 2px; }
.cart-pill {
  padding: 9px 16px;
  background: var(--color-accent-deep);
  color: var(--color-bg);
  font-size: 13px;
  letter-spacing: .04em;
  transition: background-color .2s ease;
}
/* Le panier s'assombrit au survol : c'est le seul bouton d'action de la barre,
   il doit répondre sous la souris. Même teinte que le survol de .btn-accent,
   pour que les deux se comportent pareil. */
.cart-pill:hover { background: #6a8f8b; color: var(--color-bg); }
@media (prefers-reduced-motion: reduce) {
  .cart-pill { transition: none; }
}
/* Zone cliquable de 44px minimum (recommandation d'accessibilité tactile),
   tout en gardant l'apparence de deux traits fins de la maquette. */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  width: 44px;
  height: 44px;
  padding: 0 10px;
  margin-right: -10px;
  background: none;
  border: none;
  cursor: pointer;
}
.nav-toggle span { display: block; height: 2px; width: 100%; background: var(--color-text); }

@media (max-width: 900px) {
  .site-nav { display: none; }
  .nav-toggle { display: flex; }
  /* Le menu déroulant prolonge la barre flottante vers le bas : même fond,
     mêmes bords, même ombre, pour qu'ils forment un seul bloc. Les -1px
     alignent ses bords latéraux sur ceux de la barre, dont le trait passerait
     sinon à un pixel à côté. */
  .site-nav.is-open {
    display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
    position: absolute; top: 100%; left: -1px; right: -1px;
    background: var(--color-input-bg);
    padding: var(--space-sm) var(--space-md);
    border: 1px solid var(--color-border); border-top: none;
    box-shadow: var(--shadow-entete);
    z-index: 20;
  }
}
/* Sur téléphone, une barre qui ne disparaît jamais prend une part notable de
   l'écran, et 40px de marge de chaque côté rognent une largeur précieuse.
   On resserre les deux. */
@media (max-width: 640px) {
  .site-header {
    margin: 10px;
    padding: 12px var(--space-sm);
    top: 10px;
  }
}

/* --- Footer ---------------------------------------------------------------*/
.site-footer {
  background: var(--color-text);
  color: rgba(244, 237, 222, .85);
  padding: var(--space-xl) var(--space-lg);
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 56px;
}
.site-footer .brand { display: flex; align-items: center; gap: 14px; font-family: var(--font-title); font-size: 22px; color: var(--color-bg); }
.site-footer .brand img { width: 46px; height: 46px; object-fit: contain; }
.site-footer h5 { color: var(--color-accent); font-size: 12px; letter-spacing: .16em; text-transform: uppercase; font-family: var(--font-mono); margin-bottom: 6px; }
/* "Atelier" et "Showroom" mènent à la page Contact. Le lien reprend la couleur
   du titre (sinon il hériterait du vert des liens) et ne se souligne qu'au survol. */
.site-footer h5 a { color: inherit; border-bottom: 1px solid transparent; padding-bottom: 2px; }
.site-footer h5 a:hover { color: var(--color-bg); border-bottom-color: currentColor; }
.site-footer p, .site-footer span { color: rgba(244, 237, 222, .7); font-size: 14px; line-height: 1.8; }
/* Deux blocs empilés dans une même colonne (Showroom puis Atelier) : sans cet
   écart, le titre du second collerait au texte du premier. */
.footer-bloc + .footer-bloc { margin-top: var(--space-md); }
.footer-liens { list-style: none; margin: 0; padding: 0; }
/* Les liens du pied de page reprennent la teinte des textes qui les entourent :
   le vert des liens du site est fait pour le fond clair, pas pour le bleu
   marine du pied de page. */
.footer-liens a { color: rgba(244, 237, 222, .7); font-size: 14px; line-height: 1.8; border-bottom: 1px solid transparent; }
.footer-liens a:hover { color: var(--color-bg); border-bottom-color: currentColor; }
@media (max-width: 800px) {
  .site-footer { grid-template-columns: 1fr; gap: var(--space-md); }
}

/* --- Cards produit / post --------------------------------------------------*/
.card { display: flex; flex-direction: column; gap: 14px; }
.card .placeholder-img { align-items: flex-start; }
.card-title { font-family: var(--font-title); font-size: 18px; }
.card-price { font-size: 15px; font-weight: 500; margin-top: 4px; }
.card-meta { font-size: 13px; color: var(--color-text-muted); }

/* --- Média de carte : zoom au survol + flèches photo -------------------------*/
/* Réservé aux grilles Vitrine et Boutique. Le cadre ne bouge pas : c'est le
   calque interne qui grandit, débordement masqué. */
.card-media {
  position: relative;
  overflow: hidden;
  background: var(--color-placeholder-a);
}
.card-media-link { display: block; width: 100%; height: 100%; }
.card-media-img {
  display: block;
  width: 100%;
  height: 100%;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  transition: transform .5s cubic-bezier(.2, .6, .2, 1);
}
.card-media:hover .card-media-img { transform: scale(1.05); }
/* Tant qu'aucune photo n'est posée, le calque garde le motif de remplissage
   et son texte ("photo à venir") aligné en bas, comme partout ailleurs. */
.card-media-img.placeholder-img { display: flex; align-items: flex-end; background-size: auto; background-repeat: repeat; }

.card-media-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 26px;
  height: 26px;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  border: none;
  cursor: pointer;
  background: rgba(244, 237, 222, .9);
  color: var(--color-text);
  font-size: 16px;
  line-height: 1;
  opacity: 0;
  transition: opacity .25s ease;
}
.card-media-nav[data-dir="-1"] { left: 10px; }
.card-media-nav[data-dir="1"] { right: 10px; }
.card-media-nav:hover { background: var(--color-bg); }
.card-media:hover .card-media-nav { opacity: 1; }
/* Au clavier, la flèche doit apparaître dès qu'elle reçoit le focus, sinon
   elle serait activable sans être visible. */
.card-media-nav:focus-visible { opacity: 1; outline: 2px solid var(--color-text); outline-offset: 2px; }
/* Sans survol possible (tactile), les flèches restent visibles en permanence. */
@media (hover: none) {
  .card-media-nav { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .card-media-img { transition: none; }
  .card-media:hover .card-media-img { transform: none; }
}

/* --- Roulement de photos (page d'accueil) -----------------------------------*/
/* La photo est portée par un calque superposé au motif de remplissage, jamais
   par la zone elle-même : si aucune photo n'est publiée, ou le temps qu'elles
   arrivent, la zone garde son apparence d'origine sans rien casser. */
/* Avant l'arrivée des photos, ces zones affichent un aplat neutre et non le
   motif rayé du gabarit. Le temps d'interroger la base puis de télécharger la
   première image, les rayures sautaient aux yeux à chaque ouverture de
   l'accueil. L'aplat se fond dans la page et se fait oublier. Le sélecteur
   combine un attribut et une classe, il l'emporte donc sur .placeholder-img
   seul, quel que soit l'ordre des feuilles de style. */
[data-roulement].placeholder-img { background: var(--color-canvas); }
.roulement-zone { position: relative; overflow: hidden; }
/* Une fois la première vraie photo à l'écran, le motif rayé du gabarit n'a plus
   lieu d'être : il ne doit jamais réapparaître entre deux photos. */
.roulement-zone.roulement-actif { background: var(--color-bg); }
.roulement-img {
  position: absolute;
  inset: 0;
  z-index: 1;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: 0;
  transition: opacity .7s ease;
  pointer-events: none;
}
.roulement-img.visible { opacity: 1; }
/* Deux calques par zone : celui qui arrive passe au-dessus de celui qu'il
   remplace, donc la photo précédente reste opaque pendant tout le fondu et
   rien ne transparaît derrière. */
.roulement-img.dessus { z-index: 2; }
/* Mouvement réduit : le fondu disparaît, la photo change d'un coup. Le
   défilement lui-même est conservé, c'est du contenu et non une décoration. */
@media (prefers-reduced-motion: reduce) {
  .roulement-img { transition: none; }
}

/* --- Formulaires ------------------------------------------------------------*/
.field { display: flex; flex-direction: column; gap: 9px; margin-bottom: var(--space-md); }
.field label { font-size: 13px; font-weight: 500; }
.field .hint { color: var(--color-text-faint); font-weight: 400; font-size: 12.5px; }
/* Les ronds et les cases sont exclus de l'habillage des champs de saisie :
   la largeur pleine et le rembourrage, faits pour une ligne de texte,
   étiraient le rond sur toute la largeur et rejetaient son libellé contre le
   bord droit, où il se coupait mot par mot. */
.field input:not([type="radio"]):not([type="checkbox"]),
.field textarea,
.field select {
  border: 1px solid rgba(27, 42, 65, .25);
  padding: 14px 16px;
  font-size: 15px;
  background: var(--color-input-bg);
  width: 100%;
}
.field input[type="radio"], .field input[type="checkbox"] {
  width: auto;
  accent-color: var(--color-accent-deep);
}
/* Cases posées directement dans leur libellé (côté administration). Le
   sélecteur d'enfant direct laisse de côté les choix de .liste-choix, qui
   gèrent eux-mêmes leur écart. */
.field > label input[type="radio"], .field > label input[type="checkbox"] {
  margin-right: 7px;
  vertical-align: -1px;
}
.field textarea { min-height: 120px; line-height: 1.7; resize: vertical; }
.form-row { display: grid; gap: 18px; }
.form-row-2 { grid-template-columns: 1fr 1fr; }
.form-row-3 { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 640px) {
  .form-row-2, .form-row-3 { grid-template-columns: 1fr; }
}

.form-note {
  background: var(--color-accent);
  padding: 16px 18px;
  font-size: 13.5px;
  line-height: 1.6;
}

.dropzone {
  border: 1px dashed rgba(27, 42, 65, .35);
  display: flex; align-items: center; justify-content: center;
  color: var(--color-text-faint);
  font-size: 12px;
  text-align: center;
  padding: var(--space-xs);
  cursor: pointer;
  background: none;
  width: 100%;
}

/* --- États --------------------------------------------------------------*/
.status-msg { font-size: 14px; padding: var(--space-sm); }
.status-msg.error { background: #F6DEDA; color: #7A2E2E; }
.status-msg.success { background: var(--color-accent); color: var(--color-text); }
.empty-state { color: var(--color-text-muted); font-size: 14.5px; padding: var(--space-lg) 0; text-align: center; }

/* --- Vignette photo avec croix de suppression -------------------------------*/
/* Partagée par les formulaires d'administration et par le formulaire de
   contact du site public : elle vit donc ici et non dans admin.css, que les
   pages publiques ne chargent pas. Voir js/lib/vignette-photo.js. */
.photo-vignette { position: relative; }
.photo-supprimer {
  position: absolute;
  top: 6px; right: 6px;
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  border: none;
  cursor: pointer;
  background: rgba(244, 237, 222, .92);
  color: var(--color-text);
  font-size: 18px;
  line-height: 1;
  box-shadow: 0 1px 4px rgba(27, 42, 65, .25);
}
.photo-supprimer:hover { background: #F6DEDA; color: #7A2E2E; }
.photo-supprimer:focus-visible { outline: 2px solid var(--color-text); outline-offset: 2px; }

/* Aperçu des photos jointes au formulaire de contact. Vide, la grille ne doit
   pas creuser un espace sous le champ. */
.apercu-photos { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.apercu-photos:empty { display: none; }
.apercu-photos .photo-vignette { height: 104px; }
