/* ==========================================================================
   Liquid Glass — couche de matière et de mouvement
   Salon de l'Agronomie 2026

   Chargée APRÈS app.css, qu'elle habille sans le remplacer : si cette feuille
   est retirée, l'application reste entièrement utilisable dans son apparence
   précédente. C'est voulu — on est à quelques jours du salon.

   Principe directeur, repris d'iOS 26 : le verre est la couche des CONTRÔLES,
   pas celle du contenu. Les grandes cartes restent opaques — elles gardent la
   géométrie et les reflets, mais pas le flou.

   Ce n'est pas qu'une question de fidélité : `backdrop-filter` est recalculé
   à chaque image par le processeur graphique, et le staff scannera sur des
   téléphones d'entrée de gamme.

   D'où la règle appliquée ici : ne floute que ce qui est UNIQUE à l'écran et
   flotte réellement au-dessus d'autre chose — barre latérale, barre du haut
   et ses deux boutons, voile, panneau de résultat, compteur de file, messages
   flash, panneau de connexion. Soit une demi-douzaine de couches au plus.

   Tout ce qui se répète — pastilles, champs, boutons de tableau — garde la
   capsule et le liseré, mais pas le flou. Trois boutons par ligne sur
   cinquante lignes feraient cent cinquante couches à recomposer par image,
   pour un effet invisible sur vingt pixels de haut.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Matière, géométrie, ressorts
   -------------------------------------------------------------------------- */
:root {
  /* Teintes du verre. Trois épaisseurs, comme les matériaux d'iOS. */
  --lg-thin: rgba(255, 255, 255, 0.44);
  --lg-regular: rgba(255, 255, 255, 0.62);
  --lg-thick: rgba(255, 255, 255, 0.82);

  --lg-blur: 20px;
  --lg-blur-strong: 32px;
  --lg-saturate: 180%;

  /* Reflet spéculaire : vif sur l'arête éclairée, sourd sur l'opposée. */
  --lg-rim-bright: rgba(255, 255, 255, 0.95);
  --lg-rim-dim: rgba(255, 255, 255, 0.25);
  --lg-rim-line: rgba(255, 255, 255, 0.55);

  /* Ombre portée : deux plans, pour un décollement franc sans lourdeur. */
  --lg-cast: 0 12px 32px -14px rgba(12, 30, 22, 0.30), 0 2px 8px -4px rgba(12, 30, 22, 0.18);
  --lg-cast-high: 0 26px 60px -20px rgba(12, 30, 22, 0.38), 0 6px 16px -8px rgba(12, 30, 22, 0.22);

  /* Rayons concentriques : chaque niveau imbriqué se resserre d'un cran. */
  --lg-r-xs: 10px;
  --lg-r-sm: 14px;
  --lg-r-md: 20px;
  --lg-r-lg: 26px;
  --lg-r-xl: 32px;
  --lg-r-pill: 999px;

  /* Ressort avec léger dépassement, pour ce qui apparaît ou s'ouvre. */
  --lg-spring: linear(
    0, 0.006, 0.025 2.8%, 0.101 6.1%, 0.539 18.9%, 0.721 25.3%, 0.849 31.5%,
    0.937 38.1%, 0.968 41.8%, 0.991 45.7%, 1.006 50.1%, 1.015 55%, 1.017 63.9%, 1.001
  );
  /* Décélération sans dépassement, pour ce qui suit le doigt. */
  --lg-ease: cubic-bezier(0.32, 0.72, 0, 1);

  --lg-fast: 0.16s;
  --lg-base: 0.3s;
  --lg-slow: 0.46s;
}

[data-theme='dark'] {
  --lg-thin: rgba(30, 46, 40, 0.44);
  --lg-regular: rgba(28, 42, 37, 0.62);
  --lg-thick: rgba(24, 36, 32, 0.84);

  --lg-rim-bright: rgba(255, 255, 255, 0.30);
  --lg-rim-dim: rgba(255, 255, 255, 0.06);
  --lg-rim-line: rgba(255, 255, 255, 0.14);

  --lg-cast: 0 12px 32px -14px rgba(0, 0, 0, 0.65), 0 2px 8px -4px rgba(0, 0, 0, 0.45);
  --lg-cast-high: 0 26px 60px -20px rgba(0, 0, 0, 0.75), 0 6px 16px -8px rgba(0, 0, 0, 0.5);
}

/* --------------------------------------------------------------------------
   2. Fond ambiant

   Sans quelque chose à traverser, du verre ne ressemble à rien. Cette nappe
   très pâle donne au flou de la matière à échantillonner et fait vivre les
   reflets quand on défile. Contraste volontairement faible : le texte du
   contenu ne doit jamais avoir à lutter contre elle.
   -------------------------------------------------------------------------- */
.app-body::before {
  content: "";
  position: fixed;
  inset: -10vmax;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(38vmax 30vmax at 12% -4%, color-mix(in srgb, var(--brand) 22%, transparent), transparent 65%),
    radial-gradient(32vmax 28vmax at 92% 8%, color-mix(in srgb, #2f9ea8 18%, transparent), transparent 62%),
    radial-gradient(44vmax 34vmax at 68% 104%, color-mix(in srgb, var(--brand) 16%, transparent), transparent 68%);
  opacity: 0.5;
  animation: lg-derive 34s ease-in-out infinite alternate;
}

[data-theme='dark'] .app-body::before {
  opacity: 0.34;
}

@keyframes lg-derive {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(-2.5%, 1.5%, 0) scale(1.08); }
}

/* --------------------------------------------------------------------------
   3. Le matériau

   `.lg` pose la teinte, le flou et l'ombre. `.lg::before` dessine l'arête :
   un dégradé en anneau, découpé au masque pour ne garder que le liseré. C'est
   lui qui donne la sensation de lumière prise dans l'épaisseur du verre —
   vive en haut à gauche, éteinte au milieu, reprise en bas à droite.
   -------------------------------------------------------------------------- */
.lg {
  position: relative;
  background: var(--lg-regular);
  -webkit-backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
  backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
  border: 0;
  box-shadow: var(--lg-cast);
  isolation: isolate;
}

.lg::before,
.lg-edge::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(
    145deg,
    var(--lg-rim-bright) 0%,
    var(--lg-rim-dim) 28%,
    transparent 52%,
    var(--lg-rim-dim) 74%,
    var(--lg-rim-line) 100%
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
}

/* Coins continus là où le navigateur sait les dessiner : c'est la différence
   entre un rectangle arrondi et la forme des icônes d'iOS. Ailleurs, le rayon
   circulaire habituel s'applique, sans rien casser. */
@supports (corner-shape: squircle) {
  .lg,
  .glass-card,
  .btn,
  .metric-card,
  .scan-result,
  .scan-action-card,
  .form-control,
  .form-select {
    corner-shape: squircle;
  }
}

/* Repli sans flou : la teinte se densifie pour rester lisible. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .lg { background: var(--lg-thick); }
}

/* --------------------------------------------------------------------------
   4. Barre latérale et barre du haut — la vraie couche flottante
   -------------------------------------------------------------------------- */
.sidebar {
  background: var(--lg-regular);
  -webkit-backdrop-filter: blur(var(--lg-blur-strong)) saturate(var(--lg-saturate));
  backdrop-filter: blur(var(--lg-blur-strong)) saturate(var(--lg-saturate));
  border-right: 1px solid var(--lg-rim-line);
  transition: transform var(--lg-slow) var(--lg-ease);
  view-transition-name: lg-sidebar;
}

.sidebar__link {
  border-radius: var(--lg-r-sm);
  transition:
    background var(--lg-fast) ease,
    color var(--lg-fast) ease,
    transform var(--lg-base) var(--lg-spring);
}

.sidebar__link:hover {
  transform: translateX(2px);
}

.sidebar__link:active {
  transform: scale(0.975);
}

/* L'élément actif est une pilule teintée, posée sur la barre.
   Le texte passe à la nuance foncée de la marque : sur un fond déjà vert,
   le vert clair d'origine ne tenait qu'à 3,8 pour 1. */
.sidebar__link.is-active {
  position: relative;
  background: color-mix(in srgb, var(--brand) 16%, transparent);
  color: var(--brand-strong);
  box-shadow: inset 0 1px 0 0 var(--lg-rim-line);
}

/* En thème sombre, c'est l'inverse : la nuance foncée disparaîtrait dans le
   fond, on garde donc la couleur vive. */
[data-theme='dark'] .sidebar__link.is-active {
  color: var(--brand);
}

.sidebar__avatar,
.sidebar__logout {
  border-radius: var(--lg-r-pill);
}

.sidebar__logout {
  transition: background var(--lg-fast) ease, transform var(--lg-base) var(--lg-spring);
}

.sidebar__logout:active {
  transform: scale(0.97);
}

.topbar {
  background: var(--lg-thin);
  -webkit-backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
  backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
  border-bottom: 1px solid transparent;
  transition: background var(--lg-base) ease, border-color var(--lg-base) ease;
  view-transition-name: lg-topbar;
}

/* Au défilement, la barre se densifie et son arête apparaît : la séparation
   ne surgit que lorsqu'il y a quelque chose à séparer. */
.topbar.is-scrolled {
  background: var(--lg-regular);
  border-bottom-color: var(--lg-rim-line);
  box-shadow: 0 1px 16px -6px rgba(12, 30, 22, 0.22);
}

.topbar__menu,
.topbar__button {
  border-radius: var(--lg-r-pill);
  background: var(--lg-thin);
  -webkit-backdrop-filter: blur(10px) saturate(160%);
  backdrop-filter: blur(10px) saturate(160%);
  border: 1px solid var(--lg-rim-line);
  transition:
    background var(--lg-fast) ease,
    transform var(--lg-base) var(--lg-spring),
    box-shadow var(--lg-fast) ease;
}

.topbar__menu:hover,
.topbar__button:hover {
  background: var(--lg-thick);
  box-shadow: var(--lg-cast);
}

.topbar__menu:active,
.topbar__button:active {
  transform: scale(0.9);
}

.topbar__event {
  border-radius: var(--lg-r-pill);
  background: var(--lg-thin);
  border: 1px solid var(--lg-rim-line);
}

/* Le voile derrière la barre latérale mobile : il floute la page au lieu de
   la noircir, ce qui garde le contexte visible sous le panneau. */
.sidebar-overlay {
  background: color-mix(in srgb, var(--bg) 30%, transparent);
  -webkit-backdrop-filter: blur(8px) saturate(120%);
  backdrop-filter: blur(8px) saturate(120%);
  transition: opacity var(--lg-base) var(--lg-ease), visibility var(--lg-base);
}

/* --------------------------------------------------------------------------
   5. Contenu — géométrie et lumière du verre, sans son coût
   -------------------------------------------------------------------------- */
.glass-card,
.metric-card,
.scan-action-card,
.scan-context-card,
.attempt-list__item,
.field-preview {
  position: relative;
  border-radius: var(--lg-r-lg);
}

.glass-card {
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  border: 1px solid var(--lg-rim-line);
  box-shadow: var(--lg-cast);
  transition: box-shadow var(--lg-base) var(--lg-ease), transform var(--lg-base) var(--lg-ease);
}

.metric-card,
.scan-context-card {
  border-radius: var(--lg-r-md);
  border: 1px solid var(--lg-rim-line);
  background: color-mix(in srgb, var(--surface-2) 70%, transparent);
  transition: transform var(--lg-base) var(--lg-spring), box-shadow var(--lg-base) ease;
}

.metric-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--lg-cast);
}

.attempt-list__item {
  border-radius: var(--lg-r-md);
  transition: transform var(--lg-base) var(--lg-ease), background var(--lg-base) ease;
}

/* Une tentative qui vient d'arriver se pose au lieu d'apparaître. */
.attempt-list__item {
  animation: lg-pose var(--lg-slow) var(--lg-spring) both;
}

@keyframes lg-pose {
  from { opacity: 0; transform: translateY(-8px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   6. Contrôles — capsules de verre
   -------------------------------------------------------------------------- */
.btn {
  position: relative;
  border-radius: var(--lg-r-pill);
  transition:
    transform var(--lg-base) var(--lg-spring),
    background var(--lg-fast) ease,
    box-shadow var(--lg-fast) ease,
    filter var(--lg-fast) ease;
}

.btn:active {
  transform: scale(0.955);
}

.btn-brand {
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--brand) 92%, white) 0%,
    var(--brand) 55%,
    var(--brand-strong) 100%
  );
  border: 1px solid color-mix(in srgb, var(--brand-strong) 80%, transparent);
  box-shadow:
    inset 0 1px 0 0 rgba(255, 255, 255, 0.45),
    var(--lg-cast);
}

.btn-brand:hover,
.btn-brand:focus {
  filter: brightness(1.05);
  box-shadow:
    inset 0 1px 0 0 rgba(255, 255, 255, 0.5),
    var(--lg-cast-high);
}

/* Pas de flou ici, volontairement : ces boutons se répètent jusqu'à trois
   fois par ligne de tableau. Cinquante lignes, et c'est cent cinquante
   couches à recomposer à chaque image. La teinte et le liseré suffisent à
   les faire lire comme du verre. */
.btn-ghost {
  background: color-mix(in srgb, var(--surface) 55%, transparent);
  border: 1px solid var(--lg-rim-line);
}

.btn-ghost:hover,
.btn-ghost:focus {
  background: var(--lg-thick);
  border-color: var(--lg-rim-line);
  box-shadow: var(--lg-cast);
}

/* Sur vingt pixels de haut, un flou de huit ne se voit pas — mais il se
   paie. On garde la capsule et le liseré. */
.status-pill,
.chip {
  border-radius: var(--lg-r-pill);
  border: 1px solid var(--lg-rim-line);
}

/* --------------------------------------------------------------------------
   7. Champs de saisie
   -------------------------------------------------------------------------- */
.form-control,
.form-select {
  border-radius: var(--lg-r-md);
  background: color-mix(in srgb, var(--surface) 72%, transparent);
  border: 1px solid var(--lg-rim-line);
  transition:
    border-color var(--lg-fast) ease,
    box-shadow var(--lg-base) var(--lg-ease),
    background var(--lg-fast) ease;
}

.form-control:focus,
.form-select:focus {
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  box-shadow: 0 0 0 4px var(--ring), var(--lg-cast);
}

/* Le champ de scan et son bouton forment une seule capsule. */
.input-group > .form-control:first-child {
  border-top-left-radius: var(--lg-r-pill);
  border-bottom-left-radius: var(--lg-r-pill);
  padding-left: 1.25rem;
}

.input-group > .btn:last-child {
  border-top-right-radius: var(--lg-r-pill);
  border-bottom-right-radius: var(--lg-r-pill);
}

/* --------------------------------------------------------------------------
   8. Écran de scan — le moment qui compte

   C'est le seul endroit où le verre a le droit d'être épais : le panneau de
   résultat est ce que le staff regarde, à bout de bras, entre deux badges. Il
   doit changer d'état de façon indiscutable.
   -------------------------------------------------------------------------- */
.scan-action-card {
  background: color-mix(in srgb, var(--surface) 80%, transparent);
  border: 1px solid var(--lg-rim-line);
  border-radius: var(--lg-r-xl);
}

.scan-result {
  position: relative;
  overflow: hidden;
  border-radius: var(--lg-r-xl);
  -webkit-backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
  backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
  transition:
    background var(--lg-slow) var(--lg-ease),
    border-color var(--lg-slow) var(--lg-ease),
    box-shadow var(--lg-slow) var(--lg-ease);
}

/* Le contenu est remplacé à chaque scan : ces nœuds sont neufs, ils s'animent
   donc d'eux-mêmes, en cascade, sans que le script ait à s'en occuper. */
.scan-result > * {
  animation: lg-rise var(--lg-base) var(--lg-ease) both;
}
.scan-result > *:nth-child(2) { animation-delay: 0.03s; }
.scan-result > *:nth-child(3) { animation-delay: 0.06s; }
.scan-result > *:nth-child(4) { animation-delay: 0.09s; }
.scan-result > *:nth-child(5) { animation-delay: 0.12s; }

@keyframes lg-rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* Onde de confirmation : traverse le panneau une fois par scan, déclenchée
   par le script. Le regard n'a pas besoin d'être sur l'écran pour la voir
   passer du coin de l'œil. */
.scan-result::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(
    60% 120% at 50% 50%,
    color-mix(in srgb, currentColor 22%, transparent),
    transparent 70%
  );
}

.scan-result.is-flash::after {
  animation: lg-onde 0.62s var(--lg-ease);
}

@keyframes lg-onde {
  0%   { opacity: 0; transform: scale(0.6); }
  35%  { opacity: 1; }
  100% { opacity: 0; transform: scale(1.35); }
}

.scan-result--success { color: var(--success); }
.scan-result--warning { color: var(--warning); }
.scan-result--danger  { color: var(--danger); }
.scan-result--queued  { color: var(--pending); }

/* Le compteur de file d'attente respire doucement : présent sans être criard. */
.scan-queue-badge {
  border-radius: var(--lg-r-pill);
  -webkit-backdrop-filter: blur(10px) saturate(150%);
  backdrop-filter: blur(10px) saturate(150%);
  animation: lg-pose var(--lg-slow) var(--lg-spring) both;
}

.camera-frame {
  border-radius: var(--lg-r-xl);
  overflow: hidden;
}

.scan-tools summary {
  border-radius: var(--lg-r-pill);
  transition: background var(--lg-fast) ease;
}

/* --------------------------------------------------------------------------
   9. Alertes et messages flash — des capsules qui se posent
   -------------------------------------------------------------------------- */
.flash-stack .alert {
  border-radius: var(--lg-r-lg);
  border: 1px solid var(--lg-rim-line);
  -webkit-backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
  backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
  box-shadow: var(--lg-cast);
  animation: lg-descend var(--lg-slow) var(--lg-spring) both;
}

@keyframes lg-descend {
  from { opacity: 0; transform: translateY(-14px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   10. Pages de connexion et d'installation
   -------------------------------------------------------------------------- */
.auth-body::before {
  content: "";
  position: fixed;
  inset: -10vmax;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(40vmax 34vmax at 18% 2%, color-mix(in srgb, var(--brand) 30%, transparent), transparent 62%),
    radial-gradient(36vmax 30vmax at 86% 92%, color-mix(in srgb, #2f9ea8 26%, transparent), transparent 60%);
  opacity: 0.62;
  animation: lg-derive 28s ease-in-out infinite alternate;
}

[data-theme='dark'] .auth-body::before { opacity: 0.4; }

.auth-panel {
  border-radius: var(--lg-r-xl);
  background: var(--lg-regular);
  -webkit-backdrop-filter: blur(var(--lg-blur-strong)) saturate(var(--lg-saturate));
  backdrop-filter: blur(var(--lg-blur-strong)) saturate(var(--lg-saturate));
  border: 1px solid var(--lg-rim-line);
  box-shadow: var(--lg-cast-high);
  animation: lg-monte var(--lg-slow) var(--lg-spring) both;
}

/* Sur la page de connexion, la carte à l'intérieur du panneau ne doit pas
   ajouter une deuxième épaisseur de verre : elle s'efface. */
.auth-panel .glass-card {
  background: transparent;
  border: 0;
  box-shadow: none;
  padding: 0 !important;
}

@keyframes lg-monte {
  from { opacity: 0; transform: translateY(18px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}

.auth-brand {
  animation: lg-monte var(--lg-slow) var(--lg-ease) both;
  animation-delay: 0.06s;
}

.auth-toolbar .topbar__button {
  background: var(--lg-thin);
}

/* --------------------------------------------------------------------------
   11. Transitions entre les pages

   L'application est faite de pages servies par le serveur : chaque clic
   provoquait un flash blanc. L'API de transition de vue fait glisser le
   contenu d'une page à l'autre, pendant que la barre latérale et la barre du
   haut restent en place au lieu d'être redessinées.
   -------------------------------------------------------------------------- */
@view-transition {
  navigation: auto;
}

::view-transition-old(root) {
  animation: lg-sortie 0.2s var(--lg-ease) both;
}

::view-transition-new(root) {
  animation: lg-entree 0.36s var(--lg-ease) both;
}

@keyframes lg-sortie {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(-6px) scale(0.995); }
}

@keyframes lg-entree {
  from { opacity: 0; transform: translateY(10px) scale(0.995); }
  to   { opacity: 1; transform: none; }
}

/* La page d'impression des cartes n'entre pas dans ce jeu : elle doit
   apparaître instantanément et telle quelle. */
.print-body { view-transition-name: none; }

/* --------------------------------------------------------------------------
   12. Économie de mouvement et d'énergie

   Trois garde-fous. Le premier est une préférence système que l'on doit
   respecter. Les deux autres protègent les téléphones modestes du staff : au
   moindre doute sur la capacité de la machine, on retire le flou plutôt que
   de livrer une interface qui saccade au moment du scan.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .app-body::before,
  .auth-body::before {
    animation: none;
  }

  *,
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Mode allégé, posé par le script quand l'appareil est peu puissant ou que la
   batterie est basse : la géométrie et les reflets restent, le flou part. */
.lg-economie .sidebar,
.lg-economie .topbar,
.lg-economie .topbar__menu,
.lg-economie .topbar__button,
.lg-economie .scan-result,
.lg-economie .scan-queue-badge,
.lg-economie .auth-panel,
.lg-economie .sidebar-overlay,
.lg-economie .flash-stack .alert {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.lg-economie .sidebar,
.lg-economie .auth-panel { background: var(--surface); }

.lg-economie .topbar { background: color-mix(in srgb, var(--surface) 92%, transparent); }

.lg-economie .app-body::before,
.lg-economie .auth-body::before { animation: none; opacity: 0.28; }

/* --------------------------------------------------------------------------
   13. Écrans étroits

   Sur téléphone, la barre latérale est un panneau qui recouvre la page : c'est
   le seul contexte où elle a vraiment quelque chose à laisser transparaître.
   -------------------------------------------------------------------------- */
@media (max-width: 1023.98px) {
  .sidebar {
    border-right: 0;
    border-radius: 0 var(--lg-r-xl) var(--lg-r-xl) 0;
    box-shadow: var(--lg-cast-high);
  }

  /* Cibles tactiles : au moins 44 px, la règle d'iOS, ici parce qu'on scanne
     debout avec une main occupée par le téléphone. */
  .btn,
  .sidebar__link,
  .topbar__menu,
  .topbar__button {
    min-height: 44px;
  }

  .scan-action-card .btn,
  .scan-action-card .form-control {
    min-height: 52px;
  }
}

@media print {
  .app-body::before,
  .auth-body::before { display: none; }
}
