/* Ordre des couches en cascade. `frankenui` (core.min.css, importé dans main.html) tombe entre
   `base` (Preflight v4) et `components`/`utilities` : les composants .uk-* battent Preflight, mais
   les utilitaires Tailwind battent le reset de formulaire de FrankenUI. Doublé de main.html, qui
   fixe l'ordre en premier. */
@layer theme, base, frankenui, components, utilities;
@import "tailwindcss" source(none);
/* Portées de scan explicites, relatives à ce fichier (src/client/). rspack passe à PostCSS le
   chemin absolu de globals.css comme `from`, donc `@source` résout depuis src/client/. */
@source "../**/*.{js,html}";
@source "../../packages/sakod-core/**/*.{js,html}";

/* `darkMode: ['class']` de l'ancienne config. Le `dark` sur <html> est posé par le script
   inline de main.hbs.html + theme.js (choix system|light|dark dans localStorage), pas par le
   media : la variante doit donc suivre la classe, pas `prefers-color-scheme`. */
@custom-variant dark (&:where(.dark, .dark *));

/*
 * L'ex-`theme.extend.colors` de tailwind.config.js. `inline` : `bg-primary` compile droit en
 * `background-color: hsl(var(--primary))`, re-résolu par élément depuis la cascade vivante — donc
 * la valeur de yollo-2a.css gagne, en clair comme en `.dark`. Les jetons bruts (`--primary`, …)
 * restent dans les blocs `:root` / `.dark` de ce fichier et de yollo-2a.css, intacts.
 */
@theme inline {
  --color-border: hsl(var(--border));
  --color-input: hsl(var(--input));
  --color-ring: hsl(var(--ring));
  --color-background: hsl(var(--background));
  --color-foreground: hsl(var(--foreground));
  --color-primary: hsl(var(--primary));
  --color-primary-foreground: hsl(var(--primary-foreground));
  --color-secondary: hsl(var(--secondary));
  --color-secondary-foreground: hsl(var(--secondary-foreground));
  --color-destructive: hsl(var(--destructive));
  --color-destructive-foreground: hsl(var(--destructive-foreground));
  --color-negative: hsl(var(--negative));
  --color-surface: hsl(var(--surface));
  --color-surface-alt: hsl(var(--surface-alt));
  --color-muted: hsl(var(--muted));
  --color-muted-foreground: hsl(var(--muted-foreground));
  --color-accent: hsl(var(--accent));
  --color-accent-foreground: hsl(var(--accent-foreground));
  --color-popover: hsl(var(--popover));
  --color-popover-foreground: hsl(var(--popover-foreground));
  --color-card: hsl(var(--card));
  --color-card-foreground: hsl(var(--card-foreground));

  /* L'ex-`theme.extend.borderRadius` : lg/md/sm dérivés de --radius ; xl+ gardent les valeurs v4. */
  --radius-sm: calc(var(--radius) - 4px);
  --radius-md: calc(var(--radius) - 2px);
  --radius-lg: var(--radius);

  /* A sheet slides in without overshoot: a spring flashed the backdrop. A token because a value with
     nested commas in an arbitrary class was once silently not generated (budgets.hbs.html). */
  --ease-sheet: cubic-bezier(0.22, 1, 0.36, 1);
}

/* A drag on a sheet that cannot scroll must not move the page behind it: UIkit used to lock the root. */
html:has([data-sheet][data-open]) {
  overscroll-behavior: none;
}

/* L'ex-`theme.extend.boxShadow`. En `@utility` et non en `@theme` : le jeton brut --shadow-card
   (défini dans yollo-2a.css, clair + sombre) porte déjà ce nom. */
@utility shadow-card {
  box-shadow: var(--shadow-card);
}

@utility shadow-card-sm {
  box-shadow: var(--shadow-card-sm);
}

@layer base {
  /* v4 Preflight met img{display:block} ; l'app veut inline-block. */
  img {
    display: inline-block;
  }

  /* v4 met la couleur de bordure par défaut à `currentColor` ; l'app la veut = --border partout
     (c'était `* { @apply border-border }`). Sélecteurs alignés sur le Preflight v4. */
  *,
  ::after,
  ::before,
  ::backdrop,
  ::file-selector-button {
    border-color: var(--color-border, currentColor);
  }
}

html,
body {
  height: 100%;
}

html {
  font-size: 13px;
}

@layer base {
  :root {
    --uk-card-radius: 1.375rem;

    --background: 0 0% 100%;
    --foreground: 0 0% 3.9%;

    --card: 0 0% 100%;
    --card-foreground: 0 0% 3.9%;

    --popover: 0 0% 100%;
    --popover-foreground: 0 0% 3.9%;

    --primary: 238 53% 58%;
    --primary-foreground: 0 0% 100%;

    --secondary: 0 0% 96.1%;
    --secondary-foreground: 0 0% 9%;

    --muted: 0 0% 96.1%;
    /*
     * 43,5 % et non 45,1 % : `text-muted-foreground` est la couleur de tout le texte secondaire
     * de l'application (130 usages), et il est très souvent posé sur `bg-muted` — le panneau de
     * filtres, la barre d'action du pointage, les chips non sélectionnées. Sur ce gris à 96,1 %,
     * 45,1 % donne 4,35:1, sous le seuil AA de 4,5:1 ; 43,5 % donne 4,61:1 sur `bg-muted` et
     * 5,03:1 sur le fond blanc. Le thème sombre était déjà au-dessus (5,99:1), il ne bouge pas.
     */
    --muted-foreground: 0 0% 43.5%;

    --accent: 0 0% 94.1%;
    --accent-foreground: 0 0% 9%;
    --morse-accent: #5c60cc;
    --morse-accent-soft: #eff0ff;

    --destructive: 0 84.2% 60.2%;
    --destructive-foreground: 0 0% 98%;

    --border: 0 0% 89.8%;
    --input: 0 0% 89.8%;
    --ring: 0 0% 3.9%;

    --radius: 0.5rem;

    --chart-1: 12 76% 61%;
    --chart-2: 173 58% 39%;
    --chart-3: 197 37% 24%;
    --chart-4: 43 74% 66%;
    --chart-5: 27 87% 67%;

    --uk-btn-height: 28px;
    --uk-btn-padding: 0 12px;
    --uk-btn-font-size: 13px;

    --uk-form-input-height: 28px;
    --uk-form-input-padding: 0 10px;
    --uk-form-input-font-size: 13px;

    --uk-form-checkbox-image: url("data:image/svg+xml,%3Csvg width='15' height='15' viewBox='0 0 15 15' xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='100%25' height='100%25' fill='%2318181b' /%3E%3Cpath d='M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z' fill='%23fafafa' fill-rule='evenodd' clip-rule='evenodd' %3E%3C/path%3E%3C/svg%3E");
    --uk-form-checkbox-image-indeterminate: url(data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Crect%20fill%3D%22%2318181b%22%20x%3D%223%22%20y%3D%228%22%20width%3D%2210%22%20height%3D%221%22%20%2F%3E%0A%3C%2Fsvg%3E);
    --uk-form-radio-image: url("data:image/svg+xml,%3Csvg width='15' height='15' viewBox='0 0 15 15' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z' fill='%2318181b' fill-rule='evenodd' clip-rule='evenodd' %3E%3C/path%3E%3C/svg%3E%0A");
    --uk-form-list-image: url("data:image/svg+xml,%3Csvg width='24' height='16' viewBox='0 0 24 16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpolygon fill='%2371717a' points='12 1 9 6 15 6' /%3E%3Cpolygon fill='%2371717a' points='12 13 9 8 15 8' /%3E%3C/svg%3E%0A");
    --uk-divider-icon-image: url(data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20viewBox%3D%220%200%2020%2020%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Ccircle%20fill%3D%22none%22%20stroke%3D%22%23e4e4e7%22%20stroke-width%3D%222%22%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%227%22%20%2F%3E%0A%3C%2Fsvg%3E%0A);
    --uk-list-bullet-image: url(data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%226%22%20height%3D%226%22%20viewBox%3D%220%200%206%206%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Ccircle%20fill%3D%22%2309090b%22%20cx%3D%223%22%20cy%3D%223%22%20r%3D%223%22%20%2F%3E%0A%3C%2Fsvg%3E)
  }

  .dark {
    --background: 0 0% 3.9%;
    --foreground: 0 0% 98%;

    --card: 0 0% 3.9%;
    --card-foreground: 0 0% 98%;

    --popover: 0 0% 3.9%;
    --popover-foreground: 0 0% 98%;

    --primary: 238 53% 58%;
    --primary-foreground: 0 0% 100%;

    --secondary: 0 0% 14.9%;
    --secondary-foreground: 0 0% 98%;

    --muted: 0 0% 14.9%;
    --muted-foreground: 0 0% 63.9%;

    --accent: 0 0% 14.9%;
    --accent-foreground: 0 0% 98%;

    --destructive: 0 62.8% 30.6%;
    --destructive-foreground: 0 0% 98%;

    --border: 0 0% 14.9%;
    --input: 0 0% 14.9%;
    --ring: 0 0% 83.1%;
  }
}

a.uk-btn,
.no-underline,
.card-link,
.uk-nav a,
.navbar-dropdown a {
  text-decoration: none !important;
}

/* uk-offcanvas: side panel */
.uk-offcanvas-bar {
  width: 420px;
}

/* Tab style */
.uk-tab-alt {
  font-size: 12px;
  margin: 0;
  padding: 4px;
  background-color: transparent;
  box-shadow: 0 0 30px #00000020;
  border-radius: 20px;
  height: auto;
  gap: 0 4px;
}

.uk-tab-alt a {
  padding: 6px 16px;
  border-radius: 20px;
}

.uk-tab-alt>.uk-active>a {
  background-color: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
}

.uk-tab-alt a:hover {
  background-color: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
}

/* Cards */
.uk-card {
  @apply rounded-lg;
  border: 0.5px solid hsl(var(--border));
  box-shadow: none;
}

/* Buttons */
.uk-btn {
  border-radius: 6px;
}

.uk-btn-primary {
  --uk-btn-background: hsl(var(--primary));
  --uk-btn-color: hsl(var(--primary-foreground));
  background-color: hsl(var(--primary));
  border-color: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
}

.uk-btn-primary:hover,
.uk-btn-primary:focus {
  background-color: hsl(var(--primary) / 0.92);
  border-color: hsl(var(--primary) / 0.92);
  color: hsl(var(--primary-foreground));
}

.uk-btn-primary.uk-btn-icon {
  background-color: hsl(var(--primary));
  border-color: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
}

.uk-btn-primary.uk-btn-icon:hover,
.uk-btn-primary.uk-btn-icon:focus {
  background-color: hsl(var(--primary) / 0.92);
  border-color: hsl(var(--primary) / 0.92);
  color: hsl(var(--primary-foreground));
}

.uk-btn-icon {
  background-color: transparent;
}

.uk-btn-icon:hover {
  background-color: hsl(var(--accent));
  color: hsl(var(--accent-foreground));
}

.uk-btn-danger {
  --uk-btn-background: hsl(var(--destructive));
  --uk-btn-color: hsl(var(--destructive-foreground));
  background-color: hsl(var(--destructive));
  border-color: hsl(var(--destructive));
  color: hsl(var(--destructive-foreground));
}

.uk-btn-danger:hover,
.uk-btn-danger:focus {
  background-color: hsl(var(--destructive) / 0.9);
  border-color: hsl(var(--destructive) / 0.9);
  color: hsl(var(--destructive-foreground));
}

.btn-ghost-danger {
  /* était `@apply uk-btn` : v4 n'applique que des utilitaires, pas une classe FrankenUI.
     `.uk-btn` (plus haut) n'apporte que ce rayon. */
  border-radius: 6px;
  /* --negative, not --destructive: the latter is a dark fill (for .uk-btn-danger) and is unreadable as
     text on the dark theme (1.9:1). */
  color: hsl(var(--negative));
  background: transparent;
  border: none;
}

.btn-ghost-danger:hover {
  background-color: hsl(var(--negative) / 0.1);
}

/* Inputs */
.uk-input:hover,
.uk-select:hover,
.uk-textarea:hover {
  background-color: hsl(var(--accent));
}

.sk-field {
  gap: 2px;
}

.sk-field>label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
}

.sk-field:not(.sk-field-checkbox)>label>div:first-child {
  margin-bottom: 0 !important;
  color: hsl(var(--foreground));
  font-size: 13px;
  font-weight: 600;
  line-height: 1.35;
}

.sk-field:not(.sk-field-checkbox)>label>div:last-child {
  width: 100%;
}

.sk-input-primary,
.input-primary,
.sk-field-select-multiple,
.sk-field-textarea {
  display: block;
  width: 100%;
  min-height: 36px;
  padding: 0 11px;
  border: 1px solid hsl(var(--input));
  border-radius: 7px;
  background: hsl(var(--card));
  color: hsl(var(--foreground));
  font-size: 13px;
  line-height: 1.4;
  box-shadow: inset 0 1px 2px #00000008;
  transition:
    background-color .15s ease,
    border-color .15s ease,
    box-shadow .15s ease;
}

.ts-wrapper.sk-field-select-unique {
  width: 100%;
}

.ts-wrapper.sk-field-select-unique .ts-control,
select.sk-field-select-unique:not(.ts-hidden-accessible) {
  width: 100%;
  min-height: 36px;
  padding: 0 11px;
  border: 1px solid hsl(var(--input));
  border-radius: 7px;
  background: hsl(var(--card));
  color: hsl(var(--foreground));
  font-size: 13px;
  line-height: 1.4;
  box-shadow: inset 0 1px 2px #00000008;
  transition:
    background-color .15s ease,
    border-color .15s ease,
    box-shadow .15s ease;
}

.sk-field-textarea {
  min-height: 92px;
  padding: 9px 11px;
  resize: vertical;
}

.sk-input-primary::placeholder,
.input-primary::placeholder,
.sk-field-textarea::placeholder {
  color: hsl(var(--muted-foreground));
}

.sk-input-primary:hover,
.input-primary:hover,
.sk-field-select-multiple:hover,
.sk-field-textarea:hover,
.ts-wrapper.sk-field-select-unique:hover .ts-control,
select.sk-field-select-unique:not(.ts-hidden-accessible):hover {
  background-color: hsl(var(--accent));
}

.sk-input-primary:focus,
.input-primary:focus,
.sk-field-select-multiple:focus,
.sk-field-textarea:focus,
.ts-wrapper.sk-field-select-unique.focus .ts-control,
select.sk-field-select-unique:not(.ts-hidden-accessible):focus {
  outline: none;
  border-color: hsl(var(--ring) / 0.35);
  box-shadow:
    0 0 0 3px hsl(var(--ring) / 0.08),
    inset 0 1px 2px #00000008;
}

.sk-input-primary[disabled],
.input-primary[disabled],
.sk-field-select-multiple[disabled],
.sk-field-textarea[disabled],
.ts-wrapper.sk-field-select-unique.disabled .ts-control,
select.sk-field-select-unique:not(.ts-hidden-accessible)[disabled] {
  opacity: 0.65;
  cursor: not-allowed;
  background: hsl(var(--muted));
}

.sk-field-checkbox>label {
  display: flex;
  align-items: center;
  flex-direction: row;
  gap: 10px;
}

.sk-field-checkbox input[type="checkbox"] {
  position: static;
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: hsl(var(--foreground));
}

.sk-field-checkbox>label>div {
  padding-left: 0;
  color: hsl(var(--foreground));
  font-size: 13px;
  font-weight: 600;
}

.ts-hidden-accessible {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  min-height: 0 !important;
  padding: 0 !important;
  overflow: hidden !important;
  opacity: 0 !important;
  pointer-events: none !important;
}

.sk-field.inline,
.sk-field.inline>label,
.sk-field.inline>label>.input-icon,
.sk-field.inline>label>.input-icon>input {
  display: inline;
}

.sk-field.inline>label>.input-icon>input,
.sk-field.inline input {
  width: unset;
  min-height: unset;
}

/* Tables */
.uk-table>thead {
  box-shadow: inset 0 -0.5px hsl(var(--border));
}

/* Legacy navbar links (kept for compatibility) */



/* App shell */
.app-shell {
  display: flex;
  flex-direction: column;
  height: 100%;
}

/*
 * La barre du bas — la seule navigation de l'application, à toutes les largeurs.
 *
 * Elle n'était visible que sous 768 px ; au-dessus, une barre du haut portait les mêmes trois
 * liens et le même menu Compte. Deux barres pour la même chose, dont une seule était visible à la
 * fois : celle du haut est partie, et ses règles avec elle.
 */

/*
 * La refonte fait de la barre une PASTILLE FLOTTANTE : elle ne touche plus les bords, se détache
 * du contenu par une ombre et son rayon, et laisse voir la page dans la gouttière tout autour.
 *
 * `.app-bottom-nav` n'est plus qu'un conteneur transparent, sans clic (`pointer-events: none`)
 * pour que la gouttière n'intercepte ni défilement ni tap sur le contenu derrière ; c'est
 * `.app-bottom-nav-inner` — la pastille visible — qui reprend les clics.
 *
 * La pastille ÉPOUSE ses onglets (`width: fit-content`) au lieu de s'étirer sur `max-w-2xl` :
 * étalés sur 42rem, quatre onglets laissaient d'énormes vides entre eux. Bornée à la largeur de
 * l'écran moins ses marges pour ne jamais déborder sur un petit téléphone.
 */
/*
 * L'enveloppe partagée par la pastille et le tiroir hors ligne (juste en dessous) : sa largeur
 * `fit-content` vient de son seul enfant en flux normal, `.app-bottom-nav-inner` — le tiroir, posé
 * en absolu, n'y contribue pas (un élément hors flux n'entre jamais dans un calcul fit-content) et
 * hérite donc exactement cette même largeur via `left: 0; right: 0`. C'est ce qui garantit que le
 * tiroir fait toujours la largeur du menu, quel que soit le nombre d'onglets, sans mesure en JS.
 */
.app-bottom-nav-wrap {
  position: relative;
  width: fit-content;
  max-width: calc(100vw - 20px);
  margin: 0 auto;
}

.app-bottom-nav-inner {
  position: relative;
  /* Au-dessus du tiroir hors ligne : c'est ce qui fait disparaître les 12px que le tiroir passe
     dessous (voir .app-net-drawer) derrière un fond opaque, plutôt que par-dessus les onglets. */
  z-index: 2;
  pointer-events: auto;
  display: flex;
  gap: 2px;
  padding: 6px;
  border-radius: 22px;
  background: hsl(var(--card));
  box-shadow: var(--shadow-card);
}

/*
 * Sync border: a rainbow turning along the menu's edge while a sync pass runs — the edge only,
 * the menu keeps its own background. A conic gradient painted on a ::before, masked down to a 2px
 * ring (the content-box / border-box mask exclusion), its angle animated through a registered
 * property. Painted over the menu (not behind it: a negative z-index child still sits above its
 * parent's own background), `pointer-events: none` so the tabs stay clickable.
 */
@property --sync-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

.app-bottom-nav-inner--syncing::before {
  content: '';
  position: absolute;
  inset: 0;
  padding: 2px;
  border-radius: inherit;
  background: conic-gradient(from var(--sync-angle), #ff3b6b, #ff9f1a, #ffe14d, #3ddc84, #2bb8ff, #8a5cff, #ff3b6b);
  -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 exclude, linear-gradient(#000 0 0);
  animation: sync-spin 2.4s linear infinite;
  pointer-events: none;
}

@keyframes sync-spin {
  to { --sync-angle: 360deg; }
}

@media (prefers-reduced-motion: reduce) {
  .app-bottom-nav-inner--syncing::before { animation-duration: 8s; }
}

/*
 * Le message hors ligne / envoi en attente — un tiroir qui sort de derrière le menu plutôt qu'une
 * bannière en haut de page (l'ancien traitement, jugé pas assez soigné). Même largeur que le menu
 * (voir `.app-bottom-nav-wrap`), même rayon (20px, arrondi seulement en haut : son bord bas se
 * cache sous le menu, un rayon là n'aurait jamais été visible). `bottom: calc(100% - 12px)` place
 * son bord bas 12px SOUS le haut du menu — cette bande reste couverte par le fond opaque du menu
 * (z-index 2 > 1 ici), le reste dépasse au-dessus, visible. Sans ce recouvrement, la jonction entre
 * les deux coins arrondis (celui du tiroir, celui du menu) se serait vue comme une entaille.
 */
.app-net-drawer {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(100% - 12px);
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  /* 12px of the bottom padding hide under the menu (the drawer slides 12px behind it): the other 12
     are what is left between the text and the menu's edge. */
  padding: 11px 14px 24px;
  border-radius: 20px 20px 0 0;
  text-align: center;
  /* `.app-bottom-nav` ignores the pointer so its gutter never blocks the page; the drawer is its
     child, not the menu's, and holds the « Réessayer » link. */
  pointer-events: auto;
}

/* La pastille est fixée en bas : sans cette réserve, elle recouvre la fin de chaque page. Sa
   hauteur ≈ 58 (rangée d'onglets) + 12 (marge basse) + le retrait de zone sécurisée. */
.app-content {
  padding-bottom: calc(78px + env(safe-area-inset-bottom, 0px));
}

.app-bottom-nav {
  display: flex;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  /* La marge basse tient dans le padding du conteneur (pas une hauteur fixe) : la pastille flotte
     au-dessus du bord, et le retrait de zone sécurisée s'AJOUTE à la marge au lieu de la rogner. */
  padding: 0 12px calc(12px + env(safe-area-inset-bottom, 0px));
  background: transparent;
  pointer-events: none;
  z-index: 1000;
}

/* Chaque onglet à sa largeur naturelle (`flex: 0 0 auto`) : c'est ce qui resserre la pastille
   autour de ses libellés. `white-space: nowrap` garde chaque libellé sur une ligne — sinon un
   retour à la ligne remonterait l'icône et casserait la hauteur de la rangée. */
.app-bottom-nav-tab {
  flex: 0 0 auto;
  padding: 8px 14px;
  border-radius: 14px;
  white-space: nowrap;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  font-size: 10px;
  font-weight: 700;
  color: hsl(var(--muted-foreground));
  text-decoration: none !important;
}

.app-bottom-nav-tab i {
  font-size: 20px;
}

/* Five tabs (the Chat tab shows once the assistant is installed) are 358px wide: 3px more than a
   375px phone leaves the pill. 12px of padding makes them 338px; without the tab nothing changes. */
.app-bottom-nav-inner--chat .app-bottom-nav-tab {
  padding-inline: 12px;
}

/* La couleur primaire de l'application (le bleu du logo), pas l'indigo hérité du gabarit d'origine. */
.app-bottom-nav-tab-active {
  color: hsl(var(--primary));
}

/*
 * Le toast « Annuler » (undo-toast.js / undoToast) — une pilule inversée qui descend du haut de
 * l'écran et s'arrête avec un léger ressort. Ancrée EN HAUT et non au-dessus de la pastille de
 * navigation : la feuille de classement peut monter jusqu'à 90 % de l'écran, et un toast en bas
 * recouvrait sa dernière rangée de pastilles (taps manqués). En haut, il ne croise ni la pastille
 * ni les contrôles de la feuille.
 */
.undo-toast {
  position: fixed;
  left: 50%;
  top: calc(12px + env(safe-area-inset-top, 0px));
  z-index: 1100;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: calc(100vw - 32px);
  padding: 10px 14px;
  border-radius: 14px;
  background: hsl(var(--foreground));
  color: hsl(var(--background));
  box-shadow: var(--shadow-card);
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
  opacity: 0;
  transform: translate(-50%, -14px);
  pointer-events: none;
  transition:
    opacity 0.35s cubic-bezier(0.34, 1.56, 0.64, 1),
    transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.undo-toast.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;
}

@media (prefers-reduced-motion: reduce) {
  .undo-toast {
    transition-duration: 0.01s;
    transition-timing-function: linear;
  }
}

/*
 * Analyse — l'entrée en croissance des barres.
 *
 * `scaleY` / `scaleX` depuis le bord (transform, donc GPU et sans reflow) : rejouée à chaque
 * (re)construction du rapport, la barre repousse quand on change de période ou de filtre. Le
 * délai par barre vient d'un `--i` posé en style inline dans le gabarit (l'index du mois).
 */
.an-bar {
  transform-origin: bottom;
  animation: an-bar-grow 0.55s cubic-bezier(0.22, 1, 0.36, 1) both;
  animation-delay: calc(var(--i, 0) * 45ms);
}

.an-fill {
  transform-origin: left;
  animation: an-fill-grow 0.5s ease both;
}

@keyframes an-bar-grow {
  from { transform: scaleY(0); }
  to { transform: scaleY(1); }
}

@keyframes an-fill-grow {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

@media (prefers-reduced-motion: reduce) {
  .an-bar,
  .an-fill {
    animation: none;
  }
}

/* App content wrapper — scrolls for regular pages; mails-layout overrides with fixed height */
.app-content {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.god-section-layout {
  display: flex;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.god-section-sidebar {
  width: 230px;
  flex-shrink: 0;
  border-right: 0.5px solid hsl(var(--border));
  background: hsl(var(--card));
  overflow-y: auto;
}

.god-section-sidebar-inner {
  padding: 18px 14px;
}

.god-section-main {
  flex: 1;
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
}

.god-section-nav-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.god-section-nav-item-main,
.god-section-nav-item-meta {
  display: flex;
  align-items: center;
  gap: 8px;
}

.god-section-nav-item-main {
  min-width: 0;
}

.god-section-nav-item-main i {
  flex-shrink: 0;
  opacity: 0.7;
}

.god-section-nav-item-meta {
  margin-left: auto;
  flex-shrink: 0;
}

@media (max-width: 639px) {
  .god-section-layout {
    flex-direction: column;
    overflow: visible;
  }

  .god-section-sidebar {
    width: auto;
    border-right: none;
    border-bottom: 0.5px solid hsl(var(--border));
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
  }

  .god-section-sidebar::-webkit-scrollbar {
    display: none;
  }

  .god-section-sidebar-inner {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 12px;
    min-width: max-content;
  }

  .god-section-main {
    min-height: auto;
    overflow: visible;
  }

  .god-section-sidebar .subheader {
    display: none;
  }

  .god-section-sidebar .list-group {
    flex-direction: row;
    gap: 6px;
    flex-wrap: nowrap;
  }

  .god-section-sidebar .list-group-item {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 34px;
    padding: 0 10px;
    white-space: nowrap;
    flex-shrink: 0;
  }

  .god-section-nav-item {
    justify-content: flex-start;
  }

  .god-section-nav-item-main,
  .god-section-nav-item-meta {
    gap: 6px;
  }

  .god-section-nav-item-meta {
    display: none;
  }
}

/* Navbar dropdowns (custom JS-driven) */
.navbar-dropdown {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 1000;
  min-width: 220px;
  background: hsl(var(--card));
  border: 0.5px solid hsl(var(--border));
  border-radius: 8px;
  padding: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}

.navbar-dropdown-right {
  left: auto;
  right: 0;
}

/* Page wrapper — flex child of app-content */
.page-wrapper {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}

/* List group (settings sidebar) */
.list-group {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.list-group-item {
  @apply px-3 py-2 rounded-md text-sm cursor-pointer;
  color: hsl(var(--foreground));
  text-decoration: none;
}

.list-group-item:hover {
  background-color: hsl(var(--accent));
}

.list-group-item.active {
  background-color: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
}

.list-group-item.active .uk-badge:not(.uk-badge-destructive) {
  background: #fff;
  color: hsl(var(--primary));
  border-color: #fff;
}

.list-group-item.active .text-muted-foreground {
  color: hsl(var(--primary-foreground) / 0.78) !important;
}

/* subheader */
.subheader {
  @apply text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-2;
}

.god-section-sidebar .subheader {
  font-size: 11px;
}

.god-section-sidebar .list-group-item {
  font-size: 13px;
}

/* Empty state */
.empty {
  @apply flex flex-col items-center justify-center py-12 text-center;
}

.empty-img {
  @apply mb-4 opacity-50;
}

.empty-title {
  @apply text-lg font-medium mb-2;
}

.empty-subtitle {
  @apply text-sm text-muted-foreground;
}

/* Ribbon */
.ribbon {
  position: absolute;
  top: 0;
  right: 0;
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 600;
  color: white;
  border-radius: 0 var(--radius) 0 var(--radius);
}

.ribbon.bg-blue {
  background-color: #3b82f6;
}

/* Input icon addon */
.input-icon {
  position: relative;
}

.input-icon .uk-input {
  padding-right: 2.5rem;
}

.input-icon-addon {
  position: absolute;
  right: 0.75rem;
  top: 50%;
  transform: translateY(-50%);
  color: hsl(var(--muted-foreground));
  pointer-events: none;
}

.input-icon-addon.cursor-pointer {
  pointer-events: auto;
  cursor: pointer;
}

/* Page body */
.page-body {
  @apply px-4 pt-4;
}

/* card-link hover */
.card-link {
  text-decoration: none;
  cursor: pointer;
  display: block;
}

.card-link:hover {
  box-shadow: 0 4px 16px #00000015;
}

.card-active {
  border-color: hsl(var(--primary));
  box-shadow: 0 0 0 2px hsl(var(--primary) / 0.2);
}

/* Avatar */
.avatar {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius);
  background-size: cover;
  background-position: center;
  overflow: hidden;
  flex-shrink: 0;
}

.avatar-xl {
  width: 4rem;
  height: 4rem;
}

.avatar-sm {
  width: 2rem;
  height: 2rem;
}

.avatar-xs {
  width: 1.5rem;
  height: 1.5rem;
}

.avatar-xxs {
  width: 1rem !important;
  height: 1rem !important;
}


/* Fix conflict between sk.toast (Sonner) and old toast class */
html .toast:not(.show) {
  display: block !important;
}

/*
  16px sur écran tactile, et seulement là — pour la LISIBILITÉ des champs, plus pour le zoom.

  Le zoom est désormais coupé au niveau du viewport (`user-scalable=no`, voir main.hbs.html) :
  cette règle visait à l'origine le zoom automatique d'iOS au focus d'un champ sous 16px, mais une
  classe Tailwind `text-[13px]` sur un champ la battait par spécificité et le zoom revenait. On
  garde quand même les 16px : un champ où l'on tape mérite d'être lisible sans zoomer.

  `pointer: coarse` plutôt qu'une largeur : c'est le doigt qui pose le problème, pas la taille de
  l'écran.
*/
@media (pointer: coarse) {
  input,
  select,
  textarea,
  .uk-input,
  .uk-select,
  .uk-textarea {
    font-size: 16px;
  }

  /*
   * La hauteur minimale d'une cible tactile.
   *
   * `html` fixe `font-size: 13px`, donc toute hauteur écrite en rem tombe à 81 % de sa valeur
   * nominale : mesuré en direct, `h-11` rend 35,8 px et non 44, `h-8` rend 26 px, et
   * `--uk-btn-height: 28px` s'applique à tous les `uk-btn` — « Connecter une banque »,
   * « Enregistrer le nouveau mot de passe », « Connecter cette banque ». Ce sont les actions
   * principales de l'application, et elles font la moitié d'un doigt.
   *
   * En pixels et non en rem, sinon la règle se ferait rogner par la même échelle qu'elle corrige.
   *
   * Seulement sur écran tactile : la densité compacte est un choix assumé à la souris, où le
   * pointeur est précis au pixel. C'est le doigt qui pose le problème, pas la taille de l'écran —
   * même raison que la règle des 16px ci-dessus.
   *
   * `.uk-input`/`.uk-select`/`.uk-textarea` rejoignent la liste pour la même raison qu'ils sont
   * déjà dans la règle des 16px juste au-dessus : posé à côté d'un bouton qui grandit à 44px et
   * pas lui, un champ CHERCHE À GARDER 28px devient visiblement plus petit — mesuré en direct sur
   * la fiche d'édition d'une contrepartie (nom + loupe, SIREN + lien). Sans cette ligne, corriger
   * le bouton à sa taille aurait fait l'inverse de ce que cette règle protège : rétrécir sa cible
   * tactile sous 44px pour qu'il rejoigne un champ qui, lui, n'a jamais eu cette garantie.
   */
  .uk-btn,
  button,
  [role="button"],
  .uk-input,
  .uk-select,
  .uk-textarea {
    min-height: 44px;
  }

  /* Une case à cocher garde sa taille : c'est son étiquette qui porte la zone tactile (voir la
     ligne du pointage, dimensionnée à 44px en dur pour cette raison). */
  input[type="checkbox"],
  input[type="radio"] {
    min-height: 0;
  }
}

