/* Reduc Shop — feuille unique.
 *
 * Reprend les jetons du design system « Broadsheet » (couleurs, espacements,
 * rayons) et le mix retenu : maquette journal claire, police Archivo.
 *
 * Aucune ressource distante : pas de CDN, pas de police Google. La page
 * s'ouvre debout dans un rayon, sur une machine qui n'expose rien.
 */

/* ── Jetons Broadsheet ─────────────────────────────────────────────────── */
:root {
  --color-bg: #f3f2f2;
  --color-surface: #eae9e9;
  --color-text: #201e1d;
  --color-accent: #0088b0;
  --color-divider: color-mix(in srgb, #201e1d 16%, transparent);

  --color-accent-100: #e9f8ff;
  --color-accent-400: #62c5ee;
  --color-accent-700: #006786;

  --color-accent-2-100: #fff1f4;
  --color-accent-2-300: #ffc0d0;
  --color-accent-2-700: #aa0b56;

  --radius-md: 2px;

  /* Rôles de l'écran, mappés sur les jetons — thème clair (le retenu). */
  --bg: var(--color-bg);
  --ink: var(--color-text);
  --mut: color-mix(in srgb, var(--color-text) 60%, transparent);
  --mut2: color-mix(in srgb, var(--color-text) 78%, transparent);
  --rule: var(--color-divider);
  --act: var(--color-accent-700);
  --chk: var(--color-accent);
  --chkink: var(--color-bg);
  --tint: var(--color-accent-100);
  --field: var(--color-surface);
  --warn: var(--color-accent-2-700);
  --warnbg: var(--color-accent-2-100);
}

/* Thème sombre — inversion complète, comme la variante 3b du design. */
:root[data-theme="sombre"] {
  --bg: var(--color-text);
  --ink: var(--color-bg);
  --mut: color-mix(in srgb, var(--color-bg) 62%, transparent);
  --mut2: color-mix(in srgb, var(--color-bg) 80%, transparent);
  --rule: color-mix(in srgb, var(--color-bg) 16%, transparent);
  --act: var(--color-accent-400);
  --chk: var(--color-accent-400);
  --chkink: var(--color-text);
  --tint: color-mix(in srgb, var(--color-accent-400) 9%, transparent);
  --field: color-mix(in srgb, var(--color-bg) 6%, transparent);
  --warn: var(--color-accent-2-300);
  --warnbg: color-mix(in srgb, var(--color-accent-2-300) 12%, transparent);
}

@media (prefers-color-scheme: dark) {
  :root[data-theme="auto"] {
    --bg: var(--color-text);
    --ink: var(--color-bg);
    --mut: color-mix(in srgb, var(--color-bg) 62%, transparent);
    --mut2: color-mix(in srgb, var(--color-bg) 80%, transparent);
    --rule: color-mix(in srgb, var(--color-bg) 16%, transparent);
    --act: var(--color-accent-400);
    --chk: var(--color-accent-400);
    --chkink: var(--color-text);
    --tint: color-mix(in srgb, var(--color-accent-400) 9%, transparent);
    --field: color-mix(in srgb, var(--color-bg) 6%, transparent);
    --warn: var(--color-accent-2-300);
    --warnbg: color-mix(in srgb, var(--color-accent-2-300) 12%, transparent);
  }
}

/* ── Base ──────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  /* Archivo si elle est installée ; sinon la police système, qui est du même
   * registre grotesque. Aucun téléchargement distant. */
  font-family: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 15px;
  line-height: 1.55;
  text-wrap: pretty;
  -webkit-text-size-adjust: 100%;
}

.page { max-width: 560px; margin: 0 auto; }

a { color: var(--act); }
:focus-visible { outline: 2px solid var(--act); outline-offset: 2px; }

/* Toute action est un bouton dans un formulaire (POST) : un GET ne modifie
 * jamais rien. On leur rend l'apparence d'un lien ou d'une case. */
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

/* ── Titre du journal ──────────────────────────────────────────────────── */
.bandeau { padding: 14px 16px 0; }

.bandeau-haut {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}

.titre-journal {
  font-size: 16px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  text-decoration: none; color: var(--ink);
}

.lien-tete {
  color: var(--act); font-size: 13.5px; font-weight: 600; text-decoration: none;
  min-height: 44px; display: inline-flex; align-items: center; padding-left: 12px;
}

.filets { height: 4px; border-top: 2px solid var(--ink); border-bottom: 1px solid var(--ink); margin-top: 4px; }
.filet { border-top: 1px solid var(--ink); }

.dateline {
  padding: 7px 0; font-size: 11px; line-height: 1.65;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--mut2);
}

/* Le bandeau d'alerte : les offres restent affichées, datées. Une page vide
 * qui a l'air normale est le pire des états. */
.alerte {
  margin-top: 10px; background: var(--warnbg); color: var(--warn);
  font-size: 12.5px; line-height: 1.5; padding: 10px 12px; border-radius: var(--radius-md);
}

/* ── Recherche et tri ──────────────────────────────────────────────────── */
.controles { padding: 14px 16px 12px; border-bottom: 1px solid var(--rule); }

.champ-recherche { position: relative; }
.champ-recherche svg { position: absolute; left: 13px; top: 15px; color: var(--mut); pointer-events: none; }

.champ-recherche input {
  width: 100%; height: 48px; padding: 0 48px 0 42px;
  background: var(--field); border: 1px solid var(--rule); border-radius: var(--radius-md);
  color: var(--ink); font-family: inherit; font-size: 15px; caret-color: var(--act);
}
.champ-recherche input:focus-visible { border-color: var(--act); outline-offset: 0; }
.champ-recherche input::placeholder { color: var(--mut); opacity: 1; }
.champ-recherche.active input { border-color: var(--act); }

.effacer {
  position: absolute; right: 2px; top: 2px; width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  color: var(--act); font-size: 20px; text-decoration: none;
}

.resultat { font-size: 13px; font-style: italic; color: var(--mut2); margin-top: 10px; }
.resultat a { font-style: normal; font-weight: 600; }

.tri { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.tri-libelle { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--mut); }
.segments { display: flex; border: 1px solid var(--rule); border-radius: var(--radius-md); overflow: hidden; }
.segments a {
  height: 44px; display: inline-flex; align-items: center; padding: 0 16px;
  color: var(--mut2); font-size: 13.5px; text-decoration: none;
}
.segments a[aria-current="true"] { background: var(--ink); color: var(--bg); font-weight: 600; }

/* ── Intertitres de rayon ──────────────────────────────────────────────── */
/* Collants : en défilant on sait toujours dans quel rayon on est, sans avoir
 * à remonter. C'est tout l'intérêt du classement quand on descend 109 offres. */
.rayon {
  position: sticky; top: 0; z-index: 2;
  margin: 0; padding: 10px 16px;
  background: var(--bg);
  border-top: 1px solid var(--ink); border-bottom: 1px solid var(--rule);
  font-size: 12px; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase;
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
}
.rayon-compte { font-size: 11px; font-weight: 400; color: var(--mut); letter-spacing: 0.04em; }

/* ── Liste d'offres ────────────────────────────────────────────────────── */
.offres { list-style: none; margin: 0; padding: 0 0 6px 16px; }

.offre {
  display: flex; gap: 12px; padding: 12px 12px 12px 0;
  min-height: 72px; border-bottom: 1px solid var(--rule);
}
.offres > .offre:last-child { border-bottom: 0; }

/* Une offre cochée est teintée sur toute la largeur : reconnaissable d'un
 * coup d'œil en descendant la liste. */
.offre.cochee { background: var(--tint); margin-left: -16px; padding-left: 16px; }

/* La vignette aide à reconnaître un produit d'un coup d'œil dans un rayon —
 * c'est tout son intérêt, donc elle doit être VUE. La maquette la donnait à
 * 48 px ; à l'usage c'est trop petit pour distinguer deux emballages proches.
 * `contain` : on ne recadre pas un paquet de lessive. */
.vignette {
  width: 88px; height: 88px; flex: none;
  object-fit: contain; border-radius: 3px; background: var(--field);
}

.offre-texte { flex: 1; min-width: 0; text-decoration: none; color: var(--ink); }
.offre-titre {
  font-size: 15.5px; font-weight: 600; line-height: 1.35;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
.sortant { color: var(--act); font-weight: 400; }

.offre-conditions {
  font-size: 12.5px; line-height: 1.45; color: var(--mut); margin-top: 3px;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}

.etiquette {
  display: inline-block; border: 1px solid var(--rule); border-radius: var(--radius-md);
  padding: 2px 7px; font-size: 11px; font-weight: 600; color: var(--mut2); margin-top: 6px;
}

.offre-droite {
  flex: none; width: 64px;
  display: flex; flex-direction: column; align-items: flex-end; gap: 2px;
}

.montant { font-weight: 700; font-size: 17px; line-height: 1.3; font-variant-numeric: tabular-nums; }
/* Un montant non lu n'est pas zéro : il le dit, en petit, sans faire semblant. */
.montant-absent { font-size: 11px; font-weight: 600; line-height: 1.25; color: var(--mut); text-align: right; text-transform: uppercase; letter-spacing: 0.04em; }

.coche {
  width: 44px; height: 44px; display: flex; align-items: center; justify-content: flex-end;
  padding: 0;
}
.case { width: 26px; height: 26px; border: 1.5px solid var(--mut); border-radius: var(--radius-md); }
.case.pleine {
  background: var(--chk); border-color: var(--chk); color: var(--chkink);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 15px;
}

/* ── Pages secondaires ─────────────────────────────────────────────────── */
.contenu { padding: 14px 16px 30px; }
.titre-page { font-size: 19px; font-weight: 600; line-height: 1.3; margin: 26px 0 0; }
.para { font-size: 13.5px; line-height: 1.6; color: var(--mut); margin: 10px 0 0; }

.total { margin-top: 16px; font-size: 15.5px; line-height: 1.5; }
.total strong { font-size: 17px; font-variant-numeric: tabular-nums; }
.total-note { font-size: 12.5px; line-height: 1.5; color: var(--mut); margin-top: 2px; }

.chiffres { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--rule); border: 1px solid var(--rule); margin-top: 18px; }
.chiffre { background: var(--bg); padding: 14px 12px; }
.chiffre b { display: block; font-size: 26px; font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.chiffre span { font-size: 11.5px; color: var(--mut); letter-spacing: 0.04em; text-transform: uppercase; }

.barres { margin-top: 20px; }
.barre { display: flex; align-items: center; gap: 10px; margin-top: 8px; font-size: 12.5px; }
.barre-libelle { width: 92px; flex: none; color: var(--mut2); font-variant-numeric: tabular-nums; }
.barre-piste { flex: 1; height: 12px; background: var(--field); border-radius: var(--radius-md); overflow: hidden; }
.barre-part { height: 100%; background: var(--act); }
.barre-valeur { width: 28px; text-align: right; font-variant-numeric: tabular-nums; color: var(--mut2); }

/* `flex-wrap` n'est pas décoratif : à 375 px, « Auto / Sombre / Clair » à côté
 * de son libellé déborde du viewport et la troisième option devient
 * inatteignable. Le contrôle passe alors sur sa propre ligne, pleine largeur. */
.reglage {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 10px 16px; padding: 14px 0; border-top: 1px solid var(--rule);
}
.reglage > :first-child { flex: 1 1 auto; min-width: 0; }
.reglage-titre { font-size: 14.5px; font-weight: 600; }
.reglage-sous { font-size: 12px; color: var(--mut); margin-top: 2px; }
.section-titre { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--mut); margin-top: 26px; }

.choix { display: flex; border: 1px solid var(--rule); border-radius: var(--radius-md); overflow: hidden; }
.choix label { min-height: 44px; display: inline-flex; align-items: center; padding: 0 14px; font-size: 13.5px; color: var(--mut2); cursor: pointer; }
/* Masquage VISUEL seulement : le bouton radio reste focusable au clavier et
 * annoncé par un lecteur d'écran. `width:0;height:0;opacity:0` le sortirait de
 * l'arbre d'accessibilité — le contrôle serait là sans être atteignable. */
.choix input {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.choix label:has(input:checked) { background: var(--ink); color: var(--bg); font-weight: 600; }
.choix label:has(input:focus-visible) { outline: 2px solid var(--act); outline-offset: -2px; }

.bouton-texte { color: var(--act); font-size: 13.5px; font-weight: 600; min-height: 44px; display: inline-flex; align-items: center; }
.bouton-danger { color: var(--warn); }

.pied { font-size: 11.5px; line-height: 1.6; color: var(--mut); margin-top: 26px; padding-top: 14px; border-top: 1px solid var(--rule); }
.pied code { font-size: 11px; background: var(--field); padding: 1px 5px; border-radius: var(--radius-md); }

/* ── Connexion ─────────────────────────────────────────────────────────── */
.formulaire { margin-top: 22px; }

.champ { display: block; margin-bottom: 16px; }
.champ-libelle {
  display: block; font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--mut); margin-bottom: 6px;
}
.champ input {
  width: 100%; height: 48px; padding: 0 14px;
  background: var(--field); border: 1px solid var(--rule); border-radius: var(--radius-md);
  color: var(--ink); font-family: inherit; font-size: 16px; /* 16px : en dessous,
    iOS zoome tout seul à la mise au point et casse la page */
  caret-color: var(--act);
}
.champ input:focus-visible { border-color: var(--act); outline-offset: 0; }

.bouton-plein {
  width: 100%; min-height: 48px;
  background: var(--ink); color: var(--bg);
  border-radius: var(--radius-md);
  font-size: 15px; font-weight: 600; letter-spacing: 0.02em;
}

/* Le bandeau d'erreur de connexion reprend celui des alertes de collecte :
   même langage visuel pour « quelque chose ne va pas ». */
.contenu .alerte { margin-top: 18px; }

/* Sous 460 px, le segmenté prend toute la largeur et se répartit à parts
 * égales : trois cibles de 44 px atteignables au pouce. */
@media (max-width: 459px) {
  .reglage .choix { width: 100%; }
  .reglage .choix label { flex: 1; justify-content: center; }
}

/* ── Écrans larges ─────────────────────────────────────────────────────────
 *
 * Le cas d'usage principal reste le téléphone, debout dans un rayon : la
 * colonne unique ne bouge pas en dessous de 700 px.
 *
 * Au-dessus, la maquette laissait deux grandes marges vides pendant qu'on
 * faisait défiler 109 offres. On passe en grille : plus d'offres visibles d'un
 * coup, moins de défilement quand on prépare la liste à la maison.
 */
@media (min-width: 700px) {
  .page { max-width: 1180px; padding: 0 12px; }

  .offres {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
    padding: 16px 16px 20px;
  }

  /* En grille, chaque offre devient une carte : le filet du bas séparait des
   * lignes empilées, il n'a plus de sens côte à côte. */
  .offre {
    border: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
    border-radius: var(--radius-md);
    padding: 12px;
    align-items: flex-start;
  }
  .offres > .offre:last-child { border-bottom: 1px solid var(--rule); }

  /* La teinte de sélection reprend toute la carte, sans le décalage négatif
   * qui servait à mordre la marge dans la liste empilée. */
  .offre.cochee { margin-left: 0; padding-left: 12px; border-color: var(--chk); }

  /* Les cartes sont larges : la vignette peut l'être aussi. Plafonnée à 128 px
   * parce que la source ne publie que du 400 px — au-delà on afficherait une
   * image agrandie, donc molle. */
  .vignette { width: 128px; height: 128px; }

  /* Le bandeau, la recherche et les pages de texte restent en colonne étroite :
   * une ligne de texte longue de 1180 px ne se lit pas. */
  .bandeau, .controles, .contenu { max-width: 720px; margin-inline: auto; }
}

@media (min-width: 1080px) {
  .offres { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 620px) and (max-width: 699px) {
  .page { border-left: 1px solid var(--rule); border-right: 1px solid var(--rule); min-height: 100vh; }
}
