/* ============================================================
   UPProcess — Outils · Feuille de style partagée
   Palette STRICTEMENT identique à upprocess.ch (Poppins) :
     recto  fond #3984BE · "UP" blanc · "Process" #A9D2F0
     verso  fond #D2E8F6 · "Process" #89BEE7 · texte #00002C
   Toute couleur de marque vient d'ici — ne pas coder de bleu en dur.
   Composants réutilisables par tous les outils.
   ============================================================ */

:root {
  /* Bleus — relevés au pixel sur la carte de visite */
  --blue-pale: #B4D8F1;   /* aplat le plus clair du verso */
  --blue-light: #A9D2F0;  /* « Process » du recto */
  --blue-mid: #89BEE7;    /* « Process » du verso */
  --blue: #3984BE;        /* fond du recto = bleu principal de la marque */
  --blue-deep: #2A6A9C;   /* dérivé : survols, dégradés */
  --blue-darker: #1E5074; /* dérivé : texte bleu appuyé */

  /* Fonds */
  --bg: #D2E8F6;          /* fond de la carte (verso) */
  --bg-soft: #E7F2FA;
  --bg-hero-1: #DDEDF7;
  --bg-hero-2: #C4E0F3;
  --panel: #ffffff;
  --chrome: #DAEAF7;      /* = fond des fichiers logo : en-tête et pied du site */

  /* Texte */
  --navy: #00002C;        /* encre des cartes : titres, menu */
  --text: #3C4C63;
  --muted: #74879E;
  --white: #ffffff;

  --line: #C7DEF0;        /* bordure claire du site */
  --danger: #c0392b;        /* 5,4:1 sur blanc */
  --ok: #217A51;            /* assombri : #2e9e6b ne tenait que 3,4:1 sur blanc */

  --radius: 18px;
  --radius-sm: 12px;
  --shadow: 0 18px 40px -18px rgba(42, 106, 156, 0.45);
  --shadow-soft: 0 10px 30px -12px rgba(42, 106, 156, 0.30);
  --max-width: 1080px;
  --transition: 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* scroll-padding-top : l'en-tête sticky ne doit pas recouvrir la cible d'une
   ancre (ex. « Voir les outils » → #hub). */
html { scroll-behavior: smooth; scroll-padding-top: 120px; }

body {
  font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  color: var(--text);
  /* Aplat, comme le site. Le dégradé radial d'avant créait une couture visible
     sous la vague du hero, dont le remplissage est un aplat --bg. */
  background: var(--bg);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  display: flex; flex-direction: column;
}
main { flex: 1 0 auto; }

img { max-width: 100%; display: block; }
a { text-decoration: none; color: inherit; }

.container { width: 100%; max-width: var(--max-width); margin: 0 auto; padding: 0 22px; }
.narrow { max-width: 860px; }

/* ============================================================
   EN-TÊTE — reprise à l'identique de upprocess.ch (injectée par shell.js)
   ============================================================ */
/* `sticky` et non `fixed` comme le site : le site compense son header fixe par
   un padding-top de 120px sur son hero, or les 20 pages d'outils commencent par
   un .tool-head sans marge équivalente — un header fixe leur passerait dessus.
   Au repos le rendu est identique. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  padding: 18px 0;
  background: var(--chrome);      /* = couleur du fond du logo, fusion parfaite */
  transition: var(--transition);
}
.site-header.scrolled {
  box-shadow: 0 4px 20px -10px rgba(42, 106, 156, 0.35);
  padding: 12px 0;
}
.header-inner { display: flex; align-items: center; justify-content: space-between; }

/* ── Logo image, avec le petit drapeau suisse sous le « UP » ── */
.brand { position: relative; display: inline-flex; align-items: center; line-height: 0; }
.brand-logo { height: 72px; width: auto; display: block; }
.brand-flag {
  position: absolute; left: 26px; bottom: 8px;
  width: 15px; height: 15px; line-height: 0;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.2));
}
.brand-flag svg { width: 100%; height: 100%; display: block; }
@media (max-width: 520px) {
  .brand-logo { height: 54px; }
  .brand-flag { left: 19px; bottom: 6px; width: 12px; height: 12px; }
}

/* ── Navigation ── */
.nav { display: flex; align-items: center; gap: 22px; }
.nav-link { color: var(--navy); font-weight: 500; font-size: 0.95rem; position: relative; transition: color 0.25s; }
.nav-link:not(.btn)::after {
  content: ""; position: absolute; left: 0; bottom: -6px;
  width: 0; height: 2px; background: var(--blue); transition: width 0.25s;
}
.nav-link:not(.btn):hover { color: var(--blue-deep); }
.nav-link:not(.btn):hover::after { width: 100%; }
/* :not(.btn) est indispensable : sur le bouton Contact, la couleur de texte
   deviendrait celle de son propre fond et le libellé disparaîtrait. */
.nav-link.active:not(.btn) { color: var(--blue-deep); }
.nav-link.active:not(.btn)::after { width: 100%; }

/* ── Mode application ──
   Le scope du manifeste est réduit à la page de l'outil : tout lien vers le
   site éjecterait de l'application. shell.js ne rend donc pas la navigation,
   et cette règle sert de second verrou (media query native, indépendante du
   JS) au cas où un navigateur rendrait la coque autrement. */
/* `:not(.app-hub)` est indispensable : le HUB installé garde la navigation du
   site et son menu hamburger — « Tous les outils » n'y aurait aucun sens.
   Seules les applications d'un outil précis se referment sur elles-mêmes. */
/* ⚠️ Le bloc d'installation n'est PAS masqué ici. Une règle CSS ne voit que
   le mode d'affichage, pas QUEL outil est installé : elle faisait disparaître
   la proposition sur tous les outils dès qu'un seul était installé. C'est
   shell.js qui décide, en vérifiant que la page a bien été ouverte depuis
   l'icône de SON application. */
@media (display-mode: standalone), (display-mode: fullscreen) {
  html:not(.app-hub) .nav,
  html:not(.app-hub) .nav-toggle { display: none !important; }
}
html.mode-app:not(.app-hub) .nav,
html.mode-app:not(.app-hub) .nav-toggle { display: none !important; }
/* Une seule sortie, volontairement discrète : un lien texte, pas un bouton.
   Il ouvre la boîte à outils dans le navigateur (target="_blank") au lieu de
   remplacer le contenu de la fenêtre de l'application. */
.app-exit {
  font-size: 0.82rem;
  color: var(--muted);
  white-space: nowrap;
  padding: 6px 4px;            /* cible tactile un peu plus large que le texte */
  transition: color 0.2s ease;
}
.app-exit:hover { color: var(--blue-deep); text-decoration: underline; text-underline-offset: 3px; }

/* ── Bouton hamburger (mobile) ── */
.nav-toggle { display: none; flex-direction: column; gap: 5px; background: none; border: none; cursor: pointer; padding: 6px; }
.nav-toggle span { width: 26px; height: 2.5px; background: var(--navy); border-radius: 2px; transition: var(--transition); }
.nav-toggle.open span:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
.nav-toggle.open span:nth-child(2) { opacity: 0; }
.nav-toggle.open span:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); }

@media (max-width: 860px) {
  .nav {
    position: fixed; inset: 0 0 0 auto;
    width: min(78vw, 320px);
    flex-direction: column; justify-content: center; gap: 26px;
    background: var(--bg-soft);
    box-shadow: -10px 0 40px -10px rgba(42, 106, 156, 0.4);
    transform: translateX(100%);
    transition: var(--transition);
    z-index: 99;
  }
  .nav.open { transform: translateX(0); }
  .nav-link { font-size: 1.1rem; }
  .nav-toggle { display: flex; z-index: 101; }
}

/* ============================================================
   PIED DE PAGE — reprise à l'identique de upprocess.ch
   ============================================================ */
.site-footer {
  flex-shrink: 0;
  /* Aplat, pas de dégradé : c'est exactement le fond des fichiers logo, donc
     l'image du logo se fond dedans au lieu d'y dessiner un rectangle clair. */
  background: var(--chrome);
  color: var(--navy);
  padding: 50px 0 36px; text-align: center;
  border-top: 1px solid rgba(57, 132, 190, 0.28);
  margin-top: 40px;
}
.footer-inner { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.footer-logo-img { height: 64px; width: auto; display: block; margin: 0 auto; }
/* --text et non --muted : sur l'aplat #DAEAF7 le gris clair tombe à 3:1. */
.footer-copy { font-size: 0.88rem; margin-top: 14px; color: var(--text); }
.footer-copy a { color: var(--blue-deep); }
.footer-copy a:hover { text-decoration: underline; }
.footer-legal { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 4px 14px; margin-top: 10px; }
.footer-legal a {
  font-size: 0.85rem; color: var(--navy); text-decoration: underline;
  text-underline-offset: 3px; text-decoration-color: rgba(0, 0, 44, 0.35);
  transition: color 0.2s ease, text-decoration-color 0.2s ease;
}
.footer-legal a:hover { color: var(--blue-darker); text-decoration-color: currentColor; }

/* ── Proposition d'installation (bloc permanent, injecté par shell.js) ──
   Dans le pied de page et non dans le menu : l'invite native de Chrome est
   discrète et n'apparaît pas à chaque visite, il fallait une porte d'entrée
   toujours visible et explicite. */
.app-install {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 16px;
  width: 100%; max-width: 680px;
  margin: 0 auto 30px;
  padding: 18px 20px;
  text-align: left;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-soft);
}
.app-install .ai-icon { width: 56px; height: 56px; flex: none; border-radius: 12px; }
.app-install .ai-txt { flex: 1 1 240px; min-width: 0; }
.app-install .ai-txt b { display: block; color: var(--navy); font-size: 0.98rem; margin-bottom: 3px; }
.app-install .ai-txt span { display: block; font-size: 0.86rem; line-height: 1.5; color: var(--text); }
.app-install .ai-go { flex: none; }
/* La marche à suivre occupe toute la largeur, sous le reste. */
.app-install .ai-aide {
  flex: 1 0 100%;
  margin: 4px 0 0;
  padding: 12px 14px;
  font-size: 0.86rem; line-height: 1.55; color: var(--text);
  background: var(--bg-soft);
  border-left: 3px solid var(--blue);
  border-radius: 0 10px 10px 0;
}
.app-install .ai-aide b { color: var(--navy); }

@media (max-width: 560px) {
  .app-install { flex-direction: column; align-items: stretch; text-align: center; gap: 12px; }
  .app-install .ai-icon { margin: 0 auto; }
  .app-install .ai-aide { text-align: left; }
}

/* ---------- En-tête d'outil ---------- */
.tool-head { text-align: center; padding: 44px 0 28px; }
.tool-head .tool-ico { font-size: 2.4rem; line-height: 1; display: inline-block; margin-bottom: 10px; }
.tool-head h1 { color: var(--navy); font-size: clamp(1.8rem, 4.5vw, 2.7rem); font-weight: 600; line-height: 1.1; }
.grad { background: linear-gradient(95deg, var(--blue), var(--blue-darker)); -webkit-background-clip: text; background-clip: text; color: transparent; }
/* Sur le site, --muted ne sert qu'au texte accessoire (notes, sous-libellés).
   Ici le chapô est le paragraphe principal, posé sur le fond de page #D2E8F6 :
   en --muted il ne tenait que 2,9:1. --text le porte à 6,9:1. */
.lead { max-width: 620px; margin: 12px auto 0; color: var(--text); font-size: 1.02rem; }

/* ============================================================
   HUB (index.html)
   ============================================================ */
/* Hero du site : dégradé 160deg, blobs floutés et vague SVG.
   Pas le padding-top de 150px du site : notre en-tête est sticky, pas fixe. */
.hub-hero {
  position: relative;
  text-align: center;
  background: linear-gradient(160deg, var(--bg-hero-1) 0%, var(--bg-hero-2) 55%, var(--blue-pale) 100%);
  padding: 72px 0 118px;   /* le bas dégage la vague (90px de haut) */
  overflow: hidden;
}
.hero-inner { position: relative; z-index: 2; }
.hub-hero h1 {
  color: var(--navy);
  font-size: clamp(2rem, 5.5vw, 3.1rem);
  font-weight: 700; letter-spacing: -1px; line-height: 1.08;
}
.accent {
  background: linear-gradient(95deg, var(--blue), var(--blue-deep));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.hub-hero .hero-text { color: var(--text); font-size: 1.08rem; max-width: 660px; margin: 18px auto 0; }
.hero-actions { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; margin-top: 30px; }

/* Formes décoratives */
.hero-blob { position: absolute; border-radius: 50%; filter: blur(40px); opacity: 0.55; z-index: 1; }
.hero-blob-1 {
  width: 480px; height: 480px;
  background: radial-gradient(circle, rgba(169, 210, 240, 0.9), transparent 70%);
  top: -120px; right: -80px;
}
.hero-blob-2 {
  width: 380px; height: 380px;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.9), transparent 70%);
  bottom: 40px; left: -100px;
}
.hero-wave { position: absolute; bottom: -1px; left: 0; width: 100%; line-height: 0; z-index: 2; }
.hero-wave svg { width: 100%; height: 90px; display: block; }
.hero-wave path { fill: var(--bg); }

@media (max-width: 520px) {
  .hub-hero { padding: 48px 0 100px; }
  .hero-actions { flex-direction: column; align-items: stretch; }
  .hero-actions .btn { width: 100%; }
}

.hub-cat { font-size: 0.82rem; text-transform: uppercase; letter-spacing: 1.5px; color: var(--blue-deep); font-weight: 600; margin: 30px 0 14px; }

.hub-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 18px; padding-bottom: 20px; }
.tool-card {
  position: relative; display: flex; flex-direction: column; gap: 8px;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-soft); padding: 22px; transition: var(--transition);
}
.tool-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--blue-light); }
.tool-card .tc-ico { font-size: 1.9rem; line-height: 1; }
.tool-card h3 { color: var(--navy); font-size: 1.08rem; font-weight: 600; }
.tool-card p { color: var(--text); font-size: 0.88rem; line-height: 1.45; }
.tool-card .tc-badge { position: absolute; top: 14px; right: 14px; font-size: 0.68rem; font-weight: 600; color: var(--blue-deep); background: var(--bg-soft); border: 1px solid var(--line); border-radius: 20px; padding: 3px 9px; text-transform: uppercase; letter-spacing: 0.5px; }
.tool-card.soon { opacity: 0.72; }

/* ============================================================
   COMPOSANTS GÉNÉRIQUES
   ============================================================ */
.panel { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-soft); padding: 26px; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; align-items: start; }
.stack { display: flex; flex-direction: column; gap: 16px; }
.center { text-align: center; }
.mt { margin-top: 18px; }
.hidden { display: none !important; }

/* Formulaires */
label { display: block; font-size: 0.85rem; font-weight: 500; color: var(--navy); margin: 14px 0 6px; }
label:first-child { margin-top: 0; }
input[type="text"], input[type="email"], input[type="tel"], input[type="url"], input[type="number"], input[type="search"], textarea, select {
  width: 100%; font-family: inherit; font-size: 0.95rem; color: var(--text);
  background: var(--bg-soft); border: 1px solid var(--line); border-radius: 10px;
  padding: 11px 13px; transition: var(--transition); resize: vertical;
}
input:focus, textarea:focus, select:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(57,132,190,0.18); background: var(--white); }
textarea { line-height: 1.5; }

.row { display: flex; gap: 14px; flex-wrap: wrap; }
.row .col { flex: 1 1 0; min-width: 120px; }
.checkbox { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-weight: 400; color: var(--text); }
.checkbox input { width: auto; }

input[type="range"] { width: 100%; accent-color: var(--blue); margin: 6px 0; cursor: pointer; }
.hint { font-size: 0.78rem; color: var(--muted); margin-top: 6px; }
.sep { border: none; border-top: 1px solid var(--line); margin: 22px 0; }

/* Couleurs */
.color-input { display: inline-flex; align-items: center; gap: 10px; background: var(--bg-soft); border: 1px solid var(--line); border-radius: 10px; padding: 6px 10px; }
.color-input input[type="color"] { width: 34px; height: 34px; padding: 0; border: none; border-radius: 8px; background: none; cursor: pointer; }
.color-input input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.color-input input[type="color"]::-webkit-color-swatch { border: 1px solid var(--line); border-radius: 6px; }
.color-input span { font-size: 0.85rem; color: var(--muted); font-variant-numeric: tabular-nums; }

/* Boutons — pilules du site : rayon 50px, bordure 2px, poids 600, survol -3px */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: inherit; font-size: 0.95rem; font-weight: 600;
  cursor: pointer; padding: 13px 26px;
  border-radius: 50px; border: 2px solid transparent;
  transition: var(--transition);
}
.btn-primary { background: linear-gradient(120deg, var(--blue), var(--blue-deep)); color: var(--white); box-shadow: var(--shadow-soft); }
.btn-primary:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.btn-ghost { background: transparent; color: var(--blue-deep); border-color: var(--blue-light); }
.btn-ghost:hover { background: var(--white); border-color: var(--blue); transform: translateY(-3px); }
/* Bouton Contact de la nav */
.btn-nav { padding: 9px 20px; background: var(--blue-deep); color: #fff; font-size: 0.95rem; }
.btn-nav:hover { background: var(--blue-darker); }
.btn-nav::after { display: none; }
.btn-lg { padding: 16px 38px; font-size: 1.05rem; }
.btn-block { width: 100%; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; box-shadow: none; }
/* Reste une pilule : un rayon réduit jurerait à côté des boutons pleine taille */
.btn-sm { padding: 8px 16px; font-size: 0.85rem; border-width: 1px; }
.btn-row { display: flex; gap: 10px; flex-wrap: wrap; }

/* Zone de dépôt de fichiers */
.dropzone {
  border: 2px dashed var(--blue-light); border-radius: var(--radius); background: var(--bg-soft);
  padding: 40px 24px; text-align: center; cursor: pointer; transition: var(--transition); color: var(--text);
}
.dropzone:hover, .dropzone.dz-over { border-color: var(--blue); background: #DCEDF8; color: var(--navy); }
.dropzone .dz-ico { font-size: 2.2rem; margin-bottom: 8px; }
.dropzone .dz-title { color: var(--navy); font-weight: 600; font-size: 1rem; }
.dropzone .dz-sub { font-size: 0.84rem; margin-top: 4px; }
.dropzone input[type="file"] { display: none; }

/* Ligne de fichier / résultat */
.file-row { display: flex; align-items: center; gap: 14px; background: var(--bg-soft); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 12px 14px; margin-top: 10px; }
.file-row .fr-thumb { width: 46px; height: 46px; border-radius: 8px; object-fit: cover; border: 1px solid var(--line); background: var(--white); flex-shrink: 0; }
.file-row .fr-info { flex: 1; min-width: 0; }
.file-row .fr-name { color: var(--navy); font-weight: 500; font-size: 0.9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.file-row .fr-meta { font-size: 0.78rem; color: var(--muted); }
.file-row .fr-actions { display: flex; gap: 6px; flex-shrink: 0; }
.icon-btn { border: 1px solid var(--line); background: var(--white); color: var(--muted); width: 32px; height: 32px; border-radius: 8px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: var(--transition); font-size: 0.95rem; }
.icon-btn:hover { color: var(--danger); border-color: var(--danger); }

/* Vignettes / galeries */
.thumbs { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 12px; margin-top: 14px; }

/* Badges & états */
.badge { display: inline-block; font-size: 0.72rem; font-weight: 600; border-radius: 20px; padding: 3px 10px; }
.badge-ok { color: var(--ok); background: rgba(33,122,81,0.12); }
.badge-save { color: var(--blue-deep); background: rgba(57,132,190,0.16); }
.status { font-size: 0.86rem; color: var(--text); min-height: 1.2em; }
.status.error { color: var(--danger); }
.status.ok { color: var(--ok); }

/* Barre de progression */
.progress { height: 8px; background: var(--bg-soft); border: 1px solid var(--line); border-radius: 20px; overflow: hidden; }
.progress > i { display: block; height: 100%; width: 0; background: linear-gradient(95deg, var(--blue), var(--blue-deep)); transition: width 0.2s; }

/* Toast */
.toast { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%) translateY(20px); background: var(--navy); color: var(--white); padding: 12px 20px; border-radius: 12px; font-size: 0.9rem; box-shadow: var(--shadow); opacity: 0; pointer-events: none; transition: var(--transition); z-index: 100; }
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ============================================================
   QR (qr.html)
   ============================================================ */
.studio { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: 26px; align-items: start; padding-bottom: 40px; }
.tabs { display: flex; gap: 6px; background: var(--bg-soft); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 5px; margin-bottom: 22px; flex-wrap: wrap; }
/* Libellés d'onglets : ce sont des commandes, pas du texte accessoire.
   La hiérarchie vient de l'onglet actif (fond blanc + navy), pas d'un gris pâle. */
.tab { flex: 1 1 auto; border: none; background: transparent; cursor: pointer; font-family: inherit; font-size: 0.9rem; font-weight: 500; color: var(--text); padding: 9px 10px; border-radius: 9px; transition: var(--transition); white-space: nowrap; }
.tab:hover { color: var(--navy); }
.tab.is-active { background: var(--white); color: var(--navy); box-shadow: var(--shadow-soft); }
.field-group { margin-bottom: 4px; }
.field-group.hidden { display: none; }
.opt-title { font-size: 1rem; color: var(--navy); font-weight: 600; margin-bottom: 6px; }
/* 112px : l'en-tête replié mesure 96px (12 + logo 72 + 12), + une marge. */
.preview { position: sticky; top: 112px; display: flex; flex-direction: column; align-items: center; text-align: center; }
.qr-frame {
  width: 100%; aspect-ratio: 1/1; max-width: 340px; border-radius: var(--radius-sm);
  background:
    linear-gradient(45deg, var(--bg-soft) 25%, transparent 25%) 0 0/20px 20px,
    linear-gradient(-45deg, var(--bg-soft) 25%, transparent 25%) 0 10px/20px 20px,
    linear-gradient(45deg, transparent 75%, var(--bg-soft) 75%) 10px -10px/20px 20px,
    linear-gradient(-45deg, transparent 75%, var(--bg-soft) 75%) -10px 0/20px 20px,
    var(--white);
  border: 1px solid var(--line); display: flex; align-items: center; justify-content: center; padding: 16px; margin-bottom: 14px;
}
#qr-holder { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; }
#qr-holder canvas, #qr-holder svg { width: 100% !important; height: 100% !important; border-radius: 4px; }
.preview-meta { font-size: 0.82rem; color: var(--muted); margin-bottom: 18px; min-height: 1.2em; }
.preview-meta.error { color: var(--danger); }
.downloads { display: flex; gap: 10px; width: 100%; }
.downloads .btn { flex: 1; }

/* ---------- Responsive ---------- */
@media (max-width: 820px) {
  .grid-2 { grid-template-columns: 1fr; }
  .studio { grid-template-columns: 1fr; }
  .preview { position: static; order: -1; }
  .qr-frame { max-width: 280px; }
}

/* ============================================================
   MOBILE — corrections transverses
   ============================================================ */

/* Safari iOS agrandit la page dès qu'on touche un champ dont la police fait
   moins de 16 px — et n'en ressort pas tout seul : le visiteur doit pincer
   pour dézoomer, à chaque champ. Nos champs étaient à 0.95rem (15,2 px), et
   jusqu'à 0.85rem dans les lignes de facture.

   !important est nécessaire : plusieurs feuilles d'outil redéfinissent ces
   polices avec une spécificité supérieure (.line-item input, .pf-input…). */
@media (max-width: 820px) {
  input[type="text"], input[type="email"], input[type="tel"], input[type="url"],
  input[type="number"], input[type="search"], input[type="date"],
  input[type="time"], input[type="password"], textarea, select {
    font-size: 16px !important;
  }
}

/* Au doigt, une cible de 24 ou 32 px se rate. 44 px est le minimum confortable ;
   on vise 40 px pour ne pas déformer les mises en page denses.
   `pointer: coarse` cible le tactile sans pénaliser la souris. */
@media (pointer: coarse) {
  .icon-btn { width: 40px; height: 40px; }
  .btn-sm { padding: 10px 18px; }
  .tab { padding: 12px 12px; }
}

/* ============================================================
   IMPRESSION — la coque ne sort jamais sur le papier
   Règle globale et non recopiée dans chaque feuille d'outil : les factures,
   devis, notes de frais et QR de paiement s'impriment, et un en-tête à logo
   en haut d'une facture serait une régression silencieuse à chaque
   renommage de classe.
   ============================================================ */
@media print {
  .site-header, .site-footer { display: none !important; }
}
